Peano
Loading...
Searching...
No Matches
RollOverUpdatedFaceWithSommerfeldBoundaryConditions.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 jinja2
4import peano4.api
5
6from .RollOverUpdatedFace import RollOverUpdatedFace
7from ...blockstructured.BoundaryConditions import get_boundary_conditions
8from ...blockstructured.SommerfeldBoundaryConditions import SommerfeldBoundaryConditions
9
10
12 """!
13
14 Roll over the face data, and set the ghost grid cells along the domain
15 boundary through exahype2.api.SommerfeldBoundaryConditions first
16
17 The action set replaces exahype2.api.rkfd4.actionsets.RollOverUpdatedFace
18 if the solver uses Sommerfeld boundary conditions. Such a solver has no
19 separate boundary task (exahype2.api.rkfd4.actionsets.ApplyDirichletBoundaryConditions).
20 In touchFaceLastTime(), the action set first writes the ghost grid cells
21 into the ghost half of patch_overlap_update, and then rolls over both
22 halves into patch_overlap_current_time_step like RollOverUpdatedFace.
23 Faces within the domain and faces along periodic axes are rolled over
24 unchanged. There are two variants:
25
26 - With a time_step_size, the action set advances the ghost grid cells
27 through @ref exahype2::blockstructured::applySommerfeldBoundaryConditions().
28 patch_overlap_current_time_step still holds the old solution, i.e.
29 both its halves are valid, and patch_overlap_update holds the new
30 interior solution. The projection of every Runge-Kutta stage uses
31 this variant: It advances the ghost grid cells from the time stamp of
32 the stage to the one of the next stage, i.e. time_step_size is
33 @f$ (c_{k+1}-c_k) \\Delta t @f$, or @f$ (1-c_{s-1}) \\Delta t @f$ after
34 the last stage (@ref
35 exahype2.api.rkfd4.CentralDifferencesWithRungeKutta).
36 - Without a time_step_size, the action set initialises the ghost grid cells
37 with the initial condition, i.e. it evaluates the solver's
38 initPointWisely() at their centres through
39 @ref exahype2::blockstructured::applyDirichletBoundaryConditions().
40 The grid construction uses this variant, so the first time step finds
41 valid ghost grid cells.
42
43 The C++ header documents the conditions, their discretisation and why
44 they replace the roll over. The class mirrors
45 exahype2.api.fv.actionsets.RollOverUpdatedFaceWithSommerfeldBoundaryConditions,
46 as rkfd4 does not depend on the Finite Volume package.
47
48 """
49
50 TemplateSommerfeldBoundaryConditions = jinja2.Template(
51 """
52 ::exahype2::blockstructured::applySommerfeldBoundaryConditions(
53 [](
54 const double* Q,
55 const tarch::la::Vector<Dimensions, double>& x,
56 int normal
57 ) -> double {
58 double lambdaMax;
59 repositories::{{SOLVER_INSTANCE}}.maxEigenvalue(Q, x, normal, &lambdaMax);
60 return lambdaMax;
61 },
62 [](const tarch::la::Vector<Dimensions, double>& x, double* Q) -> void {
63 repositories::{{SOLVER_INSTANCE}}.sommerfeldFarFieldSolution(x, Q);
64 },
65 marker,
66 DomainOffset,
67 DomainSize,
68 PeriodicBC,
69 {{DOFS_PER_AXIS}},
70 {{OVERLAP}},
71 {{NUMBER_OF_UNKNOWNS}},
72 {{NUMBER_OF_AUXILIARY_VARIABLES}},
73 tarch::la::Vector<Dimensions, double>({{ORIGIN}}),
74 {{TIME_STEP_SIZE}},
75 {{CURRENT_TIME_STEP_ACCESSOR}}.value,
76 {{UPDATE_ACCESSOR}}.value
77 );
78"""
79 )
80
81 TemplateInitialGhostCells = jinja2.Template(
82 """
83 ::exahype2::blockstructured::applyDirichletBoundaryConditions(
84 [](const tarch::la::Vector<Dimensions, double>& x, double t, double* Q) -> void {
85 repositories::{{SOLVER_INSTANCE}}.initPointWisely(x, Q);
86 },
87 marker,
88 DomainOffset,
89 DomainSize,
90 PeriodicBC,
91 {{DOFS_PER_AXIS}},
92 {{OVERLAP}},
93 {{NUMBER_OF_UNKNOWNS}} + {{NUMBER_OF_AUXILIARY_VARIABLES}},
94 repositories::{{SOLVER_INSTANCE}}.getMinTimeStamp(),
95 {{UPDATE_ACCESSOR}}.value
96 );
97"""
98 )
99
101 self,
102 solver,
103 patch_overlap_current_time_step,
104 patch_overlap_update,
105 guard,
106 includes,
107 origin,
108 time_step_size=None,
109 ):
110 """!
111
112 @param solver: exahype2.api.Solver
113 The solver whose maxEigenvalue(), sommerfeldFarFieldSolution() and
114 initPointWisely() are invoked.
115
116 @param patch_overlap_current_time_step: peano4.api.datamodel.Patch
117 @see RollOverUpdatedFace.
118
119 @param patch_overlap_update: peano4.api.datamodel.Patch
120 @see RollOverUpdatedFace.
121
122 @param guard: str
123 @see RollOverUpdatedFace.
124
125 @param includes: str
126 @see RollOverUpdatedFace.
127
128 @param origin: List[float]
129 Centre of the system, one entry per dimension, @ref
130 exahype2.api.blockstructured.SommerfeldBoundaryConditions.SommerfeldBoundaryConditions.get_origin().
131
132 @param time_step_size: str
133 C++ expression for the time step size by which the ghost grid cells
134 are advanced, or None to initialise the ghost grid cells with the
135 initial condition instead.
136
137 """
138 super().__init__(
139 patch_overlap_current_time_step, patch_overlap_update, guard, includes
140 )
141 self._time_step_size = time_step_size
142 self.d["SOLVER_INSTANCE"] = solver.get_name_of_global_instance()
143 self.d["NUMBER_OF_UNKNOWNS"] = str(solver.unknowns)
144 self.d["NUMBER_OF_AUXILIARY_VARIABLES"] = str(solver.auxiliary_variables)
145 self.d["ORIGIN"] = "{" + ", ".join(repr(float(x)) for x in origin) + "}"
146 self.d["TIME_STEP_SIZE"] = time_step_size
147
148 def get_body_of_operation(self, operation_name):
149 result = super().get_body_of_operation(operation_name)
150 if (
151 operation_name
152 == peano4.api.solversteps.ActionSet.OPERATION_TOUCH_FACE_LAST_TIME
153 ):
154 template = (
156 if self._time_step_size is None
158 )
159 result = template.render(**self.d) + result
160 return result
161
163 return __name__.replace(".py", "").replace(".", "_")
164
165 def get_includes(self):
166 return (
167 """
168#include "exahype2/blockstructured/DirichletBoundaryConditions.h"
169#include "exahype2/blockstructured/SommerfeldBoundaryConditions.h"
170"""
171 + super().get_includes()
172 )
173
174 @staticmethod
176 solver,
177 exahype2_project,
178 guard,
179 includes,
180 time_step_size=None,
181 ):
182 """!
183
184 Create the roll over of the solver's face data
185
186 @return RollOverUpdatedFace
187 RollOverUpdatedFaceWithSommerfeldBoundaryConditions if the solver
188 uses exahype2.api.SommerfeldBoundaryConditions, and a plain
189 RollOverUpdatedFace otherwise, i.e. for Dirichlet boundary
190 conditions or a domain without boundary.
191
192 @param solver: exahype2.api.Solver
193 The solver whose solver._patch_overlap_update is rolled over into
194 solver._patch_overlap_current_time_step. Its boundary condition
195 terms have to be consistent with the domain, @ref
196 exahype2.api.blockstructured.BoundaryConditions.get_boundary_conditions().
197
198 @param exahype2_project: exahype2.api.Project
199 Provides the periodic boundary conditions.
200
201 @param guard: str
202 @see RollOverUpdatedFace.
203
204 @param includes: str
205 @see RollOverUpdatedFace.
206
207 @param time_step_size: str
208 @see the constructor. Ignored for a plain RollOverUpdatedFace.
209
210 """
211 term = get_boundary_conditions(solver, exahype2_project)
212 if isinstance(term, SommerfeldBoundaryConditions):
214 solver,
215 solver._patch_overlap_current_time_step,
216 solver._patch_overlap_update,
217 guard=guard,
218 includes=includes,
219 origin=term.get_origin(len(exahype2_project.periodic_BC)),
220 time_step_size=time_step_size,
221 )
222 return RollOverUpdatedFace(
223 solver._patch_overlap_current_time_step,
224 solver._patch_overlap_update,
225 guard=guard,
226 includes=includes,
227 )
Sommerfeld (radiative, outgoing) boundary conditions: waves leave the domain with little reflection,...
__init__(self, solver, patch_overlap_current_time_step, patch_overlap_update, guard, includes, origin, time_step_size=None)
Copy patch_overlap_update - the face overlap exahype2.api.rkfd4.actionsets.ProjectPatchOntoFaces has ...