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}}.getCellDoFType(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}}.getVertexDoFType(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" );
134 super( InitDofsCollocatedMG, self ).
__init__()
136 self.
d[
"SOLVER_INSTANCE"] = solver.instance_name()
137 self.
d[
"SOLVER_NAME"] = solver.typename()
138 self.
d[
"VERTEX_CARDINALITY"] = solver._unknowns_per_vertex_node
142 if operation_name==peano4.solversteps.ActionSet.OPERATION_TOUCH_VERTEX_FIRST_TIME:
145 if operation_name==peano4.solversteps.ActionSet.OPERATION_TOUCH_CELL_FIRST_TIME:
153 Configure name of generated C++ action set
155 This action set will end up in the directory observers with a name that
156 reflects how the observer (initialisation) is mapped onto this action
157 set. The name pattern is ObserverName2ActionSetIdentifier where this
158 routine co-determines the ActionSetIdentifier. We make is reflect the
162 return __name__.replace(
".py",
"").replace(
".",
"_")
167 The action set that Peano will generate that corresponds to this class
168 should not be modified by users and can safely be overwritten every time
169 we run the Python toolkit.
177 We need the solver repository in this action set, as we directly access
178 the solver object. We also need access to Peano's d-dimensional loops.
182#include "repositories/SolverRepository.h"
183#include "peano4/utils/Loop.h"
str templateTouchCellFirstTime
get_body_of_operation(self, operation_name)
Return actual C++ code snippets to be inserted into C++ code.
get_includes(self)
We need the solver repository in this action set, as we directly access the solver object.
str templateTouchVertexFirstTime
user_should_modify_template(self)
The action set that Peano will generate that corresponds to this class should not be modified by user...
get_action_set_name(self)
Configure name of generated C++ action set.
Action set (reactions to events)