14#ifndef DUMUX_DISCRETIZATION_BOX_GRID_FVGEOMETRY_HH 
   15#define DUMUX_DISCRETIZATION_BOX_GRID_FVGEOMETRY_HH 
   18#include <unordered_map> 
   22#include <dune/localfunctions/lagrange/lagrangelfecache.hh> 
   39template<
class GV, 
class T>
 
   53template<
class Gr
idView, 
class MapperTraits = DefaultMapperTraits<Gr
idView>>
 
   60    template<
class Gr
idGeometry, 
bool enableCache>
 
 
   72         bool enableGridGeometryCache = 
false,
 
   82template<
class Scalar, 
class GV, 
class Traits>
 
   91    using Element = 
typename GV::template Codim<0>::Entity;
 
   92    using CoordScalar = 
typename GV::ctype;
 
   93    static const int dim = GV::dimension;
 
   94    static const int dimWorld = GV::dimensionworld;
 
   99    static constexpr DiscretizationMethod discMethod{};
 
  104    using LocalView = 
typename Traits::template LocalView<ThisType, true>;
 
  106    using SubControlVolume = 
typename Traits::SubControlVolume;
 
  108    using SubControlVolumeFace = 
typename Traits::SubControlVolumeFace;
 
  112    using DofMapper = 
typename Traits::VertexMapper;
 
  114    using FeCache = Dune::LagrangeLocalFiniteElementCache<CoordScalar, Scalar, dim, 1>;
 
  122    : ParentType(std::move(gg))
 
  124    , periodicGridTraits_(this->gridView().grid())
 
  130    BoxFVGridGeometry(
const GridView& gridView)
 
  131    : BoxFVGridGeometry(std::make_shared<BasicGridGeometry>(gridView))
 
  136    const DofMapper& dofMapper()
 const 
  137    { 
return this->vertexMapper(); }
 
  140    std::size_t numScv()
 const 
  144    std::size_t numScvf()
 const 
  149    std::size_t numBoundaryScvf()
 const 
  150    { 
return numBoundaryScvf_; }
 
  153    std::size_t numDofs()
 const 
  154    { 
return this->vertexMapper().size(); }
 
  158    void update(
const GridView& gridView)
 
  160        ParentType::update(gridView);
 
  165    void update(GridView&& gridView)
 
  167        ParentType::update(std::move(gridView));
 
  172    const FeCache& feCache()
 const 
  176    bool dofOnBoundary(GridIndexType dofIdx)
 const 
  177    { 
return boundaryDofIndices_[dofIdx]; }
 
  180    bool dofOnPeriodicBoundary(GridIndexType dofIdx)
 const 
  181    { 
return periodicDofMap_.count(dofIdx); }
 
  184    GridIndexType periodicallyMappedDof(GridIndexType dofIdx)
 const 
  185    { 
return periodicDofMap_.at(dofIdx); }
 
  188    const std::unordered_map<GridIndexType, GridIndexType>& periodicDofMap()
 const 
  189    { 
return periodicDofMap_; }
 
  192    friend inline LocalView 
localView(
const BoxFVGridGeometry& gg)
 
  193    { 
return { gg.cache_ }; }
 
  197    class BoxGridGeometryCache
 
  199        friend class BoxFVGridGeometry;
 
  202        using GeometryHelper = Detail::BoxGeometryHelper_t<GV, Traits>;
 
  204        explicit BoxGridGeometryCache(
const BoxFVGridGeometry& gg)
 
  208        const BoxFVGridGeometry& gridGeometry()
 const 
  209        { 
return *gridGeometry_; }
 
  212        const std::vector<SubControlVolume>& scvs(GridIndexType eIdx)
 const 
  213        { 
return scvs_[eIdx]; }
 
  216        const std::vector<SubControlVolumeFace>& scvfs(GridIndexType eIdx)
 const 
  217        { 
return scvfs_[eIdx]; }
 
  220        bool hasBoundaryScvf(GridIndexType eIdx)
 const 
  221        { 
return hasBoundaryScvf_[eIdx]; }
 
  224        const std::vector<std::array<LocalIndexType, 2>>& scvfBoundaryGeometryKeys(GridIndexType eIdx)
 const 
  225        { 
return scvfBoundaryGeometryKeys_.at(eIdx); }
 
  232            hasBoundaryScvf_.clear();
 
  233            scvfBoundaryGeometryKeys_.clear();
 
  236        std::vector<std::vector<SubControlVolume>> scvs_;
 
  237        std::vector<std::vector<SubControlVolumeFace>> scvfs_;
 
  238        std::vector<bool> hasBoundaryScvf_;
 
  239        std::unordered_map<GridIndexType, std::vector<std::array<LocalIndexType, 2>>> scvfBoundaryGeometryKeys_;
 
  241        const BoxFVGridGeometry* gridGeometry_;
 
  247    using Cache = BoxGridGeometryCache;
 
  250    using GeometryHelper = 
typename Cache::GeometryHelper;
 
  256        const auto numElements = this->gridView().size(0);
 
  257        cache_.scvs_.resize(numElements);
 
  258        cache_.scvfs_.resize(numElements);
 
  259        cache_.hasBoundaryScvf_.resize(numElements, 
false);
 
  261        boundaryDofIndices_.assign(numDofs(), 
false);
 
  265        numBoundaryScvf_ = 0;
 
  267        for (
const auto& element : elements(this->gridView()))
 
  270            const auto eIdx = this->elementMapper().index(element);
 
  273            numScv_ += 
element.subEntities(dim);
 
  274            numScvf_ += 
element.subEntities(dim-1);
 
  277            auto elementGeometry = 
element.geometry();
 
  278            const auto refElement = referenceElement(elementGeometry);
 
  281            GeometryHelper geometryHelper(elementGeometry);
 
  284            cache_.scvs_[eIdx].resize(elementGeometry.corners());
 
  285            for (LocalIndexType scvLocalIdx = 0; scvLocalIdx < elementGeometry.corners(); ++scvLocalIdx)
 
  287                const auto dofIdxGlobal = this->vertexMapper().subIndex(element, scvLocalIdx, dim);
 
  289                cache_.scvs_[eIdx][scvLocalIdx] = SubControlVolume(
 
  290                    geometryHelper.getScvCorners(scvLocalIdx),
 
  298            LocalIndexType scvfLocalIdx = 0;
 
  299            cache_.scvfs_[eIdx].resize(
element.subEntities(dim-1));
 
  300            for (; scvfLocalIdx < 
element.subEntities(dim-1); ++scvfLocalIdx)
 
  303                std::vector<LocalIndexType> localScvIndices({
static_cast<LocalIndexType
>(refElement.subEntity(scvfLocalIdx, dim-1, 0, dim)),
 
  304                                                             static_cast<LocalIndexType
>(refElement.subEntity(scvfLocalIdx, dim-1, 1, dim))});
 
  306                const auto& corners = geometryHelper.getScvfCorners(scvfLocalIdx);
 
  307                cache_.scvfs_[eIdx][scvfLocalIdx] = SubControlVolumeFace(
 
  309                    geometryHelper.normal(corners, localScvIndices),
 
  313                    std::move(localScvIndices),
 
  319            for (
const auto& intersection : intersections(this->gridView(), element))
 
  321                if (intersection.boundary() && !intersection.neighbor())
 
  323                    const auto isGeometry = intersection.geometry();
 
  324                    cache_.hasBoundaryScvf_[eIdx] = 
true;
 
  327                    numScvf_ += isGeometry.corners();
 
  328                    numBoundaryScvf_ += isGeometry.corners();
 
  330                    for (
unsigned int isScvfLocalIdx = 0; isScvfLocalIdx < isGeometry.corners(); ++isScvfLocalIdx)
 
  333                        const LocalIndexType insideScvIdx = 
static_cast<LocalIndexType
>(refElement.subEntity(intersection.indexInInside(), 1, isScvfLocalIdx, dim));
 
  334                        std::vector<LocalIndexType> localScvIndices = {insideScvIdx, insideScvIdx};
 
  336                        cache_.scvfs_[eIdx].emplace_back(
 
  337                            geometryHelper.getBoundaryScvfCorners(intersection.indexInInside(), isScvfLocalIdx),
 
  338                            intersection.centerUnitOuterNormal(),
 
  343                            std::move(localScvIndices),
 
  347                        cache_.scvfBoundaryGeometryKeys_[eIdx].emplace_back(std::array<LocalIndexType, 2>{{
 
  348                            static_cast<LocalIndexType
>(intersection.indexInInside()),
 
  349                            static_cast<LocalIndexType
>(isScvfLocalIdx)
 
  358                    const auto fIdx = intersection.indexInInside();
 
  359                    const auto numFaceVerts = refElement.size(fIdx, 1, dim);
 
  360                    for (
int localVIdx = 0; localVIdx < numFaceVerts; ++localVIdx)
 
  362                        const auto vIdx = refElement.subEntity(fIdx, 1, localVIdx, dim);
 
  363                        const auto vIdxGlobal = this->vertexMapper().subIndex(element, vIdx, dim);
 
  364                        boundaryDofIndices_[vIdxGlobal] = 
true;
 
  369                else if (periodicGridTraits_.isPeriodic(intersection))
 
  374                    const auto fIdx = intersection.indexInInside();
 
  375                    const auto numFaceVerts = refElement.size(fIdx, 1, dim);
 
  376                    const auto eps = 1e-7*(elementGeometry.corner(1) - elementGeometry.corner(0)).two_norm();
 
  377                    for (
int localVIdx = 0; localVIdx < numFaceVerts; ++localVIdx)
 
  379                        const auto vIdx = refElement.subEntity(fIdx, 1, localVIdx, dim);
 
  380                        const auto vIdxGlobal = this->vertexMapper().subIndex(element, vIdx, dim);
 
  381                        const auto vPos = elementGeometry.corner(vIdx);
 
  383                        const auto& outside = intersection.outside();
 
  384                        const auto outsideGeometry = outside.geometry();
 
  385                        for (
const auto& isOutside : intersections(this->gridView(), outside))
 
  388                            if (periodicGridTraits_.isPeriodic(isOutside))
 
  390                                const auto fIdxOutside = isOutside.indexInInside();
 
  391                                const auto numFaceVertsOutside = refElement.size(fIdxOutside, 1, dim);
 
  392                                for (
int localVIdxOutside = 0; localVIdxOutside < numFaceVertsOutside; ++localVIdxOutside)
 
  394                                    const auto vIdxOutside = refElement.subEntity(fIdxOutside, 1, localVIdxOutside, dim);
 
  395                                    const auto vPosOutside = outsideGeometry.corner(vIdxOutside);
 
  396                                    const auto shift = std::abs((this->bBoxMax()-this->bBoxMin())*intersection.centerUnitOuterNormal());
 
  397                                    if (std::abs((vPosOutside-vPos).two_norm() - shift) < eps)
 
  398                                        periodicDofMap_[vIdxGlobal] = this->vertexMapper().subIndex(outside, vIdxOutside, dim);
 
  408        if (this->isPeriodic() && this->gridView().comm().size() > 1)
 
  409            DUNE_THROW(Dune::NotImplemented, 
"Periodic boundaries for box method for parallel simulations!");
 
  412    const FeCache feCache_;
 
  415    std::size_t numScvf_;
 
  416    std::size_t numBoundaryScvf_;
 
  419    std::vector<bool> boundaryDofIndices_;
 
  422    std::unordered_map<GridIndexType, GridIndexType> periodicDofMap_;
 
  426    PeriodicGridTraits<typename GridView::Grid> periodicGridTraits_;
 
  436template<
class Scalar, 
class GV, 
class Traits>
 
  440    using ThisType = BoxFVGridGeometry<Scalar, GV, false, Traits>;
 
  441    using ParentType = BaseGridGeometry<GV, Traits>;
 
  444    static const int dim = GV::dimension;
 
  445    static const int dimWorld = GV::dimensionworld;
 
  447    using Element = 
typename GV::template Codim<0>::Entity;
 
  448    using CoordScalar = 
typename GV::ctype;
 
  453    static constexpr DiscretizationMethod discMethod{};
 
  458    using LocalView = 
typename Traits::template LocalView<ThisType, false>;
 
  460    using SubControlVolume = 
typename Traits::SubControlVolume;
 
  462    using SubControlVolumeFace = 
typename Traits::SubControlVolumeFace;
 
  466    using DofMapper = 
typename Traits::VertexMapper;
 
  468    using FeCache = Dune::LagrangeLocalFiniteElementCache<CoordScalar, Scalar, dim, 1>;
 
  472    using SupportsPeriodicity = 
typename PeriodicGridTraits<typename GV::Grid>::SupportsPeriodicity;
 
  475    BoxFVGridGeometry(std::shared_ptr<BasicGridGeometry> gg)
 
  476    : ParentType(std::move(gg))
 
  478    , periodicGridTraits_(this->gridView().grid())
 
  484    BoxFVGridGeometry(
const GridView& gridView)
 
  485    : BoxFVGridGeometry(std::make_shared<BasicGridGeometry>(gridView))
 
  490    const DofMapper& dofMapper()
 const 
  491    { 
return this->vertexMapper(); }
 
  494    std::size_t numScv()
 const 
  498    std::size_t numScvf()
 const 
  503    std::size_t numBoundaryScvf()
 const 
  504    { 
return numBoundaryScvf_; }
 
  507    std::size_t numDofs()
 const 
  508    { 
return this->vertexMapper().size(); }
 
  512    void update(
const GridView& gridView)
 
  514        ParentType::update(gridView);
 
  519    void update(GridView&& gridView)
 
  521        ParentType::update(std::move(gridView));
 
  526    const FeCache& feCache()
 const 
  530    bool dofOnBoundary(GridIndexType dofIdx)
 const 
  531    { 
return boundaryDofIndices_[dofIdx]; }
 
  534    bool dofOnPeriodicBoundary(GridIndexType dofIdx)
 const 
  535    { 
return periodicDofMap_.count(dofIdx); }
 
  538    GridIndexType periodicallyMappedDof(GridIndexType dofIdx)
 const 
  539    { 
return periodicDofMap_.at(dofIdx); }
 
  542    const std::unordered_map<GridIndexType, GridIndexType>& periodicDofMap()
 const 
  543    { 
return periodicDofMap_; }
 
  546    friend inline LocalView 
localView(
const BoxFVGridGeometry& gg)
 
  547    { 
return { gg.cache_ }; }
 
  551    class BoxGridGeometryCache
 
  553        friend class BoxFVGridGeometry;
 
  556        using GeometryHelper = Detail::BoxGeometryHelper_t<GV, Traits>;
 
  558        explicit BoxGridGeometryCache(
const BoxFVGridGeometry& gg)
 
  562        const BoxFVGridGeometry& gridGeometry()
 const 
  563        { 
return *gridGeometry_; }
 
  566        const BoxFVGridGeometry* gridGeometry_;
 
  572    using Cache = BoxGridGeometryCache;
 
  578        boundaryDofIndices_.assign(numDofs(), 
false);
 
  584        numBoundaryScvf_ = 0;
 
  585        for (
const auto& element : elements(this->gridView()))
 
  587            numScv_ += 
element.subEntities(dim);
 
  588            numScvf_ += 
element.subEntities(dim-1);
 
  590            const auto elementGeometry = 
element.geometry();
 
  591            const auto refElement = referenceElement(elementGeometry);
 
  594            for (
const auto& intersection : intersections(this->gridView(), element))
 
  596                if (intersection.boundary() && !intersection.neighbor())
 
  598                    const auto isGeometry = intersection.geometry();
 
  599                    numScvf_ += isGeometry.corners();
 
  600                    numBoundaryScvf_ += isGeometry.corners();
 
  604                    const auto fIdx = intersection.indexInInside();
 
  605                    const auto numFaceVerts = refElement.size(fIdx, 1, dim);
 
  606                    for (
int localVIdx = 0; localVIdx < numFaceVerts; ++localVIdx)
 
  608                        const auto vIdx = refElement.subEntity(fIdx, 1, localVIdx, dim);
 
  609                        const auto vIdxGlobal = this->vertexMapper().subIndex(element, vIdx, dim);
 
  610                        boundaryDofIndices_[vIdxGlobal] = 
true;
 
  615                else if (periodicGridTraits_.isPeriodic(intersection))
 
  620                    const auto fIdx = intersection.indexInInside();
 
  621                    const auto numFaceVerts = refElement.size(fIdx, 1, dim);
 
  622                    const auto eps = 1e-7*(elementGeometry.corner(1) - elementGeometry.corner(0)).two_norm();
 
  623                    for (
int localVIdx = 0; localVIdx < numFaceVerts; ++localVIdx)
 
  625                        const auto vIdx = refElement.subEntity(fIdx, 1, localVIdx, dim);
 
  626                        const auto vIdxGlobal = this->vertexMapper().subIndex(element, vIdx, dim);
 
  627                        const auto vPos = elementGeometry.corner(vIdx);
 
  629                        const auto& outside = intersection.outside();
 
  630                        const auto outsideGeometry = outside.geometry();
 
  631                        for (
const auto& isOutside : intersections(this->gridView(), outside))
 
  634                            if (periodicGridTraits_.isPeriodic(isOutside))
 
  636                                const auto fIdxOutside = isOutside.indexInInside();
 
  637                                const auto numFaceVertsOutside = refElement.size(fIdxOutside, 1, dim);
 
  638                                for (
int localVIdxOutside = 0; localVIdxOutside < numFaceVertsOutside; ++localVIdxOutside)
 
  640                                    const auto vIdxOutside = refElement.subEntity(fIdxOutside, 1, localVIdxOutside, dim);
 
  641                                    const auto vPosOutside = outsideGeometry.corner(vIdxOutside);
 
  642                                    const auto shift = std::abs((this->bBoxMax()-this->bBoxMin())*intersection.centerUnitOuterNormal());
 
  643                                    if (std::abs((vPosOutside-vPos).two_norm() - shift) < eps)
 
  644                                        periodicDofMap_[vIdxGlobal] = this->vertexMapper().subIndex(outside, vIdxOutside, dim);
 
  654        if (this->isPeriodic() && this->gridView().comm().size() > 1)
 
  655            DUNE_THROW(Dune::NotImplemented, 
"Periodic boundaries for box method for parallel simulations!");
 
  658    const FeCache feCache_;
 
  663    std::size_t numScvf_;
 
  664    std::size_t numBoundaryScvf_;
 
  667    std::vector<bool> boundaryDofIndices_;
 
  670    std::unordered_map<GridIndexType, GridIndexType> periodicDofMap_;
 
  674    PeriodicGridTraits<typename GridView::Grid> periodicGridTraits_;
 
Base class for grid geometries.
Helper class constructing the dual grid finite volume geometries for the box discretizazion method.
Base class for all grid geometries.
Definition basegridgeometry.hh:52
An implementation of a grid geometry with some basic features.
Definition basicgridgeometry.hh:37
Base class for the finite volume geometry vector for box models This builds up the sub control volume...
Definition discretization/box/fvelementgeometry.hh:41
Base class for the finite volume geometry vector for box schemes This builds up the sub control volum...
Definition discretization/box/fvgridgeometry.hh:74
Create sub control volumes and sub control volume face geometries.
Definition boxgeometryhelper.hh:257
Class for a sub control volume face in the box method, i.e a part of the boundary of a sub control vo...
Definition discretization/box/subcontrolvolumeface.hh:62
the sub control volume for the box scheme
Definition discretization/box/subcontrolvolume.hh:60
Traits extracting the public Extrusion type from T Defaults to NoExtrusion if no such type is found.
Definition extrusion.hh:155
Definition periodicgridtraits.hh:121
Defines the default element and vertex mapper types.
Base class for the local finite volume geometry for box models This builds up the sub control volumes...
the sub control volume for the box scheme
Base class for a sub control volume face.
Helper classes to compute the integration elements.
GridCache::LocalView localView(const GridCache &gridCache)
Free function to get the local view of a grid cache object.
Definition localview.hh:26
Dune::Std::detected_or_t< Dumux::BasicGridGeometry< GV, typename T::ElementMapper, typename T::VertexMapper >, Detail::SpecifiesBaseGridGeometry, T > BasicGridGeometry_t
Type of the basic grid geometry implementation used as backend.
Definition basegridgeometry.hh:38
The available discretization methods in Dumux.
Distance implementation details.
Definition cvfelocalresidual.hh:25
Dune::Std::detected_or_t< Dumux::BoxGeometryHelper< GV, GV::dimension, typename T::SubControlVolume, typename T::SubControlVolumeFace >, SpecifiesGeometryHelper, T > BoxGeometryHelper_t
Definition discretization/box/fvgridgeometry.hh:40
typename T::GeometryHelper SpecifiesGeometryHelper
Definition basegridgeometry.hh:30
CVFE< CVFEMethods::PQ1 > Box
Definition method.hh:94
typename Extrusion< T >::type Extrusion_t
Convenience alias for obtaining the extrusion type.
Definition extrusion.hh:166
Grid properties related to periodicity.
The default traits for the box finite volume grid geometry Defines the scv and scvf types and the map...
Definition discretization/box/fvgridgeometry.hh:56
BoxSubControlVolume< GridView > SubControlVolume
Definition discretization/box/fvgridgeometry.hh:57
BoxSubControlVolumeFace< GridView > SubControlVolumeFace
Definition discretization/box/fvgridgeometry.hh:58
BoxFVElementGeometry< GridGeometry, enableCache > LocalView
Definition discretization/box/fvgridgeometry.hh:61
typename GridView::IndexSet::IndexType GridIndex
Definition indextraits.hh:27
unsigned int LocalIndex
Definition indextraits.hh:28
Definition periodicgridtraits.hh:34