12 Init the degrees of freedom of a higher order scheme where nodes sit in cells
14 This action set is usually only used throughout the initialisation, i.e. once
15 all mesh cells are in place. However, you we can also use it for dynamic AMR
16 later on (not implemented yet).
18 ## Cell initialisation
20 The routine loops over the nodes within the cell, computes the location and
21 invokes the solver's initialisation routine. As much knowledge (such as
22 spacing of the integration points) as possible is kept in the C++ code to
23 keep this routine lightweight.
25 ## Face initialisation
27 The faces do not need an initialisation. It is the job of the very first
28 projection to assign them valid data. Indeed, they can hold garbage. The
29 very first compute of the numerical flux then yields garbage, too. But
30 projecting garbage into the cell just means another initial guess for the
31 cell data, and the solver should converge nevertheless.
33 However, we have encountered situations where the faces' garbage held NaN,
34 and these NaNs then somehow propagated through the solver and polluted all
35 the outcomes. Therefore, we initialise the faces to zero by default.
40 templateTouchCellFirstTime =
"""
41 logTraceInWith2Arguments("touchCellFirstTime", marker.toString(), fineGridCell{{SOLVER_NAME}}.toString());
43 celldata::{{SOLVER_NAME}}::Type dofType = repositories::{{SOLVER_INSTANCE}}.getCellType(marker.x(),marker.h());
46 case celldata::{{SOLVER_NAME}}::Type::Outside:
48 if ( marker.willBeRefined() ) {
49 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Coarse );
52 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Outside );
56 case celldata::{{SOLVER_NAME}}::Type::Interior:
58 if ( marker.willBeRefined() ) {
59 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Coarse );
62 logTraceInWith1Argument("touchCellFirstTime::Interior", marker.toString());
63 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Interior );
65 auto bottomLeftCornerOfCell = marker.x() - 0.5 * marker.h();
68 dfor( k, repositories::{{SOLVER_INSTANCE}}.PolyDegree + 1 ) {
69 auto dofPosition = bottomLeftCornerOfCell
70 + tarch::la::multiplyComponents(marker.h(),repositories::{{SOLVER_INSTANCE}}.getIntegrationPoint(k));
72 tarch::la::Vector< repositories::{{SOLVER_INSTANCE}}.UnknownsPerCellNode, double > value;
73 tarch::la::Vector< repositories::{{SOLVER_INSTANCE}}.UnknownsPerCellNode, double > rhs;
74 repositories::{{SOLVER_INSTANCE}}.initCellDoF(dofPosition, marker.h(), value, rhs, k);
76 for (int i=0; i<repositories::{{SOLVER_INSTANCE}}.UnknownsPerCellNode; i++) {
77 fineGridCell{{SOLVER_NAME}}.setSolution(counter,value(i));
78 fineGridCell{{SOLVER_NAME}}.setRhs(counter,rhs(i));
79 fineGridCell{{SOLVER_NAME}}.setResidual(counter,rhs(i));
84 logTraceOutWith2Arguments("touchCellFirstTime::Interior", fineGridCell{{SOLVER_NAME}}.getSolution(), fineGridCell{{SOLVER_NAME}}.getRhs());
88 case celldata::{{SOLVER_NAME}}::Type::Coarse:
89 case celldata::{{SOLVER_NAME}}::Type::Undefined:
90 assertionMsg(false, "should not be called");
94 logTraceOutWith2Arguments("touchCellFirstTime", marker.toString(), fineGridCell{{SOLVER_NAME}}.toString());
97 templateTouchFaceFirstTime =
"""
98 logTraceInWith2Arguments("touchFaceFirstTime", marker.toString(), fineGridFace{{SOLVER_NAME}}.toString());
100 facedata::{{SOLVER_NAME}}::Type dofType = repositories::{{SOLVER_INSTANCE}}.getFaceType(marker.x(),marker.h());
103 case facedata::{{SOLVER_NAME}}::Type::Outside:
105 if ( marker.willBeRefined() ) // make it coarse
107 fineGridFace{{SOLVER_NAME}}.setType( facedata::{{SOLVER_NAME}}::Type::Coarse );
111 fineGridFace{{SOLVER_NAME}}.setType( facedata::{{SOLVER_NAME}}::Type::Outside );
115 case facedata::{{SOLVER_NAME}}::Type::Interior:
117 if ( marker.willBeRefined() ) {
118 fineGridFace{{SOLVER_NAME}}.setType( facedata::{{SOLVER_NAME}}::Type::Coarse );
121 fineGridFace{{SOLVER_NAME}}.setType( facedata::{{SOLVER_NAME}}::Type::Interior );
125 case facedata::{{SOLVER_NAME}}::Type::Boundary:
127 if ( marker.willBeRefined() ) {
128 fineGridFace{{SOLVER_NAME}}.setType( facedata::{{SOLVER_NAME}}::Type::Coarse );
131 fineGridFace{{SOLVER_NAME}}.setType( facedata::{{SOLVER_NAME}}::Type::Boundary );
135 case facedata::{{SOLVER_NAME}}::Type::Coarse:
136 case facedata::{{SOLVER_NAME}}::Type::Undefined:
137 assertionMsg(false, "should not be called");
141 fineGridFace{{SOLVER_NAME}}.setLProjection( 0.0 );
142 fineGridFace{{SOLVER_NAME}}.setRProjection( 0.0 );
143 fineGridFace{{SOLVER_NAME}}.setSolution( 0.0 );
145 logTraceOutWith2Arguments("touchFaceFirstTime", marker.toString(), fineGridFace{{SOLVER_NAME}}.toString());
153 Configure the initialisation action set
155 @param solver: The underlying higher-order solver
156 We will use it to read out information such as the polynomial degree.
157 See remarks on template realisation.
160 super( InitHigherOrderDofs, self ).
__init__()
162 self.
d[
"SOLVER_INSTANCE"] = solver.instance_name()
163 self.
d[
"SOLVER_NAME"] = solver.typename()
164 self.
d[
"UNKNOWNS_PER_NODE"] = solver._unknowns_per_cell_node
168 if operation_name==peano4.solversteps.ActionSet.OPERATION_TOUCH_CELL_FIRST_TIME:
171 if operation_name==peano4.solversteps.ActionSet.OPERATION_TOUCH_FACE_FIRST_TIME:
179 Configure name of generated C++ action set
181 This action set will end up in the directory observers with a name that
182 reflects how the observer (initialisation) is mapped onto this action
183 set. The name pattern is ObserverName2ActionSetIdentifier where this
184 routine co-determines the ActionSetIdentifier. We make is reflect the
188 return __name__.replace(
".py",
"").replace(
".",
"_")
193 The action set that Peano will generate that corresponds to this class
194 should not be modified by users and can safely be overwritten every time
195 we run the Python toolkit.
203 We need the solver repository in this action set, as we directly access
204 the solver object. We also need access to Peano's d-dimensional loops.
208#include "../repositories/SolverRepository.h"
209#include "peano4/utils/Loop.h"
Action set (reactions to events)
Init the degrees of freedom of a higher order scheme where nodes sit in cells.
user_should_modify_template(self)
The action set that Peano will generate that corresponds to this class should not be modified by user...
get_action_set_name(self)
Configure name of generated C++ action set.
get_body_of_operation(self, operation_name)
Return actual C++ code snippets to be inserted into C++ code.
str templateTouchCellFirstTime
__init__(self, solver)
Configure the initialisation action set.
get_includes(self)
We need the solver repository in this action set, as we directly access the solver object.
str templateTouchFaceFirstTime