12 @todo Documntation missing
15 templateTouchCellFirstTime=
"""
17 fineGridCell{{SOLVER_NAME}}.getType() != celldata::{{SOLVER_NAME}}::Type::Coarse
19 // only one condition here - ensures that we don't do this when restricting the residual
20 repositories::{{SOLVER_INSTANCE}}.updateResidual()
22 logTraceInWith4Arguments("touchCellFirstTime(...)",
23 fineGridCell{{SOLVER_NAME}}.getSolution(),
24 fineGridCell{{SOLVER_NAME}}.getRhs(),
26 repositories::{{SOLVER_INSTANCE}}.getRhsMatrix( marker.x(), marker.h() )
29 const int OperatorSize = {{SOLVER_NAME}}::CellUnknowns * {{SOLVER_NAME}}::CellUnknowns;
32 * Lazy allocation of memory. In this particular realisation, it is never
33 * released. In principle, that's a reasonable strategy, although we might
34 * want to re-evaluate it later.
36 if (fineGridCell{{SOLVER_NAME}}.getInverseOfSystemMatrix()==nullptr) {
37 fineGridCell{{SOLVER_NAME}}.setInverseOfSystemMatrix(
38 tarch::allocateMemory<double>( OperatorSize, tarch::MemoryLocation::Heap )
42 auto rhsPointer = fineGridCell{{SOLVER_NAME}}.getRhsSmartPointer();
43 auto solutionPointer = fineGridCell{{SOLVER_NAME}}.getSolutionSmartPointer();
44 auto residualPointer = fineGridCell{{SOLVER_NAME}}.getResidualSmartPointer();
45 double* inverseOperator = fineGridCell{{SOLVER_NAME}}.getInverseOfSystemMatrix();
48 * Without the mutable keyword, the copied four arguments will stay const.
49 * C++ then complains as any assignment to a const copy becomes invalid.
51 * @todo There might be a lot of scope for optimisation
53 * It remains an open question to which degree these implementations can be
54 * optimised if we avoid copying forth and back into tarch vectors. We
55 * could set residualPointer to zero and then accumulate the outcome
56 * directly into this smart pointer.
58 auto updateResidualFunctor = [rhsPointer, solutionPointer, residualPointer, marker]() mutable -> void {
59 logTraceInWith1Argument( "UpdateResidualWithTasks - updateResidualFunctor", marker.toString() );
61 tarch::la::Vector< repositories::{{SOLVER_INSTANCE}}.CellUnknowns, double > r =
62 repositories::{{SOLVER_INSTANCE}}.applyRhsMatrix( marker.x(), marker.h(), rhsPointer.toVector() );
64 r = r - repositories::{{SOLVER_INSTANCE}}.applyLocalAssemblyMatrix(marker.x(), marker.h(), solutionPointer.toVector() );
68 logTraceOutWith1Argument( "UpdateResidualWithTasks - updateResidualFunctor", marker.toString() );
73 * Issue the calculation of the inverse of the system matrix
75 auto invertMatrixFunctor = [inverseOperator, marker, OperatorSize]() mutable -> void {
76 logTraceInWith1Argument( "UpdateResidualWithTasks - invertMatrixFunctor", marker.toString() );
79 repositories::{{SOLVER_INSTANCE}}.getInvertedApproxSystemMatrix(
83 sizeof(double)*OperatorSize
85 logTraceOutWith1Argument( "UpdateResidualWithTasks - invertMatrixFunctor", marker.toString() );
89 static int residualTaskType = peano4::parallel::getTaskType("{{SOLVER_INSTANCE}}::UpdateResidualTask");
90 static int invertMatrixTaskType = peano4::parallel::getTaskType("{{SOLVER_INSTANCE}}::InvertTask");
91 tarch::multicore::TaskWithCopyOfFunctor* updateResidualTask = new tarch::multicore::TaskWithCopyOfFunctor(
93 tarch::multicore::Task::DefaultPriority,
96 tarch::multicore::TaskWithCopyOfFunctor* invertMatrixTask = new tarch::multicore::TaskWithCopyOfFunctor(
98 tarch::multicore::Task::DefaultPriority,
103 int taskNumber = fineGridCell{{TASK_MARKER}}.getNumber() * 2;
104 tarch::multicore::spawnTask(
106 tarch::multicore::NoInDependencies,
109 tarch::multicore::spawnTask(
111 tarch::multicore::NoInDependencies,
114 logDebug( "touchCellFirstTime(...)", "issue tasks " << (taskNumber+0) << " and " << (taskNumber+1) << " for " << marker.toString() );
116 logTraceOut("touchCellFirstTime(...)");
123 descend_invocation_order=0,
125 super( UpdateResidualWithTasks, self ).
__init__(
126 descend_invocation_order,
130 self.
d[
"SOLVER_INSTANCE"] = solver.instance_name()
131 self.
d[
"SOLVER_NAME"] = solver.typename()
132 self.
d[
"TASK_MARKER"] = solver._task_name +
"MeshNumber"
136 if operation_name==peano4.solversteps.ActionSet.OPERATION_TOUCH_CELL_FIRST_TIME:
144 Configure name of generated C++ action set
146 This action set will end up in the directory observers with a name that
147 reflects how the observer (initialisation) is mapped onto this action
148 set. The name pattern is ObserverName2ActionSetIdentifier where this
149 routine co-determines the ActionSetIdentifier. We make is reflect the
153 return __name__.replace(
".py",
"").replace(
".",
"_")
158 The action set that Peano will generate that corresponds to this class
159 should not be modified by users and can safely be overwritten every time
160 we run the Python toolkit.
168 We need the solver repository in this action set, as we directly access
169 the solver object. We also need access to Peano's d-dimensional loops.
173#include "../repositories/SolverRepository.h"
175#include "peano4/utils/Loop.h"
176#include "tarch/multicore/Task.h"
177#include "tarch/multicore/multicore.h"
Action set (reactions to events)
__init__(self, solver, descend_invocation_order=0, parallel=True)
get_body_of_operation(self, operation_name)
Return actual C++ code snippets to be inserted into C++ code.
str templateTouchCellFirstTime
user_should_modify_template(self)
The action set that Peano will generate that corresponds to this class should not be modified by user...
get_includes(self)
We need the solver repository in this action set, as we directly access the solver object.
get_action_set_name(self)
Configure name of generated C++ action set.