17#ifndef DUMUX_POROUSMEDIUMFLOW_BOXDFM_FV_ELEMENT_GEOMETRY_HH 
   18#define DUMUX_POROUSMEDIUMFLOW_BOXDFM_FV_ELEMENT_GEOMETRY_HH 
   23#include <dune/geometry/type.hh> 
   24#include <dune/localfunctions/lagrange/pqkfactory.hh> 
   40template<
class GG, 
bool enableGr
idGeometryCache>
 
   47    using GridView = 
typename GG::GridView;
 
   48    static constexpr int dim = GridView::dimension;
 
   49    static constexpr int dimWorld = GridView::dimensionworld;
 
   50    using GridIndexType = 
typename GridView::IndexSet::IndexType;
 
   51    using CoordScalar = 
typename GridView::ctype;
 
   52    using FeLocalBasis = 
typename GG::FeCache::FiniteElementType::Traits::LocalBasisType;
 
   55    using Element = 
typename GridView::template Codim<0>::Entity;
 
   87    friend inline Dune::IteratorRange<typename std::vector<SubControlVolume>::const_iterator>
 
   90        const auto& g = fvGeometry.gridGeometry();
 
   91        using Iter = 
typename std::vector<SubControlVolume>::const_iterator;
 
   92        return Dune::IteratorRange<Iter>(g.scvs(fvGeometry.eIdx_).begin(), g.scvs(fvGeometry.eIdx_).end());
 
 
  103    friend inline Dune::IteratorRange<typename std::vector<SubControlVolumeFace>::const_iterator>
 
  106        const auto& g = fvGeometry.gridGeometry();
 
  107        using Iter = 
typename std::vector<SubControlVolumeFace>::const_iterator;
 
  108        return Dune::IteratorRange<Iter>(g.scvfs(fvGeometry.eIdx_).begin(), g.scvfs(fvGeometry.eIdx_).end());
 
 
  113    { 
return gridGeometry().feCache().get(element_->type()).localBasis(); }
 
 
  131        return std::move(*
this);
 
 
  147        return std::move(*
this);
 
 
  164    { 
return *gridGeometryPtr_; }
 
 
  168    { 
return static_cast<bool>(element_); }
 
 
  172    { 
return *element_; }
 
 
  177        if (
scv.isOnFracture())
 
  178            DUNE_THROW(Dune::InvalidStateException, 
"The geometry object cannot be defined for fracture scvs " 
  179                                                    "because the number of known corners is insufficient. " 
  180                                                    "You can do this manually by extracting the corners from this scv " 
  181                                                    "and extruding them by the corresponding aperture. ");
 
  183        const typename GG::GeometryHelper geometryHelper(
element().
geometry());
 
  184        const auto corners = geometryHelper.getScvCorners(
scv.index());
 
  185        using ScvGeometry = 
typename SubControlVolume::Traits::Geometry;
 
  186        return { Dune::GeometryTypes::cube(ScvGeometry::mydimension), corners };
 
 
  192        if (
scvf.isOnFracture())
 
  193            DUNE_THROW(Dune::InvalidStateException, 
"The geometry object cannot be defined for fracture scvs " 
  194                                                    "because the number of known corners is insufficient. " 
  195                                                    "You can do this manually by extracting the corners from this scv " 
  196                                                    "and extruding them by the corresponding aperture. ");
 
  197        const typename GG::GeometryHelper geometryHelper(
element().
geometry());
 
  198        const auto corners = geometryHelper.getScvfCorners(
scvf.indexInElement());
 
  199        using ScvfGeometry = 
typename SubControlVolumeFace::Traits::Geometry;
 
  200        return { Dune::GeometryTypes::cube(ScvfGeometry::mydimension), corners };
 
 
  204    const GridGeometry* gridGeometryPtr_;
 
  206    std::optional<Element> element_;
 
 
  214    using GridView = 
typename GG::GridView;
 
  215    static constexpr int dim = GridView::dimension;
 
  216    static constexpr int dimWorld = GridView::dimensionworld;
 
  218    using GridIndexType = 
typename GridView::IndexSet::IndexType;
 
  220    using CoordScalar = 
typename GridView::ctype;
 
  221    using FeLocalBasis = 
typename GG::FeCache::FiniteElementType::Traits::LocalBasisType;
 
  222    using GeometryHelper = 
typename GG::GeometryHelper;
 
  225    using Element = 
typename GridView::template Codim<0>::Entity;
 
  242    { 
return scvs_[scvIdx]; }
 
 
  246    { 
return scvfs_[scvfIdx]; }
 
 
  256    friend inline Dune::IteratorRange<typename std::vector<SubControlVolume>::const_iterator>
 
  259        using Iter = 
typename std::vector<SubControlVolume>::const_iterator;
 
  260        return Dune::IteratorRange<Iter>(fvGeometry.scvs_.begin(), fvGeometry.scvs_.end());
 
 
  271    friend inline Dune::IteratorRange<typename std::vector<SubControlVolumeFace>::const_iterator>
 
  274        using Iter = 
typename std::vector<SubControlVolumeFace>::const_iterator;
 
  275        return Dune::IteratorRange<Iter>(fvGeometry.scvfs_.begin(), fvGeometry.scvfs_.end());
 
 
  280    { 
return gridGeometry().feCache().get(element_->type()).localBasis(); }
 
 
  284    { 
return scvs_.size(); }
 
 
  288    { 
return scvfs_.size(); }
 
 
  298        return std::move(*
this);
 
 
  318        return std::move(*
this);
 
 
  329        makeElementGeometries_();
 
 
  334    { 
return *gridGeometryPtr_; }
 
 
  338    { 
return static_cast<bool>(element_); }
 
 
  342    { 
return *element_; }
 
 
  347        if (
scv.isOnFracture())
 
  348            DUNE_THROW(Dune::InvalidStateException, 
"The geometry object cannot be defined for fracture scvs " 
  349                                                    "because the number of known corners is insufficient. " 
  350                                                    "You can do this manually by extracting the corners from this scv " 
  351                                                    "and extruding them by the corresponding aperture. ");
 
  354        const auto corners = geometryHelper.getScvCorners(
scv.index());
 
  355        using ScvGeometry = 
typename SubControlVolume::Traits::Geometry;
 
  356        return { Dune::GeometryTypes::cube(ScvGeometry::mydimension), corners };
 
 
  362        if (
scvf.isOnFracture())
 
  363            DUNE_THROW(Dune::InvalidStateException, 
"The geometry object cannot be defined for fracture scvs " 
  364                                                    "because the number of known corners is insufficient. " 
  365                                                    "You can do this manually by extracting the corners from this scv " 
  366                                                    "and extruding them by the corresponding aperture. ");
 
  368        const auto corners = geometryHelper.getScvfCorners(
scvf.indexInElement());
 
  369        using ScvfGeometry = 
typename SubControlVolumeFace::Traits::Geometry;
 
  370        return { Dune::GeometryTypes::cube(ScvfGeometry::mydimension), corners };
 
 
  375    void makeElementGeometries_()
 
  378        const auto& element = *element_;
 
  379        const auto elementGeometry = element.geometry();
 
  380        const auto refElement = referenceElement(element);
 
  383        GeometryHelper geometryHelper(elementGeometry);
 
  386        scvs_.resize(elementGeometry.corners());
 
  387        using LocalIndexType = 
typename SubControlVolumeFace::Traits::LocalIndexType;
 
  388        for (LocalIndexType scvLocalIdx = 0; scvLocalIdx < elementGeometry.corners(); ++scvLocalIdx)
 
  391            const auto dofIdxGlobal = gridGeometry().vertexMapper().subIndex(element, scvLocalIdx, dim);
 
  394            scvs_[scvLocalIdx] = SubControlVolume(geometryHelper,
 
  401        const auto numInnerScvf = (dim==1) ? 1 : element.subEntities(dim-1);
 
  402        scvfs_.resize(numInnerScvf);
 
  404        unsigned int scvfLocalIdx = 0;
 
  405        for (; scvfLocalIdx < numInnerScvf; ++scvfLocalIdx)
 
  408            std::vector<LocalIndexType> localScvIndices({
static_cast<LocalIndexType
>(refElement.subEntity(scvfLocalIdx, dim-1, 0, dim)),
 
  409                                                         static_cast<LocalIndexType
>(refElement.subEntity(scvfLocalIdx, dim-1, 1, dim))});
 
  411            scvfs_[scvfLocalIdx] = SubControlVolumeFace(geometryHelper,
 
  415                                                        std::move(localScvIndices));
 
  429        LocalIndexType scvLocalIdx = 
element.subEntities(dim);
 
  430        for (
const auto& intersection : intersections(gridGeometry().gridView(), element))
 
  433            const auto& isGeometry = intersection.geometry();
 
  435            const auto idxInInside = intersection.indexInInside();
 
  437            std::vector<GridIndexType> isVertexIndices(numCorners);
 
  438            for (
unsigned int vIdxLocal = 0; vIdxLocal < 
numCorners; ++vIdxLocal)
 
  439                isVertexIndices[vIdxLocal] = gridGeometry().vertexMapper().subIndex(element,
 
  440                                                                                      refElement.subEntity(idxInInside, 1, vIdxLocal, dim),
 
  443            if (intersection.boundary())
 
  445                for (
unsigned int isScvfLocalIdx = 0; isScvfLocalIdx < 
numCorners; ++isScvfLocalIdx)
 
  448                    const LocalIndexType insideScvIdx = 
static_cast<LocalIndexType
>(refElement.subEntity(idxInInside, 1, isScvfLocalIdx, dim));
 
  449                    std::vector<LocalIndexType> localScvIndices = {insideScvIdx, insideScvIdx};
 
  451                    scvfs_.emplace_back(geometryHelper,
 
  456                                        std::move(localScvIndices));
 
  464            if (this->gridGeometry().isOnFracture(element, intersection))
 
  467                const auto curNumScvs = scvs_.size();
 
  468                scvs_.reserve(curNumScvs+numCorners);
 
  469                for (
unsigned int vIdxLocal = 0; vIdxLocal < 
numCorners; ++vIdxLocal)
 
  470                    scvs_.emplace_back(geometryHelper,
 
  474                                       static_cast<LocalIndexType
>(refElement.subEntity(idxInInside, 1, vIdxLocal, dim)),
 
  478                                       isVertexIndices[vIdxLocal]);
 
  483                    const auto& faceRefElement = referenceElement(isGeometry);
 
  484                    for (
unsigned int edgeIdx = 0; edgeIdx < faceRefElement.size(1); ++edgeIdx)
 
  487                        std::vector<LocalIndexType> localScvIndices({
static_cast<LocalIndexType
>(faceRefElement.subEntity(edgeIdx, 1, 0, dim-1)),
 
  488                                                                     static_cast<LocalIndexType
>(faceRefElement.subEntity(edgeIdx, 1, 1, dim-1))});
 
  491                        std::for_each( localScvIndices.begin(),
 
  492                                       localScvIndices.end(),
 
  493                                       [curNumScvs] (
auto& elemLocalIdx) { elemLocalIdx += curNumScvs; } );
 
  496                        scvfs_.emplace_back(geometryHelper,
 
  501                                            std::move(localScvIndices),
 
  502                                            intersection.boundary());
 
  510                    std::vector<LocalIndexType> localScvIndices({0, 1});
 
  513                    std::for_each( localScvIndices.begin(),
 
  514                                   localScvIndices.end(),
 
  515                                   [curNumScvs] (
auto& elemLocalIdx) { elemLocalIdx += curNumScvs; } );
 
  518                    scvfs_.emplace_back(geometryHelper,
 
  523                                        std::move(localScvIndices),
 
  524                                        intersection.boundary());
 
  531    std::optional<Element> element_;
 
  535    const GridGeometry* gridGeometryPtr_;
 
  538    std::vector<SubControlVolume> scvs_;
 
  539    std::vector<SubControlVolumeFace> scvfs_;
 
 
SubControlVolume::Traits::Geometry geometry(const SubControlVolume &scv) const
Create the geometry of a given sub control volume.
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:345
const FeLocalBasis & feLocalBasis() const
Get a local finite element basis.
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:279
const SubControlVolumeFace & scvf(std::size_t scvfIdx) const
Get a sub control volume face with a local scvf index.
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:245
const GridGeometry & gridGeometry() const
The global finite volume geometry we are a restriction of.
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:333
static constexpr std::size_t maxNumElementScvs
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:234
BoxDfmFVElementGeometry 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 porousmediumflow/boxdfm/fvelementgeometry.hh:315
typename GridView::template Codim< 0 >::Entity Element
export type of the element
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:225
std::size_t numScvf() const
The total number of sub control volume faces.
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:287
void bind(const Element &element) &
Binding of an element, has to be called before using the fvgeometries Prepares all the volume variabl...
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:307
BoxDfmFVElementGeometry 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 porousmediumflow/boxdfm/fvelementgeometry.hh:295
const Element & element() const
The bound element.
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:341
SubControlVolumeFace::Traits::Geometry geometry(const SubControlVolumeFace &scvf) const
Create the geometry of a given sub control volume face.
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:360
BoxDfmFVElementGeometry(const GridGeometry &gridGeometry)
Constructor.
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:237
std::size_t numScv() const
The total number of sub control volumes.
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:283
bool isBound() const
Returns true if bind/bindElement has already been called.
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:337
const SubControlVolume & scv(std::size_t scvIdx) const
Get a sub control volume with a local scv index.
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:241
friend Dune::IteratorRange< typename std::vector< SubControlVolume >::const_iterator > scvs(const BoxDfmFVElementGeometry &fvGeometry)
Iterator range for sub control volumes.
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:257
GG GridGeometry
Export type of finite volume grid geometry.
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:231
typename GG::SubControlVolumeFace SubControlVolumeFace
Export type of subcontrol volume face.
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:229
friend Dune::IteratorRange< typename std::vector< SubControlVolumeFace >::const_iterator > scvfs(const BoxDfmFVElementGeometry &fvGeometry)
Iterator range for sub control volumes faces.
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:272
typename GG::SubControlVolume SubControlVolume
Export type of subcontrol volume.
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:227
void bindElement(const Element &element) &
Binding of an element, has to be called before using the fvgeometries Prepares all the volume variabl...
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:325
typename GG::SubControlVolumeFace SubControlVolumeFace
Export type of subcontrol volume face.
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:59
void bindElement(const Element &element) &
Binding of an element, has to be called before using the fvgeometries.
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:156
std::size_t numScv() const
The total number of sub control volumes.
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:116
const SubControlVolumeFace & scvf(std::size_t scvfIdx) const
Get a sub control volume face with a local scvf index.
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:76
GG GridGeometry
Export type of finite volume grid geometry.
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:61
const Element & element() const
The bound element.
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:171
void bind(const Element &element) &
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:136
BoxDfmFVElementGeometry(const GridGeometry &gridGeometry)
Constructor.
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:68
std::size_t numScvf() const
The total number of sub control volume faces.
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:120
const FeLocalBasis & feLocalBasis() const
Get a local finite element basis.
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:112
typename GridView::template Codim< 0 >::Entity Element
export type of the element
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:55
typename GG::SubControlVolume SubControlVolume
Export type of subcontrol volume.
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:57
SubControlVolumeFace::Traits::Geometry geometry(const SubControlVolumeFace &scvf) const
Create the geometry of a given sub control volume face.
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:190
const SubControlVolume & scv(std::size_t scvIdx) const
Get a sub control volume with a local scv index.
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:72
static constexpr std::size_t maxNumElementScvs
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:65
BoxDfmFVElementGeometry 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 porousmediumflow/boxdfm/fvelementgeometry.hh:128
friend Dune::IteratorRange< typename std::vector< SubControlVolume >::const_iterator > scvs(const BoxDfmFVElementGeometry &fvGeometry)
Iterator range for sub control volumes.
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:88
const GridGeometry & gridGeometry() const
The global finite volume geometry we are a restriction of.
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:163
bool isBound() const
Returns true if bind/bindElement has already been called.
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:167
SubControlVolume::Traits::Geometry geometry(const SubControlVolume &scv) const
Create the geometry of a given sub control volume.
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:175
friend Dune::IteratorRange< typename std::vector< SubControlVolumeFace >::const_iterator > scvfs(const BoxDfmFVElementGeometry &fvGeometry)
Iterator range for sub control volumes faces.
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:104
BoxDfmFVElementGeometry 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 porousmediumflow/boxdfm/fvelementgeometry.hh:144
Base class for the finite volume geometry vector for box discrete fracture model.
Definition porousmediumflow/boxdfm/fvelementgeometry.hh:41
std::size_t numCorners(Shape shape)
Returns the number of corners of a given geometry.
Definition throatproperties.hh:220
Helper class constructing the dual grid finite volume geometries for the box discrete fracture model.
Class providing iterators over sub control volumes and sub control volume faces of an element.