24#ifndef DUMUX_DISCRETIZATION_STAGGERED_GEOMETRY_HELPER_HH
25#define DUMUX_DISCRETIZATION_STAGGERED_GEOMETRY_HELPER_HH
27#include <dune/geometry/multilineargeometry.hh>
70template<
class Gr
idView,
int upwindSchemeOrder>
73 using Scalar =
typename GridView::ctype;
74 using GlobalPosition =
typename GridView::template Codim<0>::Entity::Geometry::GlobalCoordinate;
94template<
class Gr
idView,
int upwindSchemeOrder>
97 using Scalar =
typename GridView::ctype;
115template<
class Gr
idView>
132template<
class Vector>
135 const auto eps = 1e-8;
136 return std::find_if(vector.begin(), vector.end(), [eps](
const auto& x) { return std::abs(x) > eps; } ) - vector.begin();
144template<
class Gr
idView,
int upwindSchemeOrder>
147 using Scalar =
typename GridView::ctype;
148 static constexpr auto dim = GridView::dimension;
150 using Element =
typename GridView::template Codim<0>::Entity;
151 using Intersection =
typename GridView::Intersection;
152 using GlobalPosition =
typename Element::Geometry::GlobalCoordinate;
158 static constexpr auto codimIntersection = 1;
159 static constexpr auto numFacets = dim * 2;
160 static constexpr auto numPairs = 2 * (dim - 1);
162 static constexpr bool useHigherOrder = upwindSchemeOrder > 1;
170 , gridView_(gridView)
174 template<
class IntersectionMapper>
177 intersection_ = intersection;
187 return intersection_.indexInInside();
230 if constexpr (useHigherOrder)
231 fillOuterAxisData_();
233 const auto inIdx = intersection_.indexInInside();
234 const auto oppIdx = localOppositeIdx_(inIdx);
237 axisData_.
selfDof = gridView_.indexSet().subIndex(intersection_.inside(), inIdx, codimIntersection);
240 axisData_.
oppositeDof = gridView_.indexSet().subIndex(intersection_.inside(), oppIdx, codimIntersection);
243 const auto self = getFacet_(inIdx, element_);
244 const auto opposite = getFacet_(oppIdx, element_);
254 void fillOuterAxisData_()
260 const auto thisFaceLocalIdx = intersection_.indexInInside();
261 const auto& faceCenterPos = getFacet_(thisFaceLocalIdx, element_).geometry().center();
262 if (intersection_.neighbor())
263 addForwardNeighborAxisData_(intersection_.outside(), 0, thisFaceLocalIdx, faceCenterPos);
266 const auto oppositeFaceLocalIdx = localOppositeIdx_(thisFaceLocalIdx);
267 const auto& oppositeFaceCenterPos = getFacet_(oppositeFaceLocalIdx, element_).geometry().center();
268 for (
const auto& intersection : intersections(gridView_, element_))
270 if (intersection.indexInInside() == oppositeFaceLocalIdx && intersection.neighbor())
272 addBackwardNeighborAxisData_(intersection.outside(), 0, oppositeFaceLocalIdx, oppositeFaceCenterPos);
281 void addForwardNeighborAxisData_(
const Element& neighbor,
283 const unsigned int localIntersectionIndex,
284 const GlobalPosition& faceCenterPos)
288 axisData_.
inAxisForwardDofs[
distance] = gridView_.indexSet().subIndex(neighbor, localIntersectionIndex, codimIntersection);
289 const auto& forwardFacePos = getFacet_(localIntersectionIndex, neighbor).geometry().center();
294 if (
distance >= numForwardBackwardAxisDofs-1)
297 for (
const auto& intersection : intersections(gridView_, neighbor))
299 if (intersection.indexInInside() == localIntersectionIndex && intersection.neighbor())
301 addForwardNeighborAxisData_(intersection.outside(),
distance+1, localIntersectionIndex, forwardFacePos);
310 void addBackwardNeighborAxisData_(
const Element& neighbor,
312 const unsigned int localIntersectionIndex,
313 const GlobalPosition& faceCenterPos)
318 const auto& backwardFacePos = getFacet_(localIntersectionIndex, neighbor).geometry().center();
323 if (
distance >= numForwardBackwardAxisDofs-1)
326 for (
const auto& intersection : intersections(gridView_, neighbor))
328 if (intersection.indexInInside() == localIntersectionIndex && intersection.neighbor())
330 addBackwardNeighborAxisData_(intersection.outside(),
distance+1, localIntersectionIndex, backwardFacePos);
346 const auto& selfElementCenter = element_.geometry().center();
347 const auto& selfFacetCenter = intersection_.geometry().center();
350 SmallLocalIndexType numPairInnerLateralIdx = 0;
351 for (
const auto& innerElementIntersection : intersections(gridView_, element_))
353 if (facetIsNormal_(innerElementIntersection.indexInInside(), intersection_.indexInInside()))
355 const auto innerElementIntersectionIdx = innerElementIntersection.indexInInside();
356 setLateralPairFirstInfo_(innerElementIntersectionIdx, element_, numPairInnerLateralIdx);
358 const auto distance = innerElementIntersection.geometry().center() - selfElementCenter;
359 pairData_[numPairInnerLateralIdx].lateralStaggeredFaceCenter = selfFacetCenter+
distance;
361 numPairInnerLateralIdx++;
366 SmallLocalIndexType numPairOuterLateralIdx = 0;
367 if (intersection_.neighbor())
370 const auto& directNeighborElement = intersection_.outside();
372 for (
const auto& directNeighborElementIntersection : intersections(gridView_, directNeighborElement))
375 if (facetIsNormal_(directNeighborElementIntersection.indexInInside(), intersection_.indexInOutside()))
377 const auto directNeighborElemIsIdx = directNeighborElementIntersection.indexInInside();
378 setLateralPairSecondInfo_(directNeighborElemIsIdx, directNeighborElement, numPairOuterLateralIdx);
379 numPairOuterLateralIdx++;
385 for (
const auto& intersection : intersections(gridView_, element_))
387 if (facetIsNormal_(intersection.indexInInside(), intersection_.indexInInside()))
389 assert(!pairData_[numPairOuterLateralIdx].hasOuterLateral);
391 const auto normalDistanceoffset = selfFacetCenter - selfElementCenter;
392 pairData_[numPairOuterLateralIdx].lateralDistance = normalDistanceoffset.two_norm();
393 numPairOuterLateralIdx++;
399 const auto parallelLocalIdx = intersection_.indexInInside();
400 SmallLocalIndexType numPairParallelIdx = 0;
401 for (
const auto& intersection : intersections(gridView_, element_))
403 if (facetIsNormal_(intersection.indexInInside(), parallelLocalIdx))
405 if (intersection.neighbor())
409 const auto localLateralIntersectionIndex = intersection.indexInInside();
424 if (intersection_.neighbor())
425 for (
const auto& outerIntersection : intersections(gridView_, intersection_.outside()))
426 if (intersection.indexInInside() == outerIntersection.indexInInside())
427 if (!outerIntersection.neighbor())
428 pairData_[numPairParallelIdx].hasHalfParallelNeighbor =
true;
442 if (!intersection_.neighbor())
443 for (
const auto& outerIntersection : intersections(gridView_, intersection.outside()))
444 if (intersection_.indexInInside() == outerIntersection.indexInInside())
445 if (outerIntersection.neighbor())
446 pairData_[numPairParallelIdx].hasCornerParallelNeighbor =
true;
449 addParallelNeighborPairData_(intersection.outside(), 0, localLateralIntersectionIndex, parallelLocalIdx, parallelAxisIdx, numPairParallelIdx);
452 ++numPairParallelIdx;
458 void addParallelNeighborPairData_(
const Element& neighbor,
460 const unsigned int localLateralIntersectionIndex,
461 const unsigned int parallelLocalIdx,
462 const unsigned int parallelAxisIdx,
463 const SmallLocalIndexType dataIdx)
466 pairData_[dataIdx].hasParallelNeighbor.set(
distance,
true);
467 pairData_[dataIdx].parallelDofs[
distance] = gridView_.indexSet().subIndex(neighbor, parallelLocalIdx, codimIntersection);
468 pairData_[dataIdx].parallelCellWidths[
distance] = setParallelPairCellWidths_(neighbor, parallelAxisIdx);
471 const auto numParallelFaces = pairData_[0].parallelCellWidths.size();
476 for (
const auto& lateralIntersection : intersections(gridView_, neighbor))
479 if (lateralIntersection.indexInInside() == localLateralIntersectionIndex)
482 if (lateralIntersection.neighbor())
483 addParallelNeighborPairData_(lateralIntersection.outside(),
distance+1,
484 localLateralIntersectionIndex, parallelLocalIdx, parallelAxisIdx, dataIdx);
495 int localOppositeIdx_(
const int idx)
const
497 return (idx % 2) ? (idx - 1) : (idx + 1);
506 bool facetIsNormal_(
const int selfIdx,
const int otherIdx)
const
508 return !(selfIdx == otherIdx || localOppositeIdx_(selfIdx) == otherIdx);
511 auto getFacet_(
const int localFacetIdx,
const Element& element)
const
513 return element.template subEntity <1> (localFacetIdx);
517 void setLateralPairFirstInfo_(
const int isIdx,
const Element& element,
const int numPairsIdx)
520 pairData_[numPairsIdx].lateralPair.first = gridView_.indexSet().subIndex(element, isIdx, codimIntersection);
523 pairData_[numPairsIdx].localLateralFaceIdx = isIdx;
527 void setLateralPairSecondInfo_(
const int isIdx,
const Element& element,
const int numPairsIdx)
530 pairData_[numPairsIdx].hasOuterLateral =
true;
531 pairData_[numPairsIdx].lateralPair.second = gridView_.indexSet().subIndex(element, isIdx, codimIntersection);
534 const auto& selfFacetCenter = intersection_.geometry().center();
535 const auto& selfElementCenter = element_.geometry().center();
537 const auto& neighborElement = intersection_.outside();
538 const auto& neighborElementCenter = neighborElement.geometry().center();
539 const auto& neighborFacetCenter = getFacet_(intersection_.indexInOutside(), neighborElement).geometry().center();
541 const Scalar insideLateralDistance = (selfFacetCenter - selfElementCenter).two_norm();
542 const Scalar outsideLateralDistance = (neighborFacetCenter - neighborElementCenter).two_norm();
544 pairData_[numPairsIdx].lateralDistance = insideLateralDistance + outsideLateralDistance;
548 Scalar setParallelPairCellWidths_(
const Element& element,
const int parallelAxisIdx)
const
550 std::vector<GlobalPosition> faces;
551 faces.reserve(numFacets);
552 for (
const auto& intersection : intersections(gridView_, element))
553 faces.push_back(intersection.geometry().center());
555 switch (parallelAxisIdx)
558 return (faces[1] - faces[0]).two_norm();
560 return (faces[3] - faces[2]).two_norm();
564 return (faces[5] - faces[4]).two_norm();
567 DUNE_THROW(Dune::InvalidStateException,
"Something went terribly wrong");
571 Intersection intersection_;
572 const Element& element_;
573 const GridView gridView_;
575 std::array<PairData, numPairs> pairData_;
Defines the index types used for grid and local indices.
Define some often used mathematical functions.
ctype distance(const Dune::FieldVector< ctype, dimWorld > &a, const Dune::FieldVector< ctype, dimWorld > &b)
Compute the shortest distance between two points.
Definition: distance.hh:138
static unsigned int directionIndex(Vector &&vector)
Returns the dirction index of the facet (0 = x, 1 = y, 2 = z)
Definition: staggeredgeometryhelper.hh:133
typename GridView::IndexSet::IndexType GridIndex
Definition: indextraits.hh:39
std::uint_least8_t SmallLocalIndex
Definition: indextraits.hh:41
defines an intersection mapper for mapping of global DOFs assigned to faces which also works for adap...
Definition: intersectionmapper.hh:224
Parallel Data stored per sub face.
Definition: staggeredgeometryhelper.hh:72
std::pair< GridIndexType, GridIndexType > lateralPair
Definition: staggeredgeometryhelper.hh:84
typename IndexTraits< GridView >::GridIndex GridIndexType
Definition: staggeredgeometryhelper.hh:75
bool hasOuterLateral
Definition: staggeredgeometryhelper.hh:83
typename GridView::ctype Scalar
Definition: staggeredgeometryhelper.hh:73
GlobalPosition lateralStaggeredFaceCenter
Definition: staggeredgeometryhelper.hh:87
std::bitset< upwindSchemeOrder > hasParallelNeighbor
Definition: staggeredgeometryhelper.hh:78
bool hasHalfParallelNeighbor
Definition: staggeredgeometryhelper.hh:79
bool hasCornerParallelNeighbor
Definition: staggeredgeometryhelper.hh:80
SmallLocalIndexType localLateralFaceIdx
Definition: staggeredgeometryhelper.hh:85
typename IndexTraits< GridView >::SmallLocalIndex SmallLocalIndexType
Definition: staggeredgeometryhelper.hh:76
std::array< Scalar, upwindSchemeOrder > parallelCellWidths
Definition: staggeredgeometryhelper.hh:82
typename GridView::template Codim< 0 >::Entity::Geometry::GlobalCoordinate GlobalPosition
Definition: staggeredgeometryhelper.hh:74
std::array< GridIndexType, upwindSchemeOrder > parallelDofs
Definition: staggeredgeometryhelper.hh:81
Scalar lateralDistance
Definition: staggeredgeometryhelper.hh:86
In Axis Data stored per sub face.
Definition: staggeredgeometryhelper.hh:96
Scalar selfToOppositeDistance
Definition: staggeredgeometryhelper.hh:106
GridIndexType selfDof
Definition: staggeredgeometryhelper.hh:100
std::array< Scalar, upwindSchemeOrder-1 > inAxisForwardDistances
Definition: staggeredgeometryhelper.hh:107
std::bitset< upwindSchemeOrder-1 > hasBackwardNeighbor
Definition: staggeredgeometryhelper.hh:103
std::array< GridIndexType, upwindSchemeOrder-1 > inAxisForwardDofs
Definition: staggeredgeometryhelper.hh:104
std::array< Scalar, upwindSchemeOrder-1 > inAxisBackwardDistances
Definition: staggeredgeometryhelper.hh:108
std::bitset< upwindSchemeOrder-1 > hasForwardNeighbor
Definition: staggeredgeometryhelper.hh:102
typename IndexTraits< GridView >::GridIndex GridIndexType
Definition: staggeredgeometryhelper.hh:98
typename GridView::ctype Scalar
Definition: staggeredgeometryhelper.hh:97
GridIndexType oppositeDof
Definition: staggeredgeometryhelper.hh:101
std::array< GridIndexType, upwindSchemeOrder-1 > inAxisBackwardDofs
Definition: staggeredgeometryhelper.hh:105
GridIndexType oppositeDof
Definition: staggeredgeometryhelper.hh:122
typename IndexTraits< GridView >::GridIndex GridIndexType
Definition: staggeredgeometryhelper.hh:119
Scalar selfToOppositeDistance
Definition: staggeredgeometryhelper.hh:123
typename GridView::ctype Scalar
Definition: staggeredgeometryhelper.hh:118
GridIndexType selfDof
Definition: staggeredgeometryhelper.hh:121
Helper class constructing the dual grid finite volume geometries for the free flow staggered discreti...
Definition: staggeredgeometryhelper.hh:146
Detail::AxisData< GridView, upwindSchemeOrder > AxisData
Definition: staggeredgeometryhelper.hh:166
SmallLocalIndexType localFaceIndex() const
Returns the local index of the face (i.e. the intersection)
Definition: staggeredgeometryhelper.hh:185
FreeFlowStaggeredGeometryHelper(const Element &element, const GridView &gridView)
Definition: staggeredgeometryhelper.hh:168
AxisData axisData() const
Returns a copy of the axis data.
Definition: staggeredgeometryhelper.hh:193
unsigned int directionIndex() const
Returns the direction index of the primary facet (0 = x, 1 = y, 2 = z)
Definition: staggeredgeometryhelper.hh:209
void updateLocalFace(const IntersectionMapper &, const Intersection &intersection)
update the local face
Definition: staggeredgeometryhelper.hh:175
std::array< PairData, numPairs > pairData() const
Returns a copy of the pair data.
Definition: staggeredgeometryhelper.hh:201
unsigned int directionIndex(const Intersection &intersection) const
Returns the direction index of the facet passed as an argument (0 = x, 1 = y, 2 = z)
Definition: staggeredgeometryhelper.hh:217