From b879a484fd41086754cf2512d6bb5ca0d635494e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Gl=C3=A4ser?= Date: Thu, 15 Nov 2018 10:58:40 +0100 Subject: [PATCH 01/35] [mpfa][localfacedata] rename isoutside function --- .../discretization/cellcentered/mpfa/darcyslaw.hh | 8 ++++---- dumux/discretization/cellcentered/mpfa/fickslaw.hh | 14 ++++++++------ .../cellcentered/mpfa/fourierslaw.hh | 14 ++++++++------ .../cellcentered/mpfa/localfacedata.hh | 6 +++--- .../cellcentered/mpfa/omethod/localassembler.hh | 6 +++--- 5 files changed, 26 insertions(+), 22 deletions(-) diff --git a/dumux/discretization/cellcentered/mpfa/darcyslaw.hh b/dumux/discretization/cellcentered/mpfa/darcyslaw.hh index fd18b34195..ad6c150e29 100644 --- a/dumux/discretization/cellcentered/mpfa/darcyslaw.hh +++ b/dumux/discretization/cellcentered/mpfa/darcyslaw.hh @@ -134,7 +134,7 @@ class DarcysLawImplementation const PrimaryIvDataHandle& dataHandle, const SubControlVolumeFace &scvf) { - switchFluxSign_ = localFaceData.isOutside(); + switchFluxSign_ = localFaceData.isOutsideFace(); stencil_ = &iv.stencil(); for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) @@ -154,7 +154,7 @@ class DarcysLawImplementation // surface grids else { - if (!localFaceData.isOutside()) + if (!localFaceData.isOutsideFace()) { primaryTij_ = &dataHandle.advectionT()[ivLocalIdx]; if (enableGravity) @@ -189,7 +189,7 @@ class DarcysLawImplementation const SecondaryIvDataHandle& dataHandle, const SubControlVolumeFace &scvf) { - switchFluxSign_ = localFaceData.isOutside(); + switchFluxSign_ = localFaceData.isOutsideFace(); stencil_ = &iv.stencil(); for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) @@ -209,7 +209,7 @@ class DarcysLawImplementation // surface grids else { - if (!localFaceData.isOutside()) + if (!localFaceData.isOutsideFace()) { secondaryTij_ = &dataHandle.advectionT()[ivLocalIdx]; if (enableGravity) diff --git a/dumux/discretization/cellcentered/mpfa/fickslaw.hh b/dumux/discretization/cellcentered/mpfa/fickslaw.hh index d9afded35c..71dcb70fcc 100644 --- a/dumux/discretization/cellcentered/mpfa/fickslaw.hh +++ b/dumux/discretization/cellcentered/mpfa/fickslaw.hh @@ -133,7 +133,7 @@ class FicksLawImplementation unsigned int phaseIdx, unsigned int compIdx) { stencil_[phaseIdx][compIdx] = &iv.stencil(); - switchFluxSign_[phaseIdx][compIdx] = localFaceData.isOutside(); + switchFluxSign_[phaseIdx][compIdx] = localFaceData.isOutsideFace(); // store pointer to the mole fraction vector of this iv primaryXj_[phaseIdx][compIdx] = &dataHandle.moleFractions(phaseIdx, compIdx); @@ -142,8 +142,9 @@ class FicksLawImplementation if (dim == dimWorld) primaryTij_[phaseIdx][compIdx] = &dataHandle.diffusionT()[ivLocalIdx]; else - primaryTij_[phaseIdx][compIdx] = localFaceData.isOutside() ? &dataHandle.diffusionTout()[ivLocalIdx][localFaceData.scvfLocalOutsideScvfIndex()] - : &dataHandle.diffusionT()[ivLocalIdx]; + primaryTij_[phaseIdx][compIdx] = localFaceData.isOutsideFace() + ? &dataHandle.diffusionTout()[ivLocalIdx][localFaceData.scvfLocalOutsideScvfIndex()] + : &dataHandle.diffusionT()[ivLocalIdx]; } /*! @@ -163,7 +164,7 @@ class FicksLawImplementation unsigned int phaseIdx, unsigned int compIdx) { stencil_[phaseIdx][compIdx] = &iv.stencil(); - switchFluxSign_[phaseIdx][compIdx] = localFaceData.isOutside(); + switchFluxSign_[phaseIdx][compIdx] = localFaceData.isOutsideFace(); // store pointer to the mole fraction vector of this iv secondaryXj_[phaseIdx][compIdx] = &dataHandle.moleFractions(phaseIdx, compIdx); @@ -172,8 +173,9 @@ class FicksLawImplementation if (dim == dimWorld) secondaryTij_[phaseIdx][compIdx] = &dataHandle.diffusionT()[ivLocalIdx]; else - secondaryTij_[phaseIdx][compIdx] = localFaceData.isOutside() ? &dataHandle.diffusionTout()[ivLocalIdx][localFaceData.scvfLocalOutsideScvfIndex()] - : &dataHandle.diffusionT()[ivLocalIdx]; + secondaryTij_[phaseIdx][compIdx] = localFaceData.isOutsideFace() + ? &dataHandle.diffusionTout()[ivLocalIdx][localFaceData.scvfLocalOutsideScvfIndex()] + : &dataHandle.diffusionT()[ivLocalIdx]; } //! In the interaction volume-local system of eq we have one unknown per face. diff --git a/dumux/discretization/cellcentered/mpfa/fourierslaw.hh b/dumux/discretization/cellcentered/mpfa/fourierslaw.hh index db27fa6202..5a69ad33ff 100644 --- a/dumux/discretization/cellcentered/mpfa/fourierslaw.hh +++ b/dumux/discretization/cellcentered/mpfa/fourierslaw.hh @@ -128,7 +128,7 @@ class FouriersLawImplementation const SubControlVolumeFace &scvf) { stencil_ = &iv.stencil(); - switchFluxSign_ = localFaceData.isOutside(); + switchFluxSign_ = localFaceData.isOutsideFace(); // store pointer to the temperature vector of this iv primaryTj_ = &dataHandle.temperatures(); @@ -137,8 +137,9 @@ class FouriersLawImplementation if (dim == dimWorld) primaryTij_ = &dataHandle.heatConductionT()[ivLocalIdx]; else - primaryTij_ = localFaceData.isOutside() ? &dataHandle.heatConductionTout()[ivLocalIdx][localFaceData.scvfLocalOutsideScvfIndex()] - : &dataHandle.heatConductionT()[ivLocalIdx]; + primaryTij_ = localFaceData.isOutsideFace() + ? &dataHandle.heatConductionTout()[ivLocalIdx][localFaceData.scvfLocalOutsideScvfIndex()] + : &dataHandle.heatConductionT()[ivLocalIdx]; } /*! @@ -157,7 +158,7 @@ class FouriersLawImplementation const SubControlVolumeFace &scvf) { stencil_ = &iv.stencil(); - switchFluxSign_ = localFaceData.isOutside(); + switchFluxSign_ = localFaceData.isOutsideFace(); // store pointer to the temperature vector of this iv secondaryTj_ = &dataHandle.temperatures(); @@ -166,8 +167,9 @@ class FouriersLawImplementation if (dim == dimWorld) secondaryTij_ = &dataHandle.heatConductionT()[ivLocalIdx]; else - secondaryTij_ = localFaceData.isOutside() ? &dataHandle.heatConductionTout()[ivLocalIdx][localFaceData.scvfLocalOutsideScvfIndex()] - : &dataHandle.heatConductionT()[ivLocalIdx]; + secondaryTij_ = localFaceData.isOutsideFace() + ? &dataHandle.heatConductionTout()[ivLocalIdx][localFaceData.scvfLocalOutsideScvfIndex()] + : &dataHandle.heatConductionT()[ivLocalIdx]; } //! Coefficients for the cell (& Dirichlet) unknowns in flux expressions (primary type) diff --git a/dumux/discretization/cellcentered/mpfa/localfacedata.hh b/dumux/discretization/cellcentered/mpfa/localfacedata.hh index 1fe6489b2d..4fec383779 100644 --- a/dumux/discretization/cellcentered/mpfa/localfacedata.hh +++ b/dumux/discretization/cellcentered/mpfa/localfacedata.hh @@ -32,7 +32,7 @@ namespace Dumux /*! * \ingroup CCMpfaDiscretization * \brief General implementation of a data structure holding interaction - * volume-local information for a grid subb-control volume face embedded in it. + * volume-local information for a grid sub-control volume face embedded in it. * * \tparam GridIndexType The type used for indices on the grid * \tparam LocalIndexType The type used for indices inside interaction volumes @@ -44,7 +44,7 @@ class InteractionVolumeLocalFaceData LocalIndexType ivLocalInsideScvIndex_; //!< the iv-local index of the scvfs' inside scv LocalIndexType scvfLocalOutsideScvfIndex_; //!< the index of this scvf in the scvf-local outside faces GridIndexType globalScvfIndex_; //!< the index of the corresponding global scvf - bool isOutside_; //!< indicates if this face maps to the iv-local index from "outside" + bool isOutside_; //!< indicates if this face is an "outside" face in the iv-local system public: //! Default constructor @@ -77,7 +77,7 @@ public: LocalIndexType ivLocalInsideScvIndex() const { return ivLocalInsideScvIndex_; } LocalIndexType scvfLocalOutsideScvfIndex() const { assert(isOutside_); return scvfLocalOutsideScvfIndex_; } GridIndexType globalScvfIndex() const { return globalScvfIndex_; } - bool isOutside() const { return isOutside_; } + bool isOutsideFace() const { return isOutside_; } }; } // end namespace diff --git a/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh b/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh index c0c35e8d7d..aeb4d2838f 100644 --- a/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh +++ b/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh @@ -115,7 +115,7 @@ public: for (const auto& localFaceData : iv.localFaceData()) { // continue only for "outside" faces - if (!localFaceData.isOutside()) + if (!localFaceData.isOutsideFace()) continue; const auto localScvIdx = localFaceData.ivLocalInsideScvIndex(); @@ -244,7 +244,7 @@ public: for (const auto& localFaceData : iv.localFaceData()) { // continue only for "outside" faces - if (!localFaceData.isOutside()) + if (!localFaceData.isOutsideFace()) continue; const auto localScvIdx = localFaceData.ivLocalInsideScvIndex(); @@ -580,7 +580,7 @@ public: for (const auto& localFaceData : iv.localFaceData()) { // continue only for "outside" faces - if (!localFaceData.isOutside()) + if (!localFaceData.isOutsideFace()) continue; const auto localScvIdx = localFaceData.ivLocalInsideScvIndex(); -- GitLab From 0d2adf573a826f381b5b5f6cc66726aaef11d82e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Gl=C3=A4ser?= Date: Thu, 15 Nov 2018 11:02:48 +0100 Subject: [PATCH 02/35] [mpfa] minor cleanup --- .../cellcentered/mpfa/dualgridindexset.hh | 8 ++--- .../cellcentered/mpfa/fvgridgeometry.hh | 12 ++++--- .../cellcentered/mpfa/helper.hh | 34 ++++++------------- 3 files changed, 20 insertions(+), 34 deletions(-) diff --git a/dumux/discretization/cellcentered/mpfa/dualgridindexset.hh b/dumux/discretization/cellcentered/mpfa/dualgridindexset.hh index 64802261dc..01c369b4ee 100644 --- a/dumux/discretization/cellcentered/mpfa/dualgridindexset.hh +++ b/dumux/discretization/cellcentered/mpfa/dualgridindexset.hh @@ -70,8 +70,8 @@ class CCMpfaDualGridNodalIndexSet using LI = typename T::LocalIndexType; using GI = typename T::GridIndexType; - using DimLocalIndexVector = Dune::ReservedVector; - using ScvfIndicesInScvStorage = typename T::template NodalScvDataStorage< DimLocalIndexVector >; + using DimIndexVector = Dune::ReservedVector; + using ScvfIndicesInScvStorage = typename T::template NodalScvDataStorage< DimIndexVector >; public: //! Export the traits type @@ -96,9 +96,7 @@ public: template void insert(const SubControlVolumeFace& scvf) { - insert(scvf.index(), - scvf.insideScvIdx(), - scvf.boundary()); + insert(scvf.index(), scvf.insideScvIdx(), scvf.boundary()); } //! Inserts scvf data diff --git a/dumux/discretization/cellcentered/mpfa/fvgridgeometry.hh b/dumux/discretization/cellcentered/mpfa/fvgridgeometry.hh index a1f315aec6..8c73955c03 100644 --- a/dumux/discretization/cellcentered/mpfa/fvgridgeometry.hh +++ b/dumux/discretization/cellcentered/mpfa/fvgridgeometry.hh @@ -166,7 +166,8 @@ public: //! Returns true if secondary interaction volumes are used around a given vertex (index). //! If the use of secondary interaction volumes is disabled, this can be evaluated at compile time. template = 0> - constexpr bool vertexUsesSecondaryInteractionVolume(GridIndexType vIdxGlobal) const { return false; } + constexpr bool vertexUsesSecondaryInteractionVolume(GridIndexType vIdxGlobal) const + { return false; } //! update all fvElementGeometries (do this again after grid adaption) void update() @@ -354,7 +355,7 @@ public: // building the geometries has finished std::cout << "Initializing of the grid finite volume geometry took " << timer.elapsed() << " seconds." << std::endl; - // Initialize the grid interaction volume seeds + // Initialize the grid interaction volume index sets timer.reset(); ivIndexSets_.update(*this, std::move(dualIdSet)); std::cout << "Initializing of the grid interaction volume index sets took " << timer.elapsed() << " seconds." << std::endl; @@ -533,7 +534,8 @@ public: //! Returns true if secondary interaction volumes are used around a given vertex (index). //! If the use of secondary interaction volumes is disabled, this can be evaluated at compile time. template = 0> - constexpr bool vertexUsesSecondaryInteractionVolume(GridIndexType vIdxGlobal) const { return false; } + constexpr bool vertexUsesSecondaryInteractionVolume(GridIndexType vIdxGlobal) const + { return false; } //! Returns true if a given vertex lies on a processor boundary inside a ghost element. bool isGhostVertex(const Vertex& v) const @@ -715,12 +717,12 @@ public: // building the geometries has finished std::cout << "Initializing of the grid finite volume geometry took " << timer.elapsed() << " seconds." << std::endl; - // Initialize the grid interaction volume seeds + // Initialize the grid interaction volume index sets timer.reset(); ivIndexSets_.update(*this, std::move(dualIdSet)); std::cout << "Initializing of the grid interaction volume index sets took " << timer.elapsed() << " seconds." << std::endl; - // build the connectivity map for an effecient assembly + // build the connectivity map for an efficient assembly timer.reset(); connectivityMap_.update(*this); std::cout << "Initializing of the connectivity map took " << timer.elapsed() << " seconds." << std::endl; diff --git a/dumux/discretization/cellcentered/mpfa/helper.hh b/dumux/discretization/cellcentered/mpfa/helper.hh index 318df5512a..63debf94c6 100644 --- a/dumux/discretization/cellcentered/mpfa/helper.hh +++ b/dumux/discretization/cellcentered/mpfa/helper.hh @@ -65,7 +65,6 @@ class MpfaDimensionHelper public: /*! * \brief Calculates the inner normal vectors to a given scv basis. - * * \param scvBasis The basis of an scv */ template< class ScvBasis > @@ -89,7 +88,6 @@ public: /*! * \brief Calculates the determinant of an scv basis. * This is equal to the cross product for dim = dimWorld = 2 - * * \param scvBasis The basis of an scv */ template< class ScvBasis > @@ -102,7 +100,6 @@ public: /*! * \brief Returns the global number of scvfs in the grid. Assumes the grid to be made up of only * basic geometry types. Overlad this function if you want to use different geometry types. - * * \param gridView The grid view to be checked */ static std::size_t getGlobalNumScvf(const GridView& gridView) @@ -118,7 +115,6 @@ public: /*! * \brief Checks whether or not a given scv basis forms a right hand system. - * * \param scvBasis The basis of an scv */ template< class ScvBasis > @@ -172,15 +168,12 @@ public: assert(cornerIdx < 2 && "provided index exceeds the number of corners of facets in 2d"); // create & return the scvf corner vector - if (cornerIdx == 0) - return ScvfCornerVector({p[0], p[1]}); - else - return ScvfCornerVector({p[0], p[2]}); + return cornerIdx == 0 ? ScvfCornerVector({p[0], p[1]}) + : ScvfCornerVector({p[0], p[2]}); } /*! * \brief Calculates the area of an scvf. - * * \param scvfCorners Container with the corners of the scvf */ static CoordScalar getScvfArea(const ScvfCornerVector& scvfCorners) @@ -188,7 +181,6 @@ public: /*! * \brief Calculates the number of scvfs in a given element geometry type. - * * \param gt The element geometry type */ static std::size_t getNumLocalScvfs(const Dune::GeometryType gt) @@ -209,7 +201,7 @@ public: */ template class MpfaDimensionHelper - : public MpfaDimensionHelper +: public MpfaDimensionHelper { using GridView = typename FVGridGeometry::GridView; using CoordScalar = typename GridView::ctype; @@ -217,18 +209,18 @@ public: /*! * \brief Calculates the inner normal vectors to a given scv basis. - * * \param scvBasis The basis of an scv */ template< class ScvBasis > static ScvBasis calculateInnerNormals(const ScvBasis& scvBasis) { // compute vector normal to the basis plane - const auto normal = [&] () { - auto n = crossProduct(scvBasis[0], scvBasis[1]); - n /= n.two_norm(); - return n; - } (); + const auto normal = [&scvBasis] () + { + auto n = crossProduct(scvBasis[0], scvBasis[1]); + n /= n.two_norm(); + return n; + } (); // compute inner normals using the normal vector ScvBasis innerNormals; @@ -302,11 +294,7 @@ public: innerNormals[2] = crossProduct(scvBasis[0], scvBasis[1]); if (!isRightHandSystem(scvBasis)) - { - innerNormals[0] *= -1.0; - innerNormals[1] *= -1.0; - innerNormals[2] *= -1.0; - } + std::for_each(innerNormals.begin(), innerNormals.end(), [] (auto& n) { n *= -1.0; }); return innerNormals; } @@ -349,7 +337,6 @@ public: /*! * \brief Checks whether or not a given scv basis forms a right hand system. - * * \param scvBasis The basis of an scv */ template< class ScvBasis > @@ -479,7 +466,6 @@ public: /*! * \brief Calculates the area of an scvf. - * * \param scvfCorners Container with the corners of the scvf */ static CoordScalar getScvfArea(const ScvfCornerVector& scvfCorners) -- GitLab From b52abfa456664ee0d8d3d26b71e37c13565cecd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Gl=C3=A4ser?= Date: Thu, 15 Nov 2018 11:15:47 +0100 Subject: [PATCH 03/35] [mpfa][properties] use mpfa-o as default for primary iv --- dumux/discretization/cellcentered/mpfa/properties.hh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/dumux/discretization/cellcentered/mpfa/properties.hh b/dumux/discretization/cellcentered/mpfa/properties.hh index 9741f71c65..44180aba17 100644 --- a/dumux/discretization/cellcentered/mpfa/properties.hh +++ b/dumux/discretization/cellcentered/mpfa/properties.hh @@ -73,8 +73,14 @@ public: template struct PrimaryInteractionVolume { +private: + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using NodalIndexSet = typename GET_PROP_TYPE(TypeTag, DualGridNodalIndexSet); + + // use the default traits + using Traits = CCMpfaODefaultInteractionVolumeTraits< NodalIndexSet, Scalar >; public: - using type = GetPropType; + using type = CCMpfaOInteractionVolume< Traits >; }; //! Per default, we use the dynamic mpfa-o interaction volume on boundaries -- GitLab From 83f4485d43de7844463828d7a74d9c5b4f558ab7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Gl=C3=A4ser?= Date: Thu, 15 Nov 2018 11:33:54 +0100 Subject: [PATCH 04/35] [mpfa][iv] make base class implementation-independent Not providing an overload for a function in the base class within the interaction volume implementation would have led to an infinite loop. We now throw if any of the functions are not overloaded. --- .../mpfa/interactionvolumebase.hh | 31 ++++++++----------- .../mpfa/omethod/interactionvolume.hh | 2 +- .../mpfa/omethod/staticinteractionvolume.hh | 2 +- 3 files changed, 15 insertions(+), 20 deletions(-) diff --git a/dumux/discretization/cellcentered/mpfa/interactionvolumebase.hh b/dumux/discretization/cellcentered/mpfa/interactionvolumebase.hh index fc14cadc8a..423c0381ed 100644 --- a/dumux/discretization/cellcentered/mpfa/interactionvolumebase.hh +++ b/dumux/discretization/cellcentered/mpfa/interactionvolumebase.hh @@ -59,16 +59,11 @@ namespace Dumux * \brief Base class for the interaction volumes of mpfa methods. It defines * the interface and actual implementations should derive from this class. * - * \tparam Impl The actual implementation of the interaction volume * \tparam T The traits class to be used */ -template< class Impl, class T > +template< class T > class CCMpfaInteractionVolumeBase { - // Curiously recurring template pattern - Impl& asImp() { return static_cast(*this); } - const Impl& asImp() const { return static_cast(*this); } - using GridView = typename T::GridView; using Element = typename GridView::template Codim<0>::Entity; @@ -86,50 +81,50 @@ public: void setUpLocalScope(const typename Traits::IndexSet& indexSet, const Problem& problem, const FVElementGeometry& fvGeometry) - { asImp().setUpLocalScope(); } + { DUNE_THROW(Dune::NotImplemented, "Interaction volume does not provide a setUpLocalScope() function"); } //! returns the number of "primary" scvfs of this interaction volume std::size_t numFaces() const - { return asImp().numFaces(); } + { DUNE_THROW(Dune::NotImplemented, "Interaction volume does not provide a numFaces() function"); } //! returns the number of intermediate unknowns within this interaction volume std::size_t numUnknowns() const - { return asImp().numUnknowns(); } + { DUNE_THROW(Dune::NotImplemented, "Interaction volume does not provide a numUnknowns() function"); } //! returns the number of (in this context) known solution values within this interaction volume std::size_t numKnowns() const - { return asImp().numKnowns(); } + { DUNE_THROW(Dune::NotImplemented, "Interaction volume does not provide a numKnowns() function"); } //! returns the number of scvs embedded in this interaction volume std::size_t numScvs() const - { return asImp().numScvs(); } + { DUNE_THROW(Dune::NotImplemented, "Interaction volume does not provide a numScvs() function"); } //! Returns a reference to the container with the local face data. The actual type of //! the container depends on the interaction volume implementation. At this point we throw //! an exception and force the implementation to overload this function. const std::vector& localFaceData() const - { DUNE_THROW(Dune::NotImplemented, "Interaction volume implementation does not provide a localFaceData() funtion"); } + { DUNE_THROW(Dune::NotImplemented, "Interaction volume does not provide a localFaceData() function"); } //! returns the cell-stencil of this interaction volume const NodalStencilType& stencil() const - { return asImp().stencil(); } + { DUNE_THROW(Dune::NotImplemented, "Interaction volume does not provide a stencil() function"); } //! returns the local scvf entity corresponding to a given iv-local scvf idx const LocalScvfType& localScvf(LocalIndexType ivLocalScvfIdx) const - { return asImp().localScvf(ivLocalScvfIdx); } + { DUNE_THROW(Dune::NotImplemented, "Interaction volume does not provide a localScvf() function"); } //! returns the local scv entity corresponding to a given iv-local scv idx const LocalScvType& localScv(LocalIndexType ivLocalScvIdx) const - { return asImp().localScv(ivLocalScvIdx); } + { DUNE_THROW(Dune::NotImplemented, "Interaction volume does not provide a localScv() function"); } //! returns the element in which the scv with the given local idx is embedded in const Element& element(LocalIndexType ivLocalScvIdx) const - { return asImp().element(); } + { DUNE_THROW(Dune::NotImplemented, "Interaction volume does not provide an element() function"); } //! returns the number of interaction volumes living around a vertex template< class NodalIndexSet > static std::size_t numIVAtVertex(const NodalIndexSet& nodalIndexSet) - { return Impl::numIVAtVertex(nodalIndexSet); } + { DUNE_THROW(Dune::NotImplemented, "Interaction volume does not provide a numIVAtVertex() function"); } //! adds the iv index sets living around a vertex to a given container //! and stores the the corresponding index in a map for each scvf @@ -141,7 +136,7 @@ public: ScvfIndexMap& scvfIndexMap, const NodalIndexSet& nodalIndexSet, const FlipScvfIndexSet& flipScvfIndexSet) - { Impl::addIVIndexSets(ivIndexSetContainer, scvfIndexMap, nodalIndexSet, flipScvfIndexSet); } + { DUNE_THROW(Dune::NotImplemented, "Interaction volume does not provide an addIVIndexSets() function"); } }; } // end namespace Dumux diff --git a/dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh b/dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh index d5fa3020cf..97c05b84b0 100644 --- a/dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh +++ b/dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh @@ -102,7 +102,7 @@ public: */ template< class Traits > class CCMpfaOInteractionVolume - : public CCMpfaInteractionVolumeBase< CCMpfaOInteractionVolume, Traits > +: public CCMpfaInteractionVolumeBase< Traits > { using GridView = typename Traits::GridView; using Element = typename GridView::template Codim<0>::Entity; diff --git a/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh b/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh index dec48f6ba8..04250ea70b 100644 --- a/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh +++ b/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh @@ -111,7 +111,7 @@ public: */ template< class Traits > class CCMpfaOStaticInteractionVolume - : public CCMpfaInteractionVolumeBase< CCMpfaOStaticInteractionVolume, Traits > +: public CCMpfaInteractionVolumeBase< Traits > { using GridView = typename Traits::GridView; using Element = typename GridView::template Codim<0>::Entity; -- GitLab From d5c7586443740a54fbdfddd41e10f1798d88a131 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Gl=C3=A4ser?= Date: Thu, 15 Nov 2018 12:39:47 +0100 Subject: [PATCH 05/35] [mpfa] apply naming convention on grid indices --- .../cellcentered/mpfa/dualgridindexset.hh | 14 +++---- .../mpfa/elementvolumevariables.hh | 2 +- .../mpfa/fluxvariablescachefiller.hh | 2 +- .../cellcentered/mpfa/localfacedata.hh | 12 +++--- .../mpfa/omethod/interactionvolume.hh | 15 ++++---- .../mpfa/omethod/interactionvolumeindexset.hh | 26 ++++++------- .../mpfa/omethod/localassembler.hh | 38 +++++++++---------- .../mpfa/omethod/localsubcontrolentities.hh | 12 +++--- .../mpfa/omethod/staticinteractionvolume.hh | 15 ++++---- dumux/discretization/fluxstencil.hh | 4 +- 10 files changed, 69 insertions(+), 71 deletions(-) diff --git a/dumux/discretization/cellcentered/mpfa/dualgridindexset.hh b/dumux/discretization/cellcentered/mpfa/dualgridindexset.hh index 01c369b4ee..fcd012caaf 100644 --- a/dumux/discretization/cellcentered/mpfa/dualgridindexset.hh +++ b/dumux/discretization/cellcentered/mpfa/dualgridindexset.hh @@ -146,11 +146,11 @@ public: { return numBoundaryScvfs_; } //! returns the grid scv indices connected to this dual grid node - const NodalGridStencilType& globalScvIndices() const + const NodalGridStencilType& gridScvIndices() const { return scvIndices_; } //! returns the grid scvf indices connected to this dual grid node - const NodalGridScvfStencilType& globalScvfIndices() const + const NodalGridScvfStencilType& gridScvfIndices() const { return scvfIndices_; } //! returns whether or not the i-th scvf is on a domain boundary @@ -161,21 +161,21 @@ public: } //! returns the grid scv idx of the i-th scv - GridIndexType scvIdxGlobal(unsigned int i) const + GridIndexType gridScvIndex(unsigned int i) const { assert(i < numScvs()); return scvIndices_[i]; } //! returns the index of the i-th scvf - GridIndexType scvfIdxGlobal(unsigned int i) const + GridIndexType gridScvfIndex(unsigned int i) const { assert(i < numScvfs()); return scvfIndices_[i]; } //! returns the grid index of the j-th scvf embedded in the i-th scv - GridIndexType scvfIdxGlobal(unsigned int i, unsigned int j) const + GridIndexType gridScvfIndex(unsigned int i, unsigned int j) const { assert(i < numScvs()); assert(j < localScvfIndicesInScv_[i].size()); @@ -183,7 +183,7 @@ public: } //! returns the node-local index of the j-th scvf embedded in the i-th scv - LocalIndexType scvfIdxLocal(unsigned int i, unsigned int j) const + LocalIndexType localScvfIndex(unsigned int i, unsigned int j) const { assert(i < numScvs()); assert(j < localScvfIndicesInScv_[i].size()); @@ -191,7 +191,7 @@ public: } //! returns the node-local index of the inside scv of the i-th scvf - LocalIndexType insideScvIdxLocal(unsigned int i) const + LocalIndexType insideScvLocalIndex(unsigned int i) const { assert(i < numScvfs()); return scvfInsideScvIndices_[i]; diff --git a/dumux/discretization/cellcentered/mpfa/elementvolumevariables.hh b/dumux/discretization/cellcentered/mpfa/elementvolumevariables.hh index 675980bf32..7f8635d08a 100644 --- a/dumux/discretization/cellcentered/mpfa/elementvolumevariables.hh +++ b/dumux/discretization/cellcentered/mpfa/elementvolumevariables.hh @@ -317,7 +317,7 @@ private: void addBoundaryVolVars_(const Problem& problem, const FVElementGeometry& fvGeometry, const NodalIndexSet& nodalIndexSet) { // check each scvf in the index set for boundary presence - for (auto scvfIdx : nodalIndexSet.globalScvfIndices()) + for (auto scvfIdx : nodalIndexSet.gridScvfIndices()) { const auto& ivScvf = fvGeometry.scvf(scvfIdx); diff --git a/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh b/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh index 8d8b4968a9..dfac3b1cb1 100644 --- a/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh +++ b/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh @@ -227,7 +227,7 @@ private: for (const auto& d : iv.localFaceData()) { // obtain the scvf - const auto& scvfJ = fvGeometry().scvf(d.globalScvfIndex()); + const auto& scvfJ = fvGeometry().scvf(d.gridScvfIndex()); ivScvfs[i] = &scvfJ; ivFluxVarCaches[i] = &fluxVarsCacheContainer[scvfJ]; ivFluxVarCaches[i]->setIvIndexInContainer(ivIndexInContainer); diff --git a/dumux/discretization/cellcentered/mpfa/localfacedata.hh b/dumux/discretization/cellcentered/mpfa/localfacedata.hh index 4fec383779..8cc387d95b 100644 --- a/dumux/discretization/cellcentered/mpfa/localfacedata.hh +++ b/dumux/discretization/cellcentered/mpfa/localfacedata.hh @@ -43,7 +43,7 @@ class InteractionVolumeLocalFaceData LocalIndexType ivLocalScvfIndex_; //!< the iv-local scvf index this scvf maps to LocalIndexType ivLocalInsideScvIndex_; //!< the iv-local index of the scvfs' inside scv LocalIndexType scvfLocalOutsideScvfIndex_; //!< the index of this scvf in the scvf-local outside faces - GridIndexType globalScvfIndex_; //!< the index of the corresponding global scvf + GridIndexType gridScvfIndex_; //!< the index of the corresponding global scvf bool isOutside_; //!< indicates if this face is an "outside" face in the iv-local system public: @@ -53,10 +53,10 @@ public: //! Constructor InteractionVolumeLocalFaceData(LocalIndexType faceIndex, LocalIndexType scvIndex, - GridIndexType globalScvfIndex) + GridIndexType gridScvfIndex) : ivLocalScvfIndex_(faceIndex) , ivLocalInsideScvIndex_(scvIndex) - , globalScvfIndex_(globalScvfIndex) + , gridScvfIndex_(gridScvfIndex) , isOutside_(false) {} @@ -64,11 +64,11 @@ public: InteractionVolumeLocalFaceData(LocalIndexType faceIndex, LocalIndexType scvIndex, LocalIndexType indexInScvfOutsideFaces, - GridIndexType globalScvfIndex) + GridIndexType gridScvfIndex) : ivLocalScvfIndex_(faceIndex) , ivLocalInsideScvIndex_(scvIndex) , scvfLocalOutsideScvfIndex_(indexInScvfOutsideFaces) - , globalScvfIndex_(globalScvfIndex) + , gridScvfIndex_(gridScvfIndex) , isOutside_(true) {} @@ -76,7 +76,7 @@ public: LocalIndexType ivLocalScvfIndex() const { return ivLocalScvfIndex_; } LocalIndexType ivLocalInsideScvIndex() const { return ivLocalInsideScvIndex_; } LocalIndexType scvfLocalOutsideScvfIndex() const { assert(isOutside_); return scvfLocalOutsideScvfIndex_; } - GridIndexType globalScvfIndex() const { return globalScvfIndex_; } + GridIndexType gridScvfIndex() const { return gridScvfIndex_; } bool isOutsideFace() const { return isOutside_; } }; diff --git a/dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh b/dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh index 97c05b84b0..4ed30d9eec 100644 --- a/dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh +++ b/dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh @@ -158,7 +158,7 @@ public: { // for the o-scheme, the stencil is equal to the scv // index set of the dual grid's nodal index set - stencil_ = &indexSet.nodalIndexSet().globalScvIndices(); + stencil_ = &indexSet.nodalIndexSet().gridScvIndices(); // number of interaction-volume-local scvs(=node-local for o-scheme) and scvfs numFaces_ = indexSet.numFaces(); @@ -178,13 +178,12 @@ public: localFaceData_.reserve(numGlobalScvfs); // set up stuff related to sub-control volumes - const auto& scvIndices = indexSet.globalScvIndices(); for (LocalIndexType scvIdxLocal = 0; scvIdxLocal < numLocalScvs; scvIdxLocal++) { - elements_.emplace_back(fvGeometry.fvGridGeometry().element( scvIndices[scvIdxLocal] )); + elements_.emplace_back(fvGeometry.fvGridGeometry().element( stencil()[scvIdxLocal] )); scvs_.emplace_back(fvGeometry.fvGridGeometry().mpfaHelper(), fvGeometry, - fvGeometry.scv( scvIndices[scvIdxLocal] ), + fvGeometry.scv( stencil()[scvIdxLocal] ), scvIdxLocal, indexSet); } @@ -197,7 +196,7 @@ public: wijk_.resize(numFaces_); for (LocalIndexType faceIdxLocal = 0; faceIdxLocal < numFaces_; ++faceIdxLocal) { - const auto& scvf = fvGeometry.scvf(indexSet.scvfIdxGlobal(faceIdxLocal)); + const auto& scvf = fvGeometry.scvf(indexSet.gridScvfIndex(faceIdxLocal)); // the neighboring scvs in local indices (order: 0 - inside scv, 1..n - outside scvs) const auto& neighborScvIndicesLocal = indexSet.neighboringLocalScvIndices(faceIdxLocal); @@ -233,9 +232,9 @@ public: const auto outsideLocalScvIdx = neighborScvIndicesLocal[i]; for (int coord = 0; coord < dim; ++coord) { - if (indexSet.scvfIdxLocal(outsideLocalScvIdx, coord) == faceIdxLocal) + if (indexSet.localScvfIndex(outsideLocalScvIdx, coord) == faceIdxLocal) { - const auto globalScvfIdx = indexSet.nodalIndexSet().scvfIdxGlobal(outsideLocalScvIdx, coord); + const auto globalScvfIdx = indexSet.nodalIndexSet().gridScvfIndex(outsideLocalScvIdx, coord); const auto& flipScvf = fvGeometry.scvf(globalScvfIdx); localFaceData_.emplace_back(faceIdxLocal, // iv-local scvf idx outsideLocalScvIdx, // iv-local scv index @@ -335,7 +334,7 @@ public: ivIndexSetContainer.emplace_back(nodalIndexSet, flipScvfIndexSet); // store the index mapping - for (const auto scvfIdx : nodalIndexSet.globalScvfIndices()) + for (const auto scvfIdx : nodalIndexSet.gridScvfIndices()) scvfIndexMap[scvfIdx] = curGlobalIndex; } diff --git a/dumux/discretization/cellcentered/mpfa/omethod/interactionvolumeindexset.hh b/dumux/discretization/cellcentered/mpfa/omethod/interactionvolumeindexset.hh index 2ab9082e1d..ca930c1651 100644 --- a/dumux/discretization/cellcentered/mpfa/omethod/interactionvolumeindexset.hh +++ b/dumux/discretization/cellcentered/mpfa/omethod/interactionvolumeindexset.hh @@ -78,7 +78,7 @@ public: // for scvfs touching the boundary there are no "outside" scvfs if (nodalIndexSet.scvfIsOnBoundary(i)) { - scvfNeighborScvLocalIndices_.push_back({nodalIndexSet.insideScvIdxLocal(i)}); + scvfNeighborScvLocalIndices_.push_back({nodalIndexSet.insideScvLocalIndex(i)}); nodeToIvScvf_[i] = ivToNodeScvf_.size(); isHandled[i] = true; ivToNodeScvf_.push_back(i); @@ -92,12 +92,12 @@ public: isHandled[i] = true; // construct local index sets - const auto& flipScvfIndices = flipScvfIndexSet[nodalIndexSet.scvfIdxGlobal(i)]; + const auto& flipScvfIndices = flipScvfIndexSet[nodalIndexSet.gridScvfIndex(i)]; const auto numFlipIndices = flipScvfIndices.size(); ScvfNeighborLocalIndexSet neighborsLocal; neighborsLocal.resize(numFlipIndices + 1); - neighborsLocal[0] = nodalIndexSet.insideScvIdxLocal(i); + neighborsLocal[0] = nodalIndexSet.insideScvLocalIndex(i); // mappings for all flip scvf for (unsigned int j = 0; j < numFlipIndices; ++j) @@ -105,9 +105,9 @@ public: const auto outsideScvfIdx = flipScvfIndices[j]; for (unsigned int nodeLocalIdx = 0; nodeLocalIdx < nodalIndexSet.numScvfs(); ++nodeLocalIdx) { - if (nodalIndexSet.scvfIdxGlobal(nodeLocalIdx) == outsideScvfIdx) + if (nodalIndexSet.gridScvfIndex(nodeLocalIdx) == outsideScvfIdx) { - neighborsLocal[j+1] = nodalIndexSet.insideScvIdxLocal(nodeLocalIdx); + neighborsLocal[j+1] = nodalIndexSet.insideScvLocalIndex(nodeLocalIdx); nodeToIvScvf_[nodeLocalIdx] = curIvLocalScvfIdx; isHandled[nodeLocalIdx] = true; break; // go to next outside scvf @@ -126,8 +126,8 @@ public: { return nodalIndexSet_; } //! returns the global scv indices connected to this dual grid node - const NodalGridStencilType& globalScvIndices() const - { return nodalIndexSet_.globalScvIndices(); } + const NodalGridStencilType& gridScvIndices() const + { return nodalIndexSet_.gridScvIndices(); } //! returns the number of faces in the interaction volume std::size_t numFaces() const @@ -137,18 +137,18 @@ public: std::size_t numScvs() const { return nodalIndexSet_.numScvs(); } - //! returns a global scvf idx for a given iv-local scvf index - GridIndexType scvfIdxGlobal(LocalIndexType ivLocalScvfIdx) const + //! returns a grid scvf idx for a given iv-local scvf index + GridIndexType gridScvfIndex(LocalIndexType ivLocalScvfIdx) const { assert(ivLocalScvfIdx < numFaces()); - return nodalIndexSet_.scvfIdxGlobal( ivToNodeScvf_[ivLocalScvfIdx] ); + return nodalIndexSet_.gridScvfIndex( ivToNodeScvf_[ivLocalScvfIdx] ); } //! returns the iv-local scvf idx of the i-th scvf embedded in a local scv - LocalIndexType scvfIdxLocal(LocalIndexType scvIdxLocal, unsigned int i) const + LocalIndexType localScvfIndex(LocalIndexType scvIdxLocal, unsigned int i) const { - assert(nodalIndexSet_.scvfIdxLocal(scvIdxLocal, i) < nodeToIvScvf_.size()); - return nodeToIvScvf_[ nodalIndexSet_.scvfIdxLocal(scvIdxLocal, i) ]; + assert(nodalIndexSet_.localScvfIndex(scvIdxLocal, i) < nodeToIvScvf_.size()); + return nodeToIvScvf_[ nodalIndexSet_.localScvfIndex(scvIdxLocal, i) ]; } //! returns the local indices of the neighboring scvs of an scvf diff --git a/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh b/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh index aeb4d2838f..82aa7b8273 100644 --- a/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh +++ b/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh @@ -133,7 +133,7 @@ public: for (LocalIndexType localDir = 0; localDir < IV::Traits::GridView::dimension; localDir++) { // the scvf corresponding to this local direction in the scv - const auto& curLocalScvf = iv.localScvf(posLocalScv.scvfIdxLocal(localDir)); + const auto& curLocalScvf = iv.localScvf(posLocalScv.localScvfIndex(localDir)); // on interior faces the coefficients of the AB matrix come into play if (!curLocalScvf.isDirichlet()) @@ -262,7 +262,7 @@ public: for (LocalIndexType localDir = 0; localDir < IV::Traits::GridView::dimension; localDir++) { // the scvf corresponding to this local direction in the scv - const auto& curLocalScvf = iv.localScvf(posLocalScv.scvfIdxLocal(localDir)); + const auto& curLocalScvf = iv.localScvf(posLocalScv.localScvfIndex(localDir)); // on interior faces the coefficients of the AB matrix come into play if (!curLocalScvf.isDirichlet()) @@ -300,7 +300,7 @@ public: // put the cell pressures first using LocalIndexType = typename IV::Traits::IndexSet::LocalIndexType; for (LocalIndexType i = 0; i < iv.numScvs(); ++i) - u[i] = getU( iv.localScv(i).globalScvIndex() ); + u[i] = getU( iv.localScv(i).gridScvIndex() ); // Dirichlet BCs come afterwards LocalIndexType i = iv.numScvs(); @@ -363,13 +363,13 @@ public: { // gravitational acceleration on this face const auto& curLocalScvf = iv.localScvf(faceIdx); - const auto& curGlobalScvf = this->fvGeometry().scvf(curLocalScvf.globalScvfIndex()); + const auto& curGlobalScvf = this->fvGeometry().scvf(curLocalScvf.gridScvfIndex()); const auto gravity = this->problem().gravityAtPos(curGlobalScvf.ipGlobal()); // get permeability tensor in "positive" sub volume const auto& neighborScvIndices = curLocalScvf.neighboringLocalScvIndices(); const auto& posLocalScv = iv.localScv(neighborScvIndices[0]); - const auto& posGlobalScv = this->fvGeometry().scv(posLocalScv.globalScvIndex()); + const auto& posGlobalScv = this->fvGeometry().scv(posLocalScv.gridScvIndex()); const auto& posVolVars = this->elemVolVars()[posGlobalScv]; const auto& posElement = iv.element(neighborScvIndices[0]); const auto tensor = getT(this->problem(), posElement, posVolVars, this->fvGeometry(), posGlobalScv); @@ -388,7 +388,7 @@ public: { // obtain outside tensor const auto& negLocalScv = iv.localScv( neighborScvIndices[1] ); - const auto& negGlobalScv = this->fvGeometry().scv(negLocalScv.globalScvIndex()); + const auto& negGlobalScv = this->fvGeometry().scv(negLocalScv.gridScvIndex()); const auto& negVolVars = this->elemVolVars()[negGlobalScv]; const auto& negElement = iv.element( neighborScvIndices[1] ); const auto negTensor = getT(this->problem(), negElement, negVolVars, this->fvGeometry(), negGlobalScv); @@ -497,13 +497,13 @@ public: { // gravitational acceleration on this face const auto& curLocalScvf = iv.localScvf(faceIdx); - const auto& curGlobalScvf = this->fvGeometry().scvf(curLocalScvf.globalScvfIndex()); + const auto& curGlobalScvf = this->fvGeometry().scvf(curLocalScvf.gridScvfIndex()); const auto gravity = this->problem().gravityAtPos(curGlobalScvf.ipGlobal()); // get permeability tensor in "positive" sub volume const auto& neighborScvIndices = curLocalScvf.neighboringLocalScvIndices(); const auto& posLocalScv = iv.localScv(neighborScvIndices[0]); - const auto& posGlobalScv = this->fvGeometry().scv(posLocalScv.globalScvIndex()); + const auto& posGlobalScv = this->fvGeometry().scv(posLocalScv.gridScvIndex()); const auto& posVolVars = this->elemVolVars()[posGlobalScv]; const auto& posElement = iv.element(neighborScvIndices[0]); const auto tensor = getT(this->problem(), posElement, posVolVars, this->fvGeometry(), posGlobalScv); @@ -526,7 +526,7 @@ public: { // obtain outside tensor const auto& negLocalScv = iv.localScv( neighborScvIndices[idxInOutside] ); - const auto& negGlobalScv = this->fvGeometry().scv(negLocalScv.globalScvIndex()); + const auto& negGlobalScv = this->fvGeometry().scv(negLocalScv.gridScvIndex()); const auto& negVolVars = this->elemVolVars()[negGlobalScv]; const auto& negElement = iv.element( neighborScvIndices[idxInOutside] ); const auto negTensor = getT(this->problem(), negElement, negVolVars, this->fvGeometry(), negGlobalScv); @@ -596,7 +596,7 @@ public: for (LocalIndexType localDir = 0; localDir < IV::Traits::GridView::dimension; localDir++) { // the scvf corresponding to this local direction in the scv - const auto& curLocalScvf = iv.localScvf(posLocalScv.scvfIdxLocal(localDir)); + const auto& curLocalScvf = iv.localScvf(posLocalScv.localScvfIndex(localDir)); // on interior faces the coefficients of the AB matrix come into play if (!curLocalScvf.isDirichlet()) @@ -655,12 +655,12 @@ private: for (LocalIndexType faceIdx = 0; faceIdx < iv.numFaces(); ++faceIdx) { const auto& curLocalScvf = iv.localScvf(faceIdx); - const auto& curGlobalScvf = this->fvGeometry().scvf(curLocalScvf.globalScvfIndex()); + const auto& curGlobalScvf = this->fvGeometry().scvf(curLocalScvf.gridScvfIndex()); const auto& neighborScvIndices = curLocalScvf.neighboringLocalScvIndices(); // get tensor in "positive" sub volume const auto& posLocalScv = iv.localScv(neighborScvIndices[0]); - const auto& posGlobalScv = this->fvGeometry().scv(posLocalScv.globalScvIndex()); + const auto& posGlobalScv = this->fvGeometry().scv(posLocalScv.gridScvIndex()); const auto& posVolVars = this->elemVolVars()[posGlobalScv]; const auto& posElement = iv.element(neighborScvIndices[0]); const auto tensor = getT(this->problem(), posElement, posVolVars, this->fvGeometry(), posGlobalScv); @@ -671,7 +671,7 @@ private: const auto posScvLocalDofIdx = posLocalScv.localDofIndex(); for (LocalIndexType localDir = 0; localDir < dim; localDir++) { - const auto& otherLocalScvf = iv.localScvf( posLocalScv.scvfIdxLocal(localDir) ); + const auto& otherLocalScvf = iv.localScvf( posLocalScv.localScvfIndex(localDir) ); const auto otherLocalDofIdx = otherLocalScvf.localDofIndex(); D[faceIdx][otherLocalDofIdx] -= wijk[localDir]; D[faceIdx][posScvLocalDofIdx] += wijk[localDir]; @@ -695,14 +695,14 @@ private: for (LocalIndexType faceIdx = 0; faceIdx < iv.numFaces(); ++faceIdx) { const auto& curLocalScvf = iv.localScvf(faceIdx); - const auto& curGlobalScvf = this->fvGeometry().scvf(curLocalScvf.globalScvfIndex()); + const auto& curGlobalScvf = this->fvGeometry().scvf(curLocalScvf.gridScvfIndex()); const auto curIsDirichlet = curLocalScvf.isDirichlet(); const auto curLocalDofIdx = curLocalScvf.localDofIndex(); // get tensor in "positive" sub volume const auto& neighborScvIndices = curLocalScvf.neighboringLocalScvIndices(); const auto& posLocalScv = iv.localScv(neighborScvIndices[0]); - const auto& posGlobalScv = this->fvGeometry().scv(posLocalScv.globalScvIndex()); + const auto& posGlobalScv = this->fvGeometry().scv(posLocalScv.gridScvIndex()); const auto& posVolVars = this->elemVolVars()[posGlobalScv]; const auto& posElement = iv.element(neighborScvIndices[0]); const auto tensor = getT(this->problem(), posElement, posVolVars, this->fvGeometry(), posGlobalScv); @@ -713,7 +713,7 @@ private: // go over the coordinate directions in the positive sub volume for (unsigned int localDir = 0; localDir < dim; localDir++) { - const auto& otherLocalScvf = iv.localScvf( posLocalScv.scvfIdxLocal(localDir) ); + const auto& otherLocalScvf = iv.localScvf( posLocalScv.localScvfIndex(localDir) ); const auto otherLocalDofIdx = otherLocalScvf.localDofIndex(); // if we are not on a Dirichlet face, add entries associated with unknown face pressures @@ -748,7 +748,7 @@ private: { const auto idxOnScvf = idxInOutside+1; const auto& negLocalScv = iv.localScv( neighborScvIndices[idxOnScvf] ); - const auto& negGlobalScv = this->fvGeometry().scv(negLocalScv.globalScvIndex()); + const auto& negGlobalScv = this->fvGeometry().scv(negLocalScv.gridScvIndex()); const auto& negVolVars = this->elemVolVars()[negGlobalScv]; const auto& negElement = iv.element( neighborScvIndices[idxOnScvf] ); const auto negTensor = getT(this->problem(), negElement, negVolVars, this->fvGeometry(), negGlobalScv); @@ -762,10 +762,10 @@ private: if (dim < dimWorld) wijk[faceIdx][idxOnScvf] *= -1.0; - // go over the coordinate directions in the positive sub volume + // go over the coordinate directions in the negative sub volume for (int localDir = 0; localDir < dim; localDir++) { - const auto otherLocalScvfIdx = negLocalScv.scvfIdxLocal(localDir); + const auto otherLocalScvfIdx = negLocalScv.localScvfIndex(localDir); const auto& otherLocalScvf = iv.localScvf(otherLocalScvfIdx); const auto otherLocalDofIdx = otherLocalScvf.localDofIndex(); diff --git a/dumux/discretization/cellcentered/mpfa/omethod/localsubcontrolentities.hh b/dumux/discretization/cellcentered/mpfa/omethod/localsubcontrolentities.hh index 32f2775f43..6c492a60a4 100644 --- a/dumux/discretization/cellcentered/mpfa/omethod/localsubcontrolentities.hh +++ b/dumux/discretization/cellcentered/mpfa/omethod/localsubcontrolentities.hh @@ -82,7 +82,7 @@ public: LocalBasis localBasis; for (unsigned int coordIdx = 0; coordIdx < myDimension; ++coordIdx) { - const auto scvfIdx = indexSet.nodalIndexSet().scvfIdxGlobal(localDofIndex_, coordIdx); + const auto scvfIdx = indexSet.nodalIndexSet().gridScvfIndex(localDofIndex_, coordIdx); const auto& scvf = fvGeometry.scvf(scvfIdx); localBasis[coordIdx] = scvf.ipGlobal(); localBasis[coordIdx] -= center; @@ -96,8 +96,8 @@ public: ctype detX() const { return detX_; } - //! grid view-global index related to this scv - GridIndexType globalScvIndex() const + //! grid index related to this scv + GridIndexType gridScvIndex() const { return globalScvIndex_; } //! returns the index in the set of cell unknowns of the iv @@ -105,10 +105,10 @@ public: { return localDofIndex_; } //! iv-local index of the coordir's scvf in this scv - LocalIndexType scvfIdxLocal(unsigned int coordDir) const + LocalIndexType localScvfIndex(unsigned int coordDir) const { assert(coordDir < myDimension); - return indexSet_->scvfIdxLocal(localDofIndex_, coordDir); + return indexSet_->localScvfIndex(localDofIndex_, coordDir); } //! the nu vectors are needed for setting up the omegas of the iv @@ -170,7 +170,7 @@ public: LocalIndexType localDofIndex() const { return localDofIndex_; } //! returns the grid view-global index of this scvf - GridIndexType globalScvfIndex() const { return scvfIdxGlobal_; } + GridIndexType gridScvfIndex() const { return scvfIdxGlobal_; } //! Returns the local indices of the scvs neighboring this scvf const ScvfNeighborLocalIndexSet& neighboringLocalScvIndices() const { return *neighborScvIndicesLocal_; } diff --git a/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh b/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh index 04250ea70b..c27a3f0598 100644 --- a/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh +++ b/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh @@ -159,16 +159,15 @@ public: // for the o-scheme, the stencil is equal to the scv // index set of the dual grid's nodal index set assert(indexSet.numScvs() == numScv); - stencil_ = &indexSet.nodalIndexSet().globalScvIndices(); + stencil_ = &indexSet.nodalIndexSet().gridScvIndices(); // set up stuff related to sub-control volumes - const auto& scvIndices = indexSet.globalScvIndices(); for (LocalIndexType scvIdxLocal = 0; scvIdxLocal < numScv; scvIdxLocal++) { - elements_[scvIdxLocal] = fvGeometry.fvGridGeometry().element( scvIndices[scvIdxLocal] ); + elements_[scvIdxLocal] = fvGeometry.fvGridGeometry().element( stencil()[scvIdxLocal] ); scvs_[scvIdxLocal] = LocalScvType(fvGeometry.fvGridGeometry().mpfaHelper(), fvGeometry, - fvGeometry.scv( scvIndices[scvIdxLocal] ), + fvGeometry.scv( stencil()[scvIdxLocal] ), scvIdxLocal, indexSet); } @@ -176,7 +175,7 @@ public: // set up quantitites related to sub-control volume faces for (LocalIndexType faceIdxLocal = 0; faceIdxLocal < numScvf; ++faceIdxLocal) { - const auto& scvf = fvGeometry.scvf(indexSet.scvfIdxGlobal(faceIdxLocal)); + const auto& scvf = fvGeometry.scvf(indexSet.gridScvfIndex(faceIdxLocal)); // the neighboring scvs in local indices (order: 0 - inside scv, 1..n - outside scvs) const auto& neighborScvIndicesLocal = indexSet.neighboringLocalScvIndices(faceIdxLocal); @@ -193,9 +192,9 @@ public: const auto outsideLocalScvIdx = neighborScvIndicesLocal[1]; for (int coord = 0; coord < dim; ++coord) { - if (indexSet.scvfIdxLocal(outsideLocalScvIdx, coord) == faceIdxLocal) + if (indexSet.localScvfIndex(outsideLocalScvIdx, coord) == faceIdxLocal) { - const auto globalScvfIdx = indexSet.nodalIndexSet().scvfIdxGlobal(outsideLocalScvIdx, coord); + const auto globalScvfIdx = indexSet.nodalIndexSet().gridScvfIndex(outsideLocalScvIdx, coord); const auto& flipScvf = fvGeometry.scvf(globalScvfIdx); localFaceData_[faceIdxLocal*2+1] = LocalFaceData(faceIdxLocal, // iv-local scvf idx outsideLocalScvIdx, // iv-local scv index @@ -295,7 +294,7 @@ public: ivIndexSetContainer.emplace_back(nodalIndexSet, flipScvfIndexSet); // store the index mapping - for (const auto scvfIdx : nodalIndexSet.globalScvfIndices()) + for (const auto scvfIdx : nodalIndexSet.gridScvfIndices()) scvfIndexMap[scvfIdx] = curGlobalIndex; } diff --git a/dumux/discretization/fluxstencil.hh b/dumux/discretization/fluxstencil.hh index fb3e859234..c601e6f1cc 100644 --- a/dumux/discretization/fluxstencil.hh +++ b/dumux/discretization/fluxstencil.hh @@ -117,9 +117,9 @@ public: // return the scv (element) indices in the interaction region if (fvGridGeometry.vertexUsesSecondaryInteractionVolume(scvf.vertexIndex())) - return fvGridGeometry.gridInteractionVolumeIndexSets().secondaryIndexSet(scvf).globalScvIndices(); + return fvGridGeometry.gridInteractionVolumeIndexSets().secondaryIndexSet(scvf).gridScvIndices(); else - return fvGridGeometry.gridInteractionVolumeIndexSets().primaryIndexSet(scvf).globalScvIndices(); + return fvGridGeometry.gridInteractionVolumeIndexSets().primaryIndexSet(scvf).gridScvIndices(); } }; -- GitLab From 177ea2a403fa96a45a28cf40f8b2569a1e462f7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Gl=C3=A4ser?= Date: Thu, 15 Nov 2018 15:12:57 +0100 Subject: [PATCH 06/35] [mpfa][ivdatahandle] get rid of resize overload for surface grids --- .../mpfa/interactionvolumedatahandle.hh | 102 +++++++----------- 1 file changed, 36 insertions(+), 66 deletions(-) diff --git a/dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh b/dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh index 72e2ddc632..e768aa65ac 100644 --- a/dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh +++ b/dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh @@ -46,7 +46,7 @@ public: template class AdvectionDataHandle { - // export matrix & vector types from interaction volume + // obtain matrix & vector types from interaction volume using AMatrix = typename MatVecTraits::AMatrix; using CMatrix = typename MatVecTraits::CMatrix; using TMatrix = typename MatVecTraits::TMatrix; @@ -59,74 +59,42 @@ class AdvectionDataHandle public: - //! prepare data handle for subsequent fill (normal grids) - template< class IV, - std::enable_if_t<(IV::Traits::GridView::dimension==IV::Traits::GridView::dimensionworld), int> = 0> - void resize(const IV& iv) - { - // resize transmissibility matrix & pressure vectors - resizeMatrix(T_, iv.numFaces(), iv.numKnowns()); - for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) - resizeVector(p_[pIdx], iv.numKnowns()); - - // maybe resize gravity container - static const bool enableGravity = getParam("Problem.EnableGravity"); - if (enableGravity) - { - resizeMatrix(CA_, iv.numFaces(), iv.numUnknowns()); - for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) - resizeVector(g_[pIdx], iv.numFaces()); - } - } - - - //! prepare data handle for subsequent fill (surface grids) - template< class IV, - std::enable_if_t<(IV::Traits::GridView::dimension = 0> + //! prepare data handle for subsequent fill + template< class IV > void resize(const IV& iv) { using LocalIndexType = typename IV::Traits::IndexSet::LocalIndexType; - static const bool enableGravity = getParam("Problem.EnableGravity"); - if (!enableGravity) - { - resizeMatrix(T_, iv.numFaces(), iv.numKnowns()); - outsideT_.resize(iv.numFaces()); + // resize matrices + resizeMatrix(T_, iv.numFaces(), iv.numKnowns()); + resizeMatrix(A_, iv.numUnknowns(), iv.numUnknowns()); + resizeMatrix(CA_, iv.numFaces(), iv.numUnknowns()); - for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) - resizeVector(p_[pIdx], iv.numKnowns()); - for (LocalIndexType i = 0; i < iv.numFaces(); ++i) - { - const auto numNeighbors = iv.localScvf(i).neighboringLocalScvIndices().size() - 1; - outsideT_[i].resize(numNeighbors); - for (LocalIndexType j = 0; j < numNeighbors; ++j) - resizeVector(outsideT_[i][j], iv.numKnowns()); - } - } + // lambdas to resize a vector + auto resizeToNumFaces = [&iv] (auto& v) { resizeVector(v, iv.numFaces()); }; + auto resizeToNumKnowns = [&iv] (auto& v) { resizeVector(v, iv.numKnowns()); }; + + // resize pressure/gravity vector + std::for_each(p_.begin(), p_.end(), resizeToNumKnowns); + std::for_each(g_.begin(), g_.end(), resizeToNumFaces); - else + // on surface grids, resize additional containers + static constexpr int dim = IV::Traits::GridView::dimension; + static constexpr int dimWorld = IV::Traits::GridView::dimensionworld; + if (dim < dimWorld) { - resizeMatrix(T_, iv.numFaces(), iv.numKnowns()); - resizeMatrix(CA_, iv.numFaces(), iv.numUnknowns()); - resizeMatrix(A_, iv.numUnknowns(), iv.numUnknowns()); outsideT_.resize(iv.numFaces()); + std::for_each(outsideG_.begin(), outsideG_.end(), resizeToNumFaces); - for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) - { - resizeVector(p_[pIdx], iv.numKnowns()); - resizeVector(g_[pIdx], iv.numFaces()); - outsideG_[pIdx].resize(iv.numFaces()); - } - + // resize the entries for each face for (LocalIndexType i = 0; i < iv.numFaces(); ++i) { - const auto numNeighbors = iv.localScvf(i).neighboringLocalScvIndices().size() - 1; + const auto& localScvf = iv.localScvf(i); + const auto numNeighbors = localScvf.neighboringLocalScvIndices().size()-1; outsideT_[i].resize(numNeighbors); - for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) - resizeVector(outsideG_[pIdx][i], numNeighbors); - for (LocalIndexType j = 0; j < numNeighbors; ++j) - resizeVector(outsideT_[i][j], iv.numKnowns()); + std::for_each(outsideT_[i].begin(), outsideT_[i].end(), resizeToNumKnowns); + std::for_each(outsideG_.begin(), outsideG_.end(), [&] (auto& v) { resizeVector(v[i], numNeighbors); }); } } } @@ -135,7 +103,7 @@ public: const CellVector& pressures(unsigned int pIdx) const { return p_[pIdx]; } CellVector& pressures(unsigned int pIdx) { return p_[pIdx]; } - //! Access to the gravitational flux contributions for one phase + //! The gravitational flux contributions for a phase on all faces const FaceVector& gravity(unsigned int pIdx) const { return g_[pIdx]; } FaceVector& gravity(unsigned int pIdx) { return g_[pIdx]; } @@ -143,15 +111,16 @@ public: const std::array< FaceVector, numPhases >& gravity() const { return g_; } std::array< FaceVector, numPhases >& gravity() { return g_; } - //! Projection matrix for gravitational acceleration + + //! Projection matrix for Neumann/gravity contribution computation const CMatrix& advectionCA() const { return CA_; } CMatrix& advectionCA() { return CA_; } - //! Additional projection matrix needed on surface grids + //! Inverse of the iv-local system matrix const AMatrix& advectionA() const { return A_; } AMatrix& advectionA() { return A_; } - //! The transmissibilities associated with advective fluxes + //! The transmissibility matrix (i.e. C*(A^-1)*B + D) const TMatrix& advectionT() const { return T_; } TMatrix& advectionT() { return T_; } @@ -168,9 +137,9 @@ public: OutsideGravityStorage& gravityOutside(unsigned int pIdx) { return outsideG_[pIdx]; } private: - TMatrix T_; //!< The transmissibilities such that f_i = T_ij*p_j - CMatrix CA_; //!< Matrix to project gravitational acceleration to all scvfs - AMatrix A_; //!< Matrix additionally needed for the projection on surface grids + TMatrix T_; //!< The transmissibilities such that f_i = T_ij*p_j (... + Neumann/gravity contributions) + AMatrix A_; //!< Inverse of the iv-local system matrix (needed e.g. for face pressure reconstruction) + CMatrix CA_; //!< A_ right multiplied to C (needed e.g. for Neumann/gravity contribution computation) std::array< CellVector, numPhases > p_; //!< The interaction volume-wide phase pressures std::array< FaceVector, numPhases > g_; //!< The gravitational acceleration at each scvf (only for enabled gravity) std::vector< std::vector > outsideT_; //!< The transmissibilities for "outside" faces (only on surface grids) @@ -313,9 +282,10 @@ class HeatConductionDataHandle : public Empt * \tparam PT The physics traits collecting data on the physical processes to be considered */ template -class InteractionVolumeDataHandle : public AdvectionDataHandle, - public DiffusionDataHandle, - public HeatConductionDataHandle +class InteractionVolumeDataHandle +: public AdvectionDataHandle +, public DiffusionDataHandle +, public HeatConductionDataHandle { using AdvectionHandle = AdvectionDataHandle; using DiffusionHandle = DiffusionDataHandle; -- GitLab From ca47f527bf82cd4b7fb769e3f8463db2d7533610 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Gl=C3=A4ser?= Date: Thu, 15 Nov 2018 16:57:47 +0100 Subject: [PATCH 07/35] [mpfa][ivdatahandle] get rid of resize method Resizing of the matrices place in the local assembler directly wherr needed. This has a small negative impact on performance but saves a lot of code. --- .../mpfa/fluxvariablescachefiller.hh | 2 - .../mpfa/interactionvolumedatahandle.hh | 122 +----------------- .../mpfa/omethod/localassembler.hh | 80 +++++++++--- 3 files changed, 61 insertions(+), 143 deletions(-) diff --git a/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh b/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh index dfac3b1cb1..0a59d20489 100644 --- a/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh +++ b/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh @@ -125,7 +125,6 @@ public: // prepare the corresponding data handle fluxVarsCacheContainer.secondaryDataHandles().emplace_back(); secondaryIvDataHandle_ = &fluxVarsCacheContainer.secondaryDataHandles().back(); - secondaryIvDataHandle_->resize(*secondaryIv_); // fill the caches for all the scvfs in the interaction volume fillCachesInInteractionVolume_(fluxVarsCacheContainer, *secondaryIv_, *secondaryIvDataHandle_, ivIndexInContainer, true); @@ -156,7 +155,6 @@ public: // prepare the corresponding data handle fluxVarsCacheContainer.primaryDataHandles().emplace_back(); primaryIvDataHandle_ = &fluxVarsCacheContainer.primaryDataHandles().back(); - primaryIvDataHandle_->resize(*primaryIv_); // fill the caches for all the scvfs in the interaction volume fillCachesInInteractionVolume_(fluxVarsCacheContainer, *primaryIv_, *primaryIvDataHandle_, ivIndexInContainer, true); diff --git a/dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh b/dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh index e768aa65ac..863bc739d8 100644 --- a/dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh +++ b/dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh @@ -29,18 +29,12 @@ #include #include -#include namespace Dumux { //! Empty data handle class -class EmptyDataHandle -{ -public: - template< class InteractionVolume > - void resize(const InteractionVolume& iv) {} -}; +class EmptyDataHandle {}; //! Data handle for quantities related to advection template @@ -58,47 +52,6 @@ class AdvectionDataHandle static constexpr int numPhases = PhysicsTraits::numPhases; public: - - //! prepare data handle for subsequent fill - template< class IV > - void resize(const IV& iv) - { - using LocalIndexType = typename IV::Traits::IndexSet::LocalIndexType; - - // resize matrices - resizeMatrix(T_, iv.numFaces(), iv.numKnowns()); - resizeMatrix(A_, iv.numUnknowns(), iv.numUnknowns()); - resizeMatrix(CA_, iv.numFaces(), iv.numUnknowns()); - - // lambdas to resize a vector - auto resizeToNumFaces = [&iv] (auto& v) { resizeVector(v, iv.numFaces()); }; - auto resizeToNumKnowns = [&iv] (auto& v) { resizeVector(v, iv.numKnowns()); }; - - // resize pressure/gravity vector - std::for_each(p_.begin(), p_.end(), resizeToNumKnowns); - std::for_each(g_.begin(), g_.end(), resizeToNumFaces); - - // on surface grids, resize additional containers - static constexpr int dim = IV::Traits::GridView::dimension; - static constexpr int dimWorld = IV::Traits::GridView::dimensionworld; - if (dim < dimWorld) - { - outsideT_.resize(iv.numFaces()); - std::for_each(outsideG_.begin(), outsideG_.end(), resizeToNumFaces); - - // resize the entries for each face - for (LocalIndexType i = 0; i < iv.numFaces(); ++i) - { - const auto& localScvf = iv.localScvf(i); - const auto numNeighbors = localScvf.neighboringLocalScvIndices().size()-1; - outsideT_[i].resize(numNeighbors); - - std::for_each(outsideT_[i].begin(), outsideT_[i].end(), resizeToNumKnowns); - std::for_each(outsideG_.begin(), outsideG_.end(), [&] (auto& v) { resizeVector(v[i], numNeighbors); }); - } - } - } - //! Access to the iv-wide pressure of one phase const CellVector& pressures(unsigned int pIdx) const { return p_[pIdx]; } CellVector& pressures(unsigned int pIdx) { return p_[pIdx]; } @@ -111,7 +64,6 @@ public: const std::array< FaceVector, numPhases >& gravity() const { return g_; } std::array< FaceVector, numPhases >& gravity() { return g_; } - //! Projection matrix for Neumann/gravity contribution computation const CMatrix& advectionCA() const { return CA_; } CMatrix& advectionCA() { return CA_; } @@ -162,37 +114,6 @@ public: void setPhaseIndex(unsigned int phaseIdx) { phaseIdx_ = phaseIdx; } void setComponentIndex(unsigned int compIdx) { compIdx_ = compIdx; } - //! prepare data handle for subsequent fill - template< class InteractionVolume > - void resize(const InteractionVolume& iv) - { - for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) - { - for (unsigned int cIdx = 0; cIdx < numComponents; ++cIdx) - { - // resize transmissibility matrix & mole fraction vector - resizeMatrix(T_[pIdx][cIdx], iv.numFaces(), iv.numKnowns()); - resizeVector(xj_[pIdx][cIdx], iv.numKnowns()); - - // resize outsideTij on surface grids - using GridView = typename InteractionVolume::Traits::GridView; - if (int(GridView::dimension) < int(GridView::dimensionworld)) - { - outsideT_[pIdx][cIdx].resize(iv.numFaces()); - - using LocalIndexType = typename InteractionVolume::Traits::IndexSet::LocalIndexType; - for (LocalIndexType i = 0; i < iv.numFaces(); ++i) - { - const auto numNeighbors = iv.localScvf(i).neighboringLocalScvIndices().size() - 1; - outsideT_[pIdx][cIdx][i].resize(numNeighbors); - for (LocalIndexType j = 0; j < numNeighbors; ++j) - resizeVector(outsideT_[pIdx][cIdx][i][j], iv.numKnowns()); - } - } - } - } - } - //! Access to the iv-wide mole fractions of a component in one phase const CellVector& moleFractions(unsigned int pIdx, unsigned int compIdx) const { return xj_[pIdx][compIdx]; } CellVector& moleFractions(unsigned int pIdx, unsigned int compIdx) { return xj_[pIdx][compIdx]; } @@ -222,31 +143,6 @@ class HeatConductionDataHandle using CellVector = typename MatVecTraits::CellVector; public: - //! prepare data handle for subsequent fill - template< class InteractionVolume > - void resize(const InteractionVolume& iv) - { - //! resize transmissibility matrix & temperature vector - resizeMatrix(T_, iv.numFaces(), iv.numKnowns()); - resizeVector(Tj_, iv.numKnowns()); - - //! resize outsideTij on surface grids - using GridView = typename InteractionVolume::Traits::GridView; - if (int(GridView::dimension) < int(GridView::dimensionworld)) - { - outsideT_.resize(iv.numFaces()); - - using LocalIndexType = typename InteractionVolume::Traits::IndexSet::LocalIndexType; - for (LocalIndexType i = 0; i < iv.numFaces(); ++i) - { - const auto numNeighbors = iv.localScvf(i).neighboringLocalScvIndices().size() - 1; - outsideT_[i].resize(numNeighbors); - for (LocalIndexType j = 0; j < numNeighbors; ++j) - resizeVector(outsideT_[i][j], iv.numKnowns()); - } - } - } - //! Access to the iv-wide temperatures const CellVector& temperatures() const { return Tj_; } CellVector& temperatures() { return Tj_; } @@ -286,21 +182,7 @@ class InteractionVolumeDataHandle : public AdvectionDataHandle , public DiffusionDataHandle , public HeatConductionDataHandle -{ - using AdvectionHandle = AdvectionDataHandle; - using DiffusionHandle = DiffusionDataHandle; - using HeatConductionHandle = HeatConductionDataHandle; - -public: - //! prepare data handles for subsequent fills - template< class InteractionVolume > - void resize(const InteractionVolume& iv) - { - AdvectionHandle::resize(iv); - DiffusionHandle::resize(iv); - HeatConductionHandle::resize(iv); - } -}; +{}; } // end namespace Dumux diff --git a/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh b/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh index 82aa7b8273..151f6f49a7 100644 --- a/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh +++ b/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh @@ -111,6 +111,23 @@ public: iv.B().leftmultiply(iv.A()); T += multiplyMatrices(iv.C(), iv.B()); + // bring outsideT vector to the right size + outsideTij.resize(iv.numFaces()); + using LocalIndexType = typename IV::Traits::IndexSet::LocalIndexType; + for (LocalIndexType faceIdx = 0; faceIdx < iv.numFaces(); ++faceIdx) + { + // gravitational acceleration on this face + const auto& curLocalScvf = iv.localScvf(faceIdx); + const auto& curGlobalScvf = this->fvGeometry().scvf(curLocalScvf.gridScvfIndex()); + const auto numOutsideFaces = curGlobalScvf.boundary() ? 0 : curGlobalScvf.numOutsideScvs(); + + // resize each face entry to the right number of outside faces + outsideTij[faceIdx].resize(numOutsideFaces); + std::for_each(outsideTij[faceIdx].begin(), + outsideTij[faceIdx].end(), + [&iv](auto& v) { resizeVector(v, iv.numKnowns()); }); + } + // compute outside transmissibilities for (const auto& localFaceData : iv.localFaceData()) { @@ -240,6 +257,23 @@ public: A = iv.A(); CA = iv.C().rightmultiply(A); + // bring outsideT vector to the right size + outsideTij.resize(iv.numFaces()); + using LocalIndexType = typename IV::Traits::IndexSet::LocalIndexType; + for (LocalIndexType faceIdx = 0; faceIdx < iv.numFaces(); ++faceIdx) + { + // gravitational acceleration on this face + const auto& curLocalScvf = iv.localScvf(faceIdx); + const auto& curGlobalScvf = this->fvGeometry().scvf(curLocalScvf.gridScvfIndex()); + const auto numOutsideFaces = curGlobalScvf.boundary() ? 0 : curGlobalScvf.numOutsideScvs(); + + // resize each face entry to the right number of outside faces + outsideTij[faceIdx].resize(numOutsideFaces); + std::for_each(outsideTij[faceIdx].begin(), + outsideTij[faceIdx].end(), + [&iv](auto& v) { resizeVector(v, iv.numKnowns()); }); + } + // compute outside transmissibilities for (const auto& localFaceData : iv.localFaceData()) { @@ -298,6 +332,7 @@ public: void assemble(typename IV::Traits::MatVecTraits::CellVector& u, const IV& iv, const GetU& getU) { // put the cell pressures first + resizeVector(u, iv.numKnowns()); using LocalIndexType = typename IV::Traits::IndexSet::LocalIndexType; for (LocalIndexType i = 0; i < iv.numScvs(); ++i) u[i] = getU( iv.localScv(i).gridScvIndex() ); @@ -337,8 +372,10 @@ public: //! - first index adresses the respective phases //! - second index adresses the face within the interaction volume - // make sure g vector and CA matrix have the correct sizes already - assert(std::all_of(g.begin(), g.end(), [&iv](const auto& v) { return v.size() == iv.numFaces(); })); + // resize the g vector + std::for_each(g.begin(), g.end(), [&iv] (auto& v) { resizeVector(v, iv.numFaces()); }); + + // make sure CA matrix has the correct size already assert(CA.rows() == iv.numFaces() && CA.cols() == iv.numUnknowns()); //! For each face, we... @@ -469,10 +506,13 @@ public: //! - second index adresses the face within the interaction volume //! - third index adresses the i-th "outside" face of the current face - // we require the CA matrix and the gravity containers to have the correct size already + // resize the g vector + auto resizeToNumFaces = [&iv] (auto& v) { resizeVector(v, iv.numFaces()); }; + std::for_each(g.begin(), g.end(), resizeToNumFaces); + std::for_each(outsideG.begin(), outsideG.end(), resizeToNumFaces); + + // we require the CA matrix to have the correct size already assert(CA.rows() == iv.numFaces() && CA.cols() == iv.numUnknowns()); - assert(std::all_of(g.begin(), g.end(), [&iv](const auto& v) { return v.size() == iv.numFaces(); })); - assert(std::all_of(outsideG.begin(), outsideG.end(), [&iv](const auto& v) { return v.size() == iv.numFaces(); })); //! For each face, we... //! - arithmetically average the phase densities @@ -490,7 +530,6 @@ public: resizeVector(sum_alphas[pIdx], iv.numUnknowns()); sum_alphas[pIdx] = 0.0; g[pIdx] = 0.0; - std::for_each(outsideG[pIdx].begin(), outsideG[pIdx].end(), [] (auto& v) { v = 0.0; }); } for (LocalIndexType faceIdx = 0; faceIdx < iv.numFaces(); ++faceIdx) @@ -513,6 +552,13 @@ public: std::vector< Scalar > alpha_outside(numOutsideFaces); std::vector< Scalar > rho(numPhases); + // resize & reset entries in outside gravity vector + for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) + { + outsideG[pIdx][faceIdx].resize(numOutsideFaces); + outsideG[pIdx][faceIdx] = 0.0; + } + if (!curLocalScvf.isDirichlet()) { for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) @@ -641,15 +687,12 @@ private: static constexpr int dim = IV::Traits::GridView::dimension; static constexpr int dimWorld = IV::Traits::GridView::dimensionworld; - // Matrix D is assumed to have the right size already - assert(D.rows() == iv.numFaces() && D.cols() == iv.numKnowns()); - // if only Dirichlet faces are present in the iv, // the matrices A, B & C are undefined and D = T if (iv.numUnknowns() == 0) { - // reset matrix beforehand - D = 0.0; + // resize & reset D matrix + resizeMatrix(D, iv.numFaces(), iv.numKnowns()); D = 0.0; // Loop over all the faces, in this case these are all dirichlet boundaries for (LocalIndexType faceIdx = 0; faceIdx < iv.numFaces(); ++faceIdx) @@ -680,16 +723,11 @@ private: } else { - // we require the matrices A,B,C to have the correct size already - assert(A.rows() == iv.numUnknowns() && A.cols() == iv.numUnknowns()); - assert(B.rows() == iv.numUnknowns() && B.cols() == iv.numKnowns()); - assert(C.rows() == iv.numFaces() && C.cols() == iv.numUnknowns()); - - // reset matrices - A = 0.0; - B = 0.0; - C = 0.0; - D = 0.0; + // resize & reset matrices + resizeMatrix(A, iv.numUnknowns(), iv.numUnknowns()); A = 0.0; + resizeMatrix(B, iv.numUnknowns(), iv.numKnowns()); B = 0.0; + resizeMatrix(C, iv.numFaces(), iv.numUnknowns()); C = 0.0; + resizeMatrix(D, iv.numFaces(), iv.numKnowns()); D = 0.0; auto& wijk = iv.omegas(); for (LocalIndexType faceIdx = 0; faceIdx < iv.numFaces(); ++faceIdx) -- GitLab From d703971351373fa926e33a2dd56ece3577167bf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Gl=C3=A4ser?= Date: Thu, 15 Nov 2018 17:22:12 +0100 Subject: [PATCH 08/35] [mpfa][ivdatahandle] introduce process-specific sub-handles Instead of deriving from the process-related handle classes the handle class contains these sub-handles and provides access to it. That allows process-independent algorithms on the sub-handle classes as soon as the return functions get more generic names. --- .../cellcentered/mpfa/darcyslaw.hh | 28 ++++----- .../cellcentered/mpfa/fickslaw.hh | 16 ++--- .../mpfa/fluxvariablescachefiller.hh | 58 +++++++++---------- .../cellcentered/mpfa/fourierslaw.hh | 14 ++--- .../mpfa/interactionvolumedatahandle.hh | 27 +++++++-- 5 files changed, 81 insertions(+), 62 deletions(-) diff --git a/dumux/discretization/cellcentered/mpfa/darcyslaw.hh b/dumux/discretization/cellcentered/mpfa/darcyslaw.hh index ad6c150e29..590859986a 100644 --- a/dumux/discretization/cellcentered/mpfa/darcyslaw.hh +++ b/dumux/discretization/cellcentered/mpfa/darcyslaw.hh @@ -138,7 +138,7 @@ class DarcysLawImplementation stencil_ = &iv.stencil(); for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) - primaryPj_[pIdx] = &dataHandle.pressures(pIdx); + primaryPj_[pIdx] = &dataHandle.advectionHandle().pressures(pIdx); static const bool enableGravity = getParamFromGroup(problem.paramGroup(), "Problem.EnableGravity"); const auto ivLocalIdx = localFaceData.ivLocalScvfIndex(); @@ -146,28 +146,28 @@ class DarcysLawImplementation // standard grids if (dim == dimWorld) { - primaryTij_ = &dataHandle.advectionT()[ivLocalIdx]; + primaryTij_ = &dataHandle.advectionHandle().advectionT()[ivLocalIdx]; if (enableGravity) for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - g_[phaseIdx] = dataHandle.gravity(phaseIdx)[ivLocalIdx]; + g_[phaseIdx] = dataHandle.advectionHandle().gravity(phaseIdx)[ivLocalIdx]; } // surface grids else { if (!localFaceData.isOutsideFace()) { - primaryTij_ = &dataHandle.advectionT()[ivLocalIdx]; + primaryTij_ = &dataHandle.advectionHandle().advectionT()[ivLocalIdx]; if (enableGravity) for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - g_[phaseIdx] = dataHandle.gravity(phaseIdx)[ivLocalIdx]; + g_[phaseIdx] = dataHandle.advectionHandle().gravity(phaseIdx)[ivLocalIdx]; } else { const auto idxInOutsideFaces = localFaceData.scvfLocalOutsideScvfIndex(); - primaryTij_ = &dataHandle.advectionTout()[ivLocalIdx][idxInOutsideFaces]; + primaryTij_ = &dataHandle.advectionHandle().advectionTout()[ivLocalIdx][idxInOutsideFaces]; if (enableGravity) for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - g_[phaseIdx] = dataHandle.gravityOutside(phaseIdx)[ivLocalIdx][idxInOutsideFaces]; + g_[phaseIdx] = dataHandle.advectionHandle().gravityOutside(phaseIdx)[ivLocalIdx][idxInOutsideFaces]; } } } @@ -193,7 +193,7 @@ class DarcysLawImplementation stencil_ = &iv.stencil(); for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) - secondaryPj_[pIdx] = &dataHandle.pressures(pIdx); + secondaryPj_[pIdx] = &dataHandle.advectionHandle().pressures(pIdx); static const bool enableGravity = getParamFromGroup(problem.paramGroup(), "Problem.EnableGravity"); const auto ivLocalIdx = localFaceData.ivLocalScvfIndex(); @@ -201,28 +201,28 @@ class DarcysLawImplementation // standard grids if (dim == dimWorld) { - secondaryTij_ = &dataHandle.advectionT()[ivLocalIdx]; + secondaryTij_ = &dataHandle.advectionHandle().advectionT()[ivLocalIdx]; if (enableGravity) for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - g_[phaseIdx] = dataHandle.gravity(phaseIdx)[ivLocalIdx]; + g_[phaseIdx] = dataHandle.advectionHandle().gravity(phaseIdx)[ivLocalIdx]; } // surface grids else { if (!localFaceData.isOutsideFace()) { - secondaryTij_ = &dataHandle.advectionT()[ivLocalIdx]; + secondaryTij_ = &dataHandle.advectionHandle().advectionT()[ivLocalIdx]; if (enableGravity) for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - g_[phaseIdx] = dataHandle.gravity(phaseIdx)[ivLocalIdx]; + g_[phaseIdx] = dataHandle.advectionHandle().gravity(phaseIdx)[ivLocalIdx]; } else { const auto idxInOutsideFaces = localFaceData.scvfLocalOutsideScvfIndex(); - secondaryTij_ = &dataHandle.advectionTout()[ivLocalIdx][idxInOutsideFaces]; + secondaryTij_ = &dataHandle.advectionHandle().advectionTout()[ivLocalIdx][idxInOutsideFaces]; if (enableGravity) for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - g_[phaseIdx] = dataHandle.gravityOutside(phaseIdx)[ivLocalIdx][idxInOutsideFaces]; + g_[phaseIdx] = dataHandle.advectionHandle().gravityOutside(phaseIdx)[ivLocalIdx][idxInOutsideFaces]; } } } diff --git a/dumux/discretization/cellcentered/mpfa/fickslaw.hh b/dumux/discretization/cellcentered/mpfa/fickslaw.hh index 71dcb70fcc..e4cc85ae57 100644 --- a/dumux/discretization/cellcentered/mpfa/fickslaw.hh +++ b/dumux/discretization/cellcentered/mpfa/fickslaw.hh @@ -136,15 +136,15 @@ class FicksLawImplementation switchFluxSign_[phaseIdx][compIdx] = localFaceData.isOutsideFace(); // store pointer to the mole fraction vector of this iv - primaryXj_[phaseIdx][compIdx] = &dataHandle.moleFractions(phaseIdx, compIdx); + primaryXj_[phaseIdx][compIdx] = &dataHandle.diffusionHandle().moleFractions(phaseIdx, compIdx); const auto ivLocalIdx = localFaceData.ivLocalScvfIndex(); if (dim == dimWorld) - primaryTij_[phaseIdx][compIdx] = &dataHandle.diffusionT()[ivLocalIdx]; + primaryTij_[phaseIdx][compIdx] = &dataHandle.diffusionHandle().diffusionT()[ivLocalIdx]; else primaryTij_[phaseIdx][compIdx] = localFaceData.isOutsideFace() - ? &dataHandle.diffusionTout()[ivLocalIdx][localFaceData.scvfLocalOutsideScvfIndex()] - : &dataHandle.diffusionT()[ivLocalIdx]; + ? &dataHandle.diffusionHandle().diffusionTout()[ivLocalIdx][localFaceData.scvfLocalOutsideScvfIndex()] + : &dataHandle.diffusionHandle().diffusionT()[ivLocalIdx]; } /*! @@ -167,15 +167,15 @@ class FicksLawImplementation switchFluxSign_[phaseIdx][compIdx] = localFaceData.isOutsideFace(); // store pointer to the mole fraction vector of this iv - secondaryXj_[phaseIdx][compIdx] = &dataHandle.moleFractions(phaseIdx, compIdx); + secondaryXj_[phaseIdx][compIdx] = &dataHandle.diffusionHandle().moleFractions(phaseIdx, compIdx); const auto ivLocalIdx = localFaceData.ivLocalScvfIndex(); if (dim == dimWorld) - secondaryTij_[phaseIdx][compIdx] = &dataHandle.diffusionT()[ivLocalIdx]; + secondaryTij_[phaseIdx][compIdx] = &dataHandle.diffusionHandle().diffusionT()[ivLocalIdx]; else secondaryTij_[phaseIdx][compIdx] = localFaceData.isOutsideFace() - ? &dataHandle.diffusionTout()[ivLocalIdx][localFaceData.scvfLocalOutsideScvfIndex()] - : &dataHandle.diffusionT()[ivLocalIdx]; + ? &dataHandle.diffusionHandle().diffusionTout()[ivLocalIdx][localFaceData.scvfLocalOutsideScvfIndex()] + : &dataHandle.diffusionHandle().diffusionT()[ivLocalIdx]; } //! In the interaction volume-local system of eq we have one unknown per face. diff --git a/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh b/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh index 0a59d20489..c63e10ccee 100644 --- a/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh +++ b/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh @@ -446,18 +446,18 @@ private: if (dim < dimWorld) { if (enableGravity) - localAssembler.assembleWithGravity( handle.advectionTout(), - handle.advectionT(), - handle.gravityOutside(), - handle.gravity(), - handle.advectionCA(), - handle.advectionA(), + localAssembler.assembleWithGravity( handle.advectionHandle().advectionTout(), + handle.advectionHandle().advectionT(), + handle.advectionHandle().gravityOutside(), + handle.advectionHandle().gravity(), + handle.advectionHandle().advectionCA(), + handle.advectionHandle().advectionA(), iv, LambdaFactory::getAdvectionLambda() ); else - localAssembler.assemble( handle.advectionTout(), - handle.advectionT(), + localAssembler.assemble( handle.advectionHandle().advectionTout(), + handle.advectionHandle().advectionT(), iv, LambdaFactory::getAdvectionLambda() ); } @@ -466,13 +466,13 @@ private: else { if (enableGravity) - localAssembler.assembleWithGravity( handle.advectionT(), - handle.gravity(), - handle.advectionCA(), + localAssembler.assembleWithGravity( handle.advectionHandle().advectionT(), + handle.advectionHandle().gravity(), + handle.advectionHandle().advectionCA(), iv, LambdaFactory::getAdvectionLambda() ); else - localAssembler.assemble( handle.advectionT(), + localAssembler.assemble( handle.advectionHandle().advectionT(), iv, LambdaFactory::getAdvectionLambda() ); } @@ -482,16 +482,16 @@ private: else if (enableGravity) { if (dim == dimWorld) - localAssembler.assembleGravity( handle.gravity(), + localAssembler.assembleGravity( handle.advectionHandle().gravity(), iv, - handle.advectionCA(), + handle.advectionHandle().advectionCA(), LambdaFactory::getAdvectionLambda() ); else - localAssembler.assembleGravity( handle.gravity(), - handle.gravityOutside(), + localAssembler.assembleGravity( handle.advectionHandle().gravity(), + handle.advectionHandle().gravityOutside(), iv, - handle.advectionCA(), - handle.advectionA(), + handle.advectionHandle().advectionCA(), + handle.advectionHandle().advectionA(), LambdaFactory::getAdvectionLambda() ); } @@ -500,7 +500,7 @@ private: { const auto& evv = &elemVolVars(); auto getPressure = [&evv, pIdx] (auto volVarIdx) { return (evv->operator[](volVarIdx)).pressure(pIdx); }; - localAssembler.assemble(handle.pressures(pIdx), iv, getPressure); + localAssembler.assemble(handle.advectionHandle().pressures(pIdx), iv, getPressure); } } @@ -522,19 +522,19 @@ private: IvLocalAssembler localAssembler(problem(), fvGeometry(), elemVolVars()); // solve the local system subject to the tensor and update the handle - handle.setPhaseIndex(phaseIdx); - handle.setComponentIndex(compIdx); + handle.diffusionHandle().setPhaseIndex(phaseIdx); + handle.diffusionHandle().setComponentIndex(compIdx); // assemble T if (forceUpdateAll || soldependentDiffusion) { if (dim < dimWorld) - localAssembler.assemble( handle.diffusionTout(), - handle.diffusionT(), + localAssembler.assemble( handle.diffusionHandle().diffusionTout(), + handle.diffusionHandle().diffusionT(), iv, LambdaFactory::getDiffusionLambda(phaseIdx, compIdx) ); else - localAssembler. assemble( handle.diffusionT(), + localAssembler. assemble( handle.diffusionHandle().diffusionT(), iv, LambdaFactory::getDiffusionLambda(phaseIdx, compIdx) ); } @@ -543,7 +543,7 @@ private: const auto& evv = &elemVolVars(); auto getMoleFraction = [&evv, phaseIdx, compIdx] (auto volVarIdx) { return (evv->operator[](volVarIdx)).moleFraction(phaseIdx, compIdx); }; - localAssembler.assemble(handle.moleFractions(phaseIdx, compIdx), iv, getMoleFraction); + localAssembler.assemble(handle.diffusionHandle().moleFractions(phaseIdx, compIdx), iv, getMoleFraction); } //! prepares the quantities necessary for conductive fluxes in the handle @@ -563,12 +563,12 @@ private: if (forceUpdateAll || soldependentAdvection) { if (dim < dimWorld) - localAssembler.assemble( handle.heatConductionTout(), - handle.heatConductionT(), + localAssembler.assemble( handle.heatConductionHandle().heatConductionTout(), + handle.heatConductionHandle().heatConductionT(), iv, LambdaFactory::template getHeatConductionLambda>() ); else - localAssembler.assemble( handle.heatConductionT(), + localAssembler.assemble( handle.heatConductionHandle().heatConductionT(), iv, LambdaFactory::template getHeatConductionLambda>() ); } @@ -576,7 +576,7 @@ private: // assemble vector of temperatures const auto& evv = &elemVolVars(); auto getMoleFraction = [&evv] (auto volVarIdx) { return (evv->operator[](volVarIdx)).temperature(); }; - localAssembler.assemble(handle.temperatures(), iv, getMoleFraction); + localAssembler.assemble(handle.heatConductionHandle().temperatures(), iv, getMoleFraction); } //! fill handle only when advection uses mpfa diff --git a/dumux/discretization/cellcentered/mpfa/fourierslaw.hh b/dumux/discretization/cellcentered/mpfa/fourierslaw.hh index 5a69ad33ff..0a8fa27743 100644 --- a/dumux/discretization/cellcentered/mpfa/fourierslaw.hh +++ b/dumux/discretization/cellcentered/mpfa/fourierslaw.hh @@ -131,15 +131,15 @@ class FouriersLawImplementation switchFluxSign_ = localFaceData.isOutsideFace(); // store pointer to the temperature vector of this iv - primaryTj_ = &dataHandle.temperatures(); + primaryTj_ = &dataHandle.heatConductionHandle().temperatures(); const auto ivLocalIdx = localFaceData.ivLocalScvfIndex(); if (dim == dimWorld) - primaryTij_ = &dataHandle.heatConductionT()[ivLocalIdx]; + primaryTij_ = &dataHandle.heatConductionHandle().heatConductionT()[ivLocalIdx]; else primaryTij_ = localFaceData.isOutsideFace() - ? &dataHandle.heatConductionTout()[ivLocalIdx][localFaceData.scvfLocalOutsideScvfIndex()] - : &dataHandle.heatConductionT()[ivLocalIdx]; + ? &dataHandle.heatConductionHandle().heatConductionTout()[ivLocalIdx][localFaceData.scvfLocalOutsideScvfIndex()] + : &dataHandle.heatConductionHandle().heatConductionT()[ivLocalIdx]; } /*! @@ -161,15 +161,15 @@ class FouriersLawImplementation switchFluxSign_ = localFaceData.isOutsideFace(); // store pointer to the temperature vector of this iv - secondaryTj_ = &dataHandle.temperatures(); + secondaryTj_ = &dataHandle.heatConductionHandle().temperatures(); const auto ivLocalIdx = localFaceData.ivLocalScvfIndex(); if (dim == dimWorld) secondaryTij_ = &dataHandle.heatConductionT()[ivLocalIdx]; else secondaryTij_ = localFaceData.isOutsideFace() - ? &dataHandle.heatConductionTout()[ivLocalIdx][localFaceData.scvfLocalOutsideScvfIndex()] - : &dataHandle.heatConductionT()[ivLocalIdx]; + ? &dataHandle.heatConductionHandle().heatConductionTout()[ivLocalIdx][localFaceData.scvfLocalOutsideScvfIndex()] + : &dataHandle.heatConductionHandle().heatConductionT()[ivLocalIdx]; } //! Coefficients for the cell (& Dirichlet) unknowns in flux expressions (primary type) diff --git a/dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh b/dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh index 863bc739d8..eb302b7d17 100644 --- a/dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh +++ b/dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh @@ -179,10 +179,29 @@ class HeatConductionDataHandle : public Empt */ template class InteractionVolumeDataHandle -: public AdvectionDataHandle -, public DiffusionDataHandle -, public HeatConductionDataHandle -{}; +{ + using AdvectionHandle = AdvectionDataHandle; + using DiffusionHandle = DiffusionDataHandle; + using HeatConductionHandle = HeatConductionDataHandle; +public: + + //! return references to the handle containing data related to advection + const AdvectionHandle& advectionHandle() const { return advectionHandle_; } + AdvectionHandle& advectionHandle() { return advectionHandle_; } + + //! return references to the handle containing data related to diffusion + const DiffusionHandle& diffusionHandle() const { return diffusionHandle_; } + DiffusionHandle& diffusionHandle() { return diffusionHandle_; } + + //! return references to the handle containing data related to heat conduction + const HeatConductionHandle& heatConductionHandle() const { return heatConductionHandle_; } + HeatConductionHandle& heatConductionHandle() { return heatConductionHandle_; } + +private: + AdvectionHandle advectionHandle_; + DiffusionHandle diffusionHandle_; + HeatConductionHandle heatConductionHandle_; +}; } // end namespace Dumux -- GitLab From ce001bb861fc235bab0aa3578e33e9ab677389b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Gl=C3=A4ser?= Date: Thu, 15 Nov 2018 17:35:42 +0100 Subject: [PATCH 09/35] [mpfa][ivdatahandle] use unified names for return functions in sub-handles --- .../cellcentered/mpfa/darcyslaw.hh | 16 +++---- .../cellcentered/mpfa/fickslaw.hh | 16 +++---- .../mpfa/fluxvariablescachefiller.hh | 42 +++++++++--------- .../cellcentered/mpfa/fourierslaw.hh | 16 +++---- .../mpfa/interactionvolumedatahandle.hh | 44 +++++++++---------- 5 files changed, 67 insertions(+), 67 deletions(-) diff --git a/dumux/discretization/cellcentered/mpfa/darcyslaw.hh b/dumux/discretization/cellcentered/mpfa/darcyslaw.hh index 590859986a..660fb4a2e1 100644 --- a/dumux/discretization/cellcentered/mpfa/darcyslaw.hh +++ b/dumux/discretization/cellcentered/mpfa/darcyslaw.hh @@ -138,7 +138,7 @@ class DarcysLawImplementation stencil_ = &iv.stencil(); for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) - primaryPj_[pIdx] = &dataHandle.advectionHandle().pressures(pIdx); + primaryPj_[pIdx] = &dataHandle.advectionHandle().uj(pIdx); static const bool enableGravity = getParamFromGroup(problem.paramGroup(), "Problem.EnableGravity"); const auto ivLocalIdx = localFaceData.ivLocalScvfIndex(); @@ -146,7 +146,7 @@ class DarcysLawImplementation // standard grids if (dim == dimWorld) { - primaryTij_ = &dataHandle.advectionHandle().advectionT()[ivLocalIdx]; + primaryTij_ = &dataHandle.advectionHandle().T()[ivLocalIdx]; if (enableGravity) for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) g_[phaseIdx] = dataHandle.advectionHandle().gravity(phaseIdx)[ivLocalIdx]; @@ -156,7 +156,7 @@ class DarcysLawImplementation { if (!localFaceData.isOutsideFace()) { - primaryTij_ = &dataHandle.advectionHandle().advectionT()[ivLocalIdx]; + primaryTij_ = &dataHandle.advectionHandle().T()[ivLocalIdx]; if (enableGravity) for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) g_[phaseIdx] = dataHandle.advectionHandle().gravity(phaseIdx)[ivLocalIdx]; @@ -164,7 +164,7 @@ class DarcysLawImplementation else { const auto idxInOutsideFaces = localFaceData.scvfLocalOutsideScvfIndex(); - primaryTij_ = &dataHandle.advectionHandle().advectionTout()[ivLocalIdx][idxInOutsideFaces]; + primaryTij_ = &dataHandle.advectionHandle().tijOutside()[ivLocalIdx][idxInOutsideFaces]; if (enableGravity) for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) g_[phaseIdx] = dataHandle.advectionHandle().gravityOutside(phaseIdx)[ivLocalIdx][idxInOutsideFaces]; @@ -193,7 +193,7 @@ class DarcysLawImplementation stencil_ = &iv.stencil(); for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) - secondaryPj_[pIdx] = &dataHandle.advectionHandle().pressures(pIdx); + secondaryPj_[pIdx] = &dataHandle.advectionHandle().uj(pIdx); static const bool enableGravity = getParamFromGroup(problem.paramGroup(), "Problem.EnableGravity"); const auto ivLocalIdx = localFaceData.ivLocalScvfIndex(); @@ -201,7 +201,7 @@ class DarcysLawImplementation // standard grids if (dim == dimWorld) { - secondaryTij_ = &dataHandle.advectionHandle().advectionT()[ivLocalIdx]; + secondaryTij_ = &dataHandle.advectionHandle().T()[ivLocalIdx]; if (enableGravity) for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) g_[phaseIdx] = dataHandle.advectionHandle().gravity(phaseIdx)[ivLocalIdx]; @@ -211,7 +211,7 @@ class DarcysLawImplementation { if (!localFaceData.isOutsideFace()) { - secondaryTij_ = &dataHandle.advectionHandle().advectionT()[ivLocalIdx]; + secondaryTij_ = &dataHandle.advectionHandle().T()[ivLocalIdx]; if (enableGravity) for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) g_[phaseIdx] = dataHandle.advectionHandle().gravity(phaseIdx)[ivLocalIdx]; @@ -219,7 +219,7 @@ class DarcysLawImplementation else { const auto idxInOutsideFaces = localFaceData.scvfLocalOutsideScvfIndex(); - secondaryTij_ = &dataHandle.advectionHandle().advectionTout()[ivLocalIdx][idxInOutsideFaces]; + secondaryTij_ = &dataHandle.advectionHandle().tijOutside()[ivLocalIdx][idxInOutsideFaces]; if (enableGravity) for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) g_[phaseIdx] = dataHandle.advectionHandle().gravityOutside(phaseIdx)[ivLocalIdx][idxInOutsideFaces]; diff --git a/dumux/discretization/cellcentered/mpfa/fickslaw.hh b/dumux/discretization/cellcentered/mpfa/fickslaw.hh index e4cc85ae57..e424bbe936 100644 --- a/dumux/discretization/cellcentered/mpfa/fickslaw.hh +++ b/dumux/discretization/cellcentered/mpfa/fickslaw.hh @@ -136,15 +136,15 @@ class FicksLawImplementation switchFluxSign_[phaseIdx][compIdx] = localFaceData.isOutsideFace(); // store pointer to the mole fraction vector of this iv - primaryXj_[phaseIdx][compIdx] = &dataHandle.diffusionHandle().moleFractions(phaseIdx, compIdx); + primaryXj_[phaseIdx][compIdx] = &dataHandle.diffusionHandle().uj(phaseIdx, compIdx); const auto ivLocalIdx = localFaceData.ivLocalScvfIndex(); if (dim == dimWorld) - primaryTij_[phaseIdx][compIdx] = &dataHandle.diffusionHandle().diffusionT()[ivLocalIdx]; + primaryTij_[phaseIdx][compIdx] = &dataHandle.diffusionHandle().T()[ivLocalIdx]; else primaryTij_[phaseIdx][compIdx] = localFaceData.isOutsideFace() - ? &dataHandle.diffusionHandle().diffusionTout()[ivLocalIdx][localFaceData.scvfLocalOutsideScvfIndex()] - : &dataHandle.diffusionHandle().diffusionT()[ivLocalIdx]; + ? &dataHandle.diffusionHandle().tijOutside()[ivLocalIdx][localFaceData.scvfLocalOutsideScvfIndex()] + : &dataHandle.diffusionHandle().T()[ivLocalIdx]; } /*! @@ -167,15 +167,15 @@ class FicksLawImplementation switchFluxSign_[phaseIdx][compIdx] = localFaceData.isOutsideFace(); // store pointer to the mole fraction vector of this iv - secondaryXj_[phaseIdx][compIdx] = &dataHandle.diffusionHandle().moleFractions(phaseIdx, compIdx); + secondaryXj_[phaseIdx][compIdx] = &dataHandle.diffusionHandle().uj(phaseIdx, compIdx); const auto ivLocalIdx = localFaceData.ivLocalScvfIndex(); if (dim == dimWorld) - secondaryTij_[phaseIdx][compIdx] = &dataHandle.diffusionHandle().diffusionT()[ivLocalIdx]; + secondaryTij_[phaseIdx][compIdx] = &dataHandle.diffusionHandle().T()[ivLocalIdx]; else secondaryTij_[phaseIdx][compIdx] = localFaceData.isOutsideFace() - ? &dataHandle.diffusionHandle().diffusionTout()[ivLocalIdx][localFaceData.scvfLocalOutsideScvfIndex()] - : &dataHandle.diffusionHandle().diffusionT()[ivLocalIdx]; + ? &dataHandle.diffusionHandle().tijOutside()[ivLocalIdx][localFaceData.scvfLocalOutsideScvfIndex()] + : &dataHandle.diffusionHandle().T()[ivLocalIdx]; } //! In the interaction volume-local system of eq we have one unknown per face. diff --git a/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh b/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh index c63e10ccee..485fde45d1 100644 --- a/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh +++ b/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh @@ -446,18 +446,18 @@ private: if (dim < dimWorld) { if (enableGravity) - localAssembler.assembleWithGravity( handle.advectionHandle().advectionTout(), - handle.advectionHandle().advectionT(), + localAssembler.assembleWithGravity( handle.advectionHandle().tijOutside(), + handle.advectionHandle().T(), handle.advectionHandle().gravityOutside(), handle.advectionHandle().gravity(), - handle.advectionHandle().advectionCA(), - handle.advectionHandle().advectionA(), + handle.advectionHandle().CA(), + handle.advectionHandle().A(), iv, LambdaFactory::getAdvectionLambda() ); else - localAssembler.assemble( handle.advectionHandle().advectionTout(), - handle.advectionHandle().advectionT(), + localAssembler.assemble( handle.advectionHandle().tijOutside(), + handle.advectionHandle().T(), iv, LambdaFactory::getAdvectionLambda() ); } @@ -466,13 +466,13 @@ private: else { if (enableGravity) - localAssembler.assembleWithGravity( handle.advectionHandle().advectionT(), + localAssembler.assembleWithGravity( handle.advectionHandle().T(), handle.advectionHandle().gravity(), - handle.advectionHandle().advectionCA(), + handle.advectionHandle().CA(), iv, LambdaFactory::getAdvectionLambda() ); else - localAssembler.assemble( handle.advectionHandle().advectionT(), + localAssembler.assemble( handle.advectionHandle().T(), iv, LambdaFactory::getAdvectionLambda() ); } @@ -484,14 +484,14 @@ private: if (dim == dimWorld) localAssembler.assembleGravity( handle.advectionHandle().gravity(), iv, - handle.advectionHandle().advectionCA(), + handle.advectionHandle().CA(), LambdaFactory::getAdvectionLambda() ); else localAssembler.assembleGravity( handle.advectionHandle().gravity(), handle.advectionHandle().gravityOutside(), iv, - handle.advectionHandle().advectionCA(), - handle.advectionHandle().advectionA(), + handle.advectionHandle().CA(), + handle.advectionHandle().A(), LambdaFactory::getAdvectionLambda() ); } @@ -500,7 +500,7 @@ private: { const auto& evv = &elemVolVars(); auto getPressure = [&evv, pIdx] (auto volVarIdx) { return (evv->operator[](volVarIdx)).pressure(pIdx); }; - localAssembler.assemble(handle.advectionHandle().pressures(pIdx), iv, getPressure); + localAssembler.assemble(handle.advectionHandle().uj(pIdx), iv, getPressure); } } @@ -529,12 +529,12 @@ private: if (forceUpdateAll || soldependentDiffusion) { if (dim < dimWorld) - localAssembler.assemble( handle.diffusionHandle().diffusionTout(), - handle.diffusionHandle().diffusionT(), + localAssembler.assemble( handle.diffusionHandle().tijOutside(), + handle.diffusionHandle().T(), iv, LambdaFactory::getDiffusionLambda(phaseIdx, compIdx) ); else - localAssembler. assemble( handle.diffusionHandle().diffusionT(), + localAssembler. assemble( handle.diffusionHandle().T(), iv, LambdaFactory::getDiffusionLambda(phaseIdx, compIdx) ); } @@ -543,7 +543,7 @@ private: const auto& evv = &elemVolVars(); auto getMoleFraction = [&evv, phaseIdx, compIdx] (auto volVarIdx) { return (evv->operator[](volVarIdx)).moleFraction(phaseIdx, compIdx); }; - localAssembler.assemble(handle.diffusionHandle().moleFractions(phaseIdx, compIdx), iv, getMoleFraction); + localAssembler.assemble(handle.diffusionHandle().uj(phaseIdx, compIdx), iv, getMoleFraction); } //! prepares the quantities necessary for conductive fluxes in the handle @@ -563,12 +563,12 @@ private: if (forceUpdateAll || soldependentAdvection) { if (dim < dimWorld) - localAssembler.assemble( handle.heatConductionHandle().heatConductionTout(), - handle.heatConductionHandle().heatConductionT(), + localAssembler.assemble( handle.heatConductionHandle().tijOutside(), + handle.heatConductionHandle().T(), iv, LambdaFactory::template getHeatConductionLambda>() ); else - localAssembler.assemble( handle.heatConductionHandle().heatConductionT(), + localAssembler.assemble( handle.heatConductionHandle().T(), iv, LambdaFactory::template getHeatConductionLambda>() ); } @@ -576,7 +576,7 @@ private: // assemble vector of temperatures const auto& evv = &elemVolVars(); auto getMoleFraction = [&evv] (auto volVarIdx) { return (evv->operator[](volVarIdx)).temperature(); }; - localAssembler.assemble(handle.heatConductionHandle().temperatures(), iv, getMoleFraction); + localAssembler.assemble(handle.heatConductionHandle().uj(), iv, getMoleFraction); } //! fill handle only when advection uses mpfa diff --git a/dumux/discretization/cellcentered/mpfa/fourierslaw.hh b/dumux/discretization/cellcentered/mpfa/fourierslaw.hh index 0a8fa27743..b48a2fec18 100644 --- a/dumux/discretization/cellcentered/mpfa/fourierslaw.hh +++ b/dumux/discretization/cellcentered/mpfa/fourierslaw.hh @@ -131,15 +131,15 @@ class FouriersLawImplementation switchFluxSign_ = localFaceData.isOutsideFace(); // store pointer to the temperature vector of this iv - primaryTj_ = &dataHandle.heatConductionHandle().temperatures(); + primaryTj_ = &dataHandle.heatConductionHandle().uj(); const auto ivLocalIdx = localFaceData.ivLocalScvfIndex(); if (dim == dimWorld) - primaryTij_ = &dataHandle.heatConductionHandle().heatConductionT()[ivLocalIdx]; + primaryTij_ = &dataHandle.heatConductionHandle().T()[ivLocalIdx]; else primaryTij_ = localFaceData.isOutsideFace() - ? &dataHandle.heatConductionHandle().heatConductionTout()[ivLocalIdx][localFaceData.scvfLocalOutsideScvfIndex()] - : &dataHandle.heatConductionHandle().heatConductionT()[ivLocalIdx]; + ? &dataHandle.heatConductionHandle().tijOutside()[ivLocalIdx][localFaceData.scvfLocalOutsideScvfIndex()] + : &dataHandle.heatConductionHandle().T()[ivLocalIdx]; } /*! @@ -161,15 +161,15 @@ class FouriersLawImplementation switchFluxSign_ = localFaceData.isOutsideFace(); // store pointer to the temperature vector of this iv - secondaryTj_ = &dataHandle.heatConductionHandle().temperatures(); + secondaryTj_ = &dataHandle.heatConductionHandle().uj(); const auto ivLocalIdx = localFaceData.ivLocalScvfIndex(); if (dim == dimWorld) - secondaryTij_ = &dataHandle.heatConductionT()[ivLocalIdx]; + secondaryTij_ = &dataHandle.T()[ivLocalIdx]; else secondaryTij_ = localFaceData.isOutsideFace() - ? &dataHandle.heatConductionHandle().heatConductionTout()[ivLocalIdx][localFaceData.scvfLocalOutsideScvfIndex()] - : &dataHandle.heatConductionHandle().heatConductionT()[ivLocalIdx]; + ? &dataHandle.heatConductionHandle().tijOutside()[ivLocalIdx][localFaceData.scvfLocalOutsideScvfIndex()] + : &dataHandle.heatConductionHandle().T()[ivLocalIdx]; } //! Coefficients for the cell (& Dirichlet) unknowns in flux expressions (primary type) diff --git a/dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh b/dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh index eb302b7d17..4d4baad796 100644 --- a/dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh +++ b/dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh @@ -53,8 +53,8 @@ class AdvectionDataHandle public: //! Access to the iv-wide pressure of one phase - const CellVector& pressures(unsigned int pIdx) const { return p_[pIdx]; } - CellVector& pressures(unsigned int pIdx) { return p_[pIdx]; } + const CellVector& uj(unsigned int pIdx) const { return p_[pIdx]; } + CellVector& uj(unsigned int pIdx) { return p_[pIdx]; } //! The gravitational flux contributions for a phase on all faces const FaceVector& gravity(unsigned int pIdx) const { return g_[pIdx]; } @@ -65,20 +65,20 @@ public: std::array< FaceVector, numPhases >& gravity() { return g_; } //! Projection matrix for Neumann/gravity contribution computation - const CMatrix& advectionCA() const { return CA_; } - CMatrix& advectionCA() { return CA_; } + const CMatrix& CA() const { return CA_; } + CMatrix& CA() { return CA_; } //! Inverse of the iv-local system matrix - const AMatrix& advectionA() const { return A_; } - AMatrix& advectionA() { return A_; } + const AMatrix& A() const { return A_; } + AMatrix& A() { return A_; } //! The transmissibility matrix (i.e. C*(A^-1)*B + D) - const TMatrix& advectionT() const { return T_; } - TMatrix& advectionT() { return T_; } + const TMatrix& T() const { return T_; } + TMatrix& T() { return T_; } //! The transmissibilities for "outside" faces (used on surface grids) - const std::vector< std::vector >& advectionTout() const { return outsideT_; } - std::vector< std::vector >& advectionTout() { return outsideT_; } + const std::vector< std::vector >& tijOutside() const { return outsideT_; } + std::vector< std::vector >& tijOutside() { return outsideT_; } //! The gravitational acceleration for "outside" faces (used on surface grids) const std::array< OutsideGravityStorage, numPhases >& gravityOutside() const { return outsideG_; } @@ -115,16 +115,16 @@ public: void setComponentIndex(unsigned int compIdx) { compIdx_ = compIdx; } //! Access to the iv-wide mole fractions of a component in one phase - const CellVector& moleFractions(unsigned int pIdx, unsigned int compIdx) const { return xj_[pIdx][compIdx]; } - CellVector& moleFractions(unsigned int pIdx, unsigned int compIdx) { return xj_[pIdx][compIdx]; } + const CellVector& uj(unsigned int pIdx, unsigned int compIdx) const { return xj_[phaseIdx_][compIdx_]; } + CellVector& uj(unsigned int pIdx, unsigned int compIdx) { return xj_[phaseIdx_][compIdx_]; } //! The transmissibilities associated with diffusive fluxes - const TMatrix& diffusionT() const { return T_[phaseIdx_][compIdx_]; } - TMatrix& diffusionT() { return T_[phaseIdx_][compIdx_]; } + const TMatrix& T() const { return T_[phaseIdx_][compIdx_]; } + TMatrix& T() { return T_[phaseIdx_][compIdx_]; } //! The transmissibilities for "outside" faces (used on surface grids) - const OutsideTContainer& diffusionTout() const { return outsideT_[phaseIdx_][compIdx_]; } - OutsideTContainer& diffusionTout() { return outsideT_[phaseIdx_][compIdx_]; } + const OutsideTContainer& tijOutside() const { return outsideT_[phaseIdx_][compIdx_]; } + OutsideTContainer& tijOutside() { return outsideT_[phaseIdx_][compIdx_]; } private: //! diffusion-related variables @@ -144,16 +144,16 @@ class HeatConductionDataHandle public: //! Access to the iv-wide temperatures - const CellVector& temperatures() const { return Tj_; } - CellVector& temperatures() { return Tj_; } + const CellVector& uj() const { return Tj_; } + CellVector& uj() { return Tj_; } //! The transmissibilities associated with conductive fluxes - const TMatrix& heatConductionT() const { return T_; } - TMatrix& heatConductionT() { return T_; } + const TMatrix& T() const { return T_; } + TMatrix& T() { return T_; } //! The transmissibilities for "outside" faces (used on surface grids) - const std::vector< std::vector >& heatConductionTout() const { return outsideT_; } - std::vector< std::vector >& heatConductionTout() { return outsideT_; } + const std::vector< std::vector >& tijOutside() const { return outsideT_; } + std::vector< std::vector >& tijOutside() { return outsideT_; } private: // heat conduction-related variables -- GitLab From 9abe4824a258dc23a54f3bbb667a2de26b80bed2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Gl=C3=A4ser?= Date: Thu, 15 Nov 2018 19:28:04 +0100 Subject: [PATCH 10/35] [mpfa][ivdatahandle] implement base classes for all handles --- .../cellcentered/mpfa/darcyslaw.hh | 76 ++++--- .../cellcentered/mpfa/fickslaw.hh | 20 +- .../mpfa/fluxvariablescachefiller.hh | 11 +- .../mpfa/interactionvolumedatahandle.hh | 196 ++++++++++-------- 4 files changed, 174 insertions(+), 129 deletions(-) diff --git a/dumux/discretization/cellcentered/mpfa/darcyslaw.hh b/dumux/discretization/cellcentered/mpfa/darcyslaw.hh index 660fb4a2e1..18cd9caa6f 100644 --- a/dumux/discretization/cellcentered/mpfa/darcyslaw.hh +++ b/dumux/discretization/cellcentered/mpfa/darcyslaw.hh @@ -134,40 +134,48 @@ class DarcysLawImplementation const PrimaryIvDataHandle& dataHandle, const SubControlVolumeFace &scvf) { + const auto& handle = dataHandle.advectionHandle(); + switchFluxSign_ = localFaceData.isOutsideFace(); stencil_ = &iv.stencil(); - for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) - primaryPj_[pIdx] = &dataHandle.advectionHandle().uj(pIdx); - static const bool enableGravity = getParamFromGroup(problem.paramGroup(), "Problem.EnableGravity"); const auto ivLocalIdx = localFaceData.ivLocalScvfIndex(); // standard grids if (dim == dimWorld) { - primaryTij_ = &dataHandle.advectionHandle().T()[ivLocalIdx]; - if (enableGravity) - for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - g_[phaseIdx] = dataHandle.advectionHandle().gravity(phaseIdx)[ivLocalIdx]; + primaryTij_ = &handle.T()[ivLocalIdx]; + for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) + { + handle.setPhaseIndex(phaseIdx); + primaryPj_[phaseIdx] = &handle.uj(); + if (enableGravity) g_[phaseIdx] = handle.g()[ivLocalIdx]; + } } // surface grids else { if (!localFaceData.isOutsideFace()) { - primaryTij_ = &dataHandle.advectionHandle().T()[ivLocalIdx]; - if (enableGravity) - for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - g_[phaseIdx] = dataHandle.advectionHandle().gravity(phaseIdx)[ivLocalIdx]; + primaryTij_ = &handle.T()[ivLocalIdx]; + for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) + { + handle.setPhaseIndex(phaseIdx); + primaryPj_[phaseIdx] = &handle.uj(); + if (enableGravity) g_[phaseIdx] = handle.g()[ivLocalIdx]; + } } else { const auto idxInOutsideFaces = localFaceData.scvfLocalOutsideScvfIndex(); - primaryTij_ = &dataHandle.advectionHandle().tijOutside()[ivLocalIdx][idxInOutsideFaces]; - if (enableGravity) - for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - g_[phaseIdx] = dataHandle.advectionHandle().gravityOutside(phaseIdx)[ivLocalIdx][idxInOutsideFaces]; + primaryTij_ = &handle.tijOutside()[ivLocalIdx][idxInOutsideFaces]; + for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) + { + handle.setPhaseIndex(phaseIdx); + primaryPj_[phaseIdx] = &handle.uj(); + if (enableGravity) g_[phaseIdx] = handle.gOutside()[ivLocalIdx][idxInOutsideFaces]; + } } } } @@ -189,40 +197,48 @@ class DarcysLawImplementation const SecondaryIvDataHandle& dataHandle, const SubControlVolumeFace &scvf) { + const auto& handle = dataHandle.advectionHandle(); + switchFluxSign_ = localFaceData.isOutsideFace(); stencil_ = &iv.stencil(); - for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) - secondaryPj_[pIdx] = &dataHandle.advectionHandle().uj(pIdx); - static const bool enableGravity = getParamFromGroup(problem.paramGroup(), "Problem.EnableGravity"); const auto ivLocalIdx = localFaceData.ivLocalScvfIndex(); // standard grids if (dim == dimWorld) { - secondaryTij_ = &dataHandle.advectionHandle().T()[ivLocalIdx]; - if (enableGravity) - for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - g_[phaseIdx] = dataHandle.advectionHandle().gravity(phaseIdx)[ivLocalIdx]; + secondaryTij_ = &handle.T()[ivLocalIdx]; + for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) + { + handle.setPhaseIndex(phaseIdx); + secondaryPj_[phaseIdx] = &handle.uj(); + if (enableGravity) g_[phaseIdx] = handle.g()[ivLocalIdx]; + } } // surface grids else { if (!localFaceData.isOutsideFace()) { - secondaryTij_ = &dataHandle.advectionHandle().T()[ivLocalIdx]; - if (enableGravity) - for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - g_[phaseIdx] = dataHandle.advectionHandle().gravity(phaseIdx)[ivLocalIdx]; + secondaryTij_ = &handle.T()[ivLocalIdx]; + for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) + { + handle.setPhaseIndex(phaseIdx); + secondaryPj_[phaseIdx] = &handle.uj(); + if (enableGravity) g_[phaseIdx] = handle.g()[ivLocalIdx]; + } } else { const auto idxInOutsideFaces = localFaceData.scvfLocalOutsideScvfIndex(); - secondaryTij_ = &dataHandle.advectionHandle().tijOutside()[ivLocalIdx][idxInOutsideFaces]; - if (enableGravity) - for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - g_[phaseIdx] = dataHandle.advectionHandle().gravityOutside(phaseIdx)[ivLocalIdx][idxInOutsideFaces]; + secondaryTij_ = &handle.tijOutside()[ivLocalIdx][idxInOutsideFaces]; + for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) + { + handle.setPhaseIndex(phaseIdx); + secondaryPj_[phaseIdx] = &handle.uj(); + if (enableGravity) g_[phaseIdx] = handle.gOutside()[ivLocalIdx][idxInOutsideFaces]; + } } } } diff --git a/dumux/discretization/cellcentered/mpfa/fickslaw.hh b/dumux/discretization/cellcentered/mpfa/fickslaw.hh index e424bbe936..7d13e5c514 100644 --- a/dumux/discretization/cellcentered/mpfa/fickslaw.hh +++ b/dumux/discretization/cellcentered/mpfa/fickslaw.hh @@ -132,19 +132,21 @@ class FicksLawImplementation const SubControlVolumeFace &scvf, unsigned int phaseIdx, unsigned int compIdx) { + const auto& handle = dataHandle.diffusionHandle(); + stencil_[phaseIdx][compIdx] = &iv.stencil(); switchFluxSign_[phaseIdx][compIdx] = localFaceData.isOutsideFace(); // store pointer to the mole fraction vector of this iv - primaryXj_[phaseIdx][compIdx] = &dataHandle.diffusionHandle().uj(phaseIdx, compIdx); + primaryXj_[phaseIdx][compIdx] = &handle.uj(); const auto ivLocalIdx = localFaceData.ivLocalScvfIndex(); if (dim == dimWorld) - primaryTij_[phaseIdx][compIdx] = &dataHandle.diffusionHandle().T()[ivLocalIdx]; + primaryTij_[phaseIdx][compIdx] = &handle.T()[ivLocalIdx]; else primaryTij_[phaseIdx][compIdx] = localFaceData.isOutsideFace() - ? &dataHandle.diffusionHandle().tijOutside()[ivLocalIdx][localFaceData.scvfLocalOutsideScvfIndex()] - : &dataHandle.diffusionHandle().T()[ivLocalIdx]; + ? &handle.tijOutside()[ivLocalIdx][localFaceData.scvfLocalOutsideScvfIndex()] + : &handle.T()[ivLocalIdx]; } /*! @@ -163,19 +165,21 @@ class FicksLawImplementation const SubControlVolumeFace &scvf, unsigned int phaseIdx, unsigned int compIdx) { + const auto& handle = dataHandle.diffusionHandle(); + stencil_[phaseIdx][compIdx] = &iv.stencil(); switchFluxSign_[phaseIdx][compIdx] = localFaceData.isOutsideFace(); // store pointer to the mole fraction vector of this iv - secondaryXj_[phaseIdx][compIdx] = &dataHandle.diffusionHandle().uj(phaseIdx, compIdx); + secondaryXj_[phaseIdx][compIdx] = &handle.uj(); const auto ivLocalIdx = localFaceData.ivLocalScvfIndex(); if (dim == dimWorld) - secondaryTij_[phaseIdx][compIdx] = &dataHandle.diffusionHandle().T()[ivLocalIdx]; + secondaryTij_[phaseIdx][compIdx] = &handle.T()[ivLocalIdx]; else secondaryTij_[phaseIdx][compIdx] = localFaceData.isOutsideFace() - ? &dataHandle.diffusionHandle().tijOutside()[ivLocalIdx][localFaceData.scvfLocalOutsideScvfIndex()] - : &dataHandle.diffusionHandle().T()[ivLocalIdx]; + ? &handle.tijOutside()[ivLocalIdx][localFaceData.scvfLocalOutsideScvfIndex()] + : &handle.T()[ivLocalIdx]; } //! In the interaction volume-local system of eq we have one unknown per face. diff --git a/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh b/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh index 485fde45d1..bdc24d18ae 100644 --- a/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh +++ b/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh @@ -314,6 +314,7 @@ private: for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { + handle.diffusionHandle().setPhaseIndex(phaseIdx); for (unsigned int compIdx = 0; compIdx < numComponents; ++compIdx) { using FluidSystem = GetPropType; @@ -321,6 +322,7 @@ private: continue; // fill data in the handle + handle.diffusionHandle().setComponentIndex(compIdx); fillDiffusionHandle(iv, handle, forceUpdateAll, phaseIdx, compIdx); // fill diffusion caches @@ -498,9 +500,10 @@ private: // assemble pressure vectors for (unsigned int pIdx = 0; pIdx < ModelTraits::numPhases(); ++pIdx) { + handle.advectionHandle().setPhaseIndex(pIdx); const auto& evv = &elemVolVars(); auto getPressure = [&evv, pIdx] (auto volVarIdx) { return (evv->operator[](volVarIdx)).pressure(pIdx); }; - localAssembler.assemble(handle.advectionHandle().uj(pIdx), iv, getPressure); + localAssembler.assemble(handle.advectionHandle().uj(), iv, getPressure); } } @@ -521,10 +524,6 @@ private: using IvLocalAssembler = InteractionVolumeAssembler< Problem, FVElementGeometry, ElementVolumeVariables, M >; IvLocalAssembler localAssembler(problem(), fvGeometry(), elemVolVars()); - // solve the local system subject to the tensor and update the handle - handle.diffusionHandle().setPhaseIndex(phaseIdx); - handle.diffusionHandle().setComponentIndex(compIdx); - // assemble T if (forceUpdateAll || soldependentDiffusion) { @@ -543,7 +542,7 @@ private: const auto& evv = &elemVolVars(); auto getMoleFraction = [&evv, phaseIdx, compIdx] (auto volVarIdx) { return (evv->operator[](volVarIdx)).moleFraction(phaseIdx, compIdx); }; - localAssembler.assemble(handle.diffusionHandle().uj(phaseIdx, compIdx), iv, getMoleFraction); + localAssembler.assemble(handle.diffusionHandle().uj(), iv, getMoleFraction); } //! prepares the quantities necessary for conductive fluxes in the handle diff --git a/dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh b/dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh index 4d4baad796..77a10772ff 100644 --- a/dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh +++ b/dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh @@ -24,14 +24,97 @@ #ifndef DUMUX_DISCRETIZATION_CC_MPFA_INTERACTIONVOLUMEDATAHANDLE_HH #define DUMUX_DISCRETIZATION_CC_MPFA_INTERACTIONVOLUMEDATAHANDLE_HH +#include #include #include #include -namespace Dumux +namespace Dumux { +namespace Detail { + +/*! + * \ingroup CCMpfaDiscretization + * \brief Common base class to all handles. Stores arrays of the + * matrices involved in the interaction volume-local systems + * of equations. + * + * \tparam MVT The matrix/vector traits collecting type information used by the iv + * \tparam size1 first size specifier for the arrays + * \tparam size2 second size specifier for the arrays + */ +template +class MatrixDataHandleBase +{ + using AMatrix = typename MVT::AMatrix; + using CMatrix = typename MVT::CMatrix; + using TMatrix = typename MVT::TMatrix; + using CellVector = typename MVT::CellVector; + using OutsideTij = std::vector< std::vector >; + +public: + //! Access functions to context-dependent data + const CMatrix& CA() const { return CA_[contextIdx1_][contextIdx2_]; } + CMatrix& CA() { return CA_[contextIdx1_][contextIdx2_]; } + + const AMatrix& A() const { return A_[contextIdx1_][contextIdx2_]; } + AMatrix& A() { return A_[contextIdx1_][contextIdx2_]; } + + const TMatrix& T() const { return T_[contextIdx1_][contextIdx2_]; } + TMatrix& T() { return T_[contextIdx1_][contextIdx2_]; } + + const OutsideTij& tijOutside() const { return tijOutside_[contextIdx1_][contextIdx2_]; } + OutsideTij& tijOutside() { return tijOutside_[contextIdx1_][contextIdx2_]; } + + //! functionality to set the context indices + void setContextIndex1(unsigned int idx) const { assert(idx < size1); contextIdx1_ = idx; } + void setContextIndex2(unsigned int idx) const { assert(idx < size2); contextIdx2_ = idx; } + +protected: + //! indices to be set before accessing data + mutable unsigned int contextIdx1_{0}; + mutable unsigned int contextIdx2_{0}; + + std::array< std::array, size1 > T_; //!< The transmissibility matrix + std::array< std::array, size1 > A_; //!< Inverse of the iv-local system matrix + std::array< std::array, size1 > CA_; //!< A_ right multiplied to C + std::array< std::array, size1 > tijOutside_; //!< The transmissibilities for "outside" faces (on surface grids) +}; + +/*! + * \ingroup CCMpfaDiscretization + * \brief Common base class to all handles. Stores arrays of the + * vectors of known cell/Dirichlet values within the interaction volume. + * + * \tparam MVT The matrix/vector traits collecting type information used by the iv + * \tparam size1 first size specifier for the arrays + * \tparam size2 second size specifier for the arrays + */ +template +class VectorDataHandleBase { + using CellVector = typename MVT::CellVector; + +public: + //! Access to the iv-wide known cell/Dirichlet values + const CellVector& uj() const { return u_[contextIdx1_][contextIdx2_]; } + CellVector& uj() { return u_[contextIdx1_][contextIdx2_]; } + +protected: + //! functionality to set the context indices + void setContextIndex1(unsigned int idx) const { assert(idx < size1); contextIdx1_ = idx; } + void setContextIndex2(unsigned int idx) const { assert(idx < size2); contextIdx2_ = idx; } + + //! indices to be set before accessing data + mutable unsigned int contextIdx1_{0}; + mutable unsigned int contextIdx2_{0}; + + //! The interaction volume-local known values + std::array< std::array, size1 > u_; +}; + +} // end namespace Detail //! Empty data handle class class EmptyDataHandle {}; @@ -39,128 +122,71 @@ class EmptyDataHandle {}; //! Data handle for quantities related to advection template class AdvectionDataHandle +: public Detail::MatrixDataHandleBase +, public Detail::VectorDataHandleBase { - // obtain matrix & vector types from interaction volume - using AMatrix = typename MatVecTraits::AMatrix; - using CMatrix = typename MatVecTraits::CMatrix; - using TMatrix = typename MatVecTraits::TMatrix; - using CellVector = typename MatVecTraits::CellVector; + // we only have one local system for all phases since we + // solve them w.r.t. permeability tensor (unique for all phases) + using Base1 = Detail::MatrixDataHandleBase; + + // we do have cell/Dirichlet values for all phases though! + static constexpr int numPhases = PhysicsTraits::numPhases; + using Base2 = Detail::VectorDataHandleBase; + using FaceVector = typename MatVecTraits::FaceVector; using FaceScalar = typename FaceVector::value_type; using OutsideGravityStorage = std::vector< Dune::DynamicVector >; - static constexpr int numPhases = PhysicsTraits::numPhases; - public: - //! Access to the iv-wide pressure of one phase - const CellVector& uj(unsigned int pIdx) const { return p_[pIdx]; } - CellVector& uj(unsigned int pIdx) { return p_[pIdx]; } + //! Set the phase index of the context + void setPhaseIndex(unsigned int phaseIdx) const { Base2::setContextIndex1(phaseIdx); } //! The gravitational flux contributions for a phase on all faces - const FaceVector& gravity(unsigned int pIdx) const { return g_[pIdx]; } - FaceVector& gravity(unsigned int pIdx) { return g_[pIdx]; } + const FaceVector& g() const { return g_[Base2::contextIdx1_]; } + FaceVector& g() { return g_[Base2::contextIdx1_]; } //! Access to the gravitational flux contributions for all phases const std::array< FaceVector, numPhases >& gravity() const { return g_; } std::array< FaceVector, numPhases >& gravity() { return g_; } - //! Projection matrix for Neumann/gravity contribution computation - const CMatrix& CA() const { return CA_; } - CMatrix& CA() { return CA_; } - - //! Inverse of the iv-local system matrix - const AMatrix& A() const { return A_; } - AMatrix& A() { return A_; } - - //! The transmissibility matrix (i.e. C*(A^-1)*B + D) - const TMatrix& T() const { return T_; } - TMatrix& T() { return T_; } - - //! The transmissibilities for "outside" faces (used on surface grids) - const std::vector< std::vector >& tijOutside() const { return outsideT_; } - std::vector< std::vector >& tijOutside() { return outsideT_; } - //! The gravitational acceleration for "outside" faces (used on surface grids) const std::array< OutsideGravityStorage, numPhases >& gravityOutside() const { return outsideG_; } std::array< OutsideGravityStorage, numPhases >& gravityOutside() { return outsideG_; } //! The gravitational acceleration for one phase on "outside" faces (used on surface grids) - const OutsideGravityStorage& gravityOutside(unsigned int pIdx) const { return outsideG_[pIdx]; } - OutsideGravityStorage& gravityOutside(unsigned int pIdx) { return outsideG_[pIdx]; } + const OutsideGravityStorage& gOutside() const { return outsideG_[Base2::contextIdx1_]; } + OutsideGravityStorage& gOutside() { return outsideG_[Base2::contextIdx1_]; } private: - TMatrix T_; //!< The transmissibilities such that f_i = T_ij*p_j (... + Neumann/gravity contributions) - AMatrix A_; //!< Inverse of the iv-local system matrix (needed e.g. for face pressure reconstruction) - CMatrix CA_; //!< A_ right multiplied to C (needed e.g. for Neumann/gravity contribution computation) - std::array< CellVector, numPhases > p_; //!< The interaction volume-wide phase pressures std::array< FaceVector, numPhases > g_; //!< The gravitational acceleration at each scvf (only for enabled gravity) - std::vector< std::vector > outsideT_; //!< The transmissibilities for "outside" faces (only on surface grids) std::array< OutsideGravityStorage, numPhases > outsideG_; //!< The gravitational acceleration on "outside" faces (only on surface grids) }; //! Data handle for quantities related to diffusion template class DiffusionDataHandle +: public Detail::MatrixDataHandleBase +, public Detail::VectorDataHandleBase { - using TMatrix = typename MatVecTraits::TMatrix; - using CellVector = typename MatVecTraits::CellVector; - using OutsideTContainer = std::vector< std::vector >; - static constexpr int numPhases = PhysicsTraits::numPhases; static constexpr int numComponents = PhysicsTraits::numComponents; + using Base1 = Detail::MatrixDataHandleBase; + using Base2 = Detail::VectorDataHandleBase; public: //! diffusion caches need to set phase and component index - void setPhaseIndex(unsigned int phaseIdx) { phaseIdx_ = phaseIdx; } - void setComponentIndex(unsigned int compIdx) { compIdx_ = compIdx; } - - //! Access to the iv-wide mole fractions of a component in one phase - const CellVector& uj(unsigned int pIdx, unsigned int compIdx) const { return xj_[phaseIdx_][compIdx_]; } - CellVector& uj(unsigned int pIdx, unsigned int compIdx) { return xj_[phaseIdx_][compIdx_]; } - - //! The transmissibilities associated with diffusive fluxes - const TMatrix& T() const { return T_[phaseIdx_][compIdx_]; } - TMatrix& T() { return T_[phaseIdx_][compIdx_]; } - - //! The transmissibilities for "outside" faces (used on surface grids) - const OutsideTContainer& tijOutside() const { return outsideT_[phaseIdx_][compIdx_]; } - OutsideTContainer& tijOutside() { return outsideT_[phaseIdx_][compIdx_]; } - -private: - //! diffusion-related variables - unsigned int phaseIdx_; //!< The phase index set for the context - unsigned int compIdx_; //!< The component index set for the context - std::array< std::array, numPhases > T_; //!< The transmissibilities such that f_i = T_ij*x_j - std::array< std::array, numPhases > xj_; //!< The interaction volume-wide mole fractions - std::array< std::array, numPhases> outsideT_; + void setPhaseIndex(unsigned int phaseIdx) const + { Base1::setContextIndex1(phaseIdx); Base2::setContextIndex1(phaseIdx); } + void setComponentIndex(unsigned int compIdx) const + { Base1::setContextIndex2(compIdx); Base2::setContextIndex2(compIdx); } }; //! Data handle for quantities related to heat conduction template class HeatConductionDataHandle -{ - using TMatrix = typename MatVecTraits::TMatrix; - using CellVector = typename MatVecTraits::CellVector; - -public: - //! Access to the iv-wide temperatures - const CellVector& uj() const { return Tj_; } - CellVector& uj() { return Tj_; } - - //! The transmissibilities associated with conductive fluxes - const TMatrix& T() const { return T_; } - TMatrix& T() { return T_; } - - //! The transmissibilities for "outside" faces (used on surface grids) - const std::vector< std::vector >& tijOutside() const { return outsideT_; } - std::vector< std::vector >& tijOutside() { return outsideT_; } - -private: - // heat conduction-related variables - TMatrix T_; //!< The transmissibilities such that f_i = T_ij*T_j - CellVector Tj_; //!< The interaction volume-wide temperatures - std::vector< std::vector > outsideT_; //!< The transmissibilities for "outside" faces (only necessary on surface grids) -}; +: public Detail::MatrixDataHandleBase +, public Detail::VectorDataHandleBase +{}; //! Process-dependent data handles when related process is disabled template -- GitLab From 7bf9a09610c2841a2a8fae46ddf6dbb94193b88d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Gl=C3=A4ser?= Date: Fri, 16 Nov 2018 10:28:31 +0100 Subject: [PATCH 11/35] [mpfa][ivdatahandle] add AB matrix to members --- .../mpfa/interactionvolumedatahandle.hh | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh b/dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh index 77a10772ff..d16b08efef 100644 --- a/dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh +++ b/dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh @@ -38,7 +38,18 @@ namespace Detail { * \ingroup CCMpfaDiscretization * \brief Common base class to all handles. Stores arrays of the * matrices involved in the interaction volume-local systems - * of equations. + * of equations. Apart from the transmissibility matrix we + * store those matrices that are needed e.g. for later face + * pressure reconstruction. + * The fluxes as well as the local systems of equations can + * be expressed as functions of the intermediate unknown face + * face values \f$\bar{\mathbf{u}}\f$ and the known cell/Dirichlet + * values \f$\mathbf{u}\f$ using the matrices \f$\mathbf{A}\f$, + * \f$\mathbf{B}\f$, \f$\mathbf{C}\f$, \f$\mathbf{D}\f$ and the + * vector of Neumann fluxes \f$\mathbf{N}\f$ as follows: + * + * Fluxes: \f$\mathbf{f} = \mathbf{C}\bar{\mathbf{u}} + \mathbf{D}\mathbf{u}\f$ + * Local eq system: \f$\mathbf{A}\bar{\mathbf{u}} = \mathbf{B}\mathbf{u} + \mathbf{N}\f$ * * \tparam MVT The matrix/vector traits collecting type information used by the iv * \tparam size1 first size specifier for the arrays @@ -48,6 +59,7 @@ template class MatrixDataHandleBase { using AMatrix = typename MVT::AMatrix; + using BMatrix = typename MVT::BMatrix; using CMatrix = typename MVT::CMatrix; using TMatrix = typename MVT::TMatrix; using CellVector = typename MVT::CellVector; @@ -61,6 +73,9 @@ public: const AMatrix& A() const { return A_[contextIdx1_][contextIdx2_]; } AMatrix& A() { return A_[contextIdx1_][contextIdx2_]; } + const BMatrix& AB() const { return AB_[contextIdx1_][contextIdx2_]; } + BMatrix& AB() { return AB_[contextIdx1_][contextIdx2_]; } + const TMatrix& T() const { return T_[contextIdx1_][contextIdx2_]; } TMatrix& T() { return T_[contextIdx1_][contextIdx2_]; } @@ -78,6 +93,7 @@ protected: std::array< std::array, size1 > T_; //!< The transmissibility matrix std::array< std::array, size1 > A_; //!< Inverse of the iv-local system matrix + std::array< std::array, size1 > AB_; //!< A_ left multiplied to B std::array< std::array, size1 > CA_; //!< A_ right multiplied to C std::array< std::array, size1 > tijOutside_; //!< The transmissibilities for "outside" faces (on surface grids) }; -- GitLab From 8faaa0ef91af5ce6af8c699a5ec1701bdba5cd72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Gl=C3=A4ser?= Date: Fri, 16 Nov 2018 12:09:29 +0100 Subject: [PATCH 12/35] [mpfa][localassembler] unify assemble routines --- .../mpfa/fluxvariablescachefiller.hh | 79 +---- .../mpfa/omethod/localassembler.hh | 308 ++++-------------- .../2p/implicit/fracture/CMakeLists.txt | 2 +- 3 files changed, 80 insertions(+), 309 deletions(-) diff --git a/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh b/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh index bdc24d18ae..5356cd9bf1 100644 --- a/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh +++ b/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh @@ -443,45 +443,10 @@ private: // Assemble T only if permeability is sol-dependent or if update is forced if (forceUpdateAll || soldependentAdvection) - { - // distinguish between normal/surface grids (optimized away by compiler) - if (dim < dimWorld) - { - if (enableGravity) - localAssembler.assembleWithGravity( handle.advectionHandle().tijOutside(), - handle.advectionHandle().T(), - handle.advectionHandle().gravityOutside(), - handle.advectionHandle().gravity(), - handle.advectionHandle().CA(), - handle.advectionHandle().A(), - iv, - LambdaFactory::getAdvectionLambda() ); - - else - localAssembler.assemble( handle.advectionHandle().tijOutside(), - handle.advectionHandle().T(), - iv, - LambdaFactory::getAdvectionLambda() ); - } - - // normal grids - else - { - if (enableGravity) - localAssembler.assembleWithGravity( handle.advectionHandle().T(), - handle.advectionHandle().gravity(), - handle.advectionHandle().CA(), - iv, - LambdaFactory::getAdvectionLambda() ); - else - localAssembler.assemble( handle.advectionHandle().T(), - iv, - LambdaFactory::getAdvectionLambda() ); - } - } + localAssembler.assembleMatrices(handle.advectionHandle(), iv, LambdaFactory::getAdvectionLambda()); - // (maybe) only reassemble gravity vector - else if (enableGravity) + // maybe (re-)assemble gravity vector + if (enableGravity) { if (dim == dimWorld) localAssembler.assembleGravity( handle.advectionHandle().gravity(), @@ -503,7 +468,7 @@ private: handle.advectionHandle().setPhaseIndex(pIdx); const auto& evv = &elemVolVars(); auto getPressure = [&evv, pIdx] (auto volVarIdx) { return (evv->operator[](volVarIdx)).pressure(pIdx); }; - localAssembler.assemble(handle.advectionHandle().uj(), iv, getPressure); + localAssembler.assembleU(handle.advectionHandle(), iv, getPressure); } } @@ -524,25 +489,17 @@ private: using IvLocalAssembler = InteractionVolumeAssembler< Problem, FVElementGeometry, ElementVolumeVariables, M >; IvLocalAssembler localAssembler(problem(), fvGeometry(), elemVolVars()); - // assemble T + // maybe (re-)assemble matrices if (forceUpdateAll || soldependentDiffusion) - { - if (dim < dimWorld) - localAssembler.assemble( handle.diffusionHandle().tijOutside(), - handle.diffusionHandle().T(), - iv, - LambdaFactory::getDiffusionLambda(phaseIdx, compIdx) ); - else - localAssembler. assemble( handle.diffusionHandle().T(), - iv, - LambdaFactory::getDiffusionLambda(phaseIdx, compIdx) ); - } + localAssembler.assembleMatrices(handle.diffusionHandle(), + iv, + LambdaFactory::getDiffusionLambda(phaseIdx, compIdx)); // assemble vector of mole fractions const auto& evv = &elemVolVars(); auto getMoleFraction = [&evv, phaseIdx, compIdx] (auto volVarIdx) { return (evv->operator[](volVarIdx)).moleFraction(phaseIdx, compIdx); }; - localAssembler.assemble(handle.diffusionHandle().uj(), iv, getMoleFraction); + localAssembler.assembleU(handle.diffusionHandle(), iv, getMoleFraction); } //! prepares the quantities necessary for conductive fluxes in the handle @@ -553,29 +510,23 @@ private: void fillHeatConductionHandle(InteractionVolume& iv, DataHandle& handle, bool forceUpdateAll) { using LambdaFactory = TensorLambdaFactory; + using ThermCondModel = GetPropType; // get instance of the interaction volume-local assembler static constexpr MpfaMethods M = InteractionVolume::MpfaMethod; using IvLocalAssembler = InteractionVolumeAssembler< Problem, FVElementGeometry, ElementVolumeVariables, M >; IvLocalAssembler localAssembler(problem(), fvGeometry(), elemVolVars()); + // maybe (re-)assemble matrices (TODO: USE CORRECT SOLDEPENDENT FLAG!) if (forceUpdateAll || soldependentAdvection) - { - if (dim < dimWorld) - localAssembler.assemble( handle.heatConductionHandle().tijOutside(), - handle.heatConductionHandle().T(), - iv, - LambdaFactory::template getHeatConductionLambda>() ); - else - localAssembler.assemble( handle.heatConductionHandle().T(), - iv, - LambdaFactory::template getHeatConductionLambda>() ); - } + localAssembler.assembleMatrices(handle.heatConductionHandle(), + iv, + LambdaFactory::template getHeatConductionLambda()); // assemble vector of temperatures const auto& evv = &elemVolVars(); auto getMoleFraction = [&evv] (auto volVarIdx) { return (evv->operator[](volVarIdx)).temperature(); }; - localAssembler.assemble(handle.heatConductionHandle().uj(), iv, getMoleFraction); + localAssembler.assembleU(handle.heatConductionHandle(), iv, getMoleFraction); } //! fill handle only when advection uses mpfa diff --git a/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh b/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh index 151f6f49a7..d9b435fdbf 100644 --- a/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh +++ b/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh @@ -46,275 +46,96 @@ namespace Dumux */ template< class P, class EG, class EV > class InteractionVolumeAssemblerImpl< P, EG, EV, MpfaMethods::oMethod > - : public InteractionVolumeAssemblerBase< P, EG, EV > +: public InteractionVolumeAssemblerBase< P, EG, EV > { using ParentType = InteractionVolumeAssemblerBase< P, EG, EV >; public: - //! Use the constructor of the base class + //! Pull up constructor of the base class using ParentType::ParentType; /*! - * \brief Assembles the transmissibility matrix within an - * interaction volume in an mpfa-o type way. + * \brief Assembles the matrices involved in the flux + * expressions and the local system of equations + * within an interaction volume in an mpfa-o type way. * * \tparam IV The interaction volume type implementation * \tparam TensorFunc Lambda to obtain the tensor w.r.t. - * which the local system is to be solved - * - * \param T The transmissibility matrix to be assembled - * \param iv The interaction volume - * \param getT Lambda to evaluate the scv-wise tensors - */ - template< class IV, class TensorFunc > - void assemble(typename IV::Traits::MatVecTraits::TMatrix& T, IV& iv, const TensorFunc& getT) - { - // assemble D into T directly - assembleLocalMatrices_(iv.A(), iv.B(), iv.C(), T, iv, getT); - - // maybe solve the local system - if (iv.numUnknowns() > 0) - { - // T = C*A^-1*B + D - iv.A().invert(); - iv.C().rightmultiply(iv.A()); - T += multiplyMatrices(iv.C(), iv.B()); - } - } - - /*! - * \brief Assembles the interaction volume-local transmissibility - * matrix for surface grids. The transmissibilities associated - * with "outside" faces are stored in a separate container. - * - * \tparam TOutside Container to store the "outside" transmissibilities - * \tparam IV The interaction volume type implementation - * \tparam TensorFunc Lambda to obtain the tensor w.r.t. * which the local system is to be solved * - * \param outsideTij tij on "outside" faces to be assembled - * \param T The transmissibility matrix tij to be assembled + * \param handle The data handle in which the matrices are stored * \param iv The interaction volume * \param getT Lambda to evaluate the scv-wise tensors */ - template< class TOutside, class IV, class TensorFunc > - void assemble(TOutside& outsideTij, typename IV::Traits::MatVecTraits::TMatrix& T, IV& iv, const TensorFunc& getT) + template< class DataHandle, class IV, class TensorFunc > + void assembleMatrices(DataHandle& handle, IV& iv, const TensorFunc& getT) { - // assemble D into T directly - assembleLocalMatrices_(iv.A(), iv.B(), iv.C(), T, iv, getT); + assembleLocalMatrices_(handle.A(), handle.AB(), handle.CA(), handle.T(), iv, getT); // maybe solve the local system if (iv.numUnknowns() > 0) { - // T = C*A^-1*B + D - iv.A().invert(); - iv.B().leftmultiply(iv.A()); - T += multiplyMatrices(iv.C(), iv.B()); - - // bring outsideT vector to the right size - outsideTij.resize(iv.numFaces()); - using LocalIndexType = typename IV::Traits::IndexSet::LocalIndexType; - for (LocalIndexType faceIdx = 0; faceIdx < iv.numFaces(); ++faceIdx) - { - // gravitational acceleration on this face - const auto& curLocalScvf = iv.localScvf(faceIdx); - const auto& curGlobalScvf = this->fvGeometry().scvf(curLocalScvf.gridScvfIndex()); - const auto numOutsideFaces = curGlobalScvf.boundary() ? 0 : curGlobalScvf.numOutsideScvs(); - - // resize each face entry to the right number of outside faces - outsideTij[faceIdx].resize(numOutsideFaces); - std::for_each(outsideTij[faceIdx].begin(), - outsideTij[faceIdx].end(), - [&iv](auto& v) { resizeVector(v, iv.numKnowns()); }); - } - - // compute outside transmissibilities - for (const auto& localFaceData : iv.localFaceData()) + // T = C*(A^-1)*B + D + handle.A().invert(); + handle.CA().rightmultiply(handle.A()); + handle.T() += multiplyMatrices(handle.CA(), handle.AB()); + handle.AB().leftmultiply(handle.A()); + + // On surface grids, compute the "outside" transmissibilities + using GridView = typename IV::Traits::GridView; + static constexpr int dim = GridView::dimension; + static constexpr int dimWorld = GridView::dimensionworld; + if (dim < dimWorld) { - // continue only for "outside" faces - if (!localFaceData.isOutsideFace()) - continue; - - const auto localScvIdx = localFaceData.ivLocalInsideScvIndex(); - const auto localScvfIdx = localFaceData.ivLocalScvfIndex(); - const auto idxInOutside = localFaceData.scvfLocalOutsideScvfIndex(); - const auto& posLocalScv = iv.localScv(localScvIdx); - const auto& wijk = iv.omegas()[localScvfIdx][idxInOutside+1]; - - // store the calculated transmissibilities in the data handle - auto& tij = outsideTij[localScvfIdx][idxInOutside]; - tij = 0.0; - - // add contributions from all local directions + // bring outside tij container to the right size + auto& tijOut = handle.tijOutside(); + tijOut.resize(iv.numFaces()); using LocalIndexType = typename IV::Traits::IndexSet::LocalIndexType; - for (LocalIndexType localDir = 0; localDir < IV::Traits::GridView::dimension; localDir++) + for (LocalIndexType fIdx = 0; fIdx < iv.numFaces(); ++fIdx) { - // the scvf corresponding to this local direction in the scv - const auto& curLocalScvf = iv.localScvf(posLocalScv.localScvfIndex(localDir)); - - // on interior faces the coefficients of the AB matrix come into play - if (!curLocalScvf.isDirichlet()) - { - auto tmp = iv.B()[curLocalScvf.localDofIndex()]; - tmp *= wijk[localDir]; - tij -= tmp; - } - else - tij[curLocalScvf.localDofIndex()] -= wijk[localDir]; - - // add entry from the scv unknown - tij[localScvIdx] += wijk[localDir]; + const auto& curGlobalScvf = this->fvGeometry().scvf(iv.localScvf(fIdx).gridScvfIndex()); + const auto numOutsideFaces = curGlobalScvf.boundary() ? 0 : curGlobalScvf.numOutsideScvs(); + // resize each face entry to the right number of outside faces + tijOut[fIdx].resize(numOutsideFaces); + std::for_each(tijOut[fIdx].begin(), tijOut[fIdx].end(), [&iv](auto& v) { resizeVector(v, iv.numKnowns()); }); } - } - } - } - /*! - * \brief Assemble the transmissibility matrix within an interaction - * volume for the mpfa-o scheme to be used for advective flux - * computation in the case that gravity is to be considered in - * the local system of equations. - * - * \tparam GC The type of container used to store the - * gravitational acceleration per scvf & phase - * \tparam IV The interaction volume type implementation - * \tparam TensorFunc Lambda to obtain the tensor w.r.t. - * which the local system is to be solved - * - * \param T The transmissibility matrix to be assembled - * \param g Container to assemble gravity per scvf & phase - * \param CA Matrix to store matrix product C*A^-1 - * \param iv The mpfa-o interaction volume - * \param getT Lambda to evaluate the scv-wise tensors - */ - template< class GC, class IV, class TensorFunc > - void assembleWithGravity(typename IV::Traits::MatVecTraits::TMatrix& T, - GC& g, - typename IV::Traits::MatVecTraits::CMatrix& CA, - IV& iv, - const TensorFunc& getT) - { - // assemble D into T & C into CA directly - assembleLocalMatrices_(iv.A(), iv.B(), CA, T, iv, getT); - - // maybe solve the local system - if (iv.numUnknowns() > 0) - { - // T = C*A^-1*B + D - iv.A().invert(); - CA.rightmultiply(iv.A()); - T += multiplyMatrices(CA, iv.B()); - } - - // assemble gravitational acceleration container (enforce usage of mpfa-o type version) - assembleGravity(g, iv, CA, getT); - } - - /*! - * \brief Assembles the interaction volume-local transmissibility - * matrix in the case that gravity is to be considered in the - * local system of equations. This specialization is to be used - * on surface grids, where the gravitational flux contributions - * on "outside" faces are stored in a separate container. - * - * \tparam GC The type of container used to store the - * gravitational acceleration per scvf & phase - * \tparam GOut Type of container used to store gravity on "outside" faces - * \tparam TOutside Container to store the "outside" transmissibilities - * \tparam IV The interaction volume type implementation - * \tparam TensorFunc Lambda to obtain the tensor w.r.t. - * which the local system is to be solved - * - * \param outsideTij tij on "outside" faces to be assembled - * \param T The transmissibility matrix to be assembled - * \param outsideG Container to assemble gravity on "outside" faces - * \param g Container to assemble gravity per scvf & phase - * \param CA Matrix to store matrix product C*A^-1 - * \param A Matrix to store the inverse A^-1 - * \param iv The mpfa-o interaction volume - * \param getT Lambda to evaluate the scv-wise tensors - */ - template< class GC, class GOut, class TOutside, class IV, class TensorFunc > - void assembleWithGravity(TOutside& outsideTij, - typename IV::Traits::MatVecTraits::TMatrix& T, - GOut& outsideG, - GC& g, - typename IV::Traits::MatVecTraits::CMatrix& CA, - typename IV::Traits::MatVecTraits::AMatrix& A, - IV& iv, - const TensorFunc& getT) - { - // assemble D into T directly - assembleLocalMatrices_(iv.A(), iv.B(), iv.C(), T, iv, getT); - - // maybe solve the local system - if (iv.numUnknowns() > 0) - { - // T = C*A^-1*B + D - iv.A().invert(); - iv.B().leftmultiply(iv.A()); - T += multiplyMatrices(iv.C(), iv.B()); - A = iv.A(); - CA = iv.C().rightmultiply(A); - - // bring outsideT vector to the right size - outsideTij.resize(iv.numFaces()); - using LocalIndexType = typename IV::Traits::IndexSet::LocalIndexType; - for (LocalIndexType faceIdx = 0; faceIdx < iv.numFaces(); ++faceIdx) - { - // gravitational acceleration on this face - const auto& curLocalScvf = iv.localScvf(faceIdx); - const auto& curGlobalScvf = this->fvGeometry().scvf(curLocalScvf.gridScvfIndex()); - const auto numOutsideFaces = curGlobalScvf.boundary() ? 0 : curGlobalScvf.numOutsideScvs(); - - // resize each face entry to the right number of outside faces - outsideTij[faceIdx].resize(numOutsideFaces); - std::for_each(outsideTij[faceIdx].begin(), - outsideTij[faceIdx].end(), - [&iv](auto& v) { resizeVector(v, iv.numKnowns()); }); - } + // compute outside transmissibilities + for (const auto& localFaceData : iv.localFaceData()) + { + // continue only for "outside" faces + if (!localFaceData.isOutsideFace()) + continue; - // compute outside transmissibilities - for (const auto& localFaceData : iv.localFaceData()) - { - // continue only for "outside" faces - if (!localFaceData.isOutsideFace()) - continue; + const auto scvIdx = localFaceData.ivLocalInsideScvIndex(); + const auto scvfIdx = localFaceData.ivLocalScvfIndex(); + const auto idxInOut = localFaceData.scvfLocalOutsideScvfIndex(); - const auto localScvIdx = localFaceData.ivLocalInsideScvIndex(); - const auto localScvfIdx = localFaceData.ivLocalScvfIndex(); - const auto idxInOutside = localFaceData.scvfLocalOutsideScvfIndex(); - const auto& posLocalScv = iv.localScv(localScvIdx); - const auto& wijk = iv.omegas()[localScvfIdx][idxInOutside+1]; + const auto& wijk = iv.omegas()[scvfIdx][idxInOut+1]; + auto& tij = tijOut[scvfIdx][idxInOut]; - // store the calculated transmissibilities in the data handle - auto& tij = outsideTij[localScvfIdx][idxInOutside]; - tij = 0.0; + tij = 0.0; + for (unsigned int dir = 0; dir < dim; dir++) + { + // the scvf corresponding to this local direction in the scv + const auto& scvf = iv.localScvf(iv.localScv(scvIdx).localScvfIndex(dir)); - // add contributions from all local directions - using LocalIndexType = typename IV::Traits::IndexSet::LocalIndexType; - for (LocalIndexType localDir = 0; localDir < IV::Traits::GridView::dimension; localDir++) - { - // the scvf corresponding to this local direction in the scv - const auto& curLocalScvf = iv.localScvf(posLocalScv.localScvfIndex(localDir)); + // on interior faces the coefficients of the AB matrix come into play + if (!scvf.isDirichlet()) + { + auto tmp = handle.AB()[scvf.localDofIndex()]; + tmp *= wijk[dir]; + tij -= tmp; + } + else + tij[scvf.localDofIndex()] -= wijk[dir]; - // on interior faces the coefficients of the AB matrix come into play - if (!curLocalScvf.isDirichlet()) - { - auto tmp = iv.B()[curLocalScvf.localDofIndex()]; - tmp *= wijk[localDir]; - tij -= tmp; + // add entry from the scv unknown + tij[scvIdx] += wijk[dir]; } - else - tij[curLocalScvf.localDofIndex()] -= wijk[localDir]; - - // add entry from the scv unknown - tij[localScvIdx] += wijk[localDir]; } } } - - assembleGravity(g, outsideG, iv, CA, A, getT); } /*! @@ -324,21 +145,20 @@ public: * \tparam IV The interaction volume type implementation * \tparam GetU Lambda to obtain the cell unknowns from grid indices * - * \param u The vector to be filled with the cell unknowns + * \param handle The data handle in which the vector is stored * \param iv The mpfa-o interaction volume * \param getU Lambda to obtain the desired cell/Dirichlet value from grid index */ - template< class IV, class GetU > - void assemble(typename IV::Traits::MatVecTraits::CellVector& u, const IV& iv, const GetU& getU) + template< class DataHandle, class IV, class GetU > + void assembleU(DataHandle& handle, const IV& iv, const GetU& getU) { - // put the cell pressures first + auto& u = handle.uj(); resizeVector(u, iv.numKnowns()); - using LocalIndexType = typename IV::Traits::IndexSet::LocalIndexType; - for (LocalIndexType i = 0; i < iv.numScvs(); ++i) - u[i] = getU( iv.localScv(i).gridScvIndex() ); - // Dirichlet BCs come afterwards - LocalIndexType i = iv.numScvs(); + // put the cell unknowns first, then Dirichlet values + typename IV::Traits::IndexSet::LocalIndexType i = 0; + for (; i < iv.numScvs(); i++) + u[i] = getU( iv.localScv(i).gridScvIndex() ); for (const auto& data : iv.dirichletData()) u[i++] = getU( data.volVarIndex() ); } diff --git a/test/porousmediumflow/2p/implicit/fracture/CMakeLists.txt b/test/porousmediumflow/2p/implicit/fracture/CMakeLists.txt index 2ad42d586b..4724143f3e 100644 --- a/test/porousmediumflow/2p/implicit/fracture/CMakeLists.txt +++ b/test/porousmediumflow/2p/implicit/fracture/CMakeLists.txt @@ -27,7 +27,7 @@ dune_add_test(NAME test_2p_fracture_mpfa COMMAND ${CMAKE_SOURCE_DIR}/bin/testing/runtest.py CMD_ARGS --script fuzzy --files ${CMAKE_SOURCE_DIR}/test/references/test_2p_fracture_mpfa-reference.vtu - ${CMAKE_CURRENT_BINARY_DIR}/test_2p_fracture_mpfa-00031.vtu + ${CMAKE_CURRENT_BINARY_DIR}/test_2p_fracture_mpfa-00030.vtu --command "${CMAKE_CURRENT_BINARY_DIR}/test_2p_fracture_mpfa params.input -Problem.Name test_2p_fracture_mpfa") # tests with gravity -- GitLab From afec13f67a511be388221e748124d99e9e1c9931 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Gl=C3=A4ser?= Date: Mon, 19 Nov 2018 10:43:56 +0100 Subject: [PATCH 13/35] [mpfa][localassembler] unify assembleGravity functions --- .../mpfa/fluxvariablescachefiller.hh | 15 +- .../mpfa/omethod/localassembler.hh | 284 +++++------------- 2 files changed, 78 insertions(+), 221 deletions(-) diff --git a/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh b/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh index 5356cd9bf1..65015ee94d 100644 --- a/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh +++ b/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh @@ -447,20 +447,7 @@ private: // maybe (re-)assemble gravity vector if (enableGravity) - { - if (dim == dimWorld) - localAssembler.assembleGravity( handle.advectionHandle().gravity(), - iv, - handle.advectionHandle().CA(), - LambdaFactory::getAdvectionLambda() ); - else - localAssembler.assembleGravity( handle.advectionHandle().gravity(), - handle.advectionHandle().gravityOutside(), - iv, - handle.advectionHandle().CA(), - handle.advectionHandle().A(), - LambdaFactory::getAdvectionLambda() ); - } + localAssembler.assembleGravity(handle.advectionHandle(), iv); // assemble pressure vectors for (unsigned int pIdx = 0; pIdx < ModelTraits::numPhases(); ++pIdx) diff --git a/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh b/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh index d9b435fdbf..37f9b67d67 100644 --- a/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh +++ b/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh @@ -163,160 +163,15 @@ public: u[i++] = getU( data.volVarIndex() ); } - /*! - * \brief Assemble the gravitational flux contributions on the scvfs within - * an mpfa-o interaction volume. - * - * \note For each face, the gravity term in the form of \f$\rho \mathbf{n K g}\f$ is - * evaluated. Thus, make sure to only call this with a lambda that returns the - * hydraulic conductivity. - * - * \tparam GC The type of container used to store the - * gravitational acceleration per scvf & phase - * \tparam TensorFunc Lambda to obtain the tensor w.r.t. - * which the local system is to be solved - * - * \param g Container to assemble gravity per scvf & phase - * \param iv The mpfa-o interaction volume - * \param CA Projection matrix transforming the gravity terms in the local system of - * equations to the entire set of faces within the interaction volume - * \param getT Lambda to evaluate scv-wise hydraulic conductivities - */ - template< class GC, class IV, class TensorFunc > - void assembleGravity(GC& g, - const IV& iv, - const typename IV::Traits::MatVecTraits::CMatrix& CA, - const TensorFunc& getT) - { - //! We require the gravity container to be a two-dimensional vector/array type, structured as follows: - //! - first index adresses the respective phases - //! - second index adresses the face within the interaction volume - - // resize the g vector - std::for_each(g.begin(), g.end(), [&iv] (auto& v) { resizeVector(v, iv.numFaces()); }); - - // make sure CA matrix has the correct size already - assert(CA.rows() == iv.numFaces() && CA.cols() == iv.numUnknowns()); - - //! For each face, we... - //! - arithmetically average the phase densities - //! - compute the term \f$ \alpha := A \rho \ \mathbf{n}^T \mathbf{K} \mathbf{g} \f$ in each neighboring cell - //! - compute \f$ \alpha^* = \alpha_{outside} - \alpha_{inside} \f$ - using Scalar = typename IV::Traits::MatVecTraits::TMatrix::value_type; - using FaceVector = typename IV::Traits::MatVecTraits::FaceVector; - using LocalIndexType = typename IV::Traits::IndexSet::LocalIndexType; - - // reset gravity containers to zero - const auto numPhases = g.size(); - std::vector< FaceVector > sum_alphas(numPhases); - for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) - { - resizeVector(sum_alphas[pIdx], iv.numUnknowns()); - sum_alphas[pIdx] = 0.0; - g[pIdx] = 0.0; - } - - for (LocalIndexType faceIdx = 0; faceIdx < iv.numFaces(); ++faceIdx) - { - // gravitational acceleration on this face - const auto& curLocalScvf = iv.localScvf(faceIdx); - const auto& curGlobalScvf = this->fvGeometry().scvf(curLocalScvf.gridScvfIndex()); - const auto gravity = this->problem().gravityAtPos(curGlobalScvf.ipGlobal()); - - // get permeability tensor in "positive" sub volume - const auto& neighborScvIndices = curLocalScvf.neighboringLocalScvIndices(); - const auto& posLocalScv = iv.localScv(neighborScvIndices[0]); - const auto& posGlobalScv = this->fvGeometry().scv(posLocalScv.gridScvIndex()); - const auto& posVolVars = this->elemVolVars()[posGlobalScv]; - const auto& posElement = iv.element(neighborScvIndices[0]); - const auto tensor = getT(this->problem(), posElement, posVolVars, this->fvGeometry(), posGlobalScv); - - // On surface grids one should use the function specialization below - assert(neighborScvIndices.size() <= 2); - - std::vector< Scalar > rho(numPhases); - const auto alpha_inside = posVolVars.extrusionFactor()*vtmv(curGlobalScvf.unitOuterNormal(), tensor, gravity); - if (!curLocalScvf.isDirichlet()) - { - for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) - rho[pIdx] = posVolVars.density(pIdx); - - if (!curGlobalScvf.boundary()) - { - // obtain outside tensor - const auto& negLocalScv = iv.localScv( neighborScvIndices[1] ); - const auto& negGlobalScv = this->fvGeometry().scv(negLocalScv.gridScvIndex()); - const auto& negVolVars = this->elemVolVars()[negGlobalScv]; - const auto& negElement = iv.element( neighborScvIndices[1] ); - const auto negTensor = getT(this->problem(), negElement, negVolVars, this->fvGeometry(), negGlobalScv); - - const auto sum_alpha = negVolVars.extrusionFactor() - * vtmv(curGlobalScvf.unitOuterNormal(), negTensor, gravity) - - alpha_inside; - - const auto localDofIdx = curLocalScvf.localDofIndex(); - for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) - { - rho[pIdx] = 0.5*( rho[pIdx] + negVolVars.density(pIdx) ); - sum_alphas[pIdx][localDofIdx] = sum_alpha*rho[pIdx]*curGlobalScvf.area(); - } - } - else - { - const auto localDofIdx = curLocalScvf.localDofIndex(); - for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) - sum_alphas[pIdx][localDofIdx] -= alpha_inside*rho[pIdx]*curGlobalScvf.area(); - } - } - // use Dirichlet BC densities - else - { - const auto& dirichletVolVars = this->elemVolVars()[curGlobalScvf.outsideScvIdx()]; - for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) - rho[pIdx] = dirichletVolVars.density(pIdx); - } - - // add "inside" alpha to gravity container - for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) - g[pIdx][faceIdx] += alpha_inside*rho[pIdx]*curGlobalScvf.area(); - } - - // g += CA*sum_alphas - for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) - CA.umv(sum_alphas[pIdx], g[pIdx]); - } - /*! * \brief Assembles the gravitational flux contributions on the scvfs within an mpfa-o - * interaction volume. This specialization is to be used on surface grids, where the - * gravitational flux contributions on "outside" faces are stored in a separate container. + * interaction volume. * - * \note For each face, the gravity term in the form of \f$\rho \mathbf{n K g}\f$ is - * evaluated. Thus, make sure to only call this with a lambda that returns the - * hydraulic conductivity. - * - * \tparam GC The type of container used to store the - * gravitational acceleration per scvf & phase - * \tparam GOut Type of container used to store gravity on "outside" faces - * \tparam IV The interaction volume type implementation - * \tparam TensorFunc Lambda to obtain the tensor w.r.t. - * which the local system is to be solved - * - * \param g Container to store gravity per scvf & phase - * \param outsideG Container to store gravity per "outside" scvf & phase + * \param handle The data handle in which the vector is stored * \param iv The mpfa-o interaction volume - * \param CA Projection matrix transforming the gravity terms in the local system of - * equations to the entire set of faces within the interaction volume - * \param A Matrix needed for the "reconstruction" of face unknowns as a function of gravity - * \param getT Lambda to evaluate scv-wise hydraulic conductivities */ - template< class GC, class GOut, class IV, class TensorFunc > - void assembleGravity(GC& g, - GOut& outsideG, - const IV& iv, - const typename IV::Traits::MatVecTraits::CMatrix& CA, - const typename IV::Traits::MatVecTraits::AMatrix& A, - const TensorFunc& getT) + template< class DataHandle, class IV > + void assembleGravity(DataHandle& handle, const IV& iv) { //! We require the gravity container to be a two-dimensional vector/array type, structured as follows: //! - first index adresses the respective phases @@ -325,11 +180,19 @@ public: //! - first index adresses the respective phases //! - second index adresses the face within the interaction volume //! - third index adresses the i-th "outside" face of the current face - - // resize the g vector - auto resizeToNumFaces = [&iv] (auto& v) { resizeVector(v, iv.numFaces()); }; - std::for_each(g.begin(), g.end(), resizeToNumFaces); - std::for_each(outsideG.begin(), outsideG.end(), resizeToNumFaces); + using GridView = typename IV::Traits::GridView; + static constexpr int dim = GridView::dimension; + static constexpr int dimWorld = GridView::dimensionworld; + static constexpr bool isSurfaceGrid = dim < dimWorld; + + // resize the gravity vectors + auto& g = handle.gravity(); + auto& outsideG = handle.gravityOutside(); + std::for_each(g.begin(), g.end(), [&iv] (auto& v) { resizeVector(v, iv.numFaces()); }); + if (isSurfaceGrid) + std::for_each(outsideG.begin(), + outsideG.end(), + [&iv] (auto& v) { resizeVector(v, iv.numFaces()); }); // we require the CA matrix to have the correct size already assert(CA.rows() == iv.numFaces() && CA.cols() == iv.numUnknowns()); @@ -344,40 +207,37 @@ public: // reset everything to zero const auto numPhases = g.size(); - std::vector< FaceVector > sum_alphas(numPhases); - for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) - { - resizeVector(sum_alphas[pIdx], iv.numUnknowns()); - sum_alphas[pIdx] = 0.0; - g[pIdx] = 0.0; - } + std::vector< std::vector > sum_alphas(numPhases); + std::for_each(sum_alphas.begin(), sum_alphas.end(), [&iv] (auto& v) { resizeVector(v, iv.numUnknowns()); }); + std::for_each(sum_alphas.begin(), sum_alphas.end(), [] (auto& v) { std::fill(v.begin(), v.end(), 0.0); }); + std::for_each(g.begin(), g.end(), [] (auto& v) { v = 0.0; }); for (LocalIndexType faceIdx = 0; faceIdx < iv.numFaces(); ++faceIdx) { // gravitational acceleration on this face const auto& curLocalScvf = iv.localScvf(faceIdx); const auto& curGlobalScvf = this->fvGeometry().scvf(curLocalScvf.gridScvfIndex()); - const auto gravity = this->problem().gravityAtPos(curGlobalScvf.ipGlobal()); + const auto& gravity = this->problem().gravityAtPos(curGlobalScvf.ipGlobal()); // get permeability tensor in "positive" sub volume const auto& neighborScvIndices = curLocalScvf.neighboringLocalScvIndices(); - const auto& posLocalScv = iv.localScv(neighborScvIndices[0]); - const auto& posGlobalScv = this->fvGeometry().scv(posLocalScv.gridScvIndex()); + const auto& posGlobalScv = this->fvGeometry().scv(iv.localScv(neighborScvIndices[0]).gridScvIndex()); const auto& posVolVars = this->elemVolVars()[posGlobalScv]; - const auto& posElement = iv.element(neighborScvIndices[0]); - const auto tensor = getT(this->problem(), posElement, posVolVars, this->fvGeometry(), posGlobalScv); + const auto alpha_inside = posVolVars.extrusionFactor()*vtmv(curGlobalScvf.unitOuterNormal(), + posVolVars.permeability(), + gravity); - const auto alpha_inside = posVolVars.extrusionFactor()*vtmv(curGlobalScvf.unitOuterNormal(), tensor, gravity); const auto numOutsideFaces = curGlobalScvf.boundary() ? 0 : curGlobalScvf.numOutsideScvs(); std::vector< Scalar > alpha_outside(numOutsideFaces); std::vector< Scalar > rho(numPhases); - // resize & reset entries in outside gravity vector - for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) - { - outsideG[pIdx][faceIdx].resize(numOutsideFaces); - outsideG[pIdx][faceIdx] = 0.0; - } + if (isSurfaceGrid) + for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) + { + resizeVector(outsideG[pIdx][faceIdx], numOutsideFaces); + outsideG[pIdx][faceIdx] = 0.0; + } + if (!curLocalScvf.isDirichlet()) { @@ -391,19 +251,22 @@ public: for (unsigned int idxInOutside = 0; idxInOutside < curGlobalScvf.numOutsideScvs(); ++idxInOutside) { // obtain outside tensor - const auto& negLocalScv = iv.localScv( neighborScvIndices[idxInOutside] ); - const auto& negGlobalScv = this->fvGeometry().scv(negLocalScv.gridScvIndex()); + const auto negLocalScvIdx = neighborScvIndices[idxInOutside+1]; + const auto& negGlobalScv = this->fvGeometry().scv(iv.localScv(negLocalScvIdx).gridScvIndex()); const auto& negVolVars = this->elemVolVars()[negGlobalScv]; - const auto& negElement = iv.element( neighborScvIndices[idxInOutside] ); - const auto negTensor = getT(this->problem(), negElement, negVolVars, this->fvGeometry(), negGlobalScv); + const auto& flipScvf = !isSurfaceGrid ? curGlobalScvf + : this->fvGeometry().flipScvf(curGlobalScvf.index(), idxInOutside); - const auto& flipScvf = this->fvGeometry().flipScvf(curGlobalScvf.index(), idxInOutside); - alpha_outside[idxInOutside] = negVolVars.extrusionFactor()*vtmv(flipScvf.unitOuterNormal(), negTensor, gravity); + alpha_outside[idxInOutside] = negVolVars.extrusionFactor()*vtmv(flipScvf.unitOuterNormal(), + negVolVars.permeability(), + gravity); + if (isSurfaceGrid) + alpha_outside[idxInOutside] *= -1.0; for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) { rho[pIdx] += negVolVars.density(pIdx); - sum_alphas[pIdx][localDofIdx] -= alpha_outside[idxInOutside]; + sum_alphas[pIdx][localDofIdx] += alpha_outside[idxInOutside]; } } } @@ -427,9 +290,13 @@ public: for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) { g[pIdx][faceIdx] += alpha_inside*rho[pIdx]*curGlobalScvf.area(); - unsigned int i = 0; - for (const auto& alpha : alpha_outside) - outsideG[pIdx][faceIdx][i++] -= alpha*rho[pIdx]*curGlobalScvf.area(); + + if (isSurfaceGrid) + { + unsigned int i = 0; + for (const auto& alpha : alpha_outside) + outsideG[pIdx][faceIdx][i++] += alpha*rho[pIdx]*curGlobalScvf.area(); + } } } @@ -437,36 +304,39 @@ public: // outsideG = wikj*A^-1*sum_alphas + outsideG for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) { - CA.umv(sum_alphas[pIdx], g[pIdx]); - - FaceVector AG(iv.numUnknowns()); - A.mv(sum_alphas[pIdx], AG); + handle.CA().umv(sum_alphas[pIdx], g[pIdx]); - // compute gravitational accelerations - for (const auto& localFaceData : iv.localFaceData()) + if (isSurfaceGrid) { - // continue only for "outside" faces - if (!localFaceData.isOutsideFace()) - continue; + FaceVector AG(iv.numUnknowns()); + handle.A().mv(sum_alphas[pIdx], AG); - const auto localScvIdx = localFaceData.ivLocalInsideScvIndex(); - const auto localScvfIdx = localFaceData.ivLocalScvfIndex(); - const auto idxInOutside = localFaceData.scvfLocalOutsideScvfIndex(); - const auto& posLocalScv = iv.localScv(localScvIdx); - const auto& wijk = iv.omegas()[localScvfIdx][idxInOutside+1]; + // compute gravitational accelerations + for (const auto& localFaceData : iv.localFaceData()) + { + // continue only for "outside" faces + if (!localFaceData.isOutsideFace()) + continue; - // make sure the given outside gravity container has the right size - assert(outsideG[pIdx][localScvfIdx].size() == iv.localScvf(localScvfIdx).neighboringLocalScvIndices().size()-1); + const auto localScvIdx = localFaceData.ivLocalInsideScvIndex(); + const auto localScvfIdx = localFaceData.ivLocalScvfIndex(); + const auto idxInOutside = localFaceData.scvfLocalOutsideScvfIndex(); + const auto& posLocalScv = iv.localScv(localScvIdx); + const auto& wijk = iv.omegas()[localScvfIdx][idxInOutside+1]; - // add contributions from all local directions - for (LocalIndexType localDir = 0; localDir < IV::Traits::GridView::dimension; localDir++) - { - // the scvf corresponding to this local direction in the scv - const auto& curLocalScvf = iv.localScvf(posLocalScv.localScvfIndex(localDir)); + // make sure the given outside gravity container has the right size + assert(outsideG[pIdx][localScvfIdx].size() == iv.localScvf(localScvfIdx).neighboringLocalScvIndices().size()-1); + + // add contributions from all local directions + for (LocalIndexType localDir = 0; localDir < IV::Traits::GridView::dimension; localDir++) + { + // the scvf corresponding to this local direction in the scv + const auto& curLocalScvf = iv.localScvf(posLocalScv.localScvfIndex(localDir)); - // on interior faces the coefficients of the AB matrix come into play - if (!curLocalScvf.isDirichlet()) - outsideG[pIdx][localScvfIdx][idxInOutside] -= wijk[localDir]*AG[curLocalScvf.localDofIndex()]; + // on interior faces the coefficients of the AB matrix come into play + if (!curLocalScvf.isDirichlet()) + outsideG[pIdx][localScvfIdx][idxInOutside] -= wijk[localDir]*AG[curLocalScvf.localDofIndex()]; + } } } } -- GitLab From 8b604f217161bce38818399ad2f3173ef036106f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Gl=C3=A4ser?= Date: Mon, 19 Nov 2018 11:36:22 +0100 Subject: [PATCH 14/35] [mpfa][localassembler] make gravity assembly phase-specific --- .../mpfa/fluxvariablescachefiller.hh | 18 ++- .../mpfa/interactionvolumedatahandle.hh | 10 +- .../mpfa/omethod/localassembler.hh | 140 +++++++----------- 3 files changed, 65 insertions(+), 103 deletions(-) diff --git a/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh b/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh index 65015ee94d..b2fd78636c 100644 --- a/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh +++ b/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh @@ -438,22 +438,24 @@ private: using IvLocalAssembler = InteractionVolumeAssembler< Problem, FVElementGeometry, ElementVolumeVariables, M >; IvLocalAssembler localAssembler(problem(), fvGeometry(), elemVolVars()); - // Use different assembly if gravity is enabled - static const bool enableGravity = getParamFromGroup(problem().paramGroup(), "Problem.EnableGravity"); - // Assemble T only if permeability is sol-dependent or if update is forced if (forceUpdateAll || soldependentAdvection) localAssembler.assembleMatrices(handle.advectionHandle(), iv, LambdaFactory::getAdvectionLambda()); - // maybe (re-)assemble gravity vector - if (enableGravity) - localAssembler.assembleGravity(handle.advectionHandle(), iv); - // assemble pressure vectors + const auto& evv = &elemVolVars(); for (unsigned int pIdx = 0; pIdx < ModelTraits::numPhases(); ++pIdx) { + // set context in handle handle.advectionHandle().setPhaseIndex(pIdx); - const auto& evv = &elemVolVars(); + + // maybe (re-)assemble gravity contribution vector + auto getRho = [pIdx] (const auto& volVars) { return volVars.density(pIdx); }; + static const bool enableGravity = getParamFromGroup(problem().paramGroup(), "Problem.EnableGravity"); + if (enableGravity) + localAssembler.assembleGravity(handle.advectionHandle(), iv, getRho); + + // reassemble pressure vector auto getPressure = [&evv, pIdx] (auto volVarIdx) { return (evv->operator[](volVarIdx)).pressure(pIdx); }; localAssembler.assembleU(handle.advectionHandle(), iv, getPressure); } diff --git a/dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh b/dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh index d16b08efef..fbcb7a6dcf 100644 --- a/dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh +++ b/dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh @@ -151,7 +151,7 @@ class AdvectionDataHandle using FaceVector = typename MatVecTraits::FaceVector; using FaceScalar = typename FaceVector::value_type; - using OutsideGravityStorage = std::vector< Dune::DynamicVector >; + using OutsideGravityStorage = std::vector< std::vector >; public: //! Set the phase index of the context @@ -161,14 +161,6 @@ public: const FaceVector& g() const { return g_[Base2::contextIdx1_]; } FaceVector& g() { return g_[Base2::contextIdx1_]; } - //! Access to the gravitational flux contributions for all phases - const std::array< FaceVector, numPhases >& gravity() const { return g_; } - std::array< FaceVector, numPhases >& gravity() { return g_; } - - //! The gravitational acceleration for "outside" faces (used on surface grids) - const std::array< OutsideGravityStorage, numPhases >& gravityOutside() const { return outsideG_; } - std::array< OutsideGravityStorage, numPhases >& gravityOutside() { return outsideG_; } - //! The gravitational acceleration for one phase on "outside" faces (used on surface grids) const OutsideGravityStorage& gOutside() const { return outsideG_[Base2::contextIdx1_]; } OutsideGravityStorage& gOutside() { return outsideG_[Base2::contextIdx1_]; } diff --git a/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh b/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh index 37f9b67d67..eaa5ac3a4d 100644 --- a/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh +++ b/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh @@ -169,30 +169,22 @@ public: * * \param handle The data handle in which the vector is stored * \param iv The mpfa-o interaction volume + * \param getRho Lambda to obtain the density from volume variables */ - template< class DataHandle, class IV > - void assembleGravity(DataHandle& handle, const IV& iv) + template< class DataHandle, class IV, class GetRho > + void assembleGravity(DataHandle& handle, const IV& iv, const GetRho& getRho) { - //! We require the gravity container to be a two-dimensional vector/array type, structured as follows: - //! - first index adresses the respective phases - //! - second index adresses the face within the interaction volume - //! We require the outside gravity container to be a three-dimensional vector/array type, structured as follows: - //! - first index adresses the respective phases - //! - second index adresses the face within the interaction volume - //! - third index adresses the i-th "outside" face of the current face using GridView = typename IV::Traits::GridView; static constexpr int dim = GridView::dimension; static constexpr int dimWorld = GridView::dimensionworld; static constexpr bool isSurfaceGrid = dim < dimWorld; // resize the gravity vectors - auto& g = handle.gravity(); - auto& outsideG = handle.gravityOutside(); - std::for_each(g.begin(), g.end(), [&iv] (auto& v) { resizeVector(v, iv.numFaces()); }); + auto& g = handle.g(); + auto& outsideG = handle.gOutside(); + resizeVector(g, iv.numFaces()); if (isSurfaceGrid) - std::for_each(outsideG.begin(), - outsideG.end(), - [&iv] (auto& v) { resizeVector(v, iv.numFaces()); }); + resizeVector(outsideG, iv.numFaces()); // we require the CA matrix to have the correct size already assert(CA.rows() == iv.numFaces() && CA.cols() == iv.numUnknowns()); @@ -202,16 +194,10 @@ public: //! - compute the term \f$ \alpha := \mathbf{A} \rho \ \mathbf{n}^T \mathbf{K} \mathbf{g} \f$ in each neighboring cell //! - compute \f$ \alpha^* = \sum{\alpha_{outside, i}} - \alpha_{inside} \f$ using Scalar = typename IV::Traits::MatVecTraits::TMatrix::value_type; - using FaceVector = typename IV::Traits::MatVecTraits::FaceVector; using LocalIndexType = typename IV::Traits::IndexSet::LocalIndexType; - // reset everything to zero - const auto numPhases = g.size(); - std::vector< std::vector > sum_alphas(numPhases); - std::for_each(sum_alphas.begin(), sum_alphas.end(), [&iv] (auto& v) { resizeVector(v, iv.numUnknowns()); }); - std::for_each(sum_alphas.begin(), sum_alphas.end(), [] (auto& v) { std::fill(v.begin(), v.end(), 0.0); }); - std::for_each(g.begin(), g.end(), [] (auto& v) { v = 0.0; }); - + std::fill(g.begin(), g.end(), 0.0); + std::vector sum_alphas(iv.numUnknowns(), 0.0); for (LocalIndexType faceIdx = 0; faceIdx < iv.numFaces(); ++faceIdx) { // gravitational acceleration on this face @@ -228,21 +214,19 @@ public: gravity); const auto numOutsideFaces = curGlobalScvf.boundary() ? 0 : curGlobalScvf.numOutsideScvs(); + Scalar rho; std::vector< Scalar > alpha_outside(numOutsideFaces); - std::vector< Scalar > rho(numPhases); if (isSurfaceGrid) - for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) - { - resizeVector(outsideG[pIdx][faceIdx], numOutsideFaces); - outsideG[pIdx][faceIdx] = 0.0; - } + { + resizeVector(outsideG[faceIdx], numOutsideFaces); + std::fill(outsideG[faceIdx].begin(), outsideG[faceIdx].end(), 0.0); + } if (!curLocalScvf.isDirichlet()) { - for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) - rho[pIdx] = posVolVars.density(pIdx); + rho = getRho(posVolVars); // arithmetically average density on inside faces const auto localDofIdx = curLocalScvf.localDofIndex(); @@ -263,80 +247,64 @@ public: if (isSurfaceGrid) alpha_outside[idxInOutside] *= -1.0; - for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) - { - rho[pIdx] += negVolVars.density(pIdx); - sum_alphas[pIdx][localDofIdx] += alpha_outside[idxInOutside]; - } + rho += getRho(negVolVars); + sum_alphas[localDofIdx] += alpha_outside[idxInOutside]; } } - for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) - { - rho[pIdx] /= numOutsideFaces + 1; - sum_alphas[pIdx][localDofIdx] -= alpha_inside; - sum_alphas[pIdx][localDofIdx] *= rho[pIdx]*curGlobalScvf.area(); - } + rho /= numOutsideFaces + 1; + sum_alphas[localDofIdx] -= alpha_inside; + sum_alphas[localDofIdx] *= rho*curGlobalScvf.area(); } - // use Dirichlet BC densities + // use density resulting from Dirichlet BCs else - { - const auto& dirichletVolVars = this->elemVolVars()[curGlobalScvf.outsideScvIdx()]; - for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) - rho[pIdx] = dirichletVolVars.density(pIdx); - } + rho = getRho(this->elemVolVars()[curGlobalScvf.outsideScvIdx()]); // add "inside" & "outside" alphas to gravity containers - for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) - { - g[pIdx][faceIdx] += alpha_inside*rho[pIdx]*curGlobalScvf.area(); + g[faceIdx] += alpha_inside*rho*curGlobalScvf.area(); - if (isSurfaceGrid) - { - unsigned int i = 0; - for (const auto& alpha : alpha_outside) - outsideG[pIdx][faceIdx][i++] += alpha*rho[pIdx]*curGlobalScvf.area(); - } + if (isSurfaceGrid) + { + unsigned int i = 0; + for (const auto& alpha : alpha_outside) + outsideG[faceIdx][i++] += alpha*rho*curGlobalScvf.area(); } } // g += CA*sum_alphas // outsideG = wikj*A^-1*sum_alphas + outsideG - for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) + handle.CA().umv(sum_alphas, g); + + if (isSurfaceGrid) { - handle.CA().umv(sum_alphas[pIdx], g[pIdx]); + using FaceVector = typename IV::Traits::MatVecTraits::FaceVector; + FaceVector AG; + resizeVector(AG, iv.numUnknowns()); + handle.A().mv(sum_alphas, AG); - if (isSurfaceGrid) + // compute gravitational accelerations + for (const auto& localFaceData : iv.localFaceData()) { - FaceVector AG(iv.numUnknowns()); - handle.A().mv(sum_alphas[pIdx], AG); - - // compute gravitational accelerations - for (const auto& localFaceData : iv.localFaceData()) - { - // continue only for "outside" faces - if (!localFaceData.isOutsideFace()) - continue; - - const auto localScvIdx = localFaceData.ivLocalInsideScvIndex(); - const auto localScvfIdx = localFaceData.ivLocalScvfIndex(); - const auto idxInOutside = localFaceData.scvfLocalOutsideScvfIndex(); - const auto& posLocalScv = iv.localScv(localScvIdx); - const auto& wijk = iv.omegas()[localScvfIdx][idxInOutside+1]; + // continue only for "outside" faces + if (!localFaceData.isOutsideFace()) + continue; - // make sure the given outside gravity container has the right size - assert(outsideG[pIdx][localScvfIdx].size() == iv.localScvf(localScvfIdx).neighboringLocalScvIndices().size()-1); + const auto localScvIdx = localFaceData.ivLocalInsideScvIndex(); + const auto localScvfIdx = localFaceData.ivLocalScvfIndex(); + const auto idxInOutside = localFaceData.scvfLocalOutsideScvfIndex(); + const auto& posLocalScv = iv.localScv(localScvIdx); + const auto& wijk = iv.omegas()[localScvfIdx][idxInOutside+1]; - // add contributions from all local directions - for (LocalIndexType localDir = 0; localDir < IV::Traits::GridView::dimension; localDir++) - { - // the scvf corresponding to this local direction in the scv - const auto& curLocalScvf = iv.localScvf(posLocalScv.localScvfIndex(localDir)); + // make sure the given outside gravity container has the right size + assert(outsideG[localScvfIdx].size() == iv.localScvf(localScvfIdx).neighboringLocalScvIndices().size()-1); - // on interior faces the coefficients of the AB matrix come into play - if (!curLocalScvf.isDirichlet()) - outsideG[pIdx][localScvfIdx][idxInOutside] -= wijk[localDir]*AG[curLocalScvf.localDofIndex()]; - } + // add contributions from all local directions + for (LocalIndexType localDir = 0; localDir < dim; localDir++) + { + // the scvf corresponding to this local direction in the scv + const auto& curLocalScvf = iv.localScvf(posLocalScv.localScvfIndex(localDir)); + if (!curLocalScvf.isDirichlet()) + outsideG[localScvfIdx][idxInOutside] -= wijk[localDir]*AG[curLocalScvf.localDofIndex()]; } } } -- GitLab From 4699ad06905bd331f5c6f1050817f39c699c86f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Gl=C3=A4ser?= Date: Mon, 19 Nov 2018 11:38:42 +0100 Subject: [PATCH 15/35] [mpfa][localassembler] lambda obtains volvars to obtain cell/dirichlet values --- .../cellcentered/mpfa/fluxvariablescachefiller.hh | 10 +++------- .../cellcentered/mpfa/omethod/localassembler.hh | 6 +++--- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh b/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh index b2fd78636c..82fceb984e 100644 --- a/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh +++ b/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh @@ -443,7 +443,6 @@ private: localAssembler.assembleMatrices(handle.advectionHandle(), iv, LambdaFactory::getAdvectionLambda()); // assemble pressure vectors - const auto& evv = &elemVolVars(); for (unsigned int pIdx = 0; pIdx < ModelTraits::numPhases(); ++pIdx) { // set context in handle @@ -456,7 +455,7 @@ private: localAssembler.assembleGravity(handle.advectionHandle(), iv, getRho); // reassemble pressure vector - auto getPressure = [&evv, pIdx] (auto volVarIdx) { return (evv->operator[](volVarIdx)).pressure(pIdx); }; + auto getPressure = [pIdx] (const auto& volVars) { return volVars.pressure(pIdx); }; localAssembler.assembleU(handle.advectionHandle(), iv, getPressure); } } @@ -485,9 +484,7 @@ private: LambdaFactory::getDiffusionLambda(phaseIdx, compIdx)); // assemble vector of mole fractions - const auto& evv = &elemVolVars(); - auto getMoleFraction = [&evv, phaseIdx, compIdx] (auto volVarIdx) - { return (evv->operator[](volVarIdx)).moleFraction(phaseIdx, compIdx); }; + auto getMoleFraction = [phaseIdx, compIdx] (const auto& volVars) { return volVars.moleFraction(phaseIdx, compIdx); }; localAssembler.assembleU(handle.diffusionHandle(), iv, getMoleFraction); } @@ -513,8 +510,7 @@ private: LambdaFactory::template getHeatConductionLambda()); // assemble vector of temperatures - const auto& evv = &elemVolVars(); - auto getMoleFraction = [&evv] (auto volVarIdx) { return (evv->operator[](volVarIdx)).temperature(); }; + auto getMoleFraction = [] (const auto& volVars) { return volVars.temperature(); }; localAssembler.assembleU(handle.heatConductionHandle(), iv, getMoleFraction); } diff --git a/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh b/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh index eaa5ac3a4d..fd25271136 100644 --- a/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh +++ b/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh @@ -147,7 +147,7 @@ public: * * \param handle The data handle in which the vector is stored * \param iv The mpfa-o interaction volume - * \param getU Lambda to obtain the desired cell/Dirichlet value from grid index + * \param getU Lambda to obtain the desired cell/Dirichlet value from vol vars */ template< class DataHandle, class IV, class GetU > void assembleU(DataHandle& handle, const IV& iv, const GetU& getU) @@ -158,9 +158,9 @@ public: // put the cell unknowns first, then Dirichlet values typename IV::Traits::IndexSet::LocalIndexType i = 0; for (; i < iv.numScvs(); i++) - u[i] = getU( iv.localScv(i).gridScvIndex() ); + u[i] = getU( this->elemVolVars()[iv.localScv(i).gridScvIndex()] ); for (const auto& data : iv.dirichletData()) - u[i++] = getU( data.volVarIndex() ); + u[i++] = getU( this->elemVolVars()[data.volVarIndex()] ); } /*! -- GitLab From b740964c9958e6a9288b62b68cc952a7d9de0827 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Gl=C3=A4ser?= Date: Mon, 19 Nov 2018 11:48:35 +0100 Subject: [PATCH 16/35] [mpfa][localassemblerbase] adapt interfaces & remove obsolete ones --- .../cellcentered/mpfa/localassembler.hh | 178 +++--------------- 1 file changed, 22 insertions(+), 156 deletions(-) diff --git a/dumux/discretization/cellcentered/mpfa/localassembler.hh b/dumux/discretization/cellcentered/mpfa/localassembler.hh index ad06867aee..1fdc768594 100644 --- a/dumux/discretization/cellcentered/mpfa/localassembler.hh +++ b/dumux/discretization/cellcentered/mpfa/localassembler.hh @@ -82,187 +82,53 @@ class InteractionVolumeAssemblerBase const ElementVolumeVariables& elemVolVars() const { return *elemVolVarsPtr_; } /*! - * \brief General interface of a function assembling the - * interaction volume-local transmissibility matrix. + * \brief Assembles the matrices involved in the flux + * expressions and the local system of equations + * within an mpfa interaction volume. * - * \tparam IV Interaction volume type implementation - * \tparam TensorFunc Lambda to obtain the tensor w.r.t. - * which the local system is to be solved - * - * \param T The transmissibility matrix to be assembled - * \param iv The interaction volume - * \param getT Lambda to evaluate the scv-wise tensors - */ - template< class IV, class TensorFunc > - void assemble(typename IV::Traits::MatVecTraits::MatVecTraits::TMatrix& T, IV& iv, const TensorFunc& getT) - { - DUNE_THROW(Dune::NotImplemented, "Implementation does not provide a assemble() function"); - } - - /*! - * \brief General interface of a function assembling the interaction - * volume-local transmissibilities matrix for surface grids. The - * transmissibilities associated with "outside" faces are stored - * in a separate container. - * - * \tparam TOutside Container to store the "outside" transmissibilities - * \tparam IV Interaction volume type implementation - * \tparam TensorFunc Lambda to obtain the tensor w.r.t. - * which the local system is to be solved - * - * \param outsideTij tij on "outside" faces to be assembled - * \param T The transmissibility matrix tij to be assembled - * \param iv The mpfa-o interaction volume - * \param getT Lambda to evaluate the scv-wise tensors - */ - template< class TOutside, class IV, class TensorFunc > - void assemble(TOutside& outsideTij, typename IV::Traits::MatVecTraits::TMatrix& T, IV& iv, const TensorFunc& getT) - { - DUNE_THROW(Dune::NotImplemented, "Implementation does not provide a assemble() function to be used on surface grids"); - } - - /*! - * \brief General interface of a function assembling the interaction - * volume-local transmissibility matrix in the case that gravity - * is to be considered in the local system of equations. - * - * \tparam GC The type of container used to store the - * gravitational acceleration per scvf & phase - * \tparam IV The interaction volume type implementation - * \tparam TensorFunc Lambda to obtain the tensor w.r.t. - * which the local system is to be solved - * - * \param T The transmissibility matrix to be assembled - * \param g Container to assemble gravity per scvf & phase - * \param CA Matrix to store matrix product C*A^-1 - * \param iv The interaction volume - * \param getT Lambda to evaluate the scv-wise tensors - */ - template< class GC, class IV, class TensorFunc > - void assembleWithGravity(typename IV::Traits::MatVecTraits::TMatrix& T, - GC& g, - typename IV::Traits::MatVecTraits::CMatrix& CA, - IV& iv, - const TensorFunc& getT) - { - DUNE_THROW(Dune::NotImplemented, "Implementation does not provide a assembleWithGravity() function"); - } - - /*! - * \brief General interface of a function assembling the interaction - * volume-local transmissibility matrix in the case that gravity - * is to be considered in the local system of equations. This - * specialization is to be used on surface grids, where the - * gravitational flux contributions on "outside" faces are stored - * in a separate container. - * - * \tparam GC The type of container used to store the - * gravitational acceleration per scvf & phase - * \tparam GOut Type of container used to store gravity on "outside" faces - * \tparam TOutside Container to store the "outside" transmissibilities * \tparam IV The interaction volume type implementation * \tparam TensorFunc Lambda to obtain the tensor w.r.t. * which the local system is to be solved * - * \param outsideTij tij on "outside" faces to be assembled - * \param T The transmissibility matrix to be assembled - * \param outsideG Container to assemble gravity on "outside" faces - * \param g Container to assemble gravity per scvf & phase - * \param CA Matrix to store matrix product C*A^-1 - * \param A Matrix to store the inverse A^-1 + * \param handle The data handle in which the matrices are stored * \param iv The interaction volume * \param getT Lambda to evaluate the scv-wise tensors */ - template< class GC, class GOut, class TOutside, class IV, class TensorFunc > - void assembleWithGravity(TOutside& outsideTij, - typename IV::Traits::MatVecTraits::TMatrix& T, - GOut& outsideG, - GC& g, - typename IV::Traits::MatVecTraits::CMatrix& CA, - typename IV::Traits::MatVecTraits::AMatrix& A, - IV& iv, - const TensorFunc& getT) + template< class DataHandle, class IV, class TensorFunc > + void assembleMatrices(DataHandle& handle, IV& iv, const TensorFunc& getT) { - DUNE_THROW(Dune::NotImplemented, "Implementation does not provide a assembleWithGravity() function to be used on surface grids"); + DUNE_THROW(Dune::NotImplemented, "Implementation does not provide a assembleMatrices() function"); } /*! - * \brief General interface for the assembly of the vector of - * primary (cell) unknowns and (maybe) Dirichlet boundary - * conditions within an interaction volume. + * \brief Assembles the vector of primary (cell) unknowns and (maybe) + * Dirichlet boundary conditions within an interaction volume. * * \tparam IV The interaction volume type implementation * \tparam GetU Lambda to obtain the cell unknowns from grid indices * - * \param u The vector to be filled with the cell unknowns - * \param iv The interaction volume - * \param getU Lambda to obtain the desired cell value from grid indices - */ - template< class IV, class GetU > - void assemble(typename IV::Traits::MatVecTraits::CellVector& u, const IV& iv, const GetU& getU) - { - DUNE_THROW(Dune::NotImplemented, "Implementation does not provide a assemble() function for the cell unknowns"); - } - - /*! - * \brief General interface for the assembly of the gravitational - * flux contributions on the scvfs within an interaction volume. - * - * \note For each face, the gravity term in the form of \f$\rho \mathbf{n K g}\f$ is - * evaluated. Thus, make sure to only call this with a lambda that returns the - * hydraulic conductivity. - * - * \tparam GC The type of container used to store the - * gravitational acceleration per scvf & phase - * \tparam TensorFunc Lambda to obtain the tensor w.r.t. - * which the local system is to be solved - * - * \param g Container to assemble gravity per scvf & phase - * \param iv The interaction volume - * \param CA Projection matrix transforming the gravity terms in the local system of - * equations to the entire set of faces within the interaction volume - * \param getT Lambda to evaluate scv-wise hydraulic conductivities + * \param handle The data handle in which the vector is stored + * \param iv The mpfa-o interaction volume + * \param getU Lambda to obtain the desired cell/Dirichlet value from vol vars */ - template< class GC, class IV, class TensorFunc > - void assembleGravity(GC& g, const IV& iv, const typename IV::Traits::MatVecTraits::CMatrix& CA, const TensorFunc& getT) + template< class DataHandle, class IV, class GetU > + void assembleU(DataHandle& handle, const IV& iv, const GetU& getU) { - DUNE_THROW(Dune::NotImplemented, "Implementation does not provide a assembleGravity() function"); + DUNE_THROW(Dune::NotImplemented, "Implementation does not provide a assemble() function for the cell/Dirichlet unknowns"); } /*! - * \brief General interface for the assembly of the gravitational - * flux contributions on the scvfs within an interaction volume. - * This specialization is to be used on surface grids, where the gravitational - * flux contributions on "outside" faces are stored in a separate container. + * \brief Assembles the gravitational flux contributions on the scvfs within an + * interaction volume. * - * \note For each face, the gravity term in the form of \f$\rho \mathbf{n K g}\f$ is - * evaluated. Thus, make sure to only call this with a lambda that returns the - * hydraulic conductivity. - * - * \tparam GC The type of container used to store the - * gravitational acceleration per scvf & phase - * \tparam GOut Type of container used to store gravity on "outside" faces - * \tparam IV The interaction volume type implementation - * \tparam TensorFunc Lambda to obtain the tensor w.r.t. - * which the local system is to be solved - * - * \param g Container to store gravity per scvf & phase - * \param outsideG Container to store gravity per "outside" scvf & phase + * \param handle The data handle in which the vector is stored * \param iv The mpfa-o interaction volume - * \param CA Projection matrix transforming the gravity terms in the local system of - * equations to the entire set of faces within the interaction volume - * \param A Matrix needed for the "reconstruction" of face unknowns as a function of gravity - * \param getT Lambda to evaluate scv-wise hydraulic conductivities + * \param getRho Lambda to obtain the density from volume variables */ - template< class GC, class GOut, class IV, class TensorFunc > - void assembleGravity(GC& g, - GOut& outsideG, - const IV& iv, - const typename IV::Traits::MatVecTraits::CMatrix& CA, - const typename IV::Traits::MatVecTraits::AMatrix& A, - const TensorFunc& getT) + template< class DataHandle, class IV, class GetRho > + void assembleGravity(DataHandle& handle, const IV& iv, const GetRho& getRho) { - DUNE_THROW(Dune::NotImplemented, "Implementation does not provide a assembleGravity() function to be used on surface grids"); + DUNE_THROW(Dune::NotImplemented, "Implementation does not provide a assembleGravity() function"); } private: -- GitLab From 638f795928454e926cf2490f63bc675a5c47d511 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Gl=C3=A4ser?= Date: Mon, 19 Nov 2018 12:07:13 +0100 Subject: [PATCH 17/35] [mpfa][iv] remove obsolete matrices All matrices are now stored in the data handles --- .../mpfa/omethod/interactionvolume.hh | 22 ------------------- .../mpfa/omethod/staticinteractionvolume.hh | 22 ------------------- 2 files changed, 44 deletions(-) diff --git a/dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh b/dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh index 4ed30d9eec..2dd239e6cb 100644 --- a/dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh +++ b/dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh @@ -249,11 +249,6 @@ public: } } } - - // Maybe resize local matrices if dynamic types are used - resizeMatrix(A_, numUnknowns_, numUnknowns_); - resizeMatrix(B_, numUnknowns_, numKnowns_); - resizeMatrix(C_, numFaces_, numUnknowns_); } //! returns the number of primary scvfs of this interaction volume @@ -296,18 +291,6 @@ public: const std::vector& dirichletData() const { return dirichletData_; } - //! returns the matrix associated with face unknowns in local equation system - const AMatrix& A() const { return A_; } - AMatrix& A() { return A_; } - - //! returns the matrix associated with cell unknowns in local equation system - const BMatrix& B() const { return B_; } - BMatrix& B() { return B_; } - - //! returns the matrix associated with face unknowns in flux expressions - const CMatrix& C() const { return C_; } - CMatrix& C() { return C_; } - //! returns container storing the transmissibilities for each face & coordinate const TransmissibilityStorage& omegas() const { return wijk_; } TransmissibilityStorage& omegas() { return wijk_; } @@ -349,11 +332,6 @@ private: std::vector localFaceData_; std::vector dirichletData_; - // Matrices needed for computation of transmissibilities - AMatrix A_; - BMatrix B_; - CMatrix C_; - // The omega factors are stored during assembly of local system TransmissibilityStorage wijk_; diff --git a/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh b/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh index c27a3f0598..cfd6891edc 100644 --- a/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh +++ b/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh @@ -207,11 +207,6 @@ public: // make sure we found it assert(localFaceData_[faceIdxLocal*2+1].ivLocalInsideScvIndex() == outsideLocalScvIdx); } - - // Maybe resize local matrices if dynamic types are used - resizeMatrix(A_, numScvf, numScvf); - resizeMatrix(B_, numScvf, numScv); - resizeMatrix(C_, numScvf, numScv); } //! returns the number of primary scvfs of this interaction volume @@ -255,18 +250,6 @@ public: const std::array& dirichletData() const { return dirichletData_; } - //! returns the matrix associated with face unknowns in local equation system - const AMatrix& A() const { return A_; } - AMatrix& A() { return A_; } - - //! returns the matrix associated with cell unknowns in local equation system - const BMatrix& B() const { return B_; } - BMatrix& B() { return B_; } - - //! returns the matrix associated with face unknowns in flux expressions - const CMatrix& C() const { return C_; } - CMatrix& C() { return C_; } - //! returns container storing the transmissibilities for each face & coordinate const TransmissibilityStorage& omegas() const { return wijk_; } TransmissibilityStorage& omegas() { return wijk_; } @@ -308,11 +291,6 @@ private: std::array scvfs_; std::array localFaceData_; - // Matrices needed for computation of transmissibilities - AMatrix A_; - BMatrix B_; - CMatrix C_; - // The omega factors are stored during assembly of local system TransmissibilityStorage wijk_; -- GitLab From 4ee62dd26664af372115072fb74b51b32c2838dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Gl=C3=A4ser?= Date: Mon, 19 Nov 2018 12:02:24 +0100 Subject: [PATCH 18/35] [mpfa][ivlocalassembler] put resize() methods in base class --- .../cellcentered/mpfa/localassembler.hh | 67 ++++++++++++++++++- .../mpfa/omethod/interactionvolume.hh | 1 - .../mpfa/omethod/localassembler.hh | 25 +++---- .../mpfa/omethod/staticinteractionvolume.hh | 1 - 4 files changed, 77 insertions(+), 17 deletions(-) diff --git a/dumux/discretization/cellcentered/mpfa/localassembler.hh b/dumux/discretization/cellcentered/mpfa/localassembler.hh index 1fdc768594..2dc51bb868 100644 --- a/dumux/discretization/cellcentered/mpfa/localassembler.hh +++ b/dumux/discretization/cellcentered/mpfa/localassembler.hh @@ -26,8 +26,9 @@ #ifndef DUMUX_DISCRETIZATION_CC_MPFA_LOCAL_ASSEMBLER_HH #define DUMUX_DISCRETIZATION_CC_MPFA_LOCAL_ASSEMBLER_HH -#include +#include +#include #include namespace Dumux @@ -58,7 +59,34 @@ class InteractionVolumeAssemblerBase using FVElementGeometry = EG; using ElementVolumeVariables = EV; - public: + typedef std::true_type yes; + typedef std::false_type no; + + //! Determines whether or not a matrix has a resize() function + template + struct matrix_has_resize_method + { + private: + // resize function is called with two indices for matrices + template static auto test(int) -> decltype(std::declval().resize(0, 0), yes()); + template static no test(...); + public: + static constexpr bool value = std::is_same(0)), yes>::value; + }; + + //! determines whether or not a vector has a resize() function + template + struct vector_has_resize_method + { + private: + // resize function is called with one index for vectors + template static auto test(int) -> decltype(std::declval().resize(0), yes()); + template static no test(...); + public: + static constexpr bool value = std::is_same(0)), yes>::value; + }; + + public: /*! * \brief The constructor. * Sets pointers to the objects required for a subsequent call to assemble(). @@ -131,7 +159,40 @@ class InteractionVolumeAssemblerBase DUNE_THROW(Dune::NotImplemented, "Implementation does not provide a assembleGravity() function"); } - private: +protected: + //! resizes a matrix to the given sizes (specialization for dynamic matrix type) + template< class Matrix, + class size_type, + std::enable_if_t::value, int> = 0 > + void resizeMatrix_(Matrix& M, size_type rows, size_type cols) + { + M.resize(rows, cols); + } + + //! resizes a matrix to the given sizes (specialization for static matrix type - do nothing) + template< class Matrix, + class size_type, + std::enable_if_t::value, int> = 0 > + void resizeMatrix_(Matrix& M, size_type rows, size_type cols) + {} + + //! resizes a vector to the given size (specialization for dynamic matrix type) + template< class Vector, + class size_type, + std::enable_if_t::value, int> = 0 > + void resizeVector_(Vector& v, size_type size) + { + v.resize(size); + } + + //! resizes a vector to the given size (specialization for static vector type - do nothing) + template< class Vector, + class size_type, + std::enable_if_t::value, int> = 0 > + void resizeVector_(Vector& v, size_type rows) + {} + +private: // pointers to the data required for assembly const Problem* problemPtr_; const FVElementGeometry* fvGeometryPtr_; diff --git a/dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh b/dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh index 2dd239e6cb..ab52179d16 100644 --- a/dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh +++ b/dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh @@ -32,7 +32,6 @@ #include #include -#include #include #include diff --git a/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh b/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh index fd25271136..ad77922b52 100644 --- a/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh +++ b/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh @@ -26,7 +26,6 @@ #define DUMUX_DISCRETIZATION_CC_MPFA_O_LOCAL_ASSEMBLER_HH #include -#include #include #include @@ -97,7 +96,9 @@ public: const auto numOutsideFaces = curGlobalScvf.boundary() ? 0 : curGlobalScvf.numOutsideScvs(); // resize each face entry to the right number of outside faces tijOut[fIdx].resize(numOutsideFaces); - std::for_each(tijOut[fIdx].begin(), tijOut[fIdx].end(), [&iv](auto& v) { resizeVector(v, iv.numKnowns()); }); + std::for_each(tijOut[fIdx].begin(), + tijOut[fIdx].end(), + [&](auto& v) { this->resizeVector_(v, iv.numKnowns()); }); } // compute outside transmissibilities @@ -153,7 +154,7 @@ public: void assembleU(DataHandle& handle, const IV& iv, const GetU& getU) { auto& u = handle.uj(); - resizeVector(u, iv.numKnowns()); + this->resizeVector_(u, iv.numKnowns()); // put the cell unknowns first, then Dirichlet values typename IV::Traits::IndexSet::LocalIndexType i = 0; @@ -182,9 +183,9 @@ public: // resize the gravity vectors auto& g = handle.g(); auto& outsideG = handle.gOutside(); - resizeVector(g, iv.numFaces()); + this->resizeVector_(g, iv.numFaces()); if (isSurfaceGrid) - resizeVector(outsideG, iv.numFaces()); + this->resizeVector_(outsideG, iv.numFaces()); // we require the CA matrix to have the correct size already assert(CA.rows() == iv.numFaces() && CA.cols() == iv.numUnknowns()); @@ -219,7 +220,7 @@ public: if (isSurfaceGrid) { - resizeVector(outsideG[faceIdx], numOutsideFaces); + this->resizeVector_(outsideG[faceIdx], numOutsideFaces); std::fill(outsideG[faceIdx].begin(), outsideG[faceIdx].end(), 0.0); } @@ -279,7 +280,7 @@ public: { using FaceVector = typename IV::Traits::MatVecTraits::FaceVector; FaceVector AG; - resizeVector(AG, iv.numUnknowns()); + this->resizeVector_(AG, iv.numUnknowns()); handle.A().mv(sum_alphas, AG); // compute gravitational accelerations @@ -350,7 +351,7 @@ private: if (iv.numUnknowns() == 0) { // resize & reset D matrix - resizeMatrix(D, iv.numFaces(), iv.numKnowns()); D = 0.0; + this->resizeMatrix_(D, iv.numFaces(), iv.numKnowns()); D = 0.0; // Loop over all the faces, in this case these are all dirichlet boundaries for (LocalIndexType faceIdx = 0; faceIdx < iv.numFaces(); ++faceIdx) @@ -382,10 +383,10 @@ private: else { // resize & reset matrices - resizeMatrix(A, iv.numUnknowns(), iv.numUnknowns()); A = 0.0; - resizeMatrix(B, iv.numUnknowns(), iv.numKnowns()); B = 0.0; - resizeMatrix(C, iv.numFaces(), iv.numUnknowns()); C = 0.0; - resizeMatrix(D, iv.numFaces(), iv.numKnowns()); D = 0.0; + this->resizeMatrix_(A, iv.numUnknowns(), iv.numUnknowns()); A = 0.0; + this->resizeMatrix_(B, iv.numUnknowns(), iv.numKnowns()); B = 0.0; + this->resizeMatrix_(C, iv.numFaces(), iv.numUnknowns()); C = 0.0; + this->resizeMatrix_(D, iv.numFaces(), iv.numKnowns()); D = 0.0; auto& wijk = iv.omegas(); for (LocalIndexType faceIdx = 0; faceIdx < iv.numFaces(); ++faceIdx) diff --git a/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh b/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh index cfd6891edc..60f78d6d68 100644 --- a/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh +++ b/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh @@ -30,7 +30,6 @@ #include #include -#include #include #include -- GitLab From bd0cb2c2c55ef84bee1daa863a7ba86ec639a573 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Gl=C3=A4ser?= Date: Mon, 19 Nov 2018 12:11:18 +0100 Subject: [PATCH 19/35] [common] remove obsolete matrixvector helper That was used by the mpfa framework only, which also doesn't anymore. --- dumux/common/CMakeLists.txt | 1 - dumux/common/matrixvectorhelper.hh | 97 ------------------------------ 2 files changed, 98 deletions(-) delete mode 100644 dumux/common/matrixvectorhelper.hh diff --git a/dumux/common/CMakeLists.txt b/dumux/common/CMakeLists.txt index e7d5753277..abda2600c7 100644 --- a/dumux/common/CMakeLists.txt +++ b/dumux/common/CMakeLists.txt @@ -20,7 +20,6 @@ intersectionmapper.hh intrange.hh loggingparametertree.hh math.hh -matrixvectorhelper.hh numericdifferentiation.hh optional.hh parameters.hh diff --git a/dumux/common/matrixvectorhelper.hh b/dumux/common/matrixvectorhelper.hh deleted file mode 100644 index 44769ee23f..0000000000 --- a/dumux/common/matrixvectorhelper.hh +++ /dev/null @@ -1,97 +0,0 @@ -// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- -// vi: set et ts=4 sw=4 sts=4: -/***************************************************************************** - * See the file COPYING for full copying permissions. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *****************************************************************************/ -/*! - * \file - * \ingroup Common - * \brief Helper functions to be used for memory allocation operations on matrices & vectors - * that can be called for both static and dynamic types. This is useful wherever it - * is not always known if the matrix & vector types at hand are static or dynamic. - */ -#ifndef DUMUX_COMMON_MATRIX_VECTOR_HELPER_HH -#define DUMUX_COMMON_MATRIX_VECTOR_HELPER_HH - -#include - -namespace Dumux { - -//! Determines whether or not a matrix has a resize() function -template -struct matrix_has_resize_method -{ -private: - typedef std::true_type yes; - typedef std::false_type no; - - // resize function is called with two indices for matrices - template static auto test(int) -> decltype(std::declval().resize(0, 0), yes()); - template static no test(...); - -public: - static constexpr bool value = std::is_same(0)), yes>::value; -}; - -//! determines whether or not a vector has a resize() function -template -struct vector_has_resize_method -{ -private: - typedef std::true_type yes; - typedef std::false_type no; - - // resize function is called with one index for vectors - template static auto test(int) -> decltype(std::declval().resize(0), yes()); - template static no test(...); - -public: - static constexpr bool value = std::is_same(0)), yes>::value; -}; - -//! resizes a matrix to the given sizes (specialization for dynamic matrix type) -template< class Matrix, - class size_type, - std::enable_if_t::value, int> = 0 > -void resizeMatrix(Matrix& M, size_type rows, size_type cols) -{ - M.resize(rows, cols); -} - -//! resizes a matrix to the given sizes (specialization for static matrix type - do nothing) -template< class Matrix, - class size_type, - std::enable_if_t::value, int> = 0 > -void resizeMatrix(Matrix& M, size_type rows, size_type cols) {} - -//! resizes a vector to the given size (specialization for dynamic matrix type) -template< class Vector, - class size_type, - std::enable_if_t::value, int> = 0 > -void resizeVector(Vector& v, size_type size) -{ - v.resize(size); -} - -//! resizes a vector to the given size (specialization for static vector type - do nothing) -template< class Vector, - class size_type, - std::enable_if_t::value, int> = 0 > -void resizeVector(Vector& v, size_type rows) {} - -} // end namespace Dumux - -#endif -- GitLab From baa881ebb399593be517855fa4ec0e0804b5bb54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Gl=C3=A4ser?= Date: Mon, 19 Nov 2018 12:33:04 +0100 Subject: [PATCH 20/35] [mpfa-o][localassembler] use iv-specific types within gravity assembly --- .../cellcentered/mpfa/omethod/localassembler.hh | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh b/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh index ad77922b52..10d1fa3435 100644 --- a/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh +++ b/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh @@ -25,8 +25,9 @@ #ifndef DUMUX_DISCRETIZATION_CC_MPFA_O_LOCAL_ASSEMBLER_HH #define DUMUX_DISCRETIZATION_CC_MPFA_O_LOCAL_ASSEMBLER_HH -#include +#include +#include #include #include #include @@ -195,10 +196,13 @@ public: //! - compute the term \f$ \alpha := \mathbf{A} \rho \ \mathbf{n}^T \mathbf{K} \mathbf{g} \f$ in each neighboring cell //! - compute \f$ \alpha^* = \sum{\alpha_{outside, i}} - \alpha_{inside} \f$ using Scalar = typename IV::Traits::MatVecTraits::TMatrix::value_type; + using FaceVector = typename IV::Traits::MatVecTraits::FaceVector; using LocalIndexType = typename IV::Traits::IndexSet::LocalIndexType; + FaceVector sum_alphas; + this->resizeVector_(sum_alphas, iv.numUnknowns()); + sum_alphas = 0.0; std::fill(g.begin(), g.end(), 0.0); - std::vector sum_alphas(iv.numUnknowns(), 0.0); for (LocalIndexType faceIdx = 0; faceIdx < iv.numFaces(); ++faceIdx) { // gravitational acceleration on this face @@ -214,9 +218,13 @@ public: posVolVars.permeability(), gravity); - const auto numOutsideFaces = curGlobalScvf.boundary() ? 0 : curGlobalScvf.numOutsideScvs(); + const auto numOutsideFaces = !curGlobalScvf.boundary() ? curGlobalScvf.numOutsideScvs() : 0; + using OutsideAlphaStorage = std::conditional_t< isSurfaceGrid, + std::vector, + Dune::ReservedVector >; + OutsideAlphaStorage alpha_outside; alpha_outside.resize(numOutsideFaces); + std::fill(alpha_outside.begin(), alpha_outside.end(), 0.0); Scalar rho; - std::vector< Scalar > alpha_outside(numOutsideFaces); if (isSurfaceGrid) { @@ -224,7 +232,6 @@ public: std::fill(outsideG[faceIdx].begin(), outsideG[faceIdx].end(), 0.0); } - if (!curLocalScvf.isDirichlet()) { rho = getRho(posVolVars); -- GitLab From d2fc21e3d7812be0c28ba5e8b5ed776e5e4d3c6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Gl=C3=A4ser?= Date: Mon, 19 Nov 2018 12:35:12 +0100 Subject: [PATCH 21/35] [mpfa][localassembly] put gravity assembly in base class This should be identical for all mpfa schemes --- .../cellcentered/mpfa/localassembler.hh | 141 +++++++++++++++- .../mpfa/omethod/localassembler.hh | 153 ------------------ 2 files changed, 140 insertions(+), 154 deletions(-) diff --git a/dumux/discretization/cellcentered/mpfa/localassembler.hh b/dumux/discretization/cellcentered/mpfa/localassembler.hh index 2dc51bb868..c3247c6b44 100644 --- a/dumux/discretization/cellcentered/mpfa/localassembler.hh +++ b/dumux/discretization/cellcentered/mpfa/localassembler.hh @@ -156,7 +156,146 @@ class InteractionVolumeAssemblerBase template< class DataHandle, class IV, class GetRho > void assembleGravity(DataHandle& handle, const IV& iv, const GetRho& getRho) { - DUNE_THROW(Dune::NotImplemented, "Implementation does not provide a assembleGravity() function"); + using GridView = typename IV::Traits::GridView; + static constexpr int dim = GridView::dimension; + static constexpr int dimWorld = GridView::dimensionworld; + static constexpr bool isSurfaceGrid = dim < dimWorld; + + // resize the gravity vectors + auto& g = handle.g(); + auto& outsideG = handle.gOutside(); + resizeVector_(g, iv.numFaces()); + if (isSurfaceGrid) + resizeVector_(outsideG, iv.numFaces()); + + // we require the CA matrix to have the correct size already + assert(CA.rows() == iv.numFaces() && CA.cols() == iv.numUnknowns()); + + //! For each face, we... + //! - arithmetically average the phase densities + //! - compute the term \f$ \alpha := \mathbf{A} \rho \ \mathbf{n}^T \mathbf{K} \mathbf{g} \f$ in each neighboring cell + //! - compute \f$ \alpha^* = \sum{\alpha_{outside, i}} - \alpha_{inside} \f$ + using Scalar = typename IV::Traits::MatVecTraits::TMatrix::value_type; + using FaceVector = typename IV::Traits::MatVecTraits::FaceVector; + using LocalIndexType = typename IV::Traits::IndexSet::LocalIndexType; + + FaceVector sum_alphas; + resizeVector_(sum_alphas, iv.numUnknowns()); + sum_alphas = 0.0; + std::fill(g.begin(), g.end(), 0.0); + for (LocalIndexType faceIdx = 0; faceIdx < iv.numFaces(); ++faceIdx) + { + // gravitational acceleration on this face + const auto& curLocalScvf = iv.localScvf(faceIdx); + const auto& curGlobalScvf = fvGeometry().scvf(curLocalScvf.gridScvfIndex()); + const auto& gravity = problem().gravityAtPos(curGlobalScvf.ipGlobal()); + + // get permeability tensor in "positive" sub volume + const auto& neighborScvIndices = curLocalScvf.neighboringLocalScvIndices(); + const auto& posGlobalScv = fvGeometry().scv(iv.localScv(neighborScvIndices[0]).gridScvIndex()); + const auto& posVolVars = elemVolVars()[posGlobalScv]; + const auto alpha_inside = posVolVars.extrusionFactor()*vtmv(curGlobalScvf.unitOuterNormal(), + posVolVars.permeability(), + gravity); + + const auto numOutsideFaces = !curGlobalScvf.boundary() ? curGlobalScvf.numOutsideScvs() : 0; + using OutsideAlphaStorage = std::conditional_t< isSurfaceGrid, + std::vector, + Dune::ReservedVector >; + OutsideAlphaStorage alpha_outside; alpha_outside.resize(numOutsideFaces); + std::fill(alpha_outside.begin(), alpha_outside.end(), 0.0); + Scalar rho; + + if (isSurfaceGrid) + { + resizeVector_(outsideG[faceIdx], numOutsideFaces); + std::fill(outsideG[faceIdx].begin(), outsideG[faceIdx].end(), 0.0); + } + + if (!curLocalScvf.isDirichlet()) + { + rho = getRho(posVolVars); + + // arithmetically average density on inside faces + const auto localDofIdx = curLocalScvf.localDofIndex(); + if (!curGlobalScvf.boundary()) + { + for (unsigned int idxInOutside = 0; idxInOutside < curGlobalScvf.numOutsideScvs(); ++idxInOutside) + { + // obtain outside tensor + const auto negLocalScvIdx = neighborScvIndices[idxInOutside+1]; + const auto& negGlobalScv = fvGeometry().scv(iv.localScv(negLocalScvIdx).gridScvIndex()); + const auto& negVolVars = elemVolVars()[negGlobalScv]; + const auto& flipScvf = !isSurfaceGrid ? curGlobalScvf + : fvGeometry().flipScvf(curGlobalScvf.index(), idxInOutside); + + alpha_outside[idxInOutside] = negVolVars.extrusionFactor()*vtmv(flipScvf.unitOuterNormal(), + negVolVars.permeability(), + gravity); + if (isSurfaceGrid) + alpha_outside[idxInOutside] *= -1.0; + + rho += getRho(negVolVars); + sum_alphas[localDofIdx] += alpha_outside[idxInOutside]; + } + } + + rho /= numOutsideFaces + 1; + sum_alphas[localDofIdx] -= alpha_inside; + sum_alphas[localDofIdx] *= rho*curGlobalScvf.area(); + } + // use density resulting from Dirichlet BCs + else + rho = getRho(elemVolVars()[curGlobalScvf.outsideScvIdx()]); + + // add "inside" & "outside" alphas to gravity containers + g[faceIdx] += alpha_inside*rho*curGlobalScvf.area(); + + if (isSurfaceGrid) + { + unsigned int i = 0; + for (const auto& alpha : alpha_outside) + outsideG[faceIdx][i++] += alpha*rho*curGlobalScvf.area(); + } + } + + // g += CA*sum_alphas + // outsideG = wikj*A^-1*sum_alphas + outsideG + handle.CA().umv(sum_alphas, g); + + if (isSurfaceGrid) + { + using FaceVector = typename IV::Traits::MatVecTraits::FaceVector; + FaceVector AG; + resizeVector_(AG, iv.numUnknowns()); + handle.A().mv(sum_alphas, AG); + + // compute gravitational accelerations + for (const auto& localFaceData : iv.localFaceData()) + { + // continue only for "outside" faces + if (!localFaceData.isOutsideFace()) + continue; + + const auto localScvIdx = localFaceData.ivLocalInsideScvIndex(); + const auto localScvfIdx = localFaceData.ivLocalScvfIndex(); + const auto idxInOutside = localFaceData.scvfLocalOutsideScvfIndex(); + const auto& posLocalScv = iv.localScv(localScvIdx); + const auto& wijk = iv.omegas()[localScvfIdx][idxInOutside+1]; + + // make sure the given outside gravity container has the right size + assert(outsideG[localScvfIdx].size() == iv.localScvf(localScvfIdx).neighboringLocalScvIndices().size()-1); + + // add contributions from all local directions + for (LocalIndexType localDir = 0; localDir < dim; localDir++) + { + // the scvf corresponding to this local direction in the scv + const auto& curLocalScvf = iv.localScvf(posLocalScv.localScvfIndex(localDir)); + if (!curLocalScvf.isDirichlet()) + outsideG[localScvfIdx][idxInOutside] -= wijk[localDir]*AG[curLocalScvf.localDofIndex()]; + } + } + } } protected: diff --git a/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh b/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh index 10d1fa3435..4828fc0cff 100644 --- a/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh +++ b/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh @@ -165,159 +165,6 @@ public: u[i++] = getU( this->elemVolVars()[data.volVarIndex()] ); } - /*! - * \brief Assembles the gravitational flux contributions on the scvfs within an mpfa-o - * interaction volume. - * - * \param handle The data handle in which the vector is stored - * \param iv The mpfa-o interaction volume - * \param getRho Lambda to obtain the density from volume variables - */ - template< class DataHandle, class IV, class GetRho > - void assembleGravity(DataHandle& handle, const IV& iv, const GetRho& getRho) - { - using GridView = typename IV::Traits::GridView; - static constexpr int dim = GridView::dimension; - static constexpr int dimWorld = GridView::dimensionworld; - static constexpr bool isSurfaceGrid = dim < dimWorld; - - // resize the gravity vectors - auto& g = handle.g(); - auto& outsideG = handle.gOutside(); - this->resizeVector_(g, iv.numFaces()); - if (isSurfaceGrid) - this->resizeVector_(outsideG, iv.numFaces()); - - // we require the CA matrix to have the correct size already - assert(CA.rows() == iv.numFaces() && CA.cols() == iv.numUnknowns()); - - //! For each face, we... - //! - arithmetically average the phase densities - //! - compute the term \f$ \alpha := \mathbf{A} \rho \ \mathbf{n}^T \mathbf{K} \mathbf{g} \f$ in each neighboring cell - //! - compute \f$ \alpha^* = \sum{\alpha_{outside, i}} - \alpha_{inside} \f$ - using Scalar = typename IV::Traits::MatVecTraits::TMatrix::value_type; - using FaceVector = typename IV::Traits::MatVecTraits::FaceVector; - using LocalIndexType = typename IV::Traits::IndexSet::LocalIndexType; - - FaceVector sum_alphas; - this->resizeVector_(sum_alphas, iv.numUnknowns()); - sum_alphas = 0.0; - std::fill(g.begin(), g.end(), 0.0); - for (LocalIndexType faceIdx = 0; faceIdx < iv.numFaces(); ++faceIdx) - { - // gravitational acceleration on this face - const auto& curLocalScvf = iv.localScvf(faceIdx); - const auto& curGlobalScvf = this->fvGeometry().scvf(curLocalScvf.gridScvfIndex()); - const auto& gravity = this->problem().gravityAtPos(curGlobalScvf.ipGlobal()); - - // get permeability tensor in "positive" sub volume - const auto& neighborScvIndices = curLocalScvf.neighboringLocalScvIndices(); - const auto& posGlobalScv = this->fvGeometry().scv(iv.localScv(neighborScvIndices[0]).gridScvIndex()); - const auto& posVolVars = this->elemVolVars()[posGlobalScv]; - const auto alpha_inside = posVolVars.extrusionFactor()*vtmv(curGlobalScvf.unitOuterNormal(), - posVolVars.permeability(), - gravity); - - const auto numOutsideFaces = !curGlobalScvf.boundary() ? curGlobalScvf.numOutsideScvs() : 0; - using OutsideAlphaStorage = std::conditional_t< isSurfaceGrid, - std::vector, - Dune::ReservedVector >; - OutsideAlphaStorage alpha_outside; alpha_outside.resize(numOutsideFaces); - std::fill(alpha_outside.begin(), alpha_outside.end(), 0.0); - Scalar rho; - - if (isSurfaceGrid) - { - this->resizeVector_(outsideG[faceIdx], numOutsideFaces); - std::fill(outsideG[faceIdx].begin(), outsideG[faceIdx].end(), 0.0); - } - - if (!curLocalScvf.isDirichlet()) - { - rho = getRho(posVolVars); - - // arithmetically average density on inside faces - const auto localDofIdx = curLocalScvf.localDofIndex(); - if (!curGlobalScvf.boundary()) - { - for (unsigned int idxInOutside = 0; idxInOutside < curGlobalScvf.numOutsideScvs(); ++idxInOutside) - { - // obtain outside tensor - const auto negLocalScvIdx = neighborScvIndices[idxInOutside+1]; - const auto& negGlobalScv = this->fvGeometry().scv(iv.localScv(negLocalScvIdx).gridScvIndex()); - const auto& negVolVars = this->elemVolVars()[negGlobalScv]; - const auto& flipScvf = !isSurfaceGrid ? curGlobalScvf - : this->fvGeometry().flipScvf(curGlobalScvf.index(), idxInOutside); - - alpha_outside[idxInOutside] = negVolVars.extrusionFactor()*vtmv(flipScvf.unitOuterNormal(), - negVolVars.permeability(), - gravity); - if (isSurfaceGrid) - alpha_outside[idxInOutside] *= -1.0; - - rho += getRho(negVolVars); - sum_alphas[localDofIdx] += alpha_outside[idxInOutside]; - } - } - - rho /= numOutsideFaces + 1; - sum_alphas[localDofIdx] -= alpha_inside; - sum_alphas[localDofIdx] *= rho*curGlobalScvf.area(); - } - // use density resulting from Dirichlet BCs - else - rho = getRho(this->elemVolVars()[curGlobalScvf.outsideScvIdx()]); - - // add "inside" & "outside" alphas to gravity containers - g[faceIdx] += alpha_inside*rho*curGlobalScvf.area(); - - if (isSurfaceGrid) - { - unsigned int i = 0; - for (const auto& alpha : alpha_outside) - outsideG[faceIdx][i++] += alpha*rho*curGlobalScvf.area(); - } - } - - // g += CA*sum_alphas - // outsideG = wikj*A^-1*sum_alphas + outsideG - handle.CA().umv(sum_alphas, g); - - if (isSurfaceGrid) - { - using FaceVector = typename IV::Traits::MatVecTraits::FaceVector; - FaceVector AG; - this->resizeVector_(AG, iv.numUnknowns()); - handle.A().mv(sum_alphas, AG); - - // compute gravitational accelerations - for (const auto& localFaceData : iv.localFaceData()) - { - // continue only for "outside" faces - if (!localFaceData.isOutsideFace()) - continue; - - const auto localScvIdx = localFaceData.ivLocalInsideScvIndex(); - const auto localScvfIdx = localFaceData.ivLocalScvfIndex(); - const auto idxInOutside = localFaceData.scvfLocalOutsideScvfIndex(); - const auto& posLocalScv = iv.localScv(localScvIdx); - const auto& wijk = iv.omegas()[localScvfIdx][idxInOutside+1]; - - // make sure the given outside gravity container has the right size - assert(outsideG[localScvfIdx].size() == iv.localScvf(localScvfIdx).neighboringLocalScvIndices().size()-1); - - // add contributions from all local directions - for (LocalIndexType localDir = 0; localDir < dim; localDir++) - { - // the scvf corresponding to this local direction in the scv - const auto& curLocalScvf = iv.localScvf(posLocalScv.localScvfIndex(localDir)); - if (!curLocalScvf.isDirichlet()) - outsideG[localScvfIdx][idxInOutside] -= wijk[localDir]*AG[curLocalScvf.localDofIndex()]; - } - } - } - } - private: /*! * \brief Assemble the matrices involved in the flux expressions -- GitLab From 3e3f3aa60d55d1b54def9173bb0d73651cd3cf3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Gl=C3=A4ser?= Date: Mon, 19 Nov 2018 16:36:17 +0100 Subject: [PATCH 22/35] [mpfa][ivlocalassembler][gravity] remove obsolete reset to zero --- dumux/discretization/cellcentered/mpfa/localassembler.hh | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/dumux/discretization/cellcentered/mpfa/localassembler.hh b/dumux/discretization/cellcentered/mpfa/localassembler.hh index c3247c6b44..8c644aecb5 100644 --- a/dumux/discretization/cellcentered/mpfa/localassembler.hh +++ b/dumux/discretization/cellcentered/mpfa/localassembler.hh @@ -182,7 +182,6 @@ class InteractionVolumeAssemblerBase FaceVector sum_alphas; resizeVector_(sum_alphas, iv.numUnknowns()); sum_alphas = 0.0; - std::fill(g.begin(), g.end(), 0.0); for (LocalIndexType faceIdx = 0; faceIdx < iv.numFaces(); ++faceIdx) { // gravitational acceleration on this face @@ -207,10 +206,7 @@ class InteractionVolumeAssemblerBase Scalar rho; if (isSurfaceGrid) - { resizeVector_(outsideG[faceIdx], numOutsideFaces); - std::fill(outsideG[faceIdx].begin(), outsideG[faceIdx].end(), 0.0); - } if (!curLocalScvf.isDirichlet()) { @@ -249,13 +245,13 @@ class InteractionVolumeAssemblerBase rho = getRho(elemVolVars()[curGlobalScvf.outsideScvIdx()]); // add "inside" & "outside" alphas to gravity containers - g[faceIdx] += alpha_inside*rho*curGlobalScvf.area(); + g[faceIdx] = alpha_inside*rho*curGlobalScvf.area(); if (isSurfaceGrid) { unsigned int i = 0; for (const auto& alpha : alpha_outside) - outsideG[faceIdx][i++] += alpha*rho*curGlobalScvf.area(); + outsideG[faceIdx][i++] = alpha*rho*curGlobalScvf.area(); } } -- GitLab From 0b4b74108868dbd3cdbb6b696a34e2ceb147581c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Gl=C3=A4ser?= Date: Mon, 19 Nov 2018 16:45:36 +0100 Subject: [PATCH 23/35] [mpfa][ivlocalassembler] assemble deltaG directly into data handle --- .../mpfa/interactionvolumedatahandle.hh | 8 +++++- .../cellcentered/mpfa/localassembler.hh | 28 ++++++++----------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh b/dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh index fbcb7a6dcf..30bb4088f7 100644 --- a/dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh +++ b/dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh @@ -149,6 +149,7 @@ class AdvectionDataHandle static constexpr int numPhases = PhysicsTraits::numPhases; using Base2 = Detail::VectorDataHandleBase; + using UnknownVector = typename MatVecTraits::AMatrix::row_type; using FaceVector = typename MatVecTraits::FaceVector; using FaceScalar = typename FaceVector::value_type; using OutsideGravityStorage = std::vector< std::vector >; @@ -161,12 +162,17 @@ public: const FaceVector& g() const { return g_[Base2::contextIdx1_]; } FaceVector& g() { return g_[Base2::contextIdx1_]; } + //! The deltaG vector for gravity within the iv-local eq-system + const UnknownVector& deltaG() const { return deltaG_[Base2::contextIdx1_]; } + UnknownVector& deltaG() { return deltaG_[Base2::contextIdx1_]; } + //! The gravitational acceleration for one phase on "outside" faces (used on surface grids) const OutsideGravityStorage& gOutside() const { return outsideG_[Base2::contextIdx1_]; } OutsideGravityStorage& gOutside() { return outsideG_[Base2::contextIdx1_]; } private: - std::array< FaceVector, numPhases > g_; //!< The gravitational acceleration at each scvf (only for enabled gravity) + std::array< FaceVector, numPhases > g_; //!< The gravitational acceleration at each scvf (only for enabled gravity) + std::array< UnknownVector, numPhases > deltaG_; //!< The gravity coefficients forming part of iv-local eq-system std::array< OutsideGravityStorage, numPhases > outsideG_; //!< The gravitational acceleration on "outside" faces (only on surface grids) }; diff --git a/dumux/discretization/cellcentered/mpfa/localassembler.hh b/dumux/discretization/cellcentered/mpfa/localassembler.hh index 8c644aecb5..40948a54a3 100644 --- a/dumux/discretization/cellcentered/mpfa/localassembler.hh +++ b/dumux/discretization/cellcentered/mpfa/localassembler.hh @@ -163,8 +163,10 @@ class InteractionVolumeAssemblerBase // resize the gravity vectors auto& g = handle.g(); + auto& deltaG = handle.deltaG(); auto& outsideG = handle.gOutside(); resizeVector_(g, iv.numFaces()); + resizeVector_(deltaG, iv.numUnknowns()); if (isSurfaceGrid) resizeVector_(outsideG, iv.numFaces()); @@ -176,12 +178,8 @@ class InteractionVolumeAssemblerBase //! - compute the term \f$ \alpha := \mathbf{A} \rho \ \mathbf{n}^T \mathbf{K} \mathbf{g} \f$ in each neighboring cell //! - compute \f$ \alpha^* = \sum{\alpha_{outside, i}} - \alpha_{inside} \f$ using Scalar = typename IV::Traits::MatVecTraits::TMatrix::value_type; - using FaceVector = typename IV::Traits::MatVecTraits::FaceVector; using LocalIndexType = typename IV::Traits::IndexSet::LocalIndexType; - FaceVector sum_alphas; - resizeVector_(sum_alphas, iv.numUnknowns()); - sum_alphas = 0.0; for (LocalIndexType faceIdx = 0; faceIdx < iv.numFaces(); ++faceIdx) { // gravitational acceleration on this face @@ -210,10 +208,11 @@ class InteractionVolumeAssemblerBase if (!curLocalScvf.isDirichlet()) { + const auto localDofIdx = curLocalScvf.localDofIndex(); + rho = getRho(posVolVars); + deltaG[localDofIdx] = 0.0; - // arithmetically average density on inside faces - const auto localDofIdx = curLocalScvf.localDofIndex(); if (!curGlobalScvf.boundary()) { for (unsigned int idxInOutside = 0; idxInOutside < curGlobalScvf.numOutsideScvs(); ++idxInOutside) @@ -232,13 +231,13 @@ class InteractionVolumeAssemblerBase alpha_outside[idxInOutside] *= -1.0; rho += getRho(negVolVars); - sum_alphas[localDofIdx] += alpha_outside[idxInOutside]; + deltaG[localDofIdx] += alpha_outside[idxInOutside]; } } rho /= numOutsideFaces + 1; - sum_alphas[localDofIdx] -= alpha_inside; - sum_alphas[localDofIdx] *= rho*curGlobalScvf.area(); + deltaG[localDofIdx] -= alpha_inside; + deltaG[localDofIdx] *= rho*curGlobalScvf.area(); } // use density resulting from Dirichlet BCs else @@ -255,16 +254,14 @@ class InteractionVolumeAssemblerBase } } - // g += CA*sum_alphas - // outsideG = wikj*A^-1*sum_alphas + outsideG - handle.CA().umv(sum_alphas, g); - + // add iv-wide contributions to gravity vectors + handle.CA().umv(deltaG, g); if (isSurfaceGrid) { using FaceVector = typename IV::Traits::MatVecTraits::FaceVector; FaceVector AG; resizeVector_(AG, iv.numUnknowns()); - handle.A().mv(sum_alphas, AG); + handle.A().mv(deltaG, AG); // compute gravitational accelerations for (const auto& localFaceData : iv.localFaceData()) @@ -279,9 +276,6 @@ class InteractionVolumeAssemblerBase const auto& posLocalScv = iv.localScv(localScvIdx); const auto& wijk = iv.omegas()[localScvfIdx][idxInOutside+1]; - // make sure the given outside gravity container has the right size - assert(outsideG[localScvfIdx].size() == iv.localScvf(localScvfIdx).neighboringLocalScvIndices().size()-1); - // add contributions from all local directions for (LocalIndexType localDir = 0; localDir < dim; localDir++) { -- GitLab From d8a1a2c9af9701e363698d6f0ab0f850be488517 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Gl=C3=A4ser?= Date: Mon, 19 Nov 2018 17:24:05 +0100 Subject: [PATCH 24/35] [mpfa][darcyslaw] store pointer to handle instead of storing pointers to the transmissibilities and pressures etc, we now only store a pointer to the data handle and reconstruct the fluxes in the DarcysLaw implementation. This dramatically reduces the number of lines needed for the cache implementation. --- .../cellcentered/mpfa/darcyslaw.hh | 237 +++++------------- .../mpfa/fluxvariablescachefiller.hh | 3 + .../mpfa/interactionvolumedatahandle.hh | 4 +- .../1p/incompressiblelocalresidual.hh | 47 +--- dumux/porousmediumflow/fluxvariablescache.hh | 29 ++- 5 files changed, 93 insertions(+), 227 deletions(-) diff --git a/dumux/discretization/cellcentered/mpfa/darcyslaw.hh b/dumux/discretization/cellcentered/mpfa/darcyslaw.hh index 18cd9caa6f..10d186ec21 100644 --- a/dumux/discretization/cellcentered/mpfa/darcyslaw.hh +++ b/dumux/discretization/cellcentered/mpfa/darcyslaw.hh @@ -50,6 +50,9 @@ class DarcysLawImplementation using GridView = GetPropType; using Element = typename GridView::template Codim<0>::Entity; + static constexpr int dim = GridView::dimension; + static constexpr int dimWorld = GridView::dimensionworld; + using FVGridGeometry = GetPropType; using FVElementGeometry = typename FVGridGeometry::LocalView; using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace; @@ -74,44 +77,34 @@ class DarcysLawImplementation { // get interaction volume related data from the filler class & upate the cache if (fvGeometry.fvGridGeometry().vertexUsesSecondaryInteractionVolume(scvf.vertexIndex())) - scvfFluxVarsCache.updateAdvection(problem, - fluxVarsCacheFiller.secondaryInteractionVolume(), + scvfFluxVarsCache.updateAdvection(fluxVarsCacheFiller.secondaryInteractionVolume(), fluxVarsCacheFiller.secondaryIvLocalFaceData(), - fluxVarsCacheFiller.secondaryIvDataHandle(), - scvf); + fluxVarsCacheFiller.secondaryIvDataHandle()); else - scvfFluxVarsCache.updateAdvection(problem, - fluxVarsCacheFiller.primaryInteractionVolume(), + scvfFluxVarsCache.updateAdvection(fluxVarsCacheFiller.primaryInteractionVolume(), fluxVarsCacheFiller.primaryIvLocalFaceData(), - fluxVarsCacheFiller.primaryIvDataHandle(), - scvf); + fluxVarsCacheFiller.primaryIvDataHandle()); } }; //! The cache used in conjunction with the mpfa Darcy's Law class MpfaDarcysLawCache { - static constexpr int dim = GridView::dimension; - static constexpr int dimWorld = GridView::dimensionworld; - static constexpr int numPhases = GetPropType::numPhases(); - using DualGridNodalIndexSet = GetPropType; using Stencil = typename DualGridNodalIndexSet::NodalGridStencilType; - using MpfaHelper = typename FVGridGeometry::MpfaHelper; - static constexpr bool considerSecondaryIVs = MpfaHelper::considerSecondaryIVs(); + static constexpr bool considerSecondaryIVs = FVGridGeometry::MpfaHelper::considerSecondaryIVs(); + using PrimaryDataHandle = typename ElementFluxVariablesCache::PrimaryIvDataHandle::AdvectionHandle; + using SecondaryDataHandle = typename ElementFluxVariablesCache::SecondaryIvDataHandle::AdvectionHandle; - using PrimaryInteractionVolume = GetPropType; - using PrimaryIvLocalFaceData = typename PrimaryInteractionVolume::Traits::LocalFaceData; - using PrimaryIvDataHandle = typename ElementFluxVariablesCache::PrimaryIvDataHandle; - using PrimaryIvCellVector = typename PrimaryInteractionVolume::Traits::MatVecTraits::CellVector; - using PrimaryIvTij = typename PrimaryInteractionVolume::Traits::MatVecTraits::TMatrix::row_type; + //! sets the pointer to the data handle (overload for secondary data handles) + template< bool doSecondary = considerSecondaryIVs, std::enable_if_t = 0 > + void setHandlePointer_(const SecondaryDataHandle& dataHandle) + { secondaryHandlePtr_ = &dataHandle; } - using SecondaryInteractionVolume = GetPropType; - using SecondaryIvLocalFaceData = typename SecondaryInteractionVolume::Traits::LocalFaceData; - using SecondaryIvDataHandle = typename ElementFluxVariablesCache::SecondaryIvDataHandle; - using SecondaryIvCellVector = typename SecondaryInteractionVolume::Traits::MatVecTraits::CellVector; - using SecondaryIvTij = typename SecondaryInteractionVolume::Traits::MatVecTraits::TMatrix::row_type; + //! sets the pointer to the data handle (overload for primary data handles) + void setHandlePointer_(const PrimaryDataHandle& dataHandle) + { primaryHandlePtr_ = &dataHandle; } public: // export the filler type @@ -121,168 +114,39 @@ class DarcysLawImplementation * \brief Update cached objects (transmissibilities and gravity). * This is used for updates with primary interaction volumes. * - * \param problem The problem * \param iv The interaction volume this scvf is embedded in * \param localFaceData iv-local info on this scvf * \param dataHandle Transmissibility matrix & gravity data of this iv - * \param scvf The sub-control volume face */ - template - void updateAdvection(const Problem& problem, - const PrimaryInteractionVolume& iv, - const PrimaryIvLocalFaceData& localFaceData, - const PrimaryIvDataHandle& dataHandle, - const SubControlVolumeFace &scvf) + template + void updateAdvection(const IV& iv, + const LocalFaceData& localFaceData, + const DataHandle& dataHandle) { - const auto& handle = dataHandle.advectionHandle(); - switchFluxSign_ = localFaceData.isOutsideFace(); stencil_ = &iv.stencil(); - - static const bool enableGravity = getParamFromGroup(problem.paramGroup(), "Problem.EnableGravity"); - const auto ivLocalIdx = localFaceData.ivLocalScvfIndex(); - - // standard grids - if (dim == dimWorld) - { - primaryTij_ = &handle.T()[ivLocalIdx]; - for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - { - handle.setPhaseIndex(phaseIdx); - primaryPj_[phaseIdx] = &handle.uj(); - if (enableGravity) g_[phaseIdx] = handle.g()[ivLocalIdx]; - } - } - // surface grids - else - { - if (!localFaceData.isOutsideFace()) - { - primaryTij_ = &handle.T()[ivLocalIdx]; - for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - { - handle.setPhaseIndex(phaseIdx); - primaryPj_[phaseIdx] = &handle.uj(); - if (enableGravity) g_[phaseIdx] = handle.g()[ivLocalIdx]; - } - } - else - { - const auto idxInOutsideFaces = localFaceData.scvfLocalOutsideScvfIndex(); - primaryTij_ = &handle.tijOutside()[ivLocalIdx][idxInOutsideFaces]; - for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - { - handle.setPhaseIndex(phaseIdx); - primaryPj_[phaseIdx] = &handle.uj(); - if (enableGravity) g_[phaseIdx] = handle.gOutside()[ivLocalIdx][idxInOutsideFaces]; - } - } - } - } - - /*! - * \brief Update cached objects (transmissibilities and gravity). - * This is used for updates with secondary interaction volumes. - * - * \param problem The problem - * \param iv The interaction volume this scvf is embedded in - * \param localFaceData iv-local info on this scvf - * \param dataHandle Transmissibility matrix & gravity data of this iv - * \param scvf The sub-control volume face - */ - template = 0 > - void updateAdvection(const Problem& problem, - const SecondaryInteractionVolume& iv, - const SecondaryIvLocalFaceData& localFaceData, - const SecondaryIvDataHandle& dataHandle, - const SubControlVolumeFace &scvf) - { - const auto& handle = dataHandle.advectionHandle(); - - switchFluxSign_ = localFaceData.isOutsideFace(); - stencil_ = &iv.stencil(); - - static const bool enableGravity = getParamFromGroup(problem.paramGroup(), "Problem.EnableGravity"); - const auto ivLocalIdx = localFaceData.ivLocalScvfIndex(); - - // standard grids - if (dim == dimWorld) - { - secondaryTij_ = &handle.T()[ivLocalIdx]; - for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - { - handle.setPhaseIndex(phaseIdx); - secondaryPj_[phaseIdx] = &handle.uj(); - if (enableGravity) g_[phaseIdx] = handle.g()[ivLocalIdx]; - } - } - // surface grids - else - { - if (!localFaceData.isOutsideFace()) - { - secondaryTij_ = &handle.T()[ivLocalIdx]; - for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - { - handle.setPhaseIndex(phaseIdx); - secondaryPj_[phaseIdx] = &handle.uj(); - if (enableGravity) g_[phaseIdx] = handle.g()[ivLocalIdx]; - } - } - else - { - const auto idxInOutsideFaces = localFaceData.scvfLocalOutsideScvfIndex(); - secondaryTij_ = &handle.tijOutside()[ivLocalIdx][idxInOutsideFaces]; - for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - { - handle.setPhaseIndex(phaseIdx); - secondaryPj_[phaseIdx] = &handle.uj(); - if (enableGravity) g_[phaseIdx] = handle.gOutside()[ivLocalIdx][idxInOutsideFaces]; - } - } - } + setHandlePointer_(dataHandle.advectionHandle()); } //! The stencil corresponding to the transmissibilities (primary type) const Stencil& advectionStencil() const { return *stencil_; } - //! Coefficients for the cell (& Dirichlet) unknowns in flux expressions (primary type) - const PrimaryIvTij& advectionTijPrimaryIv() const { return *primaryTij_; } - - //! Coefficients for the cell (& Dirichlet) unknowns in flux expressions (secondary type) - const SecondaryIvTij& advectionTijSecondaryIv() const { return *secondaryTij_; } - - //! The cell (& maybe Dirichlet) pressures within this interaction volume (primary type) - const PrimaryIvCellVector& pressuresPrimaryIv(unsigned int phaseIdx) const { return *primaryPj_[phaseIdx]; } - - //! The cell (& maybe Dirichlet) pressures within this interaction volume (secondary type) - const SecondaryIvCellVector& pressuresSecondaryIv(unsigned int phaseIdx) const { return *secondaryPj_[phaseIdx]; } + //! The corresponding data handles + const PrimaryDataHandle& advectionPrimaryDataHandle() const { return *primaryHandlePtr_; } + const SecondaryDataHandle& advectionSecondaryDataHandle() const { return *secondaryHandlePtr_; } - //! The gravitational acceleration for a phase on this scvf - Scalar gravity(unsigned int phaseIdx) const { return g_[phaseIdx]; } - - //! In the interaction volume-local system of eq we have one unknown per face. - //! On scvfs on this face, but in "outside" (neighbor) elements of it, we have - //! to take the negative value of the fluxes due to the flipped normal vector. - //! This function returns whether or not this scvf is an "outside" face in the iv. + //! Returns whether or not this scvf is an "outside" face in the scope of the iv. bool advectionSwitchFluxSign() const { return switchFluxSign_; } private: bool switchFluxSign_; + //! pointers to the corresponding iv-data handles + const PrimaryDataHandle* primaryHandlePtr_; + const SecondaryDataHandle* secondaryHandlePtr_; + //! The stencil, i.e. the grid indices j const Stencil* stencil_; - - //! The transmissibilities such that f = Tij*pj - const PrimaryIvTij* primaryTij_; - const SecondaryIvTij* secondaryTij_; - - //! The interaction-volume wide phase pressures pj - std::array primaryPj_; - std::array secondaryPj_; - - //! Gravitational flux contribution on this face - std::array< Scalar, numPhases > g_; }; public: @@ -303,28 +167,41 @@ public: { const auto& fluxVarsCache = elemFluxVarsCache[scvf]; - // compute t_ij*p_j - Scalar scvfFlux; + // forward to the private function taking the iv data handle if (fluxVarsCache.usesSecondaryIv()) - { - const auto& tij = fluxVarsCache.advectionTijSecondaryIv(); - const auto& pj = fluxVarsCache.pressuresSecondaryIv(phaseIdx); - scvfFlux = tij*pj; - } + return flux_(problem, fluxVarsCache, fluxVarsCache.advectionSecondaryDataHandle(), phaseIdx); else - { - const auto& tij = fluxVarsCache.advectionTijPrimaryIv(); - const auto& pj = fluxVarsCache.pressuresPrimaryIv(phaseIdx); - scvfFlux = tij*pj; - } + return flux_(problem, fluxVarsCache, fluxVarsCache.advectionPrimaryDataHandle(), phaseIdx); + } + +private: + template< class Problem, class FluxVarsCache, class DataHandle > + static Scalar flux_(const Problem& problem, + const FluxVarsCache& cache, + const DataHandle& dataHandle, + int phaseIdx) + { + dataHandle.setPhaseIndex(phaseIdx); + + const bool switchSign = cache.advectionSwitchFluxSign(); + + const auto localFaceIdx = cache.ivLocalFaceIndex(); + const auto idxInOutside = cache.indexInOutsideFaces(); + const auto& pj = dataHandle.uj(); + const auto& tij = dim == dimWorld ? dataHandle.T()[localFaceIdx] + : (!switchSign ? dataHandle.T()[localFaceIdx] + : dataHandle.tijOutside()[localFaceIdx][idxInOutside]); + Scalar scvfFlux = tij*pj; // maybe add gravitational acceleration static const bool enableGravity = getParamFromGroup(problem.paramGroup(), "Problem.EnableGravity"); if (enableGravity) - scvfFlux += fluxVarsCache.gravity(phaseIdx); + scvfFlux += dim == dimWorld ? dataHandle.g()[localFaceIdx] + : (!switchSign ? dataHandle.g()[localFaceIdx] + : dataHandle.gOutside()[localFaceIdx][idxInOutside]); // switch the sign if necessary - if (fluxVarsCache.advectionSwitchFluxSign()) + if (cache.advectionSwitchFluxSign()) scvfFlux *= -1.0; return scvfFlux; diff --git a/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh b/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh index 82fceb984e..8ec7bfc63e 100644 --- a/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh +++ b/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh @@ -231,6 +231,9 @@ private: ivFluxVarCaches[i]->setIvIndexInContainer(ivIndexInContainer); ivFluxVarCaches[i]->setUpdateStatus(true); ivFluxVarCaches[i]->setSecondaryIvUsage(isSecondary); + ivFluxVarCaches[i]->setIvLocalFaceIndex(d.ivLocalScvfIndex()); + if (dim < dimWorld) + ivFluxVarCaches[i]->setIndexInOutsideFaces(d.scvfLocalOutsideScvfIndex()); i++; } diff --git a/dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh b/dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh index 30bb4088f7..baee94234a 100644 --- a/dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh +++ b/dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh @@ -220,10 +220,12 @@ class HeatConductionDataHandle : public Empt template class InteractionVolumeDataHandle { + +public: + //! export the underlying process-specific handle types using AdvectionHandle = AdvectionDataHandle; using DiffusionHandle = DiffusionDataHandle; using HeatConductionHandle = HeatConductionDataHandle; -public: //! return references to the handle containing data related to advection const AdvectionHandle& advectionHandle() const { return advectionHandle_; } diff --git a/dumux/porousmediumflow/1p/incompressiblelocalresidual.hh b/dumux/porousmediumflow/1p/incompressiblelocalresidual.hh index 219394d476..8089363462 100644 --- a/dumux/porousmediumflow/1p/incompressiblelocalresidual.hh +++ b/dumux/porousmediumflow/1p/incompressiblelocalresidual.hh @@ -126,41 +126,20 @@ public: / curElemVolVars[scvf.insideScvIdx()].viscosity(); const auto& fluxVarsCache = elemFluxVarsCache[scvf]; - const auto& stencil = fluxVarsCache.advectionStencil(); - if (fluxVarsCache.usesSecondaryIv()) - { - const auto& tij = fluxVarsCache.advectionTijSecondaryIv(); - - // We assume same the tij are order as the stencil up to stencil.size() - // any contribution of Dirichlet BCs is assumed to be placed afterwards - assert(stencil.size() <= tij.size()); + const auto localFaceIdx = fluxVarsCache.ivLocalFaceIndex(); + const auto usesSecondary = fluxVarsCache.usesSecondaryIv(); + const auto switchSign = fluxVarsCache.advectionSwitchFluxSign(); - // add partial derivatives to the respective given matrices - for (unsigned int i = 0; i < stencil.size();++i) - { - if (fluxVarsCache.advectionSwitchFluxSign()) - derivativeMatrices[stencil[i]][conti0EqIdx][pressureIdx] -= tij[i]*up; - else - derivativeMatrices[stencil[i]][conti0EqIdx][pressureIdx] += tij[i]*up; - } - } - else - { - const auto& tij = fluxVarsCache.advectionTijPrimaryIv(); - - // We assume same the tij are order as the stencil up to stencil.size() - // any contribution of Dirichlet BCs is assumed to be placed afterwards - assert(stencil.size() <= tij.size()); - - // add partial derivatives to the respective given matrices - for (unsigned int i = 0; i < stencil.size();++i) - { - if (fluxVarsCache.advectionSwitchFluxSign()) - derivativeMatrices[stencil[i]][conti0EqIdx][pressureIdx] -= tij[i]*up; - else - derivativeMatrices[stencil[i]][conti0EqIdx][pressureIdx] += tij[i]*up; - } - } + const auto& stencil = fluxVarsCache.advectionStencil(); + const auto& tij = usesSecondary ? fluxVarsCache.advectionSecondaryDataHandle().T()[localFaceIdx] + : fluxVarsCache.advectionPrimaryDataHandle().T()[localFaceIdx]; + + // We assume same the tij are order as the stencil up to stencil.size() + // any contribution of Dirichlet BCs is assumed to be placed afterwards + assert(stencil.size() <= tij.size()); + for (unsigned int i = 0; i < stencil.size();++i) + derivativeMatrices[stencil[i]][conti0EqIdx][pressureIdx] += switchSign ? -tij[i]*up + : tij[i]*up; } //! flux derivatives for the box scheme diff --git a/dumux/porousmediumflow/fluxvariablescache.hh b/dumux/porousmediumflow/fluxvariablescache.hh index f35e0e691c..82170bc148 100644 --- a/dumux/porousmediumflow/fluxvariablescache.hh +++ b/dumux/porousmediumflow/fluxvariablescache.hh @@ -103,27 +103,32 @@ public: template< bool doSecondary = considerSecondary, std::enable_if_t = 0> bool usesSecondaryIv() const { return usesSecondaryIv_; } + //! Returns the index of the iv (this scvf is embedded in) in its container + GridIndexType ivIndexInContainer() const { return ivIndexInContainer_; } + //! Returns interaction volume-local face index + unsigned int ivLocalFaceIndex() const { return ivLocalFaceIdx_; } + //! Returns index of the face among "outside" faces of iv-local "positive" face + unsigned int indexInOutsideFaces() const { return idxInOutsideFaces_; } + //! Sets the update status. When set to true, consecutive updates will be skipped void setUpdateStatus(bool status) { isUpdated_ = status; } - - //! Sets if this cache is associated witha secondary iv + //! Sets if this cache is associated with a secondary iv void setSecondaryIvUsage(bool status) { usesSecondaryIv_ = status; } - //! Sets the index of the iv (this scvf is embedded in) in its container void setIvIndexInContainer(GridIndexType ivIndex) { ivIndexInContainer_ = ivIndex; } - - //! Returns the index of the iv (this scvf is embedded in) in its container - GridIndexType ivIndexInContainer() const { return ivIndexInContainer_; } + //! Sets the iv-local face index + void setIvLocalFaceIndex(unsigned int idx) { ivLocalFaceIdx_ = idx; } + //! Sets the index of the face among the "positive" face's outside scvfs + void setIndexInOutsideFaces(unsigned int idx) { idxInOutsideFaces_ = idx; } private: - //! indicates if cache has been fully updated - bool isUpdated_ = false; - //! indicates if cache is associated with secondary interaction volume - bool usesSecondaryIv_ = false; + bool isUpdated_ = false; //!< returns true if cache has been fully updated + bool usesSecondaryIv_ = false; //!< returns true if scvf is embedded in secondary interaction volume - //! the index of the iv (this scvf is embedded in) in its container - GridIndexType ivIndexInContainer_; + GridIndexType ivIndexInContainer_; //!< index of the iv (this scvf is embedded in) in its container + unsigned int ivLocalFaceIdx_; //!< the interaction volume-local face index of this scvf + unsigned int idxInOutsideFaces_; //!< index of scvf among outside scvfs of iv-local "positive" face (only surface grids) }; } // end namespace Dumux -- GitLab From d921fcb7ec8c89a16fdb274557f57e3884c255ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Gl=C3=A4ser?= Date: Tue, 20 Nov 2018 12:53:19 +0100 Subject: [PATCH 25/35] [mpfa][fickslaw] store pointer to handle instead of storing pointers to the transmissibilities and pressures etc, we now only store a pointer to the data handle and reconstruct the fluxes in the FicksLaw implementation. This dramatically reduces the number of lines needed for the cache implementation. --- .../cellcentered/mpfa/fickslaw.hh | 183 +++++++----------- 1 file changed, 67 insertions(+), 116 deletions(-) diff --git a/dumux/discretization/cellcentered/mpfa/fickslaw.hh b/dumux/discretization/cellcentered/mpfa/fickslaw.hh index 7d13e5c514..3d5e759d4d 100644 --- a/dumux/discretization/cellcentered/mpfa/fickslaw.hh +++ b/dumux/discretization/cellcentered/mpfa/fickslaw.hh @@ -46,6 +46,9 @@ class FicksLawImplementation using GridView = GetPropType; using Element = typename GridView::template Codim<0>::Entity; + static constexpr int dim = GridView::dimension; + static constexpr int dimWorld = GridView::dimensionworld; + using FVGridGeometry = GetPropType; using FVElementGeometry = typename FVGridGeometry::LocalView; using FluidSystem = GetPropType; @@ -79,12 +82,12 @@ class FicksLawImplementation scvfFluxVarsCache.updateDiffusion(fluxVarsCacheFiller.secondaryInteractionVolume(), fluxVarsCacheFiller.secondaryIvLocalFaceData(), fluxVarsCacheFiller.secondaryIvDataHandle(), - scvf, phaseIdx, compIdx); + phaseIdx, compIdx); else scvfFluxVarsCache.updateDiffusion(fluxVarsCacheFiller.primaryInteractionVolume(), fluxVarsCacheFiller.primaryIvLocalFaceData(), fluxVarsCacheFiller.primaryIvDataHandle(), - scvf, phaseIdx, compIdx); + phaseIdx, compIdx); } }; @@ -94,24 +97,19 @@ class FicksLawImplementation using DualGridNodalIndexSet = GetPropType; using Stencil = typename DualGridNodalIndexSet::NodalGridStencilType; - using MpfaHelper = typename FVGridGeometry::MpfaHelper; - static constexpr bool considerSecondaryIVs = MpfaHelper::considerSecondaryIVs(); - - using PrimaryInteractionVolume = GetPropType; - using PrimaryIvLocalFaceData = typename PrimaryInteractionVolume::Traits::LocalFaceData; - using PrimaryIvDataHandle = typename ElementFluxVariablesCache::PrimaryIvDataHandle; - using PrimaryIvCellVector = typename PrimaryInteractionVolume::Traits::MatVecTraits::CellVector; - using PrimaryIvTij = typename PrimaryInteractionVolume::Traits::MatVecTraits::TMatrix::row_type; + static constexpr int numPhases = GetPropType::numPhases(); + static constexpr bool considerSecondaryIVs = FVGridGeometry::MpfaHelper::considerSecondaryIVs(); + using PrimaryDataHandle = typename ElementFluxVariablesCache::PrimaryIvDataHandle::DiffusionHandle; + using SecondaryDataHandle = typename ElementFluxVariablesCache::SecondaryIvDataHandle::DiffusionHandle; - using SecondaryInteractionVolume = GetPropType; - using SecondaryIvLocalFaceData = typename SecondaryInteractionVolume::Traits::LocalFaceData; - using SecondaryIvDataHandle = typename ElementFluxVariablesCache::SecondaryIvDataHandle; - using SecondaryIvCellVector = typename SecondaryInteractionVolume::Traits::MatVecTraits::CellVector; - using SecondaryIvTij = typename SecondaryInteractionVolume::Traits::MatVecTraits::TMatrix::row_type; + //! sets the pointer to the data handle (overload for secondary data handles) + template< bool doSecondary = considerSecondaryIVs, std::enable_if_t = 0 > + void setHandlePointer_(const SecondaryDataHandle& dataHandle) + { secondaryHandlePtr_ = &dataHandle; } - static constexpr int dim = GridView::dimension; - static constexpr int dimWorld = GridView::dimensionworld; - static constexpr int numPhases = GetPropType::numPhases(); + //! sets the pointer to the data handle (overload for primary data handles) + void setHandlePointer_(const PrimaryDataHandle& dataHandle) + { primaryHandlePtr_ = &dataHandle; } public: // export filler type @@ -124,104 +122,39 @@ class FicksLawImplementation * \param iv The interaction volume this scvf is embedded in * \param localFaceData iv-local info on this scvf * \param dataHandle Transmissibility matrix & gravity data of this iv - * \param scvf The sub-control volume face */ - void updateDiffusion(const PrimaryInteractionVolume& iv, - const PrimaryIvLocalFaceData& localFaceData, - const PrimaryIvDataHandle& dataHandle, - const SubControlVolumeFace &scvf, + template + void updateDiffusion(const IV& iv, + const LocalFaceData& localFaceData, + const DataHandle& dataHandle, unsigned int phaseIdx, unsigned int compIdx) { - const auto& handle = dataHandle.diffusionHandle(); - stencil_[phaseIdx][compIdx] = &iv.stencil(); switchFluxSign_[phaseIdx][compIdx] = localFaceData.isOutsideFace(); - - // store pointer to the mole fraction vector of this iv - primaryXj_[phaseIdx][compIdx] = &handle.uj(); - - const auto ivLocalIdx = localFaceData.ivLocalScvfIndex(); - if (dim == dimWorld) - primaryTij_[phaseIdx][compIdx] = &handle.T()[ivLocalIdx]; - else - primaryTij_[phaseIdx][compIdx] = localFaceData.isOutsideFace() - ? &handle.tijOutside()[ivLocalIdx][localFaceData.scvfLocalOutsideScvfIndex()] - : &handle.T()[ivLocalIdx]; + setHandlePointer_(dataHandle.diffusionHandle()); } - /*! - * \brief Update cached objects (transmissibilities). - * This is used for updates with secondary interaction volumes. - * - * \param iv The interaction volume this scvf is embedded in - * \param localFaceData iv-local info on this scvf - * \param dataHandle Transmissibility matrix & gravity data of this iv - * \param scvf The sub-control volume face - */ - template< bool doSecondary = considerSecondaryIVs, std::enable_if_t = 0 > - void updateDiffusion(const SecondaryInteractionVolume& iv, - const SecondaryIvLocalFaceData& localFaceData, - const SecondaryIvDataHandle& dataHandle, - const SubControlVolumeFace &scvf, - unsigned int phaseIdx, unsigned int compIdx) - { - const auto& handle = dataHandle.diffusionHandle(); - - stencil_[phaseIdx][compIdx] = &iv.stencil(); - switchFluxSign_[phaseIdx][compIdx] = localFaceData.isOutsideFace(); - - // store pointer to the mole fraction vector of this iv - secondaryXj_[phaseIdx][compIdx] = &handle.uj(); + //! The stencils corresponding to the transmissibilities + const Stencil& diffusionStencil(unsigned int phaseIdx, unsigned int compIdx) const + { return *stencil_[phaseIdx][compIdx]; } - const auto ivLocalIdx = localFaceData.ivLocalScvfIndex(); - if (dim == dimWorld) - secondaryTij_[phaseIdx][compIdx] = &handle.T()[ivLocalIdx]; - else - secondaryTij_[phaseIdx][compIdx] = localFaceData.isOutsideFace() - ? &handle.tijOutside()[ivLocalIdx][localFaceData.scvfLocalOutsideScvfIndex()] - : &handle.T()[ivLocalIdx]; - } + //! The corresponding data handles + const PrimaryDataHandle& diffusionPrimaryDataHandle() const { return *primaryHandlePtr_; } + const SecondaryDataHandle& diffusionSecondaryDataHandle() const { return *secondaryHandlePtr_; } - //! In the interaction volume-local system of eq we have one unknown per face. - //! On scvfs on this face, but in "outside" (neighbor) elements of it, we have - //! to take the negative value of the fluxes due to the flipped normal vector. - //! This function returns whether or not this scvf is an "outside" face in the iv. + //! Returns whether or not this scvf is an "outside" face in the scope of the iv. bool diffusionSwitchFluxSign(unsigned int phaseIdx, unsigned int compIdx) const { return switchFluxSign_[phaseIdx][compIdx]; } - //! Coefficients for the cell (& Dirichlet) unknowns in flux expressions (primary type) - const PrimaryIvTij& diffusionTijPrimaryIv(unsigned int phaseIdx, unsigned int compIdx) const - { return *primaryTij_[phaseIdx][compIdx]; } - - //! Coefficients for the cell (& Dirichlet) unknowns in flux expressions (secondary type) - const SecondaryIvTij& diffusionTijSecondaryIv(unsigned int phaseIdx, unsigned int compIdx) const - { return *secondaryTij_[phaseIdx][compIdx]; } - - //! The cell (& maybe Dirichlet) mole fractions within this interaction volume (primary type) - const PrimaryIvCellVector& moleFractionsPrimaryIv(unsigned int phaseIdx, unsigned int compIdx) const - { return *primaryXj_[phaseIdx][compIdx]; } - - //! The cell (& maybe Dirichlet) mole fractions within this interaction volume (secondary type) - const SecondaryIvCellVector& moleFractionsSecondaryIv(unsigned int phaseIdx, unsigned int compIdx) const - { return *secondaryXj_[phaseIdx][compIdx]; } - - //! The stencils corresponding to the transmissibilities - const Stencil& diffusionStencil(unsigned int phaseIdx, unsigned int compIdx) const - { return *stencil_[phaseIdx][compIdx]; } private: + //! phase-/component- specific data std::array< std::array, numPhases > switchFluxSign_; - - //! The stencils, i.e. the grid indices j std::array< std::array, numPhases > stencil_; - //! The transmissibilities such that f = Tij*xj - std::array< std::array, numPhases > primaryTij_; - std::array< std::array, numPhases > secondaryTij_; - - //! The interaction-volume wide mole fractions xj - std::array< std::array, numPhases > primaryXj_; - std::array< std::array, numPhases > secondaryXj_; + //! pointers to the corresponding iv-data handles + const PrimaryDataHandle* primaryHandlePtr_; + const SecondaryDataHandle* secondaryHandlePtr_; }; public: @@ -259,25 +192,17 @@ public: // calculate the density at the interface const auto rho = interpolateDensity(elemVolVars, scvf, phaseIdx); - // calculate Tij*xj - Scalar flux; + // compute the flux if (fluxVarsCache.usesSecondaryIv()) - { - const auto& tij = fluxVarsCache.diffusionTijSecondaryIv(phaseIdx, compIdx); - const auto& xj = fluxVarsCache.moleFractionsSecondaryIv(phaseIdx, compIdx); - flux = tij*xj; - } + componentFlux[compIdx] = rho*effFactor*computeVolumeFlux(problem, + fluxVarsCache, + fluxVarsCache.diffusionSecondaryDataHandle(), + phaseIdx, compIdx); else - { - const auto& tij = fluxVarsCache.diffusionTijPrimaryIv(phaseIdx, compIdx); - const auto& xj = fluxVarsCache.moleFractionsPrimaryIv(phaseIdx, compIdx); - flux = tij*xj; - } - - if (fluxVarsCache.diffusionSwitchFluxSign(phaseIdx, compIdx)) - flux *= -1.0; - - componentFlux[compIdx] = flux*rho*effFactor; + componentFlux[compIdx] = rho*effFactor*computeVolumeFlux(problem, + fluxVarsCache, + fluxVarsCache.diffusionPrimaryDataHandle(), + phaseIdx, compIdx); } // accumulate the phase component flux @@ -289,6 +214,32 @@ public: } private: + template< class Problem, class FluxVarsCache, class DataHandle > + static Scalar computeVolumeFlux(const Problem& problem, + const FluxVarsCache& cache, + const DataHandle& dataHandle, + int phaseIdx, int compIdx) + { + dataHandle.setPhaseIndex(phaseIdx); + dataHandle.setComponentIndex(compIdx); + + const bool switchSign = cache.diffusionSwitchFluxSign(phaseIdx, compIdx); + + const auto localFaceIdx = cache.ivLocalFaceIndex(); + const auto idxInOutside = cache.indexInOutsideFaces(); + const auto& xj = dataHandle.uj(); + const auto& tij = dim == dimWorld ? dataHandle.T()[localFaceIdx] + : (!switchSign ? dataHandle.T()[localFaceIdx] + : dataHandle.tijOutside()[localFaceIdx][idxInOutside]); + Scalar scvfFlux = tij*xj; + + // switch the sign if necessary + if (cache.advectionSwitchFluxSign()) + scvfFlux *= -1.0; + + return scvfFlux; + } + //! compute the density at branching facets for network grids as arithmetic mean static Scalar interpolateDensity(const ElementVolumeVariables& elemVolVars, const SubControlVolumeFace& scvf, -- GitLab From e5afd009cea3818a14e466a5839dd87a4159152a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Gl=C3=A4ser?= Date: Tue, 20 Nov 2018 13:02:29 +0100 Subject: [PATCH 26/35] [mpfa][fourierslaw] store pointer to handle instead of storing pointers to the transmissibilities and temperatures etc, we now only store a pointer to the data handle and reconstruct the fluxes in the FouriersLaw implementation. This dramatically reduces the number of lines needed for the cache implementation. --- .../cellcentered/mpfa/fourierslaw.hh | 155 ++++++------------ 1 file changed, 52 insertions(+), 103 deletions(-) diff --git a/dumux/discretization/cellcentered/mpfa/fourierslaw.hh b/dumux/discretization/cellcentered/mpfa/fourierslaw.hh index b48a2fec18..7b56dfb9e5 100644 --- a/dumux/discretization/cellcentered/mpfa/fourierslaw.hh +++ b/dumux/discretization/cellcentered/mpfa/fourierslaw.hh @@ -48,6 +48,9 @@ class FouriersLawImplementation using GridView = GetPropType; using Element = typename GridView::template Codim<0>::Entity; + static constexpr int dim = GridView::dimension; + static constexpr int dimWorld = GridView::dimensionworld; + using FVGridGeometry = GetPropType; using FVElementGeometry = typename FVGridGeometry::LocalView; using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace; @@ -75,13 +78,11 @@ class FouriersLawImplementation if (fvGeometry.fvGridGeometry().vertexUsesSecondaryInteractionVolume(scvf.vertexIndex())) scvfFluxVarsCache.updateHeatConduction(fluxVarsCacheFiller.secondaryInteractionVolume(), fluxVarsCacheFiller.secondaryIvLocalFaceData(), - fluxVarsCacheFiller.secondaryIvDataHandle(), - scvf); + fluxVarsCacheFiller.secondaryIvDataHandle()); else scvfFluxVarsCache.updateHeatConduction(fluxVarsCacheFiller.primaryInteractionVolume(), fluxVarsCacheFiller.primaryIvLocalFaceData(), - fluxVarsCacheFiller.primaryIvDataHandle(), - scvf); + fluxVarsCacheFiller.primaryIvDataHandle()); } }; @@ -91,23 +92,18 @@ class FouriersLawImplementation using DualGridNodalIndexSet = GetPropType; using Stencil = typename DualGridNodalIndexSet::NodalGridStencilType; - using MpfaHelper = typename FVGridGeometry::MpfaHelper; - static constexpr bool considerSecondaryIVs = MpfaHelper::considerSecondaryIVs(); - - using PrimaryInteractionVolume = GetPropType; - using PrimaryIvLocalFaceData = typename PrimaryInteractionVolume::Traits::LocalFaceData; - using PrimaryIvDataHandle = typename ElementFluxVarsCache::PrimaryIvDataHandle; - using PrimaryIvCellVector = typename PrimaryInteractionVolume::Traits::MatVecTraits::CellVector; - using PrimaryIvTij = typename PrimaryInteractionVolume::Traits::MatVecTraits::TMatrix::row_type; + static constexpr bool considerSecondaryIVs = FVGridGeometry::MpfaHelper::considerSecondaryIVs(); + using PrimaryDataHandle = typename ElementFluxVarsCache::PrimaryIvDataHandle::HeatConductionHandle; + using SecondaryDataHandle = typename ElementFluxVarsCache::SecondaryIvDataHandle::HeatConductionHandle; - using SecondaryInteractionVolume = GetPropType; - using SecondaryIvLocalFaceData = typename SecondaryInteractionVolume::Traits::LocalFaceData; - using SecondaryIvDataHandle = typename ElementFluxVarsCache::SecondaryIvDataHandle; - using SecondaryIvCellVector = typename SecondaryInteractionVolume::Traits::MatVecTraits::CellVector; - using SecondaryIvTij = typename SecondaryInteractionVolume::Traits::MatVecTraits::TMatrix::row_type; + //! sets the pointer to the data handle (overload for secondary data handles) + template< bool doSecondary = considerSecondaryIVs, std::enable_if_t = 0 > + void setHandlePointer_(const SecondaryDataHandle& dataHandle) + { secondaryHandlePtr_ = &dataHandle; } - static constexpr int dim = GridView::dimension; - static constexpr int dimWorld = GridView::dimensionworld; + //! sets the pointer to the data handle (overload for primary data handles) + void setHandlePointer_(const PrimaryDataHandle& dataHandle) + { primaryHandlePtr_ = &dataHandle; } public: // export filler type @@ -120,92 +116,36 @@ class FouriersLawImplementation * \param iv The interaction volume this scvf is embedded in * \param localFaceData iv-local info on this scvf * \param dataHandle Transmissibility matrix & gravity data of this iv - * \param scvf The sub-control volume face */ - void updateHeatConduction(const PrimaryInteractionVolume& iv, - const PrimaryIvLocalFaceData& localFaceData, - const PrimaryIvDataHandle& dataHandle, - const SubControlVolumeFace &scvf) + template + void updateHeatConduction(const IV& iv, + const LocalFaceData& localFaceData, + const DataHandle& dataHandle) { - stencil_ = &iv.stencil(); switchFluxSign_ = localFaceData.isOutsideFace(); - - // store pointer to the temperature vector of this iv - primaryTj_ = &dataHandle.heatConductionHandle().uj(); - - const auto ivLocalIdx = localFaceData.ivLocalScvfIndex(); - if (dim == dimWorld) - primaryTij_ = &dataHandle.heatConductionHandle().T()[ivLocalIdx]; - else - primaryTij_ = localFaceData.isOutsideFace() - ? &dataHandle.heatConductionHandle().tijOutside()[ivLocalIdx][localFaceData.scvfLocalOutsideScvfIndex()] - : &dataHandle.heatConductionHandle().T()[ivLocalIdx]; - } - - /*! - * \brief Update cached objects (transmissibilities). - * This is used for updates with secondary interaction volumes. - * - * \param iv The interaction volume this scvf is embedded in - * \param localFaceData iv-local info on this scvf - * \param dataHandle Transmissibility matrix & gravity data of this iv - * \param scvf The sub-control volume face - */ - template< bool doSecondary = considerSecondaryIVs, std::enable_if_t = 0 > - void updateHeatConduction(const SecondaryInteractionVolume& iv, - const SecondaryIvLocalFaceData& localFaceData, - const SecondaryIvDataHandle& dataHandle, - const SubControlVolumeFace &scvf) - { stencil_ = &iv.stencil(); - switchFluxSign_ = localFaceData.isOutsideFace(); - - // store pointer to the temperature vector of this iv - secondaryTj_ = &dataHandle.heatConductionHandle().uj(); - - const auto ivLocalIdx = localFaceData.ivLocalScvfIndex(); - if (dim == dimWorld) - secondaryTij_ = &dataHandle.T()[ivLocalIdx]; - else - secondaryTij_ = localFaceData.isOutsideFace() - ? &dataHandle.heatConductionHandle().tijOutside()[ivLocalIdx][localFaceData.scvfLocalOutsideScvfIndex()] - : &dataHandle.heatConductionHandle().T()[ivLocalIdx]; + setHandlePointer_(dataHandle.heatConductionHandle()); } - //! Coefficients for the cell (& Dirichlet) unknowns in flux expressions (primary type) - const PrimaryIvTij& heatConductionTijPrimaryIv() const { return *primaryTij_; } - - //! Coefficients for the cell (& Dirichlet) unknowns in flux expressions (secondary type) - const SecondaryIvTij& heatConductionTijSecondaryIv() const { return *secondaryTij_; } - //! The stencil corresponding to the transmissibilities (primary type) const Stencil& heatConductionStencil() const { return *stencil_; } - //! The cell (& Dirichlet) temperatures within this interaction volume (primary type) - const PrimaryIvCellVector& temperaturesPrimaryIv() const { return *primaryTj_; } + //! The corresponding data handles + const PrimaryDataHandle& heatConductionPrimaryDataHandle() const { return *primaryHandlePtr_; } + const SecondaryDataHandle& heatConductionSecondaryDataHandle() const { return *secondaryHandlePtr_; } - //! The cell (& Dirichlet) temperatures within this interaction volume (secondary type) - const SecondaryIvCellVector& temperaturesSecondaryIv() const { return *secondaryTj_; } - - //! In the interaction volume-local system of eq we have one unknown per face. - //! On scvfs on this face, but in "outside" (neighbor) elements of it, we have - //! to take the negative value of the fluxes due to the flipped normal vector. - //! This function returns whether or not this scvf is an "outside" face in the iv. + //! Returns whether or not this scvf is an "outside" face in the scope of the iv. bool heatConductionSwitchFluxSign() const { return switchFluxSign_; } private: bool switchFluxSign_; + //! pointers to the corresponding iv-data handles + const PrimaryDataHandle* primaryHandlePtr_; + const SecondaryDataHandle* secondaryHandlePtr_; + //! The stencil, i.e. the grid indices j const Stencil* stencil_; - - //! The transmissibilities such that f = Tij*Tj - const PrimaryIvTij* primaryTij_; - const SecondaryIvTij* secondaryTij_; - - //! The interaction-volume wide temperature Tj - const PrimaryIvCellVector* primaryTj_; - const SecondaryIvCellVector* secondaryTj_; }; public: @@ -225,25 +165,34 @@ public: { const auto& fluxVarsCache = elemFluxVarsCache[scvf]; - // compute Tij*tj - Scalar flux; + // forward to the private function taking the iv data handle if (fluxVarsCache.usesSecondaryIv()) - { - const auto& tij = fluxVarsCache.heatConductionTijSecondaryIv(); - const auto& Tj = fluxVarsCache.temperaturesSecondaryIv(); - flux = tij*Tj; - } + return flux_(problem, fluxVarsCache, fluxVarsCache.heatConductionSecondaryDataHandle()); else - { - const auto& tij = fluxVarsCache.heatConductionTijPrimaryIv(); - const auto& Tj = fluxVarsCache.temperaturesPrimaryIv(); - flux = tij*Tj; - } + return flux_(problem, fluxVarsCache, fluxVarsCache.heatConductionPrimaryDataHandle()); + } + +private: + template< class Problem, class FluxVarsCache, class DataHandle > + static Scalar flux_(const Problem& problem, + const FluxVarsCache& cache, + const DataHandle& dataHandle) + { + const bool switchSign = cache.advectionSwitchFluxSign(); + + const auto localFaceIdx = cache.ivLocalFaceIndex(); + const auto idxInOutside = cache.indexInOutsideFaces(); + const auto& Tj = dataHandle.uj(); + const auto& tij = dim == dimWorld ? dataHandle.T()[localFaceIdx] + : (!switchSign ? dataHandle.T()[localFaceIdx] + : dataHandle.tijOutside()[localFaceIdx][idxInOutside]); + Scalar scvfFlux = tij*Tj; - if (fluxVarsCache.heatConductionSwitchFluxSign()) - flux *= -1.0; + // switch the sign if necessary + if (cache.advectionSwitchFluxSign()) + scvfFlux *= -1.0; - return flux; + return scvfFlux; } }; -- GitLab From e9e124538c3409502d31d70bdff7b927e515776a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Gl=C3=A4ser?= Date: Tue, 20 Nov 2018 14:03:11 +0100 Subject: [PATCH 27/35] [mpfa] export local assembler type in iv traits That makes it possible to overload the local assembler class while reusing an interaction volume. --- .../cellcentered/mpfa/CMakeLists.txt | 2 +- .../mpfa/fluxvariablescachefiller.hh | 13 ++++++------- .../cellcentered/mpfa/interactionvolumebase.hh | 2 ++ ...{localassembler.hh => localassemblerbase.hh} | 17 +++-------------- .../mpfa/omethod/interactionvolume.hh | 5 +++++ .../cellcentered/mpfa/omethod/localassembler.hh | 4 ++-- .../mpfa/omethod/staticinteractionvolume.hh | 5 +++++ 7 files changed, 24 insertions(+), 24 deletions(-) rename dumux/discretization/cellcentered/mpfa/{localassembler.hh => localassemblerbase.hh} (95%) diff --git a/dumux/discretization/cellcentered/mpfa/CMakeLists.txt b/dumux/discretization/cellcentered/mpfa/CMakeLists.txt index d1940659e2..51527f79f9 100644 --- a/dumux/discretization/cellcentered/mpfa/CMakeLists.txt +++ b/dumux/discretization/cellcentered/mpfa/CMakeLists.txt @@ -19,7 +19,7 @@ gridvolumevariables.hh helper.hh interactionvolumebase.hh interactionvolumedatahandle.hh -localassembler.hh +localassemblerbase.hh localfacedata.hh methods.hh properties.hh diff --git a/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh b/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh index 8ec7bfc63e..a95a31c84f 100644 --- a/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh +++ b/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh @@ -29,7 +29,6 @@ #include #include -#include namespace Dumux { @@ -437,8 +436,8 @@ private: using LambdaFactory = TensorLambdaFactory; // get instance of the interaction volume-local assembler - static constexpr MpfaMethods M = InteractionVolume::MpfaMethod; - using IvLocalAssembler = InteractionVolumeAssembler< Problem, FVElementGeometry, ElementVolumeVariables, M >; + using Traits = typename InteractionVolume::Traits; + using IvLocalAssembler = typename Traits::template LocalAssembler; IvLocalAssembler localAssembler(problem(), fvGeometry(), elemVolVars()); // Assemble T only if permeability is sol-dependent or if update is forced @@ -476,8 +475,8 @@ private: using LambdaFactory = TensorLambdaFactory; // get instance of the interaction volume-local assembler - static constexpr MpfaMethods M = InteractionVolume::MpfaMethod; - using IvLocalAssembler = InteractionVolumeAssembler< Problem, FVElementGeometry, ElementVolumeVariables, M >; + using Traits = typename InteractionVolume::Traits; + using IvLocalAssembler = typename Traits::template LocalAssembler; IvLocalAssembler localAssembler(problem(), fvGeometry(), elemVolVars()); // maybe (re-)assemble matrices @@ -502,8 +501,8 @@ private: using ThermCondModel = GetPropType; // get instance of the interaction volume-local assembler - static constexpr MpfaMethods M = InteractionVolume::MpfaMethod; - using IvLocalAssembler = InteractionVolumeAssembler< Problem, FVElementGeometry, ElementVolumeVariables, M >; + using Traits = typename InteractionVolume::Traits; + using IvLocalAssembler = typename Traits::template LocalAssembler; IvLocalAssembler localAssembler(problem(), fvGeometry(), elemVolVars()); // maybe (re-)assemble matrices (TODO: USE CORRECT SOLDEPENDENT FLAG!) diff --git a/dumux/discretization/cellcentered/mpfa/interactionvolumebase.hh b/dumux/discretization/cellcentered/mpfa/interactionvolumebase.hh index 423c0381ed..dbaf61141d 100644 --- a/dumux/discretization/cellcentered/mpfa/interactionvolumebase.hh +++ b/dumux/discretization/cellcentered/mpfa/interactionvolumebase.hh @@ -51,6 +51,8 @@ namespace Dumux * using LocalFaceData = ...; * //! export the matrix/vector type traits to be used by the iv * using MatVecTraits = ...; + * //! export the type used for the assembly of the iv's local eq system + * using LocalAssembler = ...; * \endcode */ diff --git a/dumux/discretization/cellcentered/mpfa/localassembler.hh b/dumux/discretization/cellcentered/mpfa/localassemblerbase.hh similarity index 95% rename from dumux/discretization/cellcentered/mpfa/localassembler.hh rename to dumux/discretization/cellcentered/mpfa/localassemblerbase.hh index 40948a54a3..20cbb2a1cc 100644 --- a/dumux/discretization/cellcentered/mpfa/localassembler.hh +++ b/dumux/discretization/cellcentered/mpfa/localassemblerbase.hh @@ -21,25 +21,17 @@ * \ingroup CCMpfaDiscretization * \brief Defines the general interface of classes used for the assembly * of the local systems of equations involved in the transmissibility - * computaion in mpfa schemes. + * computation in mpfa schemes. */ -#ifndef DUMUX_DISCRETIZATION_CC_MPFA_LOCAL_ASSEMBLER_HH -#define DUMUX_DISCRETIZATION_CC_MPFA_LOCAL_ASSEMBLER_HH +#ifndef DUMUX_DISCRETIZATION_CC_MPFA_LOCAL_ASSEMBLER_BASE_HH +#define DUMUX_DISCRETIZATION_CC_MPFA_LOCAL_ASSEMBLER_BASE_HH #include #include -#include namespace Dumux { -//! Forward declaration of the implementation -template< class P, class EG, class EV, MpfaMethods M > class InteractionVolumeAssemblerImpl; - -//! Alias to select the right implementation. -template< class P, class EG, class EV, MpfaMethods M > -using InteractionVolumeAssembler = InteractionVolumeAssemblerImpl< P, EG, EV, M >; - /*! * \ingroup CCMpfaDiscretization * \brief Defines the general interface of the local assembler @@ -330,7 +322,4 @@ private: } // end namespace Dumux -//! include all specializations for different mpfa schemes -#include - #endif diff --git a/dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh b/dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh index ab52179d16..cf45a0ca5b 100644 --- a/dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh +++ b/dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh @@ -38,6 +38,7 @@ #include #include +#include "localassembler.hh" #include "localsubcontrolentities.hh" #include "interactionvolumeindexset.hh" @@ -91,6 +92,10 @@ public: using LocalFaceData = InteractionVolumeLocalFaceData; //! export the matrix/vector traits to be used by the iv using MatVecTraits = MVTraits; + + //! the type of assembler used for the o-method's iv-local eq systems + template + using LocalAssembler = MpfaOInteractionVolumeAssembler; }; /*! diff --git a/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh b/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh index 4828fc0cff..dafa103d8c 100644 --- a/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh +++ b/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh @@ -29,7 +29,7 @@ #include #include -#include +#include #include namespace Dumux @@ -45,7 +45,7 @@ namespace Dumux * \tparam EV The element volume variables type */ template< class P, class EG, class EV > -class InteractionVolumeAssemblerImpl< P, EG, EV, MpfaMethods::oMethod > +class MpfaOInteractionVolumeAssembler : public InteractionVolumeAssemblerBase< P, EG, EV > { using ParentType = InteractionVolumeAssemblerBase< P, EG, EV >; diff --git a/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh b/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh index 60f78d6d68..a0df661d3c 100644 --- a/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh +++ b/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh @@ -37,6 +37,7 @@ #include #include +#include "localassembler.hh" #include "localsubcontrolentities.hh" #include "interactionvolumeindexset.hh" @@ -96,6 +97,10 @@ public: static constexpr int numScvs = C; //! export the number of scvfs in the interaction volumes static constexpr int numScvfs = F; + + //! the type of assembler used for the o-method's iv-local eq systems + template + using LocalAssembler = MpfaOInteractionVolumeAssembler; }; /*! -- GitLab From 628c3e127070a11e4d6e65dba617238a3d9b7c71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Gl=C3=A4ser?= Date: Wed, 21 Nov 2018 11:17:16 +0100 Subject: [PATCH 28/35] [mpfa][fluxvarcachefiller] use correct sol-dep flag for ni --- .../cellcentered/mpfa/fluxvariablescachefiller.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh b/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh index a95a31c84f..3eb3ddf5ce 100644 --- a/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh +++ b/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh @@ -505,8 +505,8 @@ private: using IvLocalAssembler = typename Traits::template LocalAssembler; IvLocalAssembler localAssembler(problem(), fvGeometry(), elemVolVars()); - // maybe (re-)assemble matrices (TODO: USE CORRECT SOLDEPENDENT FLAG!) - if (forceUpdateAll || soldependentAdvection) + // maybe (re-)assemble matrices + if (forceUpdateAll || soldependentHeatConduction) localAssembler.assembleMatrices(handle.heatConductionHandle(), iv, LambdaFactory::template getHeatConductionLambda()); -- GitLab From ab6e2806905ec4e69b7a8b88e1b08dd17e6117a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Gl=C3=A4ser?= Date: Wed, 21 Nov 2018 11:26:22 +0100 Subject: [PATCH 29/35] [mpfa][iv] remove unused aliases --- .../cellcentered/mpfa/omethod/interactionvolume.hh | 4 ---- .../cellcentered/mpfa/omethod/staticinteractionvolume.hh | 4 ---- 2 files changed, 8 deletions(-) diff --git a/dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh b/dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh index cf45a0ca5b..8b557cb505 100644 --- a/dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh +++ b/dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh @@ -126,10 +126,6 @@ class CCMpfaOInteractionVolume std::vector, Dune::ReservedVector >::type; - using AMatrix = typename Traits::MatVecTraits::AMatrix; - using BMatrix = typename Traits::MatVecTraits::BMatrix; - using CMatrix = typename Traits::MatVecTraits::CMatrix; - using LocalScvType = typename Traits::LocalScvType; using LocalScvfType = typename Traits::LocalScvfType; using LocalFaceData = typename Traits::LocalFaceData; diff --git a/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh b/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh index a0df661d3c..82cbe5c1a7 100644 --- a/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh +++ b/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh @@ -133,10 +133,6 @@ class CCMpfaOStaticInteractionVolume using DimVector = Dune::FieldVector; using FaceOmegas = typename Dune::ReservedVector; - using AMatrix = typename Traits::MatVecTraits::AMatrix; - using BMatrix = typename Traits::MatVecTraits::BMatrix; - using CMatrix = typename Traits::MatVecTraits::CMatrix; - using LocalScvType = typename Traits::LocalScvType; using LocalScvfType = typename Traits::LocalScvfType; using LocalFaceData = typename Traits::LocalFaceData; -- GitLab From 8feea16b6d666095902e1c8da15f49cfdda3fb09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Gl=C3=A4ser?= Date: Wed, 21 Nov 2018 11:56:45 +0100 Subject: [PATCH 30/35] [mpfa][iv] put omegas in data handle --- .../mpfa/interactionvolumedatahandle.hh | 6 ++++ .../cellcentered/mpfa/localassemblerbase.hh | 2 +- .../mpfa/omethod/interactionvolume.hh | 31 +++++-------------- .../mpfa/omethod/localassembler.hh | 17 ++++++---- .../mpfa/omethod/staticinteractionvolume.hh | 25 ++++----------- 5 files changed, 32 insertions(+), 49 deletions(-) diff --git a/dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh b/dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh index baee94234a..ebcebfd5a5 100644 --- a/dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh +++ b/dumux/discretization/cellcentered/mpfa/interactionvolumedatahandle.hh @@ -64,6 +64,7 @@ class MatrixDataHandleBase using TMatrix = typename MVT::TMatrix; using CellVector = typename MVT::CellVector; using OutsideTij = std::vector< std::vector >; + using OmegaStorage = typename MVT::OmegaStorage; public: //! Access functions to context-dependent data @@ -82,6 +83,9 @@ public: const OutsideTij& tijOutside() const { return tijOutside_[contextIdx1_][contextIdx2_]; } OutsideTij& tijOutside() { return tijOutside_[contextIdx1_][contextIdx2_]; } + const OmegaStorage& omegas() const { return wijk_[contextIdx1_][contextIdx2_]; } + OmegaStorage& omegas() { return wijk_[contextIdx1_][contextIdx2_]; } + //! functionality to set the context indices void setContextIndex1(unsigned int idx) const { assert(idx < size1); contextIdx1_ = idx; } void setContextIndex2(unsigned int idx) const { assert(idx < size2); contextIdx2_ = idx; } @@ -91,6 +95,8 @@ protected: mutable unsigned int contextIdx1_{0}; mutable unsigned int contextIdx2_{0}; + std::array< std::array, size1 > wijk_; //!< The omega factors that form the entries of the matrices + std::array< std::array, size1 > T_; //!< The transmissibility matrix std::array< std::array, size1 > A_; //!< Inverse of the iv-local system matrix std::array< std::array, size1 > AB_; //!< A_ left multiplied to B diff --git a/dumux/discretization/cellcentered/mpfa/localassemblerbase.hh b/dumux/discretization/cellcentered/mpfa/localassemblerbase.hh index 20cbb2a1cc..56c350025d 100644 --- a/dumux/discretization/cellcentered/mpfa/localassemblerbase.hh +++ b/dumux/discretization/cellcentered/mpfa/localassemblerbase.hh @@ -266,7 +266,7 @@ class InteractionVolumeAssemblerBase const auto localScvfIdx = localFaceData.ivLocalScvfIndex(); const auto idxInOutside = localFaceData.scvfLocalOutsideScvfIndex(); const auto& posLocalScv = iv.localScv(localScvIdx); - const auto& wijk = iv.omegas()[localScvfIdx][idxInOutside+1]; + const auto& wijk = handle.omegas()[localScvfIdx][idxInOutside+1]; // add contributions from all local directions for (LocalIndexType localDir = 0; localDir < dim; localDir++) diff --git a/dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh b/dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh index 8b557cb505..ed91b8d447 100644 --- a/dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh +++ b/dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh @@ -67,9 +67,16 @@ private: static constexpr int dim = NodalIndexSet::Traits::GridView::dimension; static constexpr int dimWorld = NodalIndexSet::Traits::GridView::dimensionworld; + using DimVector = Dune::FieldVector; + using FaceOmegas = typename std::conditional< (dim, + Dune::ReservedVector >::type; + //! Matrix/Vector traits to be used by the data handle struct MVTraits { + using OmegaStorage = std::vector< FaceOmegas >; + using AMatrix = Dune::DynamicMatrix< Scalar >; using BMatrix = Dune::DynamicMatrix< Scalar >; using CMatrix = Dune::DynamicMatrix< Scalar >; @@ -116,16 +123,6 @@ class CCMpfaOInteractionVolume using LocalIndexType = typename IndexSet::LocalIndexType; using Stencil = typename IndexSet::NodalGridStencilType; - static constexpr int dim = GridView::dimension; - static constexpr int dimWorld = GridView::dimensionworld; - - //! export scalar type from T matrix and define omegas - using Scalar = typename Traits::MatVecTraits::TMatrix::value_type; - using DimVector = Dune::FieldVector; - using FaceOmegas = typename std::conditional< (dim, - Dune::ReservedVector >::type; - using LocalScvType = typename Traits::LocalScvType; using LocalScvfType = typename Traits::LocalScvfType; using LocalFaceData = typename Traits::LocalFaceData; @@ -144,9 +141,6 @@ public: GridIndexType volVarIndex() const { return volVarIndex_; } }; - //! export the type used for transmissibility storage - using TransmissibilityStorage = std::vector< FaceOmegas >; - //! publicly state the mpfa-scheme this interaction volume is associated with static constexpr MpfaMethods MpfaMethod = MpfaMethods::oMethod; @@ -193,7 +187,6 @@ public: numKnowns_ = numLocalScvs; // set up quantitites related to sub-control volume faces - wijk_.resize(numFaces_); for (LocalIndexType faceIdxLocal = 0; faceIdxLocal < numFaces_; ++faceIdxLocal) { const auto& scvf = fvGeometry.scvf(indexSet.gridScvfIndex(faceIdxLocal)); @@ -206,7 +199,6 @@ public: // we will need as many omegas as scvs around the face const auto numNeighborScvs = neighborScvIndicesLocal.size(); - wijk_[faceIdxLocal].resize(numNeighborScvs); // create iv-local scvf object if (scvf.boundary()) @@ -230,7 +222,7 @@ public: { // loop over scvfs in outside scv until we find the one coinciding with current scvf const auto outsideLocalScvIdx = neighborScvIndicesLocal[i]; - for (int coord = 0; coord < dim; ++coord) + for (int coord = 0; coord < GridView::dimension; ++coord) { if (indexSet.localScvfIndex(outsideLocalScvIdx, coord) == faceIdxLocal) { @@ -291,10 +283,6 @@ public: const std::vector& dirichletData() const { return dirichletData_; } - //! returns container storing the transmissibilities for each face & coordinate - const TransmissibilityStorage& omegas() const { return wijk_; } - TransmissibilityStorage& omegas() { return wijk_; } - //! returns the number of interaction volumes living around a vertex template< class NI > static constexpr std::size_t numIVAtVertex(const NI& nodalIndexSet) { return 1; } @@ -332,9 +320,6 @@ private: std::vector localFaceData_; std::vector dirichletData_; - // The omega factors are stored during assembly of local system - TransmissibilityStorage wijk_; - // sizes involved in the local system equations std::size_t numFaces_; std::size_t numUnknowns_; diff --git a/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh b/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh index dafa103d8c..a403964578 100644 --- a/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh +++ b/dumux/discretization/cellcentered/mpfa/omethod/localassembler.hh @@ -70,7 +70,7 @@ public: template< class DataHandle, class IV, class TensorFunc > void assembleMatrices(DataHandle& handle, IV& iv, const TensorFunc& getT) { - assembleLocalMatrices_(handle.A(), handle.AB(), handle.CA(), handle.T(), iv, getT); + assembleLocalMatrices_(handle.A(), handle.AB(), handle.CA(), handle.T(), handle.omegas(), iv, getT); // maybe solve the local system if (iv.numUnknowns() > 0) @@ -113,7 +113,7 @@ public: const auto scvfIdx = localFaceData.ivLocalScvfIndex(); const auto idxInOut = localFaceData.scvfLocalOutsideScvfIndex(); - const auto& wijk = iv.omegas()[scvfIdx][idxInOut+1]; + const auto& wijk = handle.omegas()[scvfIdx][idxInOut+1]; auto& tij = tijOut[scvfIdx][idxInOut]; tij = 0.0; @@ -194,12 +194,16 @@ private: typename IV::Traits::MatVecTraits::BMatrix& B, typename IV::Traits::MatVecTraits::CMatrix& C, typename IV::Traits::MatVecTraits::DMatrix& D, + typename IV::Traits::MatVecTraits::OmegaStorage& wijk, IV& iv, const TensorFunc& getT) { using LocalIndexType = typename IV::Traits::IndexSet::LocalIndexType; static constexpr int dim = IV::Traits::GridView::dimension; static constexpr int dimWorld = IV::Traits::GridView::dimensionworld; + // resize omegas + this->resizeVector_(wijk, iv.numFaces()); + // if only Dirichlet faces are present in the iv, // the matrices A, B & C are undefined and D = T if (iv.numUnknowns() == 0) @@ -222,15 +226,16 @@ private: const auto tensor = getT(this->problem(), posElement, posVolVars, this->fvGeometry(), posGlobalScv); // the omega factors of the "positive" sub volume - const auto wijk = computeMpfaTransmissibility(posLocalScv, curGlobalScvf, tensor, posVolVars.extrusionFactor()); + this->resizeVector_(wijk[faceIdx], /*no outside scvs present*/1); + wijk[faceIdx][0] = computeMpfaTransmissibility(posLocalScv, curGlobalScvf, tensor, posVolVars.extrusionFactor()); const auto posScvLocalDofIdx = posLocalScv.localDofIndex(); for (LocalIndexType localDir = 0; localDir < dim; localDir++) { const auto& otherLocalScvf = iv.localScvf( posLocalScv.localScvfIndex(localDir) ); const auto otherLocalDofIdx = otherLocalScvf.localDofIndex(); - D[faceIdx][otherLocalDofIdx] -= wijk[localDir]; - D[faceIdx][posScvLocalDofIdx] += wijk[localDir]; + D[faceIdx][otherLocalDofIdx] -= wijk[faceIdx][0][localDir]; + D[faceIdx][posScvLocalDofIdx] += wijk[faceIdx][0][localDir]; } } } @@ -242,7 +247,6 @@ private: this->resizeMatrix_(C, iv.numFaces(), iv.numUnknowns()); C = 0.0; this->resizeMatrix_(D, iv.numFaces(), iv.numKnowns()); D = 0.0; - auto& wijk = iv.omegas(); for (LocalIndexType faceIdx = 0; faceIdx < iv.numFaces(); ++faceIdx) { const auto& curLocalScvf = iv.localScvf(faceIdx); @@ -259,6 +263,7 @@ private: const auto tensor = getT(this->problem(), posElement, posVolVars, this->fvGeometry(), posGlobalScv); // the omega factors of the "positive" sub volume + this->resizeVector_(wijk[faceIdx], neighborScvIndices.size()); wijk[faceIdx][0] = computeMpfaTransmissibility(posLocalScv, curGlobalScvf, tensor, posVolVars.extrusionFactor()); // go over the coordinate directions in the positive sub volume diff --git a/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh b/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh index 82cbe5c1a7..25dc7c492f 100644 --- a/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh +++ b/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh @@ -68,9 +68,14 @@ private: static constexpr int dim = NI::Traits::GridView::dimension; static constexpr int dimWorld = NI::Traits::GridView::dimensionworld; + using DimVector = Dune::FieldVector; + using FaceOmegas = Dune::ReservedVector; + //! Matrix/Vector traits to be used by the data handle struct MVTraits { + using OmegaStorage = std::array< FaceOmegas, F >; + using AMatrix = Dune::FieldMatrix< S, F, F >; using BMatrix = Dune::FieldMatrix< S, F, C >; using CMatrix = Dune::FieldMatrix< S, F, F >; @@ -125,14 +130,6 @@ class CCMpfaOStaticInteractionVolume using LocalIndexType = typename IndexSet::LocalIndexType; using Stencil = typename IndexSet::NodalGridStencilType; - static constexpr int dim = GridView::dimension; - static constexpr int dimWorld = GridView::dimensionworld; - - //! export scalar type from T matrix and define omegas - using Scalar = typename Traits::MatVecTraits::TMatrix::value_type; - using DimVector = Dune::FieldVector; - using FaceOmegas = typename Dune::ReservedVector; - using LocalScvType = typename Traits::LocalScvType; using LocalScvfType = typename Traits::LocalScvfType; using LocalFaceData = typename Traits::LocalFaceData; @@ -144,9 +141,6 @@ public: //! export the standard o-methods dirichlet data using DirichletData = typename CCMpfaOInteractionVolume< Traits >::DirichletData; - //! export the type used for transmissibility storage - using TransmissibilityStorage = std::array< FaceOmegas, numScvf >; - //! publicly state the mpfa-scheme this interaction volume is associated with static constexpr MpfaMethods MpfaMethod = MpfaMethods::oMethod; @@ -190,7 +184,7 @@ public: // add local face data objects for the outside face const auto outsideLocalScvIdx = neighborScvIndicesLocal[1]; - for (int coord = 0; coord < dim; ++coord) + for (int coord = 0; coord < GridView::dimension; ++coord) { if (indexSet.localScvfIndex(outsideLocalScvIdx, coord) == faceIdxLocal) { @@ -250,10 +244,6 @@ public: const std::array& dirichletData() const { return dirichletData_; } - //! returns container storing the transmissibilities for each face & coordinate - const TransmissibilityStorage& omegas() const { return wijk_; } - TransmissibilityStorage& omegas() { return wijk_; } - //! returns the number of interaction volumes living around a vertex template< class NI > static constexpr std::size_t numIVAtVertex(const NI& nodalIndexSet) @@ -291,9 +281,6 @@ private: std::array scvfs_; std::array localFaceData_; - // The omega factors are stored during assembly of local system - TransmissibilityStorage wijk_; - // Dummy dirichlet data container (compatibility with dynamic o-iv) std::array dirichletData_; }; -- GitLab From 291545611642b41035a05349eee81c20b638f097 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Gl=C3=A4ser?= Date: Wed, 21 Nov 2018 12:02:59 +0100 Subject: [PATCH 31/35] [mpfa][iv] use bind as function name for local scope setup This is more in agreement to the local view classes. --- .../cellcentered/mpfa/fluxvariablescachefiller.hh | 4 ++-- .../cellcentered/mpfa/interactionvolumebase.hh | 8 ++++---- .../cellcentered/mpfa/omethod/interactionvolume.hh | 6 +++--- .../cellcentered/mpfa/omethod/staticinteractionvolume.hh | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh b/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh index 3eb3ddf5ce..30ccbd1282 100644 --- a/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh +++ b/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh @@ -119,7 +119,7 @@ public: const auto& indexSet = fvGridGeometry.gridInteractionVolumeIndexSets().secondaryIndexSet(scvf); fluxVarsCacheContainer.secondaryInteractionVolumes().emplace_back(); secondaryIv_ = &fluxVarsCacheContainer.secondaryInteractionVolumes().back(); - secondaryIv_->setUpLocalScope(indexSet, problem(), fvGeometry); + secondaryIv_->bind(indexSet, problem(), fvGeometry); // prepare the corresponding data handle fluxVarsCacheContainer.secondaryDataHandles().emplace_back(); @@ -149,7 +149,7 @@ public: const auto& indexSet = fvGridGeometry.gridInteractionVolumeIndexSets().primaryIndexSet(scvf); fluxVarsCacheContainer.primaryInteractionVolumes().emplace_back(); primaryIv_ = &fluxVarsCacheContainer.primaryInteractionVolumes().back(); - primaryIv_->setUpLocalScope(indexSet, problem(), fvGeometry); + primaryIv_->bind(indexSet, problem(), fvGeometry); // prepare the corresponding data handle fluxVarsCacheContainer.primaryDataHandles().emplace_back(); diff --git a/dumux/discretization/cellcentered/mpfa/interactionvolumebase.hh b/dumux/discretization/cellcentered/mpfa/interactionvolumebase.hh index dbaf61141d..f399ac51df 100644 --- a/dumux/discretization/cellcentered/mpfa/interactionvolumebase.hh +++ b/dumux/discretization/cellcentered/mpfa/interactionvolumebase.hh @@ -80,10 +80,10 @@ public: //! Prepares everything for the assembly template< class Problem, class FVElementGeometry > - void setUpLocalScope(const typename Traits::IndexSet& indexSet, - const Problem& problem, - const FVElementGeometry& fvGeometry) - { DUNE_THROW(Dune::NotImplemented, "Interaction volume does not provide a setUpLocalScope() function"); } + void bind(const typename Traits::IndexSet& indexSet, + const Problem& problem, + const FVElementGeometry& fvGeometry) + { DUNE_THROW(Dune::NotImplemented, "Interaction volume does not provide a bind() function"); } //! returns the number of "primary" scvfs of this interaction volume std::size_t numFaces() const diff --git a/dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh b/dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh index ed91b8d447..9e4569bd99 100644 --- a/dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh +++ b/dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh @@ -146,9 +146,9 @@ public: //! Sets up the local scope for a given iv index set template< class Problem, class FVElementGeometry > - void setUpLocalScope(const IndexSet& indexSet, - const Problem& problem, - const FVElementGeometry& fvGeometry) + void bind(const IndexSet& indexSet, + const Problem& problem, + const FVElementGeometry& fvGeometry) { // for the o-scheme, the stencil is equal to the scv // index set of the dual grid's nodal index set diff --git a/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh b/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh index 25dc7c492f..347dd1cab8 100644 --- a/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh +++ b/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh @@ -146,9 +146,9 @@ public: //! Sets up the local scope for a given iv index set template< class Problem, class FVElementGeometry > - void setUpLocalScope(const IndexSet& indexSet, - const Problem& problem, - const FVElementGeometry& fvGeometry) + void bind(const IndexSet& indexSet, + const Problem& problem, + const FVElementGeometry& fvGeometry) { // for the o-scheme, the stencil is equal to the scv // index set of the dual grid's nodal index set -- GitLab From 53f7c46dc62bbf1081689f455c4751a7c099181c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Gl=C3=A4ser?= Date: Wed, 21 Nov 2018 12:11:07 +0100 Subject: [PATCH 32/35] [mpfa-o][iv] minor cleanup --- .../mpfa/omethod/interactionvolume.hh | 28 ++++++------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh b/dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh index 9e4569bd99..a81919eaa3 100644 --- a/dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh +++ b/dumux/discretization/cellcentered/mpfa/omethod/interactionvolume.hh @@ -160,16 +160,11 @@ public: const auto numGlobalScvfs = indexSet.nodalIndexSet().numScvfs(); // reserve memory for local entities - elements_.clear(); - scvs_.clear(); - scvfs_.clear(); - localFaceData_.clear(); - dirichletData_.clear(); - elements_.reserve(numLocalScvs); - scvs_.reserve(numLocalScvs); - scvfs_.reserve(numFaces_); - dirichletData_.reserve(numFaces_); - localFaceData_.reserve(numGlobalScvfs); + elements_.clear(); elements_.reserve(numLocalScvs); + scvs_.clear(); scvs_.reserve(numLocalScvs); + scvfs_.clear(); scvfs_.reserve(numFaces_); + localFaceData_.clear(); localFaceData_.reserve(numGlobalScvfs); + dirichletData_.clear(); dirichletData_.reserve(numFaces_); // set up stuff related to sub-control volumes for (LocalIndexType scvIdxLocal = 0; scvIdxLocal < numLocalScvs; scvIdxLocal++) @@ -193,19 +188,13 @@ public: // the neighboring scvs in local indices (order: 0 - inside scv, 1..n - outside scvs) const auto& neighborScvIndicesLocal = indexSet.neighboringLocalScvIndices(faceIdxLocal); - - // create local face data object for this face - localFaceData_.emplace_back(faceIdxLocal, neighborScvIndicesLocal[0], scvf.index()); - - // we will need as many omegas as scvs around the face const auto numNeighborScvs = neighborScvIndicesLocal.size(); + localFaceData_.emplace_back(faceIdxLocal, neighborScvIndicesLocal[0], scvf.index()); // create iv-local scvf object if (scvf.boundary()) { - const auto bcTypes = problem.boundaryTypes(elements_[neighborScvIndicesLocal[0]], scvf); - - if (bcTypes.hasOnlyDirichlet()) + if (problem.boundaryTypes(elements_[neighborScvIndicesLocal[0]], scvf).hasOnlyDirichlet()) { scvfs_.emplace_back(scvf, neighborScvIndicesLocal, numKnowns_++, /*isDirichlet*/true); dirichletData_.emplace_back(scvf.outsideScvIdx()); @@ -285,7 +274,8 @@ public: //! returns the number of interaction volumes living around a vertex template< class NI > - static constexpr std::size_t numIVAtVertex(const NI& nodalIndexSet) { return 1; } + static constexpr std::size_t numIVAtVertex(const NI& nodalIndexSet) + { return 1; } //! adds the iv index sets living around a vertex to a given container //! and stores the the corresponding index in a map for each scvf -- GitLab From 260bcdc6c79ef48f70951db5ecf523ed7151c2a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Gl=C3=A4ser?= Date: Wed, 21 Nov 2018 12:44:02 +0100 Subject: [PATCH 33/35] [mpfa-o][staticiv] move surface grid check into static assert --- .../cellcentered/mpfa/omethod/staticinteractionvolume.hh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh b/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh index 347dd1cab8..f70232f062 100644 --- a/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh +++ b/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh @@ -138,6 +138,9 @@ class CCMpfaOStaticInteractionVolume static constexpr int numScv = Traits::numScvs; public: + //! This does not work on surface grids + static_assert(int(GridView::dimension)==int(GridView::dimensionworld), "static iv does not work on surface grids"); + //! export the standard o-methods dirichlet data using DirichletData = typename CCMpfaOInteractionVolume< Traits >::DirichletData; @@ -170,14 +173,11 @@ public: for (LocalIndexType faceIdxLocal = 0; faceIdxLocal < numScvf; ++faceIdxLocal) { const auto& scvf = fvGeometry.scvf(indexSet.gridScvfIndex(faceIdxLocal)); + assert(!scvf.boundary()); // the neighboring scvs in local indices (order: 0 - inside scv, 1..n - outside scvs) const auto& neighborScvIndicesLocal = indexSet.neighboringLocalScvIndices(faceIdxLocal); - // this does not work for network grids or on boundaries - assert(!scvf.boundary()); - assert(neighborScvIndicesLocal.size() == 2); - // create iv-local scvf objects scvfs_[faceIdxLocal] = LocalScvfType(scvf, neighborScvIndicesLocal, faceIdxLocal, /*isDirichlet*/false); localFaceData_[faceIdxLocal*2] = LocalFaceData(faceIdxLocal, neighborScvIndicesLocal[0], scvf.index()); -- GitLab From 65f953cd8315011f347969bcb40ba73edb1c8ef2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Gl=C3=A4ser?= Date: Wed, 21 Nov 2018 13:08:17 +0100 Subject: [PATCH 34/35] [test][2p2c][mpfa] use static iv around interior vertices --- .../2p2c/implicit/injection/problem.hh | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/test/porousmediumflow/2p2c/implicit/injection/problem.hh b/test/porousmediumflow/2p2c/implicit/injection/problem.hh index cf5466effb..9f94940af5 100644 --- a/test/porousmediumflow/2p2c/implicit/injection/problem.hh +++ b/test/porousmediumflow/2p2c/implicit/injection/problem.hh @@ -26,6 +26,7 @@ #include +#include #include #include #include @@ -90,6 +91,24 @@ template struct EnableGridVolumeVariablesCache { static constexpr bool value = ENABLECACHING; }; template struct EnableGridFluxVariablesCache { static constexpr bool value = ENABLECACHING; }; + +// use the static interaction volume around interior vertices in the mpfa test +template +struct PrimaryInteractionVolume +{ +private: + using Scalar = GetPropType; + using NodalIndexSet = GetPropType; + + // structured two-d grid + static constexpr int numIvScvs = 4; + static constexpr int numIvScvfs = 4; + + // use the default traits + using Traits = CCMpfaODefaultStaticInteractionVolumeTraits< NodalIndexSet, Scalar, numIvScvs, numIvScvfs >; +public: + using type = CCMpfaOStaticInteractionVolume< Traits >; +}; } // end namespace Properties /*! -- GitLab From 50b148b5b5c0ae00eb513c92e5d27ca19c7aa96e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Gl=C3=A4ser?= Date: Wed, 21 Nov 2018 15:14:00 +0100 Subject: [PATCH 35/35] [mpfa-o][staticiv] reuse functionality from standard o-iv --- .../mpfa/omethod/staticinteractionvolume.hh | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh b/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh index f70232f062..14703fc152 100644 --- a/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh +++ b/dumux/discretization/cellcentered/mpfa/omethod/staticinteractionvolume.hh @@ -260,15 +260,11 @@ public: const NodalIndexSet& nodalIndexSet, const FlipScvfIndexSet& flipScvfIndexSet) { - // the global index of the iv index set that is about to be created - const auto curGlobalIndex = ivIndexSetContainer.size(); - - // make the one index set for this node - ivIndexSetContainer.emplace_back(nodalIndexSet, flipScvfIndexSet); - - // store the index mapping - for (const auto scvfIdx : nodalIndexSet.gridScvfIndices()) - scvfIndexMap[scvfIdx] = curGlobalIndex; + // reuse the standard o-method's implementation of this + CCMpfaOInteractionVolume::addIVIndexSets(ivIndexSetContainer, + scvfIndexMap, + nodalIndexSet, + flipScvfIndexSet); } private: -- GitLab