diff --git a/dumux/discretization/cellcentered/tpfa/darcyslaw.hh b/dumux/discretization/cellcentered/tpfa/darcyslaw.hh index 3a3143739464163573a757f40d09403c5a765160..a87ed7610372948dd2ba72d3335d516bdb7f6c34 100644 --- a/dumux/discretization/cellcentered/tpfa/darcyslaw.hh +++ b/dumux/discretization/cellcentered/tpfa/darcyslaw.hh @@ -51,6 +51,7 @@ NEW_PROP_TAG(ProblemEnableGravity); template <class TypeTag> class DarcysLawImplementation<TypeTag, DiscretizationMethods::CCTpfa> { + using Implementation = DarcysLawImplementation<TypeTag, DiscretizationMethods::CCTpfa>; using Problem = typename GET_PROP_TYPE(TypeTag, Problem); using SubControlVolume = typename GET_PROP_TYPE(TypeTag, SubControlVolume); using SubControlVolumeFace = typename GET_PROP_TYPE(TypeTag, SubControlVolumeFace); @@ -60,6 +61,7 @@ class DarcysLawImplementation<TypeTag, DiscretizationMethods::CCTpfa> using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables); using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables); using ElementFluxVarsCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache); + using FluxVariablesCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache); using Element = typename GridView::template Codim<0>::Entity; using IndexType = typename GridView::IndexSet::IndexType; @@ -70,10 +72,56 @@ class DarcysLawImplementation<TypeTag, DiscretizationMethods::CCTpfa> using DimWorldMatrix = Dune::FieldMatrix<Scalar, dimWorld, dimWorld>; using GlobalPosition = Dune::FieldVector<Scalar, dimWorld>; + class TpfaDarcysLawCache + { + public: + void updateAdvection(const Problem& problem, + const Element& element, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolVars, + const SubControlVolumeFace &scvf) + { + tij_ = Implementation::calculateTransmissibilities(problem, element, fvGeometry, elemVolVars, scvf); + } + + const Scalar& tij() const + { return tij_; } + + private: + Scalar tij_; + }; + + //! Class that fills the cache corresponding to tpfa Darcy's Law + class TpfaDarcysLawCacheFiller + { + public: + //! Function to fill a TpfaDarcysLawCache of a given scvf + //! This interface has to be met by any advection-related cache filler class + template<class FluxVariablesCacheFiller> + static void fill(FluxVariablesCache& scvfFluxVarsCache, + const Problem& problem, + const Element& element, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolVars, + const SubControlVolumeFace& scvf, + const FluxVariablesCacheFiller& fluxVarsCacheFiller) + { + scvfFluxVarsCache.updateAdvection(problem, + element, + fvGeometry, + elemVolVars, + scvf); + } + }; + public: // state the discretization method this implementation belongs to static const DiscretizationMethods myDiscretizationMethod = DiscretizationMethods::CCTpfa; + // state the type for the corresponding cache and its filler + using Cache = TpfaDarcysLawCache; + using CacheFiller = TpfaDarcysLawCacheFiller; + static Scalar flux(const Problem& problem, const Element& element, const FVElementGeometry& fvGeometry, diff --git a/dumux/discretization/cellcentered/tpfa/elementfluxvariablescache.hh b/dumux/discretization/cellcentered/tpfa/elementfluxvariablescache.hh index 343e7d13e7f24c10c755a36d30cfde0813cd7b41..f2360b74848afe0ac31467cdbe70723fdc4c8933 100644 --- a/dumux/discretization/cellcentered/tpfa/elementfluxvariablescache.hh +++ b/dumux/discretization/cellcentered/tpfa/elementfluxvariablescache.hh @@ -24,6 +24,7 @@ #define DUMUX_DISCRETIZATION_CCTPFA_ELEMENT_FLUXVARSCACHE_HH #include <dumux/implicit/properties.hh> +#include <dumux/discretization/cellcentered/tpfa/fluxvariablescachefiller.hh> namespace Dumux { @@ -111,8 +112,7 @@ class CCTpfaElementFluxVariablesCache<TypeTag, false> using FluxVariablesCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache); using GlobalFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GlobalFluxVariablesCache); using SubControlVolumeFace = typename GET_PROP_TYPE(TypeTag, SubControlVolumeFace); - - static const bool solDependentAdvection = GET_PROP_VALUE(TypeTag, SolutionDependentAdvection); + using FluxVariablesCacheFiller = CCTpfaFluxVariablesCacheFiller<TypeTag>; public: CCTpfaElementFluxVariablesCache(const GlobalFluxVariablesCache& global) @@ -128,12 +128,15 @@ public: const auto numScvf = fvGeometry.numScvf(); fluxVarsCache_.resize(numScvf); globalScvfIndices_.resize(numScvf); - IndexType localScvfIdx = 0; + // instantiate helper class to fill the caches + FluxVariablesCacheFiller filler(globalFluxVarsCache().problem_()); + + IndexType localScvfIdx = 0; // fill the containers for (auto&& scvf : scvfs(fvGeometry)) { - fluxVarsCache_[localScvfIdx].update(globalFluxVarsCache().problem_(), element, fvGeometry, elemVolVars, scvf); + filler.fill(*this, fluxVarsCache_[localScvfIdx], element, fvGeometry, elemVolVars, scvf); globalScvfIndices_[localScvfIdx] = scvf.index(); localScvfIdx++; } @@ -150,6 +153,9 @@ public: const auto& assemblyMapI = problem.model().localJacobian().assemblyMap()[globalI]; const auto numNeighbors = assemblyMapI.size(); + // instantiate helper class to fill the caches + FluxVariablesCacheFiller filler(problem); + // find the number of scv faces that need to be prepared auto numScvf = fvGeometry.numScvf(); for (unsigned int localIdxJ = 0; localIdxJ < numNeighbors; ++localIdxJ) @@ -161,7 +167,7 @@ public: unsigned int localScvfIdx = 0; for (auto&& scvf : scvfs(fvGeometry)) { - fluxVarsCache_[localScvfIdx].update(problem, element, fvGeometry, elemVolVars, scvf); + filler.fill(*this, fluxVarsCache_[localScvfIdx], element, fvGeometry, elemVolVars, scvf); globalScvfIndices_[localScvfIdx] = scvf.index(); localScvfIdx++; } @@ -173,7 +179,7 @@ public: for (auto scvfIdx : assemblyMapI[localIdxJ].scvfsJ) { auto&& scvfJ = fvGeometry.scvf(scvfIdx); - fluxVarsCache_[localScvfIdx].update(problem, elementJ, fvGeometry, elemVolVars, scvfJ); + filler.fill(*this, fluxVarsCache_[localScvfIdx], elementJ, fvGeometry, elemVolVars, scvfJ); globalScvfIndices_[localScvfIdx] = scvfJ.index(); localScvfIdx++; } @@ -188,7 +194,10 @@ public: fluxVarsCache_.resize(1); globalScvfIndices_.resize(1); - fluxVarsCache_[0].update(globalFluxVarsCache().problem_(), element, fvGeometry, elemVolVars, scvf); + // instantiate helper class to fill the caches + FluxVariablesCacheFiller filler(globalFluxVarsCache().problem_()); + + filler.fill(*this, fluxVarsCache_[0], element, fvGeometry, elemVolVars, scvf); globalScvfIndices_[0] = scvf.index(); } @@ -211,8 +220,29 @@ private: const FVElementGeometry& fvGeometry, const ElementVolumeVariables& elemVolVars) { - if (solDependentAdvection) - bind(element, fvGeometry, elemVolVars); + static const bool isSolIndependent = FluxVariablesCacheFiller::isSolutionIndependent(); + + if (!isSolIndependent) + { + const auto& problem = globalFluxVarsCache().problem_(); + const auto globalI = problem.elementMapper().index(element); + + // instantiate filler class + FluxVariablesCacheFiller filler(problem); + + // let the filler class update the caches + for (unsigned int localScvfIdx = 0; localScvfIdx < fluxVarsCache_.size(); ++localScvfIdx) + { + const auto& scvf = fvGeometry.scvf(globalScvfIndices_[localScvfIdx]); + + const auto scvfInsideScvIdx = scvf.insideScvIdx(); + const auto& insideElement = scvfInsideScvIdx == globalI ? + element : + problem.model().globalFvGeometry().element(scvfInsideScvIdx); + + filler.fill(*this, fluxVarsCache_[localScvfIdx], insideElement, fvGeometry, elemVolVars, scvf); + } + } } // get index of scvf in the local container diff --git a/dumux/discretization/cellcentered/tpfa/fickslaw.hh b/dumux/discretization/cellcentered/tpfa/fickslaw.hh index 7b05340bfad569bf72afc7fdff95d0d794c53d9d..4634f678473d928d7f351c9689808365a4d9781e 100644 --- a/dumux/discretization/cellcentered/tpfa/fickslaw.hh +++ b/dumux/discretization/cellcentered/tpfa/fickslaw.hh @@ -61,6 +61,7 @@ class FicksLawImplementation<TypeTag, DiscretizationMethods::CCTpfa > using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables); using Element = typename GridView::template Codim<0>::Entity; using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache); + using FluxVariablesCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache); static const int dim = GridView::dimension; static const int dimWorld = GridView::dimensionworld; @@ -69,10 +70,36 @@ class FicksLawImplementation<TypeTag, DiscretizationMethods::CCTpfa > using DimWorldMatrix = Dune::FieldMatrix<Scalar, dimWorld, dimWorld>; using GlobalPosition = Dune::FieldVector<Scalar, dimWorld>; + //! We don't store anything for this law + class TpfaFicksLawCache + {}; + + //! The corresponding filler class + class TpfaFicksLawCacheFiller + { + public: + //! Function to fill a TpfaFicksLawCache (empty cache) of a given scvf + //! We have to fulfill the interface of a diffusion-related cache filler class + template<class FluxVariablesCacheFiller> + static void fill(FluxVariablesCache& scvfFluxVarsCache, + unsigned int phaseIdx, unsigned int compIdx, + const Problem& problem, + const Element& element, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolVars, + const SubControlVolumeFace& scvf, + const FluxVariablesCacheFiller& fluxVarsCacheFiller) + {} + }; + public: // state the discretization method this implementation belongs to static const DiscretizationMethods myDiscretizationMethod = DiscretizationMethods::CCTpfa; + // state the type for the corresponding cache and its filler + using Cache = TpfaFicksLawCache; + using CacheFiller = TpfaFicksLawCacheFiller; + static Scalar flux(const Problem& problem, const Element& element, const FVElementGeometry& fvGeometry, diff --git a/dumux/discretization/cellcentered/tpfa/fluxvariablescachefiller.hh b/dumux/discretization/cellcentered/tpfa/fluxvariablescachefiller.hh new file mode 100644 index 0000000000000000000000000000000000000000..285ee8bc5c8aad50bafdefa5d4df17d2597d3e94 --- /dev/null +++ b/dumux/discretization/cellcentered/tpfa/fluxvariablescachefiller.hh @@ -0,0 +1,233 @@ +// -*- 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 <http://www.gnu.org/licenses/>. * + *****************************************************************************/ +/*! + * \file + * \brief The flux variables cache filler class for the cell-centered TPFA scheme + */ +#ifndef DUMUX_DISCRETIZATION_CCTPFA_FLUXVARSCACHE_FILLER_HH +#define DUMUX_DISCRETIZATION_CCTPFA_FLUXVARSCACHE_FILLER_HH + +#include <dumux/implicit/properties.hh> +#include <dumux/discretization/methods.hh> + +namespace Dumux +{ + +/*! + * \ingroup ImplicitModel + * \brief Helper class to fill the flux var caches + */ +template<class TypeTag> +class CCTpfaFluxVariablesCacheFiller +{ + using Problem = typename GET_PROP_TYPE(TypeTag, Problem); + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using SubControlVolume = typename GET_PROP_TYPE(TypeTag, SubControlVolume); + using SubControlVolumeFace = typename GET_PROP_TYPE(TypeTag, SubControlVolumeFace); + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); + using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables); + using FluxVariablesCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache); + + using Element = typename GridView::template Codim<0>::Entity; + + static constexpr bool doAdvection = GET_PROP_VALUE(TypeTag, EnableAdvection); + static constexpr bool doDiffusion = GET_PROP_VALUE(TypeTag, EnableMolecularDiffusion); + static constexpr bool doHeatConduction = GET_PROP_VALUE(TypeTag, EnableEnergyBalance); + + static constexpr bool soldependentAdvection = GET_PROP_VALUE(TypeTag, SolutionDependentAdvection); + static constexpr bool soldependentDiffusion = GET_PROP_VALUE(TypeTag, SolutionDependentMolecularDiffusion); + static constexpr bool soldependentHeatConduction = GET_PROP_VALUE(TypeTag, SolutionDependentHeatConduction); + + enum ProcessIndices : unsigned int + { + advectionIdx, + diffusionIdx, + heatConductionIdx + }; + +public: + //! The constructor. Sets the problem pointer + CCTpfaFluxVariablesCacheFiller(const Problem& problem) : problemPtr_(&problem) {} + + /*! + * \brief function to fill the flux variables caches + * + * \param fluxVarsCacheContainer Either the element or global flux variables cache + * \param scvfFluxVarsCache The flux var cache to be updated corresponding to the given scvf + * \param element The finite element + * \param fvGeometry The finite volume geometry + * \param elemVolVars The element volume variables + * \param scvf The corresponding sub-control volume face + * \param doSubCaches Array of bools indicating which sub caches have to be updated + */ + template<class FluxVariablesCacheContainer> + void fill(FluxVariablesCacheContainer& fluxVarsCacheContainer, + FluxVariablesCache& scvfFluxVarsCache, + const Element& element, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolVars, + const SubControlVolumeFace& scvf, + const std::array<bool, 3>& doSubCaches = std::array<bool, 3>({true, true, true})) + { + // fill the physics-related quantities of the caches + if (doSubCaches[ProcessIndices::advectionIdx]) + fillAdvection(scvfFluxVarsCache, element, fvGeometry, elemVolVars, scvf); + if (doSubCaches[ProcessIndices::diffusionIdx]) + fillDiffusion(scvfFluxVarsCache, element, fvGeometry, elemVolVars, scvf); + if (doSubCaches[ProcessIndices::heatConductionIdx]) + fillHeatConduction(scvfFluxVarsCache, element, fvGeometry, elemVolVars, scvf); + } + + /*! + * \brief function to update the flux variables caches during derivative calculation + * + * \copydoc fill + */ + template<class FluxVariablesCacheContainer> + void update(FluxVariablesCacheContainer& fluxVarsCacheContainer, + FluxVariablesCache& scvfFluxVarsCache, + const Element& element, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolVars, + const SubControlVolumeFace& scvf) + { + // array of bool with which we indicate the sub-caches which have to be + // filled. During update, we only update solution-dependent quantities. + static const std::array<bool, 3> updateSubCaches = []() + { + std::array<bool, 3> tmp; + tmp[ProcessIndices::advectionIdx] = doAdvection && soldependentAdvection; + tmp[ProcessIndices::diffusionIdx] = doDiffusion && soldependentDiffusion; + tmp[ProcessIndices::heatConductionIdx] = doHeatConduction && soldependentHeatConduction; + return tmp; + } (); + + // forward to fill routine + fill(fluxVarsCacheContainer, scvfFluxVarsCache, element, fvGeometry, elemVolVars, scvf, updateSubCaches); + } + + static bool isSolutionIndependent() + { + static const bool isSolDependent = (doAdvection && soldependentAdvection) || + (doDiffusion && soldependentDiffusion) || + (doHeatConduction && soldependentHeatConduction); + return !isSolDependent; + } + +private: + + const Problem& problem() const + { return *problemPtr_; } + + //! method to fill the advective quantities + template<bool advectionEnabled = doAdvection> + typename std::enable_if<advectionEnabled>::type + fillAdvection(FluxVariablesCache& scvfFluxVarsCache, + const Element& element, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolVars, + const SubControlVolumeFace& scvf) + { + using AdvectionType = typename GET_PROP_TYPE(TypeTag, AdvectionType); + using AdvectionFiller = typename AdvectionType::CacheFiller; + + // forward to the filler for the advective quantities + AdvectionFiller::fill(scvfFluxVarsCache, problem(), element, fvGeometry, elemVolVars, scvf, *this); + } + + //! do nothing if advection is not enabled + template<bool advectionEnabled = doAdvection> + typename std::enable_if<!advectionEnabled>::type + fillAdvection(FluxVariablesCache& scvfFluxVarsCache, + const Element& element, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolVars, + const SubControlVolumeFace& scvf) + {} + + //! method to fill the diffusive quantities + template<bool diffusionEnabled = doDiffusion> + typename std::enable_if<diffusionEnabled>::type + fillDiffusion(FluxVariablesCache& scvfFluxVarsCache, + const Element& element, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolVars, + const SubControlVolumeFace& scvf) + { + using DiffusionType = typename GET_PROP_TYPE(TypeTag, MolecularDiffusionType); + using DiffusionFiller = typename DiffusionType::CacheFiller; + + static constexpr int numPhases = GET_PROP_VALUE(TypeTag, NumPhases); + static constexpr int numComponents = GET_PROP_VALUE(TypeTag, NumComponents); + + for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) + { + for (unsigned int compIdx = 0; compIdx < numComponents; ++compIdx) + { + if (phaseIdx == compIdx) + continue; + + // forward to the filler of the diffusive quantities + DiffusionFiller::fill(scvfFluxVarsCache, phaseIdx, compIdx, problem(), element, fvGeometry, elemVolVars, scvf, *this); + } + } + } + + //! do nothing if diffusion is not enabled + template<bool diffusionEnabled = doDiffusion> + typename std::enable_if<!diffusionEnabled>::type + fillDiffusion(FluxVariablesCache& scvfFluxVarsCache, + const Element& element, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolVars, + const SubControlVolumeFace& scvf) + {} + + //! method to fill the quantities related to heat conduction + template<bool heatConductionEnabled = doHeatConduction> + typename std::enable_if<heatConductionEnabled>::type + fillHeatConduction(FluxVariablesCache& scvfFluxVarsCache, + const Element& element, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolVars, + const SubControlVolumeFace& scvf) + { + using HeatConductionType = typename GET_PROP_TYPE(TypeTag, HeatConductionType); + using HeatConductionFiller = typename HeatConductionType::CacheFiller; + + // forward to the filler of the diffusive quantities + HeatConductionFiller::fill(scvfFluxVarsCache, problem(), element, fvGeometry, elemVolVars, scvf, *this); + } + + //! do nothing if heat conduction is disabled + template<bool heatConductionEnabled = doHeatConduction> + typename std::enable_if<!heatConductionEnabled>::type + fillHeatConduction(FluxVariablesCache& scvfFluxVarsCache, + const Element& element, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolVars, + const SubControlVolumeFace& scvf) + {} + + const Problem* problemPtr_; +}; + +} // end namespace + +#endif diff --git a/dumux/discretization/cellcentered/tpfa/fourierslaw.hh b/dumux/discretization/cellcentered/tpfa/fourierslaw.hh index c46876547ae2ff4f9a4f60fb44861d615272fa46..a7aba69b2804559fd13887792c20808540396da2 100644 --- a/dumux/discretization/cellcentered/tpfa/fourierslaw.hh +++ b/dumux/discretization/cellcentered/tpfa/fourierslaw.hh @@ -57,6 +57,7 @@ class FouriersLawImplementation<TypeTag, DiscretizationMethods::CCTpfa> using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables); using Element = typename GridView::template Codim<0>::Entity; using ElementFluxVarsCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache); + using FluxVariablesCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache); static const int dim = GridView::dimension; static const int dimWorld = GridView::dimensionworld; @@ -66,10 +67,35 @@ class FouriersLawImplementation<TypeTag, DiscretizationMethods::CCTpfa> using ThermalConductivityModel = typename GET_PROP_TYPE(TypeTag, ThermalConductivityModel); + //! We don't store anything for this law + class TpfaFouriersLawCache + {}; + + //! The corresponding filler class + class TpfaFouriersLawCacheFiller + { + public: + //! Function to fill a TpfaFicksLawCache (empty cache) of a given scvf + //! We have to fulfill the interface of a heat conduction related cache filler class + template<class FluxVariablesCacheFiller> + static void fill(FluxVariablesCache& scvfFluxVarsCache, + const Problem& problem, + const Element& element, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolVars, + const SubControlVolumeFace& scvf, + const FluxVariablesCacheFiller& fluxVarsCacheFiller) + {} + }; + public: // state the discretization method this implementation belongs to static const DiscretizationMethods myDiscretizationMethod = DiscretizationMethods::CCTpfa; + // state the type for the corresponding cache and its filler + using Cache = TpfaFouriersLawCache; + using CacheFiller = TpfaFouriersLawCacheFiller; + static Scalar flux(const Problem& problem, const Element& element, const FVElementGeometry& fvGeometry, diff --git a/dumux/discretization/cellcentered/tpfa/globalfluxvariablescache.hh b/dumux/discretization/cellcentered/tpfa/globalfluxvariablescache.hh index 2718ffcf18bcf34b2b695aac548cb3c0e045cc8b..aba839d8eb379c9ce3568829792c3f6f324dc681 100644 --- a/dumux/discretization/cellcentered/tpfa/globalfluxvariablescache.hh +++ b/dumux/discretization/cellcentered/tpfa/globalfluxvariablescache.hh @@ -24,6 +24,7 @@ #define DUMUX_DISCRETIZATION_CCTPFA_GLOBAL_FLUXVARSCACHE_HH #include <dumux/implicit/properties.hh> +#include <dumux/discretization/cellcentered/tpfa/fluxvariablescachefiller.hh> namespace Dumux { @@ -44,18 +45,26 @@ class CCTpfaGlobalFluxVariablesCache<TypeTag, true> { // the local class needs access to the problem friend typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache); + // the filler class needs access to the access operators + friend CCTpfaFluxVariablesCacheFiller<TypeTag>; + using Problem = typename GET_PROP_TYPE(TypeTag, Problem); using GridView = typename GET_PROP_TYPE(TypeTag, GridView); using IndexType = typename GridView::IndexSet::IndexType; using FluxVariablesCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache); using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache); using SubControlVolumeFace = typename GET_PROP_TYPE(TypeTag, SubControlVolumeFace); + using FluxVariablesCacheFiller = CCTpfaFluxVariablesCacheFiller<TypeTag>; public: // When global caching is enabled, precompute transmissibilities and stencils for all the scv faces void update(Problem& problem) { problemPtr_ = &problem; + + // instantiate helper class to fill the caches + FluxVariablesCacheFiller filler(problem); + const auto& globalFvGeometry = problem.model().globalFvGeometry(); fluxVarsCache_.resize(globalFvGeometry.numScvf()); for (const auto& element : elements(problem.gridView())) @@ -69,7 +78,7 @@ public: for (auto&& scvf : scvfs(fvGeometry)) { - fluxVarsCache_[scvf.index()].update(problem, element, fvGeometry, elemVolVars, scvf); + filler.fill(*this, fluxVarsCache_[scvf.index()], element, fvGeometry, elemVolVars, scvf); } } } @@ -83,7 +92,13 @@ public: { return ElementFluxVariablesCache(global); } private: - // access operators in the case of caching + // // access operators in the case of caching + // const FluxVariablesCache& operator [](const SubControlVolumeFace& scvf) const + // { return fluxVarsCache_[scvf.index()]; } + + // FluxVariablesCache& operator [](const SubControlVolumeFace& scvf) + // { return fluxVarsCache_[scvf.index()]; } + const FluxVariablesCache& operator [](IndexType scvfIdx) const { return fluxVarsCache_[scvfIdx]; } diff --git a/dumux/porousmediumflow/implicit/fluxvariablescache.hh b/dumux/porousmediumflow/implicit/fluxvariablescache.hh index 181aa3240c0082cdfb00a0adf7641b20c77e4783..21c62a763c73e75729176b2272ce6c6ea44cb3ba 100644 --- a/dumux/porousmediumflow/implicit/fluxvariablescache.hh +++ b/dumux/porousmediumflow/implicit/fluxvariablescache.hh @@ -40,15 +40,24 @@ namespace Properties NEW_PROP_TAG(NumPhases); } +/////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//! The cache is dependent on the active physical processes (advection, diffusion, heat conduction) +//! For each type of process there is a base cache storing the data required to compute the respective fluxes +//! Specializations of the overall cache are provided for combinations of processes +/////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /*! * \ingroup ImplicitModel * \brief The flux variables cache classes for porous media. - * Store flux stencils and data required for flux calculation + * Store data required for flux calculation. For each type of physical process (advection, diffusion, heat conduction) + * there is a base cache storing the data required to compute the respective fluxes. Specializations of the overall + * cache class are provided for different combinations of processes. */ template<class TypeTag> using PorousMediumFluxVariablesCache = PorousMediumFluxVariablesCacheImplementation<TypeTag, GET_PROP_VALUE(TypeTag, DiscretizationMethod)>; -// specialization for the Box Method +//! We only store discretization-related quantities for the box method. +//! Thus, we need no physics-dependent specialization. template<class TypeTag> class PorousMediumFluxVariablesCacheImplementation<TypeTag, DiscretizationMethods::Box> { @@ -100,65 +109,44 @@ public: const JacobianInverseTransposed& jacInvT() const { return jacInvT_; } - // The stencil info is obsolete for the box method. - // It is here for compatibility with cc methods - const Stencil& stencil() const - { - return stencil_; - } - private: std::vector<ShapeJacobian> shapeJacobian_; std::vector<ShapeValue> shapeValues_; JacobianInverseTransposed jacInvT_; - - Stencil stencil_; }; +// forward declaration of the base class of the tpfa flux variables cache +template<class TypeTag, bool EnableAdvection, bool EnableMolecularDiffusion, bool EnableEnergyBalance> +class CCTpfaPorousMediumFluxVariablesCache; + // specialization for the cell centered tpfa method template<class TypeTag> class PorousMediumFluxVariablesCacheImplementation<TypeTag, DiscretizationMethods::CCTpfa> -{ - using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - using Problem = typename GET_PROP_TYPE(TypeTag, Problem); - using GridView = typename GET_PROP_TYPE(TypeTag, GridView); - using FluxVariables = typename GET_PROP_TYPE(TypeTag, FluxVariables); - using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); - using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables); - using SubControlVolumeFace = typename GET_PROP_TYPE(TypeTag, SubControlVolumeFace); - using AdvectionType = typename GET_PROP_TYPE(TypeTag, AdvectionType); - using Element = typename GridView::template Codim<0>::Entity; - using IndexType = typename GridView::IndexSet::IndexType; - using Stencil = std::vector<IndexType>; + : public CCTpfaPorousMediumFluxVariablesCache<TypeTag, GET_PROP_VALUE(TypeTag, EnableAdvection), + GET_PROP_VALUE(TypeTag, EnableMolecularDiffusion), + GET_PROP_VALUE(TypeTag, EnableEnergyBalance)> {}; -public: - void update(const Problem& problem, - const Element& element, - const FVElementGeometry& fvGeometry, - const ElementVolumeVariables& elemVolVars, - const SubControlVolumeFace &scvf) - { - stencil_ = FluxVariables::computeStencil(problem, element, fvGeometry, scvf); - tij_ = AdvectionType::calculateTransmissibilities(problem, element, fvGeometry, elemVolVars, scvf); - } +// specialization for the case of pure advection +template<class TypeTag> +class CCTpfaPorousMediumFluxVariablesCache<TypeTag, true, false, false> : public GET_PROP_TYPE(TypeTag, AdvectionType)::Cache {}; - const Stencil& stencil() const - { return stencil_; } +// specialization for the case of advection & diffusion +template<class TypeTag> +class CCTpfaPorousMediumFluxVariablesCache<TypeTag, true, true, false> : public GET_PROP_TYPE(TypeTag, AdvectionType)::Cache, + public GET_PROP_TYPE(TypeTag, MolecularDiffusionType)::Cache {}; - const Scalar& tij() const - { return tij_; } +// specialization for the case of advection & heat conduction +template<class TypeTag> +class CCTpfaPorousMediumFluxVariablesCache<TypeTag, true, false, true> : public GET_PROP_TYPE(TypeTag, AdvectionType)::Cache, + public GET_PROP_TYPE(TypeTag, HeatConductionType)::Cache {}; -private: - Stencil stencil_; - Scalar tij_; -}; +// specialization for the case of advection, diffusion & heat conduction +template<class TypeTag> +class CCTpfaPorousMediumFluxVariablesCache<TypeTag, true, true, true> : public GET_PROP_TYPE(TypeTag, AdvectionType)::Cache, + public GET_PROP_TYPE(TypeTag, MolecularDiffusionType)::Cache, + public GET_PROP_TYPE(TypeTag, HeatConductionType)::Cache {}; -/////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//! Classes building up the porous medium flux variables cache for mpfa methods -//! The cache is dependent on the active physical processes (advection, diffusion, heat conduction) -//! For each type of process there is a base cache storing the data required to compute the respective fluxes -//! Specializations of the overall cache are provided for combinations of processes -////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// TODO further specializations // forward declaration of the base class of the mpfa flux variables cache template<class TypeTag, bool EnableAdvection, bool EnableMolecularDiffusion, bool EnableEnergyBalance>