9 Redoing this class for discontinuous galerkin solver.
11 This time, we store values only in the cells and just
12 determine the type of vertex we see.
14 templateTouchVertexFirstTime =
"""
16 //logTraceInWith3Arguments("InitDofsDG::touchVertexFirstTime", marker.toString(), isOnBoundary(marker.x()), fineGridVertex{{SOLVER_NAME}}.toString());
18 vertexdata::{{SOLVER_NAME}}::Type dofType = repositories::{{SOLVER_INSTANCE}}.getVertexDoFType(marker.x(),marker.h());
23 case vertexdata::{{SOLVER_NAME}}::Type::Interior:
25 if ( marker.willBeRefined() )
27 fineGridVertex{{SOLVER_NAME}}.setType( vertexdata::{{SOLVER_NAME}}::Type::Coarse );
32 fineGridVertex{{SOLVER_NAME}}.setType( vertexdata::{{SOLVER_NAME}}::Type::Interior );
37 case vertexdata::{{SOLVER_NAME}}::Type::Coarse:
38 assertionMsg(false, "should not be returned by user" );
41 case vertexdata::{{SOLVER_NAME}}::Type::Undefined:
42 assertionMsg(false, "should not be returned by user" );
47 //logTraceOutWith2Arguments("InitDofsDG::touchVertexFirstTime", marker.toString(), fineGridVertex{{SOLVER_NAME}}.toString());
50 templateTouchCellFirstTime =
"""
51 logTraceInWith2Arguments("InitDofs::touchCellFirstTime", marker.toString(), fineGridCell{{SOLVER_NAME}}.toString());
53 auto insertIfNotPresent = []( std::vector<int>& v, int i ) {
54 if( std::find( v.begin(), v.end(), i ) == v.end() ) v.push_back(i);
57 // anonymous functions to calculate cell indices which are on the boundary
58 std::vector<int> indicesOnBoundary;
60 for (int f=0; f<TwoTimesD; f++) {
61 if( fineGridFaces{{SOLVER_NAME}}(f).getType() == facedata::{{SOLVER_NAME}}::Type::Boundary ) {
62 // this face is on the boundary. Gather the cell dof indices this corresponds to
66 for (int i=0; i<repositories::{{SOLVER_INSTANCE}}.PolyDegree+1; i++) insertIfNotPresent( indicesOnBoundary, (repositories::{{SOLVER_INSTANCE}}.PolyDegree+1 + 1)*i );
70 for (int i=0; i<repositories::{{SOLVER_INSTANCE}}.PolyDegree+1; i++) insertIfNotPresent( indicesOnBoundary, i );
74 for (int i=0; i<repositories::{{SOLVER_INSTANCE}}.PolyDegree+1; i++) insertIfNotPresent( indicesOnBoundary, repositories::{{SOLVER_INSTANCE}}.PolyDegree + (repositories::{{SOLVER_INSTANCE}}.PolyDegree+1 + 1)*i );
78 for (int i=(repositories::{{SOLVER_INSTANCE}}.PolyDegree+1)*repositories::{{SOLVER_INSTANCE}}.PolyDegree; i<(repositories::{{SOLVER_INSTANCE}}.PolyDegree+1)*(repositories::{{SOLVER_INSTANCE}}.PolyDegree+1); i++) insertIfNotPresent( indicesOnBoundary, i );
86 auto indexIsOnBoundary = [&indicesOnBoundary](int i) -> bool { return not( indicesOnBoundary.empty() ) and std::find( indicesOnBoundary.begin(), indicesOnBoundary.end(), i ) != indicesOnBoundary.end() ; };
88 celldata::{{SOLVER_NAME}}::Type dofType = repositories::{{SOLVER_INSTANCE}}.getCellDoFType(marker.x(),marker.h());
91 extremely hacky static random number generator
93 static std::mt19937 rng(0); // seed with 0 for reproducibility
94 static std::uniform_real_distribution<> dis(0.0, 1.0);
98 case celldata::{{SOLVER_NAME}}::Type::Outside:
100 if ( marker.willBeRefined() ) // make it coarse
102 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Coarse );
106 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Outside );
111 case celldata::{{SOLVER_NAME}}::Type::Interior:
113 if ( marker.willBeRefined() )
115 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Coarse );
119 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Interior );
121 // create vectors to send to implementation
122 tarch::la::Vector< repositories::{{SOLVER_INSTANCE}}.CellUnknowns, double > solution;
123 tarch::la::Vector< repositories::{{SOLVER_INSTANCE}}.CellUnknowns, double > rhs;
124 tarch::la::Vector< repositories::{{SOLVER_INSTANCE}}.CellUnknowns, double > residual;
126 // first - fill the solution vector with randoms
127 for (int i=0; i<repositories::{{SOLVER_INSTANCE}}.CellUnknowns; i++) {
128 if ( indexIsOnBoundary(i) ) {
134 solution[i] = dis(rng);
136 // and residual to 0...
140 // set rhs and update when we have all the projections...
141 rhs = repositories::{{SOLVER_INSTANCE}}.getLocalAssemblyMatrix(marker.x(), marker.h()) * solution;
144 fineGridCell{{SOLVER_NAME}}.setSolution( solution );
145 fineGridCell{{SOLVER_NAME}}.setRhs( rhs );
146 fineGridCell{{SOLVER_NAME}}.setResidual( residual );
147 fineGridCell{{SOLVER_NAME}}.setRand( solution );
149 // now we need to compute all projections...
150 auto faceProjections = repositories::{{SOLVER_INSTANCE}}. getFaceFromCellMatrix(marker.x(), marker.h()) * solution;
152 for (int f=0; f<TwoTimesD; f++) {
153 int startIndexProjection =
155 repositories::{{SOLVER_INSTANCE}}.NodesPerFace * repositories::{{SOLVER_INSTANCE}}.ProjectionsPerFaceNode :
157 for (int p=0; p<repositories::{{SOLVER_INSTANCE}}.NodesPerFace * repositories::{{SOLVER_INSTANCE}}.ProjectionsPerFaceNode; p++) {
158 fineGridFaces{{SOLVER_NAME}}(f).setProjection(
159 p + startIndexProjection,
160 faceProjections( f*repositories::{{SOLVER_INSTANCE}}.FaceUnknownsProjection + p + startIndexProjection )
173 logTraceOutWith2Arguments("InitDofs::touchCellFirstTime", marker.toString(), fineGridCell{{SOLVER_NAME}}.toString());
176 templateTouchFaceFirstTime =
"""
177 logTraceInWith2Arguments("InitDofs::touchFaceFirstTime", marker.toString(), fineGridFace{{SOLVER_NAME}}.toString());
179 facedata::{{SOLVER_NAME}}::Type dofType = repositories::{{SOLVER_INSTANCE}}.getFaceDoFType(marker.x(),marker.h());
183 case facedata::{{SOLVER_NAME}}::Type::Outside:
185 if ( marker.willBeRefined() ) // make it coarse
187 fineGridFace{{SOLVER_NAME}}.setType( facedata::{{SOLVER_NAME}}::Type::Coarse );
191 fineGridFace{{SOLVER_NAME}}.setType( facedata::{{SOLVER_NAME}}::Type::Outside );
195 case facedata::{{SOLVER_NAME}}::Type::Interior:
197 if ( marker.willBeRefined() )
199 fineGridFace{{SOLVER_NAME}}.setType( facedata::{{SOLVER_NAME}}::Type::Coarse );
203 fineGridFace{{SOLVER_NAME}}.setType( facedata::{{SOLVER_NAME}}::Type::Interior );
205 // vectors to be passed into face
206 tarch::la::Vector< repositories::{{SOLVER_INSTANCE}}.FaceUnknownsSolution, double > sol;
207 tarch::la::Vector< repositories::{{SOLVER_INSTANCE}}.FaceUnknownsProjection, double > projection;
209 // set all of these values to 0
210 for (int i=0; i<repositories::{{SOLVER_INSTANCE}}.FaceUnknownsSolution; i++)
213 for (int i=0; i<repositories::{{SOLVER_INSTANCE}}.FaceUnknownsProjection; i++)
218 fineGridFace{{SOLVER_NAME}}.setSolution(sol);
219 fineGridFace{{SOLVER_NAME}}.setProjection(projection);
224 case facedata::{{SOLVER_NAME}}::Type::Boundary:
226 if ( marker.willBeRefined() )
228 fineGridFace{{SOLVER_NAME}}.setType( facedata::{{SOLVER_NAME}}::Type::Coarse );
232 fineGridFace{{SOLVER_NAME}}.setType( facedata::{{SOLVER_NAME}}::Type::Boundary );
234 // vectors to be passed into face
235 tarch::la::Vector< repositories::{{SOLVER_INSTANCE}}.FaceUnknownsSolution, double > sol;
236 tarch::la::Vector< repositories::{{SOLVER_INSTANCE}}.FaceUnknownsProjection, double > projection;
238 // set all of these values to 0
239 for (int i=0; i<repositories::{{SOLVER_INSTANCE}}.FaceUnknownsSolution; i++)
242 for (int i=0; i<repositories::{{SOLVER_INSTANCE}}.FaceUnknownsProjection; i++)
246 fineGridFace{{SOLVER_NAME}}.setSolution(sol);
247 fineGridFace{{SOLVER_NAME}}.setProjection(projection);
254 logTraceOutWith2Arguments("InitDofs::touchFaceFirstTime", marker.toString(), fineGridFace{{SOLVER_NAME}}.toString());
259 super( InitDofsDGTest1, self ).
__init__()
261 self.
d[
"SOLVER_INSTANCE"] = solver.instance_name()
262 self.
d[
"SOLVER_NAME"] = solver.typename()
267 if operation_name==peano4.solversteps.ActionSet.OPERATION_TOUCH_VERTEX_FIRST_TIME:
270 if operation_name==peano4.solversteps.ActionSet.OPERATION_TOUCH_CELL_FIRST_TIME:
273 if operation_name==peano4.solversteps.ActionSet.OPERATION_TOUCH_FACE_FIRST_TIME:
281 Configure name of generated C++ action set
283 This action set will end up in the directory observers with a name that
284 reflects how the observer (initialisation) is mapped onto this action
285 set. The name pattern is ObserverName2ActionSetIdentifier where this
286 routine co-determines the ActionSetIdentifier. We make is reflect the
290 return __name__.replace(
".py",
"").replace(
".",
"_")
295 The action set that Peano will generate that corresponds to this class
296 should not be modified by users and can safely be overwritten every time
297 we run the Python toolkit.
305 We need the solver repository in this action set, as we directly access
306 the solver object. We also need access to Peano's d-dimensional loops.
310#include "repositories/SolverRepository.h"
311#include "peano4/utils/Loop.h"
312#include<numeric> // for std::iota
318 Perform some intermediate actions in test 1, namely:
319 - Fix the face solution, with projections that we get from the init phase
320 - Fix the rhs, using new face solution projected back into cell
322 This action set will run first, so we can fix the face solution (perhaps redundantly,
323 as the first TFFT in the solver will do this anyway), and then we fix the rhs during
324 the TCFT of this action set, which will be run first.
326 We only want to do this once, so we have a static int to keep count...
329 templateEndTraversal=
"""
333 templateTouchFaceFirstTime=
"""
335 fineGridFace{{SOLVER_NAME}}.getType() == facedata::{{SOLVER_NAME}}::Type::Interior
339 logTraceInWith2Arguments( "updateFaceSolution::Interior", fineGridFace{{SOLVER_NAME}}.getSolution(), marker.toString() );
341 // project the u^\pm into a temporary vector
342 tarch::la::Vector< repositories::{{SOLVER_INSTANCE}}.FaceUnknownsSolution, double > projection =
343 repositories::{{SOLVER_INSTANCE}}.getRiemannMatrix() * fineGridFace{{SOLVER_NAME}}.getProjection();
345 for (int i=0; i<repositories::{{SOLVER_INSTANCE}}.FaceUnknownsSolution; i++)
346 fineGridFace{{SOLVER_NAME}}.setSolution(
348 repositories::{{SOLVER_INSTANCE}}.OmegaFace * projection(i)
350 logTraceOutWith1Argument( "updateFaceSolution::Interior", fineGridFace{{SOLVER_NAME}}.getSolution() );
354 fineGridFace{{SOLVER_NAME}}.getType() == facedata::{{SOLVER_NAME}}::Type::Boundary
358 logTraceInWith1Argument( "updateFaceSolution::InteriorPenalty", fineGridFace{{SOLVER_NAME}}.getProjection() );
359 // Essentially what we do here is fix the solution on the boundary to be
360 // the inner-side projection.
362 // skip halfway along the projection vector if we are on face 0 or 1
363 int startIndexProjection =
364 marker.getSelectedFaceNumber() < Dimensions ?
365 repositories::{{SOLVER_INSTANCE}}.NodesPerFace * repositories::{{SOLVER_INSTANCE}}.ProjectionsPerFaceNode :
368 auto boundaryMatrix = repositories::{{SOLVER_INSTANCE}}.getBoundaryConditionMatrix();
371 Here we do slightly messy matrix multiplication. We would just multiply the boundary matrix
372 by the projection vector, and place that into the solution, but here we only want to capture
373 half of the projection vector; the other half lies outside the computational domain and
374 should be fixed to 0.
376 for (int row=0; row<boundaryMatrix.rows(); row++)
378 double rowSolution = 0;
379 for (int col=0; col<boundaryMatrix.cols(); col++)
381 rowSolution += boundaryMatrix( row, col ) * fineGridFace{{SOLVER_NAME}}.getProjection( col + startIndexProjection );
383 // place this solution into the face
384 fineGridFace{{SOLVER_NAME}}.setSolution( row, rowSolution );
387 logTraceOut( "updateFaceSolution::InteriorPenalty");
393 templateTouchCellFirstTime=
"""
395 fineGridCell{{SOLVER_NAME}}.getType() != celldata::{{SOLVER_NAME}}::Type::Coarse
399 // now let's finish updating rhs
400 tarch::la::Vector< repositories::{{SOLVER_INSTANCE}}.FaceUnknownsSolution*TwoTimesD, double > faceSol;
401 for (int f=0; f<TwoTimesD; f++)
402 for (int s=0; s<repositories::{{SOLVER_INSTANCE}}.FaceUnknownsSolution; s++)
403 faceSol( f*repositories::{{SOLVER_INSTANCE}}.FaceUnknownsSolution + s ) = fineGridFaces{{SOLVER_NAME}}(f).getSolution(s);
405 // next, we need to project solution on face onto the cell...
406 auto projection = repositories::{{SOLVER_INSTANCE}}.getCellFromFaceMatrix(marker.x(), marker.h()) * faceSol;
408 fineGridCell{{SOLVER_NAME}}.setRhs( fineGridCell{{SOLVER_NAME}}.getRhs( ) + projection );
414 super(InitDofsIntermediatePhaseTest1, self).
__init__(0,
False)
416 self.
d[
"SOLVER_INSTANCE"] = solver.instance_name()
417 self.
d[
"SOLVER_NAME"] = solver.typename()
426 int {full_qualified_classname}::Counter = 0;
430 if operation_name==peano4.solversteps.ActionSet.OPERATION_TOUCH_CELL_FIRST_TIME:
432 if operation_name==peano4.solversteps.ActionSet.OPERATION_TOUCH_FACE_FIRST_TIME:
434 if operation_name==peano4.solversteps.ActionSet.OPERATION_END_TRAVERSAL:
441 Configure name of generated C++ action set
443 This action set will end up in the directory observers with a name that
444 reflects how the observer (initialisation) is mapped onto this action
445 set. The name pattern is ObserverName2ActionSetIdentifier where this
446 routine co-determines the ActionSetIdentifier. We make is reflect the
450 return __name__.replace(
".py",
"").replace(
".",
"_") +
"IntermediateSolve"
460#include "repositories/SolverRepository.h"
461#include "peano4/utils/Loop.h"
467 Inherit from class above and modify one template.
468 The only difference is that here we set the initial guess to 0.
473 super( InitDofsDGTest6, self ).
__init__(solver)
475 templateTouchCellFirstTime =
"""
476 logTraceInWith2Arguments("InitDofs::touchCellFirstTime", marker.toString(), fineGridCell{{SOLVER_NAME}}.toString());
478 auto insertIfNotPresent = []( std::vector<int>& v, int i ) {
479 if( std::find( v.begin(), v.end(), i ) == v.end() ) v.push_back(i);
482 // anonymous functions to calculate cell indices which are on the boundary
483 std::vector<int> indicesOnBoundary;
485 for (int f=0; f<TwoTimesD; f++) {
486 if( fineGridFaces{{SOLVER_NAME}}(f).getType() == facedata::{{SOLVER_NAME}}::Type::Boundary ) {
487 // this face is on the boundary. Gather the cell dof indices this corresponds to
491 for (int i=0; i<repositories::{{SOLVER_INSTANCE}}.PolyDegree+1; i++) insertIfNotPresent( indicesOnBoundary, (repositories::{{SOLVER_INSTANCE}}.PolyDegree + 1)*i );
495 for (int i=0; i<repositories::{{SOLVER_INSTANCE}}.PolyDegree+1; i++) insertIfNotPresent( indicesOnBoundary, i );
499 for (int i=0; i<repositories::{{SOLVER_INSTANCE}}.PolyDegree+1; i++) insertIfNotPresent( indicesOnBoundary, repositories::{{SOLVER_INSTANCE}}.PolyDegree + (repositories::{{SOLVER_INSTANCE}}.PolyDegree + 1)*i );
503 for (int i=(repositories::{{SOLVER_INSTANCE}}.PolyDegree+1)*repositories::{{SOLVER_INSTANCE}}.PolyDegree; i<(repositories::{{SOLVER_INSTANCE}}.PolyDegree+1)*(repositories::{{SOLVER_INSTANCE}}.PolyDegree+1); i++) insertIfNotPresent( indicesOnBoundary, i );
511 auto indexIsOnBoundary = [&indicesOnBoundary](int i) -> bool { return not( indicesOnBoundary.empty() ) and std::find( indicesOnBoundary.begin(), indicesOnBoundary.end(), i ) != indicesOnBoundary.end() ; };
513 celldata::{{SOLVER_NAME}}::Type dofType = repositories::{{SOLVER_INSTANCE}}.getCellDoFType(marker.x(),marker.h());
516 extremely hacky static random number generator
518 static std::mt19937 rng(0); // seed with 0 for reproducibility
519 static std::uniform_real_distribution<> dis(0.0, 1.0);
523 case celldata::{{SOLVER_NAME}}::Type::Outside:
525 if ( marker.willBeRefined() ) // make it coarse
527 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Coarse );
531 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Outside );
536 case celldata::{{SOLVER_NAME}}::Type::Interior:
538 if ( marker.willBeRefined() )
540 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Coarse );
544 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Interior );
546 // create vectors to send to implementation
547 tarch::la::Vector< repositories::{{SOLVER_INSTANCE}}.CellUnknowns, double > solution;
548 tarch::la::Vector< repositories::{{SOLVER_INSTANCE}}.CellUnknowns, double > rhs;
549 tarch::la::Vector< repositories::{{SOLVER_INSTANCE}}.CellUnknowns, double > residual;
550 tarch::la::Vector< repositories::{{SOLVER_INSTANCE}}.CellUnknowns, double > rand;
552 // first - fill the solution vector with randoms
553 for (int i=0; i<repositories::{{SOLVER_INSTANCE}}.CellUnknowns; i++) {
554 if ( indexIsOnBoundary(i) ) {
555 rand[i] = 0.0; // to satisfy the boundary conditions
559 // rand[i] = std::sin( 2*tarch::la::PI * marker.x()(0) ) * std::sin( 2*tarch::la::PI * marker.x()(1) );
562 // and residual to 0...
567 // save the random field
568 fineGridCell{{SOLVER_NAME}}.setRand( rand );
571 rhs = repositories::{{SOLVER_INSTANCE}}.getLocalAssemblyMatrix(marker.x(), marker.h()) * rand;
573 // now we need to compute all projections...
574 auto faceProjections = repositories::{{SOLVER_INSTANCE}}. getFaceFromCellMatrix(marker.x(), marker.h()) * rand;
576 for (int f=0; f<TwoTimesD; f++) {
577 int startIndexProjection =
579 repositories::{{SOLVER_INSTANCE}}.NodesPerFace * repositories::{{SOLVER_INSTANCE}}.ProjectionsPerFaceNode :
581 for (int p=0; p<repositories::{{SOLVER_INSTANCE}}.NodesPerFace * repositories::{{SOLVER_INSTANCE}}.ProjectionsPerFaceNode; p++) {
582 fineGridFaces{{SOLVER_NAME}}(f).setRandProjection(
583 p + startIndexProjection,
584 faceProjections( f*repositories::{{SOLVER_INSTANCE}}.FaceUnknownsProjection + p + startIndexProjection )
591 fineGridCell{{SOLVER_NAME}}.setSolution( solution );
592 fineGridCell{{SOLVER_NAME}}.setRhs( rhs );
593 fineGridCell{{SOLVER_NAME}}.setResidual( residual );
601 logTraceOutWith2Arguments("InitDofs::touchCellFirstTime", marker.toString(), fineGridCell{{SOLVER_NAME}}.toString());
606 Inherit from the class for test1.
608 templateTouchCellFirstTime=
"""
610 fineGridCell{{SOLVER_NAME}}.getType() != celldata::{{SOLVER_NAME}}::Type::Coarse
614 // now let's finish updating rhs
615 tarch::la::Vector< repositories::{{SOLVER_INSTANCE}}.FaceUnknownsSolution*TwoTimesD, double > faceSol;
616 for (int f=0; f<TwoTimesD; f++)
617 for (int s=0; s<repositories::{{SOLVER_INSTANCE}}.FaceUnknownsSolution; s++)
618 faceSol( f*repositories::{{SOLVER_INSTANCE}}.FaceUnknownsSolution + s ) = fineGridFaces{{SOLVER_NAME}}(f).getRandSolution(s);
620 // next, we need to project solution on face onto the cell...
621 auto projection = repositories::{{SOLVER_INSTANCE}}.getCellFromFaceMatrix(marker.x(), marker.h()) * faceSol;
623 fineGridCell{{SOLVER_NAME}}.setRhs( fineGridCell{{SOLVER_NAME}}.getRhs( ) + projection );
627 templateTouchFaceFirstTime=
"""
629 fineGridFace{{SOLVER_NAME}}.getType() == facedata::{{SOLVER_NAME}}::Type::Interior
634 // project the u^\pm into a temporary vector
635 tarch::la::Vector< repositories::{{SOLVER_INSTANCE}}.FaceUnknownsSolution, double > projection =
636 repositories::{{SOLVER_INSTANCE}}.getRiemannMatrix() * fineGridFace{{SOLVER_NAME}}.getRandProjection();
638 for (int i=0; i<repositories::{{SOLVER_INSTANCE}}.FaceUnknownsSolution; i++)
639 fineGridFace{{SOLVER_NAME}}.setRandSolution(
641 repositories::{{SOLVER_INSTANCE}}.OmegaFace * projection(i)
646 fineGridFace{{SOLVER_NAME}}.getType() == facedata::{{SOLVER_NAME}}::Type::Boundary
650 // Essentially what we do here is fix the solution on the boundary to be
651 // the inner-side projection.
653 // skip halfway along the projection vector if we are on face 0 or 1
654 int startIndexProjection =
655 marker.getSelectedFaceNumber() < Dimensions ?
656 repositories::{{SOLVER_INSTANCE}}.NodesPerFace * repositories::{{SOLVER_INSTANCE}}.ProjectionsPerFaceNode :
659 auto boundaryMatrix = repositories::{{SOLVER_INSTANCE}}.getBoundaryConditionMatrix();
662 Here we do slightly messy matrix multiplication. We would just multiply the boundary matrix
663 by the projection vector, and place that into the solution, but here we only want to capture
664 half of the projection vector; the other half lies outside the computational domain and
665 should be fixed to 0.
667 for (int row=0; row<boundaryMatrix.rows(); row++)
669 double rowSolution = 0;
670 for (int col=0; col<boundaryMatrix.cols(); col++)
672 rowSolution += boundaryMatrix( row, col ) * fineGridFace{{SOLVER_NAME}}.getRandProjection( col + startIndexProjection );
674 // place this solution into the face
675 fineGridFace{{SOLVER_NAME}}.setRandSolution( row, rowSolution );
685 super( InitDofsDGTest4, self ).
__init__(solver)
688 templateTouchCellFirstTime=
"""
689 celldata::{{SOLVER_NAME}}::Type dofType = repositories::{{SOLVER_INSTANCE}}.getCellDoFType(marker.x(),marker.h());
692 extremely hacky static random number generator
694 static std::mt19937 rng(1); // seed with 1 for reproducibility. make sure it's different to the numbers we put in the vertices
695 static std::uniform_real_distribution<> dis(0.0, 1.0);
699 case celldata::{{SOLVER_NAME}}::Type::Outside:
701 if ( marker.willBeRefined() ) // make it coarse
703 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Coarse );
707 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Outside );
712 case celldata::{{SOLVER_NAME}}::Type::Interior:
714 if ( marker.willBeRefined() )
716 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Coarse );
720 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Interior );
722 // create vectors to send to implementation
723 tarch::la::Vector< repositories::{{SOLVER_INSTANCE}}.CellUnknowns, double > solution;
724 tarch::la::Vector< repositories::{{SOLVER_INSTANCE}}.CellUnknowns, double > rhs;
725 tarch::la::Vector< repositories::{{SOLVER_INSTANCE}}.CellUnknowns, double > residual;
727 // first - fill the solution vector with randoms
728 for (int i=0; i<repositories::{{SOLVER_INSTANCE}}.CellUnknowns; i++) {
729 solution[i] = dis(rng);
731 // and residual to 0...
736 rhs = repositories::{{SOLVER_INSTANCE}}.getLocalAssemblyMatrix(marker.x(), marker.h()) * solution;
739 fineGridCell{{SOLVER_NAME}}.setSolution( solution );
740 fineGridCell{{SOLVER_NAME}}.setRhs( rhs );
741 fineGridCell{{SOLVER_NAME}}.setResidual( residual );
753 templateTouchCellFirstTime=
"""
754 celldata::{{SOLVER_NAME}}::Type dofType = repositories::{{SOLVER_INSTANCE}}.getCellDoFType(marker.x(),marker.h());
758 case celldata::{{SOLVER_NAME}}::Type::Outside:
760 if ( marker.willBeRefined() ) // make it coarse
762 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Coarse );
766 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Outside );
771 case celldata::{{SOLVER_NAME}}::Type::Interior:
773 if ( marker.willBeRefined() )
775 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Coarse );
779 fineGridCell{{SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Interior );
790 super( InitDofsDGTest5, self ).
__init__(solver)
794 templateTouchCellFirstTime=
"""
795 constexpr int Cols = TwoPowerD * {{CG_SOLVER_NAME}}::VertexUnknowns;
796 constexpr int Rows = {{DG_SOLVER_NAME}}::NodesPerCell * {{DG_SOLVER_NAME}}::UnknownsPerCellNode;
798 static const tarch::la::Matrix< Rows, Cols, double > prolongationMatrix =
800 {{PROLONGATION_MATRIX[0]| join(", ")}}
801 {% for ROW in PROLONGATION_MATRIX[1:] %}
802 ,{{ROW | join(", ")}}
806 celldata::{{DG_SOLVER_NAME}}::Type dofType = repositories::{{DG_SOLVER_INSTANCE}}.getCellDoFType(marker.x(),marker.h());
810 case celldata::{{DG_SOLVER_NAME}}::Type::Outside:
812 if ( marker.willBeRefined() ) // make it coarse
814 fineGridCell{{DG_SOLVER_NAME}}.setType( celldata::{{DG_SOLVER_NAME}}::Type::Coarse );
818 fineGridCell{{DG_SOLVER_NAME}}.setType( celldata::{{DG_SOLVER_NAME}}::Type::Outside );
823 case celldata::{{SOLVER_NAME}}::Type::Interior:
825 if ( marker.willBeRefined() )
827 fineGridCell{{DG_SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Coarse );
831 fineGridCell{{DG_SOLVER_NAME}}.setType( celldata::{{SOLVER_NAME}}::Type::Interior );
833 // also gather the cg values
834 tarch::la::Vector<TwoPowerD, double> u_cg_random;
835 for (int i=0; i<TwoPowerD; i++) u_cg_random(i) = fineGridVertices{{CG_SOLVER_NAME}}(i).getRand(0);
836 auto v_cell = prolongationMatrix * u_cg_random;
838 // next, project v_cell onto each of the faces
839 tarch::la::Vector< TwoTimesD * repositories::{{DG_SOLVER_INSTANCE}}.FaceUnknownsProjection, double > faceProjections = repositories::{{SOLVER_INSTANCE}}. getFaceFromCellMatrix(marker.x(), marker.h()) * v_cell;
840 for (int f=0; f<TwoTimesD; f++) {
841 int startIndexProjection =
843 repositories::{{DG_SOLVER_INSTANCE}}.NodesPerFace * repositories::{{DG_SOLVER_INSTANCE}}.ProjectionsPerFaceNode :
845 for (int p=0; p<repositories::{{DG_SOLVER_INSTANCE}}.NodesPerFace * repositories::{{DG_SOLVER_INSTANCE}}.ProjectionsPerFaceNode; p++) {
846 fineGridFaces{{DG_SOLVER_NAME}}(f).setRandProjections(
847 p + startIndexProjection,
848 faceProjections( f*repositories::{{DG_SOLVER_INSTANCE}}.FaceUnknownsProjection + p + startIndexProjection )
854 // also begin to set rhs
855 fineGridCell{{DG_SOLVER_NAME}}.setRhs(
856 repositories::{{DG_SOLVER_INSTANCE}}.getLocalAssemblyMatrix(marker.x(), marker.h()) * v_cell
859 // set the initial guess to 0
860 fineGridCell{{DG_SOLVER_NAME}}.setSolution(
872 templateTouchFaceLastTime=
"""
873 // perform averaging on the faces
875 fineGridFace{{DG_SOLVER_NAME}}.getType() == facedata::{{DG_SOLVER_NAME}}::Type::Interior
877 // project the u^\pm into a temporary vector
878 tarch::la::Vector< repositories::{{DG_SOLVER_INSTANCE}}.FaceUnknownsSolution, double > projection =
879 repositories::{{DG_SOLVER_INSTANCE}}.getRiemannMatrix() * fineGridFace{{DG_SOLVER_NAME}}.getRandProjections();
881 for (int i=0; i<repositories::{{DG_SOLVER_INSTANCE}}.FaceUnknownsSolution; i++)
882 fineGridFace{{DG_SOLVER_NAME}}.setRandSolutions(
889 fineGridFace{{DG_SOLVER_NAME}}.getType() == facedata::{{DG_SOLVER_NAME}}::Type::Boundary
891 // Essentially what we do here is fix the solution on the boundary to be
892 // the inner-side projection.
894 // skip halfway along the projection vector if we are on face 0 or 1
895 int startIndexProjection =
896 marker.getSelectedFaceNumber() < Dimensions ?
897 repositories::{{DG_SOLVER_INSTANCE}}.NodesPerFace * repositories::{{DG_SOLVER_INSTANCE}}.ProjectionsPerFaceNode :
900 auto boundaryMatrix = repositories::{{DG_SOLVER_INSTANCE}}.getBoundaryConditionMatrix();
903 Here we do slightly messy matrix multiplication. We would just multiply the boundary matrix
904 by the projection vector, and place that into the solution, but here we only want to capture
905 half of the projection vector; the other half lies outside the computational domain and
906 should be fixed to 0.
908 for (int row=0; row<boundaryMatrix.rows(); row++)
910 double rowSolution = 0;
911 for (int col=0; col<boundaryMatrix.cols(); col++)
913 rowSolution += boundaryMatrix( row, col ) * fineGridFace{{DG_SOLVER_NAME}}.getRandProjections( col + startIndexProjection );
915 // place this solution into the face
916 fineGridFace{{DG_SOLVER_NAME}}.setRandSolutions( row, rowSolution );
929 return intergrid_operators.prolongation()
934 super( InitDofsDGTest7, self ).
__init__(dg_solver)
936 self.
dd[
"DG_SOLVER_INSTANCE"] = dg_solver.instance_name()
937 self.
dd[
"DG_SOLVER_NAME"] = dg_solver.typename()
938 self.
dd[
"CG_SOLVER_INSTANCE"] =
"instanceOfCollocatedPoisson"
939 self.
dd[
"CG_SOLVER_NAME"] =
"CollocatedPoisson"
943 if operation_name==peano4.solversteps.ActionSet.OPERATION_TOUCH_FACE_LAST_TIME:
Redoing this class for discontinuous galerkin solver.
str templateTouchFaceFirstTime
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.
str templateTouchVertexFirstTime
str templateTouchCellFirstTime
get_includes(self)
We need the solver repository in this action set, as we directly access the solver object.
user_should_modify_template(self)
The action set that Peano will generate that corresponds to this class should not be modified by user...
Inherit from class above and modify one template.
str templateTouchFaceLastTime
get_prolongation_matrix(self)
get_body_of_operation(self, operation_name)
Return actual C++ code snippets to be inserted into C++ code.
__init__(self, dg_solver)
templateTouchFaceLastTime
Action set (reactions to events)