Peano
Loading...
Searching...
No Matches
Decomposition.py
Go to the documentation of this file.
1# This file is part of the ExaHyPE2 project. For conditions of decomposition and
2# use, please see the copyright notice at www.peano-framework.org
3
4from ..Tree import Tree
5from .Utils import no_split_result
6
7
8def equidistant_splitting(peano_tree: Tree,
9 number_of_subtrees: int,
10 verbose=False,
11 ):
12
13 if number_of_subtrees <= 1:
14 return no_split_result(
15 f"No splitting requested (number_of_subtrees = {number_of_subtrees})."
16 )
17
18 total_leaves = peano_tree.number_of_leaves
19
20 if total_leaves == 0:
21 print("No leaf nodes found in subtree 0 to split.")
22 return (False, [])
23
24 # Calculate how many leaves each subtree should get for balanced decomposition
25 leaves_per_subtree, remaining_leaves = divmod(total_leaves, number_of_subtrees)
26
27 # Create decomposition plan
28 decomposition = [
29 leaves_per_subtree + (1 if subtree_id < remaining_leaves else 0)
30 for subtree_id in range(number_of_subtrees)
31 ]
32
33 if verbose:
34 print(
35 f"Splitting tree '{peano_tree._name}' into "
36 f"{number_of_subtrees} subtrees (staged workflow)"
37 )
38 print(f"Found {total_leaves} leaf nodes across all levels for decomposition")
39 print(f"Target decomposition: {leaves_per_subtree} leaves per subtree, {remaining_leaves} extra leaves that have to be distributed among other trees")
40 print(f"Decomposition plan: {decomposition}")
41
42 return decomposition
43
44
45def quantised_splitting(peano_tree: Tree,
46 number_of_subtrees: int,
47 dimension: int,
48 verbose=False,
49 ):
50 """!
51
52 Quantised splitting
53
54 This splitting starts from a perfect splitting as we find it in
55 equidistant_splitting(), but then it picks partitions of the type
56 @f$ 1 \\cdot 3^{kd}, 2 \\cdot 3^{kd}, ..., (3^d-1) \\cdot 3^{kd}, 1 \\cdot 3^{(k+1)d}, 2 \\cdot 3^{(k+1)d}, ... @f$
57
58 ## Implementation
59
60 - Determine optimal number of splittings
61 - Introduce a residual counter. As the number of leaves typically does not
62 exactly fit to number_of_subtrees, this is the remainder of the modulo
63 division.
64 - Identify smallest chunk from sequence above that literally just fits.
65 - Add the cells that should have been added to this chunk (due to the
66 optimal decomposition) but cannot be added (due to the quantisation from
67 the sequence above) to the residual.
68 - Next step, increase the optimum threshold by the residual.
69
70 """
71
72 if number_of_subtrees <= 1:
73 return no_split_result(
74 f"No splitting requested (number_of_subtrees = {number_of_subtrees})."
75 )
76
77 total_leaves = peano_tree.number_of_leaves
78
79 if total_leaves == 0:
80 print("No leaf nodes found in subtree 0 to split.")
81 return (False, [])
82
83 # Calculate how many leaves each subtree should get for balanced decomposition
84 optimal_leaves_per_subtree, residual_leaves = divmod(total_leaves, number_of_subtrees)
85
86 # Create decomposition plan
87 decomposition = []
88 for i in range(number_of_subtrees):
89 current_chunk = 0
90 current_step_size = 3**dimension
91 while (current_chunk<optimal_leaves_per_subtree+residual_leaves):
92 if current_chunk == current_step_size * 3**dimension:
93 current_step_size *= 3**dimension
94 current_chunk += current_step_size
95 current_chunk -= current_step_size
96 residual_leaves += optimal_leaves_per_subtree - current_chunk
97 assert residual_leaves>=0, "residual leaves = {}".format(residual_leaves)
98 decomposition.append(current_chunk)
99 print(f"append {current_chunk} and maintain residual {residual_leaves} with optimum {optimal_leaves_per_subtree}. New target {optimal_leaves_per_subtree+residual_leaves}")
100
101 decomposition[-1] += residual_leaves
102
103 assert sum(decomposition)==total_leaves, "{} vs {}".format(sum(decomposition),total_leaves)
104
105 if verbose:
106 print(
107 f"Splitting tree '{peano_tree._name}' into "
108 f"{number_of_subtrees} subtrees (staged workflow)"
109 )
110 print(f"Found {total_leaves} leaf nodes across all levels for decomposition")
111 print(f"Target decomposition: {optimal_leaves_per_subtree} leaves per subtree")
112 print(f"Decomposition plan: {decomposition}")
113
114 return decomposition
quantised_splitting(Tree peano_tree, int number_of_subtrees, int dimension, verbose=False)
Quantised splitting.