9 Reconstruct a cell patch together with its halo into a separate,
10 already-declared reconstructed_patch cell submodel.
12 This class assumes that you have an NxNxN patch within your block. It also
13 assumes that you have a 2MxNxN patch on your faces, M<N. The code
14 interprets these face-associated data as overlap with the patch, hooks
15 into touchCellFirstTime, and gathers the cell patch and its face-associated
16 overlaps into reconstructed_patch - a real, separately-declared cell
17 submodel of shape (N+2M)x(N+2M)x(N+2M) (@see ProjectPatchOntoFaces for the
18 counterpart that fills the face-associated overlap patches in the first
21 reconstructed_patch is not a scratch array this class allocates and frees
22 itself - it is a proper Peano-managed cell submodel handed in directly by
23 the caller (declared on the surrounding Task/Step the same way patch and
24 patch_overlap are), so this class never has to choose where or how to
25 allocate memory for it: it simply writes into reconstructed_patch's own
28 @see ReconstructPatchAndApplyFunctor, which extends this with an
29 additional functor invoked once the reconstruction is done.
38 add_assertions_to_halo_exchange = True,
39 additional_includes = ""
43 patch: peano4.api.datamodel.Patch
44 Patch which is to be used
46 patch_overlap: peano4.api.datamodel.Patch
47 Consult remark above about how the dimensions of this overlap
50 reconstructed_patch: peano4.api.datamodel.Patch
51 Where to write the reconstructed patch-plus-halo to - has to already be
52 declared (use_cell()) on the surrounding Task/Step, just like patch and
53 patch_overlap, and its dimensions have to be patch's plus twice
54 patch_overlap's overlap width, per axis.
56 additional_includes: str
57 Further includes this action set's generated code needs - e.g. a
58 solver's own default and user includes.
62 I use quite a lot of validitiy checks for the copied data via comparison to its self. This
63 way, I can at least spot nans. I use the dictionary entries ASSERTION_WITH_X_ARGUMENTS to
64 realise this, and they are, by default, set to Peano's assertion macros. You can redefine
68 super(ReconstructPatchWithHalo,self).
__init__(descend_invocation_order=1,parallel=
False)
70 if patch_overlap.dim[0] % 2 != 0:
71 print(
"Error: Patch associated to face has to have even number of cells. Otherwise, it is not a symmetric overlap." )
72 assert( patch_overlap.dim[0] % 2 == 0 )
73 if patch.dim[0] != patch.dim[1]:
74 print(
"Error: Can only handle square patches." )
75 assert( patch.dim[0] == patch.dim[1] )
76 if patch_overlap.dim[1] != patch.dim[0]:
77 print(
"Error: Patch of overlap and patch of cell have to match" )
78 assert( patch_overlap.dim[1] == patch.dim[0] )
79 if reconstructed_patch.dim[0] != patch.dim[0] + patch_overlap.dim[0]:
80 print(
"Error: reconstructed_patch has to be patch's plus patch_overlap's full width per axis." )
81 assert( reconstructed_patch.dim[0] == patch.dim[0] + patch_overlap.dim[0] )
100 If you inherit from this class and specialise this routine, you can add
101 more entries to the dictionary. This is important if you change the
102 actual compute kernels (templates) and use futher unknowns in there. If
103 you specialise the function, i.e. overwrite it in a subclass, please
104 ensure that you use the superclass still.
107 d[
"GUARD" ] = self.
guard
120 d[
"FACES_ACCESSOR" ] =
"fineGridFaces" + self.
overlap_name
121 d[
"CELL_ACCESSOR" ] =
"fineGridCell" + self.
patch_name
124 d[
"ASSERTION_WITH_1_ARGUMENTS" ] =
"assertion1"
125 d[
"ASSERTION_WITH_2_ARGUMENTS" ] =
"assertion2"
126 d[
"ASSERTION_WITH_3_ARGUMENTS" ] =
"assertion3"
127 d[
"ASSERTION_WITH_4_ARGUMENTS" ] =
"assertion4"
128 d[
"ASSERTION_WITH_5_ARGUMENTS" ] =
"assertion5"
129 d[
"ASSERTION_WITH_6_ARGUMENTS" ] =
"assertion6"
130 d[
"ASSERTION_WITH_7_ARGUMENTS" ] =
"assertion7"
133 d[
"ASSERTION_PREFIX_FOR_HALO" ] =
"false"
135 d[
"ASSERTION_PREFIX_FOR_HALO" ] =
"true"
143 return __name__.replace(
".py",
"").replace(
".",
"_")
150 _Template_TouchCellFirstTime_Preamble =
"""
151 auto serialisePatchIndex = [](tarch::la::Vector<Dimensions,int> overlapCell, int normal) {{
154 for (int d=0; d<Dimensions; d++) {{
155 result += overlapCell(d) * base;
160 base *= {DOFS_PER_AXIS};
166 logTraceInWith1Argument( "touchCellFirstTime(...)", marker.toString() );
168 double* oldQWithHalo = {RECONSTRUCTED_PATCH_ACCESSOR}.value;
172 _Template_TouchCellFirstTime_Fill_Patch =
"""
174 // Loop over original patch (k) and copy stuff over.
176 dfor(sourceCell,{DOFS_PER_AXIS}) {{
177 tarch::la::Vector<Dimensions,int> destinationCell = sourceCell + tarch::la::Vector<Dimensions,int>({OVERLAP});
178 int sourceCellSerialised = peano4::utils::dLinearised(sourceCell,{DOFS_PER_AXIS});
179 int destinationCellSerialised = peano4::utils::dLinearised(destinationCell,{DOFS_PER_AXIS} + 2*{OVERLAP});
180 for (int j=0; j<{UNKNOWNS}; j++) {{
181 oldQWithHalo[destinationCellSerialised*{UNKNOWNS}+j] = {CELL_ACCESSOR}.value[ sourceCellSerialised*{UNKNOWNS}+j ];
182 {ASSERTION_WITH_4_ARGUMENTS}( oldQWithHalo[destinationCellSerialised*{UNKNOWNS}+j]==oldQWithHalo[destinationCellSerialised*{UNKNOWNS}+j], sourceCell, j, "Unknown Tree Number", marker.toString() );
188 _Template_TouchCellFirstTime_Fill_Halos =
"""
190 // Bring in the auxiliary patches, i.e. befill halo
192 for(int d=0; d<Dimensions; d++) {{
193 logTraceInWith1Argument( "touchCellFirstTime(...)::loopOverFace", d );
195 // d-loop over all dimensions except d. The vector k's entry d is set
196 // to 0. We start with the left/bottom face, i.e. the one closer to the
197 // coordinate system's origin.
199 dfore(k,{DOFS_PER_AXIS},d,0) {{
200 for (int i=0; i<{OVERLAP}; i++) {{
201 tarch::la::Vector<Dimensions,int> destinationCell = k + tarch::la::Vector<Dimensions,int>({OVERLAP});
202 tarch::la::Vector<Dimensions,int> sourceCell = k;
203 destinationCell(d) = i;
206 int destinationCellSerialised = peano4::utils::dLinearised(destinationCell,{DOFS_PER_AXIS} + 2*{OVERLAP});
207 int sourceCellSerialised = serialisePatchIndex(sourceCell,d);
209 for (int j=0; j<{UNKNOWNS}; j++) {{
210 oldQWithHalo[ destinationCellSerialised*{UNKNOWNS}+j ] = {FACES_ACCESSOR}(d).value[ sourceCellSerialised*{UNKNOWNS}+j ];
211 {ASSERTION_WITH_7_ARGUMENTS}(
212 {ASSERTION_PREFIX_FOR_HALO} or
213 oldQWithHalo[ destinationCellSerialised*{UNKNOWNS}+j ]==oldQWithHalo[ destinationCellSerialised*{UNKNOWNS}+j ],
214 sourceCell, destinationCell, j, d, marker.toString(), "Unknown Tree Number", marker.toString()
218 destinationCell(d) = i+{DOFS_PER_AXIS}+{OVERLAP};
219 sourceCell(d) = i+{OVERLAP};
221 destinationCellSerialised = peano4::utils::dLinearised(destinationCell,{DOFS_PER_AXIS} + 2*{OVERLAP});
222 sourceCellSerialised = serialisePatchIndex(sourceCell,d);
223 for (int j=0; j<{UNKNOWNS}; j++) {{
224 oldQWithHalo[ destinationCellSerialised*{UNKNOWNS}+j ] = {FACES_ACCESSOR}(d+Dimensions).value[ sourceCellSerialised*{UNKNOWNS}+j ];
225 {ASSERTION_WITH_7_ARGUMENTS}(
226 {ASSERTION_PREFIX_FOR_HALO} or
227 oldQWithHalo[ destinationCellSerialised*{UNKNOWNS}+j ]==oldQWithHalo[ destinationCellSerialised*{UNKNOWNS}+j ],
228 sourceCell, destinationCell, j, d, marker.toString(), "Unknown Tree Number", marker.toString()
233 logTraceOut( "touchCellFirstTime(...)::loopOverFace" );
238 _Template_TouchCellFirstTime_Epilogue =
"""
239 logTraceOut( "touchCellFirstTime(...)" );
245 if operation_name==ActionSet.OPERATION_TOUCH_CELL_FIRST_TIME:
257 if operation_name==ActionSet.OPERATION_TOUCH_CELL_FIRST_TIME:
269#include "peano4/utils/Loop.h"
270#include "tarch/multicore/Core.h"
Reconstruct a cell patch together with its halo into a separate, already-declared reconstructed_patch...
get_guard_of_operation(self, operation_name)
Return the guard of an operation.
_add_action_set_entries_to_dictionary(self, d)
Befill dictionary.
str _Template_TouchCellFirstTime_Fill_Halos
get_action_set_name(self)
Return unique action set name.
get_body_of_operation(self, operation_name)
Return actual C++ code snippets to be inserted into C++ code.
str _Template_TouchCellFirstTime_Preamble
get_attributes(self)
Return attributes as copied and pasted into the generated class.
str _Template_TouchCellFirstTime_Epilogue
add_assertions_to_halo_exchange
get_constructor_body(self)
Define a tailored constructor body.
str _Template_TouchCellFirstTime_Fill_Patch
user_should_modify_template(self)
Is the user allowed to modify the output.
__init__(self, patch, patch_overlap, reconstructed_patch, guard="true", add_assertions_to_halo_exchange=True, additional_includes="")
patch: peano4.api.datamodel.Patch Patch which is to be used
get_includes(self)
Return include statements that you need.
Action set (reactions to events)