3from __future__
import annotations
5from typing
import Sequence
7from ..PDETerm
import PDETerm
13 Sommerfeld (radiative, outgoing) boundary conditions: waves leave the
14 domain with little reflection, and the solution approaches a far-field
15 solution towards infinity
17 The term is an alternative to exahype2.api.DirichletBoundaryConditions.
18 @ref exahype2::blockstructured::applySommerfeldBoundaryConditions()
19 documents the conditions, their discretisation, and how block-structured
20 schemes realise them. The user specifies the far-field solution
24 virtual void sommerfeldFarFieldSolution(
25 const tarch::la::Vector<Dimensions, double>& x,
26 double* __restrict__ Q // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}]
30 Only the first NUMBER_OF_UNKNOWNS entries of Q are read, i.e. the
31 implementation does not have to set the auxiliary variables.
33 The wave speed is the solver's maximum eigenvalue along the face normal,
34 i.e. the solver has to hold a non-stateless exahype2.api.MaxEigenvalue
35 term. The ghost cells are initialised with the initial condition
36 (exahype2.api.InitPointWisely) before the first time step.
38 Different to Dirichlet conditions, there is no separate boundary task
39 in the time step. The Sommerfeld update replaces the roll over of the
40 face data instead (@see
41 exahype2.api.fv.actionsets.RollOverUpdatedFaceWithSommerfeldBoundaryConditions and
42 exahype2.api.rkfd4.actionsets.RollOverUpdatedFaceWithSommerfeldBoundaryConditions).
43 Runge-Kutta schemes accept the term only if the time stamps of their
44 stages do not decrease.
46 A solver needs a boundary condition term if and only if at least one
47 axis of the domain is not periodic (@see
48 exahype2.api.blockstructured.BoundaryConditions.get_boundary_conditions()).
50 Only the non-stateless variant is supported, i.e. the term has to be
51 added with stateless=False.
56 "const tarch::la::Vector<Dimensions, double>& x, " "double* __restrict__ Q"
59 NAME =
"sommerfeldFarFieldSolution"
63 implementation: str =
None,
64 origin: Sequence[float] =
None,
65 stateless: bool =
False,
69 @param implementation: str
70 A C++ snippet that becomes sommerfeldFarFieldSolution()'s body, or
71 None (the default) to leave sommerfeldFarFieldSolution() pure
72 virtual for you to implement by hand.
74 @param origin: Sequence[float]
75 Centre of the system, i.e. the point the outgoing spherical waves
76 emanate from. One entry per dimension. None (the default) is the
77 origin of the coordinate system.
79 @param stateless: bool
80 Has to be False, @see the class documentation.
85 implementation=implementation,
88 self.
origin =
None if origin
is None else [float(x)
for x
in origin]
93 The origin with one entry per dimension
95 @param dimensions: int
96 Number of dimensions of the domain.
102 return [0.0] * dimensions
103 if len(self.
origin) != dimensions:
105 f
"The origin {self.origin} of the Sommerfeld boundary conditions has "
106 f
"{len(self.origin)} entries, but the domain has {dimensions} dimensions."
113 SommerfeldBoundaryConditions-specific code generation
115 Reuses PDETerm.Generator as-is - SommerfeldBoundaryConditions.SIGNATURE
116 is picked up automatically. Declared explicitly for the same reason
Turns a PDETerm into the C++ text for its generated method: exactly one method - the static,...
Represents one named, point-wise PDE operator that a solver exposes for the user to implement: a C++ ...
SommerfeldBoundaryConditions-specific code generation.
Sommerfeld (radiative, outgoing) boundary conditions: waves leave the domain with little reflection,...
origin
The origin with one entry per dimension.
get_origin(self, int dimensions)
The origin with one entry per dimension.
__init__(self, str implementation=None, Sequence[float] origin=None, bool stateless=False)