Peano
Loading...
Searching...
No Matches
DynamicAMR.py
Go to the documentation of this file.
1# This file is part of the ExaHyPE2 project. For conditions of distribution and
2# use, please see the copyright notice at www.peano-framework.org
3import peano4
4import exahype2
5import jinja2
6
7
9
10
12 """
13
14 The ExaHyPE 2 Finite Volume handling of (dynamically) adaptive meshes
15
16 This class is basically a plain copy of the DynamicAMR action set
17 from the toolbox. However, we have to ensure that we also set the
18 update markers appropriately such that restricted data are taken
19 into account. This action set thus has to be studied in combination
20 with the ProjectPatchOntoFaces action set which is very similar and
21 also enriches the toolbox version by this marker aspect.
22
23 """
24
25
26 def __init__(self,
27 solver,
28 interpolation,
29 restriction):
30 """
31 Construct object
32
33 Please consult exahype2.solvers.rkfd.actionsets.DynamicAMR's class
34 documentation of details.
35
36 """
37 super( DynamicAMR, self ).__init__(
38 patch = solver._patch,
39 patch_overlap_interpolation = solver._patch_overlap_old,
40 patch_overlap_restriction = solver._patch_overlap_update,
41 interpolation_scheme = interpolation,
42 restriction_scheme = restriction,
43 clear_guard = solver._provide_face_data_to_compute_kernels_default_guard(),
44 interpolate_guard = solver._provide_face_data_to_compute_kernels_default_guard() + """ and
45 repositories::""" + solver.get_name_of_global_instance() + """.getSolverState()!=""" + solver._name + """::SolverState::GridInitialisation
46""",
47 restrict_guard = solver._provide_face_data_to_compute_kernels_default_guard(),
48 additional_includes = """
49#include "../repositories/SolverRepository.h"
50"""
51)
52
53 self.d[ "SOLVER_INSTANCE" ] = solver.get_name_of_global_instance()
54 self.d[ "FINE_GRID_FACE_ACCESSOR_INTERPOLATION" ] = "fineGridFace" + solver._name
55 self.d[ "FINE_GRID_FACE_ACCESSOR_INTERPOLATION" ] = "fineGridFace" + solver._name
56 self.d[ "COARSE_GRID_FACE_ACCESSOR_INTERPOLATION" ] = "coarseGridFaces" + solver._name
57 self.d[ "FINE_GRID_FACE_ACCESSOR_RESTRICTION" ] = "fineGridFace" + solver._name
58 self.d[ "COARSE_GRID_FACE_ACCESSOR_RESTRICTION" ] = "coarseGridFaces" + solver._name
59
60 """
61
62 Touch first time does nothing proper. It simply clears the halo
63 layer.
64
65 """
67 if ( {{CLEAR_GUARD}} ) {
68 logTraceInWith2Arguments( "touchFaceFirstTime(...)", marker.toString(), "clear halo layer {{FINE_GRID_FACE_ACCESSOR_RESTRICTION}}" );
69
70 ::toolbox::blockstructured::clearHaloLayerAoS(
71 marker,
72 {{DOFS_PER_AXIS}},
73 {{OVERLAP}},
74 {{UNKNOWNS}},
75 {{FINE_GRID_FACE_ACCESSOR_RESTRICTION}}QUpdate.value
76 );
77
78 logTraceOut( "touchFaceFirstTime(...)" );
79 }
80"""
81
82 """
83
84 Very similar to original toolbox's routine, but this one restricts
85 into QUpdate, and leaves QOld and QNew unchanged. Furthermore to the
86 actual data restriction, we also restrict the updated flag and the
87 time face's time stamp.
88
89 """
91 if ( {{RESTRICT_GUARD}} ) {
92 logTraceInWith4Arguments( "destroyHangingFace(...)", "{{FINE_GRID_FACE_ACCESSOR_RESTRICTION}}", "{{COARSE_GRID_FACE_ACCESSOR_RESTRICTION}}", marker.getSelectedFaceNumber(), marker.toString() );
93
94 ::toolbox::blockstructured::restrictInnerHalfOfHaloLayer_AoS_{{RESTRICTION_SCHEME}}(
95 marker,
96 {{DOFS_PER_AXIS}},
97 {{OVERLAP}},
98 {{UNKNOWNS}},
99 {{FINE_GRID_FACE_ACCESSOR_RESTRICTION}}QUpdate.value,
100 {{COARSE_GRID_FACE_ACCESSOR_RESTRICTION}}QUpdate(marker.getSelectedFaceNumber()).value
101 );
102
103 bool isLeftEntryOnCoarseFaceLabel = marker.getSelectedFaceNumber() >= Dimensions;
104 double newTimeStamp = std::max( coarseGridFaces""" + solver._face_label.name + """(marker.getSelectedFaceNumber()).getUpdatedTimeStamp( isLeftEntryOnCoarseFaceLabel ? 0 : 1 ), fineGridFace""" + solver._face_label.name + """.getUpdatedTimeStamp( isLeftEntryOnCoarseFaceLabel ? 0 : 1 ));
105 coarseGridFaces""" + solver._face_label.name + """(marker.getSelectedFaceNumber()).setUpdated( isLeftEntryOnCoarseFaceLabel ? 0 : 1,true);
106 coarseGridFaces""" + solver._face_label.name + """(marker.getSelectedFaceNumber()).setUpdatedTimeStamp( isLeftEntryOnCoarseFaceLabel ? 0 : 1,newTimeStamp);
107
108 logTraceOut( "destroyHangingFace(...)" );
109 }
110"""
111
113 if ( not marker.isInteriorFaceWithinPatch() ) {
114 logTraceIn( "destroyPersistentFace(...)" );
115
116 ::toolbox::blockstructured::restrictHaloLayer_AoS_{{RESTRICTION_SCHEME}}(
117 marker,
118 {{DOFS_PER_AXIS}},
119 {{OVERLAP}},
120 {{UNKNOWNS}},
121 {{FINE_GRID_FACE_ACCESSOR_RESTRICTION}}QUpdate.value,
122 {{COARSE_GRID_FACE_ACCESSOR_RESTRICTION}}QUpdate(marker.getSelectedFaceNumber()).value
123 );
124
125 ::toolbox::blockstructured::restrictHaloLayer_AoS_{{RESTRICTION_SCHEME}}(
126 marker,
127 {{DOFS_PER_AXIS}},
128 {{OVERLAP}},
129 {{UNKNOWNS}},
130 {{FINE_GRID_FACE_ACCESSOR_RESTRICTION}}QNew.value,
131 {{COARSE_GRID_FACE_ACCESSOR_RESTRICTION}}QNew(marker.getSelectedFaceNumber()).value
132 );
133
134 ::toolbox::blockstructured::restrictHaloLayer_AoS_{{RESTRICTION_SCHEME}}(
135 marker,
136 {{DOFS_PER_AXIS}},
137 {{OVERLAP}},
138 {{UNKNOWNS}},
139 {{FINE_GRID_FACE_ACCESSOR_RESTRICTION}}QOld.value,
140 {{COARSE_GRID_FACE_ACCESSOR_RESTRICTION}}QOld(marker.getSelectedFaceNumber()).value
141 );
142
143 // A coarse face might have been non-persistent before. So it might
144 // not carry a valid boundary flag, and we have to re-analyse it and
145 // set it accordingly.
146 tarch::la::Vector<Dimensions, double> offset(DomainOffset);
147 tarch::la::Vector<Dimensions, double> size(DomainSize);
148 bool isBoundary = false;
149 for (int d=0; d<Dimensions; d++) {
150 isBoundary |= tarch::la::equals( marker.x()(d), offset(d) );
151 isBoundary |= tarch::la::equals( marker.x()(d), offset(d) + size(d) );
152 }
153 coarseGridFaces""" + exahype2.grid.UpdateFaceLabel.get_attribute_name(solver._name) + """(marker.getSelectedFaceNumber()).setBoundary( isBoundary );
154
155 // left and right
156 for (int i=0; i<2; i++) {
157 double newTimeStamp = std::max( coarseGridFaces""" + solver._face_label.name + """(marker.getSelectedFaceNumber()).getNewTimeStamp( i ), fineGridFace""" + solver._face_label.name + """.getNewTimeStamp( i ));
158 double oldTimeStamp = std::max( coarseGridFaces""" + solver._face_label.name + """(marker.getSelectedFaceNumber()).getOldTimeStamp( i ), fineGridFace""" + solver._face_label.name + """.getOldTimeStamp( i ));
159 double updatedTimeStamp = std::max( coarseGridFaces""" + solver._face_label.name + """(marker.getSelectedFaceNumber()).getUpdatedTimeStamp( i ), fineGridFace""" + solver._face_label.name + """.getUpdatedTimeStamp( i ));
160 coarseGridFaces""" + solver._face_label.name + """(marker.getSelectedFaceNumber()).setUpdated( i,true);
161 coarseGridFaces""" + solver._face_label.name + """(marker.getSelectedFaceNumber()).setNewTimeStamp( i,newTimeStamp);
162 coarseGridFaces""" + solver._face_label.name + """(marker.getSelectedFaceNumber()).setOldTimeStamp( i,oldTimeStamp);
163 coarseGridFaces""" + solver._face_label.name + """(marker.getSelectedFaceNumber()).setUpdatedTimeStamp(i,updatedTimeStamp);
164 }
165
166 logTraceOut( "destroyPersistentFace(...)" );
167 }
168"""
169
170 """
171
172 Again, a 1:1 extension of the toolbox routine which interpolates both QOld
173 and QNew. The clue here is that we treat the solution initialisation
174 separately: Here, we do not interpolate. We initialise using the solver's
175 callback themselves.
176
177 """
179 if ( {{INTERPOLATE_GUARD}} ) {
180 logTraceInWith1Argument( "createHangingFace(...)", marker.toString() );
181
182 ::toolbox::blockstructured::interpolateHaloLayer_AoS_{{INTERPOLATION_SCHEME}}(
183 marker,
184 {{DOFS_PER_AXIS}},
185 {{OVERLAP}},
186 {{UNKNOWNS}},
187 {{COARSE_GRID_FACE_ACCESSOR_INTERPOLATION}}QNew(marker.getSelectedFaceNumber()).value,
188 {{FINE_GRID_FACE_ACCESSOR_INTERPOLATION}}QNew.value
189 );
190 ::toolbox::blockstructured::interpolateHaloLayer_AoS_{{INTERPOLATION_SCHEME}}(
191 marker,
192 {{DOFS_PER_AXIS}},
193 {{OVERLAP}},
194 {{UNKNOWNS}},
195 coarseGridFaces""" + solver._name + """QOld(marker.getSelectedFaceNumber()).value,
196 fineGridFace""" + solver._name + """QOld.value
197 );
198 ::toolbox::blockstructured::interpolateHaloLayer_AoS_{{INTERPOLATION_SCHEME}}(
199 marker,
200 {{DOFS_PER_AXIS}},
201 {{OVERLAP}},
202 {{UNKNOWNS}},
203 coarseGridFaces""" + solver._name + """QNew(marker.getSelectedFaceNumber()).value,
204 fineGridFace""" + solver._name + """QNew.value
205 );
206
207 // It is important that we clear the halo layer. If we have two layers of
208 // AMR, the finest one will restrict into QUpdate (so it has to be properly
209 // initialised as 0).
210 ::toolbox::blockstructured::clearHaloLayerAoS(
211 marker,
212 {{DOFS_PER_AXIS}},
213 {{OVERLAP}},
214 {{UNKNOWNS}},
215 fineGridFace""" + solver._name + """QUpdate.value
216 );
217 const int leftRightEntry = marker.getSelectedFaceNumber()<Dimensions ? 0 : 1;
218 fineGridFace""" + solver._face_label.name + """.setNewTimeStamp(leftRightEntry,coarseGridFaces""" + solver._face_label.name + """(marker.getSelectedFaceNumber()).getNewTimeStamp(leftRightEntry));
219 fineGridFace""" + solver._face_label.name + """.setOldTimeStamp(leftRightEntry,coarseGridFaces""" + solver._face_label.name + """(marker.getSelectedFaceNumber()).getOldTimeStamp(leftRightEntry));
220
221 logTraceOut( "createHangingFace(...)" );
222 }
223 else if ( repositories::""" + solver.get_name_of_global_instance() + """.getSolverState()==""" + solver._name + """::SolverState::GridInitialisation ) {
224 /*
225
226 @todo Not required for FV, but compare to FD4 variant what has to be done
227 throughout initialisation.
228
229 logTraceInWith1Argument( "createHangingFace(...)", marker.toString() );
230
231 int normal = marker.getSelectedFaceNumber() % Dimensions;
232 dfore(i, {{DOFS_PER_AXIS}}, normal, 0) {
233 for( int j=0; j<2*{{OVERLAP}}; j++) {
234 tarch::la::Vector<Dimensions, int> dof = i;
235 dof(normal) = j;
236
237 int serialisedDoF = ::toolbox::blockstructured::serialiseVoxelIndexInOverlap(
238 dof,
239 {{DOFS_PER_AXIS}},
240 {{OVERLAP}},
241 normal
242 );
243
244 repositories::{{SOLVER_INSTANCE}}.initialCondition(
245 fineGridFace""" + solver._name + """QNew.value + serialisedDoF * {{UNKNOWNS}},
246 ::exahype2::fv::getVolumeCentre( marker.x(), marker.h(), {{DOFS_PER_AXIS}}, {{OVERLAP}}, normal, dof),
247 ::exahype2::fv::getVolumeSize( marker.h(), {{DOFS_PER_AXIS}} ),
248 true // grid grid is constructed
249 );
250 repositories::{{SOLVER_INSTANCE}}.initialCondition(
251 fineGridFace""" + solver._name + """QOld.value + serialisedDoF * {{UNKNOWNS}},
252 ::exahype2::fv::getVolumeCentre( marker.x(), marker.h(), {{DOFS_PER_AXIS}}, {{OVERLAP}}, normal, dof),
253 ::exahype2::fv::getVolumeSize( marker.h(), {{DOFS_PER_AXIS}} ),
254 true // grid grid is constructed
255 );
256 repositories::{{SOLVER_INSTANCE}}.initialCondition(
257 fineGridFace""" + solver._name + """QUpdate.value + serialisedDoF * {{UNKNOWNS}},
258 ::exahype2::fv::getVolumeCentre( marker.x(), marker.h(), {{DOFS_PER_AXIS}}, {{OVERLAP}}, normal, dof),
259 ::exahype2::fv::getVolumeSize( marker.h(), {{DOFS_PER_AXIS}} ),
260 true // grid grid is constructed
261 );
262 }
263 }
264
265 logTraceOut( "createHangingFace(...)" );
266 */
267 }
268"""
269
270 """
271
272 Very similar to default version, but this time we interpolate QOld and
273 QNew. We also clear the update field via clearHaloLayerAoS(). It is
274 important that we initialise the time step sizes properly. As we deal
275 with a persistent face, we set both the left and right time stamp from
276 the coarse face.
277
278 """
280 logTraceInWith1Argument( "createPersistentFace(...)", marker.toString() );
281
282 ::toolbox::blockstructured::interpolateHaloLayer_AoS_{{INTERPOLATION_SCHEME}}(
283 marker,
284 {{DOFS_PER_AXIS}},
285 {{OVERLAP}},
286 {{UNKNOWNS}},
287 coarseGridCell""" + solver._name + """Q.value,
288 coarseGridFaces""" + solver._name + """QOld(marker.getSelectedFaceNumber()).value,
289 fineGridFace""" + solver._name + """QOld.value
290 );
291 ::toolbox::blockstructured::interpolateHaloLayer_AoS_{{INTERPOLATION_SCHEME}}(
292 marker,
293 {{DOFS_PER_AXIS}},
294 {{OVERLAP}},
295 {{UNKNOWNS}},
296 coarseGridCell""" + solver._name + """Q.value,
297 coarseGridFaces""" + solver._name + """QNew(marker.getSelectedFaceNumber()).value,
298 fineGridFace""" + solver._name + """QNew.value
299 );
300
301 // It is important that we clear the halo layer. If we have two layers of
302 // AMR, the finest one will restrict into QUpdate (so it has to be properly
303 // initialised as 0).
304 ::toolbox::blockstructured::clearHaloLayerAoS(
305 marker,
306 {{DOFS_PER_AXIS}},
307 {{OVERLAP}},
308 {{UNKNOWNS}},
309 fineGridFace""" + solver._name + """QUpdate.value
310 );
311 fineGridFace""" + solver._face_label.name + """.setNewTimeStamp(coarseGridCell""" + solver._cell_label.name + """.getTimeStamp());
312 fineGridFace""" + solver._face_label.name + """.setOldTimeStamp(coarseGridCell""" + solver._cell_label.name + """.getTimeStamp());
313
314 logTraceOutWith1Argument( "createPersistentFace(...)", marker.toString() );
315"""
316
318 logTraceIn( "createCell(...)" );
319
320 ::toolbox::blockstructured::interpolateCell_AoS_{{INTERPOLATION_SCHEME}}(
321 marker,
322 {{DOFS_PER_AXIS}},
323 {{UNKNOWNS}},
324 {{COARSE_GRID_CELL}}.value,
325 {{FINE_GRID_CELL}}.value
326 );
327
328 ::exahype2::fv::validatePatch(
329 {{FINE_GRID_CELL}}.value,
330 {{UNKNOWNS}},
331 0, // auxiliary values. Not known here
332 {{DOFS_PER_AXIS}},
333 0, // no halo
334 std::string(__FILE__) + "(" + std::to_string(__LINE__) + "): " + marker.toString()
335 );
336
337 fineGridCell""" + solver._cell_label.name + """.setTimeStamp( coarseGridCell""" + solver._cell_label.name + """.getTimeStamp() );
338 fineGridCell""" + solver._cell_label.name + """.setTimeStepSize( coarseGridCell""" + solver._cell_label.name + """.getTimeStepSize() );
339
340 logTraceOut( "createCell(...)" );
341"""
342
344 logTraceInWith1Argument( "destroyCell(...)", marker.toString() );
345
346 ::toolbox::blockstructured::restrictCell_AoS_{{RESTRICTION_SCHEME}}(
347 marker,
348 {{DOFS_PER_AXIS}},
349 {{UNKNOWNS}},
350 {{FINE_GRID_CELL}}.value,
351 {{COARSE_GRID_CELL}}.value
352 );
353
354 // exploit the fact that we can "reuse" some FV utils here
355 ::exahype2::fv::validatePatch(
356 {{FINE_GRID_CELL}}.value,
357 {{UNKNOWNS}},
358 0, // auxiliary values. Not known here
359 {{DOFS_PER_AXIS}},
360 0, // no halo
361 std::string(__FILE__) + "(" + std::to_string(__LINE__) + "): " + marker.toString()
362 );
363
364 coarseGridCell""" + solver._cell_label.name + """.setTimeStamp( fineGridCell""" + solver._cell_label.name + """.getTimeStamp() );
365 coarseGridCell""" + solver._cell_label.name + """.setTimeStepSize( fineGridCell""" + solver._cell_label.name + """.getTimeStepSize() );
366
367 logTraceOut( "destroyCell(...)" );
368"""
369
370
372 return __name__.replace(".py", "").replace(".", "_")
373
374
375 def get_includes(self):
376 return super(DynamicAMR,self).get_includes() + """
377#include <cstring>
378#include "exahype2/fv/PatchUtils.h"
379#include "exahype2/fv/InterpolationRestriction.h"
380"""
The ExaHyPE 2 Finite Volume handling of (dynamically) adaptive meshes.
Definition DynamicAMR.py:11
__init__(self, solver, interpolation, restriction)
Construct object.
Definition DynamicAMR.py:29
get_action_set_name(self)
Return unique action set name.
get_includes(self)
Return include statements that you need.
This class assumes that you have an 2MxNxN patch on your faces.
Definition DynamicAMR.py:9