Peano
Loading...
Searching...
No Matches
ProjectIntoCellAndUpdateCellSolution.py
Go to the documentation of this file.
1from peano4.solversteps.ActionSet import ActionSet
2
3import peano4
4import jinja2
5
6
8 templateTouchCellFirstTime="""
9 if (
10 fineGridCell{{SOLVER_NAME}}.getType() != celldata::{{SOLVER_NAME}}::Type::Coarse
11 and
12 repositories::{{SOLVER_INSTANCE}}.projectOntoCells()
13 ) {
14 logTraceInWith2Arguments( "ProjectOntoCells", fineGridCell{{SOLVER_NAME}}.getResidual(), fineGridCell{{SOLVER_NAME}}.getSolution() );
15
16 // we intend that the internal residual vector should be reset and updated in the
17 // cell update procedure
18
19 // This vector faceSol will contain: soln on face 0 | soln on face 1 | soln on face 2 | .....
20 tarch::la::Vector< repositories::{{SOLVER_INSTANCE}}.FaceUnknownsSolution*TwoTimesD, double > faceSol;
21 for (int f=0; f<TwoTimesD; f++)
22 for (int s=0; s<repositories::{{SOLVER_INSTANCE}}.FaceUnknownsSolution; s++) {
23 assertion2( fineGridFaces{{SOLVER_NAME}}(f).getSolution(s)<1e10, fineGridFaces{{SOLVER_NAME}}(f).getSolution(s), fineGridFaces{{SOLVER_NAME}}(f).getSolution() );
24 faceSol( f*repositories::{{SOLVER_INSTANCE}}.FaceUnknownsSolution + s ) = fineGridFaces{{SOLVER_NAME}}(f).getSolution(s);
25 }
26
27 // next, we need to project solution on face onto the cell...
28 auto projection = repositories::{{SOLVER_INSTANCE}}.applyCellFromFaceMatrix(marker.x(), marker.h(), faceSol);
29
30 // loop over each face, finish updating residual as we go
31 for (int f=0; f<repositories::{{SOLVER_INSTANCE}}.CellUnknowns; f++)
32 {
33 assertion2( fineGridCell{{SOLVER_NAME}}.getResidual(f)<1e10, fineGridCell{{SOLVER_NAME}}.getResidual(f), projection(f) );
34 // project the face solution onto the cell; add to r
35 fineGridCell{{SOLVER_NAME}}.setResidual(f,
36 fineGridCell{{SOLVER_NAME}}.getResidual(f)- projection(f));
37 }
38
39 // update global residual before multiplying by the preconditioner
40 for (int i=0; i<fineGridCell{{SOLVER_NAME}}.getSolution().size(); i++) {
41 double res = fineGridCell{{SOLVER_NAME}}.getResidual( i );
42 _solverStatistics.updateGlobalResidual(res, marker.h());
43 }
44
45 // multiply by "smoother" / preconditioner
46 fineGridCell{{SOLVER_NAME}}.setResidual( repositories::{{SOLVER_INSTANCE}}.applyInvertedApproxSystemMatrix(
47 marker.x(),
48 marker.h(),
49 fineGridCell{{SOLVER_NAME}}.getResidual()
50 ));
51
52 for (int i=0; i<fineGridCell{{SOLVER_NAME}}.getSolution().size(); i++) {
53 double res = fineGridCell{{SOLVER_NAME}}.getResidual( i );
54 double du = repositories::{{SOLVER_INSTANCE}}.OmegaCell * res;
55 fineGridCell{{SOLVER_NAME}}.setSolution( i,
56 fineGridCell{{SOLVER_NAME}}.getSolution( i ) + du
57 );
58 _solverStatistics.updateGlobalSolutionUpdates(du, marker.h()(0));
59 _solverStatistics.updateMinMaxMeshSize( marker.h() );
60 }
61
62 logTraceOutWith2Arguments( "ProjectOntoCells", fineGridCell{{SOLVER_NAME}}.getResidual(), fineGridCell{{SOLVER_NAME}}.getSolution() );
63 }
64
65 """
66 def __init__(self,
67 solver,
68 descend_invocation_order=0,
69 parallel=True):
70 super( ProjectIntoCellAndUpdateCellSolution, self ).__init__(
71 descend_invocation_order,
72 parallel
73 )
74 self.d = {}
75 self.d["SOLVER_INSTANCE"] = solver.instance_name()
76 self.d["SOLVER_NAME"] = solver.typename()
77
78 def get_body_of_operation(self,operation_name):
79 result = ""
80 if operation_name==peano4.solversteps.ActionSet.OPERATION_TOUCH_CELL_FIRST_TIME:
81 result = jinja2.Template(self.templateTouchCellFirstTime).render(**self.d)
82 pass
83 # This is now done within the abstract solver
84# if operation_name==peano4.solversteps.ActionSet.OPERATION_BEGIN_TRAVERSAL:
85# result = jinja2.Template("""
86# _solverStatistics.clearGlobalPrecondResidualUpdate();
87# _solverStatistics.clearGlobalResidualAndSolutionUpdate();
88#""").render(**self.d)
89 if operation_name==peano4.solversteps.ActionSet.OPERATION_END_TRAVERSAL:
90 result = jinja2.Template("""
91 repositories::{{SOLVER_INSTANCE}}.merge( _solverStatistics );
92""").render(**self.d)
93 return result
94
96 """!
97
98 Configure name of generated C++ action set
99
100 This action set will end up in the directory observers with a name that
101 reflects how the observer (initialisation) is mapped onto this action
102 set. The name pattern is ObserverName2ActionSetIdentifier where this
103 routine co-determines the ActionSetIdentifier. We make is reflect the
104 Python class name.
105
106 """
107 return __name__.replace(".py", "").replace(".", "_") + "_ProjectIntoCellAndUpdateCellSolution"
108
110 """!
111
112 The action set that Peano will generate that corresponds to this class
113 should not be modified by users and can safely be overwritten every time
114 we run the Python toolkit.
115
116 """
117 return False
118
119 def get_includes(self):
120 """!
121
122 We need the solver repository in this action set, as we directly access
123 the solver object. We also need access to Peano's d-dimensional loops.
124
125 """
126 return """
127#include "../repositories/SolverRepository.h"
128#include "peano4/utils/Loop.h"
129"""
130
131 def get_attributes(self):
132 """!
133
134 Return attributes as copied and pasted into the generated class.
135
136 Please note that action sets are not persistent, i.e. there is one
137 object creation per grid sweep per tree.
138
139 """
140 return """
141 ::mghype::matrixfree::solvers::SolverStatistics _solverStatistics;
142"""
143
Action set (reactions to events)
Definition ActionSet.py:6
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.
user_should_modify_template(self)
The action set that Peano will generate that corresponds to this class should not be modified by user...