12#ifndef DUMUX_DISCRETIZATION_FACECENTERED_STAGGERED_FV_ELEMENT_GEOMETRY_HH
13#define DUMUX_DISCRETIZATION_FACECENTERED_STAGGERED_FV_ELEMENT_GEOMETRY_HH
18#include <dune/common/rangeutilities.hh>
19#include <dune/common/reservedvector.hh>
20#include <dune/common/iteratorrange.hh>
21#include <dune/common/exceptions.hh>
32namespace Detail::FCStaggered {
34template<
class FVElementGeometry,
class SubControlVolume>
35typename SubControlVolume::Traits::Geometry scvGeometry(
const FVElementGeometry& fvGeometry,
36 const SubControlVolume& scv)
38 typename SubControlVolume::Traits::CornerStorage corners{};
40 const auto elementGeometry = (scv.elementIndex() != fvGeometry.elementIndex()) ?
41 fvGeometry.element().geometry() :
42 fvGeometry.gridGeometry().element(scv.elementIndex()).geometry();
44 const auto center = elementGeometry.center();
45 const auto dofAxis = scv.dofAxis();
46 for (
int i = 0; i < corners.size(); ++i)
48 auto& corner = corners[i];
51 corner = elementGeometry.corner(i);
55 if ((corner[dofAxis] - center[dofAxis]) * scv.directionSign() < 0.0)
56 corner[dofAxis] =
center[dofAxis];
59 return {corners.front(), corners.back()};
62template<
class FVElementGeometry,
class SubControlVolumeFace>
63typename SubControlVolumeFace::Traits::Geometry scvfGeometry(
const FVElementGeometry& fvGeometry,
64 const SubControlVolumeFace& scvf)
66 const auto normalAxis = scvf.normalAxis();
67 const auto center = scvf.center();
68 const auto shift = scvf.ipGlobal() -
center;
70 const auto insideElementIndex = (fvGeometry.scv(scvf.insideScvIdx())).elementIndex();
71 const auto elementGeometry = (insideElementIndex != fvGeometry.elementIndex()) ?
72 fvGeometry.element().geometry() :
73 fvGeometry.gridGeometry().element(insideElementIndex).geometry();
75 auto corners = std::array{
76 elementGeometry.corner(0),
77 elementGeometry.corner(elementGeometry.corners() - 1)
81 for (
int i = 0; i < corners.size(); ++i)
83 auto& corner = corners[i];
84 corner[normalAxis] =
center[normalAxis];
85 if (scvf.isLateral() && (corner - center)*shift < 0.0)
86 corner[dofAxis] = elementGeometry.center()[dofAxis];
89 auto inPlaneAxes = std::move(std::bitset<SubControlVolumeFace::Traits::dimWorld>{}.set());
90 inPlaneAxes.set(normalAxis,
false);
92 return {corners[0], corners[1], inPlaneAxes};
96template<
class FVElementGeometry,
class SubControlVolume>
97const SubControlVolume& outsidePeriodicScv(
const FVElementGeometry& fvGeometry,
98 const SubControlVolume& selfScv)
100 assert(fvGeometry.gridGeometry().dofOnPeriodicBoundary(selfScv.dofIndex()));
102 auto localOppositeIndex = FVElementGeometry::GridGeometry::GeometryHelper::localOppositeIdx(selfScv.localDofIndex());
103 const auto& normalScvf = std::next(scvfs(fvGeometry, selfScv).begin());
106 const auto& orthogonalScvf = fvGeometry.lateralOrthogonalScvf(*normalScvf);
107 const auto orthogonalOutsideScv = fvGeometry.scv(orthogonalScvf.outsideScvIdx());
109 auto outsidePeriodicFVGeometry =
localView(fvGeometry.gridGeometry());
110 const auto& periodicElement = fvGeometry.gridGeometry().element(orthogonalOutsideScv.elementIndex());
111 outsidePeriodicFVGeometry.bindElement(periodicElement);
113 for (
const auto& outerPeriodicScv : scvs(outsidePeriodicFVGeometry))
114 if (outerPeriodicScv.localDofIndex() == localOppositeIndex)
115 return outerPeriodicScv;
117 DUNE_THROW(Dune::InvalidStateException,
"No outside periodic scv found");
123template<
class GG,
bool cachingEnabled>
135 using GridView =
typename GG::GridView;
137 static constexpr auto numScvsPerElement = GG::StaticInformation::numScvsPerElement;
141 using SubControlVolume =
typename GG::SubControlVolume;
142 using SubControlVolumeFace =
typename GG::SubControlVolumeFace;
143 using Element =
typename GridView::template Codim<0>::Entity;
144 using GridGeometry = GG;
147 static constexpr std::size_t maxNumElementScvs = numScvsPerElement;
150 : gridGeometry_(&gridGeometry)
154 const SubControlVolume& scv(GridIndexType scvIdx)
const
155 {
return gridGeometry().scv(scvIdx); }
158 const SubControlVolumeFace& scvf(GridIndexType scvfIdx)
const
159 {
return gridGeometry().scvf(scvfIdx); }
162 const SubControlVolumeFace& lateralOrthogonalScvf(
const SubControlVolumeFace& scvf)
const
164 assert(scvf.isLateral());
165 const auto otherGlobalIdx = scvfIndices_()[GridGeometry::GeometryHelper::lateralOrthogonalScvfLocalIndex(scvf.localIndex())];
166 return gridGeometry().scvf(otherGlobalIdx);
171 const SubControlVolumeFace& frontalScvfOnBoundary(
const SubControlVolume& scv)
const
173 assert(scv.boundary());
176 auto scvfIter = scvfs(*
this, scv).begin();
177 const auto end = scvfs(*
this, scv).end();
178 while (!(scvfIter->isFrontal() && scvfIter->boundary()) && (scvfIter != end))
181 assert(scvfIter->isFrontal());
182 assert(scvfIter->boundary());
192 scvs(
const FaceCenteredStaggeredFVElementGeometry& fvGeometry)
193 {
return fvGeometry.gridGeometry().scvs(fvGeometry); }
201 scvfs(
const FaceCenteredStaggeredFVElementGeometry& fvGeometry)
203 using IndexContainerType = std::decay_t<
decltype(fvGeometry.scvfIndices_())>;
204 using ScvfIterator = Dumux::ScvfIterator<SubControlVolumeFace, IndexContainerType, ThisType>;
205 return Dune::IteratorRange<ScvfIterator>(ScvfIterator(fvGeometry.scvfIndices_().begin(), fvGeometry),
206 ScvfIterator(fvGeometry.scvfIndices_().end(), fvGeometry));
215 scvfs(
const FaceCenteredStaggeredFVElementGeometry& fvGeometry,
const SubControlVolume& scv)
217 using IndexContainerType = std::decay_t<
decltype(fvGeometry.scvfIndices_())>;
218 using ScvfIterator = Dumux::SkippingScvfIterator<SubControlVolumeFace, IndexContainerType, ThisType>;
219 auto begin = ScvfIterator::makeBegin(fvGeometry.scvfIndices_(), fvGeometry, scv.index());
220 auto end = ScvfIterator::makeEnd(fvGeometry.scvfIndices_(), fvGeometry, scv.index());
221 return Dune::IteratorRange<ScvfIterator>(begin, end);
225 std::size_t numScv()
const
226 {
return numScvsPerElement; }
229 std::size_t numScvf()
const
230 {
return scvfIndices_().size(); }
233 bool hasBoundaryScvf()
const
234 {
return gridGeometry().hasBoundaryScvf(eIdx_); }
241 FaceCenteredStaggeredFVElementGeometry bind(
const Element& element) &&
244 return std::move(*
this);
248 void bind(
const Element& element) &
249 { this->bindElement(element); }
256 FaceCenteredStaggeredFVElementGeometry bindElement(
const Element& element) &&
258 this->bindElement(element);
259 return std::move(*
this);
263 void bindElement(
const Element& element) &
266 eIdx_ = gridGeometry().elementMapper().index(element);
270 const GridGeometry& gridGeometry()
const
272 assert(gridGeometry_);
273 return *gridGeometry_;
276 std::size_t elementIndex()
const
281 {
return *elementPtr_; }
284 bool scvfIntegrationPointInConcaveCorner(
const SubControlVolumeFace& scvf)
const
285 {
return GG::GeometryHelper::scvfIntegrationPointInConcaveCorner(*
this, scvf); }
288 const SubControlVolumeFace& outsideScvfWithSameIntegrationPoint(
const SubControlVolumeFace& scvf)
const
290 const auto& lateralOrthogonalScvf = this->lateralOrthogonalScvf(scvf);
291 assert(!lateralOrthogonalScvf.boundary());
293 const auto otherLocalIdx = GG::GeometryHelper::localIndexOutsideScvfWithSameIntegrationPoint(scvf, scv(scvf.insideScvIdx()));
295 auto outsideFVGeometry =
localView(gridGeometry());
296 const auto outsideElementIdx = scv(lateralOrthogonalScvf.outsideScvIdx()).elementIndex();
297 outsideFVGeometry.bindElement(gridGeometry().
element(outsideElementIdx));
299 for (
const auto& otherScvf : scvfs(outsideFVGeometry))
300 if (otherScvf.localIndex() == otherLocalIdx)
303 DUNE_THROW(Dune::InvalidStateException,
"No outside scvf found");
307 const SubControlVolume& outsidePeriodicScv(
const SubControlVolume& selfScv)
const
309 return Detail::FCStaggered::outsidePeriodicScv(*
this, selfScv);
313 typename SubControlVolume::Traits::Geometry geometry(
const SubControlVolume& scv)
const
315 return Detail::FCStaggered::scvGeometry(*
this, scv);
319 typename SubControlVolumeFace::Traits::Geometry geometry(
const SubControlVolumeFace& scvf)
const
321 return Detail::FCStaggered::scvfGeometry(*
this, scvf);
326 const auto& scvfIndices_()
const
328 return gridGeometry().scvfIndicesOfElement(eIdx_);
331 const Element* elementPtr_;
333 const GridGeometry* gridGeometry_;
344 using ThisType = FaceCenteredStaggeredFVElementGeometry<GG,
false>;
346 using GridView =
typename GG::GridView;
351 using StaticInfo =
typename GG::StaticInformation;
352 static constexpr auto dim = StaticInfo::dim;
353 static constexpr auto numScvsPerElement = StaticInfo::numScvsPerElement;
354 static constexpr auto numLateralScvfsPerScv = StaticInfo::numLateralScvfsPerScv;
355 static constexpr auto numLateralScvfsPerElement = StaticInfo::numLateralScvfsPerElement;
356 static constexpr auto minNumScvfsPerElement = StaticInfo::minNumScvfsPerElement;
357 static constexpr auto maxNumScvfsPerElement = StaticInfo::maxNumScvfsPerElement;
363 using SubControlVolume =
typename GG::SubControlVolume;
364 using SubControlVolumeFace =
typename GG::SubControlVolumeFace;
365 using Element =
typename GridView::template Codim<0>::Entity;
366 using GridGeometry = GG;
369 static constexpr std::size_t maxNumElementScvs = numScvsPerElement;
371 FaceCenteredStaggeredFVElementGeometry(
const GridGeometry& gridGeometry)
372 : gridGeometry_(&gridGeometry)
373 , geometryHelper_(gridGeometry.gridView())
377 const SubControlVolumeFace& scvf(
const GridIndexType scvfIdx)
const
378 {
return scvfs_[findLocalIndex_(scvfIdx, scvfIndices_())]; }
386 scvfs(
const FaceCenteredStaggeredFVElementGeometry& fvGeometry)
388 using Iter =
typename decltype(fvGeometry.scvfs_)::const_iterator;
389 return Dune::IteratorRange<Iter>(fvGeometry.scvfs_.begin(), fvGeometry.scvfs_.end());
398 scvfs(
const FaceCenteredStaggeredFVElementGeometry& fvGeometry,
const SubControlVolume& scv)
400 using IndexContainerType = std::decay_t<
decltype(fvGeometry.scvfIndices_())>;
401 using ScvfIterator = Dumux::SkippingScvfIterator<SubControlVolumeFace, IndexContainerType, ThisType>;
402 auto begin = ScvfIterator::makeBegin(fvGeometry.scvfIndices_(), fvGeometry, scv.index());
403 auto end = ScvfIterator::makeEnd(fvGeometry.scvfIndices_(), fvGeometry, scv.index());
404 return Dune::IteratorRange<ScvfIterator>(begin, end);
408 const SubControlVolume& scv(
const GridIndexType scvIdx)
const
410 if (scvIdx >= scvIndicesOfElement_.front() && scvIdx <= scvIndicesOfElement_.back())
411 return scvs_[findLocalIndex_(scvIdx, scvIndicesOfElement_)];
413 return neighborScvs_[findLocalIndex_(scvIdx, neighborScvIndices_)];
422 scvs(
const FaceCenteredStaggeredFVElementGeometry& g)
424 using IteratorType =
typename std::array<SubControlVolume, 1>::const_iterator;
425 return Dune::IteratorRange<IteratorType>(g.scvs_.begin(), g.scvs_.end());
429 const SubControlVolumeFace& lateralOrthogonalScvf(
const SubControlVolumeFace& scvf)
const
431 assert(scvf.isLateral());
432 const auto otherLocalIdx = GridGeometry::GeometryHelper::lateralOrthogonalScvfLocalIndex(scvf.localIndex());
433 return scvfs_[otherLocalIdx];
437 const SubControlVolumeFace& frontalScvfOnBoundary(
const SubControlVolume& scv)
const
439 assert(scv.boundary());
442 auto scvfIter = scvfs(*
this, scv).begin();
443 const auto end = scvfs(*
this, scv).end();
444 while (!(scvfIter->isFrontal() && scvfIter->boundary()) && (scvfIter != end))
447 assert(scvfIter->isFrontal());
448 assert(scvfIter->boundary());
453 bool hasBoundaryScvf()
const
454 {
return gridGeometry().hasBoundaryScvf(eIdx_); }
457 std::size_t numScv()
const
458 {
return numScvsPerElement; }
461 std::size_t numScvf()
const
462 {
return scvfIndices_().size(); }
469 FaceCenteredStaggeredFVElementGeometry bind(
const Element& element) &&
471 this->bind_(element);
472 return std::move(*
this);
475 void bind(
const Element& element) &
476 { this->bind_(element); }
483 FaceCenteredStaggeredFVElementGeometry bindElement(
const Element& element) &&
485 typename GG::LocalIntersectionMapper localIsMapper;
486 localIsMapper.update(gridGeometry().gridView(), element);
487 this->bindElement_(element, localIsMapper);
488 return std::move(*
this);
491 void bindElement(
const Element& element) &
493 typename GG::LocalIntersectionMapper localIsMapper;
494 localIsMapper.update(gridGeometry().gridView(), element);
495 this->bindElement_(element, localIsMapper);
498 GridIndexType elementIndex()
const
503 {
return *elementPtr_; }
506 const GridGeometry& gridGeometry()
const
508 assert(gridGeometry_);
509 return *gridGeometry_;
513 bool scvfIntegrationPointInConcaveCorner(
const SubControlVolumeFace& scvf)
const
514 {
return GG::GeometryHelper::scvfIntegrationPointInConcaveCorner(*
this, scvf); }
518 SubControlVolumeFace outsideScvfWithSameIntegrationPoint(
const SubControlVolumeFace& scvf)
const
520 const SubControlVolumeFace& lateralOrthogonalScvf = this->lateralOrthogonalScvf(scvf);
521 assert(!lateralOrthogonalScvf.boundary());
523 const auto otherLocalIdx = GG::GeometryHelper::localIndexOutsideScvfWithSameIntegrationPoint(scvf, scv(scvf.insideScvIdx()));
525 auto outsideFVGeometry =
localView(gridGeometry());
526 const auto outsideElementIdx = scv(lateralOrthogonalScvf.outsideScvIdx()).elementIndex();
527 outsideFVGeometry.bindElement(gridGeometry().
element(outsideElementIdx));
529 for (
const auto& otherScvf : scvfs(outsideFVGeometry))
530 if (otherScvf.localIndex() == otherLocalIdx)
533 DUNE_THROW(Dune::InvalidStateException,
"No outside scvf found");
537 SubControlVolume outsidePeriodicScv(
const SubControlVolume& selfScv)
const
539 return Detail::FCStaggered::outsidePeriodicScv(*
this, selfScv);
543 typename SubControlVolume::Traits::Geometry geometry(
const SubControlVolume& scv)
const
545 return Detail::FCStaggered::scvGeometry(*
this, scv);
549 typename SubControlVolumeFace::Traits::Geometry geometry(
const SubControlVolumeFace& scvf)
const
551 return Detail::FCStaggered::scvfGeometry(*
this, scvf);
557 void bind_(
const Element& element)
559 typename GG::LocalIntersectionMapper localIsMapper;
560 localIsMapper.update(gridGeometry().gridView(), element);
562 bindElement_(element, localIsMapper);
563 neighborScvIndices_.clear();
564 neighborScvs_.clear();
566 for (
const auto& intersection : intersections(gridGeometry().gridView(), element))
568 if (intersection.neighbor())
570 const auto localScvIdx = localIsMapper.realToRefIdx(intersection.indexInInside());
571 const auto localOppositeScvIdx = geometryHelper_.localOppositeIdx(localScvIdx);
572 const auto& neighborElement = intersection.outside();
573 const auto neighborElementIdx = gridGeometry().elementMapper().index(neighborElement);
574 const auto& neighborElementGeometry = neighborElement.geometry();
577 std::array<GridIndexType, numScvsPerElement> globalScvIndicesOfNeighborElement;
578 std::iota(globalScvIndicesOfNeighborElement.begin(), globalScvIndicesOfNeighborElement.end(), neighborElementIdx*numScvsPerElement);
580 typename GG::LocalIntersectionMapper localNeighborIsMapper;
581 localNeighborIsMapper.update(gridGeometry().gridView(), neighborElement);
583 for (
const auto& neighborIntersection : intersections(gridGeometry().gridView(), neighborElement))
585 const auto localNeighborScvIdx = localNeighborIsMapper.realToRefIdx(neighborIntersection.indexInInside());
586 if (localNeighborScvIdx != localScvIdx && localNeighborScvIdx != localOppositeScvIdx)
589 const auto dofIndex = gridGeometry().intersectionMapper().globalIntersectionIndex(neighborElement, neighborIntersection.indexInInside());
590 neighborScvs_.push_back(SubControlVolume(
591 neighborElementGeometry,
592 neighborIntersection.geometry(),
593 globalScvIndicesOfNeighborElement[localNeighborScvIdx],
598 onDomainBoundary_(neighborIntersection)
601 neighborScvIndices_.push_back(globalScvIndicesOfNeighborElement[localNeighborScvIdx]);
609 void bindElement_(
const Element& element,
const typename GG::LocalIntersectionMapper& localIsMapper)
612 eIdx_ = gridGeometry().elementMapper().index(element);
613 std::iota(scvIndicesOfElement_.begin(), scvIndicesOfElement_.end(), eIdx_*numScvsPerElement);
615 scvfs_.resize(minNumScvfsPerElement);
617 const auto& elementGeometry =
element.geometry();
619 for (
const auto& intersection : intersections(gridGeometry().gridView(), element))
621 const auto localScvIdx = localIsMapper.realToRefIdx(intersection.indexInInside());
622 auto localScvfIdx = localScvIdx*(1 + numLateralScvfsPerScv);
623 const auto& intersectionGeometry = intersection.geometry();
624 const auto dofIndex = gridGeometry().intersectionMapper().globalIntersectionIndex(element, intersection.indexInInside());
626 scvs_[localScvIdx] = SubControlVolume(
628 intersectionGeometry,
629 scvIndicesOfElement_[localScvIdx],
634 onDomainBoundary_(intersection)
638 const auto localOppositeScvIdx = geometryHelper_.localOppositeIdx(localScvIdx);
639 scvfs_[localScvfIdx] = SubControlVolumeFace(
641 intersectionGeometry,
642 std::array{scvIndicesOfElement_[localScvIdx], scvIndicesOfElement_[localOppositeScvIdx]},
644 scvfIndices_()[localScvfIdx],
645 intersection.centerUnitOuterNormal(),
646 SubControlVolumeFace::FaceType::frontal,
647 SubControlVolumeFace::BoundaryType::interior
652 for (
const auto lateralFacetIndex : Dune::transformedRangeView(geometryHelper_.localLaterFaceIndices(localScvIdx),
653 [&](
auto&& idx) { return localIsMapper.refToRealIdx(idx) ;})
656 const auto& lateralIntersection = geometryHelper_.intersection(lateralFacetIndex, element);
657 const auto& lateralFacet = geometryHelper_.facet(lateralFacetIndex, element);
658 const auto& lateralFacetGeometry = lateralFacet.geometry();
661 const auto globalScvIndicesForLateralFace = [&]
663 const auto globalOutsideScvIdx = [&]
665 if (lateralIntersection.neighbor())
667 const auto parallelElemIdx = gridGeometry().elementMapper().index(lateralIntersection.outside());
669 std::array<GridIndexType, numScvsPerElement> globalScvIndicesOfNeighborElement;
670 std::iota(globalScvIndicesOfNeighborElement.begin(), globalScvIndicesOfNeighborElement.end(), parallelElemIdx*numScvsPerElement);
671 return globalScvIndicesOfNeighborElement[localScvIdx];
674 return gridGeometry().outsideVolVarIndex(scvfIndices_()[localScvfIdx]);
677 return std::array{scvIndicesOfElement_[localScvIdx], globalOutsideScvIdx};
680 const auto boundaryType = [&]
682 if (onProcessorBoundary_(lateralIntersection))
683 return SubControlVolumeFace::BoundaryType::processorBoundary;
684 else if (onDomainBoundary_(lateralIntersection))
685 return SubControlVolumeFace::BoundaryType::physicalBoundary;
687 return SubControlVolumeFace::BoundaryType::interior;
690 scvfs_[localScvfIdx] = SubControlVolumeFace(
692 intersectionGeometry,
693 lateralFacetGeometry,
694 globalScvIndicesForLateralFace,
696 scvfIndices_()[localScvfIdx],
697 lateralIntersection.centerUnitOuterNormal(),
698 SubControlVolumeFace::FaceType::lateral,
706 auto localScvfIdx = minNumScvfsPerElement;
707 for (
const auto& intersection : intersections(gridGeometry().gridView(), element))
710 if (onDomainBoundary_(intersection))
712 const auto localScvIdx = localIsMapper.realToRefIdx(intersection.indexInInside());
714 scvfs_.push_back(SubControlVolumeFace(
716 intersection.geometry(),
717 std::array{scvIndicesOfElement_[localScvIdx], scvIndicesOfElement_[localScvIdx]},
719 scvfIndices_()[localScvfIdx],
720 intersection.centerUnitOuterNormal(),
721 SubControlVolumeFace::FaceType::frontal,
722 SubControlVolumeFace::BoundaryType::physicalBoundary
728 if constexpr (!ConsistentlyOrientedGrid<typename GridView::Grid>{})
730 static const bool makeConsistentlyOriented =
getParam<bool>(
"Grid.MakeConsistentlyOriented",
true);
731 if (makeConsistentlyOriented && scvfs_.size() > minNumScvfsPerElement)
734 std::sort(scvfs_.begin() + minNumScvfsPerElement, scvfs_.end(),
735 [](
const auto& scvfLeft,
const auto& scvfRight)
736 { return scvfLeft.insideScvIdx() < scvfRight.insideScvIdx(); }
742 const auto& scvfIndices_()
const
743 {
return gridGeometry().scvfIndicesOfElement(eIdx_); }
745 template<
class Entry,
class Container>
746 const LocalIndexType findLocalIndex_(
const Entry& entry,
747 const Container& container)
const
749 auto it = std::find(container.begin(), container.end(), entry);
750 assert(it != container.end() &&
"Could not find the entry! Make sure to properly bind this class!");
751 return std::distance(container.begin(), it);
754 bool onDomainBoundary_(
const typename GridView::Intersection& intersection)
const
756 return !intersection.neighbor() && intersection.boundary();
759 bool onProcessorBoundary_(
const typename GridView::Intersection& intersection)
const
761 return !intersection.neighbor() && !intersection.boundary();
764 Dune::ReservedVector<SubControlVolumeFace, maxNumScvfsPerElement> scvfs_;
766 Dune::ReservedVector<SubControlVolume, numLateralScvfsPerElement> neighborScvs_;
767 Dune::ReservedVector<GridIndexType, numLateralScvfsPerElement> neighborScvIndices_;
769 std::array<SubControlVolume, numScvsPerElement> scvs_;
770 std::array<GridIndexType, numScvsPerElement> scvIndicesOfElement_;
772 const GridGeometry* gridGeometry_;
773 const Element* elementPtr_;
775 typename GridGeometry::GeometryHelper geometryHelper_;
Definition discretization/facecentered/staggered/fvelementgeometry.hh:124
Helper type to determine whether a grid is guaranteed to be oriented consistently....
GridCache::LocalView localView(const GridCache &gridCache)
Free function to get the local view of a grid cache object.
Definition localview.hh:26
static std::size_t normalAxis(const Vector &v)
Returns the normal axis index of a unit vector (0 = x, 1 = y, 2 = z)
Definition normalaxis.hh:26
Corners::value_type center(const Corners &corners)
The center of a given list of corners.
Definition center.hh:24
T getParam(Args &&... args)
A free function to get a parameter from the parameter tree singleton.
Definition parameters.hh:139
Base class for the finite volume geometry vector for face-centered staggered models This builds up th...
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.
Class providing iterators over sub control volumes and sub control volume faces of an element.
typename GridView::IndexSet::IndexType GridIndex
Definition indextraits.hh:27
unsigned int LocalIndex
Definition indextraits.hh:28