12 Enumerate the vertices, cells and face entries
14 This is the first step in a typical PETSc algorithm, as discussed on @ref documentation_multigrid_petsc.
15 It has to ensure that each mesh entity hosts the appropriate number of
16 degrees of freedom. It hence strongly depends on the solver chosen, as
17 different solvers place different amounts of data and auxiliary quantities on
18 the mesh entities. The information on data cardinality is queried from the
19 solver objects. The added logic contributed by this action set is if a mesh
20 entity really holds unknowns or not. That is, this action set injects the
21 domain layout and boundary data knowledge into the mesh. This guiding
22 principles of this injection are discussed on
23 @ref documentation_multigrid_boundary_conditions "Peano's generic boundary condition pages".
28 TemplateEnumerateVertex =
"""
29 auto isOnBoundary = [&]( const tarch::la::Vector< Dimensions, double > & x ) -> bool{
30 bool isOnBoundary = false;
31 for (int d=0; d<Dimensions; d++) {
32 isOnBoundary |= tarch::la::smallerEquals( x(d), DomainOffset(d) );
33 isOnBoundary |= tarch::la::greaterEquals( x(d), DomainOffset(d)+DomainSize(d) );
38 fineGridVertex{{SOLVER_NAME}}PETScData.setUnknownBaseNumber( ::petsc::LocalToGlobalMap::NoDegreeOfFreedom );
39 fineGridVertex{{SOLVER_NAME}}PETScData.setType( vertexdata::{{SOLVER_NAME}}PETScData::Type::Undefined );
41 vertexdata::{{SOLVER_NAME}}PETScData::Type dofType = repositories::{{SOLVER_INSTANCE}}.getVertexDoFType(marker.x(),marker.h());
44 case vertexdata::{{SOLVER_NAME}}PETScData::Type::Boundary:
46 fineGridVertex{{SOLVER_NAME}}PETScData.setType( vertexdata::{{SOLVER_NAME}}PETScData::Type::Boundary );
47 {% if BOUNDARY_VERTICES_HOLD_DATA %}
48 if ( marker.willBeRefined() ) {
49 fineGridVertex{{SOLVER_NAME}}PETScData.setType( vertexdata::{{SOLVER_NAME}}PETScData::Type::Coarse );
52 fineGridVertex{{SOLVER_NAME}}PETScData.setUnknownBaseNumber( _localVertexMap.reserveIndex( {{VERTEX_CARDINALITY}} ) );
57 case vertexdata::{{SOLVER_NAME}}PETScData::Type::Interior:
59 if (isOnBoundary(marker.x())) {
60 logWarning( "touchVertexFirstTime(...)", "vertex at " << marker.toString() << " labelled as interior even though it is located at global domain boundary" );
62 if ( marker.willBeRefined() ) {
63 fineGridVertex{{SOLVER_NAME}}PETScData.setType( vertexdata::{{SOLVER_NAME}}PETScData::Type::Coarse );
66 fineGridVertex{{SOLVER_NAME}}PETScData.setType( vertexdata::{{SOLVER_NAME}}PETScData::Type::Interior );
67 fineGridVertex{{SOLVER_NAME}}PETScData.setUnknownBaseNumber( _localVertexMap.reserveIndex( {{VERTEX_CARDINALITY}} ) );
71 case vertexdata::{{SOLVER_NAME}}PETScData::Type::Coarse:
72 assertionMsg(false, "should not be returned by user" );
74 case vertexdata::{{SOLVER_NAME}}PETScData::Type::Outside:
76 fineGridVertex{{SOLVER_NAME}}PETScData.setType( vertexdata::{{SOLVER_NAME}}PETScData::Type::Outside );
79 case vertexdata::{{SOLVER_NAME}}PETScData::Type::Undefined:
80 assertionEquals( {{VERTEX_CARDINALITY}}, 0 );
86 TemplateEnumerateFace =
"""
87 auto isOnBoundary = [&]( const tarch::la::Vector< Dimensions, double >& x) -> bool {
88 bool isOnBoundary = false;
89 for (int d=0; d<Dimensions; d++) {
90 isOnBoundary |= tarch::la::smallerEquals( x(d), DomainOffset(d) );
91 isOnBoundary |= tarch::la::greaterEquals( x(d), DomainOffset(d)+DomainSize(d) );
96 fineGridFace{{SOLVER_NAME}}PETScData.setUnknownBaseNumber( ::petsc::LocalToGlobalMap::NoDegreeOfFreedom );
97 fineGridFace{{SOLVER_NAME}}PETScData.setType( facedata::{{SOLVER_NAME}}PETScData::Type::Undefined );
99 facedata::{{SOLVER_NAME}}PETScData::Type dofType = repositories::{{SOLVER_INSTANCE}}.getFaceDoFType(marker.x(),marker.h());
102 case facedata::{{SOLVER_NAME}}PETScData::Type::Boundary:
104 fineGridFace{{SOLVER_NAME}}PETScData.setType( facedata::{{SOLVER_NAME}}PETScData::Type::Boundary );
105 {% if BOUNDARY_FACES_HOLD_DATA %}
106 if ( marker.willBeRefined() ) {
107 fineGridFace{{SOLVER_NAME}}PETScData.setType( facedata::{{SOLVER_NAME}}PETScData::Type::Coarse );
110 fineGridFace{{SOLVER_NAME}}PETScData.setUnknownBaseNumber( _localFaceMap.reserveIndex( {{FACE_CARDINALITY}} ) );
115 case facedata::{{SOLVER_NAME}}PETScData::Type::Interior:
117 if (isOnBoundary(marker.x())) {
118 logWarning( "touchFaceFirstTime(...)", "face at " << marker.toString() << " labelled as interior even though it is located at global domain boundary" );
120 if ( marker.willBeRefined() ) {
121 fineGridFace{{SOLVER_NAME}}PETScData.setType( facedata::{{SOLVER_NAME}}PETScData::Type::Coarse );
124 fineGridFace{{SOLVER_NAME}}PETScData.setType( facedata::{{SOLVER_NAME}}PETScData::Type::Interior );
125 fineGridFace{{SOLVER_NAME}}PETScData.setUnknownBaseNumber( _localFaceMap.reserveIndex( {{FACE_CARDINALITY}} ) );
129 case facedata::{{SOLVER_NAME}}PETScData::Type::Coarse:
130 assertionMsg(false, "should not be returned by user" );
132 case facedata::{{SOLVER_NAME}}PETScData::Type::Outside:
134 fineGridFace{{SOLVER_NAME}}PETScData.setType( facedata::{{SOLVER_NAME}}PETScData::Type::Outside );
137 case facedata::{{SOLVER_NAME}}PETScData::Type::Undefined:
138 assertionEquals( {{FACE_CARDINALITY}}, 0 );
144 TemplateEnumerateCell =
"""
145 fineGridCell{{SOLVER_NAME}}PETScData.setUnknownBaseNumber( ::petsc::LocalToGlobalMap::NoDegreeOfFreedom );
146 fineGridCell{{SOLVER_NAME}}PETScData.setType( celldata::{{SOLVER_NAME}}PETScData::Type::Undefined );
148 celldata::{{SOLVER_NAME}}PETScData::Type dofType = repositories::{{SOLVER_INSTANCE}}.getCellDoFType(marker.x(),marker.h());
151 case celldata::{{SOLVER_NAME}}PETScData::Type::Interior:
153 if ( marker.willBeRefined() ) {
154 fineGridCell{{SOLVER_NAME}}PETScData.setType( celldata::{{SOLVER_NAME}}PETScData::Type::Coarse );
157 fineGridCell{{SOLVER_NAME}}PETScData.setType( celldata::{{SOLVER_NAME}}PETScData::Type::Interior );
158 fineGridCell{{SOLVER_NAME}}PETScData.setUnknownBaseNumber( _localCellMap.reserveIndex( {{CELL_CARDINALITY}} ) );
162 case celldata::{{SOLVER_NAME}}PETScData::Type::Coarse:
163 assertionMsg(false, "should not be returned by user" );
165 case celldata::{{SOLVER_NAME}}PETScData::Type::Outside:
167 fineGridCell{{SOLVER_NAME}}PETScData.setType( celldata::{{SOLVER_NAME}}PETScData::Type::Outside );
170 case celldata::{{SOLVER_NAME}}PETScData::Type::Undefined:
171 assertionEquals( {{CELL_CARDINALITY}}, 0 );
177 TemplateEndTraversal =
"""
180 "vertex dofs=" << _localVertexMap.getTotalNumberOfIndices() <<
181 ", face dofs=" << _localFaceMap.getTotalNumberOfIndices() <<
182 ", cell dofs=" << _localCellMap.getTotalNumberOfIndices()
185 repositories::{{SOLVER_INSTANCE}}.getLocalToGlobalMap().merge( _localVertexMap, ::petsc::LocalToGlobalMap::Type::Vertex );
186 repositories::{{SOLVER_INSTANCE}}.getLocalToGlobalMap().merge( _localFaceMap, ::petsc::LocalToGlobalMap::Type::Face );
187 repositories::{{SOLVER_INSTANCE}}.getLocalToGlobalMap().merge( _localCellMap, ::petsc::LocalToGlobalMap::Type::Cell );
193 boundary_vertices_hold_data,
194 boundary_faces_hold_data,
198Enumerate vertex-associated degrees of freedom
200The initialisation requires a solver object, as we have to know what C++
201object this solver will produce, and we need to know how many unknowns
204solver: petsc.solvers.CollocatedLowOrderDiscretisation or similar solver where
205 degrees of freedom are assigned exclusively to the vertices.
208 super( EnumerateDoFs, self ).
__init__()
210 self.
d[
"SOLVER_INSTANCE"] = solver.instance_name()
211 self.
d[
"SOLVER_NAME"] = solver.typename()
212 self.
d[
"VERTEX_CARDINALITY"] = solver.number_of_matrix_entries_per_vertex
213 self.
d[
"FACE_CARDINALITY"] = solver.number_of_matrix_entries_per_face
214 self.
d[
"CELL_CARDINALITY"] = solver.number_of_matrix_entries_per_cell
215 self.
d[
"BOUNDARY_VERTICES_HOLD_DATA"] = boundary_vertices_hold_data
216 self.
d[
"BOUNDARY_FACES_HOLD_DATA"] = boundary_faces_hold_data
222Provide C++ code snippet for peano4.solversteps.ActionSet.OPERATION_TOUCH_VERTEX_FIRST_TIME
224Only touchVertexFirstTime is an event where this action set actually
225does something: It inserts the template TemplateInitVertex and
226replaces it with entries from the dictionary. The latter is befilled
231 if operation_name==peano4.solversteps.ActionSet.OPERATION_TOUCH_VERTEX_FIRST_TIME:
234 if operation_name==peano4.solversteps.ActionSet.OPERATION_TOUCH_CELL_FIRST_TIME:
237 if operation_name==peano4.solversteps.ActionSet.OPERATION_TOUCH_FACE_FIRST_TIME:
240 if operation_name==peano4.solversteps.ActionSet.OPERATION_END_TRAVERSAL:
249Configure name of generated C++ action set
251This action set will end up in the directory observers with a name that
252reflects how the observer (initialisation) is mapped onto this action
253set. The name pattern is ObserverName2ActionSetIdentifier where this
254routine co-determines the ActionSetIdentifier. We make is reflect the
258 return __name__.replace(
".py",
"").replace(
".",
"_")
264 The action set that Peano will generate that corresponds to this class
265 should not be modified by users and can safely be overwritten every time
266 we run the Python toolkit.
277Every action set has excactly one attribute and that's an instance of
278petsc::LocalToGlobalMap. Before we run through a local mesh partition,
279the corresponding observer object will create a copy of the action set
280for this traversal. In the corresponding constructor, we initialise
281our thread-local copy of the map with the correct tree number.
285 ::petsc::LocalToGlobalMap _localCellMap;
286 ::petsc::LocalToGlobalMap _localFaceMap;
287 ::petsc::LocalToGlobalMap _localVertexMap;
293Define body of constructor
295Consult the superclass' description of the function for results. I
296basically initialise the _localMap with the correct tree number.
302 _localCellMap.setTreeNumber( treeNumber );
303 _localFaceMap.setTreeNumber( treeNumber );
304 _localVertexMap.setTreeNumber( treeNumber );
311Consult multigrid.petsc.Project for details
315#include "../repositories/SolverRepository.h"
Enumerate the vertices, cells and face entries.
get_constructor_body(self)
Define body of constructor.
get_body_of_operation(self, operation_name)
Provide C++ code snippet for peano4.solversteps.ActionSet.OPERATION_TOUCH_VERTEX_FIRST_TIME
get_includes(self)
Consult multigrid.petsc.Project for details.
str TemplateEnumerateCell
str TemplateEnumerateFace
get_action_set_name(self)
Configure name of generated C++ action set.
user_should_modify_template(self)
The action set that Peano will generate that corresponds to this class should not be modified by user...
get_attributes(self)
Define the local map.
__init__(self, solver, boundary_vertices_hold_data, boundary_faces_hold_data)
A.
str TemplateEnumerateVertex
Action set (reactions to events)