Peano
Loading...
Searching...
No Matches
ProjectLinearCombinationOfEstimatesOntoFaces.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
3
4from .AbstractRungeKuttaDGActionSet import AbstractRungeKuttaDGActionSet
5
6import peano4
7import jinja2
8
9from exahype2.solvers.ButcherTableau import ButcherTableau
10
11from enum import Enum
12
13class FaceProjections(Enum):
14 """
15 Different data can be projected onto the faces. In the simplest variant,
16 only the solution is projected on the faces and the Riemann solver then
17 reconstructs the flux from the arising jump, i.e. the solution left and
18 right of the face. There are more sophisticated variants however which
19 exploit the solution left and right plus additional data such as the
20 gradient along the normal.
21 """
22 Solution = 1,
23 SolutionAndGradient = 2,
24 SolutionAndFluxExtrapolation = 3
25
26def compute_number_of_face_projection_quantities(face_projections: FaceProjections):
27 """
28 Translate the information what is projected onto the faces into a number
29 how many quantities are to be held per face.
30 """
31 if face_projections == FaceProjections.Solution:
32 return 1
33 elif face_projections == FaceProjections.SolutionAndGradient:
34 return 2
35 elif face_projections == FaceProjections.SolutionAndFluxExtrapolation:
36 return 2
37 else:
38 assert False, "variant {} not handled".format( face_projections )
39 return -1
40
42 """
43
44 The linear combination of the Runge-Kutta trials has to be projected onto
45 the faces, so we can then solve the Riemann problems. So the projection
46 happens in one grid sweep, the corresponding Riemann solve in the next one.
47
48 Please consult the documentation of RungeKuttaDG for an explanation of the
49 role of the two different boundary data fields.
50
51
52 ## Time step sizes and time stamps
53
54 Besides the actual projection, I also set the following fields on the
55 face:
56
57 - Updated Is set after each projection.
58
59 - UpdatedTimeStamp Is set after each projection with the time stamp
60 of the current Runge-Kutta trial.
61
62 We do not update the new and old time stamp on the face label. These
63 values are properly set in the ComputeFinalLinearCombination action set.
64
65
66 ## Guards
67
68 We can set separate guards for each individual step (which we have to do,
69 as the different steps depend on the role of the individual Runge-Kutta
70 phases). The action set does not initialise the guards with a dummy.
71 Instead, I expect that the person who creates the action set explicitly
72 sets the guard list before the action set is handed over to the code
73 generation phase.
74
75 """
76
77
78 TemplateProjectLinearCombinationSolution = """
79 {% for PREDICATE_NO in range(0,PREDICATES|length) %}
80 if ({{PREDICATES[PREDICATE_NO]}}) {
81
82 double* QIn = fineGridCell{{UNKNOWN_IDENTIFIER}}LinearCombination.value;
83
84 #if Dimensions==2
85 ::exahype2::dg::projectVolumetricDataOntoFaces(
86 QIn,
87 {{ORDER}},
88 {{NUMBER_OF_UNKNOWNS}},
89 {{NUMBER_OF_AUXILIARY_VARIABLES}},
90 repositories::{{SOLVER_INSTANCE}}.BasisFunctionValuesLeft1d,
91 fineGridFaces{{UNKNOWN_IDENTIFIER}}EstimateProjection(0).value, //left
92 fineGridFaces{{UNKNOWN_IDENTIFIER}}EstimateProjection(2).value, //right
93 fineGridFaces{{UNKNOWN_IDENTIFIER}}EstimateProjection(1).value, //down
94 fineGridFaces{{UNKNOWN_IDENTIFIER}}EstimateProjection(3).value //up
95 );
96 #elif Dimensions==3
97 ::exahype2::dg::projectVolumetricDataOntoFaces(
98 QIn,
99 {{ORDER}},
100 {{NUMBER_OF_UNKNOWNS}},
101 {{NUMBER_OF_AUXILIARY_VARIABLES}},
102 repositories::{{SOLVER_INSTANCE}}.BasisFunctionValuesLeft1d,
103 fineGridFaces{{UNKNOWN_IDENTIFIER}}EstimateProjection(0).value, //left
104 fineGridFaces{{UNKNOWN_IDENTIFIER}}EstimateProjection(3).value, //right
105 fineGridFaces{{UNKNOWN_IDENTIFIER}}EstimateProjection(1).value, //down
106 fineGridFaces{{UNKNOWN_IDENTIFIER}}EstimateProjection(4).value, //up
107 fineGridFaces{{UNKNOWN_IDENTIFIER}}EstimateProjection(2).value, //front
108 fineGridFaces{{UNKNOWN_IDENTIFIER}}EstimateProjection(5).value //back
109 );
110 #endif
111
112
113 // Set the variable
114 // double timeStepSize
115 const double timeStampOldSolution = fineGridCell{{SOLVER_NAME}}CellLabel.getTimeStamp();
116 {{COMPUTE_TIME_STEP_SIZE}}
117 const double timeStamp = timeStampOldSolution + {{BUTCHER_TABLEAU_RELATIVE_TIME_STEP_SIZES[PREDICATE_NO]}} * timeStepSize;
118
119 for (int d=0; d<Dimensions; d++) {
120 {{FACE_METADATA_ACCESSOR}}(d).setUpdated( 1,true);
121 {{FACE_METADATA_ACCESSOR}}(d+Dimensions).setUpdated(0,true);
122
123 {{FACE_METADATA_ACCESSOR}}(d).setUpdatedTimeStamp( 1, timeStamp );
124 {{FACE_METADATA_ACCESSOR}}(d+Dimensions).setUpdatedTimeStamp(0, timeStamp );
125
126 logDebug( "touchCellLastTime(...)", "update {{FACE_METADATA_ACCESSOR}}(" << d << ")(1)" );
127 logDebug( "touchCellLastTime(...)", "update {{FACE_METADATA_ACCESSOR}}(" << (d+Dimensions) << ")(0)" );
128 }
129 }
130 {% endfor %}
131"""
132
133
134 def __init__(self,
135 solver,
136 face_projections: FaceProjections):
137 """
138
139
140 """
141 super(ProjectLinearCombinationOfEstimatesOntoFaces,self).__init__(solver)
143 self.face_projections = face_projections
145
146
147 @property
148 def guards(self):
149 if self._guards==[]:
150 raise Exception( "Guards are not initialised" )
151 return self._guards
152
153
154 @guards.setter
155 def guards(self,new_guards):
156 if new_guards!=[] and len(new_guards)!=self._solver.number_of_Runge_Kutta_steps():
157 raise Exception( "Expect one guard per Runge Kutta step. Have {} steps but got guards {}".format(solver.number_of_Runge_Kutta_steps(),guards) )
158 self._guards = new_guards
159
160
161 def get_body_of_operation(self,operation_name):
162 result = ""
163 d = {}
164 self._solver._init_dictionary_with_default_parameters(d)
165 self._solver.add_entries_to_text_replacement_dictionary(d)
166 d[ "PREDICATES" ] = self.guardsguardsguards
167 d[ "FACE_METADATA_ACCESSOR" ] = "fineGridFaces" + self._solver._face_label.name
168 d[ "CELL_METADATA_ACCESSOR" ] = "fineGridCell""" + self._solver._cell_label.name
169 d[ "WEIGHTS" ] = self._butcher_tableau.final_estimate_weights()
170 d[ "BUTCHER_TABLEAU_RELATIVE_TIME_STEP_SIZES" ] = self._butcher_tableau.time_step_sizes()
171 if operation_name==peano4.solversteps.ActionSet.OPERATION_TOUCH_CELL_FIRST_TIME and self.face_projections==FaceProjections.Solution:
172 result = jinja2.Template(self.TemplateProjectLinearCombinationSolution).render(**d)
173 pass
174 elif operation_name==peano4.solversteps.ActionSet.OPERATION_TOUCH_CELL_FIRST_TIME:
175 assert False, "face projection variant {} not supported yet ".format( self.face_projections)
176
177 return result
178
179
181 return __name__.replace(".py", "").replace(".", "_")
get_action_set_name(self)
You should replicate this function in each subclass, so you get meaningful action set names (otherwis...
compute_number_of_face_projection_quantities(FaceProjections face_projections)
Translate the information what is projected onto the faces into a number how many quantities are to b...