10 Using this action set isn't strictly necessary. But it's the easiest way
11 to pipe in the prolongation / restriction matrices.
14 - Set the auxiliary cell data by prolongating the aux vertex values
15 - Set the auxiliary vertex data by restricting the aux cell values
18 templateEndTraversal=
"""
22 templateTouchCellFirstTime=
"""
24 fineGridCell{{DG_SOLVER_NAME}}.getType() != celldata::{{DG_SOLVER_NAME}}::Type::Coarse
28 constexpr int Cols = TwoPowerD * {{CG_SOLVER_NAME}}::VertexUnknowns;
29 constexpr int Rows = {{DG_SOLVER_NAME}}::NodesPerCell * {{DG_SOLVER_NAME}}::UnknownsPerCellNode;
31 // gather vertex values to interpolate upwards:
32 tarch::la::Vector< Cols, double > vertexValues;
33 for (int i=0; i<TwoPowerD; i++) vertexValues[i] = fineGridVertices{{CG_SOLVER_NAME}}(i).getU( 0 );
35 static std::vector< tarch::la::Matrix< Rows, Cols, double > > matrices = {
36 {% for MATRIX in PROLONGATION_MATRIX %}
38 {{MATRIX[0]| join(", ")}}
39 {% for ROW in MATRIX[1:] %}
46 {% if PROLONGATION_MATRIX_SCALING is not defined %}
47 #error No scaling for prolongation matrix available.
50 static std::vector<int> scaleFactors = {
51 {% for el in PROLONGATION_MATRIX_SCALING %}
56 static tarch::la::Matrix< Rows, Cols, double > composedProlongationMatrix = ::mghype::composeMatrixFromHWeightedLinearCombination( matrices, scaleFactors, marker.h() );
59 auto newDgVector1 = composedProlongationMatrix * vertexValues;
60 fineGridCell{{DG_SOLVER_NAME}}.setVector1( newDgVector1 );
62 // NEXT - do the same thing for the vertices...
63 // forget about solution injection!!
65 static std::vector< tarch::la::Matrix< TwoPowerD * {{CG_SOLVER_NAME}}::VertexUnknowns, {{DG_SOLVER_NAME}}::NodesPerCell * {{DG_SOLVER_NAME}}::UnknownsPerCellNode, double > > restrictionMatrices = {
66 {% for MATRIX in RESTRICTION_MATRIX %}
68 {{MATRIX[0]| join(", ")}}
69 {% for ROW in MATRIX[1:] %}
76 {% if RESTRICTION_MATRIX_SCALING is not defined %}
77 #error No scaling for injection matrix available.
80 static std::vector<int> restrictionMatricesScaleFactors = {
81 {% for el in INJECTION_MATRIX_SCALING %}
86 static tarch::la::Matrix< TwoPowerD * {{CG_SOLVER_NAME}}::VertexUnknowns, {{DG_SOLVER_NAME}}::NodesPerCell * {{DG_SOLVER_NAME}}::UnknownsPerCellNode, double > composedRestrictionMatrix = ::mghype::composeMatrixFromHWeightedLinearCombination( restrictionMatrices, restrictionMatricesScaleFactors, marker.h() );
88 auto valuesToPutIntoVertex = composedRestrictionMatrix * fineGridCell{{DG_SOLVER_NAME}}.getSolution();
89 for (int v=0; v<TwoPowerD; v++)
90 fineGridVertices{{CG_SOLVER_NAME}}(v).setVector2(
91 0, // assume only one value, so we ask for index 0
92 fineGridVertices{{CG_SOLVER_NAME}}(v).getVector2(0) + valuesToPutIntoVertex(v)
103 prolongation_matrix_scaling,
105 restriction_matrix_scaling,
107 injection_matrix_scaling
110 super( Test4Coupling, self ).
__init__(
115 dg_solver._basic_descend_order = cg_solver._basic_descend_order - 1
118 self.
d[
"DG_SOLVER_INSTANCE"] = dg_solver.instance_name()
119 self.
d[
"DG_SOLVER_NAME"] = dg_solver.typename()
120 self.
d[
"CG_SOLVER_INSTANCE"] = cg_solver.instance_name()
121 self.
d[
"CG_SOLVER_NAME"] = cg_solver.typename()
123 self.
d[
"INJECTION_MATRIX"] = injection_matrix
124 self.
d[
"INJECTION_MATRIX_SCALING"] = injection_matrix_scaling
125 self.
d[
"PROLONGATION_MATRIX"] = prolongation_matrix
126 self.
d[
"PROLONGATION_MATRIX_SCALING"] = prolongation_matrix_scaling
127 self.
d[
"RESTRICTION_MATRIX"] = restriction_matrix
128 self.
d[
"RESTRICTION_MATRIX_SCALING"] = restriction_matrix_scaling
132 if operation_name==peano4.solversteps.ActionSet.OPERATION_TOUCH_CELL_FIRST_TIME:
134 if operation_name==peano4.solversteps.ActionSet.OPERATION_END_TRAVERSAL:
141 Configure name of generated C++ action set
143 This action set will end up in the directory observers with a name that
144 reflects how the observer (initialisation) is mapped onto this action
145 set. The name pattern is ObserverName2ActionSetIdentifier where this
146 routine co-determines the ActionSetIdentifier. We make is reflect the
150 return __name__.replace(
".py",
"").replace(
".",
"_")
155 The action set that Peano will generate that corresponds to this class
156 should not be modified by users and can safely be overwritten every time
157 we run the Python toolkit.
165 We need the solver repository in this action set, as we directly access
166 the solver object. We also need access to Peano's d-dimensional loops.
170#include "repositories/SolverRepository.h"
172#include "peano4/utils/Loop.h"
173#include "mghype/mghype.h"
183 int {full_qualified_classname}::Counter = 0;
189 templateTouchCellFirstTime=
"""
190 constexpr int Cols = TwoPowerD * {{CG_SOLVER_NAME}}::VertexUnknowns;
191 constexpr int Rows = {{DG_SOLVER_NAME}}::NodesPerCell * {{DG_SOLVER_NAME}}::UnknownsPerCellNode;
193 static std::vector< tarch::la::Matrix< Rows, Cols, double > > matrices = {
194 {% for MATRIX in PROLONGATION_MATRIX %}
196 {{MATRIX[0]| join(", ")}}
197 {% for ROW in MATRIX[1:] %}
198 ,{{ROW | join(", ")}}
204 {% if PROLONGATION_MATRIX_SCALING is not defined %}
205 #error No scaling for prolongation matrix available.
208 static std::vector<int> scaleFactors = {
209 {% for el in PROLONGATION_MATRIX_SCALING %}
214 static tarch::la::Matrix< Rows, Cols, double > composedProlongationMatrix = ::mghype::composeMatrixFromHWeightedLinearCombination( matrices, scaleFactors, marker.h() );
216 // restriction matrix
217 static std::vector< tarch::la::Matrix< TwoPowerD * {{CG_SOLVER_NAME}}::VertexUnknowns, {{DG_SOLVER_NAME}}::NodesPerCell * {{DG_SOLVER_NAME}}::UnknownsPerCellNode, double > > restrictionMatrices = {
218 {% for MATRIX in RESTRICTION_MATRIX %}
220 {{MATRIX[0]| join(", ")}}
221 {% for ROW in MATRIX[1:] %}
222 ,{{ROW | join(", ")}}
228 {% if RESTRICTION_MATRIX_SCALING is not defined %}
229 #error No scaling for injection matrix available.
232 static std::vector<int> restrictionMatricesScaleFactors = {
233 {% for el in INJECTION_MATRIX_SCALING %}
238 static tarch::la::Matrix< TwoPowerD * {{CG_SOLVER_NAME}}::VertexUnknowns, {{DG_SOLVER_NAME}}::NodesPerCell * {{DG_SOLVER_NAME}}::UnknownsPerCellNode, double > composedRestrictionMatrix = ::mghype::composeMatrixFromHWeightedLinearCombination( restrictionMatrices, restrictionMatricesScaleFactors, marker.h() );
241 fineGridCell{{DG_SOLVER_NAME}}.getType() != celldata::{{DG_SOLVER_NAME}}::Type::Coarse
245 // fetch the cg stuff
246 tarch::la::Vector<TwoPowerD, double> u_cg_random;
248 for (int i=0; i<TwoPowerD; i++) u_cg_random(i) = fineGridVertices{{CG_SOLVER_NAME}}(i).getRand(0);
250 auto v_cell = composedProlongationMatrix * u_cg_random;
252 fineGridCell{{DG_SOLVER_NAME}}.setVcell(
256 // and now project that onto the faces
257 auto faceProjections = repositories::{{DG_SOLVER_INSTANCE}}.getFaceFromCellMatrix( marker.x(), marker.h() ) * v_cell;
259 for (int f=0; f<TwoTimesD; f++) {
260 int startIndexProjection =
262 repositories::{{DG_SOLVER_INSTANCE}}.NodesPerFace * repositories::{{DG_SOLVER_INSTANCE}}.ProjectionsPerFaceNode :
264 for (int p=0; p<repositories::{{DG_SOLVER_INSTANCE}}.NodesPerFace * repositories::{{DG_SOLVER_INSTANCE}}.ProjectionsPerFaceNode; p++) {
265 fineGridFaces{{DG_SOLVER_NAME}}(f).setProjectionTest(
266 p + startIndexProjection,
267 faceProjections( f*repositories::{{DG_SOLVER_INSTANCE}}.FaceUnknownsProjection + p + startIndexProjection )
276 fineGridCell{{DG_SOLVER_NAME}}.getType() != celldata::{{DG_SOLVER_NAME}}::Type::Coarse
281 tarch::la::Vector< repositories::{{DG_SOLVER_INSTANCE}}.FaceUnknownsSolution*TwoTimesD, double > faceSol;
282 for (int f=0; f<TwoTimesD; f++)
283 for (int s=0; s<repositories::{{DG_SOLVER_INSTANCE}}.FaceUnknownsSolution; s++)
284 faceSol( f*repositories::{{DG_SOLVER_INSTANCE}}.FaceUnknownsSolution + s ) = fineGridFaces{{DG_SOLVER_NAME}}(f).getSolutionTest(s);
286 fineGridCell{{DG_SOLVER_NAME}}.setAdgp(
287 repositories::{{DG_SOLVER_INSTANCE}}.getLocalAssemblyMatrix(marker.x(), marker.h()) * fineGridCell{{DG_SOLVER_NAME}}.getVcell()
289 repositories::{{DG_SOLVER_INSTANCE}}.getCellFromFaceMatrix(marker.x(), marker.h()) * faceSol
292 // now that's done, set v_restrict_ADG
293 auto v_restrict_ADG = composedRestrictionMatrix * fineGridCell{{DG_SOLVER_NAME}}.getAdgp();
295 for (int v=0; v<TwoPowerD; v++)
296 fineGridVertices{{CG_SOLVER_NAME}}(v).setVrestrictADG( fineGridVertices{{CG_SOLVER_NAME}}(v).getVrestrictADG(0) + v_restrict_ADG(v) );
298 // finally, steps 9 and 10
299 auto mdg_p = repositories::{{DG_SOLVER_INSTANCE}}.getMassMatrix(marker.x(), marker.h()) * fineGridCell{{DG_SOLVER_NAME}}.getVcell();
301 fineGridCell{{DG_SOLVER_NAME}}.setMdgp(
305 auto v_restrict_mdg = composedRestrictionMatrix * mdg_p;
306 for (int v=0; v<TwoPowerD; v++)
307 fineGridVertices{{CG_SOLVER_NAME}}(v).setVrestrictMDG( 0, fineGridVertices{{CG_SOLVER_NAME}}(v).getVrestrictMDG(0) + v_restrict_mdg(v) );
312 templateTouchFaceLastTime=
"""
313 // perform averaging on the faces
315 fineGridFace{{DG_SOLVER_NAME}}.getType() == facedata::{{DG_SOLVER_NAME}}::Type::Interior
319 // project the u^\pm into a temporary vector
320 tarch::la::Vector< repositories::{{DG_SOLVER_INSTANCE}}.FaceUnknownsSolution, double > projection =
321 repositories::{{DG_SOLVER_INSTANCE}}.getRiemannMatrix() * fineGridFace{{DG_SOLVER_NAME}}.getProjectionTest();
323 for (int i=0; i<repositories::{{DG_SOLVER_INSTANCE}}.FaceUnknownsSolution; i++)
324 fineGridFace{{DG_SOLVER_NAME}}.setSolutionTest(
331 fineGridFace{{DG_SOLVER_NAME}}.getType() == facedata::{{DG_SOLVER_NAME}}::Type::Boundary
335 // Essentially what we do here is fix the solution on the boundary to be
336 // the inner-side projection.
338 // skip halfway along the projection vector if we are on face 0 or 1
339 int startIndexProjection =
340 marker.getSelectedFaceNumber() < Dimensions ?
341 repositories::{{DG_SOLVER_INSTANCE}}.NodesPerFace * repositories::{{DG_SOLVER_INSTANCE}}.ProjectionsPerFaceNode :
344 auto boundaryMatrix = repositories::{{DG_SOLVER_INSTANCE}}.getBoundaryConditionMatrix();
347 Here we do slightly messy matrix multiplication. We would just multiply the boundary matrix
348 by the projection vector, and place that into the solution, but here we only want to capture
349 half of the projection vector; the other half lies outside the computational domain and
350 should be fixed to 0.
352 for (int row=0; row<boundaryMatrix.rows(); row++)
354 double rowSolution = 0;
355 for (int col=0; col<boundaryMatrix.cols(); col++)
357 rowSolution += boundaryMatrix( row, col ) * fineGridFace{{DG_SOLVER_NAME}}.getProjection( col + startIndexProjection );
359 // place this solution into the face
360 fineGridFace{{DG_SOLVER_NAME}}.setSolutionTest( row, rowSolution );
372 prolongation_matrix_scaling,
374 restriction_matrix_scaling,
376 injection_matrix_scaling
379 super( Test5Coupling, self ).
__init__(
383 prolongation_matrix_scaling,
385 restriction_matrix_scaling,
387 injection_matrix_scaling
389 dg_solver._basic_descend_order = cg_solver._basic_descend_order - 1
392 self.
dd[
"DG_SOLVER_INSTANCE"] = dg_solver.instance_name()
393 self.
dd[
"DG_SOLVER_NAME"] = dg_solver.typename()
394 self.
dd[
"CG_SOLVER_INSTANCE"] = cg_solver.instance_name()
395 self.
dd[
"CG_SOLVER_NAME"] = cg_solver.typename()
397 self.
dd[
"INJECTION_MATRIX"] = injection_matrix
398 self.
dd[
"INJECTION_MATRIX_SCALING"] = injection_matrix_scaling
399 self.
dd[
"PROLONGATION_MATRIX"] = prolongation_matrix
400 self.
dd[
"PROLONGATION_MATRIX_SCALING"] = prolongation_matrix_scaling
401 self.
dd[
"RESTRICTION_MATRIX"] = restriction_matrix
402 self.
dd[
"RESTRICTION_MATRIX_SCALING"] = restriction_matrix_scaling
406 if operation_name==peano4.solversteps.ActionSet.OPERATION_TOUCH_CELL_FIRST_TIME:
408 if operation_name==peano4.solversteps.ActionSet.OPERATION_TOUCH_FACE_LAST_TIME:
410 if operation_name==peano4.solversteps.ActionSet.OPERATION_END_TRAVERSAL:
415class Test7Coupling(mghype.matrixfree.solvers.api.actionsets.MultiplicativeDGCGCoupling):
416 templateTouchCellFirstTime=
"""
420 fineGridCell{{DG_SOLVER_NAME}}.getType() != celldata::{{DG_SOLVER_NAME}}::Type::Coarse
422 // finish updating rhs
423 tarch::la::Vector< repositories::{{DG_SOLVER_INSTANCE}}.CellUnknowns, double > rhs;
426 tarch::la::Vector< repositories::{{DG_SOLVER_INSTANCE}}.FaceUnknownsSolution*TwoTimesD, double > faceSol;
427 for (int f=0; f<TwoTimesD; f++)
428 for (int s=0; s<repositories::{{DG_SOLVER_INSTANCE}}.FaceUnknownsSolution; s++)
429 faceSol( f*repositories::{{DG_SOLVER_INSTANCE}}.FaceUnknownsSolution + s ) = fineGridFaces{{DG_SOLVER_NAME}}(f).getRandSolutions(s);
431 fineGridCell{{DG_SOLVER_NAME}}.setRhs(
432 fineGridCell{{DG_SOLVER_NAME}}.getRhs()
434 repositories::{{DG_SOLVER_INSTANCE}}.getCellFromFaceMatrix(marker.x(), marker.h()) * faceSol
437 """ + mghype.matrixfree.solvers.api.actionsets.MultiplicativeDGCGCoupling.templateTouchCellFirstTime
439 templateEndTraversal =
"""
446 We need the solver repository in this action set, as we directly access
447 the solver object. We also need access to Peano's d-dimensional loops.
451#include "repositories/SolverRepository.h"
453#include "peano4/utils/Loop.h"
454#include "mghype/mghype.h"
455#include "mghype/matrixfree/solvers/DGCGCoupling.h"
460 static int firstCycleCounter;
465int {full_qualified_classname}::firstCycleCounter = 0;
468 if operation_name==peano4.solversteps.ActionSet.OPERATION_END_TRAVERSAL:
Using this action set isn't strictly necessary.
__init__(self, dg_solver, cg_solver, prolongation_matrix, prolongation_matrix_scaling, restriction_matrix, restriction_matrix_scaling, injection_matrix, injection_matrix_scaling)
str templateTouchCellFirstTime
get_includes(self)
We need the solver repository in this action set, as we directly access the solver object.
get_attributes(self)
Return attributes as copied and pasted into the generated class.
get_body_of_operation(self, operation_name)
Return actual C++ code snippets to be inserted into C++ code.
templateTouchCellFirstTime
user_should_modify_template(self)
The action set that Peano will generate that corresponds to this class should not be modified by user...
get_action_set_name(self)
Configure name of generated C++ action set.
get_static_initialisations(self, full_qualified_classname)
get_body_of_operation(self, operation_name)
Return actual C++ code snippets to be inserted into C++ code.
templateTouchFaceLastTime
templateTouchCellFirstTime
__init__(self, dg_solver, cg_solver, prolongation_matrix, prolongation_matrix_scaling, restriction_matrix, restriction_matrix_scaling, injection_matrix, injection_matrix_scaling)
str templateTouchFaceLastTime
str templateTouchCellFirstTime
get_body_of_operation(self, operation_name)
get_static_initialisations(self, full_qualified_classname)
get_includes(self)
We need the solver repository in this action set, as we directly access the solver object.
Action set (reactions to events)