3from .CellCenteredFiniteDifferences
import CellCenteredFiniteDifferences
16ComputeNewQPointer =
"""
18 constexpr int NumberOfDoFsPerCell = {{NUMBER_OF_GRID_CELLS_PER_PATCH_PER_AXIS}} * {{NUMBER_OF_GRID_CELLS_PER_PATCH_PER_AXIS}};
19 newQ = fineGridCell{{UNKNOWN_IDENTIFIER}}RhsEstimates.value + {{PREDICATE_NO}} * NumberOfDoFsPerCell * {{NUMBER_OF_UNKNOWNS}};
21 constexpr int NumberOfDoFsPerCell = {{NUMBER_OF_GRID_CELLS_PER_PATCH_PER_AXIS}} * {{NUMBER_OF_GRID_CELLS_PER_PATCH_PER_AXIS}} * {{NUMBER_OF_GRID_CELLS_PER_PATCH_PER_AXIS}};
22 newQ = fineGridCell{{UNKNOWN_IDENTIFIER}}RhsEstimates.value + {{PREDICATE_NO}} * NumberOfDoFsPerCell * {{NUMBER_OF_UNKNOWNS}};
27ReconstructLinearCombination =
"""
28 double timeStamp = fineGridCell{{SOLVER_NAME}}CellLabel.getTimeStamp();
31 // double timeStepSize
32 {{COMPUTE_TIME_STEP_SIZE}}
34 {% for PREDICATE_NO in range(0,PREDICATES|length) %}
35 if ({{PREDICATES[PREDICATE_NO]}}) {
36 ::exahype2::enumerator::AoSLexicographicEnumerator enumeratorWithAuxiliaryVariablesOnReconstructedPatch( 1, {{NUMBER_OF_GRID_CELLS_PER_PATCH_PER_AXIS}}, {{HALO_SIZE}}, {{NUMBER_OF_UNKNOWNS}}, {{NUMBER_OF_AUXILIARY_VARIABLES}});
37 ::exahype2::enumerator::AoSLexicographicEnumerator enumeratorWithoutAuxiliaryVariables( {{RK_STEPS}}, {{NUMBER_OF_GRID_CELLS_PER_PATCH_PER_AXIS}}, 0, {{NUMBER_OF_UNKNOWNS}}, 0 );
39 // Add rhs estimates to oldQ (if RK order>1)
40 dfor( dof, {{NUMBER_OF_GRID_CELLS_PER_PATCH_PER_AXIS}} ) {
41 for (int unknown=0; unknown<{{NUMBER_OF_UNKNOWNS}}; unknown++) {
42 {% for WEIGHT_NO in range(0,BUTCHER_TABLEAU_WEIGHTS[PREDICATE_NO]|length) %}
43 {% if BUTCHER_TABLEAU_WEIGHTS[PREDICATE_NO][WEIGHT_NO]!=0 %}
44 oldQWithHalo[ enumeratorWithAuxiliaryVariablesOnReconstructedPatch(0,dof,unknown) ] +=
45 timeStepSize * {{BUTCHER_TABLEAU_WEIGHTS[PREDICATE_NO][WEIGHT_NO]}} *
46 fineGridCell{{UNKNOWN_IDENTIFIER}}RhsEstimates.value[ enumeratorWithoutAuxiliaryVariables({{WEIGHT_NO}},dof,unknown) ];
51 """ + ComputeNewQPointer +
"""
55 {{PREPROCESS_RECONSTRUCTED_PATCH}}
57 assertion2( tarch::la::greaterEquals( timeStamp, 0.0 ), timeStamp, timeStepSize );
58 assertion2( tarch::la::greaterEquals( timeStepSize, 0.0 ), timeStamp, timeStepSize );
60 ::exahype2::fd::validatePatch(
62 {{NUMBER_OF_UNKNOWNS}},
63 {{NUMBER_OF_AUXILIARY_VARIABLES}},
64 {{NUMBER_OF_GRID_CELLS_PER_PATCH_PER_AXIS}},
65 {{HALO_SIZE}}, // halo
66 std::string(__FILE__) + "(" + std::to_string(__LINE__) + "): " + marker.toString()
67 ); // previous time step has to be valid
75 Update one cell, i.e. compute Runge-Kutta step on it
77 This routine is very similar to the Finite Volume step. The big difference in
78 the context of Runge-Kutta is that we always have to construct a linear
79 combination of the input data and then write the new estimate for the
80 right-hand side into the large estimate field.
82 So we operate in two steps: First, we let the default block-structured code
83 reconstruct the old time step data. After that, we add the rhs estimates
84 onto this reconstructed data. The latter can be read as a correction step
85 to the reconstructed values. It is correct if and only if the haloes are
86 properly initialised with a corrected value, as we cannot correct the halo
90 # Correction terms with Runge-Kutta trials
92 We current the values with a linear combination of all of the estimates according to the
95 The linear combination is a volumetric representation which includes both
96 the degrees of freedom and the auxiliary variables. However, the auxiliary
97 variables are not developing over time. In Runge-Kutta, I have estimates
98 for the right-hand side, i.e. for the derivatives
100 @f$ \partial _t Q = F(Q) @f$
102 This is the stuff stored in RhsEstimates. It does not comprise any auxiliary
103 variables. So I have to copy the auxiliary variables from the last valid
104 time step every time I reconstruct a new guess.
110 SolveRiemannProblemsOverPatch = jinja2.Template( ReconstructLinearCombination +
"""
111 double subTimeStamp=timeStamp;
112 {% for PREDICATE_NO in range(0,PREDICATES|length) %}
113 if ({{PREDICATES[PREDICATE_NO]}}) {
114 subTimeStamp += {{BUTCHER_TABLEAU_RELATIVE_TIME_STEP_SIZES[PREDICATE_NO]}}*timeStepSize;
118 ::exahype2::CellData patchData( oldQWithHalo, marker.x(), marker.h(), subTimeStamp, timeStepSize, newQ );
120 ::exahype2::fd::{{KERNEL_NAMESPACE}}::{{COMPUTE_KERNEL_CALL}}
122 ::exahype2::fd::validatePatch(
124 {{NUMBER_OF_UNKNOWNS}},
125 {{NUMBER_OF_AUXILIARY_VARIABLES}},
126 {{NUMBER_OF_GRID_CELLS_PER_PATCH_PER_AXIS}},
128 std::string(__FILE__) + "(" + std::to_string(__LINE__) + "): " + marker.toString()
129 ); // outcome has to be valid
138 ReconstructPatchAndApplyFunctor.__init__(self,
139 patch = solver._patch,
140 patch_overlap = solver._patch_overlap_new,
141 functor_implementation =
"""
142#error please switch to your Riemann solver of choice
144 reconstructed_array_memory_location = solver._reconstructed_array_memory_location,
145 guard =
"not marker.willBeRefined() and not marker.hasBeenRefined()",
146 add_assertions_to_halo_exchange =
False
151 fineGridCell""" + solver._name +
"""CellLabel.setHasUpdated(false);
160 This is our plug-in point to alter the underlying dictionary
165 self.
_solver._init_dictionary_with_default_parameters(d)
166 self.
_solver.add_entries_to_text_replacement_dictionary(d)
168 d[
"PREDICATES" ] = [
169 "{} and repositories::{}.getSolverState()=={}::SolverState::RungeKuttaSubStep{}".format(self.
_solver._store_cell_data_default_guard(),self.
_solver.get_name_of_global_instance(),self.
_solver._name,step)
for step
in range(0,self.
_solver.number_of_Runge_Kutta_steps())
172 d[
"BUTCHER_TABLEAU_RELATIVE_TIME_STEP_SIZES" ] = self.
_butcher_tableau.time_step_sizes()
181#include "exahype2/enumerator/enumerator.h"
182#include "exahype2/fd/PatchUtils.h"
183#include "tarch/NonCriticalAssertions.h"
184""" + self.
_solver._get_default_includes() + self.
_solver.user_action_set_includes
192 Probably the simplest solver you could think off.
194 This particular variant works only for Runge-Kutta order greater or equal
198 :: Write your own specialisation ::
200 self._preprocess_reconstructed_patch
201 Has to hold any preprocessing, but it also has to set the doubles
202 timeStepSize and timeStamp to valid data.
204 self._postprocess_updated_patch
205 You don't have to redefine this one, but if you want to alter the
206 time step size, then this is the right place to do so. If you don't
207 alter timeStepSize, the code will automatically continue with
208 the current one subject to a preprocessing in the next step.
213 def __init__(self, name, patch_size, overlap, rk_order, unknowns, auxiliary_variables, min_meshcell_h, max_meshcell_h, plot_grid_properties, kernel_namespace):
216 Instantiate a generic FV scheme with an overlap of 1.
219 super(OneSweepPerRungeKuttaStep, self).
__init__(name, patch_size, overlap, rk_order, unknowns, auxiliary_variables, min_meshcell_h, max_meshcell_h, plot_grid_properties, kernel_namespace)
222 raise Exception(
"Runge-Kutta order has to be at least 1 but was {}".format(rk_order) )
236 Call the superclass' create_data_structures() to ensure that all the data
237 structures are in place, i.e. each cell can host a patch, that each face hosts
238 patch overlaps, and so forth. These quantities are all set to defaults. See
239 FV.create_data_structures().
241 After that, take the patch overlap (that's the data stored within the faces)
242 and ensure that these are sent and received via MPI whenever they are also
243 stored persistently. The default in FV is that no domain boundary data exchange
244 is active. Finally, ensure that the old data is only exchanged between the
245 initialisation sweep and the first first grid run-through.
250 initialisation_sweep_guard =
"(" + \
253 first_iteration_after_initialisation_guard =
"(" + \
262 self.
_patch_overlap_old.generator.receive_and_merge_condition = first_iteration_after_initialisation_guard
268 Call superclass routine and then reconfigure the update cell call.
269 Only the UpdateCell action set is specific to a single sweep.
271 This operation is implicity called via the superconstructor.
285#include "exahype2/CellData.h"
286""" + super(OneSweepPerRungeKuttaStep, self).user_action_set_includes
290 flux, ncp, source_term, eigenvalues,
291 boundary_conditions, refinement_criterion, initial_conditions,
293 additional_action_set_includes,
294 additional_user_includes
297 If you pass in User_Defined, then the generator will create C++ stubs
298 that you have to befill manually. If you pass in None_Implementation, it
299 will create nop, i.e. no implementation or defaults. Any other string
300 is copied 1:1 into the implementation. If you pass in None, then the
301 set value so far won't be overwritten.
308 if refinement_criterion==exahype2.solvers.PDETerms.None_Implementation:
309 assert False,
"refinement criterion cannot be none"
310 if initial_conditions==exahype2.solvers.PDETerms.None_Implementation:
311 assert False,
"initial conditions cannot be none"
321 raise Exception(
"memory mode without appropriate delete chosen, i.e. this will lead to a memory leak" )
331 d: Dictionary of string to string
Abstract solver for patch-based finite diffences.
_action_set_project_patch_onto_faces
_user_action_set_includes
_store_cell_data_default_guard(self)
Extend the guard via ands only.
get_name_of_global_instance(self)
number_of_Runge_Kutta_steps(self)
Return number of steps required to realise the Runge-Kutta scheme.
_solver_template_file_class_name
_boundary_conditions_implementation
_reconstructed_array_memory_location
create_action_sets(self)
Create required action sets.
_action_set_compute_final_linear_combination
_initial_conditions_implementation
_refinement_criterion_implementation
Probably the simplest solver you could think off.
create_action_sets(self)
Call superclass routine and then reconfigure the update cell call.
create_data_structures(self)
Call the superclass' create_data_structures() to ensure that all the data structures are in place,...
_eigenvalues_implementation
_refinement_criterion_implementation
_reconstructed_array_memory_location
_initial_conditions_implementation
__init__(self, name, patch_size, overlap, rk_order, unknowns, auxiliary_variables, min_meshcell_h, max_meshcell_h, plot_grid_properties, kernel_namespace)
Instantiate a generic FV scheme with an overlap of 1.
set_implementation(self, flux, ncp, source_term, eigenvalues, boundary_conditions, refinement_criterion, initial_conditions, memory_location, additional_action_set_includes, additional_user_includes)
If you pass in User_Defined, then the generator will create C++ stubs that you have to befill manuall...
add_entries_to_text_replacement_dictionary(self, d)
d: Dictionary of string to string in/out argument
_solver_template_file_class_name
_boundary_conditions_implementation
_source_term_implementation
user_action_set_includes(self)
Add further includes to this property, if your action sets require some additional routines from othe...
_add_action_set_entries_to_dictionary(self, d)
This is our plug-in point to alter the underlying dictionary.
__init__(self, solver)
patch: peano4.datamodel.Patch Patch which is to be used
_Template_TouchCellFirstTime_Preamble
SolveRiemannProblemsOverPatch
get_includes(self)
Return include statements that you need.