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