Peano
Loading...
Searching...
No Matches
ResetAndUpdateResidual.py
Go to the documentation of this file.
1from peano4.solversteps.ActionSet import ActionSet
2
3import peano4
4import jinja2
5
7 templateTouchVertexFirstTime = """
8 if (
9 fineGridVertex{{SOLVER_NAME}}.getType() == vertexdata::{{SOLVER_NAME}}::Type::Boundary
10 and
11 repositories::{{SOLVER_INSTANCE}}.updateResidual( fineGridVertex{{SOLVER_NAME}}.getLevel() )
12 ) {
13 logTraceInWith1Argument("TouchVertexFirstTimeBoundary", fineGridVertex{{SOLVER_NAME}}.toString());
14 auto value = fineGridVertex{{SOLVER_NAME}}.getU();
15 repositories::{{SOLVER_INSTANCE}}.setBoundaryConditions(
16 marker.x(),
17 marker.h(),
18 value
19 );
20 fineGridVertex{{SOLVER_NAME}}.setU(value);
21 logTraceOutWith1Argument("TouchVertexFirstTimeBoundary", fineGridVertex{{SOLVER_NAME}}.toString());
22 }
23 else if (
24 fineGridVertex{{SOLVER_NAME}}.getType() == vertexdata::{{SOLVER_NAME}}::Type::Interior
25 and
26 repositories::{{SOLVER_INSTANCE}}.updateResidual( fineGridVertex{{SOLVER_NAME}}.getLevel() )
27 )
28 {
29 logTraceInWith3Arguments("TouchVertexFirstTimeInterior", fineGridVertex{{SOLVER_NAME}}.toString(), marker.x(), marker.h());
30
31 for (int unknown=0; unknown<{{VERTEX_CARDINALITY}}; unknown++) {
32 // set residual to 0
33 // we can pass the whole vector around, but intent is clearer this way
34 fineGridVertex{{SOLVER_NAME}}.setResidual( unknown, 0);
35
36 // set diag to 0
37 fineGridVertex{{SOLVER_NAME}}.setDiag(unknown, 0.0);
38 }
39
40 logTraceOutWith2Arguments("TouchVertexFirstTimeInterior", marker.toString(), fineGridVertex{{SOLVER_NAME}}.toString());
41 }
42 """
43
44 templateTouchCellFirstTime = """
45 if (
46 fineGridCell{{SOLVER_NAME}}.getType() == celldata::{{SOLVER_NAME}}::Type::Interior
47 and
48 repositories::{{SOLVER_INSTANCE}}.updateResidual( fineGridCell{{SOLVER_NAME}}.getLevel() )
49 ) {
50 logTraceInWith3Arguments("Solve::touchCellFirstTime", fineGridCell{{SOLVER_NAME}}.toString(), marker.x(), marker.h());
51 for (int unknown=0; unknown<{{VERTEX_CARDINALITY}}; unknown++)
52 {
53 // Mass and assembly matrix should be block diagonal,
54 // depending on which unknown we are currently dealing with.
55 // We will collect the rhs & solution values from the
56 // vertices, and apply the correct matrix as we go.
57 // Define the offset:
58 int startIndex = TwoPowerD * unknown;
59
60 auto A = repositories::{{SOLVER_INSTANCE}}.getLocalAssemblyMatrix(marker.x(), marker.h());
61 auto M = repositories::{{SOLVER_INSTANCE}}.getRhsMatrix(marker.x(), marker.h(), fineGridCell{{SOLVER_NAME}}.getLevel());
62
63 // collect all of the vertex values into one vector - apply the appropriate
64 // part of the matrix as we go.
65 tarch::la::Vector<TwoPowerD, double> vertexValues;
66 tarch::la::Vector<TwoPowerD, double> rhsValues;
67 tarch::la::Vector<TwoPowerD, double> residualValues;
68 for (int i=0; i<TwoPowerD; i++){
69 double solColSum = 0;
70 double rhsColSum = 0;
71 for (int j=0; j<TwoPowerD; j++){
72 solColSum += A(startIndex+i, startIndex+j) * fineGridVertices{{SOLVER_NAME}}(j).getU(unknown);
73 rhsColSum += M(startIndex+i, startIndex+j) * fineGridVertices{{SOLVER_NAME}}(j).getRhs(unknown);
74 }
75
76 vertexValues(i) = solColSum;
77 rhsValues(i) = rhsColSum;
78 residualValues(i) = fineGridVertices{{SOLVER_NAME}}(i).getResidual(unknown);
79 }
80
81 // residual = rhs - Ax
82 residualValues += rhsValues;
83 residualValues -= vertexValues;
84
85 for (int i=0; i<TwoPowerD; i++)
86 {
87 logTraceInWith1Argument("puttingValuesBack", fineGridVertices{{SOLVER_NAME}}(i).toString());
88
89 // increment fieldDiag
90 // get current val
91 double diagVal = fineGridVertices{{SOLVER_NAME}}(i).getDiag(unknown);
92 // increment it
93 diagVal += A(i,i);
94 fineGridVertices{{SOLVER_NAME}}(i).setDiag(unknown, diagVal);
95
96 // put new residual values back
97 fineGridVertices{{SOLVER_NAME}}(i).setResidual(unknown, residualValues(i));
98
99 logTraceOutWith1Argument("puttingValuesBack", fineGridVertices{{SOLVER_NAME}}(i).toString());
100 }
101
102 }
103 logTraceOutWith1Argument("Solve::touchCellFirstTime", fineGridCell{{SOLVER_NAME}}.toString());
104 }
105 """
106 def __init__(self,
107 solver,
108 descend_invocation_order=0,
109 parallel=False):
110 super( ResetAndUpdateResidual, self ).__init__(
111 descend_invocation_order,
112 parallel
113 )
114 self.d = {}
115 self.d["SOLVER_INSTANCE"] = solver.instance_name()
116 self.d["SOLVER_NAME"] = solver.typename()
117 self.d["VERTEX_CARDINALITY"] = solver._unknowns_per_vertex_node
118
119 def get_body_of_operation(self,operation_name):
120 result = ""
121 if operation_name==peano4.solversteps.ActionSet.OPERATION_TOUCH_VERTEX_FIRST_TIME:
122 result = jinja2.Template(self.templateTouchVertexFirstTime).render(**self.d)
123 pass
124 if operation_name==peano4.solversteps.ActionSet.OPERATION_TOUCH_CELL_FIRST_TIME:
125 result = jinja2.Template(self.templateTouchCellFirstTime).render(**self.d)
126 pass
127 return result
128
130 """!
131
132 The action set that Peano will generate that corresponds to this class
133 should not be modified by users and can safely be overwritten every time
134 we run the Python toolkit.
135
136 """
137 return False
138
139 def get_includes(self):
140 """!
141
142 We need the solver repository in this action set, as we directly access
143 the solver object. We also need access to Peano's d-dimensional loops.
144
145 """
146 return """
147#include "repositories/SolverRepository.h"
148#include "peano4/utils/Loop.h"
149#include "mghype/matrixfree/solvers/CGMultigrid.h"
150"""
151
153 """!
154
155 Configure name of generated C++ action set
156
157 This action set will end up in the directory observers with a name that
158 reflects how the observer (initialisation) is mapped onto this action
159 set. The name pattern is ObserverName2ActionSetIdentifier where this
160 routine co-determines the ActionSetIdentifier. We make is reflect the
161 Python class name.
162
163 """
164 return __name__.replace(".py", "").replace(".", "_")
Action set (reactions to events)
Definition ActionSet.py:6
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_body_of_operation(self, operation_name)
Return actual C++ code snippets to be inserted into C++ code.