3from .AbstractFVActionSet
import AbstractFVActionSet
4from .UpdateCellInterior
import UpdateCellInterior
12 Update the patch interior with a damped time step size
14 The action set takes the admissible time step size of the current time
15 step, i.e. the fourth entry of solver._max_eigenvalue_and_time_step_sizes
16 (@see exahype2.api.fv.actionsets.ReadjustTimeStepSizeForOptimisticGlobalTimestepping),
17 multiplies it with damp_time_step_size, and stores the result as
18 estimated time step size in the second entry. Afterwards, it updates the
19 patch interior with this damped time step size (@see
20 exahype2.api.fv.actionsets.UpdateCellInterior and
21 exahype2.api.fv.RusanovWithOptimisticExplicitEuler). As the admissible
22 time step size is never damped itself, the estimates do not shrink from
23 time step to time step.
25 The action set has to run before
26 exahype2.api.fv.actionsets.ComputeGlobalCFLCondition, which is why
27 exahype2.api.fv.RusanovWithOptimisticExplicitEuler makes the CFL
28 condition's task depend on the spawn's task. This way, the order in
29 which the tasks are added to the task graph does not matter. The CFL
30 condition advances the solver's time stamp and time step size
31 straightaway. Before it runs, the solver still holds the time stamp
32 and time step size of the current time step. The patch, however, has
33 already been advanced by the current time step. The patch interior
34 update hence starts from the solver's time stamp plus its time step
37 If the admissible time step size is zero, i.e. in the very first time
38 step, there is nothing to estimate from. The action set then does not
39 update the patch interior. It sets the maximum eigenvalue of the patch
40 interior (third entry) to zero and the estimated time step size
41 (second entry) to the maximum double value, so the next time step
42 takes the traditional route.
44 ## Spawning the update as a task
46 If the action set is given the cell data holding a task number, it does
47 not update the patch interior straightaway. Instead, it takes a new task
48 number, stores it in the cell data, and spawns the update as a task
49 with this number. exahype2.api.fv.actionsets.InsertPatchInterior and
50 exahype2.api.fv.actionsets.DiscardPatchInterior wait for this task.
51 If there is nothing to update, the action set stores
52 tarch::multicore::TaskEnumerator::NoNumber instead.
54 The task captures the cell data by value. As the patch interior and the
55 eigenvalue data are managed via smart pointers, the task writes into the
56 cell's data. The patch, however, is handed to the task as a private copy,
57 as the next time step updates the patch's shell, which the task reads,
58 while the task might still be running. The time stamp and the time step
59 size are evaluated before the task is spawned, as the CFL condition
60 changes the solver's values afterwards.
64 def __init__(self, solver, damp_time_step_size, guard, task_number=None):
67 @param solver: exahype2.api.Solver
68 Has to have solver._patch, solver._patch_interior,
69 solver._max_eigenvalue_and_time_step_sizes and
70 solver.compute_kernel_call_on_patch_interior set - @see
71 exahype2.api.fv.RusanovWithOptimisticExplicitEuler.
73 @param damp_time_step_size: float
74 Factor the solver's current time step size is scaled with to
75 obtain the estimated time step size of the patch interior update.
78 C++ boolean expression, evaluated per cell in touchCellFirstTime,
79 guarding whether the patch interior of that cell is updated.
81 @param task_number: peano4.api.datamodel.DaStGen2
82 Cell data holding the number of the task updating the patch
83 interior. If None, the update runs straightaway.
86 AbstractFVActionSet.__init__(self, solver)
90 if task_number
is None:
94 time_step_size=
"dampedTimeStepSize",
95 time_stamp=f
"repositories::{solver.get_name_of_global_instance()}.getMinTimeStamp() + "
96 f
"repositories::{solver.get_name_of_global_instance()}.getMinTimeStepSize()",
102 time_step_size=
"dampedTimeStepSize",
103 time_stamp=
"timeStampOfPatchInteriorUpdate",
104 input=
"patchCopy->data()",
109 if operation_name == peano4.api.solversteps.ActionSet.OPERATION_TOUCH_CELL_FIRST_TIME:
110 solver = f
"repositories::{self._solver.get_name_of_global_instance()}"
111 data = f
"fineGridCell{self._solver._max_eigenvalue_and_time_step_sizes.name}"
115 if ( tarch::la::equals({data}.getMaxEigenvalue(3), 0.0) ) {{
116 {data}.setMaxEigenvalue( 1, std::numeric_limits<double>::max() );
117 {data}.setMaxEigenvalue( 2, 0.0 );
120 double dampedTimeStepSize = {self.damp_time_step_size} * {data}.getMaxEigenvalue(3);
121 {data}.setMaxEigenvalue( 1, dampedTimeStepSize );
126 task_number = f
"fineGridCell{self.task_number.name}"
127 patch = f
"fineGridCell{self._solver._patch.name}"
129 if ( tarch::la::equals({data}.getMaxEigenvalue(3), 0.0) ) {{
130 {data}.setMaxEigenvalue( 1, std::numeric_limits<double>::max() );
131 {data}.setMaxEigenvalue( 2, 0.0 );
132 {task_number}.setTaskNumber( tarch::multicore::TaskEnumerator::NoNumber );
135 const double dampedTimeStepSize = {self.damp_time_step_size} * {data}.getMaxEigenvalue(3);
136 const double timeStampOfPatchInteriorUpdate = {solver}.getMinTimeStamp() + {solver}.getMinTimeStepSize();
137 {data}.setMaxEigenvalue( 1, dampedTimeStepSize );
139 // The next time step updates the patch's shell while the task might still run
140 auto patchCopy = std::make_shared< std::vector<double> >( {patch}.Cardinality );
141 for (int i=0; i<{patch}.Cardinality; i++) {{
142 (*patchCopy)[i] = {patch}.value[i];
145 const int taskNumber = {task_number}.getTaskEnumerator().getNumber();
146 {task_number}.setTaskNumber( taskNumber );
147 tarch::multicore::spawnTask(
148 new tarch::multicore::TaskWithCopyOfFunctor(
149 tarch::multicore::Task::DontFuse,
150 tarch::multicore::Task::DefaultPriority,
155 tarch::multicore::NoInDependencies,
163 if operation_name == peano4.api.solversteps.ActionSet.OPERATION_TOUCH_CELL_FIRST_TIME:
170#include "tarch/la/ScalarOperations.h"
176#include "tarch/multicore/multicore.h"
177#include "tarch/multicore/Task.h"
178#include "tarch/multicore/TaskEnumerator.h"
183 return __name__.replace(
".py",
"").replace(
".",
"_")
Update the patch interior with a damped time step size.
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.
get_guard_of_operation(self, operation_name)
Return the guard of an operation.
__init__(self, solver, damp_time_step_size, guard, task_number=None)
Update the patch interior of a Finite Volume patch.