14#ifndef DUMUX_DISCRETIZATION_CCMPFA_FV_ELEMENT_GEOMETRY_HH
15#define DUMUX_DISCRETIZATION_CCMPFA_FV_ELEMENT_GEOMETRY_HH
20#include <dune/common/exceptions.hh>
21#include <dune/common/iteratorrange.hh>
22#include <dune/geometry/type.hh>
31namespace Detail::Mpfa {
33template<
typename Gr
idGeometry,
typename SubControlVolumeFace>
34typename SubControlVolumeFace::Traits::Geometry makeScvfGeometry(
const GridGeometry& gridGeometry,
35 const SubControlVolumeFace& scvf)
37 static constexpr int dim = GridGeometry::GridView::dimension;
39 const auto& facetInfo = scvf.facetInfo();
40 const auto element = gridGeometry.element(facetInfo.elementIndex);
41 const auto elemGeo =
element.geometry();
42 const auto refElement = referenceElement(elemGeo);
43 for (
const auto& is : intersections(gridGeometry.gridView(), element))
45 if (is.indexInInside() == facetInfo.facetIndex)
47 const auto numCorners = is.geometry().corners();
48 const auto isPositions = GridGeometry::MpfaHelper::computeScvfCornersOnIntersection(
49 elemGeo, refElement, facetInfo.facetIndex,
numCorners
52 Dune::GeometryTypes::cube(dim-1),
53 GridGeometry::MpfaHelper::getScvfCorners(
54 isPositions,
numCorners, facetInfo.facetCornerIndex
59 DUNE_THROW(Dune::InvalidStateException,
"Could not construct scvf geometry");
62template<
typename Gr
idGeometry,
typename SubControlVolumeFace>
63auto getVertexCorner(
const GridGeometry& gridGeometry,
const SubControlVolumeFace& scvf)
65 static constexpr int dim = GridGeometry::GridView::dimension;
67 const auto& facetInfo = scvf.facetInfo();
68 const auto element = gridGeometry.element(facetInfo.elementIndex);
69 const auto elemGeo =
element.geometry();
70 const auto refElement = referenceElement(elemGeo);
71 return elemGeo.global(refElement.position(
72 refElement.subEntity(facetInfo.facetIndex, 1, facetInfo.facetCornerIndex, dim),
77template<
typename Gr
idGeometry,
typename SubControlVolumeFace>
78auto getFacetCorner(
const GridGeometry& gridGeometry,
const SubControlVolumeFace& scvf)
80 const auto& facetInfo = scvf.facetInfo();
81 const auto element = gridGeometry.element(facetInfo.elementIndex);
82 const auto elemGeo =
element.geometry();
83 const auto refElement = referenceElement(elemGeo);
84 return elemGeo.global(refElement.position(facetInfo.facetIndex, 1));
99template<
class GG,
bool enableGr
idGeometryCache>
112 using GridView =
typename GG::GridView;
115 static constexpr int dim = GridView::dimension;
116 static constexpr int dimWorld = GridView::dimensionworld;
120 using Element =
typename GridView::template Codim<0>::Entity;
128 static constexpr std::size_t maxNumElementScvs = 1;
130 static constexpr std::size_t maxNumElementScvfs = dim == 3 ? 24 : 8;
134 : gridGeometryPtr_(&gridGeometry) {}
139 return gridGeometry().scv(scvIdx);
145 return gridGeometry().scvf(scvfIdx);
152 return gridGeometry().flipScvf(scvfIdx, outsideScvIdx);
160 friend inline Dune::IteratorRange< ScvIterator<SubControlVolume, std::array<GridIndexType, 1>, ThisType> >
164 return Dune::IteratorRange<ScvIterator>(
ScvIterator(fvGeometry.scvIndices_.begin(), fvGeometry),
165 ScvIterator(fvGeometry.scvIndices_.end(), fvGeometry));
173 friend inline Dune::IteratorRange< ScvfIterator<SubControlVolumeFace, std::vector<GridIndexType>, ThisType> >
176 const auto& g = fvGeometry.gridGeometry();
177 const auto scvIdx = fvGeometry.scvIndices_[0];
179 return Dune::IteratorRange<ScvfIterator>(
ScvfIterator(g.scvfIndicesOfScv(scvIdx).begin(), fvGeometry),
180 ScvfIterator(g.scvfIndicesOfScv(scvIdx).end(), fvGeometry));
186 return scvIndices_.size();
192 return gridGeometry().scvfIndicesOfScv(scvIndices_[0]).size();
202 this->bindElement(element);
203 return std::move(*
this);
208 this->bindElement(element);
218 this->bindElement(element);
219 return std::move(*
this);
226 scvIndices_[0] = gridGeometry().elementMapper().index(element);
231 {
return static_cast<bool>(element_); }
235 {
return *element_; }
239 {
return *gridGeometryPtr_; }
243 {
return gridGeometry().hasBoundaryScvf(scvIndices_[0]); }
247 {
return gridGeometryPtr_->element(scv.dofIndex()).geometry(); }
251 {
return Detail::Mpfa::makeScvfGeometry(gridGeometry(), scvf); }
255 {
return Detail::Mpfa::getVertexCorner(gridGeometry(), scvf); }
259 {
return Detail::Mpfa::getFacetCorner(gridGeometry(), scvf); }
263 std::optional<Element> element_;
264 std::array<GridIndexType, 1> scvIndices_;
265 const GridGeometry* gridGeometryPtr_;
277 using GridView =
typename GG::GridView;
279 using MpfaHelper =
typename GG::MpfaHelper;
281 static constexpr int dim = GridView::dimension;
282 static constexpr int dimWorld = GridView::dimensionworld;
283 using CoordScalar =
typename GridView::ctype;
287 using Element =
typename GridView::template Codim<0>::Entity;
295 static constexpr std::size_t maxNumElementScvs = 1;
297 static constexpr std::size_t maxNumElementScvfs = dim == 3 ? 24 : 8;
301 : gridGeometryPtr_(&gridGeometry) {}
307 if (scvIdx == scvIndices_[0])
310 return neighborScvs_[
findLocalIndex(scvIdx, neighborScvIndices_)];
317 auto it = std::find(scvfIndices_.begin(), scvfIndices_.end(), scvfIdx);
318 if (it != scvfIndices_.end())
321 return neighborScvfs_[
findLocalIndex(scvfIdx, neighborScvfIndices_)];
328 return scvf( gridGeometry().flipScvfIdx(scvfIdx, outsideScvIdx) );
336 friend inline Dune::IteratorRange<typename std::array<SubControlVolume, 1>::const_iterator>
339 using IteratorType =
typename std::array<SubControlVolume, 1>::const_iterator;
340 return Dune::IteratorRange<IteratorType>(g.scvs_.begin(), g.scvs_.end());
348 friend inline Dune::IteratorRange<typename std::vector<SubControlVolumeFace>::const_iterator>
351 using IteratorType =
typename std::vector<SubControlVolumeFace>::const_iterator;
352 return Dune::IteratorRange<IteratorType>(g.scvfs_.begin(), g.scvfs_.end());
357 {
return scvs_.size(); }
361 {
return scvfs_.size(); }
370 this->bindElement_(element);
371 return std::move(*
this);
376 this->bindElement_(element);
386 this->bind_(element);
387 return std::move(*
this);
392 this->bind_(element);
397 {
return static_cast<bool>(element_); }
401 {
return *element_; }
405 {
return *gridGeometryPtr_; }
409 {
return hasBoundaryScvf_; }
413 {
return gridGeometryPtr_->element(scv.dofIndex()).geometry(); }
417 {
return Detail::Mpfa::makeScvfGeometry(gridGeometry(), scvf); }
421 {
return Detail::Mpfa::getVertexCorner(gridGeometry(), scvf); }
425 {
return Detail::Mpfa::getFacetCorner(gridGeometry(), scvf); }
431 void bind_(
const Element& element)
434 bindElement_(element);
437 const auto globalI = gridGeometry().elementMapper().index(element);
438 const auto& assemblyMapI = gridGeometry().connectivityMap()[globalI];
441 const auto numNeighbors = assemblyMapI.size();
442 const auto numNeighborScvfs = numNeighborScvfs_(assemblyMapI);
443 neighborScvs_.reserve(numNeighbors);
444 neighborScvIndices_.reserve(numNeighbors);
445 neighborScvfIndices_.reserve(numNeighborScvfs);
446 neighborScvfs_.reserve(numNeighborScvfs);
450 for (
const auto& dataJ : assemblyMapI)
451 makeNeighborGeometries(gridGeometry().element(dataJ.globalJ),
454 dataJ.additionalScvfs);
473 void bindElement_(
const Element& element)
477 makeElementGeometries(element);
481 template<
class DataJContainer>
482 std::size_t numNeighborScvfs_(
const DataJContainer& dataJContainer)
484 std::size_t numNeighborScvfs = 0;
485 for (
const auto& dataJ : dataJContainer)
486 numNeighborScvfs += dataJ.scvfsJ.size() + dataJ.additionalScvfs.size();
487 return numNeighborScvfs;
491 void makeElementGeometries(
const Element& element)
494 const auto eIdx = gridGeometry().elementMapper().index(element);
495 scvs_[0] = SubControlVolume(
element.geometry(), eIdx);
496 scvIndices_[0] = eIdx;
499 const auto& scvFaceIndices = gridGeometry().scvfIndicesOfScv(eIdx);
500 const auto& neighborVolVarIndices = gridGeometry().neighborVolVarIndices(eIdx);
503 static const auto q = getParam<CoordScalar>(
"MPFA.Q");
506 const auto numLocalScvf = scvFaceIndices.size();
507 scvfIndices_.reserve(numLocalScvf);
508 scvfs_.reserve(numLocalScvf);
512 std::vector<bool> finishedFacets;
514 finishedFacets.resize(
element.subEntities(1),
false);
517 for (
const auto& is : intersections(gridGeometry().gridView(), element))
523 const auto indexInInside = is.indexInInside();
524 if (finishedFacets[indexInInside])
527 finishedFacets[indexInInside] =
true;
531 bool useNeighbor = is.neighbor() && is.outside().level() >
element.level();
532 const auto& e = useNeighbor ? is.outside() :
element;
533 const auto indexInElement = useNeighbor ? is.indexInOutside() : is.indexInInside();
534 const auto eg = e.geometry();
535 const auto refElement = referenceElement(eg);
538 const auto numCorners = is.geometry().corners();
539 const auto isPositions = MpfaHelper::computeScvfCornersOnIntersection(eg,
548 auto vIdxLocal = refElement.subEntity(indexInElement, 1, c, dim);
549 auto vIdxGlobal = gridGeometry().vertexMapper().subIndex(e, vIdxLocal, dim);
552 if (gridGeometry().isGhostVertex(vIdxGlobal))
555 hasBoundaryScvf_ = (hasBoundaryScvf_ || is.boundary());
556 typename SubControlVolumeFace::FacetInfo facetInfo{
557 gridGeometry().elementMapper().index(e),
558 useNeighbor ? is.indexInOutside() : is.indexInInside(),
561 scvfs_.emplace_back(MpfaHelper(),
562 MpfaHelper::getScvfCorners(isPositions,
numCorners, c),
564 std::move(facetInfo),
567 scvFaceIndices[scvfCounter],
569 neighborVolVarIndices[scvfCounter],
573 scvfIndices_.emplace_back(scvFaceIndices[scvfCounter]);
580 template<
typename IndexVector>
581 void makeNeighborGeometries(
const Element& element,
582 GridIndexType eIdxGlobal,
583 const IndexVector& scvfIndices,
584 const IndexVector& additionalScvfs)
587 neighborScvs_.emplace_back(
element.geometry(), eIdxGlobal);
588 neighborScvIndices_.push_back(eIdxGlobal);
591 const auto& scvFaceIndices = gridGeometry().scvfIndicesOfScv(eIdxGlobal);
592 const auto& neighborVolVarIndices = gridGeometry().neighborVolVarIndices(eIdxGlobal);
595 static const auto q = getParam<CoordScalar>(
"MPFA.Q");
599 std::vector<bool> finishedFacets;
601 finishedFacets.resize(
element.subEntities(1),
false);
604 for (
const auto& is : intersections(gridGeometry().gridView(), element))
610 auto indexInInside = is.indexInInside();
611 if(finishedFacets[indexInInside])
614 finishedFacets[indexInInside] =
true;
618 bool useNeighbor = is.neighbor() && is.outside().level() >
element.level();
619 const auto& e = useNeighbor ? is.outside() :
element;
620 const auto indexInElement = useNeighbor ? is.indexInOutside() : is.indexInInside();
621 const auto eg = e.geometry();
622 const auto refElement = referenceElement(eg);
625 const auto numCorners = is.geometry().corners();
626 const auto isPositions = MpfaHelper::computeScvfCornersOnIntersection(eg,
635 auto vIdxLocal = refElement.subEntity(indexInElement, 1, c, dim);
636 auto vIdxGlobal = gridGeometry().vertexMapper().subIndex(e, vIdxLocal, dim);
639 if (gridGeometry().isGhostVertex(vIdxGlobal))
643 if (!MpfaHelper::vectorContainsValue(scvfIndices, scvFaceIndices[scvfCounter])
644 && !MpfaHelper::vectorContainsValue(additionalScvfs, scvFaceIndices[scvfCounter]))
652 typename SubControlVolumeFace::FacetInfo facetInfo{
653 gridGeometry().elementMapper().index(e),
654 useNeighbor ? is.indexInOutside() : is.indexInInside(),
657 neighborScvfs_.emplace_back(MpfaHelper(),
658 MpfaHelper::getScvfCorners(isPositions,
numCorners, c),
660 std::move(facetInfo),
663 scvFaceIndices[scvfCounter],
665 neighborVolVarIndices[scvfCounter],
669 neighborScvfIndices_.emplace_back(scvFaceIndices[scvfCounter]);
679 const std::vector<GridIndexType>& indices)
const
681 auto it = std::find(indices.begin(), indices.end(), idx);
682 assert(it != indices.end() &&
"Could not find the scv/scvf! Make sure to properly bind this class!");
689 scvfIndices_.clear();
692 neighborScvIndices_.clear();
693 neighborScvfIndices_.clear();
694 neighborScvs_.clear();
695 neighborScvfs_.clear();
697 hasBoundaryScvf_ =
false;
700 const GridGeometry* gridGeometryPtr_;
701 std::optional<Element> element_;
704 std::array<GridIndexType, 1> scvIndices_;
705 std::vector<GridIndexType> scvfIndices_;
706 std::array<SubControlVolume, 1> scvs_;
707 std::vector<SubControlVolumeFace> scvfs_;
709 std::vector<GridIndexType> neighborScvIndices_;
710 std::vector<GridIndexType> neighborScvfIndices_;
711 std::vector<SubControlVolume> neighborScvs_;
712 std::vector<SubControlVolumeFace> neighborScvfs_;
714 bool hasBoundaryScvf_ =
false;
Stencil-local finite volume geometry (scvs and scvfs) for cell-centered TPFA models Specialization fo...
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:275
const SubControlVolumeFace & scvf(GridIndexType scvfIdx) const
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:315
const SubControlVolume & scv(GridIndexType scvIdx) const
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:305
friend Dune::IteratorRange< typename std::vector< SubControlVolumeFace >::const_iterator > scvfs(const ThisType &g)
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:349
SubControlVolume::Traits::Geometry geometry(const SubControlVolume &scv) const
Create the geometry of a given sub control volume.
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:412
void bindElement(const Element &element) &
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:374
const GridGeometry & gridGeometry() const
The global finite volume geometry we are a restriction of.
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:404
CCMpfaFVElementGeometry bind(const Element &element) &&
bind the local view (r-value overload) This overload is called when an instance of this class is a te...
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:384
SubControlVolumeFace::Traits::GlobalPosition vertexCorner(const SubControlVolumeFace &scvf) const
Return the position of the scvf corner that coincides with an element vertex.
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:420
const SubControlVolumeFace & flipScvf(GridIndexType scvfIdx, unsigned int outsideScvIdx=0) const
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:326
typename GG::SubControlVolume SubControlVolume
export type of subcontrol volume
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:289
typename GridView::template Codim< 0 >::Entity Element
export type of the element
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:287
std::size_t numScv() const
number of sub control volumes in this fv element geometry
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:356
typename GG::SubControlVolumeFace SubControlVolumeFace
export type of subcontrol volume face
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:291
SubControlVolumeFace::Traits::GlobalPosition facetCorner(const SubControlVolumeFace &scvf) const
Return the corner of the scvf that is inside the facet the scvf is embedded in.
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:424
const Element & element() const
The bound element.
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:400
bool isBound() const
Returns true if bind/bindElement has already been called.
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:396
void bind(const Element &element) &
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:390
CCMpfaFVElementGeometry bindElement(const Element &element) &&
bind the local view (r-value overload) This overload is called when an instance of this class is a te...
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:368
std::size_t numScvf() const
number of sub control volumes in this fv element geometry
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:360
bool hasBoundaryScvf() const
Returns whether one of the geometry's scvfs lies on a boundary.
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:408
SubControlVolumeFace::Traits::Geometry geometry(const SubControlVolumeFace &scvf) const
Create the geometry of a given sub control volume face.
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:416
GG GridGeometry
export type of finite volume grid geometries
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:293
friend Dune::IteratorRange< typename std::array< SubControlVolume, 1 >::const_iterator > scvs(const ThisType &g)
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:337
CCMpfaFVElementGeometry(const GridGeometry &gridGeometry)
Constructor.
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:300
Stencil-local finite volume geometry (scvs and scvfs) for cell-centered mpfa models Specialization fo...
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:110
const SubControlVolume & scv(GridIndexType scvIdx) const
Get an element sub control volume with a global scv index.
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:137
CCMpfaFVElementGeometry bindElement(const Element &element) &&
bind the local view (r-value overload) This overload is called when an instance of this class is a te...
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:216
SubControlVolumeFace::Traits::Geometry geometry(const SubControlVolumeFace &scvf) const
Create the geometry of a given sub control volume face.
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:250
Element::Geometry geometry(const SubControlVolume &scv) const
Create the geometry of a given sub control volume.
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:246
void bindElement(const Element &element) &
Bind only element-local.
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:223
std::size_t numScvf() const
number of sub control volumes in this fv element geometry
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:190
CCMpfaFVElementGeometry(const GridGeometry &gridGeometry)
Constructor.
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:133
const Element & element() const
The bound element.
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:234
CCMpfaFVElementGeometry bind(const Element &element) &&
bind the local view (r-value overload) This overload is called when an instance of this class is a te...
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:200
bool isBound() const
Returns true if bind/bindElement has already been called.
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:230
friend Dune::IteratorRange< ScvIterator< SubControlVolume, std::array< GridIndexType, 1 >, ThisType > > scvs(const CCMpfaFVElementGeometry &fvGeometry)
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:161
void bind(const Element &element) &
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:206
bool hasBoundaryScvf() const
Returns whether one of the geometry's scvfs lies on a boundary.
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:242
typename GG::SubControlVolumeFace SubControlVolumeFace
export type of subcontrol volume face
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:124
friend Dune::IteratorRange< ScvfIterator< SubControlVolumeFace, std::vector< GridIndexType >, ThisType > > scvfs(const CCMpfaFVElementGeometry &fvGeometry)
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:174
const SubControlVolumeFace & scvf(GridIndexType scvfIdx) const
Get an element sub control volume face with a global scvf index.
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:143
const SubControlVolumeFace & flipScvf(GridIndexType scvfIdx, unsigned int outsideScvIdx=0) const
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:150
SubControlVolumeFace::Traits::GlobalPosition vertexCorner(const SubControlVolumeFace &scvf) const
Return the position of the scvf corner that coincides with an element vertex.
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:254
const GridGeometry & gridGeometry() const
The global finite volume geometry we are a restriction of.
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:238
std::size_t numScv() const
number of sub control volumes in this fv element geometry
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:184
typename GridView::template Codim< 0 >::Entity Element
export type of the element
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:120
typename GG::SubControlVolume SubControlVolume
export type of subcontrol volume
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:122
SubControlVolumeFace::Traits::GlobalPosition facetCorner(const SubControlVolumeFace &scvf) const
Return the corner of the scvf that is inside the facet the scvf is embedded in.
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:258
GG GridGeometry
export type of finite volume grid geometry
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:126
Stencil-local finite volume geometry (scvs and scvfs) for cell-centered mpfa models This builds up th...
Definition: discretization/cellcentered/mpfa/fvelementgeometry.hh:100
Iterators over sub control volumes.
Definition: scvandscvfiterators.hh:30
Iterators over sub control volume faces of an fv geometry.
Definition: scvandscvfiterators.hh:70
static ctype distance(const Dune::FieldVector< ctype, dimWorld > &a, const Dune::FieldVector< ctype, dimWorld > &b)
Compute the shortest distance between two points.
Definition: distance.hh:282
auto findLocalIndex(const GridIndexType idx, const std::vector< GridIndexType > &indices)
Definition: discretization/cellcentered/tpfa/fvelementgeometry.hh:33
std::size_t numCorners(Shape shape)
Returns the number of corners of a given geometry.
Definition: throatproperties.hh:220
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