Peano
Loading...
Searching...
No Matches
LocalTimeSteppingCodeSnippets.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
14 return """
15private:
16 double _maxEigenvalue;
17 double _maxEigenvalueOfPreviousSweep;
18public:
19 /**
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
23 * take the minimum.
24 */
25 double getMaxEigenvalue() const;
26
27 void setMaxEigenvalue( double eigenvalue );
28 """
29
30
32 return """
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);
37 }
38}
39
40
41double {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::getMaxEigenvalue() const {
42 return _maxEigenvalueOfPreviousSweep;
43}
44 """
45
46
48 return "_maxEigenvalue = std::numeric_limits<double>::max();"
49
50
52 result = """
53 double timeStepSize = ::exahype2::removeTimeStepAccumulationErrorsFromCell( fineGridCell""" + solver_name + """CellLabel, fineGridFaces""" + solver_name + """FaceLabel, fineGridCell""" + solver_name + """CellLabel.getTimeStepSize() );
54"""
55 return result
56
57
59 """
60
61 :: Zero eigenvalues
62
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.
69
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.
72
73
74 avoid_staircase_effect: Boolean
75
76 discretisation_steps: Integer
77 See exahype2::discretiseAndTruncateTimeStepSizes() for a description of admissible
78 values and the semantics of the values.
79
80 """
81 determine_eigenvalue = """
82 repositories::{{SOLVER_INSTANCE}}.setMaxEigenvalue( maxEigenvalue );
83"""
84
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) + """
95 );
96 }
97 else {
98 const double minTimeStampOfNeighbours = ::exahype2::getMinTimeStampOfNeighboursAhead(fineGridCell{{SOLVER_NAME}}CellLabel, fineGridFaces{{SOLVER_NAME}}FaceLabel);
99
100 newTimeStepSize = minTimeStampOfNeighbours - fineGridCell{{SOLVER_NAME}}CellLabel.getTimeStamp();
101 }
102"""
103 else:
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) + """
114 );
115 }
116 else if ( tarch::la::greater( repositories::{{SOLVER_INSTANCE}}.getMaxEigenvalue(),0.0) ) {
117 newTimeStepSize = minGlobalTimeStepSize;
118 }
119"""
120
121
122# set_time_step_size = """
123# if ( tarch::la::equals(newTimeStepSize,0.0) ) {
124# logDebug( "touchCellFirstTime(...)", "can't do a time step on cell " << marker.toString() << " as global max eigenvalue=" << repositories::{{SOLVER_INSTANCE}}.getMaxEigenvalue() );
125# fineGridCell{{SOLVER_NAME}}CellLabel.setTimeStepSize(0.0);
126# }
127# else {
128# fineGridCell{{SOLVER_NAME}}CellLabel.setTimeStepSize(newTimeStepSize);
129# }
130#"""
131
132 return determine_eigenvalue + compute_time_step_sizes
133
134
136 """
137
138 This routine is inserted after we have reduced all global quantities. These
139 are the quantities with the postfix ThisTimeStep.
140
141 """
142 return """
143 assertion( _minVolumeH >= 0.0 );
144 assertion( MaxAdmissibleVolumeH > 0.0 );
145 assertion2( _minVolumeH <= MaxAdmissibleVolumeH, _minVolumeH, MaxAdmissibleVolumeH );
146"""
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...