Peano
Loading...
Searching...
No Matches
OptimisticAdaptiveTimeSteppingCodeSnippets.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 fixed time stepping solvers
10
11 Consult the @ref page_exahype_solvers_enclave_solvers "generic discussion of optimistic enclave solvers" before
12 you continue to study this class. On this generic overview page, I notably
13 clarify why this solver variant and its code snippets are inappropriate for
14 Finite Difference and Finite Volume methods.
15
16 """
17
19 return """
20protected:
21 double _maxEigenvalue;
22 double _admissibleTimeStepSize;
23 double _predictedAdmissibleTimeStepSize;
24 bool _cancelOptimisticTasks;
25public:
26 void setMaxEigenvalue( double eigenvalue );
27 /**
28 * @return Admissible time step size for the current sweep, i.e.
29 * return _admissibleTimeStepSize. This value always refers
30 * to the minimum mesh volume size. If you use subcycling,
31 * you have to scale it for cells that are not on the finest
32 * mesh resolution.
33 */
34 virtual double getAdmissibleTimeStepSize() const;
35 virtual double getPredictedAdmissibleTimeStepSize() const;
36 bool cancelOptimisticTasks() const;
37 """
38
39
41 return """
42void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::setMaxEigenvalue( double eigenvalue ) {
43 if ( tarch::la::greater( eigenvalue, 0.0 ) ) {
44 tarch::multicore::Lock lock(_semaphore);
45 _maxEigenvalue = std::max(_maxEigenvalue,eigenvalue);
46 }
47}
48
49
50double {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::getAdmissibleTimeStepSize() const {
51 return _admissibleTimeStepSize;
52}
53
54
55double {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::getPredictedAdmissibleTimeStepSize() const {
56 return _predictedAdmissibleTimeStepSize;
57}
58
59
60bool {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::cancelOptimisticTasks() const {
61 return _cancelOptimisticTasks;
62}
63 """
64
65
67 """!
68
69 Set the admissible time step size as well as the predicted time step size to zero.
70
71 The admissible time step size will be analysed throughout the first
72 time step, and then we can really kick off with an admissible one.
73
74 """
75 return """
76_admissibleTimeStepSize = 0.0;
77_predictedAdmissibleTimeStepSize = 0.0;
78_cancelOptimisticTasks = false;
79"""
80
81
83 return """
84 double timeStepSize = repositories::{{SOLVER_INSTANCE}}.getAdmissibleTimeStepSize();
85"""
86
87
89 """
90
91 This is global, fixed time stepping, i.e. the new time step size will likely
92 be the same as the previous one, unless the mesh changes, as we work with
93 normalised time step sizes, i.e. in this case the time step size might change.
94 Anyway, the new time step size is only for stats anyway, as we'll pick a
95 global one when we determine timeStepSize the next time step.
96
97 """
98 return """
99 repositories::{{SOLVER_INSTANCE}}.setMaxEigenvalue( maxEigenvalue );
100
101 // This is a value set for stats reasons. We'll ignore it later as we
102 // ask for a new valid time step size from getAdmissibleTimeStepSize().
103 const double newTimeStepSize = repositories::{{SOLVER_INSTANCE}}.getAdmissibleTimeStepSize();
104"""
105
106
108 """
109
110 This routine is inserted after we have reduced all global quantities. These
111 are the quantities with the postfix ThisTimeStep.
112
113 """
114 return """
115 if ( isLastGridSweepOfTimeStep() ) {
116 #ifdef Parallel
117 double newMaxEigenvalue = _maxEigenvalue;
118 tarch::mpi::Rank::getInstance().allReduce(
119 &newMaxEigenvalue,
120 &_maxEigenvalue,
121 1,
122 MPI_DOUBLE,
123 MPI_MAX,
124 [&]() -> void { tarch::services::ServiceRepository::getInstance().receiveDanglingMessages(); }
125 );
126 #endif
127
128 if ( tarch::la::smaller(_maxEigenvalue, 0.0 ) ) {
129 ::tarch::triggerNonCriticalAssertion( __FILE__, __LINE__, "_maxEigenvalue>=0", "invalid max eigenvalue: " + std::to_string(_maxEigenvalue) );
130 // keep time step size invariant
131 // _admissibleTimeStepSize = _admissibleTimeStepSize;
132 }
133 else if ( tarch::la::equals(_maxEigenvalue, 0.0 ) ) {
134 logWarning( "finishTimeStep(...)", "maximum eigenvalue approaches 0.0. For nonlinear PDEs, this often means the PDE becomes stationary. It could also be a bug however" );
135 _admissibleTimeStepSize = 0.0;
136 _predictedAdmissibleTimeStepSize = 0.0;
137 }
138 }
139"""
create_abstract_solver_constructor_statements(self)
Set the admissible time step size as well as the predicted time step size to zero.
Interface for all solvers' code snippets.
create_compute_new_time_step_size()
Very similar to create_compute_time_step_size(), this routine should return a code snippet which crea...
create_compute_time_step_size()
Within the actual compute kernels, the kernels ask the solver variant how to determine a new field.