7 templateTouchVertexFirstTime =
"""
9 fineGridVertex{{SOLVER_NAME}}.getType() == vertexdata::{{SOLVER_NAME}}::Type::Boundary
11 repositories::{{SOLVER_INSTANCE}}.updateResidual( fineGridVertex{{SOLVER_NAME}}.getLevel() )
13 logTraceInWith1Argument("TouchVertexFirstTimeBoundary", fineGridVertex{{SOLVER_NAME}}.toString());
14 auto value = fineGridVertex{{SOLVER_NAME}}.getU();
15 repositories::{{SOLVER_INSTANCE}}.setBoundaryConditions(
20 fineGridVertex{{SOLVER_NAME}}.setU(value);
21 logTraceOutWith1Argument("TouchVertexFirstTimeBoundary", fineGridVertex{{SOLVER_NAME}}.toString());
24 fineGridVertex{{SOLVER_NAME}}.getType() == vertexdata::{{SOLVER_NAME}}::Type::Interior
26 repositories::{{SOLVER_INSTANCE}}.updateResidual( fineGridVertex{{SOLVER_NAME}}.getLevel() )
29 logTraceInWith3Arguments("TouchVertexFirstTimeInterior", fineGridVertex{{SOLVER_NAME}}.toString(), marker.x(), marker.h());
31 for (int unknown=0; unknown<{{VERTEX_CARDINALITY}}; unknown++) {
33 // we can pass the whole vector around, but intent is clearer this way
34 fineGridVertex{{SOLVER_NAME}}.setResidual( unknown, 0);
37 fineGridVertex{{SOLVER_NAME}}.setDiag(unknown, 0.0);
40 logTraceOutWith2Arguments("TouchVertexFirstTimeInterior", marker.toString(), fineGridVertex{{SOLVER_NAME}}.toString());
44 templateTouchCellFirstTime =
"""
46 fineGridCell{{SOLVER_NAME}}.getType() == celldata::{{SOLVER_NAME}}::Type::Interior
48 repositories::{{SOLVER_INSTANCE}}.updateResidual( fineGridCell{{SOLVER_NAME}}.getLevel() )
50 logTraceInWith3Arguments("Solve::touchCellFirstTime", fineGridCell{{SOLVER_NAME}}.toString(), marker.x(), marker.h());
51 for (int unknown=0; unknown<{{VERTEX_CARDINALITY}}; unknown++)
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.
58 int startIndex = TwoPowerD * unknown;
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());
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++){
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);
76 vertexValues(i) = solColSum;
77 rhsValues(i) = rhsColSum;
78 residualValues(i) = fineGridVertices{{SOLVER_NAME}}(i).getResidual(unknown);
81 // residual = rhs - Ax
82 residualValues += rhsValues;
83 residualValues -= vertexValues;
85 for (int i=0; i<TwoPowerD; i++)
87 logTraceInWith1Argument("puttingValuesBack", fineGridVertices{{SOLVER_NAME}}(i).toString());
89 // increment fieldDiag
91 double diagVal = fineGridVertices{{SOLVER_NAME}}(i).getDiag(unknown);
94 fineGridVertices{{SOLVER_NAME}}(i).setDiag(unknown, diagVal);
96 // put new residual values back
97 fineGridVertices{{SOLVER_NAME}}(i).setResidual(unknown, residualValues(i));
99 logTraceOutWith1Argument("puttingValuesBack", fineGridVertices{{SOLVER_NAME}}(i).toString());
103 logTraceOutWith1Argument("Solve::touchCellFirstTime", fineGridCell{{SOLVER_NAME}}.toString());
108 descend_invocation_order=0,
110 super( ResetAndUpdateResidual, self ).
__init__(
111 descend_invocation_order,
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
121 if operation_name==peano4.solversteps.ActionSet.OPERATION_TOUCH_VERTEX_FIRST_TIME:
124 if operation_name==peano4.solversteps.ActionSet.OPERATION_TOUCH_CELL_FIRST_TIME:
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.
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.
147#include "repositories/SolverRepository.h"
148#include "peano4/utils/Loop.h"
149#include "mghype/matrixfree/solvers/CGMultigrid.h"
155 Configure name of generated C++ action set
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
164 return __name__.replace(
".py",
"").replace(
".",
"_")
Action set (reactions to events)
user_should_modify_template(self)
The action set that Peano will generate that corresponds to this class should not be modified by user...
str templateTouchVertexFirstTime
str templateTouchCellFirstTime
__init__(self, solver, descend_invocation_order=0, parallel=False)
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.
get_action_set_name(self)
Configure name of generated C++ action set.