From 84a79cedd30f24b04efe0d26e326d0bb169465a5 Mon Sep 17 00:00:00 2001 From: DennisGlaeser <dennis.glaeser@iws.uni-stuttgart.de> Date: Thu, 1 Feb 2018 16:36:02 +0100 Subject: [PATCH] [mpfa][indexsets] allow for customizable stencil types The types for stencils are now passed to the nodal index set via a traits class. This allows using Dune::ReservedVector whenever the maximum sizes are known at compile time. --- .../cellcentered/mpfa/darcyslaw.hh | 2 +- .../cellcentered/mpfa/dualgridindexset.hh | 60 ++++++++----------- .../cellcentered/mpfa/fickslaw.hh | 2 +- .../cellcentered/mpfa/fourierslaw.hh | 2 +- .../mpfa/interactionvolumebase.hh | 3 +- .../mpfa/omethod/interactionvolume.hh | 8 +-- .../mpfa/omethod/interactionvolumeindexset.hh | 39 +++++------- .../mpfa/omethod/staticinteractionvolume.hh | 4 +- .../cellcentered/mpfa/properties.hh | 35 ++++++----- dumux/discretization/fluxstencil.hh | 2 +- 10 files changed, 73 insertions(+), 84 deletions(-) diff --git a/dumux/discretization/cellcentered/mpfa/darcyslaw.hh b/dumux/discretization/cellcentered/mpfa/darcyslaw.hh index c8efffbee3..85628f892d 100644 --- a/dumux/discretization/cellcentered/mpfa/darcyslaw.hh +++ b/dumux/discretization/cellcentered/mpfa/darcyslaw.hh @@ -94,7 +94,7 @@ class DarcysLawImplementation<TypeTag, DiscretizationMethods::CCMpfa> static constexpr int numPhases = GET_PROP_VALUE(TypeTag, NumPhases); using DualGridNodalIndexSet = typename GET_PROP_TYPE(TypeTag, DualGridNodalIndexSet); - using Stencil = typename DualGridNodalIndexSet::GridStencilType; + using Stencil = typename DualGridNodalIndexSet::NodalGridStencilType; using MpfaHelper = typename FVGridGeometry::MpfaHelper; static constexpr bool considerSecondaryIVs = MpfaHelper::considerSecondaryIVs(); diff --git a/dumux/discretization/cellcentered/mpfa/dualgridindexset.hh b/dumux/discretization/cellcentered/mpfa/dualgridindexset.hh index b9b95cbc5f..59680aded6 100644 --- a/dumux/discretization/cellcentered/mpfa/dualgridindexset.hh +++ b/dumux/discretization/cellcentered/mpfa/dualgridindexset.hh @@ -38,44 +38,32 @@ namespace Dumux * \brief Nodal index set for mpfa schemes, constructed * around grid vertices. * - * \tparam GV The grid view type - * \tparam LI The type used for indexing in interaction volumes - * \tparam dim The dimension of the grid - * \tparam maxE The maximum admissible number of elements around vertices. - * \tparam maxB The maximum admissible number of branches on intersections. - * This is only to be specified for network grids and defaults to 1 - * for normal grids. + * \tparam T The traits class to be used */ -template< class GV, class LI, int dim, int maxE, int maxB = 2 > +template< class T > class CCMpfaDualGridNodalIndexSet { - using GI = typename GV::IndexSet::IndexType; - using DimIndexVector = Dune::ReservedVector<GI, dim>; + using LI = typename T::LocalIndexType; + using GI = typename T::GridIndexType; + + using DimLocalIndexVector = Dune::ReservedVector<LI, T::GridView::dimension>; + using ScvfIndicesInScvStorage = typename T::template NodalScvDataStorage< DimLocalIndexVector >; public: - //! Export the grid view type - using GridView = GV; + //! Export the traits type + using Traits = T; - //! Export the used index types - using GridIndexType = GI; + //! Export the index types used using LocalIndexType = LI; - - //! Export the specified maximum admissible sizes - static constexpr int dimension = dim; - static constexpr int maxBranches = maxB; - static constexpr int maxNumElementsAtNode = maxE*(maxBranches-1); - static constexpr int maxNumScvfsAtNode = maxNumElementsAtNode*dim; + using GridIndexType = GI; //! Export the stencil types used - using GridStencilType = Dune::ReservedVector<GridIndexType, maxNumElementsAtNode>; - using LocalStencilType = Dune::ReservedVector<LocalIndexType, maxNumElementsAtNode>; - - //! Export the type used for storing the global scvf indices at this node - using GridScvfStencilType = Dune::ReservedVector<GridIndexType, maxNumScvfsAtNode>; + using NodalGridStencilType = typename T::template NodalScvDataStorage< GI >; + using NodalLocalStencilType = typename T::template NodalScvDataStorage< LI >; + using NodalGridScvfStencilType = typename T::template NodalScvfDataStorage< GI >; //! Data structure to store the neighboring scv indices of an scvf (grid/local indices) - using ScvfNeighborIndexSet = Dune::ReservedVector<GridIndexType, maxBranches>; - using ScvfNeighborLocalIndexSet = Dune::ReservedVector<LocalIndexType, maxBranches>; + using ScvfNeighborLocalIndexSet = typename T::template ScvfNeighborDataStorage< LI >; //! Constructor CCMpfaDualGridNodalIndexSet() : numBoundaryScvfs_(0) {} @@ -133,10 +121,10 @@ public: std::size_t numBoundaryScvfs() const { return numBoundaryScvfs_; } //! returns the grid scv indices connected to this dual grid node - const GridStencilType& globalScvIndices() const { return scvIndices_; } + const NodalGridStencilType& globalScvIndices() const { return scvIndices_; } //! returns the grid scvf indices connected to this dual grid node - const GridScvfStencilType& globalScvfIndices() const { return scvfIndices_; } + const NodalGridScvfStencilType& globalScvfIndices() const { return scvfIndices_; } //! returns whether or not the i-th scvf is on a domain boundary bool scvfIsOnBoundary(unsigned int i) const @@ -183,13 +171,13 @@ public: } private: - GridStencilType scvIndices_; //!< The indices of the scvs around a dual grid node - Dune::ReservedVector<DimIndexVector, maxNumElementsAtNode> localScvfIndicesInScv_; //!< Maps to each scv a list of scvf indices embedded in it + NodalGridStencilType scvIndices_; //!< The indices of the scvs around a dual grid node + ScvfIndicesInScvStorage localScvfIndicesInScv_; //!< Maps to each scv a list of scvf indices embedded in it - GridScvfStencilType scvfIndices_; //!< the indices of the scvfs around a dual grid node - std::size_t numBoundaryScvfs_; //!< stores how many boundary scvfs are embedded in this dual grid node - Dune::ReservedVector<bool, maxNumScvfsAtNode> scvfIsOnBoundary_; //!< Maps to each scvf a boolean to indicate if it is on the boundary - Dune::ReservedVector<LocalIndexType, maxNumScvfsAtNode> scvfInsideScvIndices_; //!< The inside local scv index for each scvf + std::size_t numBoundaryScvfs_; //!< stores how many boundary scvfs are embedded in this dual grid node + NodalGridScvfStencilType scvfIndices_; //!< the indices of the scvfs around a dual grid node + typename T::template NodalScvfDataStorage< bool > scvfIsOnBoundary_; //!< Maps to each scvf a boolean to indicate if it is on the boundary + typename T::template NodalScvfDataStorage< LI > scvfInsideScvIndices_; //!< The inside local scv index for each scvf }; /*! @@ -210,7 +198,7 @@ public: //! Constructor taking a grid view template< class GridView > - CCMpfaDualGridIndexSet(const GridView& gridView) : nodalIndexSets_(gridView.size(NodalIndexSet::dimension)) {} + CCMpfaDualGridIndexSet(const GridView& gridView) : nodalIndexSets_(gridView.size(GridView::dimension)) {} //! Access with an scvf template< class SubControlVolumeFace > diff --git a/dumux/discretization/cellcentered/mpfa/fickslaw.hh b/dumux/discretization/cellcentered/mpfa/fickslaw.hh index 91518e9edc..e0bfd2e70b 100644 --- a/dumux/discretization/cellcentered/mpfa/fickslaw.hh +++ b/dumux/discretization/cellcentered/mpfa/fickslaw.hh @@ -92,7 +92,7 @@ class FicksLawImplementation<TypeTag, DiscretizationMethods::CCMpfa> class MpfaFicksLawCache { using DualGridNodalIndexSet = typename GET_PROP_TYPE(TypeTag, DualGridNodalIndexSet); - using Stencil = typename DualGridNodalIndexSet::GridStencilType; + using Stencil = typename DualGridNodalIndexSet::NodalGridStencilType; using MpfaHelper = typename FVGridGeometry::MpfaHelper; static constexpr bool considerSecondaryIVs = MpfaHelper::considerSecondaryIVs(); diff --git a/dumux/discretization/cellcentered/mpfa/fourierslaw.hh b/dumux/discretization/cellcentered/mpfa/fourierslaw.hh index 14b59a3fa3..ded6184e1e 100644 --- a/dumux/discretization/cellcentered/mpfa/fourierslaw.hh +++ b/dumux/discretization/cellcentered/mpfa/fourierslaw.hh @@ -91,7 +91,7 @@ class FouriersLawImplementation<TypeTag, DiscretizationMethods::CCMpfa> class MpfaFouriersLawCache { using DualGridNodalIndexSet = typename GET_PROP_TYPE(TypeTag, DualGridNodalIndexSet); - using Stencil = typename DualGridNodalIndexSet::GridStencilType; + using Stencil = typename DualGridNodalIndexSet::NodalGridStencilType; using MpfaHelper = typename FVGridGeometry::MpfaHelper; static constexpr bool considerSecondaryIVs = MpfaHelper::considerSecondaryIVs(); diff --git a/dumux/discretization/cellcentered/mpfa/interactionvolumebase.hh b/dumux/discretization/cellcentered/mpfa/interactionvolumebase.hh index def2fff434..1e0d605b92 100644 --- a/dumux/discretization/cellcentered/mpfa/interactionvolumebase.hh +++ b/dumux/discretization/cellcentered/mpfa/interactionvolumebase.hh @@ -70,6 +70,7 @@ class CCMpfaInteractionVolumeBase using GridView = typename T::GridView; using Element = typename GridView::template Codim<0>::Entity; + using NodalStencilType = typename T::IndexSet::NodalGridStencilType; using LocalIndexType = typename T::IndexSet::LocalIndexType; using LocalScvType = typename T::LocalScvType; using LocalScvfType = typename T::LocalScvfType; @@ -104,7 +105,7 @@ public: { DUNE_THROW(Dune::NotImplemented, "Interaction volume implementation does not provide a localFaceData() funtion"); } //! returns the cell-stencil of this interaction volume - const typename Traits::IndexSet::GridStencilType& stencil() const { return asImp().stencil(); } + const NodalStencilType& stencil() const { return asImp().stencil(); } //! returns the local scvf entity corresponding to a given iv-local scvf idx const LocalScvfType& localScvf(LocalIndexType ivLocalScvfIdx) const { return asImp().localScvf(ivLocalScvfIdx); } diff --git a/dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh b/dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh index 1a5595f824..7dde618795 100644 --- a/dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh +++ b/dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh @@ -64,8 +64,8 @@ private: using GridIndexType = typename NodalIndexSet::GridIndexType; using LocalIndexType = typename NodalIndexSet::LocalIndexType; - static constexpr int dim = NodalIndexSet::GridView::dimension; - static constexpr int dimWorld = NodalIndexSet::GridView::dimensionworld; + static constexpr int dim = NodalIndexSet::Traits::GridView::dimension; + static constexpr int dimWorld = NodalIndexSet::Traits::GridView::dimensionworld; //! Matrix/Vector traits to be used by the data handle struct MVTraits @@ -81,7 +81,7 @@ private: public: //! export the type of grid view - using GridView = typename NodalIndexSet::GridView; + using GridView = typename NodalIndexSet::Traits::GridView; //! export the type for the interaction volume index set using IndexSet = CCMpfaOInteractionVolumeIndexSet< NodalIndexSet >; //! export the type of interaction-volume local scvs @@ -110,7 +110,7 @@ class CCMpfaOInteractionVolume using IndexSet = typename Traits::IndexSet; using GridIndexType = typename IndexSet::GridIndexType; using LocalIndexType = typename IndexSet::LocalIndexType; - using Stencil = typename IndexSet::GridStencilType; + using Stencil = typename IndexSet::NodalGridStencilType; static constexpr int dim = GridView::dimension; static constexpr int dimWorld = GridView::dimensionworld; diff --git a/dumux/discretization/cellcentered/mpfa/omethod/interactionvolumeindexset.hh b/dumux/discretization/cellcentered/mpfa/omethod/interactionvolumeindexset.hh index 86f11c0452..51894f6ce2 100644 --- a/dumux/discretization/cellcentered/mpfa/omethod/interactionvolumeindexset.hh +++ b/dumux/discretization/cellcentered/mpfa/omethod/interactionvolumeindexset.hh @@ -47,10 +47,10 @@ public: using LocalIndexType = typename DualGridNodalIndexSet::LocalIndexType; using GridIndexType = typename DualGridNodalIndexSet::GridIndexType; - // Export the types used for local/grid stencils - using LocalStencilType = typename DualGridNodalIndexSet::LocalStencilType; - using GridStencilType = typename DualGridNodalIndexSet::GridStencilType; - using GridScvfStencilType = typename DualGridNodalIndexSet::GridScvfStencilType; + //! Export the stencil types used + using NodalGridStencilType = typename DualGridNodalIndexSet::NodalGridStencilType; + using NodalLocalStencilType = typename DualGridNodalIndexSet::NodalLocalStencilType; + using NodalGridScvfStencilType = typename DualGridNodalIndexSet::NodalGridScvfStencilType; //! Export the type used for the neighbor scv index sets of the scvfs using ScvfNeighborLocalIndexSet = typename DualGridNodalIndexSet::ScvfNeighborLocalIndexSet; @@ -62,7 +62,8 @@ public: { const auto numNodalScvfs = nodalIndexSet.numScvfs(); - // keeps track of which nodal scvfs have been handled already + // kee track of which nodal scvfs have been handled already + nodeToIvScvf_.resize(numNodalScvfs); std::vector<bool> isHandled(numNodalScvfs, false); // go over faces in nodal index set, check if iv-local face has been @@ -121,13 +122,10 @@ public: } //! returns the corresponding nodal index set - const DualGridNodalIndexSet& nodalIndexSet() const { return nodalIndexSet_; } + const NodalIndexSet& nodalIndexSet() const { return nodalIndexSet_; } //! returns the global scv indices connected to this dual grid node - const GridStencilType& globalScvIndices() const { return nodalIndexSet_.globalScvIndices(); } - - //! returns the global scvf indices connected to this dual grid node - const GridScvfStencilType& globalScvfIndices() const { return nodalIndexSet_.globalScvfIndices(); } + const NodalGridStencilType& globalScvIndices() const { return nodalIndexSet_.globalScvIndices(); } //! returns the number of faces in the interaction volume std::size_t numFaces() const { return numFaces_; } @@ -157,23 +155,18 @@ public: } private: - //! returns the local scv index to a given global scv index - unsigned int findLocalScvIdx_(GridIndexType globalScvIdx) const - { - auto it = std::find( nodalIndexSet_.globalScvIndices().begin(), nodalIndexSet_.globalScvIndices().end(), globalScvIdx ); - assert(it != nodalIndexSet_.globalScvIndices().end() && "Global scv index not found in local container!"); - return std::distance(nodalIndexSet_.globalScvIndices().begin(), it); - } - - const DualGridNodalIndexSet& nodalIndexSet_; + using NI = NodalIndexSet; std::size_t numFaces_; - Dune::ReservedVector< LocalIndexType, NodalIndexSet::maxNumScvfsAtNode > ivToNodeScvf_; - Dune::ReservedVector< LocalIndexType, NodalIndexSet::maxNumScvfsAtNode > nodeToIvScvf_; - + const NI& nodalIndexSet_; + // Index maps from and to nodal index set. For the map to the + // nodal set we use the same storage type as we know the nodal + // has more faces, thus sufficient guaranteed here! + typename NI::Traits::template NodalScvfDataStorage< LocalIndexType > ivToNodeScvf_; + typename NI::Traits::template NodalScvfDataStorage< LocalIndexType > nodeToIvScvf_; // maps to each scvf a list of neighbouring scv indices // ordering: 0 - inside scv idx; 1..n - outside scv indices - Dune::ReservedVector< ScvfNeighborLocalIndexSet, NodalIndexSet::maxNumScvfsAtNode > scvfNeighborScvLocalIndices_; + typename NI::Traits::template NodalScvfDataStorage< ScvfNeighborLocalIndexSet > scvfNeighborScvLocalIndices_; }; } // end namespace Dumux diff --git a/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh b/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh index 7c30e02ecd..f98f6d297e 100644 --- a/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh +++ b/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh @@ -82,7 +82,7 @@ private: public: //! export the type of grid view - using GridView = typename NI::GridView; + using GridView = typename NI::Traits::GridView; //! export the type for the interaction volume index set using IndexSet = CCMpfaOInteractionVolumeIndexSet< NI >; //! export the type of interaction-volume local scvs @@ -119,7 +119,7 @@ class CCMpfaOStaticInteractionVolume using IndexSet = typename Traits::IndexSet; using GridIndexType = typename IndexSet::GridIndexType; using LocalIndexType = typename IndexSet::LocalIndexType; - using Stencil = typename IndexSet::GridStencilType; + using Stencil = typename IndexSet::NodalGridStencilType; static constexpr int dim = GridView::dimension; static constexpr int dimWorld = GridView::dimensionworld; diff --git a/dumux/discretization/cellcentered/mpfa/properties.hh b/dumux/discretization/cellcentered/mpfa/properties.hh index 53a04d86cd..d861dd3b81 100644 --- a/dumux/discretization/cellcentered/mpfa/properties.hh +++ b/dumux/discretization/cellcentered/mpfa/properties.hh @@ -25,6 +25,8 @@ #ifndef DUMUX_CC_MPFA_PROPERTIES_HH #define DUMUX_CC_MPFA_PROPERTIES_HH +#include <dune/common/reservedvector.hh> + #include <dumux/common/properties.hh> #include <dumux/common/defaultmappertraits.hh> @@ -80,23 +82,28 @@ public: //! Set the index set type used on the dual grid nodes SET_PROP(CCMpfaModel, DualGridNodalIndexSet) { -private: using GV = typename GET_PROP_TYPE(TypeTag, GridView); - - // per default, use uint8_t as iv-local index type - using LI = std::uint8_t; - - // the specified maximum admissible number of branches per scvf - static constexpr int maxB = GET_PROP_VALUE(TypeTag, MaxNumNeighborsPerScvf); - - // maximum admissible number of elements around a node - // if for a given grid this number is still not high enough, - // overwrite this property in your problem with a higher number static constexpr int dim = GV::dimension; - static constexpr int maxE = dim == 3 ? 45 : 15; - + static constexpr int dimWorld = GV::dimensionworld; +private: + struct Traits + { + using GridView = GV; + using GridIndexType = typename GV::IndexSet::IndexType; + using LocalIndexType = std::uint8_t; + + //! per default, we use dynamic data containers (iv size unknown) + template< class T > using NodalScvDataStorage = std::vector< T >; + template< class T > using NodalScvfDataStorage = std::vector< T >; + + //! store data on neighbors of scvfs in static containers if possible + template< class T > + using ScvfNeighborDataStorage = typename std::conditional_t< (dim<dimWorld), + std::vector< T >, + Dune::ReservedVector< T, 2 > >; + }; public: - using type = CCMpfaDualGridNodalIndexSet<GV, LI, dim, maxE, maxB>; + using type = CCMpfaDualGridNodalIndexSet< Traits >; }; //! Per default, we use the dynamic mpfa-o interaction volume diff --git a/dumux/discretization/fluxstencil.hh b/dumux/discretization/fluxstencil.hh index e34321cf03..b249dbe5a8 100644 --- a/dumux/discretization/fluxstencil.hh +++ b/dumux/discretization/fluxstencil.hh @@ -104,7 +104,7 @@ public: using ScvfStencilIForJ = std::vector<IndexType>; //! The flux stencil type - using Stencil = typename NodalIndexSet::GridStencilType; + using Stencil = typename NodalIndexSet::NodalGridStencilType; //! Returns the indices of the elements required for flux calculation on an scvf. static const Stencil& stencil(const Element& element, -- GitLab