From 8feea16b6d666095902e1c8da15f49cfdda3fb09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Gl=C3=A4ser?= <dennis.glaeser@iws.uni-stuttgart.de> Date: Wed, 21 Nov 2018 11:56:45 +0100 Subject: [PATCH] [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<CellVector> >; + 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<OmegaStorage, size2>, size1 > wijk_; //!< The omega factors that form the entries of the matrices + std::array< std::array<TMatrix, size2>, size1 > T_; //!< The transmissibility matrix std::array< std::array<AMatrix, size2>, size1 > A_; //!< Inverse of the iv-local system matrix std::array< std::array<CMatrix, size2>, 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<Scalar, dim>; + using FaceOmegas = typename std::conditional< (dim<dimWorld), + std::vector<DimVector>, + Dune::ReservedVector<DimVector, 2> >::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<Scalar, dim>; - using FaceOmegas = typename std::conditional< (dim<dimWorld), - std::vector<DimVector>, - Dune::ReservedVector<DimVector, 2> >::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>& 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> localFaceData_; std::vector<DirichletData> 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<S, dim>; + using FaceOmegas = Dune::ReservedVector<DimVector, 2>; + //! 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<Scalar, dim>; - using FaceOmegas = typename Dune::ReservedVector<DimVector, 2>; - 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, 0>& 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<LocalScvfType, numScvf> scvfs_; std::array<LocalFaceData, numScvf*2> 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, 0> dirichletData_; }; -- GitLab