Peano
Loading...
Searching...
No Matches
HandleBoundary.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
4
5import jinja2
6import peano4.solversteps
7
8
10 """
11 The linear combination of the Runge-Kutta trials has to be projected onto
12 the faces, so we can then solve the Riemann problems. So the projection
13 happens in one grid sweep, the corresponding Riemann solve in the next one.
14 """
15
16 _Template_HandleBoundary = """
17 if ({{PREDICATE}}) {
18 const double timeStamp = fineGridFace{{SOLVER_NAME}}FaceLabel.getNewTimeStamp(marker.getSelectedFaceNumber() < Dimensions ? 1 : 0);
19
20 // Needs to declare and define timeStepSize
21 {{COMPUTE_TIME_STEP_SIZE}}
22
23 #if Dimensions == 2
24 constexpr int SpaceFaceSize = {{ORDER}} + 1;
25 #else
26 constexpr int SpaceFaceSize = ({{ORDER}} + 1) * ({{ORDER}} + 1);
27 #endif
28
29 constexpr int FluxElementsByFace = SpaceFaceSize * {{NUMBER_OF_UNKNOWNS}};
30 constexpr int BasisElementsByFace = SpaceFaceSize * ({{NUMBER_OF_UNKNOWNS}} + {{NUMBER_OF_AUXILIARY_VARIABLES}});
31
32 const int normal = marker.getSelectedFaceNumber() % Dimensions;
33 const bool isLeftFace = marker.getSelectedFaceNumber() < Dimensions;
34
35 {{CORRECTOR_COMPUTATION_PRECISION}}* FIn = fineGridFace{{UNKNOWN_IDENTIFIER}}FluxEstimates.value + (!isLeftFace ? 0 : FluxElementsByFace);
36 {{CORRECTOR_COMPUTATION_PRECISION}}* FOut = fineGridFace{{UNKNOWN_IDENTIFIER}}FluxEstimates.value + (!isLeftFace ? FluxElementsByFace : 0);
37 {{CORRECTOR_COMPUTATION_PRECISION}}* QIn = fineGridFace{{UNKNOWN_IDENTIFIER}}Estimates.value + (!isLeftFace ? 0 : BasisElementsByFace);
38 {{CORRECTOR_COMPUTATION_PRECISION}}* QOut = fineGridFace{{UNKNOWN_IDENTIFIER}}Estimates.value + (!isLeftFace ? BasisElementsByFace : 0);
39
40 tarch::la::Vector<Dimensions, double> faceOffset = marker.x() - 0.5 * marker.h();
41 faceOffset(normal) += 0.5 * marker.h()(normal);
42
43 dfore(dof, {{ORDER}} + 1, normal, 0) {
44 tarch::la::Vector<Dimensions, double> nodePosition;
45 int dofSerialised = 0;
46 int basis = 1;
47 for (int d = 0; d < Dimensions; d++) {
48 nodePosition(d) = faceOffset(d);
49 nodePosition(d) += (d == normal) ? 0.0 : kernels::{{SOLVER_NAME}}::Quadrature<{{SOLUTION_STORAGE_PRECISION}}>::nodes[dof(d)] * marker.h()(d);
50 dofSerialised += (d == normal) ? 0 : dof(d) * basis;
51 basis *= (d == normal) ? 1 : ({{ORDER}} + 1);
52 }
53
54 repositories::{{SOLVER_INSTANCE}}.boundaryConditions(
55 QIn + dofSerialised * ({{NUMBER_OF_UNKNOWNS}} + {{NUMBER_OF_AUXILIARY_VARIABLES}}),
56 QOut + dofSerialised * ({{NUMBER_OF_UNKNOWNS}} + {{NUMBER_OF_AUXILIARY_VARIABLES}}),
57 nodePosition,
58 marker.h(),
59 timeStamp,
60 normal
61 );
62
63 {% if USE_FLUX %}
64 repositories::{{SOLVER_INSTANCE}}.flux(
65 QOut + dofSerialised * ({{NUMBER_OF_UNKNOWNS}} + {{NUMBER_OF_AUXILIARY_VARIABLES}}),
66 nodePosition,
67 marker.h(),
68 timeStamp,
69 timeStepSize,
70 normal,
71 FOut + dofSerialised * {{NUMBER_OF_UNKNOWNS}}
72 );
73 {% else %}
74 // Not formally correct, should still be able to contain contributions from things such as sources, point sources etc.
75 // These must now be handled through the boundary conditions.
76 std::fill_n(FOut + dofSerialised * {{NUMBER_OF_UNKNOWNS}}, {{NUMBER_OF_UNKNOWNS}}, 0.0);
77 {% endif %}
78 }
79 }
80"""
81
82 def __init__(self, solver, guard):
83 """
84 guard_project: String (C++ code)
85 Predicate which controls if the solution is actually projected
86
87 guard_safe_old_time_step: String (C++ code)
88 Predicate which controls if the projection should be copied into
89 the old solution and the time step should also be moved over
90 """
91 super(HandleBoundary, self).__init__(solver)
92 self._guard = guard
93
94 def get_body_of_operation(self, operation_name):
95 result = ""
96 if (
97 operation_name
98 == peano4.solversteps.ActionSet.OPERATION_TOUCH_FACE_FIRST_TIME
99 ):
100 d = {}
101 self._solver._init_dictionary_with_default_parameters(d)
102 self._solver.add_entries_to_text_replacement_dictionary(d)
103 d["PREDICATE"] = self._guard
104 result += jinja2.Template(self._Template_HandleBoundary).render(**d)
105 return result
106
108 return __name__.replace(".py", "").replace(".", "_")
109
110 def get_includes(self):
111 return (
112 super(HandleBoundary, self).get_includes()
113 + """
114#include "kernels/"""
115 + self._solver._name
116 + """/Quadrature.h"
117 """
118 )
The linear combination of the Runge-Kutta trials has to be projected onto the faces,...
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_action_set_name(self)
You should replicate this function in each subclass, so you get meaningful action set names (otherwis...
get_body_of_operation(self, operation_name)
Return actual C++ code snippets to be inserted into C++ code.