9 Write a patch with halo onto the overlaps of all of its faces
11 Counterpart of ReconstructPatchWithHalo: That action set gathers a cell's
12 NxNxN patch and the 2MxNxN overlaps of its faces into one patch with halo
13 of (N+2M)x(N+2M)x(N+2M) entries. This action set takes such a patch with
14 halo and writes it back onto the face overlaps. Different to
15 ProjectPatchOntoFaces, it writes both halves of each overlap: the half
16 inside the cell from the patch, and the half outside of the cell from the
17 halo. Afterwards, the overlaps hold exactly the data the patch with halo
18 has been reconstructed from. The corners of the halo are not used.
20 The action set is used to restore the face data from a checkpoint
21 (@ref exahype2.api.blockstructured.LoadCheckpoint.LoadCheckpoint): Along the
22 domain boundary, the outer half of each overlap holds the ghost data. A
23 projection from the patch alone cannot restore it.
25 Faces between two cells receive their data from both cells. If the patches
26 with halo are consistent, as they are in a checkpoint, both cells write the
35 additional_includes=""):
38 @param patch_with_halo: peano4.api.datamodel.Patch
39 Cell data of (N+2M)^d entries which is projected.
41 @param patch_overlap: peano4.api.datamodel.Patch
42 Face data of 2M x N^(d-1) entries which is written.
45 C++ predicate. The action set only projects cells for which it holds.
47 @param additional_includes: str
48 Further includes the generated code needs, e.g. for the guard.
51 super(ProjectPatchWithHaloOntoFaces, self).
__init__(descend_invocation_order=1, parallel=
False)
53 if patch_overlap.dim[0] % 2 != 0:
54 raise Exception(
"Patch associated to face has to have even number of cells. Otherwise, it is not a symmetric overlap.")
55 if patch_with_halo.dim[0] != patch_overlap.dim[1] + patch_overlap.dim[0]:
56 raise Exception(
"patch_with_halo has to hold the face overlap's tangential extent plus its full width per axis.")
59 self.
unknowns = int(patch_with_halo.no_of_unknowns)
61 self.
overlap = int(patch_overlap.dim[0] // 2)
70 return __name__.replace(
".py",
"").replace(
".",
"_")
76 if operation_name != ActionSet.OPERATION_TOUCH_CELL_FIRST_TIME:
79 logTraceInWith1Argument( "touchCellFirstTime(...)", marker.toString() );
81 constexpr int Unknowns = {self.unknowns};
82 constexpr int DoFsPerAxis = {self.dofs_per_axis};
83 constexpr int Overlap = {self.overlap};
84 constexpr int EntriesPerAxisHalo = DoFsPerAxis + 2 * Overlap;
86 // Index of an entry within a face overlap with 2*Overlap entries along the
87 // normal and DoFsPerAxis entries along all other axes
88 auto serialiseOverlapIndex = [](const tarch::la::Vector<Dimensions,int>& overlapCell, int normal) {{
91 for (int d=0; d<Dimensions; d++) {{
92 result += overlapCell(d) * base;
93 base *= (d==normal) ? 2*Overlap : DoFsPerAxis;
98 const double* patchWithHalo = fineGridCell{self.patch_with_halo}.value;
100 for (int d=0; d<Dimensions; d++) {{
101 dfore(k,DoFsPerAxis,d,0) {{
102 for (int j=0; j<2*Overlap; j++) {{
103 tarch::la::Vector<Dimensions,int> overlapCell = k;
105 const int overlapCellSerialised = serialiseOverlapIndex(overlapCell,d);
107 // Left/bottom face: entries 0 to 2*Overlap-1 along d of the patch with halo
108 tarch::la::Vector<Dimensions,int> patchCell = k + tarch::la::Vector<Dimensions,int>(Overlap);
110 int patchCellSerialised = peano4::utils::dLinearised(patchCell,EntriesPerAxisHalo);
111 for (int unknown=0; unknown<Unknowns; unknown++) {{
112 fineGridFaces{self.patch_overlap}(d).value[overlapCellSerialised*Unknowns+unknown] = patchWithHalo[patchCellSerialised*Unknowns+unknown];
115 // Right/top face: entries DoFsPerAxis to DoFsPerAxis+2*Overlap-1 along d
116 patchCell(d) = DoFsPerAxis + j;
117 patchCellSerialised = peano4::utils::dLinearised(patchCell,EntriesPerAxisHalo);
118 for (int unknown=0; unknown<Unknowns; unknown++) {{
119 fineGridFaces{self.patch_overlap}(d+Dimensions).value[overlapCellSerialised*Unknowns+unknown] = patchWithHalo[patchCellSerialised*Unknowns+unknown];
125 logTraceOut( "touchCellFirstTime(...)" );
129 if operation_name == ActionSet.OPERATION_TOUCH_CELL_FIRST_TIME:
138#include "peano4/utils/Loop.h"
Write a patch with halo onto the overlaps of all of its faces.
__init__(self, patch_with_halo, patch_overlap, guard="true", additional_includes="")
user_should_modify_template(self)
Is the user allowed to modify the output.
get_body_of_operation(self, operation_name)
Return actual C++ code snippets to be inserted into C++ code.
get_guard_of_operation(self, operation_name)
Return the guard of an operation.
get_constructor_body(self)
Define a tailored constructor body.
get_attributes(self)
Return attributes as copied and pasted into the generated class.
get_includes(self)
Return include statements that you need.
get_action_set_name(self)
Return unique action set name.
Action set (reactions to events)