Peano
Loading...
Searching...
No Matches
Correction.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
3from .AbstractADERDGActionSet import AbstractADERDGActionSet
4from exahype2.solvers.PDETerms import PDETerms
5
6import jinja2
7import peano4.solversteps
8
9
11 """
12 The linear combination of the Runge-Kutta trials has to be projected onto
13 the faces, so we can then solve the Riemann problems. So the projection
14 happens in one grid sweep, the corresponding Riemann solve in the next one.
15 """
16
17 _Template_TouchFaceFirstTime = """
18 if ({{PREDICATE}}) {
19 const double timeStamp = std::max(
20 fineGridFace{{SOLVER_NAME}}FaceLabel.getNewTimeStamp(0),
21 fineGridFace{{SOLVER_NAME}}FaceLabel.getNewTimeStamp(1)
22 );
23
24 // Needs to declare and define timeStepSize
25 {{COMPUTE_TIME_STEP_SIZE}}
26
27 #if Dimensions == 2
28 constexpr int SpaceFaceSize = {{ORDER}} + 1;
29 #else
30 constexpr int SpaceFaceSize = ({{ORDER}} + 1) * ({{ORDER}} + 1);
31 #endif
32
33 constexpr int FluxElementsPerFace = SpaceFaceSize * {{NUMBER_OF_UNKNOWNS}};
34 constexpr int BasisElementsPerFace = SpaceFaceSize * ({{NUMBER_OF_UNKNOWNS}} + {{NUMBER_OF_AUXILIARY_VARIABLES}});
35
36 /*
37 * 2d: 0,1,2,3 -> 0,2,1,3
38 * 3d: 0,1,2,3,4,5 -> 0,3,1,4,2,5
39 */
40 {{CORRECTOR_COMPUTATION_PRECISION}}* FL = fineGridFace{{SOLVER_NAME}}QFluxEstimates.value;
41 {{CORRECTOR_COMPUTATION_PRECISION}}* FR = fineGridFace{{SOLVER_NAME}}QFluxEstimates.value + FluxElementsPerFace;
42 {{CORRECTOR_COMPUTATION_PRECISION}}* QL = fineGridFace{{SOLVER_NAME}}QEstimates.value;
43 {{CORRECTOR_COMPUTATION_PRECISION}}* QR = fineGridFace{{SOLVER_NAME}}QEstimates.value + BasisElementsPerFace;
44 const int direction = marker.getSelectedFaceNumber() % Dimensions;
45 const int faceNumber = marker.getSelectedFaceNumber();
46 const bool isBoundary = fineGridFace{{SOLVER_NAME}}FaceLabel.getBoundary();
47 tarch::la::Vector<Dimensions,double> faceCentre = marker.x();
48
49 {{RIEMANN_SOLVER}}
50 }
51"""
52
53 _Template_TouchCellFirstTime = """
54 if ({{PREDICATE}}) {
55 const double timeStamp = fineGridCell{{SOLVER_NAME}}CellLabel.getTimeStamp();
56
57 // Reuse the same timeStepSize from the predictor
58 const double timeStepSize = fineGridCell{{SOLVER_NAME}}CellLabel.getTimeStepSize();
59
60 {{SOLUTION_STORAGE_PRECISION}}* luh = fineGridCell{{UNKNOWN_IDENTIFIER}}.value;
61
62 {{CORRECTOR_ALLOCATIONS}}
63
64 ::exahype2::CellData<{{SOLUTION_STORAGE_PRECISION}}, {{CORRECTOR_COMPUTATION_PRECISION}}> cellData(
65 fineGridCell{{UNKNOWN_IDENTIFIER}}.value,
66 marker.x(),
67 marker.h(),
68 timeStamp,
69 timeStepSize,
70 nullptr
71 );
72
73 for (int d = 0; d < Dimensions; d++) {
74 const int direction = d;
75
76 // Negative face
77 if (!fineGridFaces{{SOLVER_NAME}}FaceLabel(d).getIsHanging()) {
78 // If above hanging face, the Riemann fluxes have been received from the other side and are therefore on that side.
79 {{CORRECTOR_COMPUTATION_PRECISION}}* FIn = fineGridFaces{{UNKNOWN_IDENTIFIER}}FluxEstimates(d).value +
80 (fineGridFaces{{SOLVER_NAME}}FaceLabel(d).getAboveHanging() ? 0 : fluxElementsPerFace);
81
82 const int orientation = 0;
83
84 {{FACE_INTEGRAL}}
85 }
86
87 // Positive face
88 if (!fineGridFaces{{SOLVER_NAME}}FaceLabel(d + Dimensions).getIsHanging()) {
89 // If above hanging face, the Riemann fluxes have been received from the other side and are therefore on that side.
90 {{CORRECTOR_COMPUTATION_PRECISION}}* FIn = fineGridFaces{{UNKNOWN_IDENTIFIER}}FluxEstimates(d + Dimensions).value +
91 (fineGridFaces{{SOLVER_NAME}}FaceLabel(d+Dimensions).getAboveHanging() ? fluxElementsPerFace : 0);
92
93 const int orientation = 1;
94
95 {{FACE_INTEGRAL}}
96 }
97 } // for d
98
99 {{POSTPROCESS_UPDATED_PATCH}}
100
101 {{COMPUTE_NEW_TIME_STEP_SIZE}}
102
103 fineGridCell{{SOLVER_NAME}}CellLabel.setTimeStamp(timeStamp + timeStepSize);
104 fineGridCell{{SOLVER_NAME}}CellLabel.setHasUpdated(true);
105
106 repositories::{{SOLVER_INSTANCE}}.update(newTimeStepSize, timeStamp+timeStepSize, marker.h()(0));
107 }
108"""
109
110 _Template_RiemannSolver = """
111 kernels::{{SOLVER_NAME}}::riemannSolver<{{CORRECTOR_COMPUTATION_PRECISION}}>(
112 repositories::{{SOLVER_INSTANCE}},
113 FL,
114 FR,
115 QL,
116 QR,
117 timeStamp,
118 timeStepSize,
119 faceCentre,
120 marker.h(),
121 direction
122 );
123"""
124
125 _Template_CustomRiemannSolver = """
126 repositories::{{SOLVER_INSTANCE}}.riemannSolver(
127 FL,
128 FR,
129 QL,
130 QR,
131 timeStamp,
132 timeStepSize,
133 faceCentre,
134 marker.h(),
135 direction,
136 isBoundary,
137 faceNumber
138 );
139"""
140
141 _Template_FaceIntegral = """
142 const double inverseDxDirection = 1.0 / marker.h()[d];
143 kernels::{{SOLVER_NAME}}::faceIntegral(
144 cellData.QIn[0],
145 FIn,
146 direction,
147 orientation,
148 inverseDxDirection,
149 timeStepSize
150 );
151"""
152
153 _Template_CorrectorAllocations = """
154 const int fluxElementsPerFace = kernels::{{SOLVER_NAME}}::getBndFluxSize();
155"""
156
157 def __init__(self, solver, guard):
158 """
159 guard_project: String (C++ code)
160 Predicate which controls if the solution is actually projected
161
162 guard_safe_old_time_step: String (C++ code)
163 Predicate which controls if the projection should be copied into
164 the old solution and the time step should also be moved over
165 """
166 super(Correction, self).__init__(solver)
167
168 self._guard = guard
169 self._riemann_guard = guard
170
172 solver._riemann_solver_implementation != PDETerms.None_Implementation
173 )
174 self._is_linear = solver._is_linear
175
176 def get_body_of_operation(self, operation_name):
177 result = ""
178 d = {}
179 self._solver._init_dictionary_with_default_parameters(d)
180 self._solver.add_entries_to_text_replacement_dictionary(d)
181 if (
182 operation_name
183 == peano4.solversteps.ActionSet.OPERATION_TOUCH_FACE_FIRST_TIME
184 ):
185 d["PREDICATE"] = self.riemann_guard
187 d["RIEMANN_SOLVER"] = jinja2.Template(
189 ).render(**d)
190 else:
191 d["RIEMANN_SOLVER"] = jinja2.Template(
193 ).render(**d)
194 result = jinja2.Template(self._Template_TouchFaceFirstTime).render(**d)
195 if (
196 operation_name
197 == peano4.solversteps.ActionSet.OPERATION_TOUCH_CELL_FIRST_TIME
198 ):
199 d["PREDICATE"] = self.guard
200 d["CORRECTOR_ALLOCATIONS"] = jinja2.Template(
202 ).render(**d)
203 d["FACE_INTEGRAL"] = jinja2.Template(self._Template_FaceIntegral).render(
204 **d
205 )
206 result = jinja2.Template(self._Template_TouchCellFirstTime).render(**d)
207 pass
208 return result
209
211 return __name__.replace(".py", "").replace(".", "_")
212
213 def get_includes(self):
214 return (
215 super(Correction, self).get_includes()
216 + """
217#include "exahype2/CellData.h"
218#include "kernels/"""
219 + self._solver._name
220 + """/CellData.h"
221#include "kernels/"""
222 + self._solver._name
223 + """/FaceIntegral.h"
224#include "kernels/"""
225 + self._solver._name
226 + """/RiemannSolver.h"
227#include "kernels/"""
228 + self._solver._name
229 + """/MaxScaledEigenvalue.h"
230"""
231 )
The linear combination of the Runge-Kutta trials has to be projected onto the faces,...
Definition Correction.py:10
get_includes(self)
Return include statements that you need.
__init__(self, solver, guard)
guard_project: String (C++ code) Predicate which controls if the solution is actually projected
get_body_of_operation(self, operation_name)
Return actual C++ code snippets to be inserted into C++ code.
get_action_set_name(self)
You should replicate this function in each subclass, so you get meaningful action set names (otherwis...