3from .SolverCodeSnippets
import SolverCodeSnippets
9 Code snippet generator for all subcycling solvers
16 double _maxEigenvalue;
17 double _maxEigenvalueOfPreviousSweep;
20 * @return Minimum non-zero eigenvalue. Keep in mind that the per-cell
21 * eigenvalues can become zero for some non-linear problems (if
22 * nothing happens), so it is important to neglect those when we
25 double getMaxEigenvalue() const;
27 void setMaxEigenvalue( double eigenvalue );
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}}::getMaxEigenvalue() const {
42 return _maxEigenvalueOfPreviousSweep;
48 return "_maxEigenvalue = std::numeric_limits<double>::max();"
53 double timeStepSize = ::exahype2::removeTimeStepAccumulationErrorsFromCell( fineGridCell""" + solver_name +
"""CellLabel, fineGridFaces""" + solver_name +
"""FaceLabel, fineGridCell""" + solver_name +
"""CellLabel.getTimeStepSize() );
63 If you solve non-linear problems, cells can have a zero eigenvalue. It means that
64 nothing happens within this cell. There are two options on the table: You can take
65 the biggest global eigenvalue and march forward using this value. In ExaHyPE 2,
66 this yields a staircase effect if you have larger, regular region, then we have
67 something similar to many stencil codes which then update the cells in the middle
68 again, and then those in the middle again, and so forth.
70 We can avoid this by making a cell march if an only if one neighbour has advanced.
71 In this case large global areas where nothing happens lag behind.
74 avoid_staircase_effect: Boolean
76 discretisation_steps: Integer
77 See exahype2::discretiseAndTruncateTimeStepSizes() for a description of admissible
78 values and the semantics of the values.
81 determine_eigenvalue =
"""
82 repositories::{{SOLVER_INSTANCE}}.setMaxEigenvalue( maxEigenvalue );
85 if avoid_staircase_effect:
86 compute_time_step_sizes =
"""
87 double newTimeStepSize = 0.0;
88 const double minGlobalTimeStepSize = repositories::{{SOLVER_INSTANCE}}.getMinTimeStepSize()<std::numeric_limits<double>::max() ? repositories::{{SOLVER_INSTANCE}}.getMinTimeStepSize() : 0.0;
89 const double maxGlobalTimeStepSize = repositories::{{SOLVER_INSTANCE}}.getMaxEigenvalue()>0.0 ? """ + str(time_step_relaxation) +
""" * repositories::{{SOLVER_INSTANCE}}.getMaxVolumeSize(false) / repositories::{{SOLVER_INSTANCE}}.getMaxEigenvalue() : 0.0;
90 if ( tarch::la::greater( maxEigenvalue,0.0) ) {
91 newTimeStepSize = ::exahype2::discretiseAndTruncateTimeStepSizes(
92 """ + str(time_step_relaxation) +
""" * marker.h()(0) / {{NUMBER_OF_GRID_CELLS_PER_PATCH_PER_AXIS}} / maxEigenvalue,
93 maxGlobalTimeStepSize,
94 """ + str(discretisation_steps) +
"""
98 const double minTimeStampOfNeighbours = ::exahype2::getMinTimeStampOfNeighboursAhead(fineGridCell{{SOLVER_NAME}}CellLabel, fineGridFaces{{SOLVER_NAME}}FaceLabel);
100 newTimeStepSize = minTimeStampOfNeighbours - fineGridCell{{SOLVER_NAME}}CellLabel.getTimeStamp();
104 compute_time_step_sizes =
"""
105 double newTimeStepSize = 0.0;
106 //const double minGlobalTimeStepSize = repositories::{{SOLVER_INSTANCE}}.getMaxEigenvalue()>0.0 ? """ + str(time_step_relaxation) +
""" * repositories::{{SOLVER_INSTANCE}}.getMinVolumeSize(false) / repositories::{{SOLVER_INSTANCE}}.getMaxEigenvalue() : 0.0;
107 const double minGlobalTimeStepSize = repositories::{{SOLVER_INSTANCE}}.getMinTimeStepSize()<std::numeric_limits<double>::max() ? repositories::{{SOLVER_INSTANCE}}.getMinTimeStepSize() : 0.0;
108 const double maxGlobalTimeStepSize = repositories::{{SOLVER_INSTANCE}}.getMaxEigenvalue()>0.0 ? """ + str(time_step_relaxation) +
""" * repositories::{{SOLVER_INSTANCE}}.getMaxVolumeSize(false) / repositories::{{SOLVER_INSTANCE}}.getMaxEigenvalue() : 0.0;
109 if ( tarch::la::greater( maxEigenvalue,0.0) ) {
110 newTimeStepSize = ::exahype2::discretiseAndTruncateTimeStepSizes(
111 """ + str(time_step_relaxation) +
""" * marker.h()(0) / {{NUMBER_OF_GRID_CELLS_PER_PATCH_PER_AXIS}} / maxEigenvalue,
112 maxGlobalTimeStepSize,
113 """ + str(discretisation_steps) +
"""
116 else if ( tarch::la::greater( repositories::{{SOLVER_INSTANCE}}.getMaxEigenvalue(),0.0) ) {
117 newTimeStepSize = minGlobalTimeStepSize;
132 return determine_eigenvalue + compute_time_step_sizes
138 This routine is inserted after we have reduced all global quantities. These
139 are the quantities with the postfix ThisTimeStep.
143 assertion( _minVolumeH >= 0.0 );
144 assertion( MaxAdmissibleVolumeH > 0.0 );
145 assertion2( _minVolumeH <= MaxAdmissibleVolumeH, _minVolumeH, MaxAdmissibleVolumeH );
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_user_definitions(self)
create_abstract_solver_constructor_statements(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...