3from .SolverCodeSnippets
import SolverCodeSnippets
9 Code snippet generator for all subcycling solvers
16 double _maxEigenvalue;
17 double _admissibleTimeStepSize;
19 void setMaxEigenvalue( double eigenvalue );
21 * @return Admissible time step size for the current sweep, i.e.
22 * return _admissibleTimeStepSize. This value always refers
23 * to the minimum mesh volume size. If you use subcycling,
24 * you have to scale it for cells that are not on the finest
27 virtual double getAdmissibleTimeStepSize() const;
33void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::setMaxEigenvalue( double eigenvalue ) {
34 if ( tarch::la::greater( eigenvalue, 0.0 ) ) {
35 tarch::multicore::Lock lock(_semaphore);
36 _maxEigenvalue = std::max(_maxEigenvalue,eigenvalue);
41double {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::getAdmissibleTimeStepSize() const {
42 return _admissibleTimeStepSize;
48 return "_admissibleTimeStepSize = 0.0;"
52 if remove_accumulation_errors:
54 // The fixed solver's _timeStepSize scales with min volume h, i.e. it is
55 // always chosen such that the finest grid does something meaningful.
56 const double originalStepSize = repositories::{{SOLVER_INSTANCE}}.getMinPatchSize(false)>0.0 ?
57 repositories::{{SOLVER_INSTANCE}}.getTimeStepSize() * marker.h()(0) / repositories::{{SOLVER_INSTANCE}}.getMinPatchSize(false) :
59 double timeStepSize = ::exahype2::removeTimeStepAccumulationErrorsFromCell( fineGridCell""" + solver_name +
"""CellLabel, fineGridFaces""" + solver_name +
"""FaceLabel, originalStepSize);
63 // The fixed solver's _timeStepSize scales with min volume h, i.e. it is
64 // always chosen such that the finest grid does something meaningful.
65 double timeStepSize = repositories::{{SOLVER_INSTANCE}}.getMinPatchSize(false)>0.0 ?
66 repositories::{{SOLVER_INSTANCE}}.getTimeStepSize() * marker.h()(0) / repositories::{{SOLVER_INSTANCE}}.getMinPatchSize(false) :
70 if remove_accumulation_errors:
72 // The fixed solver's _timeStepSize scales with min volume h, i.e. it is
73 // always chosen such that the finest grid does something meaningful.
74 const double originalTimeStepSize = repositories::{{SOLVER_INSTANCE}}.getMinPatchSize(false)>0.0 ?
75 repositories::{{SOLVER_INSTANCE}}.getAdmissibleTimeStepSize() * marker.h()(0) / repositories::{{SOLVER_INSTANCE}}.getMinPatchSize(false) :
77 double timeStepSize = ::exahype2::removeTimeStepAccumulationErrorsFromCell( fineGridCell""" + solver_name +
"""CellLabel, fineGridFaces""" + solver_name +
"""FaceLabel, originalTimeStepSize);
81 // The fixed solver's _timeStepSize scales with min volume h, i.e. it is
82 // always chosen such that the finest grid does something meaningful.
83 double timeStepSize = repositories::{{SOLVER_INSTANCE}}.getMinPatchSize(false)>0.0 ?
84 repositories::{{SOLVER_INSTANCE}}.getAdmissibleTimeStepSize() * marker.h()(0) / repositories::{{SOLVER_INSTANCE}}.getMinPatchSize(false) :
92 This is global, fixed time stepping, i.e. the new time step size will likely
93 be the same as the previous one, unless the mesh changes, as we work with
94 normalised time step sizes, i.e. in this case the time step size might change.
95 Anyway, the new time step size is only for stats anyway, as we'll pick a
96 global one when we determine timeStepSize the next time step.
100 repositories::{{SOLVER_INSTANCE}}.setMaxEigenvalue( maxEigenvalue );
102 // This is a value set for stats reasons. We'll ignore it later as we
103 // ask for a new valid time step size from getAdmissibleTimeStepSize().
104 const double newTimeStepSize = repositories::{{SOLVER_INSTANCE}}.getAdmissibleTimeStepSize();
111 This routine is inserted after we have reduced all global quantities. These
112 are the quantities with the postfix ThisTimeStep.
116 if ( isLastGridSweepOfTimeStep() ) {
118 double newMaxEigenvalue = _maxEigenvalue;
119 tarch::mpi::Rank::getInstance().allReduce(
125 [&]() -> void { tarch::services::ServiceRepository::getInstance().receiveDanglingMessages(); }
129 if ( tarch::la::smaller(_maxEigenvalue, 0.0 ) ) {
130 ::tarch::triggerNonCriticalAssertion( __FILE__, __LINE__, "_maxEigenvalue>=0", "invalid max eigenvalue: " + std::to_string(_maxEigenvalue) );
131 // keep time step size invariant
132 // _admissibleTimeStepSize = _admissibleTimeStepSize;
134 else if ( tarch::la::equals(_maxEigenvalue, 0.0 ) ) {
135 logWarning( "finishTimeStep(...)", "maximum eigenvalue approaches 0.0. For nonlinear PDEs, this often means the PDE becomes stationary. It could also be a bug however" );
136 _admissibleTimeStepSize = 0.0;
Code snippet generator for all subcycling solvers.
create_finish_time_step_implementation(self)
This routine is inserted after we have reduced all global quantities.
create_abstract_solver_user_declarations(self)
create_abstract_solver_constructor_statements(self)
create_abstract_solver_user_definitions(self)
Interface for all solvers' code snippets.
create_compute_time_step_size()
Within the actual compute kernels, the kernels ask the solver variant how to determine a new field.
create_compute_new_time_step_size()
Very similar to create_compute_time_step_size(), this routine should return a code snippet which crea...