Peano
Loading...
Searching...
No Matches
FixedSubcyclingTimeSteppingCodeSnippets.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
3from .SolverCodeSnippets import SolverCodeSnippets
4
5
7 """
8
9 Code snippet generator for all subcycling solvers
10
11 """
12
13 def __init__(self, remove_accumulation_errors):
14 self._remove_accumulation_errors = remove_accumulation_errors
15
16
18 return """
19private:
20 double _finestMeshTimeStepSize;
21public:
22 double getTimeStepSize() const;
23 """
24
25
27 return """
28void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::setMaxEigenvalue( double eigenvalue ) {
29 if ( tarch::la::greater( eigenvalue, 0.0 ) ) {
30 tarch::multicore::Lock lock(_semaphore);
31 _maxEigenvalue = std::max(_maxEigenvalue,eigenvalue);
32 }
33}
34
35
36double {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::getAdmissibleTimeStepSize() const {
37 return _admissibleTimeStepSize;
38}
39 """
40
41
43 return "_admissibleTimeStepSize = 0.0;"
44
45
48 return """
49 // The fixed solver's _timeStepSize scales with min volume h, i.e. it is
50 // always chosen such that the finest grid does something meaningful.
51 const double originalStepSize = repositories::{{SOLVER_INSTANCE}}.getMinPatchSize()>0.0 ?
52 repositories::{{SOLVER_INSTANCE}}.getTimeStepSize() * marker.h()(0) / repositories::{{SOLVER_INSTANCE}}.getMinPatchSize(false) :
53 0.0;
54 double timeStepSize = ::exahype2::removeTimeStepAccumulationErrorsFromCell( fineGridCell{{SOLVER_NAME}}CellLabel, fineGridFaces{{SOLVER_NAME}}FaceLabel, originalStepSize);
55"""
56 else:
57 return """
58 // The fixed solver's _timeStepSize scales with min volume h, i.e. it is
59 // always chosen such that the finest grid does something meaningful.
60 double timeStepSize = repositories::{{SOLVER_INSTANCE}}.getMinPatchSize()>0.0 ?
61 repositories::{{SOLVER_INSTANCE}}.getTimeStepSize() * marker.h()(0) / repositories::{{SOLVER_INSTANCE}}.getMinPatchSize(false) :
62 0.0;
63"""
64
65
67 """
68
69 This is global, fixed time stepping, i.e. the new time step size will likely
70 be the same as the previous one, unless the mesh changes, as we work with
71 normalised time step sizes, i.e. in this case the time step size might change.
72 Anyway, the new time step size is only for stats anyway, as we'll pick a
73 global one when we determine timeStepSize the next time step.
74
75 """
76 return """
77 repositories::{{SOLVER_INSTANCE}}.setMaxEigenvalue( maxEigenvalue );
78
79 // This is a value set for stats reasons. We'll ignore it later as we
80 // ask for a new valid time step size from getAdmissibleTimeStepSize().
81 const double newTimeStepSize = repositories::{{SOLVER_INSTANCE}}.getAdmissibleTimeStepSize();
82"""
83
84
86 """
87
88 This routine is inserted after we have reduced all global quantities. These
89 are the quantities with the postfix ThisTimeStep.
90
91 """
92 return """
93 if (isLastGridSweepOfTimeStep()) {
94 #ifdef Parallel
95 double newMaxEigenvalue = _maxEigenvalue;
96 tarch::mpi::Rank::getInstance().allReduce(
97 &newMaxEigenvalue,
98 &_maxEigenvalue,
99 1,
100 MPI_DOUBLE,
101 MPI_MAX,
102 [&]() -> void { tarch::services::ServiceRepository::getInstance().receiveDanglingMessages(); }
103 );
104 #endif
105
106 if ( tarch::la::smaller(_maxEigenvalue, 0.0 ) ) {
107 ::tarch::triggerNonCriticalAssertion( __FILE__, __LINE__, "_maxEigenvalue>=0", "invalid max eigenvalue: " + std::to_string(_maxEigenvalue) );
108 // keep time step size invariant
109 // _admissibleTimeStepSize = _admissibleTimeStepSize;
110 }
111 else if ( tarch::la::equals(_maxEigenvalue, 0.0 ) ) {
112 logWarning( "finishTimeStep(...)", "maximum eigenvalue approaches 0.0. For nonlinear PDEs, this often means the PDE becomes stationary. It could also be a bug however" );
113 _admissibleTimeStepSize = 0.0;
114 }
115 }
116"""
create_finish_time_step_implementation(self)
This routine is inserted after we have reduced all global quantities.
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...