3from .SeparateSweeps
import SeparateSweeps
17 ReconstructPatchAndApplyFunctor,
27 Update one cell that is compute Runge-Kutta step on it
29 This routine is significantly simpler than its counterpart in SeparateSweeps,
30 as we basically check if a cell is an enclave cell or not. If it is one, we
31 spawn a task. If not, we call the static routine from the task class which
32 updates the patch. All the computations thus are removed.
36 SolveRiemannProblemsOverPatch = jinja2.Template(
38 double timeStamp = fineGridCell{{SOLVER_NAME}}CellLabel.getTimeStamp();
41 // double timeStepSize
42 {{COMPUTE_TIME_STEP_SIZE}}
44 if ({{PREDICATES[0]}}) {
45 if (marker.willBeEnclaveCell() and {{DEVICE_RESIDENT_RK}}) {
46 // The device memory for each cell is maintained across Runge-Kutta substeps to reduce the number of allocations and deallocations.
47 // The deallocation takes place in ComputeFinalLinearCombination, which is the last step of a Runge-Kutta time step
48 ::exahype2::enumerator::AoSLexicographicEnumerator enumeratorWithAuxiliaryVariablesOnReconstructedPatch( 1, {{NUMBER_OF_GRID_CELLS_PER_PATCH_PER_AXIS}}, {{HALO_SIZE}}, {{NUMBER_OF_UNKNOWNS}}, {{NUMBER_OF_AUXILIARY_VARIABLES}});
50 fineGridCell{{SOLVER_NAME}}CellLabel.setDeviceNumber(device);
51 fineGridCell{{SOLVER_NAME}}CellLabel.setDeviceMemoryAddress(tarch::accelerator::GPUMemoryManager::getInstance().allocate<double>(enumeratorWithAuxiliaryVariablesOnReconstructedPatch.size(), device));
52 fineGridCell{{SOLVER_NAME}}CellLabel.setDeviceMemoryStatus(celldata::{{SOLVER_NAME}}CellLabel::DeviceMemoryStatus::OutOfDate);
53 fineGridCell{{UNKNOWN_IDENTIFIER}}RhsEstimates.reallocateOnDevice(device);
55 omp_target_memcpy(fineGridCell{{SOLVER_NAME}}CellLabel.getDeviceMemoryAddress(), oldQWithHalo, enumeratorWithAuxiliaryVariablesOnReconstructedPatch.size() * sizeof(double), 0, 0, device, omp_get_initial_device());
60 {% for PREDICATE_NO in range(0,PREDICATES|length) %}
61 if ({{PREDICATES[PREDICATE_NO]}}) {
62 ::exahype2::enumerator::AoSLexicographicEnumerator enumeratorWithAuxiliaryVariablesOnReconstructedPatch( 1, {{NUMBER_OF_GRID_CELLS_PER_PATCH_PER_AXIS}}, {{HALO_SIZE}}, {{NUMBER_OF_UNKNOWNS}}, {{NUMBER_OF_AUXILIARY_VARIABLES}});
63 ::exahype2::enumerator::AoSLexicographicEnumerator enumeratorWithoutAuxiliaryVariables( {{RK_STEPS}}, {{NUMBER_OF_GRID_CELLS_PER_PATCH_PER_AXIS}}, 0, {{NUMBER_OF_UNKNOWNS}}, 0 );
65 if (marker.willBeEnclaveCell() and {{DEVICE_RESIDENT_RK}}) {
66 ::exahype2::fd::fd4::omp::computeLinearCombinationStateless<{{SOLVER_NAME}}, {{NUMBER_OF_GRID_CELLS_PER_PATCH_PER_AXIS}}, {{HALO_SIZE}}, {{NUMBER_OF_UNKNOWNS}}, {{NUMBER_OF_AUXILIARY_VARIABLES}}, {{RK_ORDER}}, {{PREDICATE_NO}}>(fineGridCell{{SOLVER_NAME}}CellLabel.getDeviceNumber(), fineGridCell{{UNKNOWN_IDENTIFIER}}RhsEstimates.value, fineGridCell{{SOLVER_NAME}}CellLabel.getDeviceMemoryAddress(), timeStepSize);
68 dfor( dof, {{NUMBER_OF_GRID_CELLS_PER_PATCH_PER_AXIS}} ) {
69 for (int unknown=0; unknown<{{NUMBER_OF_UNKNOWNS}}; unknown++) {
70 {% for WEIGHT_NO in range(0,BUTCHER_TABLEAU_WEIGHTS[PREDICATE_NO]|length) %}
71 {% if BUTCHER_TABLEAU_WEIGHTS[PREDICATE_NO][WEIGHT_NO]!=0 %}
72 oldQWithHalo[ enumeratorWithAuxiliaryVariablesOnReconstructedPatch(0,dof,unknown) ] +=
73 timeStepSize * {{BUTCHER_TABLEAU_WEIGHTS[PREDICATE_NO][WEIGHT_NO]}} *
74 fineGridCell{{UNKNOWN_IDENTIFIER}}RhsEstimates.value[ enumeratorWithoutAuxiliaryVariables({{WEIGHT_NO}},dof,unknown) ];
81 newQ = fineGridCell{{UNKNOWN_IDENTIFIER}}RhsEstimates.value + enumeratorWithoutAuxiliaryVariables({{PREDICATE_NO}},0,0);
85 {{PREPROCESS_RECONSTRUCTED_PATCH}}
87 assertion2( tarch::la::greaterEquals( timeStamp, 0.0 ), timeStamp, timeStepSize );
88 assertion2( tarch::la::greaterEquals( timeStepSize, 0.0 ), timeStamp, timeStepSize );
90 ::exahype2::fd::validatePatch(
92 {{NUMBER_OF_UNKNOWNS}},
93 {{NUMBER_OF_AUXILIARY_VARIABLES}},
94 {{NUMBER_OF_GRID_CELLS_PER_PATCH_PER_AXIS}},
95 {{HALO_SIZE}}, // halo
96 std::string(__FILE__) + "(" + std::to_string(__LINE__) + "): " + marker.toString()
97 ); // previous time step has to be valid
99 double subTimeStamp=timeStamp;
100 {% for PREDICATE_NO in range(0,PREDICATES|length-1) %}
101 if ({{PREDICATES[PREDICATE_NO]}}) {
102 subTimeStamp += {{BUTCHER_TABLEAU_RELATIVE_TIME_STEP_SIZES[PREDICATE_NO]}}*timeStepSize;
106 if ( marker.willBeSkeletonCell() ) {
107 tasks::{{SOLVER_NAME}}EnclaveTask::applyKernelToCell(
115 fineGridCell{{SEMAPHORE_LABEL}}.setSemaphoreNumber( ::exahype2::EnclaveBookkeeping::SkeletonTask );
118 assertion( marker.willBeEnclaveCell() );
119 assertion( not marker.willBeRefined() );
120 ::exahype2::enumerator::AoSLexicographicEnumerator enumeratorWithAuxiliaryVariablesOnReconstructedPatch( 1, {{NUMBER_OF_GRID_CELLS_PER_PATCH_PER_AXIS}}, {{HALO_SIZE}}, {{NUMBER_OF_UNKNOWNS}}, {{NUMBER_OF_AUXILIARY_VARIABLES}});
122 tasks::{{SOLVER_NAME}}EnclaveTask* newEnclaveTask;
123 if ({{DEVICE_RESIDENT_RK}}){
124 // The reconstructed patch is copied into the allocated device memory for the cell
125 const int device = fineGridCell{{SOLVER_NAME}}CellLabel.getDeviceNumber();
126 fineGridCell{{SOLVER_NAME}}CellLabel.setDeviceMemoryStatus(celldata::{{SOLVER_NAME}}CellLabel::DeviceMemoryStatus::UpToDate);
128 newEnclaveTask = new tasks::{{SOLVER_NAME}}EnclaveTask(
132 fineGridCell{{SOLVER_NAME}}CellLabel.getDeviceMemoryAddress(),
133 {% if MAKE_COPY_OF_ENCLAVE_TASK_DATA %}
141 newEnclaveTask = new tasks::{{SOLVER_NAME}}EnclaveTask(
146 {% if MAKE_COPY_OF_ENCLAVE_TASK_DATA %}
154 int predecessorEnclaveTaskNumber = fineGridCell{{SEMAPHORE_LABEL}}.getSemaphoreNumber();
156 fineGridCell{{SEMAPHORE_LABEL}}.setSemaphoreNumber( newEnclaveTask->getTaskId() );
158 tarch::multicore::spawnTask(
160 predecessorEnclaveTaskNumber>=0 ? std::set<int>{predecessorEnclaveTaskNumber} : tarch::multicore::NoInDependencies,
161 newEnclaveTask->getTaskId()
164 if (predecessorEnclaveTaskNumber>=0) {
165 ::exahype2::EnclaveTask::releaseTaskNumber(predecessorEnclaveTaskNumber);
168 // Time stamp is not updated, as this will be done by final linear combination
169 // fineGridCell{{SOLVER_NAME}}CellLabel.setTimeStamp(timeStamp + timeStepSize);
177 one_huge_boolean_guard_expression =
"false"
178 for expr
in solver._primary_sweeps_of_Runge_Kutta_step_on_cell:
179 one_huge_boolean_guard_expression +=
" or (" + expr +
")"
183 patch_overlap=solver._patch_overlap_new,
184 functor_implementation=
"""
185#error please switch to your Riemann solver of choice
187 reconstructed_array_memory_location=peano4.toolbox.blockstructured.ReconstructedArrayMemoryLocation.ManagedSharedAcceleratorDeviceMemoryThroughTarchWithoutDelete,
188 guard=one_huge_boolean_guard_expression,
189 add_assertions_to_halo_exchange=
False,
197 +
"""CellLabel.setHasUpdated(false);
208 This is our plug-in point to alter the underlying dictionary
213 self.
_solver._init_dictionary_with_default_parameters(d)
214 self.
_solver.add_entries_to_text_replacement_dictionary(d)
216 d[
"PREDICATES"] = self.
_solver._primary_sweeps_of_Runge_Kutta_step_on_cell
219 "BUTCHER_TABLEAU_RELATIVE_TIME_STEP_SIZES"
232#include "tarch/NonCriticalAssertions.h"
233#include "exahype2/enumerator/enumerator.h"
234#include "exahype2/fd/PatchUtils.h"
235#include "exahype2/EnclaveBookkeeping.h"
236#include "tarch/multicore/Task.h"
238 + self.
_solver._get_default_includes()
239 + self.
_solver.user_action_set_includes
243 self.
_solver._enclave_task_name()
248 return __name__.replace(
".py",
"").replace(
".",
"_") +
"_UpdateCell"
253 {% for PREDICATE_NO in range(0,PREDICATES|length) %}
255 not marker.hasBeenRefined()
257 marker.hasBeenEnclaveCell()
259 {{PREDICATES[PREDICATE_NO]}}
261 const int taskNumber = fineGridCell{{LABEL_NAME}}.getSemaphoreNumber();
262 if ( taskNumber>=0 ) {
263 double maxEigenvalue; // not used here
264 if ({{DEVICE_RESIDENT_RK}}){
265 ::exahype2::EnclaveBookkeeping::getInstance().waitForTaskToTerminateAndWriteResultDirectly( taskNumber, marker.x(), marker.h() );
268 constexpr int NumberOfDoFsPerCell = {{NUMBER_OF_GRID_CELLS_PER_PATCH_PER_AXIS}} * {{NUMBER_OF_GRID_CELLS_PER_PATCH_PER_AXIS}};
269 double* QOut = fineGridCell{{UNKNOWN_IDENTIFIER}}RhsEstimates.value + {{PREDICATE_NO}} * NumberOfDoFsPerCell * {{NUMBER_OF_UNKNOWNS}};
271 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}};
272 double* QOut = fineGridCell{{UNKNOWN_IDENTIFIER}}RhsEstimates.value + {{PREDICATE_NO}} * NumberOfDoFsPerCell * {{NUMBER_OF_UNKNOWNS}};
274 ::exahype2::EnclaveBookkeeping::getInstance().waitForTaskToTerminateAndCopyResultOver( taskNumber, QOut, maxEigenvalue, marker.x(), marker.h() );
276 fineGridCell{{LABEL_NAME}}.setSemaphoreNumber( ::exahype2::EnclaveBookkeeping::NoEnclaveTaskNumber );
283 super(MergeEnclaveTaskOutcome, self).
__init__(solver)
285 self.
label_name = exahype2.grid.UpdateCellLabel.get_attribute_name(solver._name)
292 == peano4.solversteps.ActionSet.OPERATION_TOUCH_CELL_FIRST_TIME
295 self.
_solver._init_dictionary_with_default_parameters(d)
296 self.
_solver.add_entries_to_text_replacement_dictionary(d)
298 d[
"PREDICATES"] = self.
_solver._secondary_sweeps_of_Runge_Kutta_step_on_cell
300 result = jinja2.Template(self.
Template).render(**d)
306 __name__.replace(
".py",
"").replace(
".",
"_") +
"_MergeEnclaveTaskOutcome"
313#include "exahype2/EnclaveBookkeeping.h"
321 Enclave variant of the solver where we still run through mesh once per Runge-Kutta sweep
323 The concept of (enclave) tasking within ExaHyPE solvers is described in
324 detail in the @ref page_exahype_solvers_enclave_solvers "generic enclave discussion of ExaHyPE".
325 This class is a prototype realisation of this concept which other solvers
326 then specialise for particular numerical schemes.
328 The class basically replaces the standard "update a cell" action set with an
329 action set that might or might not spawn a task. In return, it adds a further
330 action set which merges the arising task outcomes into the actual mesh
331 structure. By default, we use peano4::datamanagement::CellMarker::willBeEnclaveCell()
332 and peano4::datamanagement::CellMarker::hasBeenEnclaveCell() to guide the
333 decision whether to spawn a task or not. You can overwrite this decision
334 by redefining the corresponding entry in the dictionary befilled by
335 add_entries_to_text_replacement_dictionary().
339 Use the attributes self.enclave_task_priority to change the priority of the
340 task. This value can either be a string that C++ can evaluate into a
341 priority or a plain numerical value. I set it to
343 self.enclave_task_priority = "tarch::multicore::Task::DefaultPriority-1"
360 plot_grid_properties,
362 pde_terms_without_state,
363 device_resident_rk = False
371 "{} and repositories::{}.getSolverState()=={}::SolverState::RungeKuttaPrimarySubStep{}".format(
379 "{} and repositories::{}.getSolverState()=={}::SolverState::RungeKuttaPrimarySubStep0AfterGridInitialisation".format(
386 "{} and repositories::{}.getSolverState()=={}::SolverState::RungeKuttaSecondarySubStep{}".format(
401 "{} and repositories::{}.getSolverState()=={}::SolverState::RungeKuttaPrimarySubStep{}".format(
409 "{} and repositories::{}.getSolverState()=={}::SolverState::RungeKuttaPrimarySubStep0AfterGridInitialisation".format(
416 "{} and repositories::{}.getSolverState()=={}::SolverState::RungeKuttaSecondarySubStep{}".format(
429 +
".getSolverState()=="
431 +
"::SolverState::RungeKuttaPrimarySubStep0AfterGridInitialisation "
434 self.
_primary_sweep_guard +=
" or repositories::{}.getSolverState()=={}::SolverState::RungeKuttaPrimarySubStep{}".format(
440 repositories::{}.getSolverState()=={}::SolverState::RungeKuttaPrimarySubStep0AfterGridInitialisation
441 or repositories::{}.getSolverState()=={}::SolverState::PlottingAfterGridInitialisation
442 or repositories::{}.getSolverState()=={}::SolverState::Plotting
443 or repositories::{}.getSolverState()=={}::SolverState::Suspended
460 self.
_secondary_sweep_guard +=
" or repositories::{}.getSolverState()=={}::SolverState::RungeKuttaSecondarySubStep{}".format(
466 repositories::{}.getSolverState()=={}::SolverState::GridInitialisation""".format(
475 super(SeparateSweepsWithEnclaveTasking, self).
__init__(
484 plot_grid_properties,
491 "#error Not yet defined. Set in your Python solver class."
494 "#error Not yet defined. Set in your Python solver class."
511 tensor = tensor.replace(
"{{",
"{ {")
512 tensor = tensor.replace(
"}}",
"} }")
522 Call the superclass' create_data_structures() to ensure that all the data
523 structures are in place, i.e. each cell can host a patch, that each face hosts
524 patch overlaps, and so forth. These quantities are all set to defaults. See
525 FV.create_data_structures().
527 After that, take the patch overlap (that's the data stored within the faces)
528 and ensure that these are sent and received via MPI whenever they are also
529 stored persistently. The default in FV is that no domain boundary data exchange
530 is active. Finally, ensure that the old data is only exchanged between the
531 initialisation sweep and the first first grid run-through.
536 initialisation_sweep_guard = (
540 +
".getSolverState()=="
542 +
"::SolverState::GridInitialisation"
545 first_iteration_after_initialisation_guard = (
549 +
".getSolverState()=="
551 +
"::SolverState::RungeKuttaPrimarySubStep0AfterGridInitialisation or "
554 +
".getSolverState()=="
556 +
"::SolverState::PlottingAfterGridInitialisation"
562 first_iteration_after_initialisation_guard
565 secondary_sweep_or_initialisation_or_plotting_guard =
"""(
566 repositories::{}.getSolverState()=={}::SolverState::GridInitialisation or
567 repositories::{}.getSolverState()=={}::SolverState::PlottingAfterGridInitialisation or
568 repositories::{}.getSolverState()=={}::SolverState::Plotting or
569 repositories::{}.getSolverState()=={}::SolverState::Suspended or
570 repositories::{}.isLastGridSweepOfTimeStep()
579 primary_sweep_or_plotting =
"""(
580 repositories::{}.getSolverState()=={}::SolverState::PlottingAfterGridInitialisation or
581 repositories::{}.getSolverState()=={}::SolverState::Plotting or
582 repositories::{}.getSolverState()=={}::SolverState::Suspended or
583 repositories::{}.isFirstGridSweepOfTimeStep()
592 secondary_sweep_or_initialisation_or_plotting_guard
595 primary_sweep_or_plotting
598 first_sweep_of_time_step_or_plotting_guard =
"""(
599 repositories::{}.isFirstGridSweepOfTimeStep() or
600 repositories::{}.getSolverState()=={}::SolverState::PlottingAfterGridInitialisation or
601 repositories::{}.getSolverState()=={}::SolverState::Plotting or
602 repositories::{}.getSolverState()=={}::SolverState::Suspended
610 last_sweep_of_time_step_or_plotting_or_initialisation =
"""(
611 repositories::{}.getSolverState()=={}::SolverState::GridInitialisation or
612 repositories::{}.getSolverState()=={}::SolverState::PlottingAfterGridInitialisation or
613 repositories::{}.getSolverState()=={}::SolverState::Plotting or
614 repositories::{}.getSolverState()=={}::SolverState::Suspended or
615 repositories::{}.isLastGridSweepOfTimeStep()
624 self.
_patch_estimates.generator.load_store_compute_flag =
"::peano4::grid::constructLoadStoreComputeFlag({},{},{})".format(
629 + first_sweep_of_time_step_or_plotting_guard
634 + last_sweep_of_time_step_or_plotting_or_initialisation
641 Call superclass routine and then reconfigure the update cell call.
642 Only the UpdateCell action set is specific to a single sweep.
644 This operation is implicity called via the superconstructor.
646 ## Guard construction
648 We note that the guard sets all contain the storage predicate already,
649 i.e. they combine the logic state analysis with an evaluation of
650 _load_cell_data_default_guard() and _store_cell_data_default_guard().
651 The singular strings like _primary_sweep_guard do not have this check
652 built in. We have to add it here.
690 "{} and repositories::{}.getSolverState()=={}::SolverState::GridInitialisation".format(
710 Add the enclave task for the GPU
712 See superclass for further information.
716 SeparateSweepsWithEnclaveTasking, self
718 templatefile_prefix = os.path.join(
719 os.path.dirname(os.path.realpath(__file__)),
720 "SeparateSweeps.EnclaveTask.template",
726 implementationDictionary = {}
736 generated_solver_files = (
738 "{}.h".format(templatefile_prefix),
739 "{}.cpp".format(templatefile_prefix),
741 namespace + [
"tasks"],
742 subdirectory +
"tasks",
743 implementationDictionary,
748 output.add(generated_solver_files)
749 output.makefile.add_cpp_file(subdirectory +
"tasks/" + task_name +
".cpp", generated=
True)
757 Add enclave aspect to time stepping. If you study the superclass'
758 routine add_actions_to_perform_time_step() and consider that this action
759 set is invoked in the secondary grid sweep, then it becomes clear that
760 this merger has to come first, i.e. we first add the action set and then
761 we call the superclass' add_action_set().
763 We need the result of the volumetric operation before we sum up this
764 volumetric solution and the Riemann solution.
774 SeparateSweepsWithEnclaveTasking, self
777 d[
"FUSED_COMPUTE_KERNEL_CALL_CPU"] = jinja2.Template(
780 d[
"FUSED_COMPUTE_KERNEL_CALL_GPU"] = jinja2.Template(
784 d[
"SEMAPHORE_LABEL"] = exahype2.grid.UpdateCellLabel.get_attribute_name(
796#include "exahype2/CellData.h"
798 + super(SeparateSweeps, self).user_action_set_includes
806 cell_data_storage: Storage,
807 face_data_storage: Storage,
809 if cell_data_storage == Storage.SmartPointers:
_load_face_data_default_guard(self)
Extend the guard via ands only.
_provide_cell_data_to_compute_kernels_default_guard(self)
_action_set_project_patch_onto_faces
_store_cell_data_default_guard(self)
Extend the guard via ands only.
_action_set_roll_over_update_of_faces
user_action_set_includes(self)
Add further includes to this property, if your action sets require some additional routines from othe...
_load_cell_data_default_guard(self)
Extend the guard via ands only.
_action_set_couple_resolution_transitions_and_handle_dynamic_mesh_refinement
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
_baseline_action_set_descend_invocation_order
user_solver_includes(self)
Add further includes to this property, if your solver requires some additional routines from other he...
_init_dictionary_with_default_parameters(self, d)
This one is called by all algorithmic steps before I invoke add_entries_to_text_replacement_dictionar...
add_solver_constants(self, datastring)
create_data_structures(self)
Recall in subclasses if you wanna change the number of unknowns or auxiliary variables.
create_action_sets(self)
Create required action sets.
_store_face_data_default_guard(self)
Extend the guard via ands only.
_action_set_handle_boundary
add_entries_to_text_replacement_dictionary(self, d)
_action_set_compute_final_linear_combination
get_body_of_operation(self, operation_name)
Return actual C++ code snippets to be inserted into C++ code.
__init__(self, solver)
solver: ADERDG Reference to creating class
get_action_set_name(self)
You should replicate this function in each subclass, so you get meaningful action set names (otherwis...
get_includes(self)
Return include statements that you need.
Enclave variant of the solver where we still run through mesh once per Runge-Kutta sweep.
_fused_volumetric_kernel_call_cpu
switch_storage_scheme(self, Storage cell_data_storage, Storage face_data_storage)
By default, we hold all data on the call stacks.
_secondary_sweeps_of_Runge_Kutta_step_on_face
_fused_compute_kernel_call_gpu
_fused_volumetric_kernel_call_gpu
create_data_structures(self)
Call the superclass' create_data_structures() to ensure that all the data structures are in place,...
_action_set_merge_enclave_task_outcome
_solver_template_file_class_name
_primary_sweep_or_plot_guard
_primary_sweeps_of_Runge_Kutta_step_on_cell
make_copy_of_enclave_task_data
_secondary_sweeps_of_Runge_Kutta_step_on_cell
add_actions_to_perform_time_step(self, step)
Add enclave aspect.
add_implementation_files_to_project(self, namespace, output, dimensions, subdirectory="")
Add the enclave task for the GPU.
_fused_compute_kernel_call_cpu
_last_secondary_sweep_of_Runge_Kutta_step_on_cell
add_entries_to_text_replacement_dictionary(self, d)
d: Dictionary of string to string in/out argument
__init__(self, name, patch_size, overlap, rk_order, unknowns, auxiliary_variables, min_meshcell_h, max_meshcell_h, plot_grid_properties, kernel_namespace, pde_terms_without_state, device_resident_rk=False)
Instantiate a generic FV scheme with an overlap of 1.
_secondary_sweep_or_initialisation_guard
_primary_sweeps_of_Runge_Kutta_step_on_face
create_action_sets(self)
Call superclass routine and then reconfigure the update cell call.
user_action_set_includes(self)
Add further includes to this property, if your action sets require some additional routines from othe...
Update one cell that is compute Runge-Kutta step on it.
_Template_TouchCellFirstTime_Preamble
__init__(self, solver)
patch: peano4.datamodel.Patch Patch which is to be used
_add_action_set_entries_to_dictionary(self, d)
This is our plug-in point to alter the underlying dictionary.
get_action_set_name(self)
Return unique action set name.
get_includes(self)
Return include statements that you need.
SolveRiemannProblemsOverPatch
Probably the simplest solver you could think off.
add_entries_to_text_replacement_dictionary(self, d)
d: Dictionary of string to string in/out argument
user_action_set_includes(self)
Add further includes to this property, if your action sets require some additional routines from othe...
create_data_structures(self)
Call the superclass' create_data_structures() to ensure that all the data structures are in place,...
create_action_sets(self)
Call superclass routine and then reconfigure the update cell call.
_solver_template_file_class_name