2The action sets in this file are intended for use with new MG solvers.
4We have a mix of behaviours to add in - namely determining max refinement
5level during our first descent, as well as standard stuff eg determining
6which facets are boundary / interior etc.
8For the CG, we need to determine:
9 - the number of refinement levels available
10 - the level of the finest level
12We need to add some bookkeeping to the abstract solver to keep track of
13these, because the solver level matters.
15We need to associate an int "level" with each vertex, so we give each Vertex
16this attribute (Level) and set it to -1 initially. Then during
17touchVertexFirstTime, we set the "level" of the fineGridVertex to be one more
18than the level of the coarse vertex
20Slight problem is that we don't have the coarse vertex in scope at this stage.
21So we need to maintain this hierarchy for the cells, as well as setting the
22level of the vertices to be one more than the coarse cells.
32 templateTouchCellFirstTime=
"""
35 fineGridCell{{SOLVER_NAME}}.setLevel(
36 coarseGridCell{{SOLVER_NAME}}.getLevel() + 1
39 celldata::{{SOLVER_NAME}}::Type dofType = repositories::{{SOLVER_INSTANCE}}.getCellType(marker.x(),marker.h());
42 case celldata::{{SOLVER_NAME}}::Type::Outside:
48 case celldata::{{SOLVER_NAME}}::Type::Interior:
50 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Interior );
51 repositories::{{SOLVER_INSTANCE}}.updateMinMaxMeshSize( marker.h() );
58 templateTouchVertexFirstTime=
"""
61 fineGridVertex{{SOLVER_NAME}}.setLevel(
62 coarseGridCell{{SOLVER_NAME}}.getLevel() + 1
65 tarch::la::Vector<{{VERTEX_CARDINALITY}}, double> zeroes { 0 };
66 fineGridVertex{{SOLVER_NAME}}.setResidual( zeroes );
67 fineGridVertex{{SOLVER_NAME}}.setDelta( zeroes );
68 fineGridVertex{{SOLVER_NAME}}.setOldU( zeroes );
69 fineGridVertex{{SOLVER_NAME}}.setDiag( zeroes );
71 vertexdata::{{SOLVER_NAME}}::Type dofType = repositories::{{SOLVER_INSTANCE}}.getVertexType(marker.x(),marker.h());
75 case vertexdata::{{SOLVER_NAME}}::Type::Boundary:
77 fineGridVertex{{SOLVER_NAME}}.setType( vertexdata::{{SOLVER_NAME}}::Type::Boundary );
78 if ( !marker.willBeRefined() ) {
79 // we have boundary vertex
80 // init its solution too
81 tarch::la::Vector<{{VERTEX_CARDINALITY}}, double> u;
82 tarch::la::Vector<{{VERTEX_CARDINALITY}}, double> rhs;
84 // send these into init
85 repositories::{{SOLVER_INSTANCE}}.initVertex( marker.x(), marker.h(), u, rhs );
88 fineGridVertex{{SOLVER_NAME}}.setU( u );
89 fineGridVertex{{SOLVER_NAME}}.setRhs( rhs );
91 // if we are on the finest level, we need to alert the abstract solver...
92 repositories::{{SOLVER_INSTANCE}}.setActiveLevel( fineGridVertex{{SOLVER_NAME}}.getLevel() );
93 repositories::{{SOLVER_INSTANCE}}.setFinestLevel( fineGridVertex{{SOLVER_NAME}}.getLevel() );
98 case vertexdata::{{SOLVER_NAME}}::Type::Interior:
100 fineGridVertex{{SOLVER_NAME}}.setType( vertexdata::{{SOLVER_NAME}}::Type::Interior );
102 if ( !marker.willBeRefined() ){
103 // init its solution since we are on the finest level
104 tarch::la::Vector<{{VERTEX_CARDINALITY}}, double> u;
105 tarch::la::Vector<{{VERTEX_CARDINALITY}}, double> rhs;
107 // send these into init
108 repositories::{{SOLVER_INSTANCE}}.initVertex( marker.x(), marker.h(), u, rhs );
111 fineGridVertex{{SOLVER_NAME}}.setU( u );
112 fineGridVertex{{SOLVER_NAME}}.setRhs( rhs );
114 // if we are on the finest level, we need to alert the abstract solver...
115 repositories::{{SOLVER_INSTANCE}}.setActiveLevel( fineGridVertex{{SOLVER_NAME}}.getLevel() );
116 repositories::{{SOLVER_INSTANCE}}.setFinestLevel( fineGridVertex{{SOLVER_NAME}}.getLevel() );
121 case vertexdata::{{SOLVER_NAME}}::Type::Coarse:
122 assertionMsg(false, "should not be returned by user" );
125 case vertexdata::{{SOLVER_NAME}}::Type::Undefined:
126 assertionMsg(false, "should not be returned by user" );
133 templateEndTraversal=
"""
134 repositories::{{SOLVER_INSTANCE}}.validateRefinementLevel();
139 super( InitDofsCollocatedMG, self ).
__init__()
141 self.
d[
"SOLVER_INSTANCE"] = solver.instance_name()
142 self.
d[
"SOLVER_NAME"] = solver.typename()
143 self.
d[
"VERTEX_CARDINALITY"] = solver._unknowns_per_vertex_node
147 if operation_name==peano4.solversteps.ActionSet.OPERATION_TOUCH_VERTEX_FIRST_TIME:
150 if operation_name==peano4.solversteps.ActionSet.OPERATION_TOUCH_CELL_FIRST_TIME:
153 if operation_name==peano4.solversteps.ActionSet.OPERATION_END_TRAVERSAL:
160 Configure name of generated C++ action set
162 This action set will end up in the directory observers with a name that
163 reflects how the observer (initialisation) is mapped onto this action
164 set. The name pattern is ObserverName2ActionSetIdentifier where this
165 routine co-determines the ActionSetIdentifier. We make is reflect the
169 return __name__.replace(
".py",
"").replace(
".",
"_")
174 The action set that Peano will generate that corresponds to this class
175 should not be modified by users and can safely be overwritten every time
176 we run the Python toolkit.
184 We need the solver repository in this action set, as we directly access
185 the solver object. We also need access to Peano's d-dimensional loops.
189#include "repositories/SolverRepository.h"
190#include "peano4/utils/Loop.h"
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 templateTouchCellFirstTime
get_body_of_operation(self, operation_name)
Return actual C++ code snippets to be inserted into C++ code.
str templateTouchVertexFirstTime
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.