7 Data structure for adaptive mesh trees in Peano load balancing.
9 This class represents adaptive mesh trees as sequences of grid levels,
10 where each level is stored as a 2D or 3D array. The tree structure is
11 designed to support offline decomposition and load balancing analysis.
13 ## Tree Structure Overview
15 The main content of this class is a series of 2D or 3D arrays with dimension sizes
16 of 3^(level+1), where level ranges from 1 to the maximum depth of the tree. Each entry
17 in the arrays is a tuple of 2 numbers:
19 - **Weight**: 1 if the cell exists, 0 if it doesn't (enables representation of adaptive meshes)
20 - **Subtree ID**: Integer indicating which compute resource/subtree owns the cell
22 ## Data Representation Examples
24 ### 2D Example: Uniform 2-level tree with 4 subtrees
35 {(1,0), (1,0), (1,0), (1,0), (1,0), (1,0), (1,1), (1,1), (1,1),
36 (1,0), (1,0), (1,0), (1,0), (1,0), (1,0), (1,1), (1,1), (1,1),
37 (1,0), (1,0), (1,0), (1,0), (1,0), (1,0), (1,1), (1,1), (1,1),
38 (1,1), (1,1), (1,1), (1,1), (1,1), (1,1), (1,3), (1,3), (1,3),
39 (1,1), (1,1), (1,1), (1,1), (1,1), (1,1), (1,3), (1,3), (1,3),
40 (1,1), (1,1), (1,1), (1,1), (1,1), (1,1), (1,3), (1,3), (1,3),
41 (1,2), (1,2), (1,2), (1,2), (1,2), (1,2), (1,3), (1,3), (1,3),
42 (1,2), (1,2), (1,2), (1,2), (1,2), (1,2), (1,3), (1,3), (1,3),
43 (1,2), (1,2), (1,2), (1,2), (1,2), (1,2), (1,3), (1,3), (1,3)}
46 ### Adaptive Mesh Representation
48 For adaptive meshes where some regions are not refined, entries have weight 0:
50 Level 1: {(1,0), (0,0), (1,0) # Middle cell not refined
54 Level 2: Corresponding 9x9 array with zeros in the middle 3x3 block
59 - **Hierarchical Structure**: Each level refines the previous by factor of 3 in each dimension
60 - **Adaptive Support**: Zero weights represent non-existent cells in adaptive meshes
61 - **Load Balancing Ready**: Subtree IDs enable domain decomposition analysis
63 ## Usage in Load Balancing
65 This data structure supports various load balancing operations:
67 1. **Tree Analysis**: Count leaf nodes, analyze refinement patterns
68 2. **Splitting Strategies**: Redistribute subtree assignments for load balancing
69 3. **Visualization**: Generate spatial representations of tree structure
70 4. **Export**: Create YAML outputs for integration with Peano's hardcoded load balancer
74 - **2D**: Arrays use (a,b) indexing where a,b ∈ [0, 3^(level+1)-1]
75 - **3D**: Arrays use (a,b,c) indexing where a,b,c ∈ [0, 3^(level+1)-1]
76 - **Level Numbering**: Levels start from 0 (coarsest) to max_level-1 (finest)
77 - **Array Sizes**: Level k has size 3^(k+1) in each dimension
81 - The lowest level is 1 with size 3x3 (2D) or 3x3x3 (3D)
82 - All arrays are stored as numpy arrays with dtype=object for tuple storage
83 - Tree metadata (leaf count, split patterns) is automatically updated after modifications
84 - Domain offset and size define the physical coordinate mapping
88 This class works with:
89 - `GridPatchFileReader`: Reads Peano grid files into Tree format
90 - `RegularGridGenerator`: Creates artificial uniform trees for testing
91 - `SplitTrees`: Implements splitting algorithms for load balancing
92 - `TreeVisualizer`: Generates visual representations of tree structures
97 # Create a tree from artificial regular grid
98 tree = RegularGridGenerator("test", max_level=3, dimension=2)
100 # Apply load balancing splitting
101 split_tree = split_leaves(tree, number_of_splits=3)
103 # Generate visualization
104 TreeVisualizer(split_tree, dimension=2, filename="balanced_tree")
107 generate_tree_yaml(split_tree, "output.yaml")
111 def __init__(self, name, dimension, domain_offset, domain_size):
113 Initialize a new Tree object.
116 name (str): Descriptive name for the tree (e.g., "RegularGrid" or filename)
117 dimension (int): Spatial dimension (2 for 2D, 3 for 3D)
118 domain_offset (tuple): Physical coordinates of domain origin
119 domain_size (tuple): Physical size of domain in each dimension
138Peano Tree Structure From """ + self.
_name +
"""
175 new_level_array = np.empty((size, size), dtype=object)
176 for a
in range(size):
177 for b
in range(size):
178 new_level_array[a][b]=(0,0)
180 new_level_array = np.empty((size, size, size), dtype=object)
181 for a
in range(size):
182 for b
in range(size):
183 for c
in range(size):
184 new_level_array[a][b][c]=(0,0)
201 for a
in range(3**(level+1)):
202 for b
in range(3**(level+1)):
203 if input_level_arrays[a][b]==1:
204 self.
_tree_arrays[level][a][b] = (input_level_arrays[a][b], subtree_id)
206 for a
in range(3**(level+1)):
207 for b
in range(3**(level+1)):
208 for c
in range(3**(level+1)):
209 if input_level_arrays[a][b][c]==1:
210 self.
_tree_arrays[level][a][b][c] = (input_level_arrays[a][b][c], subtree_id)
231 for a
in range(3**(level+1)):
232 for b
in range(3**(level+1)):
241 for a
in range(3**(level+1)):
242 for b
in range(3**(level+1)):
243 for c
in range(3**(level+1)):
Data structure for adaptive mesh trees in Peano load balancing.
read_in_tree_from_artificial(self, input_artificial_arrays, max_level, weighted=False)
read_in_level_array(self, input_level_arrays, subtree_id, level)
read_in_tree_from_arrays(self, input_tree_arrays, max_level, weighted=False)
__init__(self, name, dimension, domain_offset, domain_size)
Initialize a new Tree object.
update_split_pattern(self)