Peano
Loading...
Searching...
No Matches
initCollocatedRandom.py
Go to the documentation of this file.
1from peano4.solversteps.ActionSet import ActionSet
2
3import peano4
4import jinja2
5
6
7
9 """!
10 In touchVertexFirstTime, we set the type of vertex we see (either Interior, Boundary or Coarse),
11 as well as sending some values to the solver implementation file to be placed into the mesh.
12
13 In touchCellFirstTime, we just determine the type, as we don't store anything on cells in
14 this solver.
15 """
16
17 templateTouchVertexFirstTime = """
18
19 /*
20 extremely hacky static random number generator
21 */
22 static std::mt19937 rng(0); // seed with 0 for reproducibility
23 static std::uniform_real_distribution<> dis(0.0, 1.0);
24
25
26 // this is done inside getDofType. included here for sanity check
27 auto isOnBoundary = [&]( const tarch::la::Vector< Dimensions, double > & x ) -> bool{
28 bool isOnBoundary = false;
29 for (int d=0; d<Dimensions; d++) {
30 isOnBoundary |= tarch::la::smallerEquals( x(d), DomainOffset(d) );
31 isOnBoundary |= tarch::la::greaterEquals( x(d), DomainOffset(d)+DomainSize(d) );
32 }
33 return isOnBoundary;
34 };
35
36 auto isCorner = [&]( const tarch::la::Vector< Dimensions, double > & x ) -> bool{
37 bool isCorner = true;
38 for (int d=0; d<Dimensions; d++) {
39 isCorner &= tarch::la::smallerEquals( x(d), DomainOffset(d) );
40 isCorner &= tarch::la::greaterEquals( x(d), DomainOffset(d)+DomainSize(d) );
41 }
42 return isCorner;
43 };
44
45 logTraceInWith3Arguments("InitDofs::touchVertexFirstTime", marker.toString(), isOnBoundary(marker.x()), fineGridVertex{{SOLVER_NAME}}.toString());
46
47 vertexdata::{{SOLVER_NAME}}::Type dofType = repositories::{{SOLVER_INSTANCE}}.getVertexDoFType(marker.x(),marker.h());
48
49 switch(dofType)
50 {
51 case vertexdata::{{SOLVER_NAME}}::Type::Boundary:
52 {
53 if ( marker.willBeRefined() )
54 {
55 // Coarse grid vertex. Mark it as such for later
56 fineGridVertex{{SOLVER_NAME}}.setType( vertexdata::{{SOLVER_NAME}}::Type::Coarse );
57 }
58 else
59 {
60 // we have boundary vertex
61 if ( isOnBoundary( marker.x() ) )
62 fineGridVertex{{SOLVER_NAME}}.setType( vertexdata::{{SOLVER_NAME}}::Type::Boundary );
63
64 // store
65 for (int dof=0; dof<{{VERTEX_CARDINALITY}}; dof++)
66 {
67 fineGridVertex{{SOLVER_NAME}}.setU( dof, 0.0);
68 fineGridVertex{{SOLVER_NAME}}.setRhs( dof, 0.0);
69 fineGridVertex{{SOLVER_NAME}}.setRand( dof, 0.0); // vector v_random is set to 0 on the boundary
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, 0.0);
95 fineGridVertex{{SOLVER_NAME}}.setRhs( dof, 0.0);
96 fineGridVertex{{SOLVER_NAME}}.setRand( dof, dis(rng)); // vector v_random receives random values in the interior vertices
97
98 }
99 }
100 }
101 break;
102
103 case vertexdata::{{SOLVER_NAME}}::Type::Coarse:
104 assertionMsg(false, "should not be returned by user" );
105 break;
106
107 case vertexdata::{{SOLVER_NAME}}::Type::Undefined:
108 assertionMsg(false, "should not be returned by user" );
109 break;
110 }
111
112
113 logTraceOutWith3Arguments("InitDofs::touchVertexFirstTime", marker.toString(), isOnBoundary(marker.x()), fineGridVertex{{SOLVER_NAME}}.toString());
114 """
115
116 templateTouchCellFirstTime = """
117 logTraceInWith2Arguments("InitDofs::touchCellFirstTime", marker.toString(), fineGridCell{{SOLVER_NAME}}.toString());
118
119 celldata::{{SOLVER_NAME}}::Type dofType = repositories::{{SOLVER_INSTANCE}}.getCellDoFType(marker.x(),marker.h());
120
121 switch(dofType)
122 {
123 case celldata::{{SOLVER_NAME}}::Type::Outside:
124 {
125 if ( marker.willBeRefined() ) // make it coarse
126 {
127 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Coarse );
128 }
129 else
130 {
131 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Outside );
132 }
133 }
134 break;
135
136 case celldata::{{SOLVER_NAME}}::Type::Interior:
137 {
138 if ( marker.willBeRefined() )
139 {
140 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Coarse );
141 }
142 else
143 {
144 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Interior );
145 // perform initialisation proc
146 // this does not work for more than one unknown per vertex
147
148 tarch::la::Vector<TwoPowerD, double> randValues;
149 for (int i=0; i<TwoPowerD; i++){
150 randValues[i] = fineGridVertices{{SOLVER_NAME}}(i).getRand(0);
151 }
152
153 // multiply v_random by A_cg
154 randValues = repositories::{{SOLVER_INSTANCE}}.getLocalAssemblyMatrix(marker.x(), marker.h()) * randValues;
155
156 // place this into rhs
157 for (int i=0; i<TwoPowerD; i++){
158 fineGridVertices{{SOLVER_NAME}}(i).setRhs(
159 fineGridVertices{{SOLVER_NAME}}(i).getRhs() + randValues(i)
160 );
161 }
162
163 }
164 }
165 break;
166
167 }
168
169 logTraceOutWith2Arguments("InitDofs::touchCellFirstTime", marker.toString(), fineGridCell{{SOLVER_NAME}}.toString());
170 """
171
172 templateTouchVertexLastTime="""
173
174 """
175
176 def __init__(self,
177 solver):
178 super( InitDofsCollocatedRandomRhs, self ).__init__()
179 self.d = {}
180 self.d["SOLVER_INSTANCE"] = solver.instance_name()
181 self.d["SOLVER_NAME"] = solver.typename()
182 self.d["VERTEX_CARDINALITY"] = solver._unknowns_per_vertex_node
183
184 def get_body_of_operation(self,operation_name):
185 result = ""
186 if operation_name==peano4.solversteps.ActionSet.OPERATION_TOUCH_VERTEX_FIRST_TIME:
187 result = jinja2.Template(self.templateTouchVertexFirstTime).render(**self.d)
188 pass
189 if operation_name==peano4.solversteps.ActionSet.OPERATION_TOUCH_CELL_FIRST_TIME:
190 result = jinja2.Template(self.templateTouchCellFirstTime).render(**self.d)
191 pass
192 if operation_name==peano4.solversteps.ActionSet.OPERATION_TOUCH_VERTEX_LAST_TIME:
193 result = jinja2.Template(self.templateTouchVertexLastTime).render(**self.d)
194 return result
195
197 """!
198
199 Configure name of generated C++ action set
200
201 This action set will end up in the directory observers with a name that
202 reflects how the observer (initialisation) is mapped onto this action
203 set. The name pattern is ObserverName2ActionSetIdentifier where this
204 routine co-determines the ActionSetIdentifier. We make is reflect the
205 Python class name.
206
207 """
208 return __name__.replace(".py", "").replace(".", "_")
209
211 """!
212
213 The action set that Peano will generate that corresponds to this class
214 should not be modified by users and can safely be overwritten every time
215 we run the Python toolkit.
216
217 """
218 return False
219
220 def get_includes(self):
221 """!
222
223 We need the solver repository in this action set, as we directly access
224 the solver object. We also need access to Peano's d-dimensional loops.
225
226 """
227 return """
228#include "repositories/SolverRepository.h"
229#include <random>
230#include "peano4/utils/Loop.h"
231"""
232
233
235 """!
236 Exactly the same as above, with slightly modified templateTouchVertexFirstTime
237
238 Don't specialise anything apart from one template. Everything else
239 will be exactly the same
240 """
241 def __init__(self,
242 solver):
243
244 super( InitDofsCollocatedRandomTest2, self ).__init__( solver )
245
246 templateTouchVertexFirstTime = """
247
248 /*
249 extremely hacky static random number generator
250 */
251 static std::mt19937 rng(0); // seed with 0 for reproducibility
252 static std::uniform_real_distribution<> dis(0.0, 1.0);
253
254
255 // this is done inside getDofType. included here for sanity check
256 auto isOnBoundary = [&]( const tarch::la::Vector< Dimensions, double > & x ) -> bool{
257 bool isOnBoundary = false;
258 for (int d=0; d<Dimensions; d++) {
259 isOnBoundary |= tarch::la::smallerEquals( x(d), DomainOffset(d) );
260 isOnBoundary |= tarch::la::greaterEquals( x(d), DomainOffset(d)+DomainSize(d) );
261 }
262 return isOnBoundary;
263 };
264
265 auto isCorner = [&]( const tarch::la::Vector< Dimensions, double > & x ) -> bool{
266 bool isCorner = true;
267 for (int d=0; d<Dimensions; d++) {
268 isCorner &= tarch::la::smallerEquals( x(d), DomainOffset(d) );
269 isCorner &= tarch::la::greaterEquals( x(d), DomainOffset(d)+DomainSize(d) );
270 }
271 return isCorner;
272 };
273
274 logTraceInWith3Arguments("InitDofs::touchVertexFirstTime", marker.toString(), isOnBoundary(marker.x()), fineGridVertex{{SOLVER_NAME}}.toString());
275
276 vertexdata::{{SOLVER_NAME}}::Type dofType = repositories::{{SOLVER_INSTANCE}}.getVertexDoFType(marker.x(),marker.h());
277
278 switch(dofType)
279 {
280 case vertexdata::{{SOLVER_NAME}}::Type::Boundary:
281 {
282 if ( marker.willBeRefined() )
283 {
284 // Coarse grid vertex. Mark it as such for later
285 fineGridVertex{{SOLVER_NAME}}.setType( vertexdata::{{SOLVER_NAME}}::Type::Coarse );
286 }
287 else
288 {
289 // we have boundary vertex
290 if ( isOnBoundary( marker.x() ) )
291 fineGridVertex{{SOLVER_NAME}}.setType( vertexdata::{{SOLVER_NAME}}::Type::Boundary );
292
293 // store
294 for (int dof=0; dof<{{VERTEX_CARDINALITY}}; dof++)
295 {
296 fineGridVertex{{SOLVER_NAME}}.setU( dof, 0.0); // vector v_random is set to 0 on the boundary as the initial guess
297 fineGridVertex{{SOLVER_NAME}}.setRhs( dof, 0.0);
298 fineGridVertex{{SOLVER_NAME}}.setRand( dof, 0.0); // vector v_random is set to 0 on the boundary
299 }
300 }
301 }
302 break;
303
304 case vertexdata::{{SOLVER_NAME}}::Type::Interior:
305 {
306 if (isOnBoundary(marker.x()))
307 {
308 logWarning( "touchVertexFirstTime(...)", "vertex at " << marker.toString() << " labelled as interior even though it is located at global domain boundary" );
309 }
310
311 if ( marker.willBeRefined() )
312 {
313 fineGridVertex{{SOLVER_NAME}}.setType( vertexdata::{{SOLVER_NAME}}::Type::Coarse );
314 }
315
316 else
317 {
318 fineGridVertex{{SOLVER_NAME}}.setType( vertexdata::{{SOLVER_NAME}}::Type::Interior );
319
320 // store
321 for (int dof=0; dof<{{VERTEX_CARDINALITY}}; dof++)
322 {
323 double randVal = dis(rng);
324 fineGridVertex{{SOLVER_NAME}}.setU(dof, randVal); // vector v_random receives random values in the interior vertices
325 // and used as the initial guess for the CG solver
326 fineGridVertex{{SOLVER_NAME}}.setRhs( dof, 0.0);
327 fineGridVertex{{SOLVER_NAME}}.setRand( dof, randVal); // the same vector v_random will be used to compute rhs = A_CG * v_random,
328 // see templateTouchCellFirstTime in the parent class
329
330 // use a continuous distribution x*y*(1-x)*(1-y) for "u_random" instead of the random one
331 //fineGridVertex{{SOLVER_NAME}}.setRand( dof, marker.x()(0)*marker.x()(1)*(1.0-marker.x()(0))*(1.0-marker.x()(1)) );
332 }
333 }
334 }
335 break;
336
337 case vertexdata::{{SOLVER_NAME}}::Type::Coarse:
338 assertionMsg(false, "should not be returned by user" );
339 break;
340
341 case vertexdata::{{SOLVER_NAME}}::Type::Undefined:
342 assertionMsg(false, "should not be returned by user" );
343 break;
344 }
345
346
347 logTraceOutWith3Arguments("InitDofs::touchVertexFirstTime", marker.toString(), isOnBoundary(marker.x()), fineGridVertex{{SOLVER_NAME}}.toString());
348 """
349
350
352 templateTouchVertexFirstTime="""
353 /*
354 extremely hacky static random number generator
355 */
356 static std::mt19937 rng(0); // seed with 0 for reproducibility
357 static std::uniform_real_distribution<> dis(0.0, 1.0);
358
359
360 // this is done inside getDofType. included here for sanity check
361 auto isOnBoundary = [&]( const tarch::la::Vector< Dimensions, double > & x ) -> bool{
362 bool isOnBoundary = false;
363 for (int d=0; d<Dimensions; d++) {
364 isOnBoundary |= tarch::la::smallerEquals( x(d), DomainOffset(d) );
365 isOnBoundary |= tarch::la::greaterEquals( x(d), DomainOffset(d)+DomainSize(d) );
366 }
367 return isOnBoundary;
368 };
369
370 auto isCorner = [&]( const tarch::la::Vector< Dimensions, double > & x ) -> bool{
371 bool isCorner = true;
372 for (int d=0; d<Dimensions; d++) {
373 isCorner &= tarch::la::smallerEquals( x(d), DomainOffset(d) );
374 isCorner &= tarch::la::greaterEquals( x(d), DomainOffset(d)+DomainSize(d) );
375 }
376 return isCorner;
377 };
378
379 vertexdata::{{SOLVER_NAME}}::Type dofType = repositories::{{SOLVER_INSTANCE}}.getVertexDoFType(marker.x(),marker.h());
380
381 switch(dofType)
382 {
383 case vertexdata::{{SOLVER_NAME}}::Type::Boundary:
384 {
385 if ( marker.willBeRefined() )
386 {
387 // Coarse grid vertex. Mark it as such for later
388 fineGridVertex{{SOLVER_NAME}}.setType( vertexdata::{{SOLVER_NAME}}::Type::Coarse );
389 }
390 else
391 {
392 // we have boundary vertex
393 if ( isOnBoundary( marker.x() ) )
394 fineGridVertex{{SOLVER_NAME}}.setType( vertexdata::{{SOLVER_NAME}}::Type::Boundary );
395
396 // store
397 for (int dof=0; dof<{{VERTEX_CARDINALITY}}; dof++)
398 {
399 fineGridVertex{{SOLVER_NAME}}.setU( dof, dis(rng)); // vector v_random is set to 0 on the boundary as the initial guess
400 fineGridVertex{{SOLVER_NAME}}.setRhs( dof, 0.0);
401 fineGridVertex{{SOLVER_NAME}}.setVector2( dof, 0.0); // vector v_random is set to 0 on the boundary
402 }
403 }
404 }
405 break;
406
407 case vertexdata::{{SOLVER_NAME}}::Type::Interior:
408 {
409 if (isOnBoundary(marker.x()))
410 {
411 logWarning( "touchVertexFirstTime(...)", "vertex at " << marker.toString() << " labelled as interior even though it is located at global domain boundary" );
412 }
413
414 if ( marker.willBeRefined() )
415 {
416 fineGridVertex{{SOLVER_NAME}}.setType( vertexdata::{{SOLVER_NAME}}::Type::Coarse );
417 }
418
419 else
420 {
421 fineGridVertex{{SOLVER_NAME}}.setType( vertexdata::{{SOLVER_NAME}}::Type::Interior );
422
423 // store
424 for (int dof=0; dof<{{VERTEX_CARDINALITY}}; dof++)
425 {
426 // give it a random number
427 fineGridVertex{{SOLVER_NAME}}.setU(dof, dis(rng)); // vector v_random receives random values in the interior vertices
428 // and used as the initial guess for the CG solver
429 fineGridVertex{{SOLVER_NAME}}.setRhs( dof, 0.0);
430 fineGridVertex{{SOLVER_NAME}}.setVector2( dof, 0.0);
431 }
432 }
433 }
434 break;
435
436 case vertexdata::{{SOLVER_NAME}}::Type::Coarse:
437 assertionMsg(false, "should not be returned by user" );
438 break;
439
440 case vertexdata::{{SOLVER_NAME}}::Type::Undefined:
441 assertionMsg(false, "should not be returned by user" );
442 break;
443 }
444 """
445
446 templateTouchCellFirstTime="""
447 logTraceInWith2Arguments("InitDofs::touchCellFirstTime", marker.toString(), fineGridCell{{SOLVER_NAME}}.toString());
448
449 celldata::{{SOLVER_NAME}}::Type dofType = repositories::{{SOLVER_INSTANCE}}.getCellDoFType(marker.x(),marker.h());
450
451 switch(dofType)
452 {
453 case celldata::{{SOLVER_NAME}}::Type::Outside:
454 {
455 if ( marker.willBeRefined() ) // make it coarse
456 {
457 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Coarse );
458 }
459 else
460 {
461 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Outside );
462 }
463 }
464 break;
465
466 case celldata::{{SOLVER_NAME}}::Type::Interior:
467 {
468 if ( marker.willBeRefined() )
469 {
470 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Coarse );
471 }
472 else
473 {
474 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Interior );
475 }
476 }
477 break;
478
479 }
480
481 logTraceOutWith2Arguments("InitDofs::touchCellFirstTime", marker.toString(), fineGridCell{{SOLVER_NAME}}.toString());
482
483 """
484 def __init__(self,
485 solver):
486 super( InitCollocatedTest4, self ).__init__(solver)
487 self.dd = {}
488 self.dd["SOLVER_INSTANCE"] = solver.instance_name()
489 self.dd["SOLVER_NAME"] = solver.typename()
490 self.dd["VERTEX_CARDINALITY"] = solver._unknowns_per_vertex_node
491
493 templateTouchVertexFirstTime="""
494 /*
495 extremely hacky static random number generator
496 */
497 static std::mt19937 rng(0); // seed with 0 for reproducibility
498 static std::uniform_real_distribution<> dis(0.0, 1.0);
499
500
501 // this is done inside getDofType. included here for sanity check
502 auto isOnBoundary = [&]( const tarch::la::Vector< Dimensions, double > & x ) -> bool{
503 bool isOnBoundary = false;
504 for (int d=0; d<Dimensions; d++) {
505 isOnBoundary |= tarch::la::smallerEquals( x(d), DomainOffset(d) );
506 isOnBoundary |= tarch::la::greaterEquals( x(d), DomainOffset(d)+DomainSize(d) );
507 }
508 return isOnBoundary;
509 };
510
511 auto isCorner = [&]( const tarch::la::Vector< Dimensions, double > & x ) -> bool{
512 bool isCorner = true;
513 for (int d=0; d<Dimensions; d++) {
514 isCorner &= tarch::la::smallerEquals( x(d), DomainOffset(d) );
515 isCorner &= tarch::la::greaterEquals( x(d), DomainOffset(d)+DomainSize(d) );
516 }
517 return isCorner;
518 };
519
520 vertexdata::{{SOLVER_NAME}}::Type dofType = repositories::{{SOLVER_INSTANCE}}.getVertexDoFType(marker.x(),marker.h());
521
522 switch(dofType)
523 {
524 case vertexdata::{{SOLVER_NAME}}::Type::Boundary:
525 {
526 if ( marker.willBeRefined() )
527 {
528 // Coarse grid vertex. Mark it as such for later
529 fineGridVertex{{SOLVER_NAME}}.setType( vertexdata::{{SOLVER_NAME}}::Type::Coarse );
530 }
531 else
532 {
533 // we have boundary vertex
534 if ( isOnBoundary( marker.x() ) )
535 fineGridVertex{{SOLVER_NAME}}.setType( vertexdata::{{SOLVER_NAME}}::Type::Boundary );
536
537 // store
538 for (int dof=0; dof<{{VERTEX_CARDINALITY}}; dof++)
539 {
540 fineGridVertex{{SOLVER_NAME}}.setRand( dof, dis(rng)); // vector v_random is set to 0 on the boundary as the initial guess
541 fineGridVertex{{SOLVER_NAME}}.setRhs( dof, 0.0);
542 }
543 }
544 }
545 break;
546
547 case vertexdata::{{SOLVER_NAME}}::Type::Interior:
548 {
549 if (isOnBoundary(marker.x()))
550 {
551 logWarning( "touchVertexFirstTime(...)", "vertex at " << marker.toString() << " labelled as interior even though it is located at global domain boundary" );
552 }
553
554 if ( marker.willBeRefined() )
555 {
556 fineGridVertex{{SOLVER_NAME}}.setType( vertexdata::{{SOLVER_NAME}}::Type::Coarse );
557 }
558
559 else
560 {
561 fineGridVertex{{SOLVER_NAME}}.setType( vertexdata::{{SOLVER_NAME}}::Type::Interior );
562
563 // store
564 for (int dof=0; dof<{{VERTEX_CARDINALITY}}; dof++)
565 {
566 // give it a random number
567 fineGridVertex{{SOLVER_NAME}}.setRand(dof, dis(rng)); // vector v_random receives random values in the interior vertices
568 // and used as the initial guess for the CG solver
569 fineGridVertex{{SOLVER_NAME}}.setRhs( dof, 0.0);
570 }
571 }
572 }
573 break;
574
575 case vertexdata::{{SOLVER_NAME}}::Type::Coarse:
576 assertionMsg(false, "should not be returned by user" );
577 break;
578
579 case vertexdata::{{SOLVER_NAME}}::Type::Undefined:
580 assertionMsg(false, "should not be returned by user" );
581 break;
582 }
583 """
584
585 templateTouchCellFirstTime="""
586
587 celldata::{{SOLVER_NAME}}::Type dofType = repositories::{{SOLVER_INSTANCE}}.getCellDoFType(marker.x(),marker.h());
588
589 switch(dofType)
590 {
591 case celldata::{{SOLVER_NAME}}::Type::Outside:
592 {
593 if ( marker.willBeRefined() ) // make it coarse
594 {
595 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Coarse );
596 }
597 else
598 {
599 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Outside );
600 }
601 }
602 break;
603
604 case celldata::{{SOLVER_NAME}}::Type::Interior:
605 {
606 if ( marker.willBeRefined() )
607 {
608 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Coarse );
609 }
610 else
611 {
612 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Interior );
613
614 // also set the extras
615 // start by fetching the random values from the cg vertices
616 tarch::la::Vector<TwoPowerD, double> randoms;
617 for (int i=0; i<TwoPowerD; i++) randoms(i) = fineGridVertices{{SOLVER_NAME}}(i).getRand(0);
618
619 auto ACGValues = repositories::{{SOLVER_INSTANCE}}.getLocalAssemblyMatrix( marker.x(), marker.h() ) * randoms;
620 auto MCGValues = repositories::{{SOLVER_INSTANCE}}.getMassMatrix( marker.x(), marker.h() ) * randoms;
621
622 for (int i=0; i<TwoPowerD; i++) {
623 fineGridVertices{{SOLVER_NAME}}(i).setAcg( 0, ACGValues(i) + fineGridVertices{{SOLVER_NAME}}(i).getAcg(0) );
624 fineGridVertices{{SOLVER_NAME}}(i).setMcg( 0, MCGValues(i) + fineGridVertices{{SOLVER_NAME}}(i).getMcg(0) );
625 }
626 }
627 }
628 break;
629
630 }
631
632 """
633
634 def __init__(self,
635 solver):
636 super( InitCollocatedTest5, self ).__init__(solver)
637 self.dd = {}
638 self.dd["SOLVER_INSTANCE"] = solver.instance_name()
639 self.dd["SOLVER_NAME"] = solver.typename()
640 self.dd["VERTEX_CARDINALITY"] = solver._unknowns_per_vertex_node
641
643 """!
644 We just need random numbers in the inital guess and elsewhere zeroess
645 """
646
647 templateTouchVertexFirstTime = """
648
649 /*
650 extremely hacky static random number generator
651 */
652 static std::mt19937 rng(0); // seed with 0 for reproducibility
653 static std::uniform_real_distribution<> dis(0.0, 1.0);
654
655
656 // this is done inside getDofType. included here for sanity check
657 auto isOnBoundary = [&]( const tarch::la::Vector< Dimensions, double > & x ) -> bool{
658 bool isOnBoundary = false;
659 for (int d=0; d<Dimensions; d++) {
660 isOnBoundary |= tarch::la::smallerEquals( x(d), DomainOffset(d) );
661 isOnBoundary |= tarch::la::greaterEquals( x(d), DomainOffset(d)+DomainSize(d) );
662 }
663 return isOnBoundary;
664 };
665
666 auto isCorner = [&]( const tarch::la::Vector< Dimensions, double > & x ) -> bool{
667 bool isCorner = true;
668 for (int d=0; d<Dimensions; d++) {
669 isCorner &= tarch::la::smallerEquals( x(d), DomainOffset(d) );
670 isCorner &= tarch::la::greaterEquals( x(d), DomainOffset(d)+DomainSize(d) );
671 }
672 return isCorner;
673 };
674
675 logTraceInWith3Arguments("InitDofs::touchVertexFirstTime", marker.toString(), isOnBoundary(marker.x()), fineGridVertex{{SOLVER_NAME}}.toString());
676
677 vertexdata::{{SOLVER_NAME}}::Type dofType = repositories::{{SOLVER_INSTANCE}}.getVertexDoFType(marker.x(),marker.h());
678
679 switch(dofType)
680 {
681 case vertexdata::{{SOLVER_NAME}}::Type::Boundary:
682 {
683 if ( marker.willBeRefined() )
684 {
685 // Coarse grid vertex. Mark it as such for later
686 fineGridVertex{{SOLVER_NAME}}.setType( vertexdata::{{SOLVER_NAME}}::Type::Coarse );
687 }
688 else
689 {
690 // we have boundary vertex
691 if ( isOnBoundary( marker.x() ) )
692 fineGridVertex{{SOLVER_NAME}}.setType( vertexdata::{{SOLVER_NAME}}::Type::Boundary );
693
694 // store
695 for (int dof=0; dof<{{VERTEX_CARDINALITY}}; dof++)
696 {
697 fineGridVertex{{SOLVER_NAME}}.setU( dof, 0.0);
698 fineGridVertex{{SOLVER_NAME}}.setRhs( dof, 0.0);
699
700 fineGridVertex{{SOLVER_NAME}}.setRand( dof, 0.0); // vector v_random is set to 0 on the boundary
701 }
702 }
703 }
704 break;
705
706 case vertexdata::{{SOLVER_NAME}}::Type::Interior:
707 {
708 if (isOnBoundary(marker.x()))
709 {
710 logWarning( "touchVertexFirstTime(...)", "vertex at " << marker.toString() << " labelled as interior even though it is located at global domain boundary" );
711 }
712
713 if ( marker.willBeRefined() )
714 {
715 fineGridVertex{{SOLVER_NAME}}.setType( vertexdata::{{SOLVER_NAME}}::Type::Coarse );
716 }
717
718 else
719 {
720 fineGridVertex{{SOLVER_NAME}}.setType( vertexdata::{{SOLVER_NAME}}::Type::Interior );
721
722 // store
723 for (int dof=0; dof<{{VERTEX_CARDINALITY}}; dof++)
724 {
725 fineGridVertex{{SOLVER_NAME}}.setU(dof, 0.0);
726 fineGridVertex{{SOLVER_NAME}}.setRhs( dof, 0.0);
727
728 // set random values
729 double randVal = dis(rng);
730 // set the ref. solution instead of random for debugging
731 // double randVal = std::sin( 2.0*tarch::la::PI * marker.x()(0) ) * std::sin( 2.0*tarch::la::PI * marker.x()(1) );
732
733 // save the random vector separately
734 fineGridVertex{{SOLVER_NAME}}.setRand( dof, randVal);
735 }
736 }
737 }
738 break;
739
740 case vertexdata::{{SOLVER_NAME}}::Type::Coarse:
741 assertionMsg(false, "should not be returned by user" );
742 break;
743
744 case vertexdata::{{SOLVER_NAME}}::Type::Undefined:
745 assertionMsg(false, "should not be returned by user" );
746 break;
747 }
748
749
750 logTraceOutWith3Arguments("InitDofs::touchVertexFirstTime", marker.toString(), isOnBoundary(marker.x()), fineGridVertex{{SOLVER_NAME}}.toString());
751 """
752
753 templateTouchCellFirstTime="""
754 logTraceInWith2Arguments("InitDofs::touchCellFirstTime", marker.toString(), fineGridCell{{SOLVER_NAME}}.toString());
755
756 celldata::{{SOLVER_NAME}}::Type dofType = repositories::{{SOLVER_INSTANCE}}.getCellDoFType(marker.x(),marker.h());
757
758 switch(dofType)
759 {
760 case celldata::{{SOLVER_NAME}}::Type::Outside:
761 {
762 if ( marker.willBeRefined() ) // make it coarse
763 {
764 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Coarse );
765 }
766 else
767 {
768 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Outside );
769 }
770 }
771 break;
772
773 case celldata::{{SOLVER_NAME}}::Type::Interior:
774 {
775 if ( marker.willBeRefined() )
776 {
777 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Coarse );
778 }
779 else
780 {
781 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Interior );
782 }
783 }
784 break;
785
786 }
787
788 logTraceOutWith2Arguments("InitDofs::touchCellFirstTime", marker.toString(), fineGridCell{{SOLVER_NAME}}.toString());
789
790 """
791
792 templateTouchVertexLastTime="""
793
794 """
We just need random numbers in the inital guess and elsewhere zeroess.
In touchVertexFirstTime, we set the type of vertex we see (either Interior, Boundary or Coarse),...
user_should_modify_template(self)
The action set that Peano will generate that corresponds to this class should not be modified by user...
get_body_of_operation(self, operation_name)
Return actual C++ code snippets to be inserted into C++ code.
get_action_set_name(self)
Configure name of generated C++ action set.
get_includes(self)
We need the solver repository in this action set, as we directly access the solver object.
Exactly the same as above, with slightly modified templateTouchVertexFirstTime.
Action set (reactions to events)
Definition ActionSet.py:6