// -*- 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 * \brief Data handle class for interaction volumes of mpfa methods. * This class is passed to interaction volumes to store the necessary data in it. */ #ifndef DUMUX_DISCRETIZATION_CC_MPFA_INTERACTIONVOLUMEDATAHANDLE_HH #define DUMUX_DISCRETIZATION_CC_MPFA_INTERACTIONVOLUMEDATAHANDLE_HH #include #include #include namespace Dumux { //! Empty data handle class template class EmptyDataHandle { public: void resize(const InteractionVolume& iv) {} }; //! Data handle for quantities related to advection template class AdvectionDataHandle { // export matrix & vector types from interaction volume using Matrix = typename InteractionVolume::Traits::Matrix; using Vector = typename InteractionVolume::Traits::Vector; using Scalar = typename Vector::value_type; using LocalIndexType = typename InteractionVolume::Traits::LocalIndexType; using OutsideDataContainer = std::vector< std::vector >; static constexpr int dim = GET_PROP_TYPE(TypeTag, GridView)::dimension; static constexpr int dimWorld = GET_PROP_TYPE(TypeTag, GridView)::dimensionworld; static constexpr int numPhases = GET_PROP_VALUE(TypeTag, NumPhases); public: //! prepare data handle for subsequent fill (normal grids) template< int d = dim, int dw = dimWorld, std::enable_if_t<(d==dw), int> = 0> void resize(const InteractionVolume& iv) { // resize transmissibility matrix & pressure vectors T_.resize(iv.numFaces(), iv.numKnowns()); for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) p_[pIdx].resize(iv.numKnowns()); // maybe resize gravity container static const bool enableGravity = getParamFromGroup(GET_PROP_VALUE(TypeTag, ModelParameterGroup), "Problem.EnableGravity"); if (enableGravity) { CA_.resize(iv.numFaces(), iv.numUnknowns()); for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) g_[pIdx].resize(iv.numFaces()); } } //! prepare data handle for subsequent fill (surface grids) template< int d = dim, int dw = dimWorld, std::enable_if_t<(d = 0> void resize(const InteractionVolume& iv) { static const bool enableGravity = getParamFromGroup(GET_PROP_VALUE(TypeTag, ModelParameterGroup), "Problem.EnableGravity"); if (!enableGravity) { T_.resize(iv.numFaces(), iv.numKnowns()); outsideT_.resize(iv.numFaces()); for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) p_[pIdx].resize(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) outsideT_[i][j].resize(iv.numKnowns()); } } else { T_.resize(iv.numFaces(), iv.numKnowns()); CA_.resize(iv.numFaces(), iv.numUnknowns()); A_.resize(iv.numUnknowns(), iv.numUnknowns()); outsideT_.resize(iv.numFaces()); for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) { p_[pIdx].resize(iv.numKnowns()); g_[pIdx].resize(iv.numFaces()); outsideG_[pIdx].resize(iv.numFaces()); } for (LocalIndexType i = 0; i < iv.numFaces(); ++i) { const auto numNeighbors = iv.localScvf(i).neighboringLocalScvIndices().size() - 1; outsideT_[i].resize(numNeighbors); for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) outsideG_[pIdx][i].resize(numNeighbors); for (LocalIndexType j = 0; j < numNeighbors; ++j) outsideT_[i][j].resize(iv.numKnowns()); } } } //! Access to the iv-wide pressure of one phase const Vector& pressures(unsigned int pIdx) const { return p_[pIdx]; } Vector& pressures(unsigned int pIdx) { return p_[pIdx]; } //! Access to the gravitational flux contributions for one phase const Vector& gravity(unsigned int pIdx) const { return g_[pIdx]; } Vector& gravity(unsigned int pIdx) { return g_[pIdx]; } //! Access to the gravitational flux contributions for all phases const std::array< Vector, numPhases >& gravity() const { return g_; } std::array< Vector, numPhases >& gravity() { return g_; } //! Projection matrix for gravitational acceleration const Matrix& advectionCA() const { return CA_; } Matrix& advectionCA() { return CA_; } //! Additional projection matrix needed on surface grids const Matrix& advectionA() const { return A_; } Matrix& advectionA() { return A_; } //! The transmissibilities associated with advective fluxes const Matrix& advectionT() const { return T_; } Matrix& advectionT() { 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_; } //! The gravitational acceleration for "outside" faces (used on surface grids) const std::array< std::vector, numPhases >& gravityOutside() const { return outsideG_; } std::array< std::vector, numPhases >& gravityOutside() { return outsideG_; } //! The gravitational acceleration for one phase on "outside" faces (used on surface grids) const std::vector& gravityOutside(unsigned int pIdx) const { return outsideG_[pIdx]; } std::vector& gravityOutside(unsigned int pIdx) { return outsideG_[pIdx]; } private: //! advection-related variables Matrix T_; //!< The transmissibilities such that f_i = T_ij*p_j Matrix CA_; //!< Matrix to project gravitational acceleration to all scvfs Matrix A_; //!< Matrix additionally needed for the projection on surface grids std::array< Vector, numPhases > p_; //!< The interaction volume-wide phase pressures std::array< Vector, 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< std::vector, numPhases > outsideG_; //!< The gravitational acceleration on "outside" faces (only on surface grids) }; //! Data handle for quantities related to diffusion template class DiffusionDataHandle { // export matrix & vector types from interaction volume using Matrix = typename InteractionVolume::Traits::Matrix; using Vector = typename InteractionVolume::Traits::Vector; using OutsideTContainer = std::vector< std::vector >; static constexpr int dim = GET_PROP_TYPE(TypeTag, GridView)::dimension; static constexpr int dimWorld = GET_PROP_TYPE(TypeTag, GridView)::dimensionworld; static constexpr int numPhases = GET_PROP_VALUE(TypeTag, NumPhases); static constexpr int numComponents = GET_PROP_VALUE(TypeTag, NumComponents); public: //! diffusion caches need to set phase and component index void setPhaseIndex(unsigned int phaseIdx) { phaseIdx_ = phaseIdx; } void setComponentIndex(unsigned int compIdx) { compIdx_ = compIdx; } //! prepare data handle for subsequent fill void resize(const InteractionVolume& iv) { for (unsigned int pIdx = 0; pIdx < numPhases; ++pIdx) { for (unsigned int cIdx = 0; cIdx < numComponents; ++cIdx) { if (pIdx == cIdx) continue; // resize transmissibility matrix & mole fraction vector T_[pIdx][cIdx].resize(iv.numFaces(), iv.numKnowns()); xj_[pIdx][cIdx].resize(iv.numKnowns()); // resize outsideTij on surface grids if (dim < dimWorld) { outsideT_[pIdx][cIdx].resize(iv.numFaces()); using LocalIndexType = typename InteractionVolume::Traits::LocalIndexType; for (LocalIndexType i = 0; i < iv.numFaces(); ++i) outsideT_[pIdx][cIdx][i].resize(iv.localScvf(i).neighboringLocalScvIndices().size()-1); } } } } //! Access to the iv-wide mole fractions of a component in one phase const Vector& moleFractions(unsigned int pIdx, unsigned int compIdx) const { return xj_[pIdx][compIdx]; } Vector& moleFractions(unsigned int pIdx, unsigned int compIdx) { return xj_[pIdx][compIdx]; } //! The transmissibilities associated with diffusive fluxes const Matrix& diffusionT() const { return T_[phaseIdx_][compIdx_]; } Matrix& diffusionT() { 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_]; } 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_; }; //! Data handle for quantities related to heat conduction template class HeatConductionDataHandle { //! export matrix & vector types from interaction volume using Matrix = typename InteractionVolume::Traits::Matrix; using Vector = typename InteractionVolume::Traits::Vector; static constexpr int dim = GET_PROP_TYPE(TypeTag, GridView)::dimension; static constexpr int dimWorld = GET_PROP_TYPE(TypeTag, GridView)::dimensionworld; public: //! prepare data handle for subsequent fill void resize(const InteractionVolume& iv) { //! resize transmissibility matrix & temperature vector T_.resize(iv.numFaces(), iv.numKnowns()); Tj_.resize(iv.numKnowns()); //! resize outsideTij on surface grids if (dim < dimWorld) { outsideT_.resize(iv.numFaces()); using LocalIndexType = typename InteractionVolume::Traits::LocalIndexType; for (LocalIndexType i = 0; i < iv.numFaces(); ++i) outsideT_[i].resize(iv.localScvf(i).neighboringLocalScvIndices().size()-1); } } //! Access to the iv-wide temperatures const Vector& temperatures() const { return Tj_; } Vector& temperatures() { return Tj_; } //! The transmissibilities associated with conductive fluxes const Matrix& heatConductionT() const { return T_; } Matrix& heatConductionT() { 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_; } private: // heat conduction-related variables Matrix T_; //!< The transmissibilities such that f_i = T_ij*T_j Vector Tj_; //!< The interaction volume-wide temperatures std::vector< std::vector > outsideT_; //!< The transmissibilities for "outside" faces (only necessary on surface grids) }; //! Process-dependent data handles when related process is disabled template class AdvectionDataHandle : public EmptyDataHandle {}; template class DiffusionDataHandle : public EmptyDataHandle {}; template class HeatConductionDataHandle : public EmptyDataHandle {}; //! Interaction volume data handle class template class InteractionVolumeDataHandle : public AdvectionDataHandle, public DiffusionDataHandle, public HeatConductionDataHandle { using AdvectionHandle = AdvectionDataHandle; using DiffusionHandle = DiffusionDataHandle; using HeatConductionHandle = HeatConductionDataHandle; public: //! prepare data handles for subsequent fills void resize(const InteractionVolume& iv) { AdvectionHandle::resize(iv); DiffusionHandle::resize(iv); HeatConductionHandle::resize(iv); } }; } // end namespace Dumux #endif