Peano
Loading...
Searching...
No Matches
TreeSplitter.py
Go to the documentation of this file.
1import numpy as np
2import matplotlib.pyplot as plt
3from scipy import io
4import os
5import math
6
7import re
8from collections import defaultdict
9
10def round_sig(x, sig):
11 return float(np.format_float_positional(x, precision=sig, unique=False, trim='k'))
12
13def read_patches(file_path, size_groups):
14 with open(file_path, "r") as f:
15 content = f.read()
16
17 # Regular expression to extract offset and size
18 patch_pattern = re.compile(
19 r'begin patch.*?offset ([\d.eE+\-]+ [\d.eE+\-]+ [\d.eE+\-]+).*?'
20 r'size ([\d.eE+\-]+ [\d.eE+\-]+ [\d.eE+\-]+)',
21 re.DOTALL
22 )
23
24 # Find all matches
25 for match in patch_pattern.findall(content):
26 offset, size = match
27 size_groups[size].append(offset) # Group offsets by size
28
29 return size_groups
30
31def read_SFC(file_path, domain_offset, domain_size):
32 with open(file_path, "r") as f:
33 content = f.read()
34
35 # Regular expression to extract offset and size
36 patch_pattern = re.compile(
37 r'begin patch.*?offset ([\d.eE+\-]+ [\d.eE+\-]+ [\d.eE+\-]+).*?'
38 r'size ([\d.eE+\-]+ [\d.eE+\-]+ [\d.eE+\-]+)',
39 re.DOTALL
40 )
41
42 index_map=[]
43 # Find all matches
44 for match in patch_pattern.findall(content):
45 index_entry=[0,0,0,0] #level and three dimensions
46 offset, size = match
47 size_tuple = tuple(map(float, size.split()))
48 offset_tuple = tuple(map(float, offset.split()))
49
50 index_entry[0]=int( math.log( int(round_sig(domain_size[0]/size_tuple[0],1)), 3) )
51 for i in range(len(offset_tuple)):
52 index_entry[i+1]=round((offset_tuple[i]-domain_offset[i])/size_tuple[i])
53
54 index_map.append(index_entry)
55
56 return index_map
57
58
59def main():
60 #main start here
61
62 #python3 ccz4.py -impl fd4-rk1-adaptive -s gauge -maxh 0.05 -minh 0.02 -ps 3 -plt 0.1 -et 0.05 -exn test --domain_r 0.5 --ReSwi 1 -cfl 0.1 --KOSigma 8.0
63 #=========================================================
64 #input parameters
65 folder_path = 'case2'
66 prefix = 'grid-'
67 dimension=3
68 subtree_number=8
69 #=========================================================
70
71
72 # List all files in the folder with the specified prefix
73 datafiles = [f for f in os.listdir(folder_path) if f.startswith(prefix)]
74
75 #extract grid infomation
76 size_groups = defaultdict(list) # Dictionary to store {size: [offsets]}
77 for file_path in datafiles:
78 read_patches(folder_path+'/'+file_path, size_groups)
79
80 for size, offsets in size_groups.items():
81 print(f"Size: {size} -> Count: {len(offsets)}")
82 #print("Offsets:")
83 #for offset in offsets:
84 # print(f" {offset}")
85 #print("-" * 40)
86
87 #find the domain info directly from grid plot
88 max_size=0
89 for size in size_groups.keys():
90 size_tuple = tuple(map(float, size.split()))
91 if size_tuple[0]>max_size:
92 max_size=size_tuple[0]
93 max_size_key=size
94 #print(max_size)
95
96 leftmost_offset=[999,999,999]
97 for offset in size_groups[max_size_key]:
98 offset_tuple = tuple(map(float, offset.split()))
99 #print(offset_tuple)
100 for m in range(dimension):
101 if offset_tuple[m]<leftmost_offset[m]:
102 leftmost_offset[m]=offset_tuple[m]
103 leftmost_offset_key=offset
104 #print(leftmost_offset, leftmost_offset_key)
105
106 domain_offset = tuple(leftmost_offset)#tuple(map(float, leftmost_offset_key.split()))
107 domain_size = tuple(map(float, max_size_key.split()))
108 domain_size = tuple( round_sig(x * 3,5) for x in domain_size)
109
110 print(domain_offset, domain_size)
111
112 #preparing tree matrices
113 total_level=len(size_groups.keys())
114 #for i in range(total_level):
115 # print("level "+str(i)+" Matrix total entries:", (3*(3**i))**dimension,"size: "+str(domain_size[0]/3/3**i))
116 tree_matrix=[None]*total_level
117 tree_patches=[None]*total_level
118 #print(tree_matrix)
119
120 #calculate the tree matrices
121 for size, offsets in size_groups.items():
122 size_tuple = tuple(map(float, size.split()))
123 level=int( math.log( int(round_sig(domain_size[0]/size_tuple[0],1)), 3) )
124 matrix_size=(3**level)
125 #print(level, matrix_size)
126
127 matrix=np.zeros((matrix_size, matrix_size, matrix_size), dtype=np.ubyte)
128 for offset in offsets:
129 offset_tuple = tuple(map(float, offset.split()))
130 index=[-1,-1,-1]
131 for i in range(len(offset_tuple)):
132 index[i]=round((offset_tuple[i]-domain_offset[i])/size_tuple[i])
133 matrix[tuple(index)]=1
134 tree_matrix[level-1]=matrix
135 tree_patches[level-1]=len(offsets)
136
137 for i in range(total_level):
138 print("level "+str(i)+":",tree_matrix[i].shape)
139
140 #We calculate the total amount of leaves, we set tree entry with max (255) to show it is a leaf
141 print("="*40)
142 leaves_count=0
143 for level in range(total_level):
144 for i in range(3**(level+1)):
145 for j in range(3**(level+1)):
146 for k in range(3**(level+1)):
147 if tree_matrix[level][i][j][k]==1:
148 if level == total_level-1:
149 leaves_count=leaves_count+1
150 tree_matrix[level][i][j][k]=255
151 elif tree_matrix[level+1][3*i][3*j][3*k]==0:
152 leaves_count=leaves_count+1
153 tree_matrix[level][i][j][k]=255
154 #print("Cumulated leaves:", leaves_count)
155
156 print("Total leaves:", leaves_count)
157 target_size=int(leaves_count/subtree_number)
158 print("Subtree number:", subtree_number, "Expected subtree size:",target_size)
159
160 index_map=read_SFC(folder_path+'/'+file_path, domain_offset, domain_size)
161
162 '''
163 for i in range(len(index_map)):
164 print(index_map[i], end=' ')
165 if (i<len(index_map)-1):
166 if index_map[i][0] != index_map[i+1][0]:
167 print(" ")
168 '''
169
170 current_subtree_label=2 #0 for no entry, 1 for non-leaf node, 255 for leaf node, so start with 2
171 current_subtree_size=0
172 for current_node in index_map:
173 current_node_flag=tree_matrix[current_node[0]-1][current_node[1]][current_node[2]][current_node[3]]
174 if current_node_flag==1:
175 tree_matrix[current_node[0]-1][current_node[1]][current_node[2]][current_node[3]]=current_subtree_label
176 elif current_node_flag==255:
177 tree_matrix[current_node[0]-1][current_node[1]][current_node[2]][current_node[3]]=current_subtree_label
178 current_subtree_size=current_subtree_size+1
179
180 if current_subtree_size >= target_size:
181 current_subtree_label=current_subtree_label+1
182
183
184if __name__ == "__main__":
185 main()
186
read_SFC(file_path, domain_offset, domain_size)
read_patches(file_path, size_groups)
round_sig(x, sig)