diff --git a/dumux/discretization/fluxvariablesbase.hh b/dumux/discretization/fluxvariablesbase.hh index b20dd3f15e97211e66fc547fa802c2a6e41adfd6..29a46c64de505bb022e7ae1e06e995f77679031d 100644 --- a/dumux/discretization/fluxvariablesbase.hh +++ b/dumux/discretization/fluxvariablesbase.hh @@ -101,7 +101,7 @@ public: //! Applies the upwind scheme to precalculated fluxes template<class UpwindTermFunction> - Scalar applyUpwindScheme(const UpwindTermFunction& upwindTerm, Scalar flux, int phaseIdx) + Scalar applyUpwindScheme(const UpwindTermFunction& upwindTerm, Scalar flux, int phaseIdx) const { //! Give the upwind scheme access to the cached variables return UpwindScheme::apply(*this, upwindTerm, flux, phaseIdx); diff --git a/dumux/porousmediumflow/1p/implicit/properties.hh b/dumux/porousmediumflow/1p/implicit/properties.hh index d4a4dbe04693142906f248ea737e1a4a8ef26562..568bd8e2853edef1ec8bd3c9cd697f663833b38e 100644 --- a/dumux/porousmediumflow/1p/implicit/properties.hh +++ b/dumux/porousmediumflow/1p/implicit/properties.hh @@ -58,6 +58,7 @@ NEW_TYPE_TAG(CCOnePNI, INHERITS_FROM(CCModel, OnePNI)); ////////////////////////////////////////////////////////////////// NEW_PROP_TAG(NumPhases); //!< Number of fluid phases in the system +NEW_PROP_TAG(NumComponents); //!< Number of fluid phases in the system NEW_PROP_TAG(Indices); //!< Enumerations for the model NEW_PROP_TAG(SpatialParams); //!< The type of the spatial parameters object NEW_PROP_TAG(FluidSystem); //!< The type of the fluid system to use diff --git a/dumux/porousmediumflow/1p/implicit/propertydefaults.hh b/dumux/porousmediumflow/1p/implicit/propertydefaults.hh index 25bc18cfa28b937b3d820b2b9ae4d14f542ae20c..b30470f0870be87a3e29da6a52b53374b0cc8449 100644 --- a/dumux/porousmediumflow/1p/implicit/propertydefaults.hh +++ b/dumux/porousmediumflow/1p/implicit/propertydefaults.hh @@ -52,6 +52,7 @@ namespace Dumux namespace Properties { SET_INT_PROP(OneP, NumEq, 1); //!< set the number of equations to 1 SET_INT_PROP(OneP, NumPhases, 1); //!< The number of phases in the 1p model is 1 +SET_INT_PROP(OneP, NumComponents, 1); //!< The number of components in the 1p model is 1 //! The local residual function SET_TYPE_PROP(OneP, LocalResidual, ImmiscibleLocalResidual<TypeTag>); diff --git a/dumux/porousmediumflow/2p/implicit/properties.hh b/dumux/porousmediumflow/2p/implicit/properties.hh index aaa68ec5cbb22a333f8e350f0261d60a770a2e86..419a1305a259003b565185a26e7abf80dbdc42b8 100644 --- a/dumux/porousmediumflow/2p/implicit/properties.hh +++ b/dumux/porousmediumflow/2p/implicit/properties.hh @@ -64,6 +64,7 @@ NEW_TYPE_TAG(CCTwoPNI, INHERITS_FROM(CCModel, TwoPNI)); ////////////////////////////////////////////////////////////////// NEW_PROP_TAG(NumPhases); //!< Number of fluid phases in the system +NEW_PROP_TAG(NumComponents); //!< Number of components in the fluid system NEW_PROP_TAG(ProblemEnableGravity); //!< Returns whether gravity is considered in the problem NEW_PROP_TAG(Formulation); //!< The formulation of the model NEW_PROP_TAG(Indices); //!< Enumerations for the model diff --git a/dumux/porousmediumflow/2p/implicit/propertydefaults.hh b/dumux/porousmediumflow/2p/implicit/propertydefaults.hh index efcf47123a3d6f4ae7e50389f15ab04679798055..7fea86ed9f1725833a66b08af082ab2cd5948781 100644 --- a/dumux/porousmediumflow/2p/implicit/propertydefaults.hh +++ b/dumux/porousmediumflow/2p/implicit/propertydefaults.hh @@ -56,6 +56,9 @@ SET_INT_PROP(TwoP, NumEq, 2); //! The number of phases in the 2p model is 2 SET_INT_PROP(TwoP, NumPhases, 2); +//! The number of components in the 2p model is 2 +SET_INT_PROP(TwoP, NumComponents, 2); + //! Set the default formulation to pWsN SET_INT_PROP(TwoP, Formulation, diff --git a/dumux/porousmediumflow/2pdfm/implicit/properties.hh b/dumux/porousmediumflow/2pdfm/implicit/properties.hh index 20102db24c2840bb0ea16c4f051f5a75e5df7e6b..a83419381ecb47f3eb0b2aaaa824d4e124d5cd68 100644 --- a/dumux/porousmediumflow/2pdfm/implicit/properties.hh +++ b/dumux/porousmediumflow/2pdfm/implicit/properties.hh @@ -52,6 +52,7 @@ NEW_TYPE_TAG(BoxTwoPDFM, INHERITS_FROM(BoxModel, TwoPDFM)); ////////////////////////////////////////////////////////////////// NEW_PROP_TAG(NumPhases); //!< Number of fluid phases in the system +NEW_PROP_TAG(NumComponents); //!< Number of components in the system NEW_PROP_TAG(ProblemEnableGravity); //!< Returns whether gravity is considered in the problem NEW_PROP_TAG(ImplicitMassUpwindWeight); //!< The value of the weight of the upwind direction in the mass conservation equations NEW_PROP_TAG(ImplicitMobilityUpwindWeight); //!< Weight for the upwind mobility in the velocity calculation diff --git a/dumux/porousmediumflow/2pdfm/implicit/propertydefaults.hh b/dumux/porousmediumflow/2pdfm/implicit/propertydefaults.hh index 7d600912f2c0d29acbdd55b483846d1c328c7dea..95f6aed10d509e09db650e60ba9a5bc13ce0aaec 100644 --- a/dumux/porousmediumflow/2pdfm/implicit/propertydefaults.hh +++ b/dumux/porousmediumflow/2pdfm/implicit/propertydefaults.hh @@ -52,6 +52,7 @@ namespace Properties ////////////////////////////////////////////////////////////////// SET_INT_PROP(TwoPDFM, NumEq, 2); //!< set the number of equations to 2 SET_INT_PROP(TwoPDFM, NumPhases, 2); //!< The number of phases in the 2p model is 2 +SET_INT_PROP(TwoPDFM, NumComponents, 2); //!< The number of components in the 2p model is 2 //! Set the default formulation to pWsN SET_INT_PROP(TwoPDFM, diff --git a/dumux/porousmediumflow/3p/implicit/properties.hh b/dumux/porousmediumflow/3p/implicit/properties.hh index a7c8830ca2c3407a14a59542cad0035bb806575d..50b6e72ca6295225c30a4d51d3b25449bb99af60 100644 --- a/dumux/porousmediumflow/3p/implicit/properties.hh +++ b/dumux/porousmediumflow/3p/implicit/properties.hh @@ -55,6 +55,7 @@ NEW_TYPE_TAG(CCThreePNI, INHERITS_FROM(CCTpfaModel, ThreePNI)); ////////////////////////////////////////////////////////////////// NEW_PROP_TAG(NumPhases); //!< Number of fluid phases in the system +NEW_PROP_TAG(NumComponents); //!< Number of components in the system NEW_PROP_TAG(Indices); //!< Enumerations for the model NEW_PROP_TAG(SpatialParams); //!< The type of the spatial parameters NEW_PROP_TAG(FluidSystem); //!< Type of the multi-component relations diff --git a/dumux/porousmediumflow/3p/implicit/propertydefaults.hh b/dumux/porousmediumflow/3p/implicit/propertydefaults.hh index fb26cf8843967781cb5909c9221a98be26bbdc5f..e524fe4142e307452b0cecfa2e327b1c2c7ae007 100644 --- a/dumux/porousmediumflow/3p/implicit/propertydefaults.hh +++ b/dumux/porousmediumflow/3p/implicit/propertydefaults.hh @@ -69,6 +69,17 @@ SET_PROP(ThreeP, NumPhases) "Only fluid systems with 3 phases are supported by the 3p model!"); }; +SET_PROP(ThreeP, NumComponents) +{ + private: + typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; + + public: + static const int value = FluidSystem::numComponents; + static_assert(value == 3, + "Only fluid systems with 3 components are supported by the 3p model!"); +}; + SET_INT_PROP(ThreeP, NumEq, 3); //!< set the number of equations to 2 /*! diff --git a/dumux/porousmediumflow/implicit/fluxvariables.hh b/dumux/porousmediumflow/implicit/fluxvariables.hh index bb896cb687afabcd67e4f110f61ee728f6a745ec..54b21d7941c4af98638d26a3e2ea89f51bc0f0bd 100644 --- a/dumux/porousmediumflow/implicit/fluxvariables.hh +++ b/dumux/porousmediumflow/implicit/fluxvariables.hh @@ -34,30 +34,20 @@ namespace Properties { // forward declaration NEW_PROP_TAG(NumPhases); +NEW_PROP_TAG(NumComponents); NEW_PROP_TAG(EnableAdvection); NEW_PROP_TAG(EnableMolecularDiffusion); NEW_PROP_TAG(EnableEnergyBalance); } -// forward declaration -template<class TypeTag, bool enableAdvection, bool enableMolecularDiffusion, bool enableEnergyBalance> -class PorousMediumFluxVariablesImpl; - /*! * \ingroup ImplicitModel - * \brief The flux variables class - * specializations are provided for combinations of physical processes + * \brief The porous medium flux variables class that computes advective / convective, + * molecular diffusive and heat conduction fluxes. * \note Not all specializations are currently implemented */ template<class TypeTag> -using PorousMediumFluxVariables = PorousMediumFluxVariablesImpl<TypeTag, GET_PROP_VALUE(TypeTag, EnableAdvection), - GET_PROP_VALUE(TypeTag, EnableMolecularDiffusion), - GET_PROP_VALUE(TypeTag, EnableEnergyBalance)>; - - -// specialization for pure advective flow (e.g. 1p/2p/3p immiscible darcy flow) -template<class TypeTag> -class PorousMediumFluxVariablesImpl<TypeTag, true, false, false> : public FluxVariablesBase<TypeTag> +class PorousMediumFluxVariables : public FluxVariablesBase<TypeTag> { using ParentType = FluxVariablesBase<TypeTag>; using Problem = typename GET_PROP_TYPE(TypeTag, Problem); @@ -67,238 +57,98 @@ class PorousMediumFluxVariablesImpl<TypeTag, true, false, false> : public FluxVa using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); using SubControlVolumeFace = typename GET_PROP_TYPE(TypeTag, SubControlVolumeFace); using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); - using AdvectionType = typename GET_PROP_TYPE(TypeTag, AdvectionType); using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables); using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables); using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache); - static const int dim = GridView::dimension; - static const int dimWorld = GridView::dimensionworld; - -public: - - template<typename FunctionType> - Scalar advectiveFlux(const int phaseIdx, const FunctionType& upwindTerm) - { - Scalar flux = AdvectionType::flux(this->problem(), - this->element(), - this->fvGeometry(), - this->elemVolVars(), - this->scvFace(), - phaseIdx, - this->elemFluxVarsCache()); - - return this->applyUpwindScheme(upwindTerm, flux, phaseIdx); - } -}; - - -// specialization for isothermal advection molecularDiffusion equations -template<class TypeTag> -class PorousMediumFluxVariablesImpl<TypeTag, true, true, false> : public FluxVariablesBase<TypeTag> -{ - using ParentType = FluxVariablesBase<TypeTag>; - using Problem = typename GET_PROP_TYPE(TypeTag, Problem); - using GridView = typename GET_PROP_TYPE(TypeTag, GridView); - using Element = typename GridView::template Codim<0>::Entity; - using IndexType = typename GridView::IndexSet::IndexType; - using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - 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 ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache); - using AdvectionType = typename GET_PROP_TYPE(TypeTag, AdvectionType); using MolecularDiffusionType = typename GET_PROP_TYPE(TypeTag, MolecularDiffusionType); + using HeatConductionType = typename GET_PROP_TYPE(TypeTag, HeatConductionType); enum { numPhases = GET_PROP_VALUE(TypeTag, NumPhases), numComponents = GET_PROP_VALUE(TypeTag, NumComponents) }; + static constexpr bool enableAdvection = GET_PROP_VALUE(TypeTag, EnableAdvection); + static constexpr bool enableMolecularDiffusion = GET_PROP_VALUE(TypeTag, EnableMolecularDiffusion); + static constexpr bool enableEnergyBalance = GET_PROP_VALUE(TypeTag, EnableEnergyBalance); + public: + //! The constructor - PorousMediumFluxVariablesImpl() + PorousMediumFluxVariables() { - advFluxCached_.reset(); - advPreFlux_.fill(0.0); + advFluxIsCached_.reset(); + advFluxBeforeUpwinding_.fill(0.0); } template<typename FunctionType> - Scalar advectiveFlux(const int phaseIdx, const FunctionType& upwindTerm) + Scalar advectiveFlux(const int phaseIdx, const FunctionType& upwindTerm) const { - if (!advFluxCached_[phaseIdx]) + if (enableAdvection) { - - advPreFlux_[phaseIdx] = AdvectionType::flux(this->problem(), - this->element(), - this->fvGeometry(), - this->elemVolVars(), - this->scvFace(), - phaseIdx, - this->elemFluxVarsCache()); - advFluxCached_.set(phaseIdx, true); + if (!advFluxIsCached_[phaseIdx]) + { + + advFluxBeforeUpwinding_[phaseIdx] = AdvectionType::flux(this->problem(), + this->element(), + this->fvGeometry(), + this->elemVolVars(), + this->scvFace(), + phaseIdx, + this->elemFluxVarsCache()); + advFluxIsCached_.set(phaseIdx, true); + } + + return this->applyUpwindScheme(upwindTerm, advFluxBeforeUpwinding_[phaseIdx], phaseIdx); } - - return this->applyUpwindScheme(upwindTerm, advPreFlux_[phaseIdx], phaseIdx); - } - - Dune::FieldVector<Scalar, numComponents> molecularDiffusionFlux(const int phaseIdx) - { - return MolecularDiffusionType::flux(this->problem(), - this->element(), - this->fvGeometry(), - this->elemVolVars(), - this->scvFace(), - phaseIdx, - this->elemFluxVarsCache()); - } - -private: - //! simple caching if advection flux is used twice with different upwind function - std::bitset<numPhases> advFluxCached_; - std::array<Scalar, numPhases> advPreFlux_; -}; - -// specialization for non-isothermal advective flow (e.g. non-isothermal one-phase darcy equation) -template<class TypeTag> -class PorousMediumFluxVariablesImpl<TypeTag, true, false, true> : public FluxVariablesBase<TypeTag> -{ - using ParentType = FluxVariablesBase<TypeTag>; - using Problem = typename GET_PROP_TYPE(TypeTag, Problem); - using GridView = typename GET_PROP_TYPE(TypeTag, GridView); - using Element = typename GridView::template Codim<0>::Entity; - using IndexType = typename GridView::IndexSet::IndexType; - using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - 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 ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache); - - using AdvectionType = typename GET_PROP_TYPE(TypeTag, AdvectionType); - using HeatConductionType = typename GET_PROP_TYPE(TypeTag, HeatConductionType); - - enum { numPhases = GET_PROP_VALUE(TypeTag, NumPhases) }; - -public: - //! The constructor - PorousMediumFluxVariablesImpl() - { - advFluxCached_.reset(); - advPreFlux_.fill(0.0); - } - - template<typename FunctionType> - Scalar advectiveFlux(const int phaseIdx, const FunctionType& upwindTerm) - { - if (!advFluxCached_[phaseIdx]) + else { - - advPreFlux_[phaseIdx] = AdvectionType::flux(this->problem(), - this->element(), - this->fvGeometry(), - this->elemVolVars(), - this->scvFace(), - phaseIdx, - this->elemFluxVarsCache()); - advFluxCached_.set(phaseIdx, true); + return 0.0; } - - return this->applyUpwindScheme(upwindTerm, advPreFlux_[phaseIdx], phaseIdx); } - Scalar heatConductionFlux() + Dune::FieldVector<Scalar, numComponents> molecularDiffusionFlux(const int phaseIdx) const { - return HeatConductionType::flux(this->problem(), - this->element(), - this->fvGeometry(), - this->elemVolVars(), - this->scvFace(), - this->elemFluxVarsCache()); - } - -private: - //! simple caching if advection flux is used twice with different upwind function - std::bitset<numPhases> advFluxCached_; - std::array<Scalar, numPhases> advPreFlux_; -}; - -// specialization for non-isothermal advection and difussion equations (e.g. non-isothermal three-phase three-component flow) -template<class TypeTag> -class PorousMediumFluxVariablesImpl<TypeTag, true, true, true> : public FluxVariablesBase<TypeTag> -{ - using ParentType = FluxVariablesBase<TypeTag>; - using Problem = typename GET_PROP_TYPE(TypeTag, Problem); - using GridView = typename GET_PROP_TYPE(TypeTag, GridView); - using Element = typename GridView::template Codim<0>::Entity; - using IndexType = typename GridView::IndexSet::IndexType; - using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - 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 ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache); - - using AdvectionType = typename GET_PROP_TYPE(TypeTag, AdvectionType); - using MolecularDiffusionType = typename GET_PROP_TYPE(TypeTag, MolecularDiffusionType); - using HeatConductionType = typename GET_PROP_TYPE(TypeTag, HeatConductionType); - - enum { numPhases = GET_PROP_VALUE(TypeTag, NumPhases), - numComponents = GET_PROP_VALUE(TypeTag, NumComponents) - }; - -public: - //! The constructor - PorousMediumFluxVariablesImpl() - { - advFluxCached_.reset(); - advPreFlux_.fill(0.0); - } - - template<typename FunctionType> - Scalar advectiveFlux(const int phaseIdx, const FunctionType& upwindTerm) - { - if (!advFluxCached_[phaseIdx]) + if (enableMolecularDiffusion) { - - advPreFlux_[phaseIdx] = AdvectionType::flux(this->problem(), - this->element(), - this->fvGeometry(), - this->elemVolVars(), - this->scvFace(), - phaseIdx, - this->elemFluxVarsCache()); - advFluxCached_.set(phaseIdx, true); + return MolecularDiffusionType::flux(this->problem(), + this->element(), + this->fvGeometry(), + this->elemVolVars(), + this->scvFace(), + phaseIdx, + this->elemFluxVarsCache()); + } + else + { + return Dune::FieldVector<Scalar, numComponents>(0.0); } - - return this->applyUpwindScheme(upwindTerm, advPreFlux_[phaseIdx], phaseIdx); } - Dune::FieldVector<Scalar, numComponents> molecularDiffusionFlux(const int phaseIdx) + Scalar heatConductionFlux() const { - return MolecularDiffusionType::flux(this->problem(), + if (enableEnergyBalance) + { + return HeatConductionType::flux(this->problem(), this->element(), this->fvGeometry(), this->elemVolVars(), this->scvFace(), - phaseIdx, this->elemFluxVarsCache()); - } - - Scalar heatConductionFlux() - { - return HeatConductionType::flux(this->problem(), - this->element(), - this->fvGeometry(), - this->elemVolVars(), - this->scvFace(), - this->elemFluxVarsCache()); + } + else + { + return 0.0; + } } private: //! simple caching if advection flux is used twice with different upwind function - std::bitset<numPhases> advFluxCached_; - std::array<Scalar, numPhases> advPreFlux_; + mutable std::bitset<numPhases> advFluxIsCached_; + mutable std::array<Scalar, numPhases> advFluxBeforeUpwinding_; }; -} // end namespace +} // end namespace Dumux #endif diff --git a/dumux/porousmediumflow/richards/implicit/properties.hh b/dumux/porousmediumflow/richards/implicit/properties.hh index c883a91bea74e114c28f0efc2059c0ee728ee5d9..75416afcfe93818139aa83bd83b59c07f4ff626d 100644 --- a/dumux/porousmediumflow/richards/implicit/properties.hh +++ b/dumux/porousmediumflow/richards/implicit/properties.hh @@ -59,6 +59,7 @@ NEW_TYPE_TAG(CCRichardsNI, INHERITS_FROM(CCModel, RichardsNI)); ////////////////////////////////////////////////////////////////// NEW_PROP_TAG(NumPhases); //!< Number of fluid phases in the system +NEW_PROP_TAG(NumComponents); //!< Number of components in the system NEW_PROP_TAG(Indices); //!< Enumerations used by the model NEW_PROP_TAG(SpatialParams); //!< The type of the spatial parameters NEW_PROP_TAG(MaterialLaw); //!< The material law which ought to be used (by default extracted from the spatial parameters) diff --git a/dumux/porousmediumflow/richards/implicit/propertydefaults.hh b/dumux/porousmediumflow/richards/implicit/propertydefaults.hh index 859ca527893b3e073554ef2813f1270c3ed22d9e..74398f523e1562797cf2a834bc62d70caf18272d 100644 --- a/dumux/porousmediumflow/richards/implicit/propertydefaults.hh +++ b/dumux/porousmediumflow/richards/implicit/propertydefaults.hh @@ -59,6 +59,9 @@ SET_INT_PROP(Richards, NumEq, 1); //! phase with a balance equation SET_INT_PROP(Richards, NumPhases, 1); +//! Only the water component is balanced for Richards +SET_INT_PROP(Richards, NumComponents, 1); + //! The local residual operator SET_TYPE_PROP(Richards, LocalResidual, ImmiscibleLocalResidual<TypeTag>);