Peano 4
Loading...
Searching...
No Matches
toolbox::blockstructured Namespace Reference

Namespaces

namespace  internal
 
namespace  tests
 

Data Structures

class  GlobalDatabase
 A simple global database. More...
 

Functions

template<typename C >
void interpolateHaloLayer_AoS_tensor_product (const peano4::datamanagement::FaceMarker &marker, int numberOfDoFsPerAxisInPatch, int overlap, int unknowns, const double *__restrict__ coarseGridFaceValues, double *__restrict__ fineGridFaceValues)
 This is a wrapper around the toolbox routines.
 
template<typename C >
void interpolateHaloLayer_AoS_tensor_product (const peano4::datamanagement::FaceMarker &marker, int numberOfDoFsPerAxisInPatch, int overlap, int unknowns, const double *__restrict__ coarseGridCellValues, const double *__restrict__ coarseGridFaceValues, double *__restrict__ fineGridFaceValues)
 
template<typename C >
void interpolateCell_AoS_tensor_product (const peano4::datamanagement::CellMarker &marker, int numberOfDoFsPerAxisInPatch, int unknowns, const double *__restrict__ coarseGridCellValues, double *__restrict__ fineGridCellValues)
 
template<typename C >
void restrictCell_AoS_tensor_product (const peano4::datamanagement::CellMarker &marker, int numberOfDoFsPerAxisInPatch, int unknowns, double *fineGridValues, double *coarseGridValues)
 
template<typename C >
void restrictHaloLayer_AoS_tensor_product (const peano4::datamanagement::FaceMarker &marker, int numberOfDoFsPerAxisInPatch, int overlap, int unknowns, double *fineGridValues, double *coarseGridValues)
 
template<typename C >
void restrictInnerHalfOfHaloLayer_AoS_tensor_product (const peano4::datamanagement::FaceMarker &marker, int numberOfDoFsPerAxisInPatch, int overlap, int unknowns, double *fineGridValues, double *coarseGridValues, bool swapInsideOutside=false)
 
void copyUnknown (int numberOfDoFsPerAxisInPatch, const double *__restrict__ source, int sourceIndex, int sourceUnknowns, int sourceHalo, double *__restrict__ dest, int destIndex, int destUnknowns, int destHalo)
 Copy one unknown from one patch to the other.
 
void copyUnknowns (int numberOfDoFsPerAxisInPatch, const double *__restrict__ source, int sourceHalo, double *__restrict__ dest, int destHalo, int unknowns)
 Copy all unknowns.
 
double copyUnknownAndComputeMaxDifference (int numberOfDoFsPerAxisInPatch, const double *__restrict__ source, int sourceIndex, int sourceUnknowns, int sourceHalo, double *__restrict__ dest, int destIndex, int destUnknowns, int destHalo)
 
void computeGradient (int numberOfDoFsPerAxisInPatch, const double *__restrict__ source, int sourceIndex, int sourceUnknowns, int sourceHalo, double *__restrict__ dest, const tarch::la::Vector< Dimensions, int > &destIndex, int destUnknowns, int destHalo, const tarch::la::Vector< Dimensions, double > &volumeH)
 This routine assumes that we have two patches of the same numberOfDoFsPerAxisInPatch.
 
double computeGradientAndReturnMaxDifference (int numberOfDoFsPerAxisInPatch, const double *__restrict__ source, int sourceIndex, int sourceUnknowns, int sourceHalo, double *__restrict__ dest, const tarch::la::Vector< Dimensions, int > &destIndex, int destUnknowns, int destHalo, const tarch::la::Vector< Dimensions, double > &volumeH)
 
int serialiseVoxelIndexInOverlap (const tarch::la::Vector< Dimensions, int > &overlapCell, int numberOfDoFsPerAxisInPatch, int overlap, int normal)
 The volumes or elements within an overlap are always enumerated lexicographically.
 
int serialisePatchIndexInOverlap (const tarch::la::Vector< Dimensions, int > &patchIndex, int normal)
 Patches along a face are basically organised as \( 3^{d-1} \) arrays, i.e.
 
int serialiseMarkerIn3x3PatchAssembly (const tarch::la::Vector< Dimensions, int > &markerIndex, int numberOfDoFsPerAxisInPatch)
 If you have a marker identifying one element within a 3x3 or 3x3x3, respectively, set of patches, we sometimes have to serialise this marker index.
 
void interpolateHaloLayer_AoS_tensor_product (const peano4::datamanagement::FaceMarker &marker, int numberOfDoFsPerAxisInPatch, int overlap, int unknowns, const double *__restrict__ normalInterpolationMatrix1d, const double *__restrict__ tangentialInterpolationMatrix1d, const double *__restrict__ coarseGridFaceValues, double *__restrict__ fineGridFaceValues)
 Take the coarse grid values and interpolate them onto the fine grid.
 
void interpolateHaloLayer_AoS_tensor_product (const peano4::datamanagement::FaceMarker &marker, int numberOfDoFsPerAxisInPatch, int overlap, int unknowns, const double *__restrict__ normalInterpolationMatrix1d, const double *__restrict__ tangentialInterpolationMatrix1d, const double *__restrict__ coarseGridCellValues, const double *__restrict__ coarseGridFaceValues, double *__restrict__ fineGridFaceValues)
 
void interpolateCell_AoS_tensor_product (const peano4::datamanagement::CellMarker &marker, int numberOfDoFsPerAxisInPatch, int unknowns, const double *__restrict__ interpolationMatrix1d, const double *__restrict__ coarseGridCellValues, double *__restrict__ fineGridCellValues)
 
void interpolateHaloLayer_AoS_piecewise_constant (const peano4::datamanagement::FaceMarker &marker, int numberOfDoFsPerAxisInPatch, int overlap, int unknowns, const double *__restrict__ coarseGridFaceValues, double *__restrict__ fineGridFaceValues)
 Take the coarse grid values and interpolate them onto the fine grid.
 
void interpolateHaloLayer_AoS_piecewise_constant (const peano4::datamanagement::FaceMarker &marker, int numberOfDoFsPerAxisInPatch, int overlap, int unknowns, const double *__restrict__ coarseGridCellValues, const double *__restrict__ coarseGridFaceValues, double *__restrict__ fineGridFaceValues)
 This is the routine for creating a new persistent face.
 
void interpolateCell_AoS_piecewise_constant (const peano4::datamanagement::CellMarker &marker, int numberOfDoFsPerAxisInPatch, int unknowns, const double *__restrict__ coarseGridCellValues, double *__restrict__ fineGridCellValues)
 This routine is called if we create a new cell (dynamic AMR)
 
void interpolateHaloLayer_AoS_linear_with_constant_extrapolation (const peano4::datamanagement::FaceMarker &marker, int numberOfDoFsPerAxisInPatch, int overlap, int unknowns, const double *__restrict__ coarseGridFaceValues, double *__restrict__ fineGridFaceValues)
 
void interpolateHaloLayer_AoS_linear_with_constant_extrapolation (const peano4::datamanagement::FaceMarker &marker, int numberOfDoFsPerAxisInPatch, int overlap, int unknowns, const double *__restrict__ coarseGridCellValues, const double *__restrict__ coarseGridFaceValues, double *__restrict__ fineGridFaceValues)
 
void interpolateCell_AoS_linear_with_constant_extrapolation (const peano4::datamanagement::CellMarker &marker, int numberOfDoFsPerAxisInPatch, int unknowns, const double *__restrict__ coarseGridCellValues, double *__restrict__ fineGridCellValues)
 
void interpolateHaloLayer_AoS_linear_with_linear_extrapolation (const peano4::datamanagement::FaceMarker &marker, int numberOfDoFsPerAxisInPatch, int overlap, int unknowns, const double *__restrict__ coarseGridFaceValues, double *__restrict__ fineGridFaceValues)
 
void interpolateHaloLayer_AoS_linear_with_linear_extrapolation (const peano4::datamanagement::FaceMarker &marker, int numberOfDoFsPerAxisInPatch, int overlap, int unknowns, const double *__restrict__ coarseGridCellValues, const double *__restrict__ coarseGridFaceValues, double *__restrict__ fineGridFaceValues)
 
void interpolateCell_AoS_linear_with_linear_extrapolation (const peano4::datamanagement::CellMarker &marker, int numberOfDoFsPerAxisInPatch, int unknowns, const double *__restrict__ coarseGridCellValues, double *__restrict__ fineGridCellValues)
 
void interpolateHaloLayer_AoS_linear_with_constant_extrapolation_and_linear_normal_interpolation (const peano4::datamanagement::FaceMarker &marker, int numberOfDoFsPerAxisInPatch, int overlap, int unknowns, const double *__restrict__ coarseGridFaceValues, double *__restrict__ fineGridFaceValues)
 
void interpolateHaloLayer_AoS_linear_with_constant_extrapolation_and_linear_normal_interpolation (const peano4::datamanagement::FaceMarker &marker, int numberOfDoFsPerAxisInPatch, int overlap, int unknowns, const double *__restrict__ coarseGridCellValues, const double *__restrict__ coarseGridFaceValues, double *__restrict__ fineGridFaceValues)
 
void interpolateCell_AoS_linear_with_constant_extrapolation_and_linear_normal_interpolation (const peano4::datamanagement::CellMarker &marker, int numberOfDoFsPerAxisInPatch, int unknowns, const double *__restrict__ coarseGridCellValues, double *__restrict__ fineGridCellValues)
 
void interpolateHaloLayer_AoS_linear_with_linear_extrapolation_and_linear_normal_interpolation (const peano4::datamanagement::FaceMarker &marker, int numberOfDoFsPerAxisInPatch, int overlap, int unknowns, const double *__restrict__ coarseGridFaceValues, double *__restrict__ fineGridFaceValues)
 
void interpolateHaloLayer_AoS_linear_with_linear_extrapolation_and_linear_normal_interpolation (const peano4::datamanagement::FaceMarker &marker, int numberOfDoFsPerAxisInPatch, int overlap, int unknowns, const double *__restrict__ coarseGridCellValues, const double *__restrict__ coarseGridFaceValues, double *__restrict__ fineGridFaceValues)
 
void interpolateCell_AoS_linear_with_linear_extrapolation_and_linear_normal_interpolation (const peano4::datamanagement::CellMarker &marker, int numberOfDoFsPerAxisInPatch, int unknowns, const double *__restrict__ coarseGridCellValues, double *__restrict__ fineGridCellValues)
 
void interpolateCellDataAssociatedToVolumesIntoOverlappingCell_linear (int numberOfDoFsPerAxisInSourcePatch, int numberOfDoFsPerAxisInDestinationPatch, int haloSourcePatch, int haloDestinationPatch, int unknowns, const double *__restrict__ sourceValues, double *__restrict__ destinationValues, ::peano4::utils::LoopPlacement parallelisation)
 This interpolation should be used if a cell hosts two sets of unknowns.
 
void interpolateCellDataAssociatedToVolumesIntoOverlappingCell_fourthOrder (int numberOfDoFsPerAxisInSourcePatch, int numberOfDoFsPerAxisInDestinationPatch, int haloSourcePatch, int haloDestinationPatch, int unknowns, const double *__restrict__ sourceValues, double *__restrict__ destinationValues, ::peano4::utils::LoopPlacement parallelisation)
 
void projectPatchSolutionOntoFaces (int numberOfVolumesPerAxisInPatch, int haloSize, int unknowns, int auxiliaryVariables, const double *__restrict__ Q, double *__restrict__ leftFace, double *__restrict__ bottomFace, double *__restrict__ rightFace, double *__restrict__ topFace)
 Project data from patch onto adjacent faces.
 
void projectPatchSolutionOntoFaces (int numberOfVolumesPerAxisInPatch, int haloSize, int unknowns, int auxiliaryVariables, const double *__restrict__ Q, double *__restrict__ leftFace, double *__restrict__ bottomFace, double *__restrict__ frontFace, double *__restrict__ rightFace, double *__restrict__ topFace, double *__restrict__ backFace)
 
void projectPatchSolutionOntoFaces (int numberOfVolumesPerAxisInPatch, int haloSize, int unknowns, int auxiliaryVariables, const double *__restrict__ Q, double *faces[2 *Dimensions])
 
void projectPatchHaloOntoFaces (int numberOfVolumesPerAxisInPatch, int haloSize, int unknowns, int auxiliaryVariables, const double *__restrict__ Q, double *__restrict__ leftFace, double *__restrict__ bottomFace, double *__restrict__ rightFace, double *__restrict__ topFace)
 Take elements from the halo and project them onto the face.
 
void projectPatchHaloOntoFaces (int numberOfVolumesPerAxisInPatch, int haloSize, int unknowns, int auxiliaryVariables, const double *__restrict__ Q, double *__restrict__ leftFace, double *__restrict__ bottomFace, double *__restrict__ frontFace, double *__restrict__ rightFace, double *__restrict__ topFace, double *__restrict__ backFace)
 
void projectPatchHaloOntoFaces (int numberOfVolumesPerAxisInPatch, int haloSize, int unknowns, int auxiliaryVariables, const double *__restrict__ Q, double *faces[2 *Dimensions])
 
void extrapolatePatchSolutionAndProjectExtrapolatedHaloOntoFaces (int numberOfVolumesPerAxisInPatch, int haloSize, int unknowns, int auxiliaryVariables, const double *__restrict__ Q, double *__restrict__ leftFace, double *__restrict__ bottomFace, double *__restrict__ rightFace, double *__restrict__ topFace)
 
void extrapolatePatchSolutionAndProjectExtrapolatedHaloOntoFaces (int numberOfVolumesPerAxisInPatch, int haloSize, int unknowns, int auxiliaryVariables, const double *__restrict__ Q, double *__restrict__ leftFace, double *__restrict__ bottomFace, double *__restrict__ frontFace, double *__restrict__ rightFace, double *__restrict__ topFace, double *__restrict__ backFace)
 
void extrapolatePatchSolutionAndProjectExtrapolatedHaloOntoFaces (int numberOfVolumesPerAxisInPatch, int haloSize, int unknowns, int auxiliaryVariables, const double *__restrict__ Q, double *faces[2 *Dimensions])
 
void clearHaloLayerAoS (const peano4::datamanagement::FaceMarker &marker, int numberOfDoFsPerAxisInPatch, int overlap, int unknowns, double *values)
 Clear halo layer of face.
 
void clearCell (const peano4::datamanagement::CellMarker &marker, int numberOfDoFsPerAxisInPatch, int unknowns, double *values)
 
void restrictInnerHalfOfHaloLayer_AoS_inject (const peano4::datamanagement::FaceMarker &marker, int numberOfDoFsPerAxisInPatch, int overlap, int unknowns, double *fineGridValues, double *coarseGridValues, bool swapInsideOutside=false)
 Restrict data by injection.
 
void restrictHaloLayer_AoS_inject (const peano4::datamanagement::FaceMarker &marker, int numberOfDoFsPerAxisInPatch, int overlap, int unknowns, double *fineGridValues, double *coarseGridValues)
 Restrict data by injection.
 
void restrictCell_AoS_inject (const peano4::datamanagement::CellMarker &marker, int numberOfDoFsPerAxisInPatch, int unknowns, double *fineGridValues, double *coarseGridValues)
 
void restrictCellIntoOverlappingCell_inject (int numberOfDoFsPerAxisInSourcePatch, int numberOfDoFsPerAxisInDestinationPatch, int unknowns, double *sourceValues, double *destinationValues)
 This routine should be used if a cell hosts two sets of unknowns.
 
void restrictCellIntoOverlappingCell_inject_and_average (int numberOfDoFsPerAxisInSourcePatch, int numberOfDoFsPerAxisInDestinationPatch, int unknowns, double *sourceValues, double *destinationValues, double weightOfInjectedValue=0.5)
 Flavour of restrictCellIntoOverlappingCell_inject() where we inject the solution but then take the average between the original value in destinationValues an the injected value.
 
void restrictCell_AoS_averaging (const peano4::datamanagement::CellMarker &marker, int numberOfDoFsPerAxisInPatch, int unknowns, double *fineGridValues, double *coarseGridValues)
 This routine is used when we delete a cell due to dynamic AMR.
 
void restrictHaloLayer_AoS_averaging (const peano4::datamanagement::FaceMarker &marker, int numberOfDoFsPerAxisInPatch, int overlap, int unknowns, double *fineGridValues, double *coarseGridValues)
 Consult commend on interpolation that clarifies why we need two different halo layer restrictions, i.e.
 
void restrictInnerHalfOfHaloLayer_AoS_averaging (const peano4::datamanagement::FaceMarker &marker, int numberOfDoFsPerAxisInPatch, int overlap, int unknowns, double *fineGridValues, double *coarseGridValues, bool swapInsideOutside=false)
 Restrict with averaging.
 
void restrictCell_AoS_tensor_product (const peano4::datamanagement::CellMarker &marker, int numberOfDoFsPerAxisInPatch, int unknowns, const double *__restrict__ tangentialRestrictionMatrix1d, double *fineGridValues, double *coarseGridValues)
 
void restrictHaloLayer_AoS_tensor_product (const peano4::datamanagement::FaceMarker &marker, int numberOfDoFsPerAxisInPatch, int overlap, int unknowns, const double *__restrict__ normalRestrictionMatrix1d, const double *__restrict__ tangentialRestrictionMatrix1d, double *fineGridValues, double *coarseGridValues)
 Restrict whole halo layer.
 
void restrictInnerHalfOfHaloLayer_AoS_tensor_product (const peano4::datamanagement::FaceMarker &marker, int numberOfDoFsPerAxisInPatch, int overlap, int unknowns, const double *__restrict__ normalRestrictionMatrix1d, const double *__restrict__ tangentialRestrictionMatrix1d, double *fineGridValues, double *coarseGridValues, bool swapInsideOutside=false)
 Restrict inner halo half of face data.
 
tarch::tests::TestCasegetUnitTests ()
 Please destroy after usage.
 

Function Documentation

◆ clearCell()

void toolbox::blockstructured::clearCell ( const peano4::datamanagement::CellMarker & marker,
int numberOfDoFsPerAxisInPatch,
int unknowns,
double * values )

Definition at line 297 of file Restriction.cpp.

References values.

◆ clearHaloLayerAoS()

void toolbox::blockstructured::clearHaloLayerAoS ( const peano4::datamanagement::FaceMarker & marker,
int numberOfDoFsPerAxisInPatch,
int overlap,
int unknowns,
double * values )

Clear halo layer of face.

Hand in a face data structure and its marker. From the marker, we know which half of the face data is actual the halo: If we are talking about face 0, i.e. the left face of a cell, then the left half of the volumes within the face are to be clared. If we are getting face 1, which is the one at the bottom, it is the lower layer of volumes within the face data which has to be cleared.

Clearing the halo layer is something that we have to do whenever we create a new face. In theory, we could skip this, as a proper interpolation will eventually set meaningful values, but I found it useful to have non-garbage within the faces.

We also have to clear the layer prior to any restriction, as restrictions typically accumulate a result (while an interpolation just writes the interpolated value to a cell). The reason is as follows: When you interpolate, you have the coarse data and you can interpolate the whole value in one rush. When you restrict, you typically assemble the final restricted value step by step as you run through the finer cells. But there's no point where you have all the fine grid data on the table at the same time. So we have to accumulate. Clearing is something most codes do in touchFaceFirstTime(). Most codes also work with two types of face data: There's a backup of the face data into which they write the current data. This is then used for interpolation, while the actual data is cleared and used to accumulate the restricted values.

Definition at line 269 of file Restriction.cpp.

References assertion, dfore, j, k, and serialiseVoxelIndexInOverlap().

Here is the call graph for this function:

◆ computeGradient()

void toolbox::blockstructured::computeGradient ( int numberOfDoFsPerAxisInPatch,
const double *__restrict__ source,
int sourceIndex,
int sourceUnknowns,
int sourceHalo,
double *__restrict__ dest,
const tarch::la::Vector< Dimensions, int > & destIndex,
int destUnknowns,
int destHalo,
const tarch::la::Vector< Dimensions, double > & volumeH )

This routine assumes that we have two patches of the same numberOfDoFsPerAxisInPatch.

We run over the these patches. Each element therein holds a vector of unknowns, i.e. the whole patch is an AoS. We pick the sourceIndex from each of the numberOfDoFsPerAxisInPatch x numberOfDoFsPerAxisInPatch x numberOfDoFsPerAxisInPatch entries and copy it over to destinationIndex in the image.

I use an upwind/downwind scheme to compute the gradient, i.e. no central differences. Basically, I run over the left half of the patch and look one cell right (for the x-derivative) and then I run over the right half of the patch and look one cell to the left.

Parameters
numberOfDoFsPerAxisInPatchSize per coordinate axis. Has to be added twice the halo layer size if you have a halo

Definition at line 7 of file Derivative.cpp.

References dfor, peano4::utils::dLinearised(), and k.

Here is the call graph for this function:

◆ computeGradientAndReturnMaxDifference()

double toolbox::blockstructured::computeGradientAndReturnMaxDifference ( int numberOfDoFsPerAxisInPatch,
const double *__restrict__ source,
int sourceIndex,
int sourceUnknowns,
int sourceHalo,
double *__restrict__ dest,
const tarch::la::Vector< Dimensions, int > & destIndex,
int destUnknowns,
int destHalo,
const tarch::la::Vector< Dimensions, double > & volumeH )

Definition at line 44 of file Derivative.cpp.

References dfor, peano4::utils::dLinearised(), and k.

Here is the call graph for this function:

◆ copyUnknown()

void toolbox::blockstructured::copyUnknown ( int numberOfDoFsPerAxisInPatch,
const double *__restrict__ source,
int sourceIndex,
int sourceUnknowns,
int sourceHalo,
double *__restrict__ dest,
int destIndex,
int destUnknowns,
int destHalo )

Copy one unknown from one patch to the other.

This routine assumes that we have two patches of the same numberOfDoFsPerAxisInPatch. We run over the these patches. Each element therein holds a vector of unknowns, i.e. the whole patch is an AoS. We pick the sourceIndex from each of the numberOfDoFsPerAxisInPatch x numberOfDoFsPerAxisInPatch x numberOfDoFsPerAxisInPatch entries and copy it over to destinationIndex in the image. That is, the two patches have to have the same number of unknowns, but they might have different unknowns.

Parameters
numberOfDoFsPerAxisInPatchSize per coordinate axis. Has to be added twice the halo layer size if you have a halo
sourcePointer to the source data. This is the whole input patch stored as AoS. It has the dimensions \( (numberOfDoFsPerAxisInPatch+2*sourceHalo)^Dimensions \cdot sourceUnknowns \).
sourceIndexWhich index in source is to be copied over to the destination field. Has to be greater equals to zero and has to be smaller than sourceUnknowns.

Definition at line 39 of file Copy.cpp.

References assertion5.

◆ copyUnknownAndComputeMaxDifference()

double toolbox::blockstructured::copyUnknownAndComputeMaxDifference ( int numberOfDoFsPerAxisInPatch,
const double *__restrict__ source,
int sourceIndex,
int sourceUnknowns,
int sourceHalo,
double *__restrict__ dest,
int destIndex,
int destUnknowns,
int destHalo )

Definition at line 73 of file Copy.cpp.

References assertion5.

◆ copyUnknowns()

void toolbox::blockstructured::copyUnknowns ( int numberOfDoFsPerAxisInPatch,
const double *__restrict__ source,
int sourceHalo,
double *__restrict__ dest,
int destHalo,
int unknowns )

Copy all unknowns.

Definition at line 8 of file Copy.cpp.

◆ extrapolatePatchSolutionAndProjectExtrapolatedHaloOntoFaces() [1/3]

void toolbox::blockstructured::extrapolatePatchSolutionAndProjectExtrapolatedHaloOntoFaces ( int numberOfVolumesPerAxisInPatch,
int haloSize,
int unknowns,
int auxiliaryVariables,
const double *__restrict__ Q,
double *__restrict__ leftFace,
double *__restrict__ bottomFace,
double *__restrict__ frontFace,
double *__restrict__ rightFace,
double *__restrict__ topFace,
double *__restrict__ backFace )

Definition at line 220 of file Projection.cpp.

References assertionEquals, and extrapolatePatchSolutionAndProjectExtrapolatedHaloOntoFaces().

Here is the call graph for this function:

◆ extrapolatePatchSolutionAndProjectExtrapolatedHaloOntoFaces() [2/3]

void toolbox::blockstructured::extrapolatePatchSolutionAndProjectExtrapolatedHaloOntoFaces ( int numberOfVolumesPerAxisInPatch,
int haloSize,
int unknowns,
int auxiliaryVariables,
const double *__restrict__ Q,
double *__restrict__ leftFace,
double *__restrict__ bottomFace,
double *__restrict__ rightFace,
double *__restrict__ topFace )

Definition at line 196 of file Projection.cpp.

References assertionEquals, and extrapolatePatchSolutionAndProjectExtrapolatedHaloOntoFaces().

Referenced by extrapolatePatchSolutionAndProjectExtrapolatedHaloOntoFaces(), and extrapolatePatchSolutionAndProjectExtrapolatedHaloOntoFaces().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ extrapolatePatchSolutionAndProjectExtrapolatedHaloOntoFaces() [3/3]

void toolbox::blockstructured::extrapolatePatchSolutionAndProjectExtrapolatedHaloOntoFaces ( int numberOfVolumesPerAxisInPatch,
int haloSize,
int unknowns,
int auxiliaryVariables,
const double *__restrict__ Q,
double * faces[2 *Dimensions] )

d-loop over all dimensions except d. The vector k's entry d is set to 0. We start with the left/bottom face, i.e. the one closer to the coordinate system's origin.

Definition at line 246 of file Projection.cpp.

References assertion, dfore, peano4::utils::dLinearised(), j, k, and serialiseVoxelIndexInOverlap().

Here is the call graph for this function:

◆ getUnitTests()

tarch::tests::TestCase * toolbox::blockstructured::getUnitTests ( )

Please destroy after usage.

Definition at line 11 of file UnitTests.cpp.

References tarch::tests::TreeTestCaseCollection::addTestCase().

Referenced by main(), and runTests().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ interpolateCell_AoS_linear_with_constant_extrapolation()

void toolbox::blockstructured::interpolateCell_AoS_linear_with_constant_extrapolation ( const peano4::datamanagement::CellMarker & marker,
int numberOfDoFsPerAxisInPatch,
int unknowns,
const double *__restrict__ coarseGridCellValues,
double *__restrict__ fineGridCellValues )

Definition at line 539 of file Interpolation.cpp.

References logTraceInWith3Arguments, and logTraceOut.

◆ interpolateCell_AoS_linear_with_constant_extrapolation_and_linear_normal_interpolation()

void toolbox::blockstructured::interpolateCell_AoS_linear_with_constant_extrapolation_and_linear_normal_interpolation ( const peano4::datamanagement::CellMarker & marker,
int numberOfDoFsPerAxisInPatch,
int unknowns,
const double *__restrict__ coarseGridCellValues,
double *__restrict__ fineGridCellValues )

Definition at line 803 of file Interpolation.cpp.

References logTraceInWith3Arguments, and logTraceOut.

◆ interpolateCell_AoS_linear_with_linear_extrapolation()

void toolbox::blockstructured::interpolateCell_AoS_linear_with_linear_extrapolation ( const peano4::datamanagement::CellMarker & marker,
int numberOfDoFsPerAxisInPatch,
int unknowns,
const double *__restrict__ coarseGridCellValues,
double *__restrict__ fineGridCellValues )

Definition at line 671 of file Interpolation.cpp.

References logTraceInWith3Arguments, and logTraceOut.

◆ interpolateCell_AoS_linear_with_linear_extrapolation_and_linear_normal_interpolation()

void toolbox::blockstructured::interpolateCell_AoS_linear_with_linear_extrapolation_and_linear_normal_interpolation ( const peano4::datamanagement::CellMarker & marker,
int numberOfDoFsPerAxisInPatch,
int unknowns,
const double *__restrict__ coarseGridCellValues,
double *__restrict__ fineGridCellValues )

Definition at line 1026 of file Interpolation.cpp.

References logTraceInWith3Arguments, and logTraceOut.

◆ interpolateCell_AoS_piecewise_constant()

void toolbox::blockstructured::interpolateCell_AoS_piecewise_constant ( const peano4::datamanagement::CellMarker & marker,
int numberOfDoFsPerAxisInPatch,
int unknowns,
const double *__restrict__ coarseGridCellValues,
double *__restrict__ fineGridCellValues )

This routine is called if we create a new cell (dynamic AMR)

The routine looks up if the interpolation matrix does exist already. If not, it creates it. Afterwards, it takes the interpolation matrix and multiplies it with the coarse matrix. Interpolation matrices are band matrices and hold all entries for all \( 3^d \) subpatches. We only need one subpatch, so we pick a subsegment of the matrix. In return, we use the same interpolation scheme for all unknowns, so we can rely on a batched matrix multiplication.

Definition at line 371 of file Interpolation.cpp.

References logTraceInWith3Arguments, and logTraceOut.

◆ interpolateCell_AoS_tensor_product() [1/2]

template<typename C >
void toolbox::blockstructured::interpolateCell_AoS_tensor_product ( const peano4::datamanagement::CellMarker & marker,
int numberOfDoFsPerAxisInPatch,
int unknowns,
const double *__restrict__ coarseGridCellValues,
double *__restrict__ fineGridCellValues )

Definition at line 66 of file InterpolationRestriction.h.

References interpolateCell_AoS_tensor_product().

Referenced by interpolateCell_AoS_tensor_product().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ interpolateCell_AoS_tensor_product() [2/2]

void toolbox::blockstructured::interpolateCell_AoS_tensor_product ( const peano4::datamanagement::CellMarker & marker,
int numberOfDoFsPerAxisInPatch,
int unknowns,
const double *__restrict__ interpolationMatrix1d,
const double *__restrict__ coarseGridCellValues,
double *__restrict__ fineGridCellValues )

Definition at line 1170 of file Interpolation.cpp.

References assertion.

◆ interpolateCellDataAssociatedToVolumesIntoOverlappingCell_fourthOrder()

void toolbox::blockstructured::interpolateCellDataAssociatedToVolumesIntoOverlappingCell_fourthOrder ( int numberOfDoFsPerAxisInSourcePatch,
int numberOfDoFsPerAxisInDestinationPatch,
int haloSourcePatch,
int haloDestinationPatch,
int unknowns,
const double *__restrict__ sourceValues,
double *__restrict__ destinationValues,
::peano4::utils::LoopPlacement parallelisation )

Definition at line 1004 of file Interpolation.cpp.

References assertion, peano4::utils::dLinearised(), and endSimtDfor.

Here is the call graph for this function:

◆ interpolateCellDataAssociatedToVolumesIntoOverlappingCell_linear()

void toolbox::blockstructured::interpolateCellDataAssociatedToVolumesIntoOverlappingCell_linear ( int numberOfDoFsPerAxisInSourcePatch,
int numberOfDoFsPerAxisInDestinationPatch,
int haloSourcePatch,
int haloDestinationPatch,
int unknowns,
const double *__restrict__ sourceValues,
double *__restrict__ destinationValues,
::peano4::utils::LoopPlacement parallelisation )

This interpolation should be used if a cell hosts two sets of unknowns.

Frequently used if your code hosts two PDE solvers. In principle, it is up to the user to decide if they want to interpolate from pure cell data or use a reconstructed patch, i.e. cell data plus halo. However, if the finer cell has more degrees of freedom than the source, then any interpolation without halo data will yield wrong results close to the boundary of the patch.

Here's some ASCII art to illustrate this:

|------|------|------|------|------|------|
|--|--|--|--|--|--|--|--|--|--|--|--|--|--|

Inside the domain, all interpolation is straightforward. However, we do not have valid data for the very left and very right volume on the fine grid. Such data are only available once we know the halo data, too.

Data validity

There is one important catch when you interpolate linearly from a coarse patch into a fine one: In ExaHyPE 2, we typically only have face-connected data. Therefore, those coarse grid entries along the patch diagonals are invalid, and we have to ignore them. Simply leaving them away however is not an option, as we then would accumulate partial contributions which do not sum up to 1.0.

Optimisation

This routine can be quite time consuming, which is annoying if it is used for volumetric coupling. ExaHyPE's limiting is such a process. I therefore tried to optimise the routine in various ways:

  • The dfor loops in general cannot be vectorised. So I replaced the inner one with nested loops - hoping that this would allow the compiler to vectorise. However, it does not do so. This is likely due to the fact that there is an accumulation in there.
  • Intel's vectorisation reports claim that the loop manipulating outsidePatchAlongCoordinateAxis is not worth vectorising. I tried the variant where I comment out some lines. This does not work. It still claims it were not worth it.
  • I replaced the destination dfor loop with nested normal for loops and added a collapse and parallel statement (for OpenMP). This parallelisation is valid, as we split up the destination index and hence do not introduce any race conditions when we accumulate the destination value. However, I have to use an OpenMP taskloop to parallelise the code, as this routine is usually used within tasks, i.e. a parallel for would be tied to the single core that's given to the task.
Parameters
haloSourcePatch
haloDestinationPatchNote that we only interpolate into the interior of the patch correctly.

Definition at line 936 of file Interpolation.cpp.

References assertion, dfor, peano4::utils::dLinearised(), endSimtDfor, tarch::la::greaterEquals(), h, tarch::la::multiplyComponents(), and tarch::la::smallerEquals().

Referenced by toolbox::blockstructured::tests::InterpolationTest::testInterpolateCellDataAssociatedToVolumesIntoOverlappingCell_linear().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ interpolateHaloLayer_AoS_linear_with_constant_extrapolation() [1/2]

void toolbox::blockstructured::interpolateHaloLayer_AoS_linear_with_constant_extrapolation ( const peano4::datamanagement::FaceMarker & marker,
int numberOfDoFsPerAxisInPatch,
int overlap,
int unknowns,
const double *__restrict__ coarseGridCellValues,
const double *__restrict__ coarseGridFaceValues,
double *__restrict__ fineGridFaceValues )

Definition at line 474 of file Interpolation.cpp.

References tarch::freeMemory(), tarch::Heap, interpolateHaloLayer_AoS_linear_with_constant_extrapolation(), logTraceInWith4Arguments, and logTraceOut.

Here is the call graph for this function:

◆ interpolateHaloLayer_AoS_linear_with_constant_extrapolation() [2/2]

void toolbox::blockstructured::interpolateHaloLayer_AoS_linear_with_constant_extrapolation ( const peano4::datamanagement::FaceMarker & marker,
int numberOfDoFsPerAxisInPatch,
int overlap,
int unknowns,
const double *__restrict__ coarseGridFaceValues,
double *__restrict__ fineGridFaceValues )

Definition at line 428 of file Interpolation.cpp.

References assertionEquals, tarch::multicore::Lock::free(), logDebug, logTraceInWith4Arguments, logTraceOut, and serialisePatchIndexInOverlap().

Referenced by interpolateHaloLayer_AoS_linear_with_constant_extrapolation().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ interpolateHaloLayer_AoS_linear_with_constant_extrapolation_and_linear_normal_interpolation() [1/2]

void toolbox::blockstructured::interpolateHaloLayer_AoS_linear_with_constant_extrapolation_and_linear_normal_interpolation ( const peano4::datamanagement::FaceMarker & marker,
int numberOfDoFsPerAxisInPatch,
int overlap,
int unknowns,
const double *__restrict__ coarseGridCellValues,
const double *__restrict__ coarseGridFaceValues,
double *__restrict__ fineGridFaceValues )

◆ interpolateHaloLayer_AoS_linear_with_constant_extrapolation_and_linear_normal_interpolation() [2/2]

void toolbox::blockstructured::interpolateHaloLayer_AoS_linear_with_constant_extrapolation_and_linear_normal_interpolation ( const peano4::datamanagement::FaceMarker & marker,
int numberOfDoFsPerAxisInPatch,
int overlap,
int unknowns,
const double *__restrict__ coarseGridFaceValues,
double *__restrict__ fineGridFaceValues )
See also
createLinearInterpolationMatrix()

Definition at line 692 of file Interpolation.cpp.

References assertionEquals, tarch::multicore::Lock::free(), logDebug, logTraceInWith4Arguments, logTraceOut, and serialisePatchIndexInOverlap().

Referenced by interpolateHaloLayer_AoS_linear_with_constant_extrapolation_and_linear_normal_interpolation().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ interpolateHaloLayer_AoS_linear_with_linear_extrapolation() [1/2]

void toolbox::blockstructured::interpolateHaloLayer_AoS_linear_with_linear_extrapolation ( const peano4::datamanagement::FaceMarker & marker,
int numberOfDoFsPerAxisInPatch,
int overlap,
int unknowns,
const double *__restrict__ coarseGridCellValues,
const double *__restrict__ coarseGridFaceValues,
double *__restrict__ fineGridFaceValues )

Definition at line 606 of file Interpolation.cpp.

References tarch::freeMemory(), tarch::Heap, interpolateHaloLayer_AoS_linear_with_linear_extrapolation(), logTraceInWith4Arguments, and logTraceOut.

Here is the call graph for this function:

◆ interpolateHaloLayer_AoS_linear_with_linear_extrapolation() [2/2]

void toolbox::blockstructured::interpolateHaloLayer_AoS_linear_with_linear_extrapolation ( const peano4::datamanagement::FaceMarker & marker,
int numberOfDoFsPerAxisInPatch,
int overlap,
int unknowns,
const double *__restrict__ coarseGridFaceValues,
double *__restrict__ fineGridFaceValues )

Definition at line 560 of file Interpolation.cpp.

References assertionEquals, tarch::multicore::Lock::free(), logDebug, logTraceInWith4Arguments, logTraceOut, and serialisePatchIndexInOverlap().

Referenced by interpolateHaloLayer_AoS_linear_with_linear_extrapolation().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ interpolateHaloLayer_AoS_linear_with_linear_extrapolation_and_linear_normal_interpolation() [1/2]

void toolbox::blockstructured::interpolateHaloLayer_AoS_linear_with_linear_extrapolation_and_linear_normal_interpolation ( const peano4::datamanagement::FaceMarker & marker,
int numberOfDoFsPerAxisInPatch,
int overlap,
int unknowns,
const double *__restrict__ coarseGridCellValues,
const double *__restrict__ coarseGridFaceValues,
double *__restrict__ fineGridFaceValues )

◆ interpolateHaloLayer_AoS_linear_with_linear_extrapolation_and_linear_normal_interpolation() [2/2]

void toolbox::blockstructured::interpolateHaloLayer_AoS_linear_with_linear_extrapolation_and_linear_normal_interpolation ( const peano4::datamanagement::FaceMarker & marker,
int numberOfDoFsPerAxisInPatch,
int overlap,
int unknowns,
const double *__restrict__ coarseGridFaceValues,
double *__restrict__ fineGridFaceValues )

Definition at line 824 of file Interpolation.cpp.

References assertionEquals, tarch::multicore::Lock::free(), logDebug, logTraceInWith4Arguments, logTraceOut, and serialisePatchIndexInOverlap().

Referenced by interpolateHaloLayer_AoS_linear_with_linear_extrapolation_and_linear_normal_interpolation().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ interpolateHaloLayer_AoS_piecewise_constant() [1/2]

void toolbox::blockstructured::interpolateHaloLayer_AoS_piecewise_constant ( const peano4::datamanagement::FaceMarker & marker,
int numberOfDoFsPerAxisInPatch,
int overlap,
int unknowns,
const double *__restrict__ coarseGridCellValues,
const double *__restrict__ coarseGridFaceValues,
double *__restrict__ fineGridFaceValues )

This is the routine for creating a new persistent face.

Normal hanging faces are always created along the boundary of a 3x3 or 3x3x3 patch, respectively. Therefore, we always take the coarse grid face data to initialise the face values. These face data hold the overlaps, so we can interpolate accordingly. Therefore, if marker.isInteriorFaceWithinPatch() does not hold, we can use the alternative interpolateHaloLayer() variant.

If we create persistent faces within a 3x3x3 patch arrangement, we first create the interpolation of the left and right patch of the face of interest.

Definition at line 308 of file Interpolation.cpp.

References tarch::freeMemory(), tarch::Heap, interpolateHaloLayer_AoS_piecewise_constant(), logTraceInWith4Arguments, and logTraceOut.

Here is the call graph for this function:

◆ interpolateHaloLayer_AoS_piecewise_constant() [2/2]

void toolbox::blockstructured::interpolateHaloLayer_AoS_piecewise_constant ( const peano4::datamanagement::FaceMarker & marker,
int numberOfDoFsPerAxisInPatch,
int overlap,
int unknowns,
const double *__restrict__ coarseGridFaceValues,
double *__restrict__ fineGridFaceValues )

Take the coarse grid values and interpolate them onto the fine grid.

Definition at line 264 of file Interpolation.cpp.

References tarch::multicore::Lock::free(), logDebug, logTraceInWith4Arguments, logTraceOut, and serialisePatchIndexInOverlap().

Referenced by interpolateHaloLayer_AoS_piecewise_constant().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ interpolateHaloLayer_AoS_tensor_product() [1/4]

template<typename C >
void toolbox::blockstructured::interpolateHaloLayer_AoS_tensor_product ( const peano4::datamanagement::FaceMarker & marker,
int numberOfDoFsPerAxisInPatch,
int overlap,
int unknowns,
const double *__restrict__ coarseGridCellValues,
const double *__restrict__ coarseGridFaceValues,
double *__restrict__ fineGridFaceValues )

Definition at line 42 of file InterpolationRestriction.h.

References interpolateHaloLayer_AoS_tensor_product().

Here is the call graph for this function:

◆ interpolateHaloLayer_AoS_tensor_product() [2/4]

template<typename C >
void toolbox::blockstructured::interpolateHaloLayer_AoS_tensor_product ( const peano4::datamanagement::FaceMarker & marker,
int numberOfDoFsPerAxisInPatch,
int overlap,
int unknowns,
const double *__restrict__ coarseGridFaceValues,
double *__restrict__ fineGridFaceValues )

This is a wrapper around the toolbox routines.

It ensures that we have a templated function which has the same signature as the other routines in blockstructured and thus can be swapped in and out. See the documentation in exahype2.solvers.FV for example how to use it within Python.

Definition at line 20 of file InterpolationRestriction.h.

References interpolateHaloLayer_AoS_tensor_product().

Referenced by interpolateHaloLayer_AoS_tensor_product(), interpolateHaloLayer_AoS_tensor_product(), exahype2::fv::tests::InterpolationRestrictionTest::testPiecewiseConstantInterpolationWithTensorProduct1(), and exahype2::fv::tests::InterpolationRestrictionTest::testPiecewiseConstantInterpolationWithTensorProduct2().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ interpolateHaloLayer_AoS_tensor_product() [3/4]

void toolbox::blockstructured::interpolateHaloLayer_AoS_tensor_product ( const peano4::datamanagement::FaceMarker & marker,
int numberOfDoFsPerAxisInPatch,
int overlap,
int unknowns,
const double *__restrict__ normalInterpolationMatrix1d,
const double *__restrict__ tangentialInterpolationMatrix1d,
const double *__restrict__ coarseGridCellValues,
const double *__restrict__ coarseGridFaceValues,
double *__restrict__ fineGridFaceValues )

Definition at line 1156 of file Interpolation.cpp.

References assertion.

◆ interpolateHaloLayer_AoS_tensor_product() [4/4]

void toolbox::blockstructured::interpolateHaloLayer_AoS_tensor_product ( const peano4::datamanagement::FaceMarker & marker,
int numberOfDoFsPerAxisInPatch,
int overlap,
int unknowns,
const double *__restrict__ normalInterpolationMatrix1d,
const double *__restrict__ tangentialInterpolationMatrix1d,
const double *__restrict__ coarseGridFaceValues,
double *__restrict__ fineGridFaceValues )

Take the coarse grid values and interpolate them onto the fine grid.

This routine expects two matrices. Both phrase 1d interpolation rules, but one of them formalises the interpolation along the face normal and one the interpolation along the tangential directions.

The normal interpolation is a matrix of size overlap x 2*overlap. If I have an overlap of 1, then I have to befill one halo layer around a resolution transition.

Interpolation along the normal direction

The interpolation along the normal is a matrix of the dimensions \( 2k \times k \). It is always defined along the left-to-right, i.e. what happens if we have a face where the grid right of it is refined and the grid left of it is unrefined. In this case, we have two faces (one for the coarse level and one for the finer level).

The image above illustrates this for k=2. In this case, the coarse face holds four entries (along the normal): The green ones to the left are real coarse grid data stemming from the adjacent block, while the blue ones are overlapping with the fine mesh and therefore likely restricted data. For AMR, we have to set (interpolate) the halo on the fine level, i.e. the red values. We do not have to interpolate the orange values, as these guys hold proper fine grid data. So that leaves us with two entries on the fine mesh, which can be initialised using the four entries on the coarser mesh. Overall, the interpolation can be written down as 2x4 matrix.

The illustration arrows above show the data flow for the left halo entry. This one can be befilled by four entries on the coarser resolution, though only two of them are real entries and the other ones are restricted onvalues. So you can either have the corresponding restricted value entry in normalInterpolationMatrix1d as 0 - in this case you only couple from real coarse data to fine data - or you can have a value in there which means you interpolate over the resolution transition between real and restricted data.

Tangential interpolation matrix

The normalInterpolationMatrix1d has the size 3 * numberOfDoFsPerAxisInPatch x numberOfDoFsPerAxisInPatch. So we have three matrix. Each of them phrases how an element of one of the three fine grid segments is affected by the numberOfDoFsPerAxisInPatch counterparts on the coarser level.

Example matrices

Piece-wise interpolation

The interpolation matrix below realises a piece-wise constant interpolation along the normal for an overlap of three. It takes the coarse grid value of the voluem that's one away from the AMR boundary and interpolates it to the fine mesh:

    static constexpr double  NormalInterpolationMatrix1d[]     = {
       0.0, 1.0, 0.0, 0.0, 0.0, 0.0,
       0.0, 1.0, 0.0, 0.0, 0.0, 0.0,
       0.0, 1.0, 0.0, 0.0, 0.0, 0.0
    };

The data flow is illustrated below:

Most constant interplation schemes would obviously not take the middle green value but the one right of it. In the matrix, this means that third column would be 1 and not the second one.

If you also want to interpolate piece-wise constant along the tangential directions, and if you have a patch size of 5, you would pass in the following tangential interpolation matrix:

  static constexpr double  TangentialInterpolationMatrix1d[] = {
    1.0,0.0,0.0,0.0,0.0,
    1.0,0.0,0.0,0.0,0.0,
    1.0,0.0,0.0,0.0,0.0,
    0.0,1.0,0.0,0.0,0.0,
    0.0,1.0,0.0,0.0,0.0,

    0.0,1.0,0.0,0.0,0.0,
    0.0,0.0,1.0,0.0,0.0,
    0.0,0.0,1.0,0.0,0.0,
    0.0,0.0,1.0,0.0,0.0,
    0.0,0.0,0.0,1.0,0.0,

    0.0,0.0,0.0,1.0,0.0,
    0.0,0.0,0.0,1.0,0.0,
    0.0,0.0,0.0,0.0,1.0,
    0.0,0.0,0.0,0.0,1.0,
    0.0,0.0,0.0,0.0,1.0
  };

This operator is self-explaining: With a patch size of 5, we have five coarse grid values along a tangent which are to projected onto 3x5 fine grid values, as we always split into three. The operators are always read along the coordinate axes. The left fine grid value has to equal the left-most coarse grid value. This is the 1 in the first row of the matrix. The second entry on the fine grid also holds this value. This is the second line.

Definition at line 1080 of file Interpolation.cpp.

References assertion, assertion4, dfore, logDebug, logTraceInWith3Arguments, logTraceOut, and serialiseVoxelIndexInOverlap().

Here is the call graph for this function:

◆ projectPatchHaloOntoFaces() [1/3]

void toolbox::blockstructured::projectPatchHaloOntoFaces ( int numberOfVolumesPerAxisInPatch,
int haloSize,
int unknowns,
int auxiliaryVariables,
const double *__restrict__ Q,
double *__restrict__ leftFace,
double *__restrict__ bottomFace,
double *__restrict__ frontFace,
double *__restrict__ rightFace,
double *__restrict__ topFace,
double *__restrict__ backFace )

Definition at line 126 of file Projection.cpp.

References assertionEquals, and projectPatchHaloOntoFaces().

Here is the call graph for this function:

◆ projectPatchHaloOntoFaces() [2/3]

void toolbox::blockstructured::projectPatchHaloOntoFaces ( int numberOfVolumesPerAxisInPatch,
int haloSize,
int unknowns,
int auxiliaryVariables,
const double *__restrict__ Q,
double *__restrict__ leftFace,
double *__restrict__ bottomFace,
double *__restrict__ rightFace,
double *__restrict__ topFace )

Take elements from the halo and project them onto the face.

This routine is the cousin of projectPatchSolutionOntoFaces() but assumes that Q does not point to the patch only but to the patch including a halo of size haloSize. It now takes this halo and projects it onto the face.

When projectPatchSolutionOntoFaces() maps its data onto the face, it writes these data copies onto the interior parts of the face. In ASCII art, this resembles

| a | b | c | d |
| x | y |

The patch with four entries (a,b,c,d) takes its leftmost entry a and writes it into y on the left face. This example is for a halo size of

  1. This is projectPatchSolutionOntoFaces().

The present routine assumes that we have the patch plus its halo and therefore does

| h | a | b | c | d | i |
| x | y |

project the halo entry (h) onto the face at point x.

Parameters
QPatch data with halo, i.e.

Definition at line 102 of file Projection.cpp.

References assertionEquals, and projectPatchHaloOntoFaces().

Referenced by projectPatchHaloOntoFaces(), and projectPatchHaloOntoFaces().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ projectPatchHaloOntoFaces() [3/3]

void toolbox::blockstructured::projectPatchHaloOntoFaces ( int numberOfVolumesPerAxisInPatch,
int haloSize,
int unknowns,
int auxiliaryVariables,
const double *__restrict__ Q,
double * faces[2 *Dimensions] )

d-loop over all dimensions except d. The vector k's entry d is set to 0. We start with the left/bottom face, i.e. the one closer to the coordinate system's origin.

Definition at line 152 of file Projection.cpp.

References dfore, peano4::utils::dLinearised(), j, k, and serialiseVoxelIndexInOverlap().

Here is the call graph for this function:

◆ projectPatchSolutionOntoFaces() [1/3]

void toolbox::blockstructured::projectPatchSolutionOntoFaces ( int numberOfVolumesPerAxisInPatch,
int haloSize,
int unknowns,
int auxiliaryVariables,
const double *__restrict__ Q,
double *__restrict__ leftFace,
double *__restrict__ bottomFace,
double *__restrict__ frontFace,
double *__restrict__ rightFace,
double *__restrict__ topFace,
double *__restrict__ backFace )

Definition at line 32 of file Projection.cpp.

References assertionEquals, and projectPatchSolutionOntoFaces().

Here is the call graph for this function:

◆ projectPatchSolutionOntoFaces() [2/3]

void toolbox::blockstructured::projectPatchSolutionOntoFaces ( int numberOfVolumesPerAxisInPatch,
int haloSize,
int unknowns,
int auxiliaryVariables,
const double *__restrict__ Q,
double *__restrict__ leftFace,
double *__restrict__ bottomFace,
double *__restrict__ rightFace,
double *__restrict__ topFace )

Project data from patch onto adjacent faces.

Used by exahype2.solvers.fv.ProjectPatchOntoFaces for example. The more sophisticiated time-stepping schemes such as Runge-Kutta often have their own projection realised via jinja2 in Python, as they not only project some fixed data, but actually have to project linear combinations. Furthermore, the solvers often set some helper variables (meta data) on the faces, too.

However, some manual projections (user preprocessing) can benefit heavily from this routine, so I decided to deploy it to a C++ routine of its own.

Parameters
QPatch data of size \( numberOfVolumesPerAxisInPatch^d \cdot (unknowns + auxiliaryVariables)\). That is, the pointer points to a patch without any halo data.
leftFacePointer to face data, i.e. a field of size \( numberOfVolumesPerAxisInPatch^{d-1} \cdot 2 \cdot haloSize \cdot (unknowns + auxiliaryVariables)\)

Definition at line 8 of file Projection.cpp.

References assertionEquals, and projectPatchSolutionOntoFaces().

Referenced by projectPatchSolutionOntoFaces(), and projectPatchSolutionOntoFaces().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ projectPatchSolutionOntoFaces() [3/3]

void toolbox::blockstructured::projectPatchSolutionOntoFaces ( int numberOfVolumesPerAxisInPatch,
int haloSize,
int unknowns,
int auxiliaryVariables,
const double *__restrict__ Q,
double * faces[2 *Dimensions] )

d-loop over all dimensions except d. The vector k's entry d is set to 0. We start with the left/bottom face, i.e. the one closer to the coordinate system's origin.

Definition at line 58 of file Projection.cpp.

References dfore, peano4::utils::dLinearised(), j, k, and serialiseVoxelIndexInOverlap().

Here is the call graph for this function:

◆ restrictCell_AoS_averaging()

void toolbox::blockstructured::restrictCell_AoS_averaging ( const peano4::datamanagement::CellMarker & marker,
int numberOfDoFsPerAxisInPatch,
int unknowns,
double * fineGridValues,
double * coarseGridValues )

This routine is used when we delete a cell due to dynamic AMR.

Definition at line 240 of file Restriction.cpp.

References peano4::utils::dLinearised(), j, and logDebug.

Referenced by toolbox::blockstructured::tests::InterpolationTest::testRestrictCellForBreakingDam().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ restrictCell_AoS_inject()

void toolbox::blockstructured::restrictCell_AoS_inject ( const peano4::datamanagement::CellMarker & marker,
int numberOfDoFsPerAxisInPatch,
int unknowns,
double * fineGridValues,
double * coarseGridValues )

Definition at line 199 of file Restriction.cpp.

References assertion3, dfor, peano4::utils::dLinearised(), and j.

Here is the call graph for this function:

◆ restrictCell_AoS_tensor_product() [1/2]

void toolbox::blockstructured::restrictCell_AoS_tensor_product ( const peano4::datamanagement::CellMarker & marker,
int numberOfDoFsPerAxisInPatch,
int unknowns,
const double *__restrict__ tangentialRestrictionMatrix1d,
double * fineGridValues,
double * coarseGridValues )

Definition at line 13 of file Restriction.cpp.

References assertionMsg.

◆ restrictCell_AoS_tensor_product() [2/2]

template<typename C >
void toolbox::blockstructured::restrictCell_AoS_tensor_product ( const peano4::datamanagement::CellMarker & marker,
int numberOfDoFsPerAxisInPatch,
int unknowns,
double * fineGridValues,
double * coarseGridValues )

Definition at line 85 of file InterpolationRestriction.h.

References restrictCell_AoS_tensor_product().

Referenced by restrictCell_AoS_tensor_product().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ restrictCellIntoOverlappingCell_inject()

void toolbox::blockstructured::restrictCellIntoOverlappingCell_inject ( int numberOfDoFsPerAxisInSourcePatch,
int numberOfDoFsPerAxisInDestinationPatch,
int unknowns,
double * sourceValues,
double * destinationValues )

This routine should be used if a cell hosts two sets of unknowns.

Frequently used if your code hosts two PDE solvers. This routine runs over all the dofs in destinationValues, computes their position, rounds it to the closest dof within sourceValues, and then copies the data over. This is, we assume that both the source and destination field represent voxels (similar to a Finite Volume) scheme or data which is hold within the centre of a subgrid (totally staggered dof layout).

The description above assumes that numberOfDoFsPerAxisInDestinationPatch<=numberOfDoFsPerAxisInSourcePatch. While the routine also works if this is not the case, injecting from a coarser mesh into a finer one introduces a huge numerical inaccuracy (it is basically piece-wise constant) and you hence might be better off with a linear restriction. If the inequality is "violated", I'd however call this rather a projection and therefore you have to search through the provided projection routines to find such a linear scheme.

Definition at line 141 of file Restriction.cpp.

References dfor, and peano4::utils::dLinearised().

Here is the call graph for this function:

◆ restrictCellIntoOverlappingCell_inject_and_average()

void toolbox::blockstructured::restrictCellIntoOverlappingCell_inject_and_average ( int numberOfDoFsPerAxisInSourcePatch,
int numberOfDoFsPerAxisInDestinationPatch,
int unknowns,
double * sourceValues,
double * destinationValues,
double weightOfInjectedValue = 0.5 )

Flavour of restrictCellIntoOverlappingCell_inject() where we inject the solution but then take the average between the original value in destinationValues an the injected value.

This "damps" the impact of the injection.

Parameters
weightOfInjectedValueIf this value is 0.5, we take the average. If it equals 1.0, we end up exactly with restrictCellIntoOverlappingCell_inject(), i.e. overwrite the value in destinationValues. A value of 0.0 switches the injection off.

Definition at line 167 of file Restriction.cpp.

References assertion1, dfor, and peano4::utils::dLinearised().

Here is the call graph for this function:

◆ restrictHaloLayer_AoS_averaging()

void toolbox::blockstructured::restrictHaloLayer_AoS_averaging ( const peano4::datamanagement::FaceMarker & marker,
int numberOfDoFsPerAxisInPatch,
int overlap,
int unknowns,
double * fineGridValues,
double * coarseGridValues )

Consult commend on interpolation that clarifies why we need two different halo layer restrictions, i.e.

one for half of the halo and one for the whole thing.

Definition at line 228 of file Restriction.cpp.

References restrictInnerHalfOfHaloLayer_AoS_averaging().

Referenced by toolbox::blockstructured::tests::InterpolationTest::testRestrictHaloLayer_AoS_averaging().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ restrictHaloLayer_AoS_inject()

void toolbox::blockstructured::restrictHaloLayer_AoS_inject ( const peano4::datamanagement::FaceMarker & marker,
int numberOfDoFsPerAxisInPatch,
int overlap,
int unknowns,
double * fineGridValues,
double * coarseGridValues )

Restrict data by injection.

Required for dynamic AMR only. Invokes the one-sided routine twice: for the inner and the outer half of the face.

Definition at line 129 of file Restriction.cpp.

References restrictInnerHalfOfHaloLayer_AoS_inject().

Here is the call graph for this function:

◆ restrictHaloLayer_AoS_tensor_product() [1/2]

void toolbox::blockstructured::restrictHaloLayer_AoS_tensor_product ( const peano4::datamanagement::FaceMarker & marker,
int numberOfDoFsPerAxisInPatch,
int overlap,
int unknowns,
const double *__restrict__ normalRestrictionMatrix1d,
const double *__restrict__ tangentialRestrictionMatrix1d,
double * fineGridValues,
double * coarseGridValues )

Restrict whole halo layer.

This routine is usually only called when we destroy a face completely. In this case, we have to restrict the whole halo layer. Otherwise, we typically only restrict the inner halo layer, i.e. half of the overall face data.

As we have a routine that handles half of the face data, I simply call this routine twice, but once switch inside and outside.

See also
restrictInnerHalfOfHaloLayer_AoS_tensor_product()

Definition at line 24 of file Restriction.cpp.

References restrictInnerHalfOfHaloLayer_AoS_tensor_product().

Here is the call graph for this function:

◆ restrictHaloLayer_AoS_tensor_product() [2/2]

template<typename C >
void toolbox::blockstructured::restrictHaloLayer_AoS_tensor_product ( const peano4::datamanagement::FaceMarker & marker,
int numberOfDoFsPerAxisInPatch,
int overlap,
int unknowns,
double * fineGridValues,
double * coarseGridValues )

Definition at line 104 of file InterpolationRestriction.h.

References restrictHaloLayer_AoS_tensor_product().

Referenced by restrictHaloLayer_AoS_tensor_product().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ restrictInnerHalfOfHaloLayer_AoS_averaging()

void toolbox::blockstructured::restrictInnerHalfOfHaloLayer_AoS_averaging ( const peano4::datamanagement::FaceMarker & marker,
int numberOfDoFsPerAxisInPatch,
int overlap,
int unknowns,
double * fineGridValues,
double * coarseGridValues,
bool swapInsideOutside = false )

Restrict with averaging.

This routine works for overlaps of 1 and multiples of 3. However, it does only set values for the overlap/3 adjacent cells. So if you work with an overlap of 1, then the overlap just works fine, but it is not really the average. It is the average of the one layer adjacent to the fine grid transition. In 2d, it is the sum scaled with 1/3.

If you have an overlap of 3, the routine computes a meaningful average, but as it has only three overlap cells on the fine grid, it can only set the overlap cell 1 on the next coarser mesh.

Definition at line 312 of file Restriction.cpp.

References assertion1, assertion3, dfore, j, logTraceInWith4Arguments, logTraceOut, and serialiseVoxelIndexInOverlap().

Referenced by restrictHaloLayer_AoS_averaging().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ restrictInnerHalfOfHaloLayer_AoS_inject()

void toolbox::blockstructured::restrictInnerHalfOfHaloLayer_AoS_inject ( const peano4::datamanagement::FaceMarker & marker,
int numberOfDoFsPerAxisInPatch,
int overlap,
int unknowns,
double * fineGridValues,
double * coarseGridValues,
bool swapInsideOutside = false )

Restrict data by injection.

This routine works for an overlap of 1 or an overlap of 3k+2. If the overlap equals 1, we walk along the fine grid layer along the AMR boundary and we restrict every third finite volume voxel.

The routine restricts only only have to a face, and it restricts the inner half:

An interpolation sets the data in the halo layer of the fine grid cell. For this, it uses interior data from the coarse grid cell. A restriction sets the data in the halo of the coarser cell. For this, it uses the data inside the finer cell. In the sketch above, the left cell hosts the fine data. The right cell is a coarse cell. An interior voxel from the fine data left is copied into the halo of the coarser voxel.

You can invert this behaviour by setting the marker.

Halo sizes

If the overlap equals two, we don't take the voxel directly adjacent to the resolution change face, but we take the one that is one voxel further away, as the centre of this one coincides with the centre of the coarser voxel. So we can actually inject. A similar argument holds for an overlap of 3+2.

In all of these cases where we use a proper injection, i.e. where the overlap is greater than one, we cannot befill the whole coarser overlap. Instead, we will only fill one layer for an overlap of 2, or two layers for an overlap of 5. The remaining coarse layer entries are not touched.

This means that the halo data of the coarse cell is potentially incomplete - something to take into account if you use the data.

Definition at line 391 of file Restriction.cpp.

References assertion1, assertion3, dfore, j, logTraceInWith6Arguments, logTraceOut, and serialiseVoxelIndexInOverlap().

Referenced by restrictHaloLayer_AoS_inject().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ restrictInnerHalfOfHaloLayer_AoS_tensor_product() [1/2]

void toolbox::blockstructured::restrictInnerHalfOfHaloLayer_AoS_tensor_product ( const peano4::datamanagement::FaceMarker & marker,
int numberOfDoFsPerAxisInPatch,
int overlap,
int unknowns,
const double *__restrict__ normalRestrictionMatrix1d,
const double *__restrict__ tangentialRestrictionMatrix1d,
double * fineGridValues,
double * coarseGridValues,
bool swapInsideOutside = false )

Restrict inner halo half of face data.

Every cell has 2d faces. From a cell's perspective, each face hosts k layers of the adjacent cell and k entries of the neighbouring cell. The latter are usually called halo. If a face is a hanging face, these halo data are interpolated and do not stem directly from a neighbour cell (as there is no neighbour cell on the same resolution level). Once the cell has updated its data, we have to befill the halo of the adjacent coarser cell in return. This is what this routine is about.

For this restriction, we take the inner data layers associated to the face (therefore the name) and we restrict them into the halo, i.e. outer face data, of the coarser cell.

This routine assumes that the restriction can be written as a tensor product between one operator along the face normal and an operator describing the tangential restriction. The latter is applied d-1 times.

Normal restriction operator

The normal restriction is constructed from a 1d adaptive mesh: The operator describes how the k coarse grid values are initialised from the 2k fine grid values:

In the sketch above, we have a 1d adaptive mesh, where the coarse mesh is on the left and the fine mesh on the right. We restrict from the fine grid face (which is a point for a 1d setup) to the coarse grid face. Peano works with multiscale meshes: So we have two cells on the coarse mesh. The right cell is refined, i.e. overlaps with a finer cell (fat lines bottom), while the left cell is unrefined. The face in this example hosts an overlap of two, i.e. copies of two entries left and right. I denote the four coarse grid entries with green and blue bullets. The fine grid unknowns associated with the face are denoted with red and orange dots.

The restriction routine has to set the two coarse face entries to the right, i.e. the blue values. The left entries (green) are initialised properly by the mesh, as they stem directly from an unrefined cell. You can also overwrite (add something to) the left entries of the face, but most codes don't do so.

The normal operator now describes through a 4x4 matrix, what data goes from the fine mesh to the four coarser mesh. Two rows (for the green dots) of this matrix are most of the time empty.

Overlap of one

If you work with an overlap of one, the restriction along the normal is kind of canonical. You can, for example, take the fine grid data (the one orange point) and write that one to the one blue point. In principle, the data flow is trivial.

A more sophisticated scheme would set the blue value such that the average in the real face position equals the average on the finer cell. So we compute the average of red and orange, assume that the red point equals hte value of the green point, and then set the blue point such that the average between blue and green matches the other average.

Overlap greater than one

With an overlap greater than one, we observe that the fine grid data stops to overlap the coarse data spatially. We have discussed this property by means of the injection (see restrictInnerHalfOfHaloLayer_AoS_inject()). From the example above where we illustrate an overlap of two, it becomes clear that we now cannot set all halo data on the coarser mesh directly, i.e. using fine grid data. The fine grid would hold all required data, but the routine accepts the fine grid face data only. This data is not sufficient to set all coarse entries.

In the illustration, we can for example take the right orange point and write its data to the left blue point. These two points do overlap. However, we also have to set the right blue point, and there's no fine grid info for this guy. The only thing that we can do is to take the red and orange points, extrapolate somehow and then set the one remaining blue point.

Tangential operator

This yet has to be written.

Implementation

We loop over a submanifold, i.e. over a d-1 dimensional array where the index along the normal direction equals 0. The loop vector is called kCoarse. iCoarse loops over the depth of the overlap, which we called k in the examples above. The destination degree of freedom can be constructed from kCoarse and iCoarse. For this, we have to take into account that this iCoarse always counts from 0 to overlap, but we obviously have to take into account if we consider a left hanging face or a right hanging face and invert it accordingly. The destination index determines the row that we use from the normal and tangential projection matrices.

We next construct the weight of the restriction and initialise it with 1 as it will result from a tensor product of operators, i.e. a multiplication. For the tensor-product, we run over each dimension. The loop counter here's called k.

Again, we do this combination of kFine and iFine, but iFine this time runs over 2k elements. If we assess the normal operator, we have to analyse if we work with a normalised layout, i.e. the left face of a cell or the right one. If we try to find out the entry in the normal matrix, we might have to mirror entries. All the other entries are ordered along the coordinate axes.

Example matrices

If we average over all fine grid values and set all coarse grid values to the same restricted value, and if the overlap equals three, then you would pass in the following matrix:

   static constexpr double  NormalRestrictionMatrix1d[]     = {
     0.0,    0.0,    0.0,    1.0/3.0,    1.0/3.0,    1.0/3.0,
     0.0,    0.0,    0.0,    1.0/3.0,    1.0/3.0,    1.0/3.0,
     0.0,    0.0,    0.0,    1.0/3.0,    1.0/3.0,    1.0/3.0
   };

The image below illustrates the data flow (for an overlap of two, but I was too lazy to paint yet another pic):

The three zeroes in the matrix mean that the real coarse grid values (green) remain unchanged. The blue values are set according to the three rows of the matrix. Each ignores the red entries to the left (therefore the leading zeroes) and then computes the average of the right ones. The result is then written to the coarse level.

If you want to do the same type of averaging along the tangential, and if you have a patch size of 5, you have to pass in the following matrix:

  static constexpr double  TangentialRestrictionMatrix1d[] = {
    1.0/3.0, 1.0/3.0, 1.0/3.0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 1.0/3.0, 1.0/3.0, 1.0/3.0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 1.0/3.0, 1.0/3.0, 1.0/3.0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 1.0/3.0, 1.0/3.0, 1.0/3.0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.0/3.0, 1.0/3.0, 1.0/3.0
  };

We have 3x5 values on the fine grid, which determine the 5 entries on the coarse mesh. Therefore, we have a 5x15 matrix. The first coarse mesh entry is the average of the first three fine grid values. The second coarse entry results from the fine grid values 4,5,6.

Arguments

Parameters
normalRestrictionMatrix1dMatrix that describes how the fine mesh unknowns affect the coarse grid unknowns. If you work with an overlap of k, normalRestrictionMatrix1d is a \( k \times 2k \) matrix: It accepts the 2k fine grid values and spills out the value of the k outer coarse grid values.

The matrix refers to face number 0, or the sketch as given above. The values to restrict are the right ones (blue dots).

Parameters
swapInsideOutsideAll the discussions above refer to the initialisation of coarse grid's outer halo (blue points). You can alter this behaviour, i.e. make the routine manipulate the coarse grid green points instead, by setting the swap flag.

Definition at line 38 of file Restriction.cpp.

References assertion, assertion2, assertion4, assertion5, dfore, logDebug, logTraceInWith3Arguments, logTraceOut, and serialiseVoxelIndexInOverlap().

Here is the call graph for this function:

◆ restrictInnerHalfOfHaloLayer_AoS_tensor_product() [2/2]

template<typename C >
void toolbox::blockstructured::restrictInnerHalfOfHaloLayer_AoS_tensor_product ( const peano4::datamanagement::FaceMarker & marker,
int numberOfDoFsPerAxisInPatch,
int overlap,
int unknowns,
double * fineGridValues,
double * coarseGridValues,
bool swapInsideOutside = false )

◆ serialiseMarkerIn3x3PatchAssembly()

int toolbox::blockstructured::serialiseMarkerIn3x3PatchAssembly ( const tarch::la::Vector< Dimensions, int > & markerIndex,
int numberOfDoFsPerAxisInPatch )

If you have a marker identifying one element within a 3x3 or 3x3x3, respectively, set of patches, we sometimes have to serialise this marker index.

We use a lexicographic ordering here. The routine returns the index of the first cell within the patch identified via markerIndex

Parameters
markerIndexTypically returned by getRelativePositionWithinFatherCell().

Definition at line 53 of file Enumeration.cpp.

◆ serialisePatchIndexInOverlap()

int toolbox::blockstructured::serialisePatchIndexInOverlap ( const tarch::la::Vector< Dimensions, int > & patchIndex,
int normal )

Patches along a face are basically organised as \( 3^{d-1} \) arrays, i.e.

form a Cartesian 3x3 topology for a 3d setup. This routine serialises the number of patches.

Definition at line 32 of file Enumeration.cpp.

References assertion2.

Referenced by interpolateHaloLayer_AoS_linear_with_constant_extrapolation(), interpolateHaloLayer_AoS_linear_with_constant_extrapolation_and_linear_normal_interpolation(), interpolateHaloLayer_AoS_linear_with_linear_extrapolation(), interpolateHaloLayer_AoS_linear_with_linear_extrapolation_and_linear_normal_interpolation(), and interpolateHaloLayer_AoS_piecewise_constant().

Here is the caller graph for this function:

◆ serialiseVoxelIndexInOverlap()

int toolbox::blockstructured::serialiseVoxelIndexInOverlap ( const tarch::la::Vector< Dimensions, int > & overlapCell,
int numberOfDoFsPerAxisInPatch,
int overlap,
int normal )

The volumes or elements within an overlap are always enumerated lexicographically.

This routine serialises this index.

Parameters
overlapOverlap of one patch into the other. If you have a halo of one cell around each patch, then this parameter is 1.

Definition at line 4 of file Enumeration.cpp.

References assertion4.

Referenced by toolbox::blockstructured::internal::clearHalfOfHaloLayerAoS(), clearHaloLayerAoS(), exahype2::fv::copyHalfOfHalo(), extrapolatePatchSolutionAndProjectExtrapolatedHaloOntoFaces(), interpolateHaloLayer_AoS_tensor_product(), toolbox::blockstructured::internal::projectInterpolatedFineCellsOnHaloLayer_AoS(), projectPatchHaloOntoFaces(), projectPatchSolutionOntoFaces(), restrictInnerHalfOfHaloLayer_AoS_averaging(), restrictInnerHalfOfHaloLayer_AoS_inject(), and restrictInnerHalfOfHaloLayer_AoS_tensor_product().

Here is the caller graph for this function: