Peano
Loading...
Searching...
No Matches
UpdateResidualWithTasks.py
Go to the documentation of this file.
1from peano4.solversteps.ActionSet import ActionSet
2
3import peano4
4import jinja2
5
6
8 """!
9
10 This is for DG solver
11
12 @todo Documntation missing
13
14 """
15 templateTouchCellFirstTime="""
16 if (
17 fineGridCell{{SOLVER_NAME}}.getType() != celldata::{{SOLVER_NAME}}::Type::Coarse
18 and
19 // only one condition here - ensures that we don't do this when restricting the residual
20 repositories::{{SOLVER_INSTANCE}}.updateResidual()
21 ) {
22 logTraceInWith4Arguments("touchCellFirstTime(...)",
23 fineGridCell{{SOLVER_NAME}}.getSolution(),
24 fineGridCell{{SOLVER_NAME}}.getRhs(),
25 marker.toString(),
26 repositories::{{SOLVER_INSTANCE}}.getRhsMatrix( marker.x(), marker.h() )
27 );
28
29 const int OperatorSize = {{SOLVER_NAME}}::CellUnknowns * {{SOLVER_NAME}}::CellUnknowns;
30
31 /**
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.
35 */
36 if (fineGridCell{{SOLVER_NAME}}.getInverseOfSystemMatrix()==nullptr) {
37 fineGridCell{{SOLVER_NAME}}.setInverseOfSystemMatrix(
38 tarch::allocateMemory<double>( OperatorSize, tarch::MemoryLocation::Heap )
39 );
40 }
41
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();
46
47 /**
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.
50 *
51 * @todo There might be a lot of scope for optimisation
52 *
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.
57 */
58 auto updateResidualFunctor = [rhsPointer, solutionPointer, residualPointer, marker]() mutable -> void {
59 logTraceInWith1Argument( "UpdateResidualWithTasks - updateResidualFunctor", marker.toString() );
60
61 tarch::la::Vector< repositories::{{SOLVER_INSTANCE}}.CellUnknowns, double > r =
62 repositories::{{SOLVER_INSTANCE}}.applyRhsMatrix( marker.x(), marker.h(), rhsPointer.toVector() );
63
64 r = r - repositories::{{SOLVER_INSTANCE}}.applyLocalAssemblyMatrix(marker.x(), marker.h(), solutionPointer.toVector() );
65
66 residualPointer = r;
67
68 logTraceOutWith1Argument( "UpdateResidualWithTasks - updateResidualFunctor", marker.toString() );
69 };
70
71
72 /**
73 * Issue the calculation of the inverse of the system matrix
74 */
75 auto invertMatrixFunctor = [inverseOperator, marker, OperatorSize]() mutable -> void {
76 logTraceInWith1Argument( "UpdateResidualWithTasks - invertMatrixFunctor", marker.toString() );
77 std::memcpy(
78 inverseOperator,
79 repositories::{{SOLVER_INSTANCE}}.getInvertedApproxSystemMatrix(
80 marker.x(),
81 marker.h()
82 ).data(),
83 sizeof(double)*OperatorSize
84 );
85 logTraceOutWith1Argument( "UpdateResidualWithTasks - invertMatrixFunctor", marker.toString() );
86 };
87
88
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(
92 residualTaskType,
93 tarch::multicore::Task::DefaultPriority,
94 updateResidualFunctor
95 );
96 tarch::multicore::TaskWithCopyOfFunctor* invertMatrixTask = new tarch::multicore::TaskWithCopyOfFunctor(
97 invertMatrixTaskType,
98 tarch::multicore::Task::DefaultPriority,
99 invertMatrixFunctor
100 );
101
102
103 int taskNumber = fineGridCell{{TASK_MARKER}}.getNumber() * 2;
104 tarch::multicore::spawnTask(
105 updateResidualTask,
106 tarch::multicore::NoInDependencies,
107 taskNumber+0
108 );
109 tarch::multicore::spawnTask(
110 invertMatrixTask,
111 tarch::multicore::NoInDependencies,
112 taskNumber+1
113 );
114 logDebug( "touchCellFirstTime(...)", "issue tasks " << (taskNumber+0) << " and " << (taskNumber+1) << " for " << marker.toString() );
115
116 logTraceOut("touchCellFirstTime(...)");
117 }
118 """
119
120
121 def __init__(self,
122 solver,
123 descend_invocation_order=0,
124 parallel=True):
125 super( UpdateResidualWithTasks, self ).__init__(
126 descend_invocation_order,
127 parallel
128 )
129 self.d = {}
130 self.d["SOLVER_INSTANCE"] = solver.instance_name()
131 self.d["SOLVER_NAME"] = solver.typename()
132 self.d["TASK_MARKER"] = solver._task_name + "MeshNumber"
133
134 def get_body_of_operation(self,operation_name):
135 result = ""
136 if operation_name==peano4.solversteps.ActionSet.OPERATION_TOUCH_CELL_FIRST_TIME:
137 result = jinja2.Template(self.templateTouchCellFirstTime).render(**self.d)
138 pass
139 return result
140
142 """!
143
144 Configure name of generated C++ action set
145
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
150 Python class name.
151
152 """
153 return __name__.replace(".py", "").replace(".", "_")
154
156 """!
157
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.
161
162 """
163 return False
164
165 def get_includes(self):
166 """!
167
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.
170
171 """
172 return """
173#include "../repositories/SolverRepository.h"
174
175#include "peano4/utils/Loop.h"
176#include "tarch/multicore/Task.h"
177#include "tarch/multicore/multicore.h"
178
179#include <cstring>
180"""
Action set (reactions to events)
Definition ActionSet.py:6
get_body_of_operation(self, operation_name)
Return actual C++ code snippets to be inserted into C++ code.
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.