4from .AbstractRungeKuttaDGActionSet
import AbstractRungeKuttaDGActionSet
17 Solve the volumetric part of the DG method. This includes the evaluation of the
18 volume integral of the operator multiplied with a trial function, plus the
19 subsequent multiplication with an inverted (lumped) mass matrix. So, eventually,
20 we do an explicit Euler step subject to a relaxed time step size from the Butcher
21 tableau. The input is already properly computed (see LinearCombinationOfEstimates()).
23 The volume integral definition is an underdetermined action set, i.e., you still
24 have to ensure that a number of macros are actually defined when you use it:
26 - {{COMPUTE_TIME_STEP_SIZE}} has to specify a double timeStepSize. It may be const if
27 you want. I don't alter it.
29 In return, the following variables will be set by the action set:
31 - timeStampOldSolution: double This is the time stamp of the original
32 solution, i.e. not the one we are currently evaluating due to the
34 - timeStamp: double This is the time stamp of the current Runge Kutta
35 guess. It is timeStampOldSolution plus the weight of the Butcher scheme
36 times the time step size.
37 - QIn: double* A pointer to the actual linear combination of previous
38 guesses according to the Butcher tableau.
39 - QOut: For Runge-Kutta, we ahve to store all guesses of the future solution,
40 so we can eventually combine them into one final outcome. QOut points to
41 that segment/guess that's to be computed in this step.
45 TemplateCellKernel =
"""
46 {% for PREDICATE_NO in range(0,PREDICATES|length) %}
47 if ({{PREDICATES[PREDICATE_NO]}}) {
48 const double timeStampOldSolution = fineGridCell{{SOLVER_NAME}}CellLabel.getTimeStamp();
51 // double timeStepSize
52 {{COMPUTE_TIME_STEP_SIZE}}
54 const double timeStamp = timeStampOldSolution + {{BUTCHER_TABLEAU_RELATIVE_TIME_STEP_SIZES[PREDICATE_NO]}} * timeStepSize;
56 assertion3( tarch::la::greaterEquals( timeStepSize, 0.0 ), timeStamp, timeStepSize, timeStampOldSolution );
57 assertion3( tarch::la::greaterEquals( timeStamp, 0.0 ), timeStamp, timeStepSize, timeStampOldSolution );
59 double* QIn = fineGridCell{{UNKNOWN_IDENTIFIER}}LinearCombination.value;
61 double* QOut = fineGridCell{{UNKNOWN_IDENTIFIER}}RhsEstimates.value + {{PREDICATE_NO}} * {{NUMBER_OF_DOFS_PER_CELL_2D}} * {{NUMBER_OF_UNKNOWNS}};
63 double* QOut = fineGridCell{{UNKNOWN_IDENTIFIER}}RhsEstimates.value + {{PREDICATE_NO}} * {{NUMBER_OF_DOFS_PER_CELL_3D}} * {{NUMBER_OF_UNKNOWNS}};
66 {% if SPAWN_VOLUME_KERNEL_AS_TASK %}
67 if (marker.willBeSkeletonCell()) {
68 ::exahype2::CellData cellData(
77 tasks::{{SOLVER_NAME}}_VolumetricSolverEnclaveTask::applyKernelToCell(
85 assertion(marker.willBeEnclaveCell());
86 assertion(not marker.willBeRefined());
87 auto newEnclaveTask = new tasks::{{SOLVER_NAME}}_VolumetricSolverEnclaveTask(
91 {% if MAKE_COPY_OF_ENCLAVE_TASK_DATA %}
94 fineGridCell{{UNKNOWN_IDENTIFIER}}LinearCombination.getSmartPointer(),
99 int predecessorEnclaveTaskNumber = fineGridCell{{SEMAPHORE_LABEL}}.getSemaphoreNumber();
101 tarch::multicore::spawnTask(
103 predecessorEnclaveTaskNumber>=0 ? std::set<int>{predecessorEnclaveTaskNumber} : tarch::multicore::NoInDependencies,
104 newEnclaveTask->getTaskId()
107 if (predecessorEnclaveTaskNumber>=0) {
108 ::exahype2::EnclaveTask::releaseTaskNumber(predecessorEnclaveTaskNumber);
111 fineGridCell{{SEMAPHORE_LABEL}}.setSemaphoreNumber(newEnclaveTask->getTaskId());
114 ::exahype2::CellData cellData(
123 {% if STATELESS_PDE_TERMS %}
124 if (repositories::{{SOLVER_INSTANCE}}.cellCanUseStatelessPDETerms(
130 ::exahype2::dg::{{KERNEL_NAMESPACE}}::{{VOLUMETRIC_COMPUTE_KERNEL_CALL_STATELESS}}
134 ::exahype2::dg::{{KERNEL_NAMESPACE}}::{{VOLUMETRIC_COMPUTE_KERNEL_CALL}}
141 def __init__(self,solver,spawn_volume_kernel_as_task = False):
143 guard_project: String (C++ code)
144 Predicate which controls if the solution is actually projected.
146 guard_safe_old_time_step: String (C++ code)
147 Predicate which controls if the projection should be copied into
148 the old solution and the time step should also be moved over.
150 super(SolveVolumeIntegral,self).
__init__(solver)
159 raise Exception(
"Guards are not initialised")
165 if new_guards!=[]
and len(new_guards)!=self.
_solver.number_of_Runge_Kutta_steps():
166 raise Exception(
"Expect one guard per Runge Kutta step. Have {} steps but got guards {}".format(solver.number_of_Runge_Kutta_steps(),guards) )
172 if operation_name==peano4.solversteps.ActionSet.OPERATION_TOUCH_CELL_FIRST_TIME:
174 self.
_solver._init_dictionary_with_default_parameters(d)
175 self.
_solver.add_entries_to_text_replacement_dictionary(d)
177 d[
"BUTCHER_TABLEAU_RELATIVE_TIME_STEP_SIZES" ] = self.
_butcher_tableau.time_step_sizes()
179 d[
"SEMAPHORE_LABEL" ] = exahype2.grid.UpdateCellLabel.get_attribute_name(self.
_solver._name)
186 return __name__.replace(
".py",
"").replace(
".",
"_")
191 return super( SolveVolumeIntegral, self ).
get_includes() +
"""
192#include "tasks/""" + self.
_solver._name +
"""_VolumetricSolverEnclaveTask.h"
195 return super( SolveVolumeIntegral, self ).
get_includes()
get_body_of_operation(self, operation_name)
Return actual C++ code snippets to be inserted into C++ code.
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.
spawn_volume_kernel_as_task
__init__(self, solver, spawn_volume_kernel_as_task=False)
guard_project: String (C++ code) Predicate which controls if the solution is actually projected.