Peano
Loading...
Searching...
No Matches
ImposeDirichletBoundaryConditionsWithInteriorPenaltyMethod.py
Go to the documentation of this file.
1# This file is part of the Peano multigrid project. For conditions of
2# distribution and use, please see the copyright notice at www.peano-framework.org
3from peano4.solversteps.ActionSet import ActionSet
4
5import peano4
6import jinja2
7
8
9
11 """!
12
13 @todo Add comments which document from Slack
14
15 """
16 TemplateTouchFaceFirstTime = """
17 if (fineGridFace{{SOLVER_NAME}}PETScData.getType() == facedata::{{SOLVER_NAME}}PETScData::Type::Boundary) {
18 std::pair<int,int> localFaceIndex = std::make_pair(_spacetreeId, fineGridFace{{SOLVER_NAME}}PETScData.getUnknownBaseNumber());
19 int globalFaceIndex = repositories::{{SOLVER_INSTANCE}}.getLocalToGlobalMap().getGlobalIndex(localFaceIndex, ::petsc::LocalToGlobalMap::Type::Face);
20
21 assertion( globalFaceIndex>=0 );
22
23 logTraceInWith2Arguments("touchFaceFirstTime::Boundary", globalFaceIndex, marker.toString());
24
25 /*
26 we want to place -1 on the diagonal for each "interior-side" projection.
27 That is, for face 0 and 2, we write to the "+" projection
28 for face 1 and 3, we write to the "-" projection
29
30 We also write -1 to all of the "exterior-side" projections. The actual
31 value we use here is immaterial, so long as it is not zero.
32 This makes the matrix full-rank. We use -1 to make this loop easier
33 to write.
34
35 we go up to 2*repositories::{{SOLVER_INSTANCE}}.NodesPerFace*repositories::{{SOLVER_INSTANCE}}.FaceUnknowns
36 since this is total number of q^-, q^+, u^-, u^+.
37 */
38 for (int i=0; i<2*repositories::{{SOLVER_INSTANCE}}.NodesPerFace*repositories::{{SOLVER_INSTANCE}}.FaceUnknowns; i++)
39 {
40 repositories::{{SOLVER_INSTANCE}}.getLinearEquationSystem().insert(
41 globalFaceIndex + i,
42 globalFaceIndex + i,
43 -1
44 );
45 }
46
47 int faceNormalAxis = marker.getSelectedFaceNumber()%Dimensions;
48 int row = 0;
49 dfore(faceNode, repositories::{{SOLVER_INSTANCE}}.Order+1, faceNormalAxis, 0) {
50
51 tarch::la::Vector<Dimensions,double> x = marker.x(); // centre of face
52 for (int dd=0; dd<Dimensions; dd++) {
53 if (dd!=faceNormalAxis) {
54 x(dd) -= 0.5 * marker.h()(dd);
55 x(dd) += repositories::{{SOLVER_INSTANCE}}.QuadraturePointsInUnitInterval[ faceNode(dd) ] * marker.h()(dd);
56 }
57 }
58
59 logTraceInWith5Arguments("touchFaceFirstTime::dfore", faceNode, faceNormalAxis, marker.x(), x,repositories::{{SOLVER_INSTANCE}}.FaceUnknowns);
60
61 // Look up the value: rhs is not relevant here, but I want to reuse the existing signatures
62 double value, rhs, exact;
63 repositories::{{SOLVER_INSTANCE}}.initNode(
64 x,
65 marker.h(),
66 value,
67 rhs,
68 exact
69 );
70
71 for (int unknown = 0; unknown<repositories::{{SOLVER_INSTANCE}}.FaceUnknowns; unknown++) {
72 // row corresponding to solution
73 int globalMatrixRow = globalFaceIndex + row + 2*repositories::{{SOLVER_INSTANCE}}.NodesPerFace*repositories::{{SOLVER_INSTANCE}}.FaceUnknowns;
74
75 logTraceInWith4Arguments("touchFaceFirstTime:unknownLoop", unknown, globalMatrixRow, row, marker.toString());
76
77 // insert identity into row corresponding to solution at this node / for this unknown
78 repositories::{{SOLVER_INSTANCE}}.getLinearEquationSystem().insert(
79 globalMatrixRow,
80 globalMatrixRow,
81 1
82 );
83
84 static_assert(Dimensions==2, "the bodge on the line below is untested for Dimensions != 2. see comment in code");
85
86 /*
87 The faces are enumerated as follows:
88 negative x axis
89 negative y axis
90 negative z axis
91 positive x axis
92 positive y axis
93 positive z axis
94 if we are on negative side of coordinate axis, then we wanna write to the positive projection,
95 since this is the one that is on interior side of cell.
96
97 So, if the face number is >= than Dimensions, we wanna write to negative side projection.
98 */
99 bool writeToNegativeProjection = (marker.getSelectedFaceNumber() >= Dimensions);
100
101 /*
102 This part is to round off the equation. If q^- projection is on the inside of the cell,
103 then we want the equation to read q^f - q^- = 0. Hence we write 1 onto the row, col
104 corresponding to q^f and then -1 in col for q^-. rhs will be zero to round this off.
105 */
106
107 // makes sure we only do this for q unknown
108 if ( row < repositories::{{SOLVER_INSTANCE}}.FaceUnknowns )
109 {
110 repositories::{{SOLVER_INSTANCE}}.getLinearEquationSystem().insert(
111 globalMatrixRow,
112 globalFaceIndex + row, // q^-
113 writeToNegativeProjection ? -1 : 0
114 );
115
116 repositories::{{SOLVER_INSTANCE}}.getLinearEquationSystem().insert(
117 globalMatrixRow,
118 globalFaceIndex + row + repositories::{{SOLVER_INSTANCE}}.NodesPerFace*repositories::{{SOLVER_INSTANCE}}.FaceUnknowns, // q^+
119 writeToNegativeProjection ? 0 : -1
120 );
121 }
122
123 /*
124 Alternative behaviour for u unknown. Same as for q: If u^- projection is on the inside of the cell,
125 then we want the equation to read u^f - u^- = 0
126 */
127 if ( row >= repositories::{{SOLVER_INSTANCE}}.FaceUnknowns )
128 {
129 repositories::{{SOLVER_INSTANCE}}.getLinearEquationSystem().insert(
130 globalMatrixRow,
131 globalFaceIndex + row, // u^-
132 writeToNegativeProjection ? -1 : 0
133 );
134
135 repositories::{{SOLVER_INSTANCE}}.getLinearEquationSystem().insert(
136 globalMatrixRow,
137 globalFaceIndex + row + repositories::{{SOLVER_INSTANCE}}.NodesPerFace*repositories::{{SOLVER_INSTANCE}}.FaceUnknowns, // u^+
138 writeToNegativeProjection ? 0 : -1
139 );
140 }
141
142 row++;
143
144 logTraceOut("touchFaceFirstTime:unknownLoop");
145 }
146 logTraceOut("touchFaceFirstTime::dfore");
147
148 }
149 logTraceOut("touchFaceFirstTime::Boundary");
150 }
151 """
152
153 def __init__(self,
154 solver,
155 ):
156 """!
157
158 Yet to be written
159
160 """
161
162 super( ImposeDirichletBoundaryConditionsWithInteriorPenaltyMethod, self ).__init__()
163 self.d = {}
164 self.d["SOLVER_INSTANCE"] = solver.instance_name()
165 self.d["SOLVER_NAME"] = solver.typename()
166
167
168 def get_body_of_operation(self,operation_name):
169 """!
170
171Provide C++ code snippet for peano4.solversteps.ActionSet.OPERATION_TOUCH_VERTEX_FIRST_TIME
172Provide C++ code snippet for peano4.solversteps.ActionSet.OPERATION_TOUCH_CELL_FIRST_TIME
173
174Only touchVertexFirstTime is an event where this action set actually
175does something: It inserts the template TemplateTouchVertexFirstTime and
176replaces it with entries from the dictionary. The latter is befilled
177in init().
178
179We actually do something during touchVertexFirstTime and touchCellFirstTime. We insert the
180appropriate template into each.
181
182 """
183 result = ""
184 if operation_name==peano4.solversteps.ActionSet.OPERATION_TOUCH_FACE_FIRST_TIME:
185 result = jinja2.Template(self.TemplateTouchFaceFirstTime).render(**self.d)
186 pass
187 return result
188
189
191 """!
192
193 Configure name of generated C++ action set
194
195 This action set will end up in the directory observers with a name that
196 reflects how the observer (initialisation) is mapped onto this action
197 set. The name pattern is ObserverName2ActionSetIdentifier where this
198 routine co-determines the ActionSetIdentifier. We make is reflect the
199 Python class name.
200
201 """
202 return __name__.replace(".py", "").replace(".", "_")
203
204
206 """!
207
208 The action set that Peano will generate that corresponds to this class
209 should not be modified by users and can safely be overwritten every time
210 we run the Python toolkit.
211
212 """
213 return False
214
215
216 def get_includes(self):
217 """!
218
219Consult petsc.Project for details
220
221"""
222 return """
223#include "../repositories/SolverRepository.h"
224#include "tarch/la/Matrix.h"
225#include "peano4/utils/Loop.h"
226"""
227
228 def get_attributes(self):
229 """!
230
231
232 """
233 return f"""
234 int _spacetreeId;
235"""
236
238 """!
239
240Define body of constructor
241
242@see get_attributes()
243
244 """
245 return f"""
246 _spacetreeId = treeNumber;
247"""
get_body_of_operation(self, operation_name)
Provide C++ code snippet for peano4.solversteps.ActionSet.OPERATION_TOUCH_VERTEX_FIRST_TIME Provide...
Action set (reactions to events)
Definition ActionSet.py:6