Peano
Loading...
Searching...
No Matches
test8.py
Go to the documentation of this file.
1"""
2This test checks that A_CG indeed approximates the continuum operator:
3check A_DG * u_exact == M * b_exact, where u_exact and b_exact are the dof-vectors
4of the functions u_exact(x) and b_exact(x) which satisfy the PDE in the continuum
5 - Laplace u_exact(x) = b_exact(x).
6
7We use u_exact(x,y) = sin(2*pi*x) * sin(2*pi*y),
8 b_exact(x,y) = 8*pi^2 * sin(2*pi*x) * sin(2*pi*y)
9"""
10
11from peano4.solversteps.ActionSet import ActionSet
12
13import peano4
14import jinja2
15
16
17
19 """!
20 In touchVertexFirstTime, we set the type of vertex we see (either Interior, Boundary or Coarse),
21 as well as sending some values to the solver implementation file to be placed into the mesh.
22
23 In touchCellFirstTime, we just determine the type, as we don't store anything on cells in
24 this solver.
25 """
26
27 templateTouchVertexFirstTime = """
28 static constexpr double eightPiSquared = 8 * tarch::la::PI * tarch::la::PI;
29
30 double sinValue = 1;
31 double sinRhs = eightPiSquared;
32 for (int i=0; i<Dimensions; i++){
33 sinValue *= std::sin( 2*tarch::la::PI * marker.x()(i) );
34 sinRhs *= std::sin( 2*tarch::la::PI * marker.x()(i) );
35 }
36
37 // this is done inside getDofType. included here for sanity check
38 auto isOnBoundary = [&]( const tarch::la::Vector< Dimensions, double > & x ) -> bool{
39 bool isOnBoundary = false;
40 for (int d=0; d<Dimensions; d++) {
41 isOnBoundary |= tarch::la::smallerEquals( x(d), DomainOffset(d) );
42 isOnBoundary |= tarch::la::greaterEquals( x(d), DomainOffset(d)+DomainSize(d) );
43 }
44 return isOnBoundary;
45 };
46
47 logTraceInWith3Arguments("InitDofs::touchVertexFirstTime", marker.toString(), isOnBoundary(marker.x()), fineGridVertex{{SOLVER_NAME}}.toString());
48
49 vertexdata::{{SOLVER_NAME}}::Type dofType = repositories::{{SOLVER_INSTANCE}}.getVertexDoFType(marker.x(),marker.h());
50
51 switch(dofType)
52 {
53 case vertexdata::{{SOLVER_NAME}}::Type::Boundary:
54 {
55 if ( marker.willBeRefined() )
56 {
57 // Coarse grid vertex. Mark it as such for later
58 fineGridVertex{{SOLVER_NAME}}.setType( vertexdata::{{SOLVER_NAME}}::Type::Coarse );
59 }
60 else
61 {
62 // we have boundary vertex
63 fineGridVertex{{SOLVER_NAME}}.setType( vertexdata::{{SOLVER_NAME}}::Type::Boundary );
64
65 // store
66 for (int dof=0; dof<{{VERTEX_CARDINALITY}}; dof++)
67 {
68 fineGridVertex{{SOLVER_NAME}}.setU( dof, sinValue);
69 fineGridVertex{{SOLVER_NAME}}.setRhs( dof, sinRhs);
70 }
71 }
72 }
73 break;
74
75 case vertexdata::{{SOLVER_NAME}}::Type::Interior:
76 {
77 if (isOnBoundary(marker.x()))
78 {
79 logWarning( "touchVertexFirstTime(...)", "vertex at " << marker.toString() << " labelled as interior even though it is located at global domain boundary" );
80 }
81
82 if ( marker.willBeRefined() )
83 {
84 fineGridVertex{{SOLVER_NAME}}.setType( vertexdata::{{SOLVER_NAME}}::Type::Coarse );
85 }
86
87 else
88 {
89 fineGridVertex{{SOLVER_NAME}}.setType( vertexdata::{{SOLVER_NAME}}::Type::Interior );
90
91 // store
92 for (int dof=0; dof<{{VERTEX_CARDINALITY}}; dof++)
93 {
94 fineGridVertex{{SOLVER_NAME}}.setU(dof, sinValue);
95 fineGridVertex{{SOLVER_NAME}}.setRhs( dof, sinRhs);
96 }
97 }
98 }
99 break;
100
101 case vertexdata::{{SOLVER_NAME}}::Type::Coarse:
102 assertionMsg(false, "should not be returned by user" );
103 break;
104
105 case vertexdata::{{SOLVER_NAME}}::Type::Undefined:
106 assertionMsg(false, "should not be returned by user" );
107 break;
108 }
109
110
111 logTraceOutWith3Arguments("InitDofs::touchVertexFirstTime", marker.toString(), isOnBoundary(marker.x()), fineGridVertex{{SOLVER_NAME}}.toString());
112 """
113
114 templateTouchCellFirstTime = """
115 logTraceInWith2Arguments("InitDofs::touchCellFirstTime", marker.toString(), fineGridCell{{SOLVER_NAME}}.toString());
116
117 celldata::{{SOLVER_NAME}}::Type dofType = repositories::{{SOLVER_INSTANCE}}.getCellDoFType(marker.x(),marker.h());
118
119 switch(dofType)
120 {
121 case celldata::{{SOLVER_NAME}}::Type::Outside:
122 {
123 if ( marker.willBeRefined() ) // make it coarse
124 {
125 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Coarse );
126 }
127 else
128 {
129 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Outside );
130 }
131 }
132 break;
133
134 case celldata::{{SOLVER_NAME}}::Type::Interior:
135 {
136 if ( marker.willBeRefined() )
137 {
138 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Coarse );
139 }
140 else
141 {
142 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Interior );
143 // perform initialisation proc
144 // this does not work for more than one unknown per vertex
145
146 tarch::la::Vector<TwoPowerD,double> vu_values;
147 tarch::la::Vector<TwoPowerD,double> vb_values;
148
149 // collect
150 for (int i=0; i<TwoPowerD; i++){
151 vu_values[i] = fineGridVertices{{SOLVER_NAME}}(i).getU(0);
152 vb_values[i] = fineGridVertices{{SOLVER_NAME}}(i).getRhs(0);
153 }
154
155 // multiply vu by A_cg
156 vu_values = repositories::{{SOLVER_INSTANCE}}.getLocalAssemblyMatrix(marker.x(), marker.h()) * vu_values;
157 // multiply vb by M
158 vb_values = repositories::{{SOLVER_INSTANCE}}.getMassMatrix(marker.x(), marker.h()) * vb_values;
159
160 // place this into rhs
161 for (int i=0; i<TwoPowerD; i++){
162 fineGridVertices{{SOLVER_NAME}}(i).setVu(
163 fineGridVertices{{SOLVER_NAME}}(i).getVu() + vu_values(i)
164 );
165
166 fineGridVertices{{SOLVER_NAME}}(i).setVb(
167 fineGridVertices{{SOLVER_NAME}}(i).getVb() + vb_values(i)
168 );
169 }
170
171 }
172 }
173 break;
174
175 }
176
177 logTraceOutWith2Arguments("InitDofs::touchCellFirstTime", marker.toString(), fineGridCell{{SOLVER_NAME}}.toString());
178 """
179
180 templateTouchVertexLastTime="""
181 // Set boundary conditions vu = 0 strongly.
182 // This overwrites the result of A_CG * u and M * b at the boundary vertices.
183
184 if ( fineGridVertex{{SOLVER_NAME}}.getType() == vertexdata::{{SOLVER_NAME}}::Type::Boundary ) {
185 auto value = 0.0;
186 fineGridVertex{{SOLVER_NAME}}.setVu(value);
187 fineGridVertex{{SOLVER_NAME}}.setVb(value);
188 }
189 """
190
191 def __init__(self,
192 solver):
193 super( InitDofsTest8, self ).__init__()
194 self.d = {}
195 self.d["SOLVER_INSTANCE"] = solver.instance_name()
196 self.d["SOLVER_NAME"] = solver.typename()
197 self.d["VERTEX_CARDINALITY"] = solver._unknowns_per_vertex_node
198
199 def get_body_of_operation(self,operation_name):
200 result = ""
201 if operation_name==peano4.solversteps.ActionSet.OPERATION_TOUCH_VERTEX_FIRST_TIME:
202 result = jinja2.Template(self.templateTouchVertexFirstTime).render(**self.d)
203 pass
204 if operation_name==peano4.solversteps.ActionSet.OPERATION_TOUCH_CELL_FIRST_TIME:
205 result = jinja2.Template(self.templateTouchCellFirstTime).render(**self.d)
206 pass
207 if operation_name==peano4.solversteps.ActionSet.OPERATION_TOUCH_VERTEX_LAST_TIME:
208 result = jinja2.Template(self.templateTouchVertexLastTime).render(**self.d)
209 return result
210
212 """!
213
214 Configure name of generated C++ action set
215
216 This action set will end up in the directory observers with a name that
217 reflects how the observer (initialisation) is mapped onto this action
218 set. The name pattern is ObserverName2ActionSetIdentifier where this
219 routine co-determines the ActionSetIdentifier. We make is reflect the
220 Python class name.
221
222 """
223 return __name__.replace(".py", "").replace(".", "_")
224
226 """!
227
228 The action set that Peano will generate that corresponds to this class
229 should not be modified by users and can safely be overwritten every time
230 we run the Python toolkit.
231
232 """
233 return False
234
235 def get_includes(self):
236 """!
237
238 We need the solver repository in this action set, as we directly access
239 the solver object. We also need access to Peano's d-dimensional loops.
240
241 """
242 return """
243#include "repositories/SolverRepository.h"
244#include "peano4/utils/Loop.h"
245"""
Action set (reactions to events)
Definition ActionSet.py:6
In touchVertexFirstTime, we set the type of vertex we see (either Interior, Boundary or Coarse),...
Definition test8.py:18
get_body_of_operation(self, operation_name)
Return actual C++ code snippets to be inserted into C++ code.
Definition test8.py:199
str templateTouchVertexFirstTime
Definition test8.py:27
str templateTouchCellFirstTime
Definition test8.py:114
__init__(self, solver)
Definition test8.py:192
get_includes(self)
We need the solver repository in this action set, as we directly access the solver object.
Definition test8.py:235
get_action_set_name(self)
Configure name of generated C++ action set.
Definition test8.py:211
user_should_modify_template(self)
The action set that Peano will generate that corresponds to this class should not be modified by user...
Definition test8.py:225
str templateTouchVertexLastTime
Definition test8.py:180