diff --git a/dumux/discretization/box/fourierslawnonequilibrium.hh b/dumux/discretization/box/fourierslawnonequilibrium.hh index d83cc79d7357c8b99026cb71031e8e4e67c93499..3f113527bee37518e3006a52a56a1a97c76bd8a2 100644 --- a/dumux/discretization/box/fourierslawnonequilibrium.hh +++ b/dumux/discretization/box/fourierslawnonequilibrium.hh @@ -65,7 +65,7 @@ class FouriersLawNonEquilibriumImplementation<TypeTag, DiscretizationMethod::box enum { dimWorld = GridView::dimensionworld} ; enum { numPhases = GET_PROP_TYPE(TypeTag, ModelTraits)::numPhases()} ; enum { numEnergyEqFluid = GET_PROP_VALUE(TypeTag, NumEnergyEqFluid) }; - enum {sPhaseIdx = FluidSystem::sPhaseIdx}; + enum {sPhaseIdx = FluidSystem::numPhases}; using DimWorldMatrix = Dune::FieldMatrix<Scalar, dimWorld, dimWorld>; diff --git a/dumux/material/components/cao.hh b/dumux/material/components/cao.hh index 97d2b815512a020231790059820b3b6acfde5e2d..320b29865ed67526d2aa405efc756f394547e26b 100644 --- a/dumux/material/components/cao.hh +++ b/dumux/material/components/cao.hh @@ -64,7 +64,7 @@ public: /*! * \brief The mass density \f$\mathrm{[kg/m^3]}\f$ of CaO. */ - static Scalar density() + static Scalar solidDensity(Scalar temperature) { return 3370; } @@ -72,10 +72,18 @@ public: /*! * \brief The specific heat capacity \f$\mathrm{[J/kg K]}\f$ of CaO. */ - static Scalar heatCapacity() + static Scalar solidHeatCapacity(Scalar temperature) { return 934; //Nagel et al. (2014) : 934 J/kgK } + + /*! + * \brief The thermal conductivity \f$\mathrm{[W/(m K)]}\f$ of the porous material. + */ + static Scalar solidThermalConductivity(Scalar temperature) + { + return 0.4; //Nagel et al. (2014) + } }; } // end namespace Components diff --git a/dumux/material/components/cao2h2.hh b/dumux/material/components/cao2h2.hh index d703164ca5d92dd9706c3ccca0a90aef7af30ac7..d70baffe7843cf02097112117b5dcb2820605fd1 100644 --- a/dumux/material/components/cao2h2.hh +++ b/dumux/material/components/cao2h2.hh @@ -65,7 +65,7 @@ public: /*! * \brief The mass density \f$\mathrm{[kg/m^3]}\f$ of CaO2H2. */ - static Scalar density() + static Scalar solidDensity(Scalar temperature) { return 2200.0; //at 293 K ; Shao et al. (2013) } @@ -73,10 +73,18 @@ public: /*! * \brief The specific heat capacity \f$\mathrm{[J/kgK]}\f$ of CaO2H2. */ - static Scalar heatCapacity() + static Scalar solidHeatCapacity(Scalar temperature) { return 1530; //Nagel et al. (2014) : 1530 J/kgK } + + /*! + * \brief The thermal conductivity \f$\mathrm{[W/(m K)]}\f$ of the porous material. + */ + static Scalar solidThermalConductivity(Scalar temperature) + { + return 0.4; //Nagel et al. (2014) + } }; } // end namespace Components diff --git a/dumux/material/components/nacl.hh b/dumux/material/components/nacl.hh index 81e2d2c2c7a6e7744600028aa6b0f1303d9569b5..c2ccceacfceb6ed4159c41656d127a50bfd2ff69 100644 --- a/dumux/material/components/nacl.hh +++ b/dumux/material/components/nacl.hh @@ -76,7 +76,7 @@ public: /*! * \brief The mass density \f$\mathrm{[kg/m^3]}\f$ of NaCl. */ - static Scalar density() + static Scalar solidDensity(Scalar temperature) { return 2165.0; } @@ -84,7 +84,7 @@ public: /*! * \brief The specific heat capacity \f$\mathrm{[J/molK]}\f$ of NaCl. */ - static Scalar heatCapacity() + static Scalar solidHeatCapacity(Scalar temperature) { return 50.50; } diff --git a/dumux/material/components/solid.hh b/dumux/material/components/solid.hh index 62bb74099bdfee762f7800870bcbfa1c1aaf279b..91d11e5f57a5e10e33a1b7e70007fa38f9b539a8 100644 --- a/dumux/material/components/solid.hh +++ b/dumux/material/components/solid.hh @@ -54,36 +54,10 @@ public: * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$ */ template<class C = Component> - static Scalar solidDensity(Scalar temperature, Scalar pressure) + static Scalar solidDensity(Scalar temperature) { - static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: solidDensity(t,p)"); - DUNE_THROW(Dune::NotImplemented, "solidDensity(t,p)"); - } - - /*! - * \brief Specific enthalpy \f$\mathrm{[J/kg]}\f$ of the pure component in solid. - * - * \param temperature temperature of component in \f$\mathrm{[K]}\f$ - * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$ - */ - template<class C = Component> - static const Scalar solidEnthalpy(Scalar temperature, Scalar pressure) - { - static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: solidEnthalpy(t,p)"); - DUNE_THROW(Dune::NotImplemented, "solidEnthalpy(t,p)"); - } - - /*! - * \brief Specific internal energy \f$\mathrm{[J/kg]}\f$ of the pure component in solid. - * - * \param temperature temperature of component in \f$\mathrm{[K]}\f$ - * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$ - */ - template<class C = Component> - static const Scalar solidInternalEnergy(Scalar temperature, Scalar pressure) - { - static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: solidInternalEnergy(t,p)"); - DUNE_THROW(Dune::NotImplemented, "solidInternalEnergy(t,p)"); + static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: solidDensity(t)"); + DUNE_THROW(Dune::NotImplemented, "solidDensity(t)"); } /*! @@ -92,10 +66,10 @@ public: * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$ */ template<class C = Component> - static Scalar solidThermalConductivity(Scalar temperature, Scalar pressure) + static Scalar solidThermalConductivity(Scalar temperature) { - static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: solidThermalConductivity(t,p)"); - DUNE_THROW(Dune::NotImplemented, "solidThermalConductivity(t,p)"); + static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: solidThermalConductivity(t)"); + DUNE_THROW(Dune::NotImplemented, "solidThermalConductivity(t)"); } /*! @@ -104,10 +78,10 @@ public: * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$ */ template<class C = Component> - static Scalar solidHeatCapacity(Scalar temperature, Scalar pressure) + static Scalar solidHeatCapacity(Scalar temperature) { - static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: solidHeatCapacity(t,p)"); - DUNE_THROW(Dune::NotImplemented, "solidHeatCapacity(t,p)"); + static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: solidHeatCapacity(t)"); + DUNE_THROW(Dune::NotImplemented, "solidHeatCapacity(t)"); } }; diff --git a/dumux/material/fluidsystems/brineair.hh b/dumux/material/fluidsystems/brineair.hh index 84f52cf24eb8f9a6d3adb15da58c91f407c4f0be..f9b2c90708ae7b5176b7bcb6ba3feda8098b1d55 100644 --- a/dumux/material/fluidsystems/brineair.hh +++ b/dumux/material/fluidsystems/brineair.hh @@ -75,11 +75,9 @@ public: ****************************************/ static constexpr int numPhases = 2; // liquid and gas phases static constexpr int numComponents = 3; // H2O, Air, NaCl - static constexpr int numSPhases = 1;// precipitated solid phases // TODO: remove static constexpr int liquidPhaseIdx = 0; // index of the liquid phase static constexpr int gasPhaseIdx = 1; // index of the gas phase - static constexpr int solidPhaseIdx = 2; // index of the precipitated salt // TODO: remove static constexpr int phase0Idx = liquidPhaseIdx; // index of the first phase static constexpr int phase1Idx = gasPhaseIdx; // index of the second phase @@ -91,7 +89,7 @@ public: static constexpr int AirIdx = 1; static constexpr int comp0Idx = H2OIdx; static constexpr int comp1Idx = AirIdx; - static constexpr int NaClIdx = 2; // TODO: remove + static constexpr int NaClIdx = 2; /*! * \brief Return the human readable name of a fluid phase @@ -100,10 +98,10 @@ public: */ static std::string phaseName(int phaseIdx) { - switch (phaseIdx) { - case liquidPhaseIdx: return "liquid"; - case gasPhaseIdx: return "gas"; - case solidPhaseIdx: return "NaCl"; + switch (phaseIdx) + { + case liquidPhaseIdx: return "liquid"; + case gasPhaseIdx: return "gas"; } DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx); } @@ -220,18 +218,6 @@ public: DUNE_THROW(Dune::InvalidStateException, "Invalid component index " << compIdx); } - /*! - * \brief Return the mass density of the precipitate \f$\mathrm{[kg/m^3]}\f$. - * - * \param phaseIdx The index of the precipitated phase to consider - */ - static Scalar precipitateDensity(int phaseIdx) - { - if(phaseIdx != solidPhaseIdx) - DUNE_THROW(Dune::InvalidStateException, "Invalid solid phase index " << solidPhaseIdx); - return NaCl::density(); - } - /*! * \brief Return the saturation vapor pressure of the liquid phase \f$\mathrm{[Pa]}\f$. * @@ -243,25 +229,6 @@ public: return vaporPressure_(Temperature,salinity); } - /*! - * \brief Return the salt specific heat capacity \f$\mathrm{[J/molK]}\f$. - * - * \param phaseIdx The index of the precipitated phase to consider - */ - static Scalar precipitateHeatCapacity(int phaseIdx) - { - return NaCl::heatCapacity(); - } - - /*! - * \brief Return the molar density of the precipitate \f$\mathrm{[mol/m^3]}\f$. - * - * \param phaseIdx The index of the precipitated phase to consider - */ - static Scalar precipitateMolarDensity(int phaseIdx) - { - return precipitateDensity(phaseIdx)/molarMass(phaseIdx); //TODO this only works for this specific case here with phaseIdx=compIdx! - } /**************************************** * thermodynamic relations diff --git a/dumux/material/fluidsystems/h2on2kinetic.hh b/dumux/material/fluidsystems/h2on2kinetic.hh index 12bff8ba1bf1ad9e7d2449a9fcbaacde4188cf4a..13bb161ac7f26bc826bfc24e5e390a56a83bc097 100644 --- a/dumux/material/fluidsystems/h2on2kinetic.hh +++ b/dumux/material/fluidsystems/h2on2kinetic.hh @@ -58,17 +58,6 @@ public: //! The type of parameter cache objects using ParameterCache = NullParameterCache; - //! Index of the solid phase - static constexpr int sPhaseIdx = 2; - - static std::string phaseName(int phaseIdx) - { - if (phaseIdx == sPhaseIdx) - return "s"; - - return ParentType::phaseName(phaseIdx); - } - /*! * \brief Return the enthalpy of a component in a phase. * \param fluidState A container with the current (physical) state of the fluid diff --git a/dumux/material/fluidsystems/steamn2cao2h2.hh b/dumux/material/fluidsystems/steamn2cao2h2.hh index ee8f743160df9ac38b96914bd2339aa16949395b..d6ebf1130a9513e96a630bd6890c7007c4d058fd 100644 --- a/dumux/material/fluidsystems/steamn2cao2h2.hh +++ b/dumux/material/fluidsystems/steamn2cao2h2.hh @@ -34,8 +34,6 @@ #include <dumux/material/fluidsystems/base.hh> #include <dumux/material/components/n2.hh> #include <dumux/material/components/h2o.hh> -#include <dumux/material/components/cao2h2.hh> -#include <dumux/material/components/cao.hh> #include <dumux/material/binarycoefficients/h2o_n2.hh> #include <dumux/material/components/tabulatedcomponent.hh> @@ -79,22 +77,15 @@ public: //! Number of phases in the fluid system static constexpr int numPhases = 1; //gas phase: N2 and steam static constexpr int numComponents = 2; // H2O, Air - static constexpr int numSPhases = 2;// solid phases CaO and CaO2H2 TODO: Remove - static constexpr int numSComponents = 2;// CaO2H2, CaO TODO: Remove static constexpr int gasPhaseIdx = 0; //!< index of the gas phase static constexpr int phase0Idx = gasPhaseIdx; //!< index of the only phase - static constexpr int cPhaseIdx = 1; // CaO-phaseIdx TODO: Remove - static constexpr int hPhaseIdx = 2; // CaO2H2-phaseIdx TODO: Remove - static constexpr int N2Idx = 0; static constexpr int H2OIdx = 1; static constexpr int comp0Idx = N2Idx; static constexpr int comp1Idx = H2OIdx; - static constexpr int CaOIdx = 2; // CaO-phaseIdx TODO: Remove - static constexpr int CaO2H2Idx = 3; // CaO-phaseIdx TODO: Remove /**************************************** * Fluid phase related static parameters @@ -108,8 +99,6 @@ public: { switch (phaseIdx) { case gasPhaseIdx: return "gas"; - case cPhaseIdx : return "CaO"; - case hPhaseIdx : return "CaOH2"; } DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx); } @@ -197,9 +186,6 @@ public: { case H2OIdx: return "H2O"; case N2Idx: return "N2"; - case CaOIdx:return "CaO"; - case CaO2H2Idx:return "CaO2H2"; - } DUNE_THROW(Dune::InvalidStateException, "Invalid component index " << compIdx); } @@ -215,59 +201,10 @@ public: { case H2OIdx: return H2O::molarMass(); case N2Idx: return N2::molarMass(); - case CaOIdx: return CaO::molarMass(); - case CaO2H2Idx: return CaO2H2::molarMass(); } DUNE_THROW(Dune::InvalidStateException, "Invalid component index " << compIdx); } - /*! - * \brief Return the mass density of the solid \f$\mathrm{[kg/m^3]}\f$. - * - * \param phaseIdx The index of the solid phase to consider - */ - static Scalar precipitateDensity(int phaseIdx) - { - if(phaseIdx==cPhaseIdx) - return CaO::density(); - if(phaseIdx==hPhaseIdx) - return CaO2H2::density(); - else - DUNE_THROW(Dune::InvalidStateException, "Invalid solid index " << phaseIdx); - return 1; - } - - /*! - * \brief Return the salt specific heat capacity \f$\mathrm{[J/molK]}\f$. - * - * \param phaseIdx The index of the solid phase to consider - */ - static Scalar precipitateHeatCapacity(int phaseIdx) - { - if(phaseIdx==cPhaseIdx) - return CaO::heatCapacity(); - if(phaseIdx==hPhaseIdx) - return CaO2H2::heatCapacity(); - else - DUNE_THROW(Dune::InvalidStateException, "Invalid solid index " << phaseIdx); - return 1; - } - - /*! - * \brief Return the molar density of the solid \f$\mathrm{[mol/m^3]}\f$. - * - * \param phaseIdx The index of the solid phase to consider - */ - static Scalar precipitateMolarDensity(int phaseIdx) - { - if(phaseIdx==1){ - return precipitateDensity(phaseIdx)/ molarMass(CaOIdx); - } - if(phaseIdx==2){ - return precipitateDensity(phaseIdx)/molarMass(CaO2H2Idx); } - else - DUNE_THROW(Dune::InvalidStateException, "Invalid solid phase index " << phaseIdx); - } /**************************************** * thermodynamic relations diff --git a/dumux/material/solidstates/basesolidstate.hh b/dumux/material/solidstates/basesolidstate.hh index 7523cf1b40422dbd2029c09e795991a1590bc4e8..f27b81e9d689bb4f564f78a76839f18a2131e849 100644 --- a/dumux/material/solidstates/basesolidstate.hh +++ b/dumux/material/solidstates/basesolidstate.hh @@ -43,7 +43,7 @@ void updateSolidVolumeFractions(const ElemSol &elemSol, { for(int sCompIdx = solidState.numComponents- solidState.numInertComponents; sCompIdx < solidState.numComponents; ++sCompIdx) { - solidState.setVolumeFraction(sCompIdx, problem.spatialParams().inertVolumeFraction(element, scv, sCompIdx)); + solidState.setVolumeFraction(sCompIdx, problem.spatialParams().inertVolumeFraction(element, scv, solidState, sCompIdx)); } if (!(solidState.isInert())) { diff --git a/dumux/material/spatialparams/fv1p.hh b/dumux/material/spatialparams/fv1p.hh index 2bd8508cba66330641a7aa8d47b0655792c2d394..ce586e904189014e400c5cfef23c3d23c8045dcc 100644 --- a/dumux/material/spatialparams/fv1p.hh +++ b/dumux/material/spatialparams/fv1p.hh @@ -173,13 +173,10 @@ public: * * \param element The current element * \param scv The sub-control volume inside the element. - * \param elemSol The solution at the dofs connected to the element. * \return the porosity */ - template<class ElementSolution> Scalar porosity(const Element& element, - const SubControlVolume& scv, - const ElementSolution& elemSol) const + const SubControlVolume& scv) const { return asImp_().porosityAtPos(scv.center()); } @@ -193,97 +190,56 @@ public: Scalar porosityAtPos(const GlobalPosition& globalPos) const { DUNE_THROW(Dune::InvalidStateException, - "The spatial parameters do not provide " - "a porosityAtPos() method."); - } - - /*! - * \brief Returns the heat capacity \f$[J / (kg K)]\f$ of the rock matrix. - * - * This is only required for non-isothermal models. - * - * \param element The current element - * \param scv The sub-control volume inside the element. - * \param elemSol The solution at the dofs connected to the element. - */ - template<class ElementSolution> - Scalar solidHeatCapacity(const Element &element, - const SubControlVolume& scv, - const ElementSolution& elemSol) const - { - return asImp_().solidHeatCapacityAtPos(scv.center()); + "The spatial parameters do not provide a porosityAtPos() method."); } /*! - * \brief Returns the heat capacity \f$[J / (kg K)]\f$ of the rock matrix. - * - * This is only required for non-isothermal models. - * - * \param globalPos The position of the center of the element - */ - Scalar solidHeatCapacityAtPos(const GlobalPosition& globalPos) const - { - DUNE_THROW(Dune::InvalidStateException, - "The spatial parameters do not provide " - "a solidHeatCapacityAtPos() method."); - } - - /*! - * \brief Returns the mass density \f$[kg / m^3]\f$ of the rock matrix. - * - * This is only required for non-isothermal models. - * - * \param element The current element - * \param scv The sub-control volume inside the element. - * \param elemSol The solution at the dofs connected to the element. - */ - template<class ElementSolution> - Scalar solidDensity(const Element &element, - const SubControlVolume& scv, - const ElementSolution& elemSol) const - { - return asImp_().solidDensityAtPos(scv.center()); - } - - /*! - * \brief Returns the mass density \f$[kg / m^3]\f$ of the rock matrix. - * - * This is only required for non-isothermal models. + * \brief Function for defining the porosity. * - * \param globalPos The position of the center of the element + * \return porosity + * \param globalPos The position of the center of the scv */ - Scalar solidDensityAtPos(const GlobalPosition& globalPos) const - { - DUNE_THROW(Dune::InvalidStateException, - "The spatial parameters do not provide " - "a solidDensityAtPos() method."); - } + Scalar minimalPorosity(const Element& element, + const SubControlVolume& scv) const + { return 0.0; } /*! - * \brief Returns the thermal conductivity \f$\mathrm{[W/(m K)]}\f$ of the porous material. + * \brief Function for defining the porosity. + * That is possibly solution dependent. * * \param element The current element * \param scv The sub-control volume inside the element. * \param elemSol The solution at the dofs connected to the element. + * \return the porosity */ - template<class ElementSolution> - Scalar solidThermalConductivity(const Element &element, - const SubControlVolume& scv, - const ElementSolution& elemSol) const + template<class SolidState> + Scalar inertVolumeFraction(const Element& element, + const SubControlVolume& scv, + SolidState& solidState, + int compIdx) const { - return asImp_().solidThermalConductivityAtPos(scv.center()); + return asImp_().inertVolumeFractionAtPos(scv.center(), solidState, compIdx); } /*! - * \brief Returns the thermal conductivity \f$\mathrm{[W/(m K)]}\f$ of the porous material. + * \brief Function for defining the porosity. * - * \param globalPos The position of the center of the element + * \return porosity + * \param globalPos The position of the center of the scv */ - Scalar solidThermalConductivityAtPos(const GlobalPosition& globalPos) const + template<class SolidState> + Scalar inertVolumeFractionAtPos(const GlobalPosition& globalPos, + SolidState& solidState, + int compIdx) const { - DUNE_THROW(Dune::InvalidStateException, - "The spatial parameters do not provide " - "a solidThermalConductivityAtPos() method."); + if (solidState.isInert() && solidState.numInertComponents == 1) + { + return 1-asImp_().porosityAtPos(globalPos); + } + else + DUNE_THROW(Dune::InvalidStateException, + "The spatial parameters do not provide " + "a inertVolumeFractionAtPos() method."); } /*! diff --git a/dumux/porousmediumflow/1p/model.hh b/dumux/porousmediumflow/1p/model.hh index e025fdbdd202a9d29f54042f34bd45994d426910..b35409f9f6537b4f305110f249705077d5286591 100644 --- a/dumux/porousmediumflow/1p/model.hh +++ b/dumux/porousmediumflow/1p/model.hh @@ -46,6 +46,9 @@ #include <dumux/material/fluidmatrixinteractions/1p/thermalconductivityaverage.hh> #include <dumux/material/fluidstates/immiscible.hh> +#include <dumux/material/solidstates/inertsolidstate.hh> +#include <dumux/material/solidsystems/inertsolidphase.hh> +#include <dumux/material/components/constant.hh> #include <dumux/porousmediumflow/properties.hh> #include <dumux/porousmediumflow/immiscible/localresidual.hh> @@ -89,6 +92,8 @@ struct OnePModelTraits template<class PV, class FSY, class FST, + class SSY, + class SST, class PT, class MT> struct OnePVolumeVariablesTraits @@ -96,6 +101,8 @@ struct OnePVolumeVariablesTraits using PrimaryVariables = PV; using FluidSystem = FSY; using FluidState = FST; + using SolidSystem = SSY; + using SolidState = SST; using PermeabilityType = PT; using ModelTraits = MT; }; @@ -120,10 +127,12 @@ private: using PV = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); using FSY = typename GET_PROP_TYPE(TypeTag, FluidSystem); using FST = typename GET_PROP_TYPE(TypeTag, FluidState); + using SSY = typename GET_PROP_TYPE(TypeTag, SolidSystem); + using SST = typename GET_PROP_TYPE(TypeTag, SolidState); using MT = typename GET_PROP_TYPE(TypeTag, ModelTraits); using PT = typename GET_PROP_TYPE(TypeTag, SpatialParams)::PermeabilityType; - using Traits = OnePVolumeVariablesTraits<PV, FSY, FST, PT, MT>; + using Traits = OnePVolumeVariablesTraits<PV, FSY, FST, SSY, SST, PT, MT>; public: using type = OnePVolumeVariables<Traits>; }; @@ -143,6 +152,24 @@ public: using type = ImmiscibleFluidState<Scalar, FluidSystem>; }; +//! The two-phase model uses the immiscible fluid state +SET_PROP(OneP, SolidState) +{ +private: + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using SolidSystem = typename GET_PROP_TYPE(TypeTag, SolidSystem); +public: + using type = InertSolidState<Scalar, SolidSystem>; +}; + +// Set the fluid system +SET_PROP(OneP, SolidSystem) +{ + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using InertComponent = Components::Constant<1, Scalar>; + using type = SolidSystems::InertSolidPhase<Scalar, InertComponent>; +}; + /////////////////////////////////////////////////////////////////////////// // properties for the non-isothermal single phase model /////////////////////////////////////////////////////////////////////////// diff --git a/dumux/porousmediumflow/1p/volumevariables.hh b/dumux/porousmediumflow/1p/volumevariables.hh index 2b3b51573f61c0dd6731acc0cc2149fbf1566eb1..fef4a9bb25caecb246d0164ffff3f4401bceccce 100644 --- a/dumux/porousmediumflow/1p/volumevariables.hh +++ b/dumux/porousmediumflow/1p/volumevariables.hh @@ -26,6 +26,7 @@ #include <dumux/common/properties.hh> #include <dumux/porousmediumflow/volumevariables.hh> +#include <dumux/porousmediumflow/nonisothermal/volumevariables.hh> #include <dumux/material/fluidstates/immiscible.hh> namespace Dumux { @@ -38,20 +39,26 @@ namespace Dumux { * \tparam Traits Class encapsulating types to be used by the vol vars */ template<class Traits> -class OnePVolumeVariables : public PorousMediumFlowVolumeVariables< Traits, OnePVolumeVariables<Traits> > +class OnePVolumeVariables +: public PorousMediumFlowVolumeVariables< Traits> +, public EnergyVolumeVariables<Traits, OnePVolumeVariables<Traits> > { using ThisType = OnePVolumeVariables<Traits>; - using ParentType = PorousMediumFlowVolumeVariables<Traits, ThisType>; + using ParentType = PorousMediumFlowVolumeVariables<Traits>; + using EnergyVolVars = EnergyVolumeVariables<Traits, OnePVolumeVariables<Traits> >; using Scalar = typename Traits::PrimaryVariables::value_type; using Indices = typename Traits::ModelTraits::Indices; using PermeabilityType = typename Traits::PermeabilityType; - + static constexpr int numComp = ParentType::numComponents(); public: //! export the underlying fluid system using FluidSystem = typename Traits::FluidSystem; //! export the fluid state type using FluidState = typename Traits::FluidState; + //! export type of solid state + using SolidState = typename Traits::SolidState; + using SolidSystem = typename Traits::SolidSystem; /*! * \brief Update all quantities for a given control volume @@ -70,9 +77,12 @@ public: { ParentType::update(elemSol, problem, element, scv); - completeFluidState(elemSol, problem, element, scv, fluidState_); - // porosity - porosity_ = problem.spatialParams().porosity(element, scv, elemSol); + // porosity + completeFluidState(elemSol, problem, element, scv, fluidState_, solidState_); + + // porosity and permeability + updateSolidVolumeFractions(elemSol, problem, element, scv, solidState_, numComp); + EnergyVolVars::updateSolidEnergyParams(elemSol, problem, element, scv, solidState_); permeability_ = problem.spatialParams().permeability(element, scv, elemSol); }; @@ -87,15 +97,14 @@ public: * \param fluidState A container with the current (physical) state of the fluid */ template<class ElemSol, class Problem, class Element, class Scv> - static void completeFluidState(const ElemSol &elemSol, - const Problem& problem, - const Element& element, - const Scv& scv, - FluidState& fluidState) + void completeFluidState(const ElemSol &elemSol, + const Problem& problem, + const Element& element, + const Scv& scv, + FluidState& fluidState, + SolidState& solidState) { - Scalar t = ParentType::temperature(elemSol, problem, element, scv); - - fluidState.setTemperature(t); + EnergyVolVars::updateTemperature(elemSol, problem, element, scv, fluidState, solidState); fluidState.setSaturation(/*phaseIdx=*/0, 1.); const auto& priVars = ParentType::extractDofPriVars(elemSol, scv); @@ -116,7 +125,7 @@ public: fluidState.setViscosity(/*phaseIdx=*/0, value); // compute and set the enthalpy - value = ParentType::enthalpy(fluidState, paramCache, /*phaseIdx=*/0); + value = EnergyVolVars::enthalpy(fluidState, paramCache, /*phaseIdx=*/0); fluidState.setEnthalpy(/*phaseIdx=*/0, value); } @@ -130,6 +139,12 @@ public: Scalar temperature() const { return fluidState_.temperature(); } + /*! + * \brief Returns the phase state for the control volume. + */ + const SolidState &solidState() const + { return solidState_; } + /*! * \brief Return the effective pressure \f$\mathrm{[Pa]}\f$ of a given phase within * the control volume. @@ -173,7 +188,7 @@ public: * \brief Return the average porosity \f$\mathrm{[-]}\f$ within the control volume. */ Scalar porosity() const - { return porosity_; } + { return solidState_.porosity();; } /*! * \brief Returns the permeability within the control volume in \f$[m^2]\f$. @@ -189,7 +204,7 @@ public: protected: FluidState fluidState_; - Scalar porosity_; + SolidState solidState_; PermeabilityType permeability_; }; diff --git a/dumux/porousmediumflow/1pnc/model.hh b/dumux/porousmediumflow/1pnc/model.hh index 1710578a1853e8d770c11f1d0f09a5187eaa7785..a676beca99ba1b0b644adac4168c2a5da0dfa925 100644 --- a/dumux/porousmediumflow/1pnc/model.hh +++ b/dumux/porousmediumflow/1pnc/model.hh @@ -61,6 +61,9 @@ #include <dumux/material/fluidmatrixinteractions/1p/thermalconductivityaverage.hh> #include <dumux/material/fluidstates/compositional.hh> +#include <dumux/material/solidstates/inertsolidstate.hh> +#include <dumux/material/solidsystems/inertsolidphase.hh> +#include <dumux/material/components/constant.hh> #include <dumux/porousmediumflow/properties.hh> #include <dumux/porousmediumflow/1p/model.hh> @@ -108,12 +111,14 @@ struct OnePNCModelTraits * \tparam PT The type used for permeabilities * \tparam MT The model traits */ -template<class PV, class FSY, class FST, class PT, class MT> +template<class PV, class FSY, class FST, class SSY, class SST, class PT, class MT> struct OnePNCVolumeVariablesTraits { using PrimaryVariables = PV; using FluidSystem = FSY; using FluidState = FST; + using SolidSystem = SSY; + using SolidState = SST; using PermeabilityType = PT; using ModelTraits = MT; }; @@ -159,6 +164,25 @@ public: using type = CompositionalFluidState<Scalar, FluidSystem>; }; +//! The two-phase model uses the immiscible fluid state +SET_PROP(OnePNC, SolidState) +{ +private: + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using SolidSystem = typename GET_PROP_TYPE(TypeTag, SolidSystem); +public: + using type = InertSolidState<Scalar, SolidSystem>; +}; + +// Set the fluid system +SET_PROP(OnePNC, SolidSystem) +{ + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using InertComponent = Components::Constant<1, Scalar>; + using type = SolidSystems::InertSolidPhase<Scalar, InertComponent>; +}; + + //! Use the model after Millington (1961) for the effective diffusivity SET_TYPE_PROP(OnePNC, EffectiveDiffusivityModel, DiffusivityMillingtonQuirk<typename GET_PROP_TYPE(TypeTag, Scalar)>); @@ -173,12 +197,14 @@ private: using PV = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); using FSY = typename GET_PROP_TYPE(TypeTag, FluidSystem); using FST = typename GET_PROP_TYPE(TypeTag, FluidState); + using SSY = typename GET_PROP_TYPE(TypeTag, SolidSystem); + using SST = typename GET_PROP_TYPE(TypeTag, SolidState); using MT = typename GET_PROP_TYPE(TypeTag, ModelTraits); using PT = typename GET_PROP_TYPE(TypeTag, SpatialParams)::PermeabilityType; static_assert(FSY::numComponents == MT::numComponents(), "Number of components mismatch between model and fluid system"); static_assert(FST::numComponents == MT::numComponents(), "Number of components mismatch between model and fluid state"); - using Traits = OnePNCVolumeVariablesTraits<PV, FSY, FST, PT, MT>; + using Traits = OnePNCVolumeVariablesTraits<PV, FSY, FST, SSY, SST, PT, MT>; public: using type = OnePNCVolumeVariables<Traits>; }; diff --git a/dumux/porousmediumflow/1pnc/volumevariables.hh b/dumux/porousmediumflow/1pnc/volumevariables.hh index 5a1f33dbb8dc35d98efc73928f4884357dd5a838..7583287190bceee7db075429244e6a1ac5d62b1d 100644 --- a/dumux/porousmediumflow/1pnc/volumevariables.hh +++ b/dumux/porousmediumflow/1pnc/volumevariables.hh @@ -28,6 +28,7 @@ #include <dune/common/fvector.hh> #include <dumux/porousmediumflow/volumevariables.hh> +#include <dumux/porousmediumflow/nonisothermal/volumevariables.hh> namespace Dumux { @@ -42,10 +43,11 @@ namespace Dumux { */ template <class Traits> class OnePNCVolumeVariables -: public PorousMediumFlowVolumeVariables<Traits, OnePNCVolumeVariables<Traits>> +: public PorousMediumFlowVolumeVariables<Traits> + ,public EnergyVolumeVariables<Traits, OnePNCVolumeVariables<Traits> > { - using ParentType = PorousMediumFlowVolumeVariables<Traits, OnePNCVolumeVariables<Traits>>; - + using ParentType = PorousMediumFlowVolumeVariables<Traits>; + using EnergyVolVars = EnergyVolumeVariables<Traits, OnePNCVolumeVariables<Traits> >; using Scalar = typename Traits::PrimaryVariables::value_type; using PermeabilityType = typename Traits::PermeabilityType; using Idx = typename Traits::ModelTraits::Indices; @@ -69,6 +71,9 @@ public: using FluidSystem = typename Traits::FluidSystem; //! export indices using Indices = typename Traits::ModelTraits::Indices; + //! export type of solid state + using SolidState = typename Traits::SolidState; + using SolidSystem = typename Traits::SolidSystem; /*! * \brief Update all quantities for a given control volume @@ -87,9 +92,15 @@ public: { ParentType::update(elemSol, problem, element, scv); - completeFluidState(elemSol, problem, element, scv, fluidState_); + completeFluidState(elemSol, problem, element, scv, fluidState_, solidState_); + + // calculate the remaining quantities + updateSolidVolumeFractions(elemSol, problem, element, scv, solidState_, numComp); + EnergyVolVars::updateSolidEnergyParams(elemSol, problem, element, scv, solidState_); + + Scalar minPorosity = problem.spatialParams().minimalPorosity(element, scv); + solidState_.setMinPorosity(minPorosity); - porosity_ = problem.spatialParams().porosity(element, scv, elemSol); permeability_ = problem.spatialParams().permeability(element, scv, elemSol); // Second instance of a parameter cache. @@ -123,16 +134,16 @@ public: * \param fluidState A container with the current (physical) state of the fluid */ template<class ElemSol, class Problem, class Element, class Scv> - static void completeFluidState(const ElemSol &elemSol, - const Problem& problem, - const Element& element, - const Scv &scv, - FluidState& fluidState) + void completeFluidState(const ElemSol &elemSol, + const Problem& problem, + const Element& element, + const Scv &scv, + FluidState& fluidState, + SolidState& solidState) { - Scalar t = ParentType::temperature(elemSol, problem, element, scv); - fluidState.setTemperature(t); - fluidState.setSaturation(fluidSystemPhaseIdx, 1.0); + EnergyVolVars::updateTemperature(elemSol, problem, element, scv, fluidState, solidState); + fluidState.setSaturation(fluidSystemPhaseIdx, 1.); const auto& priVars = ParentType::extractDofPriVars(elemSol, scv); fluidState.setPressure(fluidSystemPhaseIdx, priVars[pressureIdx]); @@ -167,7 +178,7 @@ public: fluidState.setViscosity(fluidSystemPhaseIdx, mu); // compute and set the enthalpy - Scalar h = ParentType::enthalpy(fluidState, paramCache, fluidSystemPhaseIdx); + Scalar h = EnergyVolVars::enthalpy(fluidState, paramCache, fluidSystemPhaseIdx); fluidState.setEnthalpy(fluidSystemPhaseIdx, h); } @@ -178,6 +189,12 @@ public: const FluidState &fluidState() const { return fluidState_; } + /*! + * \brief Returns the phase state for the control volume. + */ + const SolidState &solidState() const + { return solidState_; } + /*! * \brief Return density \f$\mathrm{[kg/m^3]}\f$ the of the fluid phase. * @@ -295,7 +312,7 @@ public: * \brief Return the average porosity \f$\mathrm{[-]}\f$ within the control volume. */ Scalar porosity() const - { return porosity_; } + { return solidState_.porosity(); } /*! * \brief Return the binary diffusion coefficient \f$\mathrm{[m^2/s]}\f$ in the fluid. @@ -336,6 +353,7 @@ public: protected: FluidState fluidState_; + SolidState solidState_; private: Scalar porosity_; //!< Effective porosity within the control volume diff --git a/dumux/porousmediumflow/1pncmin/model.hh b/dumux/porousmediumflow/1pncmin/model.hh index f484bc3c833b97bc67a9a416cf4c1b578c1ac284..4e639896a30b34f02380d84c5831e800eda9e492 100644 --- a/dumux/porousmediumflow/1pncmin/model.hh +++ b/dumux/porousmediumflow/1pncmin/model.hh @@ -71,6 +71,8 @@ v = - \frac{k_{r}}{\mu} \mbox{\bf K} #include <dumux/porousmediumflow/1pnc/indices.hh> #include <dumux/porousmediumflow/1pnc/volumevariables.hh> +#include <dumux/material/solidstates/compositionalsolidstate.hh> + #include <dumux/porousmediumflow/mineralization/model.hh> #include <dumux/porousmediumflow/mineralization/localresidual.hh> #include <dumux/porousmediumflow/mineralization/volumevariables.hh> @@ -101,10 +103,12 @@ private: using PV = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); using FSY = typename GET_PROP_TYPE(TypeTag, FluidSystem); using FST = typename GET_PROP_TYPE(TypeTag, FluidState); + using SSY = typename GET_PROP_TYPE(TypeTag, SolidSystem); + using SST = typename GET_PROP_TYPE(TypeTag, SolidState); using MT = typename GET_PROP_TYPE(TypeTag, ModelTraits); using PT = typename GET_PROP_TYPE(TypeTag, SpatialParams)::PermeabilityType; - using Traits = OnePNCVolumeVariablesTraits<PV, FSY, FST, PT, MT>; + using Traits = OnePNCVolumeVariablesTraits<PV, FSY, FST, SSY, SST, PT, MT>; using NonMinVolVars = OnePNCVolumeVariables<Traits>; public: using type = MineralizationVolumeVariables<Traits, NonMinVolVars>; @@ -118,9 +122,20 @@ SET_PROP(OnePNCMin, ModelTraits) { private: using FluidSystem = typename GET_PROP_TYPE(TypeTag, PTAG(FluidSystem)); + using SolidSystem = typename GET_PROP_TYPE(TypeTag, PTAG(SolidSystem)); using NonMinTraits = OnePNCModelTraits<FluidSystem::numComponents, GET_PROP_VALUE(TypeTag, PhaseIdx)>; public: - using type = MineralizationModelTraits<NonMinTraits, FluidSystem::numSPhases>; + using type = MineralizationModelTraits<NonMinTraits, SolidSystem::numComponents, SolidSystem::numInertComponents>; +}; + +//! The two-phase model uses the immiscible fluid state +SET_PROP(OnePNCMin, SolidState) +{ +private: + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using SolidSystem = typename GET_PROP_TYPE(TypeTag, SolidSystem); +public: + using type = CompositionalSolidState<Scalar, SolidSystem>; }; //! Use the mineralization vtk output fields @@ -130,6 +145,7 @@ SET_TYPE_PROP(OnePNCMin, VtkOutputFields, MineralizationVtkOutputFields<OnePNCVt // Properties for the non-isothermal 2pncmin model ////////////////////////////////////////////////////////////////// +//! non-isothermal vtk output //! non-isothermal vtk output SET_TYPE_PROP(OnePNCMinNI, VtkOutputFields, EnergyVtkOutputFields<MineralizationVtkOutputFields<OnePNCVtkOutputFields>>); @@ -138,8 +154,9 @@ SET_PROP(OnePNCMinNI, ModelTraits) { private: using FluidSystem = typename GET_PROP_TYPE(TypeTag, PTAG(FluidSystem)); + using SolidSystem = typename GET_PROP_TYPE(TypeTag, PTAG(SolidSystem)); using OnePNCTraits = OnePNCModelTraits<FluidSystem::numComponents, GET_PROP_VALUE(TypeTag, PhaseIdx)>; - using IsothermalTraits = MineralizationModelTraits<OnePNCTraits, FluidSystem::numSPhases>; + using IsothermalTraits = MineralizationModelTraits<OnePNCTraits, SolidSystem::numComponents, SolidSystem::numInertComponents>; public: using type = PorousMediumFlowNIModelTraits<IsothermalTraits>; }; diff --git a/dumux/porousmediumflow/2p/model.hh b/dumux/porousmediumflow/2p/model.hh index b34f4b06b32e559963a93a7cbcfcdf96d147b242..e5bd1f8f95ffe555fa1dacf9b607f3ee2bd64ece 100644 --- a/dumux/porousmediumflow/2p/model.hh +++ b/dumux/porousmediumflow/2p/model.hh @@ -62,7 +62,10 @@ #include <dumux/material/fluidmatrixinteractions/2p/thermalconductivitysomerton.hh> #include <dumux/material/fluidstates/immiscible.hh> +#include <dumux/material/solidstates/inertsolidstate.hh> #include <dumux/material/spatialparams/fv.hh> +#include <dumux/material/solidsystems/inertsolidphase.hh> +#include <dumux/material/components/constant.hh> #include <dumux/porousmediumflow/properties.hh> #include <dumux/porousmediumflow/1p/model.hh> @@ -107,17 +110,21 @@ struct TwoPModelTraits * \tparam PV The type used for primary variables * \tparam FSY The fluid system type * \tparam FST The fluid state type + * \tparam SSY The solid system type + * \tparam SST The solid state type * \tparam PT The type used for permeabilities * \tparam MT The model traits * \tparam SR The class used for reconstruction of * non-wetting phase saturations in scvs */ -template<class PV, class FSY, class FST, class PT, class MT, class SR> +template<class PV, class FSY, class FST,class SSY, class SST, class PT, class MT, class SR> struct TwoPVolumeVariablesTraits { using PrimaryVariables = PV; using FluidSystem = FSY; using FluidState = FST; + using SolidSystem = SSY; + using SolidState = SST; using PermeabilityType = PT; using ModelTraits = MT; using SaturationReconstruction = SR; @@ -160,6 +167,8 @@ private: using PV = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); using FSY = typename GET_PROP_TYPE(TypeTag, FluidSystem); using FST = typename GET_PROP_TYPE(TypeTag, FluidState); + using SSY = typename GET_PROP_TYPE(TypeTag, SolidSystem); + using SST = typename GET_PROP_TYPE(TypeTag, SolidState); using MT = typename GET_PROP_TYPE(TypeTag, ModelTraits); using PT = typename GET_PROP_TYPE(TypeTag, SpatialParams)::PermeabilityType; @@ -168,11 +177,17 @@ private: // class used for scv-wise reconstruction of non-wetting phase saturations using SR = TwoPScvSaturationReconstruction<DM, enableIS>; - using Traits = TwoPVolumeVariablesTraits<PV, FSY, FST, PT, MT, SR>; + using Traits = TwoPVolumeVariablesTraits<PV, FSY, FST, SSY, SST, PT, MT, SR>; public: using type = TwoPVolumeVariables<Traits>; }; +//! The indices required by the isothermal 2p model +// SET_PROP(TwoP, Indices) +// { +// using type = TwoPIndices<GET_PROP_VALUE(TypeTag, Formulation)>; +// }; + //! The two-phase model uses the immiscible fluid state SET_PROP(TwoP, FluidState) { @@ -183,6 +198,24 @@ public: using type = ImmiscibleFluidState<Scalar, FluidSystem>; }; +//! The two-phase model uses the immiscible fluid state +SET_PROP(TwoP, SolidState) +{ +private: + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using SolidSystem = typename GET_PROP_TYPE(TypeTag, SolidSystem); +public: + using type = InertSolidState<Scalar, SolidSystem>; +}; + +// Set the fluid system +SET_PROP(TwoP, SolidSystem) +{ + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using InertComponent = Components::Constant<1,Scalar>; + using type = SolidSystems::InertSolidPhase<Scalar, InertComponent>; +}; + //////////////////////////////////////////////////////// // properties for the non-isothermal two-phase model //////////////////////////////////////////////////////// diff --git a/dumux/porousmediumflow/2p/volumevariables.hh b/dumux/porousmediumflow/2p/volumevariables.hh index f24e5fdaa94250364b93e70bc8fdda50d2272763..1d28839c556d85a74e073f4aacc910ed9ed86c8f 100644 --- a/dumux/porousmediumflow/2p/volumevariables.hh +++ b/dumux/porousmediumflow/2p/volumevariables.hh @@ -26,6 +26,8 @@ #define DUMUX_2P_VOLUME_VARIABLES_HH #include <dumux/porousmediumflow/volumevariables.hh> +#include <dumux/porousmediumflow/nonisothermal/volumevariables.hh> + #include "indices.hh" namespace Dumux { @@ -37,16 +39,17 @@ namespace Dumux { */ template <class Traits> class TwoPVolumeVariables -: public PorousMediumFlowVolumeVariables<Traits, TwoPVolumeVariables<Traits> > +: public PorousMediumFlowVolumeVariables<Traits> + ,public EnergyVolumeVariables<Traits, TwoPVolumeVariables<Traits> > { - using ParentType = PorousMediumFlowVolumeVariables<Traits, TwoPVolumeVariables<Traits> >; - + using ParentType = PorousMediumFlowVolumeVariables<Traits>; + using EnergyVolVars = EnergyVolumeVariables<Traits, TwoPVolumeVariables<Traits> >; using PermeabilityType = typename Traits::PermeabilityType; using ModelTraits = typename Traits::ModelTraits; using Indices = typename ModelTraits::Indices; using Scalar = typename Traits::PrimaryVariables::value_type; using FS = typename Traits::FluidSystem; - + static constexpr int numComp = ParentType::numComponents(); enum { pressureIdx = Indices::pressureIdx, @@ -63,6 +66,10 @@ public: using FluidSystem = typename Traits::FluidSystem; //! export type of fluid state using FluidState = typename Traits::FluidState; + //! export type of solid state + using SolidState = typename Traits::SolidState; + //! export type of solid system + using SolidSystem = typename Traits::SolidSystem; /*! * \brief Update all quantities for a given control volume @@ -81,7 +88,7 @@ public: { ParentType::update(elemSol, problem, element, scv); - completeFluidState(elemSol, problem, element, scv, fluidState_); + completeFluidState(elemSol, problem, element, scv, fluidState_, solidState_); using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; const auto& materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol); @@ -97,11 +104,13 @@ public: MaterialLaw::krn(materialParams, fluidState_.saturation(wPhaseIdx)) / fluidState_.viscosity(nPhaseIdx); - // porosity - porosity_ = problem.spatialParams().porosity(element, scv, elemSol); + // porosity calculation over inert volumefraction + updateSolidVolumeFractions(elemSol, problem, element, scv, solidState_, numComp); + EnergyVolVars::updateSolidEnergyParams(elemSol, problem, element, scv, solidState_); + Scalar minPorosity = problem.spatialParams().minimalPorosity(element, scv); + solidState_.setMinPorosity(minPorosity); permeability_ = problem.spatialParams().permeability(element, scv, elemSol); - - } + } /*! * \brief Complete the fluid state @@ -119,10 +128,10 @@ public: const Problem& problem, const Element& element, const Scv& scv, - FluidState& fluidState) + FluidState& fluidState, + SolidState& solidState) { - Scalar t = ParentType::temperature(elemSol, problem, element, scv); - fluidState.setTemperature(t); + EnergyVolVars::updateTemperature(elemSol, problem, element, scv, fluidState, solidState); using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; const auto& materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol); @@ -183,7 +192,7 @@ public: fluidState.setDensity(phaseIdx, rho); // compute and set the enthalpy - Scalar h = ParentType::enthalpy(fluidState, paramCache, phaseIdx); + Scalar h = EnergyVolVars::enthalpy(fluidState, paramCache, phaseIdx); fluidState.setEnthalpy(phaseIdx, h); } } @@ -194,6 +203,12 @@ public: const FluidState &fluidState() const { return fluidState_; } + /*! + * \brief Returns the phase state for the control volume. + */ + const SolidState &solidState() const + { return solidState_; } + /*! * \brief Returns the saturation of a given phase within * the control volume in \f$[-]\f$. @@ -261,7 +276,7 @@ public: * \brief Returns the average porosity within the control volume in \f$[-]\f$. */ Scalar porosity() const - { return porosity_; } + { return solidState_.porosity(); } /*! * \brief Returns the permeability within the control volume in \f$[m^2]\f$. @@ -271,6 +286,7 @@ public: protected: FluidState fluidState_; + SolidState solidState_; private: Scalar pc_; diff --git a/dumux/porousmediumflow/2p1c/model.hh b/dumux/porousmediumflow/2p1c/model.hh index 281a0a28e7312451995a8a8f760a2ec9eefbef66..1a5bb199c8648b1cc708ea41d6d9272fb9e34d80 100644 --- a/dumux/porousmediumflow/2p1c/model.hh +++ b/dumux/porousmediumflow/2p1c/model.hh @@ -63,6 +63,10 @@ #include <dumux/material/fluidmatrixinteractions/2p/thermalconductivitysomerton.hh> #include <dumux/material/fluidstates/compositional.hh> +#include <dumux/material/solidstates/inertsolidstate.hh> +#include <dumux/material/spatialparams/fv.hh> +#include <dumux/material/solidsystems/inertsolidphase.hh> +#include <dumux/material/components/constant.hh> #include <dumux/porousmediumflow/properties.hh> #include <dumux/porousmediumflow/compositional/switchableprimaryvariables.hh> @@ -107,12 +111,14 @@ struct TwoPOneCModelTraits * \tparam PT The type used for permeabilities * \tparam MT The model traits */ -template<class PV, class FSY, class FST, class PT, class MT> +template<class PV, class FSY, class FST, class SSY, class SST, class PT, class MT> struct TwoPOneCVolumeVariablesTraits { using PrimaryVariables = PV; using FluidSystem = FSY; using FluidState = FST; + using SolidSystem = SSY; + using SolidState = SST; using PermeabilityType = PT; using ModelTraits = MT; }; @@ -143,6 +149,24 @@ public: using type = CompositionalFluidState<Scalar, FluidSystem>; }; +//! The two-phase model uses the inert solid state +SET_PROP(TwoPOneCNI, SolidState) +{ +private: + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using SolidSystem = typename GET_PROP_TYPE(TypeTag, SolidSystem); +public: + using type = InertSolidState<Scalar, SolidSystem>; +}; + +// Set the solid system +SET_PROP(TwoPOneCNI, SolidSystem) +{ + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using InertComponent = Components::Constant<1, Scalar>; + using type = SolidSystems::InertSolidPhase<Scalar, InertComponent>; +}; + //! Do not block spurious flows by default. SET_BOOL_PROP(TwoPOneCNI, UseBlockingOfSpuriousFlow, false); @@ -159,10 +183,12 @@ private: using PV = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); using FSY = typename GET_PROP_TYPE(TypeTag, FluidSystem); using FST = typename GET_PROP_TYPE(TypeTag, FluidState); + using SSY = typename GET_PROP_TYPE(TypeTag, SolidSystem); + using SST = typename GET_PROP_TYPE(TypeTag, SolidState); using MT = typename GET_PROP_TYPE(TypeTag, ModelTraits); using PT = typename GET_PROP_TYPE(TypeTag, SpatialParams)::PermeabilityType; - using Traits = TwoPOneCVolumeVariablesTraits<PV, FSY, FST, PT, MT>; + using Traits = TwoPOneCVolumeVariablesTraits<PV, FSY, FST, SSY, SST, PT, MT>; public: using type = TwoPOneCVolumeVariables<Traits>; }; diff --git a/dumux/porousmediumflow/2p1c/volumevariables.hh b/dumux/porousmediumflow/2p1c/volumevariables.hh index c75c929a3db3f5711c39b86125d43dcda0507945..01c8b2ce8d621a0dda1b128944f98d0ce492701b 100644 --- a/dumux/porousmediumflow/2p1c/volumevariables.hh +++ b/dumux/porousmediumflow/2p1c/volumevariables.hh @@ -28,6 +28,7 @@ #include <dumux/common/valgrind.hh> #include <dumux/porousmediumflow/volumevariables.hh> +#include <dumux/porousmediumflow/nonisothermal/volumevariables.hh> namespace Dumux { @@ -37,13 +38,16 @@ namespace Dumux { */ template <class Traits> class TwoPOneCVolumeVariables -: public PorousMediumFlowVolumeVariables<Traits, TwoPOneCVolumeVariables<Traits>> +: public PorousMediumFlowVolumeVariables<Traits> + ,public EnergyVolumeVariables<Traits, TwoPOneCVolumeVariables<Traits> > { - using ParentType = PorousMediumFlowVolumeVariables<Traits, TwoPOneCVolumeVariables<Traits>>; + using ParentType = PorousMediumFlowVolumeVariables<Traits>; + using EnergyVolVars = EnergyVolumeVariables<Traits, TwoPOneCVolumeVariables<Traits> >; using Scalar = typename Traits::PrimaryVariables::value_type; using PermeabilityType = typename Traits::PermeabilityType; using FS = typename Traits::FluidSystem; using Idx = typename Traits::ModelTraits::Indices; + static constexpr int numComp = ParentType::numComponents(); enum { numPhases = Traits::ModelTraits::numPhases(), @@ -65,6 +69,10 @@ public: using FluidSystem = typename Traits::FluidSystem; //! The type of the indices using Indices = typename Traits::ModelTraits::Indices; + //! export type of solid state + using SolidState = typename Traits::SolidState; + //! export type of solid system + using SolidSystem = typename Traits::SolidSystem; // set liquid phase as wetting phase: TODO make this more flexible static constexpr int wPhaseIdx = FluidSystem::liquidPhaseIdx; @@ -88,7 +96,7 @@ public: { ParentType::update(elemSol, problem, element, scv); - completeFluidState(elemSol, problem, element, scv, fluidState_); + completeFluidState(elemSol, problem, element, scv, fluidState_, solidState_); ///////////// // calculate the remaining quantities @@ -115,7 +123,9 @@ public: } // porosity & permeability - porosity_ = problem.spatialParams().porosity(element, scv, elemSol); + // porosity calculation over inert volumefraction + updateSolidVolumeFractions(elemSol, problem, element, scv, solidState_, numComp); + EnergyVolVars::updateSolidEnergyParams(elemSol, problem, element, scv, solidState_); permeability_ = problem.spatialParams().permeability(element, scv, elemSol); } @@ -125,7 +135,8 @@ public: const Problem& problem, const Element& element, const Scv& scv, - FluidState& fluidState) + FluidState& fluidState, + SolidState& solidState) { // capillary pressure parameters @@ -183,7 +194,11 @@ public: Valgrind::CheckDefined(temperature); - fluidState.setTemperature(temperature); + for(int phaseIdx=0; phaseIdx < FluidSystem::numPhases; ++phaseIdx) + { + fluidState.setTemperature(phaseIdx, temperature); + } + solidState.setTemperature(temperature); // set the densities const Scalar rhoW = FluidSystem::density(fluidState, wPhaseIdx); @@ -216,6 +231,13 @@ public: const FluidState &fluidState() const { return fluidState_; } + /*! + * \brief Returns the phase state for the control volume. + */ + const SolidState &solidState() const + { return solidState_; } + + /*! * \brief Returns the effective saturation of a given phase within * the control volume. @@ -284,7 +306,7 @@ public: * \brief Returns the average porosity within the control volume. */ Scalar porosity() const - { return porosity_; } + { return solidState_.porosity(); } /*! * \brief Returns the average permeability within the control volume in \f$[m^2]\f$. @@ -300,9 +322,9 @@ public: protected: FluidState fluidState_; + SolidState solidState_; private: - Scalar porosity_; //!< Effective porosity within the control volume PermeabilityType permeability_; //!> Effective permeability within the control volume std::array<Scalar, numPhases> relativePermeability_; }; diff --git a/dumux/porousmediumflow/2p2c/model.hh b/dumux/porousmediumflow/2p2c/model.hh index b5ec3eef8a3f228d194b2c9f6ba5cf22d1591ef6..d1478992e1a3ca5810f798e937584987dd6e0b8e 100644 --- a/dumux/porousmediumflow/2p2c/model.hh +++ b/dumux/porousmediumflow/2p2c/model.hh @@ -90,6 +90,9 @@ #include <dumux/material/spatialparams/fv.hh> #include <dumux/material/fluidmatrixinteractions/2p/thermalconductivitysomerton.hh> #include <dumux/material/fluidmatrixinteractions/diffusivitymillingtonquirk.hh> +#include <dumux/material/solidstates/inertsolidstate.hh> +#include <dumux/material/solidsystems/inertsolidphase.hh> +#include <dumux/material/components/constant.hh> #include <dumux/porousmediumflow/compositional/localresidual.hh> #include <dumux/porousmediumflow/compositional/switchableprimaryvariables.hh> @@ -136,12 +139,14 @@ struct TwoPTwoCModelTraits * \tparam MT The model traits * \tparam useCS boolean to indicate if a constraint solver is to be used */ -template<class PV, class FSY, class FST, class PT, class MT, bool useCS> +template<class PV, class FSY, class FST, class SSY, class SST, class PT, class MT, bool useCS> struct TwoPTwoCVolumeVariablesTraits { using PrimaryVariables = PV; using FluidSystem = FSY; using FluidState = FST; + using SolidSystem = SSY; + using SolidState = SST; using PermeabilityType = PT; using ModelTraits = MT; @@ -197,6 +202,24 @@ public: SET_PROP(TwoPTwoC, Formulation) { static constexpr TwoPFormulation value = TwoPFormulation::p0s1; }; +//! The two-phase model uses the inert solid state +SET_PROP(TwoPTwoC, SolidState) +{ +private: + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using SolidSystem = typename GET_PROP_TYPE(TypeTag, SolidSystem); +public: + using type = InertSolidState<Scalar, SolidSystem>; +}; + +// Set the solid system +SET_PROP(TwoPTwoC, SolidSystem) +{ + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using InertComponent = Components::Constant<1,Scalar>; + using type = SolidSystems::InertSolidPhase<Scalar, InertComponent>; +}; + //! Set as default that no component mass balance is replaced by the total mass balance SET_INT_PROP(TwoPTwoC, ReplaceCompEqIdx, GET_PROP_TYPE(TypeTag, ModelTraits)::numComponents()); @@ -223,12 +246,14 @@ private: using PV = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); using FSY = typename GET_PROP_TYPE(TypeTag, FluidSystem); using FST = typename GET_PROP_TYPE(TypeTag, FluidState); + using SSY = typename GET_PROP_TYPE(TypeTag, SolidSystem); + using SST = typename GET_PROP_TYPE(TypeTag, SolidState); using MT = typename GET_PROP_TYPE(TypeTag, ModelTraits); using PT = typename GET_PROP_TYPE(TypeTag, SpatialParams)::PermeabilityType; static constexpr bool useCS = GET_PROP_VALUE(TypeTag, UseConstraintSolver); - using Traits = TwoPTwoCVolumeVariablesTraits<PV, FSY, FST, PT, MT, useCS>; + using Traits = TwoPTwoCVolumeVariablesTraits<PV, FSY, FST, SSY, SST, PT, MT, useCS>; public: using type = TwoPTwoCVolumeVariables<Traits>; }; diff --git a/dumux/porousmediumflow/2p2c/volumevariables.hh b/dumux/porousmediumflow/2p2c/volumevariables.hh index 649b6fb68549865fb2fabd11010bac87580028aa..82806c08809c35e35ad23029678553aaadf17c42 100644 --- a/dumux/porousmediumflow/2p2c/volumevariables.hh +++ b/dumux/porousmediumflow/2p2c/volumevariables.hh @@ -31,6 +31,7 @@ #include <dumux/discretization/methods.hh> #include <dumux/porousmediumflow/volumevariables.hh> +#include <dumux/porousmediumflow/nonisothermal/volumevariables.hh> #include <dumux/porousmediumflow/2p/formulation.hh> namespace Dumux { @@ -42,13 +43,16 @@ namespace Dumux { */ template <class Traits> class TwoPTwoCVolumeVariables -: public PorousMediumFlowVolumeVariables< Traits, TwoPTwoCVolumeVariables<Traits> > +: public PorousMediumFlowVolumeVariables<Traits> + ,public EnergyVolumeVariables<Traits, TwoPTwoCVolumeVariables<Traits> > { - using ParentType = PorousMediumFlowVolumeVariables< Traits, TwoPTwoCVolumeVariables<Traits> >; + using ParentType = PorousMediumFlowVolumeVariables< Traits >; + using EnergyVolVars = EnergyVolumeVariables<Traits, TwoPTwoCVolumeVariables<Traits> >; using Scalar = typename Traits::PrimaryVariables::value_type; using ModelTraits = typename Traits::ModelTraits; + static constexpr int numComp = ParentType::numComponents(); // component indices enum { @@ -87,6 +91,10 @@ public: using FluidState = typename Traits::FluidState; //! The fluid system used here using FluidSystem = typename Traits::FluidSystem; + //! export type of solid state + using SolidState = typename Traits::SolidState; + //! export type of solid system + using SolidSystem = typename Traits::SolidSystem; //! return whether moles or masses are balanced static constexpr bool useMoles() { return ModelTraits::useMoles(); } @@ -117,7 +125,7 @@ public: void update(const ElemSol& elemSol, const Problem& problem, const Element& element, const Scv& scv) { ParentType::update(elemSol, problem, element, scv); - completeFluidState(elemSol, problem, element, scv, fluidState_); + completeFluidState(elemSol, problem, element, scv, fluidState_, solidState_); // Second instance of a parameter cache. Could be avoided if // diffusion coefficients also became part of the fluid state. @@ -139,7 +147,8 @@ public: diffCoeff_[phase1Idx] = FluidSystem::binaryDiffusionCoefficient(fluidState_, paramCache, phase1Idx, comp0Idx, comp1Idx); // porosity & permeabilty - porosity_ = problem.spatialParams().porosity(element, scv, elemSol); + updateSolidVolumeFractions(elemSol, problem, element, scv, solidState_, numComp); + EnergyVolVars::updateSolidEnergyParams(elemSol, problem, element, scv, solidState_); permeability_ = problem.spatialParams().permeability(element, scv, elemSol); } @@ -159,10 +168,10 @@ public: const Problem& problem, const Element& element, const Scv& scv, - FluidState& fluidState) + FluidState& fluidState, + SolidState& solidState) { - const auto t = ParentType::temperature(elemSol, problem, element, scv); - fluidState.setTemperature(t); + EnergyVolVars::updateTemperature(elemSol, problem, element, scv, fluidState, solidState); const auto& priVars = ParentType::extractDofPriVars(elemSol, scv); const auto phasePresence = priVars.state(); @@ -380,7 +389,7 @@ public: } // compute and set the enthalpy - Scalar h = ParentType::enthalpy(fluidState, paramCache, phaseIdx); + Scalar h = EnergyVolVars::enthalpy(fluidState, paramCache, phaseIdx); fluidState.setEnthalpy(phaseIdx, h); } } @@ -391,6 +400,12 @@ public: const FluidState &fluidState() const { return fluidState_; } + /*! + * \brief Returns the phase state for the control-volume. + */ + const SolidState &solidState() const + { return solidState_; } + /*! * \brief Returns the saturation of a given phase within * the control volume in \f$[-]\f$. @@ -495,7 +510,7 @@ public: * \brief Returns the average porosity within the control volume in \f$[-]\f$. */ Scalar porosity() const - { return porosity_; } + { return solidState_.porosity(); } /*! * \brief Returns the average permeability within the control volume in \f$[m^2]\f$. @@ -516,8 +531,9 @@ public: private: FluidState fluidState_; + SolidState solidState_; + Scalar pc_; //!< The capillary pressure - Scalar porosity_; //!< Effective porosity within the control volume PermeabilityType permeability_; //!< Effective permeability within the control volume //!< Relative permeability within the control volume diff --git a/dumux/porousmediumflow/2pnc/model.hh b/dumux/porousmediumflow/2pnc/model.hh index 43c668d1c5f553d2c75747fc8bf9499a642ddce0..761c4b4e93038f9a5dc7a536a221f6564e9d103b 100644 --- a/dumux/porousmediumflow/2pnc/model.hh +++ b/dumux/porousmediumflow/2pnc/model.hh @@ -90,8 +90,11 @@ #include <dumux/common/properties.hh> #include <dumux/material/spatialparams/fv.hh> +#include <dumux/material/solidstates/inertsolidstate.hh> #include <dumux/material/fluidmatrixinteractions/diffusivitymillingtonquirk.hh> #include <dumux/material/fluidmatrixinteractions/2p/thermalconductivitysomerton.hh> +#include <dumux/material/solidsystems/inertsolidphase.hh> +#include <dumux/material/components/constant.hh> #include <dumux/porousmediumflow/properties.hh> #include <dumux/porousmediumflow/compositional/localresidual.hh> @@ -145,12 +148,14 @@ struct TwoPNCModelTraits * \tparam PT The type used for permeabilities * \tparam MT The model traits */ -template<class PV, class FSY, class FST, class PT, class MT> +template<class PV, class FSY, class FST, class SSY, class SST, class PT, class MT> struct TwoPNCVolumeVariablesTraits { using PrimaryVariables = PV; using FluidSystem = FSY; using FluidState = FST; + using SolidSystem = SSY; + using SolidState = SST; using PermeabilityType = PT; using ModelTraits = MT; }; @@ -185,10 +190,12 @@ private: using PV = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); using FSY = typename GET_PROP_TYPE(TypeTag, FluidSystem); using FST = typename GET_PROP_TYPE(TypeTag, FluidState); + using SSY = typename GET_PROP_TYPE(TypeTag, SolidSystem); + using SST = typename GET_PROP_TYPE(TypeTag, SolidState); using MT = typename GET_PROP_TYPE(TypeTag, ModelTraits); using PT = typename GET_PROP_TYPE(TypeTag, SpatialParams)::PermeabilityType; - using Traits = TwoPNCVolumeVariablesTraits<PV, FSY, FST, PT, MT>; + using Traits = TwoPNCVolumeVariablesTraits<PV, FSY, FST, SSY, SST, PT, MT>; public: using type = TwoPNCVolumeVariables<Traits>; }; @@ -234,6 +241,24 @@ public: using type = CompositionalFluidState<Scalar, FluidSystem>; }; +//! The two-phase model uses the immiscible fluid state +SET_PROP(TwoPNC, SolidState) +{ +private: + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using SolidSystem = typename GET_PROP_TYPE(TypeTag, SolidSystem); +public: + using type = InertSolidState<Scalar, SolidSystem>; +}; + +// Set the fluid system +SET_PROP(TwoPNC, SolidSystem) +{ + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using InertComponent = Components::Constant<1, Scalar>; + using type = SolidSystems::InertSolidPhase<Scalar, InertComponent>; +}; + ///////////////////////////////////////////////// // Properties for the non-isothermal 2pnc model ///////////////////////////////////////////////// diff --git a/dumux/porousmediumflow/2pnc/volumevariables.hh b/dumux/porousmediumflow/2pnc/volumevariables.hh index 589067bf5a945369f7d78039457278ba584af30a..1cbff74a396c150853248a73490d3ef1287ec970 100644 --- a/dumux/porousmediumflow/2pnc/volumevariables.hh +++ b/dumux/porousmediumflow/2pnc/volumevariables.hh @@ -32,8 +32,10 @@ #include <dumux/common/properties.hh> #include <dumux/discretization/methods.hh> -#include <dumux/material/fluidstates/compositional.hh> #include <dumux/porousmediumflow/volumevariables.hh> +#include <dumux/porousmediumflow/nonisothermal/volumevariables.hh> + +#include <dumux/material/fluidstates/compositional.hh> #include <dumux/material/constraintsolvers/computefromreferencephase.hh> #include <dumux/material/constraintsolvers/misciblemultiphasecomposition.hh> @@ -48,14 +50,16 @@ namespace Dumux { */ template <class Traits> class TwoPNCVolumeVariables -: public PorousMediumFlowVolumeVariables<Traits, TwoPNCVolumeVariables<Traits>> +: public PorousMediumFlowVolumeVariables<Traits> + ,public EnergyVolumeVariables<Traits, TwoPNCVolumeVariables<Traits> > { - using ParentType = PorousMediumFlowVolumeVariables<Traits, TwoPNCVolumeVariables<Traits>>; + using ParentType = PorousMediumFlowVolumeVariables<Traits>; + using EnergyVolVars = EnergyVolumeVariables<Traits, TwoPNCVolumeVariables<Traits> >; using Scalar = typename Traits::PrimaryVariables::value_type; using PermeabilityType = typename Traits::PermeabilityType; using FS = typename Traits::FluidSystem; using ModelTraits = typename Traits::ModelTraits; - + static constexpr int numComp = ParentType::numComponents(); enum { numMajorComponents = ModelTraits::numPhases(), @@ -84,11 +88,16 @@ class TwoPNCVolumeVariables using MiscibleMultiPhaseComposition = Dumux::MiscibleMultiPhaseComposition<Scalar, FS>; using ComputeFromReferencePhase = Dumux::ComputeFromReferencePhase<Scalar, FS>; + public: //! export fluid state type using FluidState = typename Traits::FluidState; //! export fluid system type using FluidSystem = typename Traits::FluidSystem; + //! export type of solid state + using SolidState = typename Traits::SolidState; + //! export type of solid system + using SolidSystem = typename Traits::SolidSystem; //! return whether moles or masses are balanced static constexpr bool useMoles() { return Traits::ModelTraits::useMoles(); } @@ -116,7 +125,8 @@ public: const Scv& scv) { ParentType::update(elemSol, problem, element, scv); - completeFluidState(elemSol, problem, element, scv, fluidState_); + + completeFluidState(elemSol, problem, element, scv, fluidState_, solidState_); ///////////// // calculate the remaining quantities @@ -156,8 +166,11 @@ public: compJIdx) ); } - // porosity & permeability - porosity_ = problem.spatialParams().porosity(element, scv, elemSol); + // calculate the remaining quantities + updateSolidVolumeFractions(elemSol, problem, element, scv, solidState_, numComp); + EnergyVolVars::updateSolidEnergyParams(elemSol, problem, element, scv, solidState_); + Scalar minPorosity = problem.spatialParams().minimalPorosity(element, scv); + solidState_.setMinPorosity(minPorosity); permeability_ = problem.spatialParams().permeability(element, scv, elemSol); } @@ -177,10 +190,10 @@ public: const Problem& problem, const Element& element, const Scv& scv, - FluidState& fluidState) + FluidState& fluidState, + SolidState& solidState) { - const auto t = ParentType::temperature(elemSol, problem, element, scv); - fluidState.setTemperature(t); + EnergyVolVars::updateTemperature(elemSol, problem, element, scv, fluidState, solidState); const auto& priVars = ParentType::extractDofPriVars(elemSol, scv); const auto phasePresence = priVars.state(); @@ -244,6 +257,7 @@ public: // set the known mole fractions in the fluidState so that they // can be used by the MiscibleMultiPhaseComposition constraint solver + const int knownPhaseIdx = setFirstPhaseMoleFractions ? phase0Idx : phase1Idx; for (int compIdx = numMajorComponents; compIdx < ModelTraits::numComponents(); ++compIdx) fluidState.setMoleFraction(knownPhaseIdx, compIdx, priVars[compIdx]); @@ -256,6 +270,7 @@ public: } else if (phasePresence == secondPhaseOnly) { + Dune::FieldVector<Scalar, ModelTraits::numComponents()> moleFrac; moleFrac[comp0Idx] = priVars[switchIdx]; @@ -293,6 +308,7 @@ public: for (int compIdx = numMajorComponents; compIdx < ModelTraits::numComponents(); ++compIdx) { moleFrac[compIdx] = priVars[compIdx]; + sumMoleFracOtherComponents += moleFrac[compIdx]; } @@ -316,7 +332,7 @@ public: { Scalar rho = FluidSystem::density(fluidState, paramCache, phaseIdx); Scalar mu = FluidSystem::viscosity(fluidState, paramCache, phaseIdx); - Scalar h = ParentType::enthalpy(fluidState, paramCache, phaseIdx); + Scalar h = EnergyVolVars::enthalpy(fluidState, paramCache, phaseIdx); fluidState.setDensity(phaseIdx, rho); fluidState.setViscosity(phaseIdx, mu); @@ -330,6 +346,12 @@ public: const FluidState &fluidState() const { return fluidState_; } + /*! + * \brief Returns the phase state for the control-volume. + */ + const SolidState &solidState() const + { return solidState_; } + /*! * \brief Returns the saturation of a given phase within * the control volume in \f$[-]\f$. @@ -405,7 +427,7 @@ public: * \brief Returns the average porosity within the control volume. */ Scalar porosity() const - { return porosity_; } + { return solidState_.porosity(); } /*! * \brief Returns the permeability within the control volume. @@ -456,6 +478,7 @@ public: protected: FluidState fluidState_; + SolidState solidState_; private: void setDiffusionCoefficient_(int phaseIdx, int compIdx, Scalar d) @@ -473,6 +496,7 @@ private: PermeabilityType permeability_; //!> Effective permeability within the control volume Scalar mobility_[ModelTraits::numPhases()]; //!< Effective mobility within the control volume std::array<std::array<Scalar, ModelTraits::numComponents()-1>, ModelTraits::numPhases()> diffCoefficient_; + }; } // end namespace Dumux diff --git a/dumux/porousmediumflow/2pnc/vtkoutputfields.hh b/dumux/porousmediumflow/2pnc/vtkoutputfields.hh index da45474989d602f3892e4c77d0c9d06435a67cac..5c2150fdcdefd9bf46453a4c1e5b9be70f6e791b 100644 --- a/dumux/porousmediumflow/2pnc/vtkoutputfields.hh +++ b/dumux/porousmediumflow/2pnc/vtkoutputfields.hh @@ -37,7 +37,7 @@ namespace Dumux class TwoPNCVtkOutputFields { public: - template <class VtkOutputModule> + template <class VtkOutputModule> static void init(VtkOutputModule& vtk) { using VolumeVariables = typename VtkOutputModule::VolumeVariables; @@ -60,6 +60,7 @@ public: } }; + } // end namespace Dumux #endif diff --git a/dumux/porousmediumflow/2pncmin/model.hh b/dumux/porousmediumflow/2pncmin/model.hh index a5ccef76cdb23d4bb0afe6dd16bdb99c66f587ac..e6dea9372c3b9e5cfada0f08ea4cef31a5ef30d4 100644 --- a/dumux/porousmediumflow/2pncmin/model.hh +++ b/dumux/porousmediumflow/2pncmin/model.hh @@ -95,6 +95,8 @@ #include <dumux/porousmediumflow/2pnc/model.hh> #include <dumux/porousmediumflow/2pnc/volumevariables.hh> +#include <dumux/material/solidstates/compositionalsolidstate.hh> + #include <dumux/porousmediumflow/mineralization/model.hh> #include <dumux/porousmediumflow/mineralization/localresidual.hh> #include <dumux/porousmediumflow/mineralization/volumevariables.hh> @@ -125,10 +127,12 @@ private: using PV = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); using FSY = typename GET_PROP_TYPE(TypeTag, FluidSystem); using FST = typename GET_PROP_TYPE(TypeTag, FluidState); + using SSY = typename GET_PROP_TYPE(TypeTag, SolidSystem); + using SST = typename GET_PROP_TYPE(TypeTag, SolidState); using MT = typename GET_PROP_TYPE(TypeTag, ModelTraits); using PT = typename GET_PROP_TYPE(TypeTag, SpatialParams)::PermeabilityType; - using Traits = TwoPNCVolumeVariablesTraits<PV, FSY, FST, PT, MT>; + using Traits = TwoPNCVolumeVariablesTraits<PV, FSY, FST, SSY, SST, PT, MT>; using NonMinVolVars = TwoPNCVolumeVariables<Traits>; public: using type = MineralizationVolumeVariables<Traits, NonMinVolVars>; @@ -144,12 +148,23 @@ private: //! we use the number of components specified by the fluid system here using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); static_assert(FluidSystem::numPhases == 2, "Only fluid systems with 2 fluid phases are supported by the 2p-nc model!"); + using SolidSystem = typename GET_PROP_TYPE(TypeTag, PTAG(SolidSystem)); using NonMineralizationTraits = TwoPNCModelTraits<FluidSystem::numComponents, GET_PROP_VALUE(TypeTag, UseMoles), GET_PROP_VALUE(TypeTag, SetMoleFractionsForFirstPhase), GET_PROP_VALUE(TypeTag, Formulation)>; public: - using type = MineralizationModelTraits<NonMineralizationTraits, FluidSystem::numSPhases>; + using type = MineralizationModelTraits<NonMineralizationTraits, SolidSystem::numComponents, SolidSystem::numInertComponents>; +}; + +//! The two-phase model uses the immiscible fluid state +SET_PROP(TwoPNCMin, SolidState) +{ +private: + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using SolidSystem = typename GET_PROP_TYPE(TypeTag, SolidSystem); +public: + using type = CompositionalSolidState<Scalar, SolidSystem>; }; ////////////////////////////////////////////////////////////////// @@ -163,11 +178,12 @@ private: //! we use the number of components specified by the fluid system here using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); static_assert(FluidSystem::numPhases == 2, "Only fluid systems with 2 fluid phases are supported by the 2p-nc model!"); + using SolidSystem = typename GET_PROP_TYPE(TypeTag, PTAG(SolidSystem)); using TwoPNCTraits = TwoPNCModelTraits<FluidSystem::numComponents, GET_PROP_VALUE(TypeTag, UseMoles), GET_PROP_VALUE(TypeTag, SetMoleFractionsForFirstPhase), GET_PROP_VALUE(TypeTag, Formulation)>; - using IsothermalTraits = MineralizationModelTraits<TwoPNCTraits, FluidSystem::numSPhases>; + using IsothermalTraits = MineralizationModelTraits<TwoPNCTraits, SolidSystem::numComponents, SolidSystem::numInertComponents>; public: // the mineralization traits, based on 2pnc traits, are the isothermal traits using type = PorousMediumFlowNIModelTraits<IsothermalTraits>; diff --git a/dumux/porousmediumflow/3p/model.hh b/dumux/porousmediumflow/3p/model.hh index be7842f4feda91d442a6b5f32ef91d3b3e396fcf..3d3adf7c852755b82c7f2d425727f3664a34a949 100644 --- a/dumux/porousmediumflow/3p/model.hh +++ b/dumux/porousmediumflow/3p/model.hh @@ -61,6 +61,9 @@ #include <dumux/material/spatialparams/fv.hh> #include <dumux/material/fluidstates/immiscible.hh> #include <dumux/material/fluidmatrixinteractions/3p/thermalconductivitysomerton3p.hh> +#include <dumux/material/solidstates/inertsolidstate.hh> +#include <dumux/material/solidsystems/inertsolidphase.hh> +#include <dumux/material/components/constant.hh> #include <dumux/porousmediumflow/properties.hh> #include <dumux/porousmediumflow/immiscible/localresidual.hh> @@ -101,12 +104,14 @@ struct ThreePModelTraits * \tparam PT The type used for permeabilities * \tparam MT The model traits */ -template<class PV, class FSY, class FST, class PT, class MT> +template<class PV, class FSY, class FST, class SSY, class SST, class PT, class MT> struct ThreePVolumeVariablesTraits { using PrimaryVariables = PV; using FluidSystem = FSY; using FluidState = FST; + using SolidSystem = SSY; + using SolidState = SST; using PermeabilityType = PT; using ModelTraits = MT; }; @@ -146,10 +151,12 @@ private: using PV = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); using FSY = typename GET_PROP_TYPE(TypeTag, FluidSystem); using FST = typename GET_PROP_TYPE(TypeTag, FluidState); + using SSY = typename GET_PROP_TYPE(TypeTag, SolidSystem); + using SST = typename GET_PROP_TYPE(TypeTag, SolidState); using MT = typename GET_PROP_TYPE(TypeTag, ModelTraits); using PT = typename GET_PROP_TYPE(TypeTag, SpatialParams)::PermeabilityType; - using Traits = ThreePVolumeVariablesTraits<PV, FSY, FST, PT, MT>; + using Traits = ThreePVolumeVariablesTraits<PV, FSY, FST, SSY, SST, PT, MT>; public: using type = ThreePVolumeVariables<Traits>; }; @@ -170,6 +177,24 @@ public: using type = ImmiscibleFluidState<Scalar, FluidSystem>; }; +//! The two-phase model uses the immiscible fluid state +SET_PROP(ThreeP, SolidState) +{ +private: + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using SolidSystem = typename GET_PROP_TYPE(TypeTag, SolidSystem); +public: + using type = InertSolidState<Scalar, SolidSystem>; +}; + +// Set the fluid system +SET_PROP(ThreeP, SolidSystem) +{ + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using InertComponent = Components::Constant<1,Scalar>; + using type = SolidSystems::InertSolidPhase<Scalar, InertComponent>; +}; + //! Set the vtk output fields specific to this model SET_PROP(ThreeP, VtkOutputFields) { diff --git a/dumux/porousmediumflow/3p/volumevariables.hh b/dumux/porousmediumflow/3p/volumevariables.hh index c5af2649f15f7ae070c9b3e66a96f962bc6e53c0..4efbfdbe053fec648634fadd8f1ab9d985321066 100644 --- a/dumux/porousmediumflow/3p/volumevariables.hh +++ b/dumux/porousmediumflow/3p/volumevariables.hh @@ -27,6 +27,8 @@ #include <dumux/material/constants.hh> #include <dumux/material/fluidstates/immiscible.hh> #include <dumux/porousmediumflow/volumevariables.hh> +#include <dumux/porousmediumflow/nonisothermal/volumevariables.hh> + namespace Dumux { @@ -36,14 +38,17 @@ namespace Dumux { */ template <class Traits> class ThreePVolumeVariables -: public PorousMediumFlowVolumeVariables<Traits, ThreePVolumeVariables<Traits>> +: public PorousMediumFlowVolumeVariables<Traits> + ,public EnergyVolumeVariables<Traits, ThreePVolumeVariables<Traits> > { - using ParentType = PorousMediumFlowVolumeVariables<Traits, ThreePVolumeVariables<Traits>>; + using ParentType = PorousMediumFlowVolumeVariables<Traits>; + using EnergyVolVars = EnergyVolumeVariables<Traits, ThreePVolumeVariables<Traits> >; using Scalar = typename Traits::PrimaryVariables::value_type; using PermeabilityType = typename Traits::PermeabilityType; using Indices = typename Traits::ModelTraits::Indices; using FS = typename Traits::FluidSystem; + static constexpr int numComp = ParentType::numComponents(); enum { numPhases = Traits::ModelTraits::numPhases(), @@ -62,6 +67,10 @@ public: using FluidState = typename Traits::FluidState; //! export fluid system type using FluidSystem = typename Traits::FluidSystem; + //! export type of solid state + using SolidState = typename Traits::SolidState; + //! export type of solid system + using SolidSystem = typename Traits::SolidSystem; /*! * \brief Update all quantities for a given control volume @@ -84,7 +93,7 @@ public: using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; const auto& materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol); - completeFluidState(elemSol, problem, element, scv, fluidState_); + completeFluidState(elemSol, problem, element, scv, fluidState_, solidState_); // mobilities for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) @@ -98,10 +107,10 @@ public: } // porosity - porosity_ = problem.spatialParams().porosity(element, scv, elemSol); + updateSolidVolumeFractions(elemSol, problem, element, scv, solidState_, numComp); + EnergyVolVars::updateSolidEnergyParams(elemSol, problem, element, scv, solidState_); permeability_ = problem.spatialParams().permeability(element, scv, elemSol); - Valgrind::CheckDefined(porosity_); Valgrind::CheckDefined(permeability_); } @@ -117,14 +126,14 @@ public: * Set temperature, saturations, capillary pressures, viscosities, densities and enthalpies. */ template<class ElemSol, class Problem, class Element, class Scv> - static void completeFluidState(const ElemSol& elemSol, - const Problem& problem, - const Element& element, - const Scv& scv, - FluidState& fluidState) + void completeFluidState(const ElemSol& elemSol, + const Problem& problem, + const Element& element, + const Scv& scv, + FluidState& fluidState, + SolidState& solidState) { - Scalar t = ParentType::temperature(elemSol, problem, element, scv); - fluidState.setTemperature(t); + EnergyVolVars::updateTemperature(elemSol, problem, element, scv, fluidState, solidState); const auto& materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol); const auto& priVars = ParentType::extractDofPriVars(elemSol, scv); @@ -172,7 +181,7 @@ public: fluidState.setDensity(phaseIdx, rho); // compute and set the enthalpy - const Scalar h = ParentType::enthalpy(fluidState, paramCache, phaseIdx); + const Scalar h = EnergyVolVars::enthalpy(fluidState, paramCache, phaseIdx); fluidState.setEnthalpy(phaseIdx, h); } } @@ -183,6 +192,12 @@ public: const FluidState &fluidState() const { return fluidState_; } + /*! + * \brief Returns the phase state for the control volume. + */ + const SolidState &solidState() const + { return solidState_; } + /*! * \brief Returns the effective saturation of a given phase within * the control volume. @@ -241,7 +256,7 @@ public: * \brief Returns the average porosity within the control volume. */ Scalar porosity() const - { return porosity_; } + { return solidState_.porosity(); } /*! * \brief Returns the permeability within the control volume in \f$[m^2]\f$. @@ -251,9 +266,10 @@ public: protected: FluidState fluidState_; + SolidState solidState_; + private: - Scalar porosity_; PermeabilityType permeability_; Scalar mobility_[numPhases]; }; diff --git a/dumux/porousmediumflow/3p3c/model.hh b/dumux/porousmediumflow/3p3c/model.hh index cc0f683f785599eab5f95a08b589e798ec5e8cbb..546b2a9b22c60d7df74b2f7f4e9a0d0467f5f545 100644 --- a/dumux/porousmediumflow/3p3c/model.hh +++ b/dumux/porousmediumflow/3p3c/model.hh @@ -89,6 +89,10 @@ #include <dumux/material/spatialparams/fv.hh> #include <dumux/material/fluidstates/compositional.hh> #include <dumux/material/fluidmatrixinteractions/3p/thermalconductivitysomerton3p.hh> +#include <dumux/material/solidstates/inertsolidstate.hh> +#include <dumux/material/solidsystems/inertsolidphase.hh> +#include <dumux/material/components/granite.hh> + #include <dumux/porousmediumflow/compositional/switchableprimaryvariables.hh> #include <dumux/material/fluidmatrixinteractions/diffusivitymillingtonquirk.hh> @@ -132,12 +136,14 @@ struct ThreePThreeCModelTraits * \tparam PT The type used for permeabilities * \tparam MT The model traits */ -template<class PV, class FSY, class FST, class PT, class MT> +template<class PV, class FSY, class FST, class SSY, class SST, class PT, class MT> struct ThreePThreeCVolumeVariablesTraits { using PrimaryVariables = PV; using FluidSystem = FSY; using FluidState = FST; + using SolidSystem = SSY; + using SolidState = SST; using PermeabilityType = PT; using ModelTraits = MT; }; @@ -182,6 +188,24 @@ SET_PROP(ThreePThreeC, FluidState){ using type = CompositionalFluidState<Scalar, FluidSystem>; }; +//! The two-phase model uses the immiscible fluid state +SET_PROP(ThreePThreeC, SolidState) +{ +private: + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using SolidSystem = typename GET_PROP_TYPE(TypeTag, SolidSystem); +public: + using type = InertSolidState<Scalar, SolidSystem>; +}; + +// Set the fluid system +SET_PROP(ThreePThreeC, SolidSystem) +{ + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using InertComponent = Components::Granite<Scalar>; + using type = SolidSystems::InertSolidPhase<Scalar, InertComponent>; +}; + //! The local residual function of the conservation equations SET_TYPE_PROP(ThreePThreeC, LocalResidual, ThreePThreeCLocalResidual<TypeTag>); @@ -205,10 +229,12 @@ private: using PV = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); using FSY = typename GET_PROP_TYPE(TypeTag, FluidSystem); using FST = typename GET_PROP_TYPE(TypeTag, FluidState); + using SSY = typename GET_PROP_TYPE(TypeTag, SolidSystem); + using SST = typename GET_PROP_TYPE(TypeTag, SolidState); using MT = typename GET_PROP_TYPE(TypeTag, ModelTraits); using PT = typename GET_PROP_TYPE(TypeTag, SpatialParams)::PermeabilityType; - using Traits = ThreePThreeCVolumeVariablesTraits<PV, FSY, FST, PT, MT>; + using Traits = ThreePThreeCVolumeVariablesTraits<PV, FSY, FST, SSY, SST, PT, MT>; public: using type = ThreePThreeCVolumeVariables<Traits>; }; diff --git a/dumux/porousmediumflow/3p3c/volumevariables.hh b/dumux/porousmediumflow/3p3c/volumevariables.hh index b89ca04a2005763e61a7968384ac73ae89290677..661ade8f6b8d32f0c2a857e7912b52849c9c24d6 100644 --- a/dumux/porousmediumflow/3p3c/volumevariables.hh +++ b/dumux/porousmediumflow/3p3c/volumevariables.hh @@ -30,6 +30,7 @@ #include <dumux/material/constraintsolvers/computefromreferencephase.hh> #include <dumux/material/constraintsolvers/misciblemultiphasecomposition.hh> #include <dumux/porousmediumflow/volumevariables.hh> +#include <dumux/porousmediumflow/nonisothermal/volumevariables.hh> namespace Dumux { @@ -40,9 +41,11 @@ namespace Dumux { */ template <class Traits> class ThreePThreeCVolumeVariables -: public PorousMediumFlowVolumeVariables<Traits, ThreePThreeCVolumeVariables<Traits>> +: public PorousMediumFlowVolumeVariables<Traits> + ,public EnergyVolumeVariables<Traits, ThreePThreeCVolumeVariables<Traits> > { - using ParentType = PorousMediumFlowVolumeVariables<Traits, ThreePThreeCVolumeVariables<Traits>>; + using ParentType = PorousMediumFlowVolumeVariables<Traits>; + using EnergyVolVars = EnergyVolumeVariables<Traits, ThreePThreeCVolumeVariables<Traits> >; using Scalar = typename Traits::PrimaryVariables::value_type; using PermeabilityType = typename Traits::PermeabilityType; @@ -53,6 +56,7 @@ class ThreePThreeCVolumeVariables using ModelTraits = typename Traits::ModelTraits; using Idx = typename ModelTraits::Indices; + static constexpr int numComp = ParentType::numComponents(); enum { wCompIdx = FS::wCompIdx, gCompIdx = FS::gCompIdx, @@ -84,6 +88,10 @@ public: using FluidSystem = typename Traits::FluidSystem; //! export the indices using Indices = typename ModelTraits::Indices; + //! export type of solid state + using SolidState = typename Traits::SolidState; + //! export type of solid system + using SolidSystem = typename Traits::SolidSystem; /*! * \brief Update all quantities for a given control volume @@ -111,8 +119,7 @@ public: problem.spatialParams().materialLawParams(element, scv, elemSol); - Scalar temp = ParentType::temperature(elemSol, problem, element, scv); - fluidState_.setTemperature(temp); + EnergyVolVars::updateTemperature(elemSol, problem, element, scv, fluidState_, solidState_); /* first the saturations */ if (phasePresence == threePhases) @@ -542,13 +549,14 @@ public: setDiffusionCoefficient_(nPhaseIdx, gCompIdx, 0.0); // porosity & permeabilty - porosity_ = problem.spatialParams().porosity(element, scv, elemSol); + updateSolidVolumeFractions(elemSol, problem, element, scv, solidState_, numComp); + EnergyVolVars::updateSolidEnergyParams(elemSol, problem, element, scv, solidState_); permeability_ = problem.spatialParams().permeability(element, scv, elemSol); // compute and set the enthalpy for (int phaseIdx = 0; phaseIdx < ModelTraits::numPhases(); ++phaseIdx) { - Scalar h = ParentType::enthalpy(fluidState_, paramCache, phaseIdx); + Scalar h = EnergyVolVars::enthalpy(fluidState_, paramCache, phaseIdx); fluidState_.setEnthalpy(phaseIdx, h); } } @@ -559,6 +567,11 @@ public: const FluidState &fluidState() const { return fluidState_; } + /*! + * \brief Returns the phase state for the control volume. + */ + const SolidState &solidState() const + { return solidState_; } /*! * \brief Returns the effective saturation of a given phase within * the control volume. @@ -646,7 +659,7 @@ public: * \brief Returns the average porosity within the control volume. */ Scalar porosity() const - { return porosity_; } + { return solidState_.porosity(); } /*! * \brief Returns the adsorption information. @@ -675,6 +688,8 @@ public: protected: FluidState fluidState_; + SolidState solidState_; + private: Scalar sw_, sg_, sn_, pg_, pw_, pn_; @@ -682,7 +697,6 @@ private: Scalar moleFrac_[ModelTraits::numPhases()][ModelTraits::numComponents()]; Scalar massFrac_[ModelTraits::numPhases()][ModelTraits::numComponents()]; - Scalar porosity_; //!< Effective porosity within the control volume PermeabilityType permeability_; //!< Effective permeability within the control volume Scalar mobility_[ModelTraits::numPhases()]; //!< Effective mobility within the control volume Scalar bulkDensTimesAdsorpCoeff_; //!< the basis for calculating adsorbed NAPL diff --git a/dumux/porousmediumflow/3pwateroil/model.hh b/dumux/porousmediumflow/3pwateroil/model.hh index da8cfd29f993ac24dc2a34d3e90d4360aaf1d0cd..7f2e373a6e2367609632ca19146b4ed831cca031 100644 --- a/dumux/porousmediumflow/3pwateroil/model.hh +++ b/dumux/porousmediumflow/3pwateroil/model.hh @@ -77,6 +77,7 @@ #include <dumux/material/spatialparams/fv.hh> #include <dumux/material/fluidmatrixinteractions/3p/thermalconductivitysomerton3p.hh> #include <dumux/material/fluidmatrixinteractions/diffusivitymillingtonquirk.hh> +#include <dumux/material/solidstates/inertsolidstate.hh> #include <dumux/porousmediumflow/properties.hh> #include <dumux/porousmediumflow/nonisothermal/model.hh> @@ -123,12 +124,14 @@ struct ThreePWaterOilModelTraits * \tparam PT The type used for permeabilities * \tparam MT The model traits */ -template<class PV, class FSY, class FST, class PT, class MT> +template<class PV, class FSY, class FST, class SSY, class SST, class PT, class MT> struct ThreePWaterOilVolumeVariablesTraits { using PrimaryVariables = PV; using FluidSystem = FSY; using FluidState = FST; + using SolidSystem = SSY; + using SolidState = SST; using PermeabilityType = PT; using ModelTraits = MT; }; @@ -166,6 +169,17 @@ SET_PROP(ThreePWaterOilNI, FluidState){ using type = CompositionalFluidState<Scalar, FluidSystem>; }; + +//! The two-phase model uses the immiscible fluid state +SET_PROP(ThreePWaterOilNI, SolidState) +{ +private: + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using SolidSystem = typename GET_PROP_TYPE(TypeTag, SolidSystem); +public: + using type = InertSolidState<Scalar, SolidSystem>; +}; + //! The local residual function of the conservation equations SET_TYPE_PROP(ThreePWaterOilNI, LocalResidual, ThreePWaterOilLocalResidual<TypeTag>); @@ -195,10 +209,12 @@ private: using PV = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); using FSY = typename GET_PROP_TYPE(TypeTag, FluidSystem); using FST = typename GET_PROP_TYPE(TypeTag, FluidState); + using SSY = typename GET_PROP_TYPE(TypeTag, SolidSystem); + using SST = typename GET_PROP_TYPE(TypeTag, SolidState); using MT = typename GET_PROP_TYPE(TypeTag, ModelTraits); using PT = typename GET_PROP_TYPE(TypeTag, SpatialParams)::PermeabilityType; - using Traits = ThreePWaterOilVolumeVariablesTraits<PV, FSY, FST, PT, MT>; + using Traits = ThreePWaterOilVolumeVariablesTraits<PV, FSY, FST, SSY, SST, PT, MT>; public: using type = ThreePWaterOilVolumeVariables<Traits>; }; diff --git a/dumux/porousmediumflow/3pwateroil/volumevariables.hh b/dumux/porousmediumflow/3pwateroil/volumevariables.hh index 4af2eadc3652b89078d88497d36159a900d5a83f..125bc09f7efa34b24af23a101f971c1379c13c01 100644 --- a/dumux/porousmediumflow/3pwateroil/volumevariables.hh +++ b/dumux/porousmediumflow/3pwateroil/volumevariables.hh @@ -34,6 +34,7 @@ #include <dumux/common/properties.hh> #include <dumux/discretization/methods.hh> #include <dumux/porousmediumflow/volumevariables.hh> +#include <dumux/porousmediumflow/nonisothermal/volumevariables.hh> #include <dumux/material/constants.hh> #include <dumux/material/fluidstates/compositional.hh> @@ -49,14 +50,16 @@ namespace Dumux { */ template <class Traits> class ThreePWaterOilVolumeVariables -: public PorousMediumFlowVolumeVariables<Traits, ThreePWaterOilVolumeVariables<Traits>> +: public PorousMediumFlowVolumeVariables<Traits> + ,public EnergyVolumeVariables<Traits, ThreePWaterOilVolumeVariables<Traits> > { - using ParentType = PorousMediumFlowVolumeVariables<Traits, ThreePWaterOilVolumeVariables<Traits>>; - + using ParentType = PorousMediumFlowVolumeVariables<Traits>; + using EnergyVolVars = EnergyVolumeVariables<Traits, ThreePWaterOilVolumeVariables<Traits> >; using Scalar = typename Traits::PrimaryVariables::value_type; using ModelTraits = typename Traits::ModelTraits; using Indices = typename ModelTraits::Indices; using FS = typename Traits::FluidSystem; + static constexpr int numComp = ParentType::numComponents(); enum { numPs = ParentType::numPhases(), @@ -89,6 +92,10 @@ public: using FluidState = typename Traits::FluidState; //! The type of the fluid system using FluidSystem = typename Traits::FluidSystem; + //! export type of solid state + using SolidState = typename Traits::SolidState; + //! export type of solid system + using SolidSystem = typename Traits::SolidSystem; /*! * \copydoc ImplicitVolumeVariables::update @@ -202,7 +209,11 @@ public: { // temp from inverse pwsat and pnsat which have to sum up to pg Scalar temp = FluidSystem::inverseVaporPressureCurve(fluidState_, gPhaseIdx, wCompIdx); // initial guess - fluidState_.setTemperature(temp); + for(int phaseIdx=0; phaseIdx < FluidSystem::numPhases; ++phaseIdx) + { + fluidState_.setTemperature(phaseIdx, temp); + } + solidState_.setTemperature(temp); Scalar defect = pg_ - FluidSystem::partialPressureGas(fluidState_, gPhaseIdx, wCompIdx) - FluidSystem::partialPressureGas(fluidState_, gPhaseIdx, nCompIdx); @@ -210,17 +221,29 @@ public: while(abs(defect) > 0.01) // simply a small number chosen ... { Scalar deltaT = 1.e-8 * temp; - fluidState_.setTemperature(temp+deltaT); + for(int phaseIdx=0; phaseIdx < FluidSystem::numPhases; ++phaseIdx) + { + fluidState_.setTemperature(phaseIdx, temp+deltaT); + } + solidState_.setTemperature(temp+deltaT); Scalar fUp = pg_ - FluidSystem::partialPressureGas(fluidState_, gPhaseIdx, wCompIdx) - FluidSystem::partialPressureGas(fluidState_, gPhaseIdx, nCompIdx); - fluidState_.setTemperature(temp-deltaT); + for(int phaseIdx=0; phaseIdx < FluidSystem::numPhases; ++phaseIdx) + { + fluidState_.setTemperature(phaseIdx, temp-deltaT); + } + solidState_.setTemperature(temp-deltaT); Scalar fDown = pg_ - FluidSystem::partialPressureGas(fluidState_, gPhaseIdx, wCompIdx) - FluidSystem::partialPressureGas(fluidState_, gPhaseIdx, nCompIdx); temp = temp - defect * 2. * deltaT / (fUp - fDown); - fluidState_.setTemperature(temp); + for(int phaseIdx=0; phaseIdx < FluidSystem::numPhases; ++phaseIdx) + { + fluidState_.setTemperature(phaseIdx, temp); + } + solidState_.setTemperature(temp); defect = pg_ - FluidSystem::partialPressureGas(fluidState_, gPhaseIdx, wCompIdx) - FluidSystem::partialPressureGas(fluidState_, gPhaseIdx, nCompIdx); } @@ -239,7 +262,11 @@ public: else DUNE_THROW(Dune::InvalidStateException, "phasePresence: " << phasePresence << " is invalid."); Valgrind::CheckDefined(temp_); - fluidState_.setTemperature(temp_); + for(int phaseIdx=0; phaseIdx < FluidSystem::numPhases; ++phaseIdx) + { + fluidState_.setTemperature(phaseIdx, temp_); + } + solidState_.setTemperature(temp_); // now comes the tricky part: calculate phase composition if (phasePresence == threePhases) { @@ -515,7 +542,11 @@ public: // temp from inverse pwsat and pnsat which have to sum up to pg Scalar tempOnlyNAPL = FluidSystem::inverseVaporPressureCurve(fluidState_, gPhaseIdx, nCompIdx); Scalar tempOnlyWater = FluidSystem::inverseVaporPressureCurve(fluidState_, gPhaseIdx, wCompIdx); - fluidState_.setTemperature(tempOnlyWater); + for(int phaseIdx=0; phaseIdx < FluidSystem::numPhases; ++phaseIdx) + { + fluidState_.setTemperature(phaseIdx, tempOnlyWater); + } + solidState_.setTemperature(tempOnlyWater); Scalar defect = pg_ - FluidSystem::partialPressureGas(fluidState_, gPhaseIdx, wCompIdx) - FluidSystem::partialPressureGas(fluidState_, gPhaseIdx, nCompIdx); @@ -525,17 +556,29 @@ public: while(abs(defect) > 0.01) // simply a small number chosen ... { Scalar deltaT = 1.e-6; // fixed number, but T should always be in the order of a few hundred Kelvin - fluidState_.setTemperature(temp+deltaT); + for(int phaseIdx=0; phaseIdx < FluidSystem::numPhases; ++phaseIdx) + { + fluidState_.setTemperature(phaseIdx, temp+deltaT); + } + solidState_.setTemperature(temp+deltaT); Scalar fUp = pg_ - FluidSystem::partialPressureGas(fluidState_, gPhaseIdx, wCompIdx) - FluidSystem::partialPressureGas(fluidState_, gPhaseIdx, nCompIdx); - fluidState_.setTemperature(temp-deltaT); + for(int phaseIdx=0; phaseIdx < FluidSystem::numPhases; ++phaseIdx) + { + fluidState_.setTemperature(phaseIdx, temp-deltaT); + } + solidState_.setTemperature(temp-deltaT); Scalar fDown = pg_ - FluidSystem::partialPressureGas(fluidState_, gPhaseIdx, wCompIdx) - FluidSystem::partialPressureGas(fluidState_, gPhaseIdx, nCompIdx); temp = temp - defect * 2. * deltaT / (fUp - fDown); - fluidState_.setTemperature(temp); + for(int phaseIdx=0; phaseIdx < FluidSystem::numPhases; ++phaseIdx) + { + fluidState_.setTemperature(phaseIdx, temp); + } + solidState_.setTemperature(temp); defect = pg_ - FluidSystem::partialPressureGas(fluidState_, gPhaseIdx, wCompIdx) - FluidSystem::partialPressureGas(fluidState_, gPhaseIdx, nCompIdx); counter +=1; @@ -551,7 +594,11 @@ public: else DUNE_THROW(Dune::InvalidStateException, "phasePresence: " << phasePresence << " is invalid."); Valgrind::CheckDefined(temp_); - fluidState_.setTemperature(temp_); + for(int phaseIdx=0; phaseIdx < FluidSystem::numPhases; ++phaseIdx) + { + fluidState_.setTemperature(phaseIdx, temp_); + } + solidState_.setTemperature(temp_); // now comes the tricky part: calculate phase composition if (phasePresence == threePhases) { @@ -657,8 +704,8 @@ public: // porosity - porosity_ = problem.spatialParams().porosity(element, scv, elemSol); - Valgrind::CheckDefined(porosity_); + updateSolidVolumeFractions(elemSol, problem, element, scv, solidState_, numComp); + EnergyVolVars::updateSolidEnergyParams(elemSol, problem, element, scv, solidState_); // permeability permeability_ = problem.spatialParams().permeability(element, scv, elemSol); @@ -679,6 +726,13 @@ public: const FluidState &fluidState() const { return fluidState_; } + /*! + * \brief Returns the phase state for the control volume. + */ + const SolidState &solidState() const + { return solidState_; } + /*! + /*! * \brief Returns the effective saturation of a given phase within * the control volume. @@ -767,7 +821,7 @@ public: * \brief Returns the average porosity within the control volume. */ Scalar porosity() const - { return porosity_; } + { return solidState_.porosity(); } /*! * \brief Returns the permeability within the control volume. @@ -818,6 +872,7 @@ public: protected: FluidState fluidState_; + SolidState solidState_; private: Scalar sw_, sg_, sn_, pg_, pw_, pn_, temp_; @@ -825,7 +880,6 @@ private: Scalar moleFrac_[numPs][numComps]; Scalar massFrac_[numPs][numComps]; - Scalar porosity_; //!< Effective porosity within the control volume Scalar permeability_; //!< Effective porosity within the control volume Scalar mobility_[numPs]; //!< Effective mobility within the control volume Scalar bulkDensTimesAdsorpCoeff_; //!< the basis for calculating adsorbed NAPL diff --git a/dumux/porousmediumflow/co2/model.hh b/dumux/porousmediumflow/co2/model.hh index 6bd8c0c8c8de32fe9928a9aae86e0ebefcb6188a..009b0c047ba8d00809c4e0646fc10592c7e23a32 100644 --- a/dumux/porousmediumflow/co2/model.hh +++ b/dumux/porousmediumflow/co2/model.hh @@ -60,12 +60,14 @@ namespace Dumux { * \tparam PT The type used for permeabilities * \tparam MT The model traits */ -template<class PV, class FSY, class FST, class PT, class MT> +template<class PV, class FSY, class FST, class SSY, class SST, class PT, class MT> struct TwoPTwoCCO2VolumeVariablesTraits { using PrimaryVariables = PV; using FluidSystem = FSY; using FluidState = FST; + using SolidSystem = SSY; + using SolidState = SST; using PermeabilityType = PT; using ModelTraits = MT; }; @@ -86,10 +88,12 @@ private: using PV = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); using FSY = typename GET_PROP_TYPE(TypeTag, FluidSystem); using FST = typename GET_PROP_TYPE(TypeTag, FluidState); + using SSY = typename GET_PROP_TYPE(TypeTag, SolidSystem); + using SST = typename GET_PROP_TYPE(TypeTag, SolidState); using MT = typename GET_PROP_TYPE(TypeTag, ModelTraits); using PT = typename GET_PROP_TYPE(TypeTag, SpatialParams)::PermeabilityType; - using Traits = TwoPTwoCCO2VolumeVariablesTraits<PV, FSY, FST, PT, MT>; + using Traits = TwoPTwoCCO2VolumeVariablesTraits<PV, FSY, FST, SSY, SST, PT, MT>; public: using type = TwoPTwoCCO2VolumeVariables< Traits >; }; @@ -100,10 +104,12 @@ private: using PV = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); using FSY = typename GET_PROP_TYPE(TypeTag, FluidSystem); using FST = typename GET_PROP_TYPE(TypeTag, FluidState); + using SSY = typename GET_PROP_TYPE(TypeTag, SolidSystem); + using SST = typename GET_PROP_TYPE(TypeTag, SolidState); using MT = typename GET_PROP_TYPE(TypeTag, ModelTraits); using PT = typename GET_PROP_TYPE(TypeTag, SpatialParams)::PermeabilityType; - using Traits = TwoPTwoCCO2VolumeVariablesTraits<PV, FSY, FST, PT, MT>; + using Traits = TwoPTwoCCO2VolumeVariablesTraits<PV, FSY, FST, SSY, SST, PT, MT>; public: using type = TwoPTwoCCO2VolumeVariables< Traits >; }; diff --git a/dumux/porousmediumflow/co2/volumevariables.hh b/dumux/porousmediumflow/co2/volumevariables.hh index 76cfb1f5671590f1bad3c40a4d0e331ffafa9965..42cf8f6b893be1b285537dbeb6308cb02664c2a1 100644 --- a/dumux/porousmediumflow/co2/volumevariables.hh +++ b/dumux/porousmediumflow/co2/volumevariables.hh @@ -40,12 +40,15 @@ namespace Dumux { */ template <class Traits> class TwoPTwoCCO2VolumeVariables -: public PorousMediumFlowVolumeVariables< Traits, TwoPTwoCCO2VolumeVariables<Traits> > +: public PorousMediumFlowVolumeVariables<Traits> + ,public EnergyVolumeVariables<Traits, TwoPTwoCCO2VolumeVariables<Traits> > { - using ParentType = PorousMediumFlowVolumeVariables< Traits, TwoPTwoCCO2VolumeVariables<Traits> >; + using ParentType = PorousMediumFlowVolumeVariables< Traits>; + using EnergyVolVars = EnergyVolumeVariables<Traits, TwoPTwoCCO2VolumeVariables<Traits> >; using Scalar = typename Traits::PrimaryVariables::value_type; using ModelTraits = typename Traits::ModelTraits; + static constexpr int numComp = ParentType::numComponents(); // component indices enum @@ -81,6 +84,11 @@ public: using FluidState = typename Traits::FluidState; //! The fluid system used here using FluidSystem = typename Traits::FluidSystem; + //! export type of solid state + using SolidState = typename Traits::SolidState; + //! export type of solid system + using SolidSystem = typename Traits::SolidSystem; + //! return whether moles or masses are balanced static constexpr bool useMoles() { return ModelTraits::useMoles(); } @@ -105,7 +113,7 @@ public: void update(const ElemSol& elemSol, const Problem& problem, const Element& element, const Scv& scv) { ParentType::update(elemSol, problem, element, scv); - completeFluidState(elemSol, problem, element, scv, fluidState_); + completeFluidState(elemSol, problem, element, scv, fluidState_, solidState_); // Second instance of a parameter cache. Could be avoided if // diffusion coefficients also became part of the fluid state. @@ -127,7 +135,8 @@ public: diffCoeff_[phase1Idx] = FluidSystem::binaryDiffusionCoefficient(fluidState_, paramCache, phase1Idx, comp0Idx, comp1Idx); // porosity & permeabilty - porosity_ = problem.spatialParams().porosity(element, scv, elemSol); + updateSolidVolumeFractions(elemSol, problem, element, scv, solidState_, numComp); + EnergyVolVars::updateSolidEnergyParams(elemSol, problem, element, scv, solidState_); permeability_ = problem.spatialParams().permeability(element, scv, elemSol); } @@ -148,10 +157,10 @@ public: const Problem& problem, const Element& element, const Scv& scv, - FluidState& fluidState) + FluidState& fluidState, + SolidState& solidState) { - const auto t = ParentType::temperature(elemSol, problem, element, scv); - fluidState.setTemperature(t); + EnergyVolVars::updateTemperature(elemSol, problem, element, scv, fluidState, solidState); const auto& priVars = ParentType::extractDofPriVars(elemSol, scv); const auto phasePresence = priVars.state(); @@ -285,7 +294,7 @@ public: fluidState.setViscosity(phaseIdx,mu); // compute and set the enthalpy - Scalar h = ParentType::enthalpy(fluidState, paramCache, phaseIdx); + Scalar h = EnergyVolVars::enthalpy(fluidState, paramCache, phaseIdx); fluidState.setEnthalpy(phaseIdx, h); } } @@ -296,6 +305,13 @@ public: const FluidState &fluidState() const { return fluidState_; } + /*! + * \brief Returns the phase state for the control volume. + */ + const SolidState &solidState() const + { return solidState_; } + + /*! * \brief Returns the saturation of a given phase within * the control volume in \f$[-]\f$. @@ -400,7 +416,7 @@ public: * \brief Returns the average porosity within the control volume in \f$[-]\f$. */ Scalar porosity() const - { return porosity_; } + { return solidState_.porosity(); } /*! * \brief Returns the average permeability within the control volume in \f$[m^2]\f$. @@ -421,8 +437,8 @@ public: private: FluidState fluidState_; + SolidState solidState_; Scalar pc_; //!< The capillary pressure - Scalar porosity_; //!< Effective porosity within the control volume PermeabilityType permeability_; //!< Effective permeability within the control volume //!< Relative permeability within the control volume diff --git a/dumux/porousmediumflow/mineralization/localresidual.hh b/dumux/porousmediumflow/mineralization/localresidual.hh index 4585b1106afbb3736f589db3bf1025cdb9e663f7..72c23abed2a949a959ae6b14aea5d2d9a365243e 100644 --- a/dumux/porousmediumflow/mineralization/localresidual.hh +++ b/dumux/porousmediumflow/mineralization/localresidual.hh @@ -47,7 +47,8 @@ class MineralizationLocalResidual: public CompositionalLocalResidual<TypeTag> using ModelTraits = typename GET_PROP_TYPE(TypeTag, ModelTraits); static constexpr int numPhases = ModelTraits::numPhases(); - static constexpr int numSPhases = ModelTraits::numSPhases(); + static constexpr int numSComponents = ModelTraits::numSolidComps(); + static constexpr int numInertSComponents = ModelTraits::numInertSolidComps(); static constexpr int numComponents = ModelTraits::numComponents(); static constexpr bool useMoles = GET_PROP_VALUE(TypeTag, UseMoles); @@ -77,13 +78,13 @@ public: auto storage = ParentType::computeStorage(problem, scv, volVars); const auto massOrMoleDensity = [](const auto& volVars, const int phaseIdx) - { return useMoles ? volVars.molarDensity(phaseIdx) : volVars.density(phaseIdx); }; + { return useMoles ? volVars.solidPhaseMolarDensity(phaseIdx) : volVars.solidPhaseDensity(phaseIdx); }; // compute storage term of all components within all fluid phases - for (int phaseIdx = numPhases; phaseIdx < numPhases + numSPhases; ++phaseIdx) + for (int phaseIdx = 0; phaseIdx <numSComponents-numInertSComponents; ++phaseIdx) { - auto eqIdx = conti0EqIdx + numComponents-numPhases + phaseIdx; - storage[eqIdx] += volVars.precipitateVolumeFraction(phaseIdx) + auto eqIdx = conti0EqIdx + numComponents + phaseIdx; + storage[eqIdx] += volVars.solidVolumeFraction(phaseIdx) * massOrMoleDensity(volVars, phaseIdx); } diff --git a/dumux/porousmediumflow/mineralization/model.hh b/dumux/porousmediumflow/mineralization/model.hh index e59fb24b9645f3f6b23a03507b0171b036795b50..3e7f01258a76f1e3b88641e1e97e58d39bec8272 100644 --- a/dumux/porousmediumflow/mineralization/model.hh +++ b/dumux/porousmediumflow/mineralization/model.hh @@ -39,17 +39,19 @@ namespace Dumux { * * \Å£param NonMinTraits traits class of the underlying model * not considering mineralization. - * \tparam numPS number of precipitating solid phases to be considered. + * \tparam numPS number of solid phases to be considered. + * \tparam numInertSP number of inert solid phases to be considered. */ -template<class NonMinTraits, int numPS> +template<class NonMinTraits, int numSC, int numInertSC> struct MineralizationModelTraits : public NonMinTraits { - //! the number of precipitating mineral phases - static constexpr int numSPhases() { return numPS; } + //! the number of mineral phases + static constexpr int numSolidComps() { return numSC; } + //! the number of inert mineral phases + static constexpr int numInertSolidComps() { return numInertSC; } //! we additionally solve one equation per precipitating mineral phase - static constexpr int numEq() { return NonMinTraits::numEq() + numPS; } + static constexpr int numEq() { return NonMinTraits::numEq() + numSC - numInertSC; } }; - } // end namespace Dumux #endif diff --git a/dumux/porousmediumflow/mineralization/volumevariables.hh b/dumux/porousmediumflow/mineralization/volumevariables.hh index 87a55ba74e0affb58b5c879e499725fd32fe2b4c..e39158238a90db23adf7711711717c3827593093 100644 --- a/dumux/porousmediumflow/mineralization/volumevariables.hh +++ b/dumux/porousmediumflow/mineralization/volumevariables.hh @@ -38,33 +38,11 @@ class MineralizationVolumeVariables : public NonMineralizationVolVars using ParentType = NonMineralizationVolVars; using Scalar = typename Traits::PrimaryVariables::value_type; using ModelTraits = typename Traits::ModelTraits; + using SolidState = typename Traits::SolidState; + static constexpr int numComp = ParentType::numComponents(); public: - //! export the type of the fluid state - using FluidState = typename Traits::FluidState; - //! export the type of the fluid system - using FluidSystem = typename Traits::FluidSystem; - - //! updates all required quantities inside the given scv - template<class ElemSol, class Problem, class Element, class Scv> - void update(const ElemSol &elemSol, - const Problem &problem, - const Element &element, - const Scv& scv) - { - // Update parent type (also completes the fluid state) - ParentType::update(elemSol, problem, element, scv); - - // calculate the remaining quantities - auto&& priVars = elemSol[scv.localDofIndex()]; - - sumPrecipitates_ = 0.0; - for(int sPhaseIdx = 0; sPhaseIdx < ModelTraits::numSPhases(); ++sPhaseIdx) - { - precipitateVolumeFraction_[sPhaseIdx] = priVars[ModelTraits::numComponents() + sPhaseIdx]; - sumPrecipitates_+= precipitateVolumeFraction_[sPhaseIdx]; - } - } + using SolidSystem = typename Traits::SolidSystem; /*! * \brief Returns the volume fraction of the precipitate (solid phase) @@ -72,60 +50,29 @@ public: * * \param phaseIdx the index of the solid phase */ - Scalar precipitateVolumeFraction(int phaseIdx) const - { return precipitateVolumeFraction_[phaseIdx - ModelTraits::numPhases()]; } + Scalar solidVolumeFraction(int sCompIdx) const + { return this->solidState_.volumeFraction(sCompIdx); } /*! * \brief Returns the density of the phase for all fluid and solid phases * * \param phaseIdx the index of the fluid phase - * \todo TODO: This fails for 1pnc if fluidSystemPhaseIdx is not 0 */ - Scalar density(int phaseIdx) const + Scalar solidPhaseDensity(int phaseIdx) const { - if (phaseIdx < ModelTraits::numPhases()) - return this->fluidState_.density(phaseIdx); - else - return FluidSystem::precipitateDensity(phaseIdx); + return SolidSystem::density(this->solidState_, phaseIdx); } /*! - * \brief Returns the mass density of a given phase within the - * control volume. - * - * \param phaseIdx The phase index - * \todo TODO: This fails for 1pnc if fluidSystemPhaseIdx is not 0 - */ - Scalar molarDensity(int phaseIdx) const - { - if (phaseIdx < ModelTraits::numPhases()) - return this->fluidState_.molarDensity(phaseIdx); - else - return FluidSystem::precipitateMolarDensity(phaseIdx); - } - - /*! - * \brief Returns the molality of a component in the phase + * \brief Returns the density of the phase for all fluid and solid phases * * \param phaseIdx the index of the fluid phase - * \param compIdx the index of the component - * \f$\mathrm{molality} - * = \frac{n_\mathrm{component}}{m_\mathrm{solvent}} - * = \frac{n_\mathrm{component}}{n_\mathrm{solvent}*M_\mathrm{solvent}}\f$ - * - * \note compIdx of the main component (solvent) in the - * phase is equal to the phaseIdx */ - Scalar molality(int phaseIdx, int compIdx) const // [moles/Kg] + Scalar solidPhaseMolarDensity(int phaseIdx) const { - return this->fluidState_.moleFraction(phaseIdx, compIdx) - /(this->fluidState_.moleFraction(phaseIdx, phaseIdx) - * FluidSystem::molarMass(phaseIdx)); + return SolidSystem::molarDensity(this->solidState_, phaseIdx); } -protected: - Scalar precipitateVolumeFraction_[ModelTraits::numSPhases()]; - Scalar sumPrecipitates_; }; } // end namespace Dumux diff --git a/dumux/porousmediumflow/mineralization/vtkoutputfields.hh b/dumux/porousmediumflow/mineralization/vtkoutputfields.hh index 79acc52d8ebc42d88e157f506f9457d66f53cc97..0395985dd61d2c531d1bf59d64df13d8b85126ba 100644 --- a/dumux/porousmediumflow/mineralization/vtkoutputfields.hh +++ b/dumux/porousmediumflow/mineralization/vtkoutputfields.hh @@ -38,17 +38,15 @@ public: template <class VtkOutputModule> static void init(VtkOutputModule& vtk) { - using FluidSystem = typename VtkOutputModule::VolumeVariables::FluidSystem; + using SolidSystem = typename VtkOutputModule::VolumeVariables::SolidSystem; // output of the model without mineralization NonMineralizationVtkOutputFields::init(vtk); // additional output - // TODO: Why does fluid system have number of solid phases?? - for (int i = 0; i < FluidSystem::numSPhases; ++i) + for (int i = 0; i < SolidSystem::numComponents - SolidSystem::numInertComponents; ++i) { - vtk.addVolumeVariable([i](const auto& v){ return v.precipitateVolumeFraction(FluidSystem::numPhases + i); }, - "precipitateVolumeFraction_"+ FluidSystem::phaseName(FluidSystem::numPhases + i)); + vtk.addVolumeVariable([i](const auto& v){ return v.solidVolumeFraction(i); },"precipitateVolumeFraction_"+ SolidSystem::phaseName(i)); } } }; diff --git a/dumux/porousmediumflow/mpnc/model.hh b/dumux/porousmediumflow/mpnc/model.hh index a0aa8996b00bd2dc84319879e4e345acc43cc662..58363229fb829f5b35d5198f22d2169aa87bd628 100644 --- a/dumux/porousmediumflow/mpnc/model.hh +++ b/dumux/porousmediumflow/mpnc/model.hh @@ -100,9 +100,12 @@ #include <dumux/material/fluidstates/nonequilibrium.hh> #include <dumux/material/fluidstates/compositional.hh> +#include <dumux/material/solidstates/inertsolidstate.hh> #include <dumux/material/spatialparams/fv.hh> #include <dumux/material/fluidmatrixinteractions/diffusivitymillingtonquirk.hh> #include <dumux/material/fluidmatrixinteractions/2p/thermalconductivitysimplefluidlumping.hh> +#include <dumux/material/components/granite.hh> +#include <dumux/material/solidsystems/inertsolidphase.hh> #include <dumux/porousmediumflow/properties.hh> #include <dumux/porousmediumflow/compositional/localresidual.hh> @@ -110,6 +113,7 @@ #include <dumux/porousmediumflow/nonisothermal/indices.hh> #include <dumux/porousmediumflow/nonisothermal/vtkoutputfields.hh> #include <dumux/porousmediumflow/nonequilibrium/model.hh> +#include <dumux/porousmediumflow/nonequilibrium/volumevariables.hh> #include "indices.hh" #include "volumevariables.hh" @@ -189,6 +193,8 @@ public: template<class PV, class FSY, class FST, + class SSY, + class SST, class PT, class MT> struct MPNCVolumeVariablesTraits @@ -196,6 +202,8 @@ struct MPNCVolumeVariablesTraits using PrimaryVariables = PV; using FluidSystem = FSY; using FluidState = FST; + using SolidSystem = SSY; + using SolidState = SST; using PermeabilityType = PT; using ModelTraits = MT; }; @@ -239,6 +247,26 @@ public: using type = CompositionalFluidState<Scalar, FluidSystem>; }; +//! The two-phase model uses the immiscible fluid state +SET_PROP(MPNC, SolidState) +{ +private: + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using SolidSystem = typename GET_PROP_TYPE(TypeTag, SolidSystem); +public: + using type = InertSolidState<Scalar, SolidSystem>; +}; + +// Set the fluid system +SET_PROP(MPNC, SolidSystem) +{ + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using InertComponent = Components::Granite<Scalar>; + using type = SolidSystems::InertSolidPhase<Scalar, InertComponent>; +}; + + + //! Set the volume variables property SET_PROP(MPNC, VolumeVariables) { @@ -246,10 +274,12 @@ private: using PV = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); using FSY = typename GET_PROP_TYPE(TypeTag, FluidSystem); using FST = typename GET_PROP_TYPE(TypeTag, FluidState); + using SSY = typename GET_PROP_TYPE(TypeTag, SolidSystem); + using SST = typename GET_PROP_TYPE(TypeTag, SolidState); using MT = typename GET_PROP_TYPE(TypeTag, ModelTraits); using PT = typename GET_PROP_TYPE(TypeTag, SpatialParams)::PermeabilityType; - using Traits = MPNCVolumeVariablesTraits<PV, FSY, FST, PT, MT>; + using Traits = MPNCVolumeVariablesTraits<PV, FSY, FST, SSY, SST, PT, MT>; public: using type = MPNCVolumeVariables<Traits>; }; @@ -333,6 +363,25 @@ public: using type = ThermalConductivitySimpleFluidLumping<Scalar, GET_PROP_VALUE(TypeTag, NumEnergyEqFluid)>; }; +//! use the mineralization volume variables together with the 2pnc vol vars +SET_PROP(MPNCNonequil, VolumeVariables) +{ +private: + using PV = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); + using FSY = typename GET_PROP_TYPE(TypeTag, FluidSystem); + using FST = typename GET_PROP_TYPE(TypeTag, FluidState); + using SSY = typename GET_PROP_TYPE(TypeTag, SolidSystem); + using SST = typename GET_PROP_TYPE(TypeTag, SolidState); + using MT = typename GET_PROP_TYPE(TypeTag, ModelTraits); + using PT = typename GET_PROP_TYPE(TypeTag, SpatialParams)::PermeabilityType; + + using Traits = MPNCVolumeVariablesTraits<PV, FSY, FST, SSY, SST, PT, MT>; + using EquilibriumVolVars = MPNCVolumeVariables<Traits>; +public: + using type = NonEquilibriumVolumeVariables<Traits, EquilibriumVolVars>; +}; + + } //end namespace Properties } //end namespace Dumux diff --git a/dumux/porousmediumflow/mpnc/volumevariables.hh b/dumux/porousmediumflow/mpnc/volumevariables.hh index 4763cb2ff26dd63c2aadd409068ec3b0ed5b184d..e1e964bd6614a37d366963a22552f9243fa400c2 100644 --- a/dumux/porousmediumflow/mpnc/volumevariables.hh +++ b/dumux/porousmediumflow/mpnc/volumevariables.hh @@ -25,17 +25,25 @@ #ifndef DUMUX_MPNC_VOLUME_VARIABLES_HH #define DUMUX_MPNC_VOLUME_VARIABLES_HH -#include <dumux/material/constraintsolvers/ncpflash.hh> -#include <dumux/material/constraintsolvers/compositionfromfugacities.hh> +#include "indices.hh" + +#include <dumux/common/properties.hh> -#include <dumux/porousmediumflow/nonequilibrium/volumevariables.hh> #include <dumux/porousmediumflow/volumevariables.hh> +#include <dumux/porousmediumflow/nonisothermal/volumevariables.hh> + +#include <dumux/material/constraintsolvers/ncpflash.hh> +#include <dumux/material/constraintsolvers/compositionfromfugacities.hh> +#include <dumux/material/constraintsolvers/misciblemultiphasecomposition.hh> #include "pressureformulation.hh" namespace Dumux { +// forward declaration +template <class Traits, bool enableChemicalNonEquilibrium> +class MPNCVolumeVariablesImplementation; /*! * \ingroup MPNCModel * \brief Contains the quantities which are constant within a finite volume in the MpNc model. @@ -43,12 +51,15 @@ namespace Dumux * \tparam Traits Class encapsulating types to be used by the vol vars */ template <class Traits> -class MPNCVolumeVariables - : public PorousMediumFlowVolumeVariables< Traits, MPNCVolumeVariables<Traits> > - , public NonEquilibriumVolumeVariables< Traits > +using MPNCVolumeVariables = MPNCVolumeVariablesImplementation<Traits, Traits::ModelTraits::enableChemicalNonEquilibrium()>; + +template <class Traits> +class MPNCVolumeVariablesImplementation<Traits, false> + : public PorousMediumFlowVolumeVariables<Traits> + , public EnergyVolumeVariables<Traits, MPNCVolumeVariables<Traits> > { - using ParentType = PorousMediumFlowVolumeVariables< Traits, MPNCVolumeVariables<Traits> >; - using NonEqVolVars = NonEquilibriumVolumeVariables< Traits >; + using ParentType = PorousMediumFlowVolumeVariables<Traits>; + using EnergyVolVars = EnergyVolumeVariables<Traits, MPNCVolumeVariables<Traits> >; using Scalar = typename Traits::PrimaryVariables::value_type; using PermeabilityType = typename Traits::PermeabilityType; @@ -69,6 +80,10 @@ public: using FluidSystem = typename Traits::FluidSystem; //! export the fluid state type using FluidState = typename Traits::FluidState; + //! export type of solid state + using SolidState = typename Traits::SolidState; + //! export type of solid system + using SolidSystem = typename Traits::SolidSystem; //! return number of phases considered by the model static constexpr int numPhases() { return ModelTraits::numPhases(); } @@ -91,16 +106,16 @@ public: const Scv& scv) { ParentType::update(elemSol, problem, element, scv); - completeFluidState(elemSol, problem, element, scv, fluidState_); + + completeFluidState(elemSol, problem, element, scv, fluidState_, solidState_); //calculate the remaining quantities const auto& materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol); - // relative permeabilities using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; - MaterialLaw::relativePermeabilities(relativePermeability_, materialParams, fluidState_); - - // binary diffusion coefficients + MaterialLaw::relativePermeabilities(relativePermeability_, + materialParams, + fluidState_); typename FluidSystem::ParameterCache paramCache; paramCache.updateAll(fluidState_); if (enableDiffusion) @@ -109,32 +124,26 @@ public: { int compIIdx = phaseIdx; for (unsigned int compJIdx = 0; compJIdx < numComponents(); ++compJIdx) + { + // binary diffusion coefficients if(compIIdx!= compJIdx) + { setDiffusionCoefficient_(phaseIdx, compJIdx, FluidSystem::binaryDiffusionCoefficient(fluidState_, paramCache, phaseIdx, compIIdx, compJIdx)); + } + } } } - - porosity_ = problem.spatialParams().porosity(element, scv, elemSol); + //porosity + updateSolidVolumeFractions(elemSol, problem, element, scv, solidState_, numComponents()); + EnergyVolVars::updateSolidEnergyParams(elemSol, problem, element, scv, solidState_); + Scalar minPorosity = problem.spatialParams().minimalPorosity(element, scv); + solidState_.setMinPorosity(minPorosity); permeability_ = problem.spatialParams().permeability(element, scv, elemSol); - - // only do this if we are either looking at chemical and/or thermal non-equilibrium - if (enableChemicalNonEquilibrium || enableThermalNonEquilibrium) - { - // specific interfacial area, - // well, also all the dimensionless numbers :-) - // well, also the mass transfer rate - NonEqVolVars::updateInterfacialArea(elemSol, - fluidState_, - paramCache, - problem, - element, - scv); - } } /*! @@ -147,60 +156,54 @@ public: * \param scv The sub-control volume * \param fluidState A container with the current (physical) state of the fluid */ + template<class ElemSol, class Problem, class Element, class Scv> void completeFluidState(const ElemSol& elemSol, const Problem& problem, const Element& element, const Scv& scv, - FluidState& fluidState) + FluidState& fluidState, + SolidState& solidState) { + ///////////// // set the fluid phase temperatures ///////////// - if(!enableThermalNonEquilibrium) - { - Scalar t = ParentType::temperature(elemSol, problem, element, scv); - fluidState.setTemperature(t); - } - else - NonEqVolVars::updateTemperatures(elemSol, problem, element, scv, fluidState); + EnergyVolVars::updateTemperature(elemSol, problem, element, scv, fluidState, solidState); ///////////// // set the phase saturations ///////////// - const auto& priVars = ParentType::extractDofPriVars(elemSol, scv); - + auto&& priVars = ParentType::extractDofPriVars(elemSol, scv); Scalar sumSat = 0; - for (int phaseIdx = 0; phaseIdx < numPhases() - 1; ++phaseIdx) - { + for (int phaseIdx = 0; phaseIdx < numPhases() - 1; ++phaseIdx) { sumSat += priVars[Indices::s0Idx + phaseIdx]; fluidState.setSaturation(phaseIdx, priVars[Indices::s0Idx + phaseIdx]); } - + Valgrind::CheckDefined(sumSat); fluidState.setSaturation(numPhases() - 1, 1.0 - sumSat); ///////////// // set the phase pressures ///////////// - const auto& materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol); - + // capillary pressure parameters + const auto& materialParams = + problem.spatialParams().materialLawParams(element, scv, elemSol); // capillary pressures Scalar capPress[numPhases()]; using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; MaterialLaw::capillaryPressures(capPress, materialParams, fluidState); + // add to the pressure of the first fluid phase - // add to the pressure of the first fluid phase, // depending on which pressure is stored in the primary variables - if(pressureFormulation == MpNcPressureFormulation::mostWettingFirst) - { + if(pressureFormulation == MpNcPressureFormulation::mostWettingFirst){ // This means that the pressures are sorted from the most wetting to the least wetting-1 in the primary variables vector. // For two phases this means that there is one pressure as primary variable: pw const Scalar pw = priVars[Indices::p0Idx]; for (int phaseIdx = 0; phaseIdx < numPhases(); ++phaseIdx) fluidState.setPressure(phaseIdx, pw - capPress[0] + capPress[phaseIdx]); } - else if(pressureFormulation == MpNcPressureFormulation::leastWettingFirst) - { + else if(pressureFormulation == MpNcPressureFormulation::leastWettingFirst){ // This means that the pressures are sorted from the least wetting to the most wetting-1 in the primary variables vector. // For two phases this means that there is one pressure as primary variable: pn const Scalar pn = priVars[Indices::p0Idx]; @@ -221,35 +224,474 @@ public: for (int compIdx = 0; compIdx < numComponents(); ++compIdx) fug[compIdx] = priVars[Indices::fug0Idx + compIdx]; - if(!enableChemicalNonEquilibrium) - { // calculate phase compositions - for (int phaseIdx = 0; phaseIdx < numPhases(); ++phaseIdx) - { + for (int phaseIdx = 0; phaseIdx < numPhases(); ++phaseIdx) { // initial guess - for (int compIdx = 0; compIdx < numComponents(); ++compIdx) - { + for (int compIdx = 0; compIdx < numComponents(); ++compIdx) { Scalar x_ij = 1.0/numComponents(); // set initial guess of the component's mole fraction - fluidState.setMoleFraction(phaseIdx, compIdx, x_ij); + fluidState.setMoleFraction(phaseIdx, + compIdx, + x_ij); } - - // calculate the phase composition from the component fugacities + // calculate the phase composition from the component + // fugacities CompositionFromFugacities::guessInitial(fluidState, paramCache, phaseIdx, fug); CompositionFromFugacities::solve(fluidState, paramCache, phaseIdx, fug); } + // dynamic viscosities + for (int phaseIdx = 0; phaseIdx < numPhases(); ++phaseIdx) { + // viscosities + Scalar mu = FluidSystem::viscosity(fluidState, paramCache, phaseIdx); + fluidState.setViscosity(phaseIdx, mu); + + // compute and set the enthalpy + Scalar h = FluidSystem::enthalpy(fluidState, paramCache, phaseIdx); + fluidState.setEnthalpy(phaseIdx, h); } + + // make sure the quantities in the fluid state are well-defined + fluidState.checkDefined(); + } + + /*! + * \brief Return the fluid configuration at the given primary + * variables + */ + const FluidState &fluidState() const + { return fluidState_; } + + /*! + * \brief Returns the phase state for the control-volume. + */ + const SolidState &solidState() const + { return solidState_; } + + /*! + * \brief Returns the saturation of a given phase within + * the control volume in \f$[-]\f$. + * + * \param phaseIdx The phase index + */ + Scalar saturation(int phaseIdx) const + { return fluidState_.saturation(phaseIdx); } + + /*! + * \brief Returns the mass fraction of a given component in a + * given phase within the control volume in \f$[-]\f$. + * + * \param phaseIdx The phase index + * \param compIdx The component index + */ + Scalar massFraction(const int phaseIdx, const int compIdx) const + { return fluidState_.massFraction(phaseIdx, compIdx); } + + /*! + * \brief Returns the mole fraction of a given component in a + * given phase within the control volume in \f$[-]\f$. + * + * \param phaseIdx The phase index + * \param compIdx The component index + */ + Scalar moleFraction(const int phaseIdx, const int compIdx) const + { return fluidState_.moleFraction(phaseIdx, compIdx); } + + /*! + * \brief Return concentration \f$\mathrm{[mol/m^3]}\f$ of a component in the phase. + * + * \param phaseIdx The phase index + * \param compIdx The index of the component + */ + Scalar molarity(const int phaseIdx, int compIdx) const + { return fluidState_.molarity(phaseIdx, compIdx); } + + /*! + * \brief Return molar density \f$\mathrm{[mol/m^3]}\f$ the of the fluid phase. + * + * \param phaseIdx The phase index + */ + Scalar molarDensity(const int phaseIdx) const + { return fluidState_.molarDensity(phaseIdx);} + + /*! + * \brief Return the effective pressure \f$\mathrm{[Pa]}\f$ of a given phase within + * the control volume. + * + * \param phaseIdx The phase index + */ + Scalar pressure(const int phaseIdx) const + { return fluidState_.pressure(phaseIdx); } + + /*! + * \brief Return density \f$\mathrm{[kg/m^3]}\f$ the of the fluid phase. + * + * \param phaseIdx The phase index + */ + Scalar density(const int phaseIdx) const + { return fluidState_.density(phaseIdx); } + + /*! + * \brief Returns temperature inside the sub-control volume. + * + * Note that we assume thermodynamic equilibrium, i.e. the + * temperature of the rock matrix and of all fluid phases are + * identical. + */ + Scalar temperature() const + { return fluidState_.temperature(0/* phaseIdx*/); } + + Scalar temperature(const int phaseIdx) const + { return fluidState_.temperature(phaseIdx); } + + /*! + * \brief Return enthalpy \f$\mathrm{[kg/m^3]}\f$ the of the fluid phase. + */ + Scalar enthalpy(const int phaseIdx) const + { return fluidState_.enthalpy(phaseIdx); } + + /*! + * \brief Return internal energy \f$\mathrm{[kg/m^3]}\f$ the of the fluid phase. + */ + Scalar internalEnergy(const int phaseIdx) const + { return fluidState_.internalEnergy(phaseIdx); } + + /*! + * \brief Returns the thermal conductivity \f$\mathrm{[W/(m*K)]}\f$ of a fluid phase in + * the sub-control volume. + */ + Scalar fluidThermalConductivity(const int phaseIdx) const + { return FluidSystem::thermalConductivity(fluidState_, phaseIdx); } + + /*! + * \brief Return fugacity \f$\mathrm{[kg/m^3]}\f$ the of the component. + */ + Scalar fugacity(const int compIdx) const + { return fluidState_.fugacity(compIdx); } + + /*! + * \brief Return average molar mass \f$\mathrm{[kg/m^3]}\f$ the of the phase. + */ + Scalar averageMolarMass(const int phaseIdx) const + { return fluidState_.averageMolarMass(phaseIdx); } + + /*! + * \brief Returns the effective mobility of a given phase within + * the control volume. + * + * \param phaseIdx The local index of the phases + */ + Scalar mobility(const unsigned int phaseIdx) const + { + return relativePermeability(phaseIdx)/fluidState_.viscosity(phaseIdx); + } + + /*! + * \brief Returns the viscosity of a given phase within + * the control volume. + */ + Scalar viscosity(const unsigned int phaseIdx) const + { return fluidState_.viscosity(phaseIdx); } + + /*! + * \brief Returns the relative permeability of a given phase within + * the control volume. + * + * \param phaseIdx The local index of the phases + */ + Scalar relativePermeability(const unsigned int phaseIdx) const + { return relativePermeability_[phaseIdx]; } + + /*! + * \brief Returns the average porosity within the control volume. + */ + Scalar porosity() const + { return solidState_.porosity(); } + + /*! + * \brief Returns the permeability within the control volume in \f$[m^2]\f$. + */ + const PermeabilityType& permeability() const + { return permeability_; } + + /*! + * \brief Returns true if the fluid state is in the active set + * for a phase, + * + * \param phaseIdx The local index of the phases + */ + bool isPhaseActive(const unsigned int phaseIdx) const + { + return + phasePresentIneq(fluidState(), phaseIdx) - + phaseNotPresentIneq(fluidState(), phaseIdx) + >= 0; + } + + /*! + * \brief Returns the diffusion coefficient + */ + Scalar diffusionCoefficient(int phaseIdx, int compIdx) const + { + if (compIdx < phaseIdx) + return diffCoefficient_[phaseIdx][compIdx]; + else if (compIdx > phaseIdx) + return diffCoefficient_[phaseIdx][compIdx-1]; else - NonEqVolVars::updateMoleFraction(fluidState, paramCache, priVars); + DUNE_THROW(Dune::InvalidStateException, "Diffusion coeffiecient called for phaseIdx = compIdx"); + } - // dynamic viscosities and enthalpies - for (int phaseIdx = 0; phaseIdx < numPhases(); ++phaseIdx) + /*! + * \brief Returns the value of the NCP-function for a phase. + * + * \param phaseIdx The local index of the phases + */ + Scalar phaseNcp(const unsigned int phaseIdx) const + { + Scalar aEval = phaseNotPresentIneq(fluidState(), phaseIdx); + Scalar bEval = phasePresentIneq(fluidState(), phaseIdx); + if (aEval > bEval) + return phasePresentIneq(fluidState(), phaseIdx); + return phaseNotPresentIneq(fluidState(), phaseIdx); + }; + + /*! + * \brief Returns the value of the inequality where a phase is + * present. + * + * \param phaseIdx The local index of the phases + * \param fluidState Container for all the secondary variables concerning the fluids + */ + Scalar phasePresentIneq(const FluidState &fluidState, + const unsigned int phaseIdx) const + { return fluidState.saturation(phaseIdx); } + + /*! + * \brief Returns the value of the inequality where a phase is not + * present. + * + * \param phaseIdx The local index of the phases + * \param fluidState Container for all the secondary variables concerning the fluids + */ + Scalar phaseNotPresentIneq(const FluidState &fluidState, + const unsigned int phaseIdx) const + { + // difference of sum of mole fractions in the phase from 100% + Scalar a = 1; + for (int compIdx = 0; compIdx < numComponents(); ++compIdx) + a -= fluidState.moleFraction(phaseIdx, compIdx); + return a; + } + +protected: + + void setDiffusionCoefficient_(int phaseIdx, int compIdx, Scalar d) + { + if (compIdx < phaseIdx) + diffCoefficient_[phaseIdx][compIdx] = std::move(d); + else if (compIdx > phaseIdx) + diffCoefficient_[phaseIdx][compIdx-1] = std::move(d); + else + DUNE_THROW(Dune::InvalidStateException, "Diffusion coeffiecient for phaseIdx = compIdx doesn't exist"); + } + + std::array<std::array<Scalar, numComponents()-1>, numPhases()> diffCoefficient_; + Scalar porosity_; //!< Effective porosity within the control volume + Scalar relativePermeability_[numPhases()]; //!< Effective relative permeability within the control volume + PermeabilityType permeability_; + + //! Mass fractions of each component within each phase + FluidState fluidState_; + SolidState solidState_; + +}; + +template <class Traits> +class MPNCVolumeVariablesImplementation<Traits, true> + : public PorousMediumFlowVolumeVariables<Traits> + , public EnergyVolumeVariables<Traits, MPNCVolumeVariables<Traits> > +{ + using ParentType = PorousMediumFlowVolumeVariables< Traits>; + using EnergyVolVars = EnergyVolumeVariables<Traits, MPNCVolumeVariables<Traits> >; + using Scalar = typename Traits::PrimaryVariables::value_type; + using PermeabilityType = typename Traits::PermeabilityType; + + using ModelTraits = typename Traits::ModelTraits; + static constexpr auto pressureFormulation = ModelTraits::pressureFormulation(); + + static constexpr bool enableThermalNonEquilibrium = ModelTraits::enableThermalNonEquilibrium(); + static constexpr bool enableChemicalNonEquilibrium = ModelTraits::enableChemicalNonEquilibrium(); + static constexpr bool enableDiffusion = ModelTraits::enableMolecularDiffusion(); + + using Indices = typename ModelTraits::Indices; + using ComponentVector = Dune::FieldVector<Scalar, ModelTraits::numComponents()>; + using CompositionFromFugacities = Dumux::CompositionFromFugacities<Scalar, typename Traits::FluidSystem>; + + using ParameterCache = typename Traits::FluidSystem::ParameterCache; +public: + //! export the underlying fluid system + using FluidSystem = typename Traits::FluidSystem; + //! export the fluid state type + using FluidState = typename Traits::FluidState; + //! export type of solid state + using SolidState = typename Traits::SolidState; + //! export type of solid system + using SolidSystem = typename Traits::SolidSystem; + + //! return number of phases considered by the model + static constexpr int numPhases() { return ModelTraits::numPhases(); } + //! return number of components considered by the model + static constexpr int numComponents() { return ModelTraits::numComponents(); } + using ConstraintSolver = MiscibleMultiPhaseComposition<Scalar, FluidSystem>; + + /*! + * \brief Update all quantities for a given control volume + * + * \param elemSol A vector containing all primary variables connected to the element + * \param problem The object specifying the problem which ought to + * be simulated + * \param element An element which contains part of the control volume + * \param scv The sub-control volume + */ + template<class ElemSol, class Problem, class Element, class Scv> + void update(const ElemSol& elemSol, + const Problem& problem, + const Element& element, + const Scv& scv) + { + ParentType::update(elemSol, problem, element, scv); + + completeFluidState(elemSol, problem, element, scv, fluidState_, solidState_); + + //calculate the remaining quantities + const auto& materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol); + + // relative permeabilities + using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; + MaterialLaw::relativePermeabilities(relativePermeability_, + materialParams, + fluidState_); + typename FluidSystem::ParameterCache paramCache; + paramCache.updateAll(fluidState_); + if (enableDiffusion) { - const auto mu = FluidSystem::viscosity(fluidState, paramCache, phaseIdx); + for (int phaseIdx = 0; phaseIdx < numPhases(); ++phaseIdx) + { + int compIIdx = phaseIdx; + for (unsigned int compJIdx = 0; compJIdx < numComponents(); ++compJIdx) + { + // binary diffusion coefficients + if(compIIdx!= compJIdx) + { + setDiffusionCoefficient_(phaseIdx, compJIdx, + FluidSystem::binaryDiffusionCoefficient(fluidState_, + paramCache, + phaseIdx, + compIIdx, + compJIdx)); + } + } + } + } + + updateSolidVolumeFractions(elemSol, problem, element, scv, solidState_, numComponents()); + EnergyVolVars::updateSolidEnergyParams(elemSol, problem, element, scv, solidState_); + Scalar minPorosity = problem.spatialParams().minimalPorosity(element, scv); + solidState_.setMinPorosity(minPorosity); + permeability_ = problem.spatialParams().permeability(element, scv, elemSol); + + } + + /*! + * \brief Set complete fluid state + * + * \param elemSol A vector containing all primary variables connected to the element + * \param problem The object specifying the problem which ought to + * be simulated + * \param element An element which contains part of the control volume + * \param scv The sub-control volume + * \param fluidState A container with the current (physical) state of the fluid + */ + + template<class ElemSol, class Problem, class Element, class Scv> + void completeFluidState(const ElemSol& elemSol, + const Problem& problem, + const Element& element, + const Scv& scv, + FluidState& fluidState, + SolidState& solidState) + { + ///////////// + // set the fluid phase temperatures + ///////////// + EnergyVolVars::updateTemperature(elemSol, problem, element, scv, fluidState, solidState); + ///////////// + // set the phase saturations + ///////////// + auto&& priVars = ParentType::extractDofPriVars(elemSol, scv); + Scalar sumSat = 0; + for (int phaseIdx = 0; phaseIdx < numPhases() - 1; ++phaseIdx) { + sumSat += priVars[Indices::s0Idx + phaseIdx]; + fluidState.setSaturation(phaseIdx, priVars[Indices::s0Idx + phaseIdx]); + } + Valgrind::CheckDefined(sumSat); + fluidState.setSaturation(numPhases() - 1, 1.0 - sumSat); + + ///////////// + // set the phase pressures + ///////////// + // capillary pressure parameters + const auto& materialParams = + problem.spatialParams().materialLawParams(element, scv, elemSol); + // capillary pressures + Scalar capPress[numPhases()]; + using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; + MaterialLaw::capillaryPressures(capPress, materialParams, fluidState); + // add to the pressure of the first fluid phase + + // depending on which pressure is stored in the primary variables + if(pressureFormulation == MpNcPressureFormulation::mostWettingFirst){ + // This means that the pressures are sorted from the most wetting to the least wetting-1 in the primary variables vector. + // For two phases this means that there is one pressure as primary variable: pw + const Scalar pw = priVars[Indices::p0Idx]; + for (int phaseIdx = 0; phaseIdx < numPhases(); ++phaseIdx) + fluidState.setPressure(phaseIdx, pw - capPress[0] + capPress[phaseIdx]); + } + else if(pressureFormulation == MpNcPressureFormulation::leastWettingFirst){ + // This means that the pressures are sorted from the least wetting to the most wetting-1 in the primary variables vector. + // For two phases this means that there is one pressure as primary variable: pn + const Scalar pn = priVars[Indices::p0Idx]; + for (int phaseIdx = numPhases()-1; phaseIdx >= 0; --phaseIdx) + fluidState.setPressure(phaseIdx, pn - capPress[numPhases()-1] + capPress[phaseIdx]); + } + else + DUNE_THROW(Dune::InvalidStateException, "MPNCVolumeVariables do not support the chosen pressure formulation"); + + + ///////////// + // set the fluid compositions + ///////////// + typename FluidSystem::ParameterCache paramCache; + paramCache.updateAll(fluidState); + + ComponentVector fug; + // retrieve component fugacities + for (int compIdx = 0; compIdx < numComponents(); ++compIdx) + fug[compIdx] = priVars[Indices::fug0Idx + compIdx]; + + updateMoleFraction(fluidState, + paramCache, + priVars); + + + // dynamic viscosities + for (int phaseIdx = 0; phaseIdx < numPhases(); ++phaseIdx) { + // viscosities + Scalar mu = FluidSystem::viscosity(fluidState, paramCache, phaseIdx); fluidState.setViscosity(phaseIdx, mu); - const auto h = FluidSystem::enthalpy(fluidState, paramCache, phaseIdx); + // compute and set the enthalpy + Scalar h = FluidSystem::enthalpy(fluidState, paramCache, phaseIdx); fluidState.setEnthalpy(phaseIdx, h); } @@ -257,6 +699,79 @@ public: fluidState.checkDefined(); } + /*! + * \brief Update composition of all phases in the mutable + * parameters from the primary variables. + * + * \param actualFluidState Container for all the secondary variables concerning the fluids + * \param paramCache Container for cache parameters + * \param priVars The primary Variables + * \param *hint the volume variables, usable for initial guess of composition + */ + void updateMoleFraction(FluidState & actualFluidState, + ParameterCache & paramCache, + const typename Traits::PrimaryVariables& priVars) + { + // setting the mole fractions of the fluid state + for(int phaseIdx=0; phaseIdx<numPhases(); ++phaseIdx) + { + // set the component mole fractions + for (int compIdx = 0; compIdx < numComponents(); ++compIdx) { + actualFluidState.setMoleFraction(phaseIdx, + compIdx, + priVars[Indices::moleFrac00Idx + + phaseIdx*numComponents() + + compIdx]); + } + } + +// // For using the ... other way of calculating equilibrium +// THIS IS ONLY FOR silencing Valgrind but is not used in this model + for(int phaseIdx=0; phaseIdx<numPhases(); ++phaseIdx) + for (int compIdx = 0; compIdx < numComponents(); ++compIdx) { + const Scalar phi = FluidSystem::fugacityCoefficient(actualFluidState, + paramCache, + phaseIdx, + compIdx); + actualFluidState.setFugacityCoefficient(phaseIdx, + compIdx, + phi); + } + + FluidState equilFluidState; // the fluidState *on the interface* i.e. chemical equilibrium + equilFluidState.assign(actualFluidState) ; + ConstraintSolver::solve(equilFluidState, + paramCache, + /*setViscosity=*/false, + /*setEnthalpy=*/false) ; + + // Setting the equilibrium composition (in a kinetic model not necessarily the same as the actual mole fraction) + for(int phaseIdx=0; phaseIdx<numPhases(); ++phaseIdx){ + for (int compIdx=0; compIdx< numComponents(); ++ compIdx){ + xEquil_[phaseIdx][compIdx] = equilFluidState.moleFraction(phaseIdx, compIdx); + } + } + + // compute densities of all phases + for(int phaseIdx=0; phaseIdx<numPhases(); ++phaseIdx){ + const Scalar rho = FluidSystem::density(actualFluidState, paramCache, phaseIdx); + actualFluidState.setDensity(phaseIdx, rho); + } + + } + + /*! + * \brief The mole fraction we would have in the case of chemical equilibrium / + * on the interface. + * + * \param phaseIdx The index of the fluid phase + * \param compIdx The local index of the component + */ + const Scalar xEquil(const unsigned int phaseIdx, const unsigned int compIdx) const + { + return xEquil_[phaseIdx][compIdx] ; + } + /*! * \brief Return the fluid configuration at the given primary * variables @@ -264,6 +779,12 @@ public: const FluidState &fluidState() const { return fluidState_; } + /*! + * \brief Returns the phase state for the control-volume. + */ + const SolidState &solidState() const + { return solidState_; } + /*! * \brief Returns the saturation of a given phase within * the control volume in \f$[-]\f$. @@ -336,10 +857,7 @@ public: */ Scalar temperature() const { - if (enableThermalNonEquilibrium) - DUNE_THROW(Dune::InvalidStateException, "this is a method for thermal equilibrium, use temperature(phaseIdx) for thermal non-equilibrium"); - else - return fluidState_.temperature(0/* phaseIdx*/); + return fluidState_.temperature(0/* phaseIdx*/); } Scalar temperature(const int phaseIdx) const @@ -407,7 +925,7 @@ public: * \brief Returns the average porosity within the control volume. */ Scalar porosity() const - { return porosity_; } + { return solidState_.porosity(); } /*! * \brief Returns the permeability within the control volume in \f$[m^2]\f$. @@ -423,8 +941,10 @@ public: */ bool isPhaseActive(const unsigned int phaseIdx) const { - return phasePresentIneq(fluidState(), phaseIdx) - - phaseNotPresentIneq(fluidState(), phaseIdx) >= 0; + return + phasePresentIneq(fluidState(), phaseIdx) - + phaseNotPresentIneq(fluidState(), phaseIdx) + >= 0; } /*! @@ -437,7 +957,7 @@ public: else if (compIdx > phaseIdx) return diffCoefficient_[phaseIdx][compIdx-1]; else - DUNE_THROW(Dune::InvalidStateException, "Diffusion coefficient called for phaseIdx = compIdx"); + DUNE_THROW(Dune::InvalidStateException, "Diffusion coeffiecient called for phaseIdx = compIdx"); } /*! @@ -482,7 +1002,7 @@ public: return a; } -private: +protected: void setDiffusionCoefficient_(int phaseIdx, int compIdx, Scalar d) { @@ -491,16 +1011,17 @@ private: else if (compIdx > phaseIdx) diffCoefficient_[phaseIdx][compIdx-1] = std::move(d); else - DUNE_THROW(Dune::InvalidStateException, "Diffusion coefficient for phaseIdx = compIdx doesn't exist"); + DUNE_THROW(Dune::InvalidStateException, "Diffusion coeffiecient for phaseIdx = compIdx doesn't exist"); } std::array<std::array<Scalar, numComponents()-1>, numPhases()> diffCoefficient_; - Scalar porosity_; //!< Effective porosity within the control volume Scalar relativePermeability_[numPhases()]; //!< Effective relative permeability within the control volume PermeabilityType permeability_; + Scalar xEquil_[numPhases()][numComponents()]; //! Mass fractions of each component within each phase FluidState fluidState_; + SolidState solidState_; }; } // end namespace diff --git a/dumux/porousmediumflow/nonequilibrium/localresidual.hh b/dumux/porousmediumflow/nonequilibrium/localresidual.hh index 03ac76bd31a1050b63d710771df513e83483fdae..bca6937aa1a1e9d1eda2d5b01fe66a8bca920c21 100644 --- a/dumux/porousmediumflow/nonequilibrium/localresidual.hh +++ b/dumux/porousmediumflow/nonequilibrium/localresidual.hh @@ -187,7 +187,6 @@ class NonEquilibriumLocalResidualImplementation<TypeTag, true, true>: public GET enum { comp0Idx = FluidSystem::comp0Idx } ; enum { phase0Idx = FluidSystem::phase0Idx} ; enum { phase1Idx = FluidSystem::phase1Idx} ; - enum { sPhaseIdx = FluidSystem::sPhaseIdx} ; public: using ParentType::ParentType; diff --git a/dumux/porousmediumflow/nonequilibrium/model.hh b/dumux/porousmediumflow/nonequilibrium/model.hh index 648f390b353b901e2b4e8bfcebfa9573a7a6a86f..ee1030843dec7f313f120e6597b72bd49b8bb65e 100644 --- a/dumux/porousmediumflow/nonequilibrium/model.hh +++ b/dumux/porousmediumflow/nonequilibrium/model.hh @@ -67,6 +67,8 @@ struct NonEquilibriumModelTraits : public ET static constexpr int numEnergyEqFluid() { return therm ? numEF : 0; } static constexpr int numEnergyEqSolid() { return therm ? numES : 0; } + static constexpr int numEnergyEq() { return numEnergyEqFluid()+numEnergyEqSolid(); } + static constexpr int numSolidComps() {return ET::SolidSystem::numComponents(); } static constexpr bool enableEnergyBalance() { return ET::enableEnergyBalance() || therm; } static constexpr bool enableThermalNonEquilibrium() { return therm; } diff --git a/dumux/porousmediumflow/nonequilibrium/thermal/localresidual.hh b/dumux/porousmediumflow/nonequilibrium/thermal/localresidual.hh index df0d778db678e56fb2b9b58c1ce3337a7437d77c..6b3f2e41ae0059b7f81efad1fc103d018005d764 100644 --- a/dumux/porousmediumflow/nonequilibrium/thermal/localresidual.hh +++ b/dumux/porousmediumflow/nonequilibrium/thermal/localresidual.hh @@ -66,7 +66,6 @@ class EnergyLocalResidualNonEquilibrium<TypeTag, 1/*numEnergyEqFluid*/> enum { numComponents = ModelTraits::numComponents() }; enum { phase0Idx = FluidSystem::phase0Idx}; enum { phase1Idx = FluidSystem::phase1Idx}; - enum { sPhaseIdx = FluidSystem::sPhaseIdx}; public: //! The energy storage in the fluid phase with index phaseIdx @@ -147,9 +146,11 @@ public: { //in case we have one energy equation for more than one fluid phase we use an effective law in the nonequilibrium fourierslaw flux[energyEq0Idx] += fluxVars.heatConductionFlux(0); - - //heat conduction for solid phase - flux[energyEqSolidIdx] += fluxVars.heatConductionFlux(sPhaseIdx); + //heat conduction for the fluid phases + for(int sPhaseIdx=0; sPhaseIdx<numEnergyEqSolid; ++sPhaseIdx) + { + flux[energyEqSolidIdx+sPhaseIdx] += fluxVars.heatConductionFlux(sPhaseIdx); + } } /*! @@ -318,6 +319,7 @@ class EnergyLocalResidualNonEquilibrium<TypeTag, 2 /*numEnergyEqFluid*/> using SubControlVolume = typename FVElementGeometry::SubControlVolume; using FluxVariables = typename GET_PROP_TYPE(TypeTag, FluxVariables); using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); + using SolidSystem = typename GET_PROP_TYPE(TypeTag, SolidSystem); using GridView = typename GET_PROP_TYPE(TypeTag, GridView); using Element = typename GridView::template Codim<0>::Entity; using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView; @@ -336,7 +338,7 @@ class EnergyLocalResidualNonEquilibrium<TypeTag, 2 /*numEnergyEqFluid*/> enum { numComponents = ModelTraits::numComponents() }; enum { phase0Idx = FluidSystem::phase0Idx}; enum { phase1Idx = FluidSystem::phase1Idx}; - enum { sPhaseIdx = FluidSystem::sPhaseIdx}; + enum { sPhaseIdx = numPhases}; static constexpr bool enableChemicalNonEquilibrium = ModelTraits::enableChemicalNonEquilibrium(); @@ -399,8 +401,10 @@ public: { flux[energyEq0Idx+phaseIdx] += fluxVars.heatConductionFlux(phaseIdx); } - //heat conduction for solid phase - flux[energyEqSolidIdx] += fluxVars.heatConductionFlux(sPhaseIdx); + for(int sPhaseIdx=0; sPhaseIdx<numEnergyEqSolid; ++sPhaseIdx) + { + flux[energyEqSolidIdx+sPhaseIdx] += fluxVars.heatConductionFlux(sPhaseIdx); + } } /*! * \brief Calculate the source term of the equation diff --git a/dumux/porousmediumflow/nonequilibrium/volumevariables.hh b/dumux/porousmediumflow/nonequilibrium/volumevariables.hh index 801de358020c9a420939bfabb3a67b6f1d4140ef..7ad7474ac374f833c173392d211919fece9ae1ba 100644 --- a/dumux/porousmediumflow/nonequilibrium/volumevariables.hh +++ b/dumux/porousmediumflow/nonequilibrium/volumevariables.hh @@ -26,16 +26,11 @@ * This files contains all specializations which use 'real' * interfacial areas. */ -#ifndef DUMUX_NONEQUILIBRIUM_VOLUME_VARIABLES__HH -#define DUMUX_NONEQUILIBRIUM_VOLUME_VARIABLES__HH +#ifndef DUMUX_NONEQUILIBRIUM_VOLUME_VARIABLES_HH +#define DUMUX_NONEQUILIBRIUM_VOLUME_VARIABLES_HH #include <dumux/common/dimensionlessnumbers.hh> -#include <dumux/porousmediumflow/volumevariables.hh> - -#include <dumux/material/fluidstates/nonequilibrium.hh> -#include <dumux/material/constraintsolvers/misciblemultiphasecomposition.hh> - namespace Dumux { /*! @@ -45,60 +40,32 @@ namespace Dumux { * modules which require the specific interfacial area between * fluid phases. */ -template<class Traits, bool enableChemicalNonEquilibrium ,bool enableThermalNonEquilibrium> +template<class Traits, class EquilibriumVolumeVariables, bool enableChemicalNonEquilibrium ,bool enableThermalNonEquilibrium> class NonEquilibriumVolumeVariablesImplementation; -template<class Traits> +template<class Traits, class EquilibriumVolumeVariables> using NonEquilibriumVolumeVariables = NonEquilibriumVolumeVariablesImplementation< Traits, + EquilibriumVolumeVariables, Traits::ModelTraits::enableChemicalNonEquilibrium(), Traits::ModelTraits::enableThermalNonEquilibrium() >; -//! Specialization for both chemical and thermal non-equilibrium disabled -template<class Traits> -class NonEquilibriumVolumeVariablesImplementation< Traits, - false/*chemicalNonEquilibrium?*/, - false/*thermalNonEquilibrium?*/ > -{ - using FluidState = typename Traits::FluidState; - using ParameterCache = typename Traits::FluidSystem::ParameterCache; - -public: - template<class ElemSol, class Problem, class Element, class Scv> - void updateInterfacialArea(const ElemSol& elemSol, - const FluidState& fluidState, - const ParameterCache& paramCache, - const Problem& problem, - const Element& element, - const Scv& scv) {} - - template<class ElemSol, class Problem, class Element, class Scv> - void updateTemperatures(const ElemSol& elemSol, - const Problem &problem, - const Element& element, - const Scv& scv, - FluidState& fluidState) {} - - void updateMoleFraction(FluidState& actualFluidState, - ParameterCache& paramCache, - const typename Traits::PrimaryVariables& priVars) {} -}; - ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // specialization for the case of NO kinetic mass but kinetic energy transfer of a fluid mixture and solid ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -template<class Traits> +template<class Traits, class EquilibriumVolumeVariables> class NonEquilibriumVolumeVariablesImplementation< Traits, + EquilibriumVolumeVariables, false/*chemicalNonEquilibrium?*/, true/*thermalNonEquilibrium?*/ > + :public EquilibriumVolumeVariables { - using FluidState = typename Traits::FluidState; + using ParentType = EquilibriumVolumeVariables; using ParameterCache = typename Traits::FluidSystem::ParameterCache; using Scalar = typename Traits::PrimaryVariables::value_type; using ModelTraits = typename Traits::ModelTraits; using Indices = typename ModelTraits::Indices; - static constexpr auto numPhases = ModelTraits::numPhases(); static constexpr auto numEnergyEqFluid = ModelTraits::numEnergyEqFluid(); static constexpr auto numEnergyEqSolid = ModelTraits::numEnergyEqSolid(); @@ -107,6 +74,30 @@ class NonEquilibriumVolumeVariablesImplementation< Traits, using DimLessNum = DimensionlessNumbers<Scalar>; public: + using FluidState = typename Traits::FluidState; + /*! + * \brief Update all quantities for a given control volume + * + * \param elemSol A vector containing all primary variables connected to the element + * \param problem The object specifying the problem which ought to + * be simulated + * \param element An element which contains part of the control volume + * \param scv The sub-control volume + */ + template<class ElemSol, class Problem, class Element, class Scv> + void update(const ElemSol &elemSol, + const Problem &problem, + const Element &element, + const Scv& scv) + { + // Update parent type (also completes the fluid state) + ParentType::update(elemSol, problem, element, scv); + + ParameterCache paramCache; + paramCache.updateAll(this->fluidState_); + updateInterfacialArea(elemSol, this->fluidState_, paramCache, problem, element, scv); + } + /*! * \brief Updates the volume specific interfacial area [m^2 / m^3] between the phases. * @@ -131,7 +122,7 @@ public: // set the dimensionless numbers and obtain respective quantities const unsigned int vIdxGlobal = scv.dofIndex(); - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) + for (int phaseIdx = 0; phaseIdx < ModelTraits::numPhases(); ++phaseIdx) { const auto darcyMagVelocity = problem.gridVariables().volumeDarcyMagVelocity(phaseIdx, vIdxGlobal); const auto dynamicViscosity = fluidState.viscosity(phaseIdx); @@ -141,7 +132,7 @@ public: using FluidSystem = typename Traits::FluidSystem; const auto heatCapacity = FluidSystem::heatCapacity(fluidState, paramCache, phaseIdx); const auto thermalConductivity = FluidSystem::thermalConductivity(fluidState, paramCache, phaseIdx); - const auto porosity = problem.spatialParams().porosity(element, scv, elemSol); + const auto porosity = problem.spatialParams().porosity(element, scv); reynoldsNumber_[phaseIdx] = DimLessNum::reynoldsNumber(darcyMagVelocity, characteristicLength_, kinematicViscosity); prandtlNumber_[phaseIdx] = DimLessNum::prandtlNumber(dynamicViscosity, heatCapacity, thermalConductivity); @@ -152,58 +143,6 @@ public: } } - /*! - * \brief Update the temperatures for a given control volume - * - * \param elemSol A vector containing all primary variables connected to the element - * \param problem The problem to be solved - * \param element An element which contains part of the control volume - * \param scv The sub-control volume - * \param fluidState Container for all the secondary variables concerning the fluids - */ - template<class ElemSol, class Problem, class Element, class Scv> - void updateTemperatures(const ElemSol& elemSol, - const Problem& problem, - const Element& element, - const Scv& scv, - FluidState& fluidState) - { - // set fluid temperature(s) - if (numEnergyEqFluid > 1) - { - // retrieve temperature from solution vector - for(int phaseIdx=0; phaseIdx < numEnergyEqFluid; ++phaseIdx) - { - const auto T = elemSol[scv.localDofIndex()][Indices::temperature0Idx + phaseIdx]; - fluidState.setTemperature(phaseIdx, T); - } - } - else - { - const auto T = elemSol[scv.localDofIndex()][Indices::temperature0Idx]; - fluidState.setTemperature(T); - } - - // set solid temperatures - static_assert(numEnergyEqSolid == 1, "Solid system not yet implemented"); - for (int solidPhaseIdx = numEnergyEqFluid; solidPhaseIdx < numEnergyEqFluid+numEnergyEqSolid; ++solidPhaseIdx) - temperatureSolid_ = elemSol[scv.localDofIndex()][Indices::temperature0Idx + solidPhaseIdx]; - } - - /*! - * \brief Update composition of all phases in the mutable parameters from the primary variables. - * - * \param actualFluidState Container for all the secondary variables concerning the fluids - * \param paramCache Container for cache parameters - * \param priVars The primary Variables - */ - void updateMoleFraction(FluidState& actualFluidState, - ParameterCache& paramCache, - const typename Traits::PrimaryVariables& priVars) {} - - - //! Returns the temperature of the solid phase(s) - Scalar temperatureSolid() const { return temperatureSolid_; } //! access function Reynolds Number const Scalar reynoldsNumber(const unsigned int phaseIdx) const { return reynoldsNumber_[phaseIdx]; } //! access function Prandtl Number @@ -219,44 +158,65 @@ public: private: //! dimensionless numbers - Scalar reynoldsNumber_[numPhases]; - Scalar prandtlNumber_[numPhases]; - Scalar nusseltNumber_[numPhases]; + Scalar reynoldsNumber_[ModelTraits::numPhases()]; + Scalar prandtlNumber_[ModelTraits::numPhases()]; + Scalar nusseltNumber_[ModelTraits::numPhases()]; Scalar characteristicLength_; Scalar factorEnergyTransfer_; Scalar factorMassTransfer_; Scalar solidSurface_ ; - Scalar temperatureSolid_; }; //////////////////////////////////////////////////////////////////////////////////////////////////// // specialization for the case of (only) kinetic mass transfer. Be careful, we do not test this! //////////////////////////////////////////////////////////////////////////////////////////////////// -template<class Traits> +template<class Traits, class EquilibriumVolumeVariables> class NonEquilibriumVolumeVariablesImplementation< Traits, + EquilibriumVolumeVariables, true/*chemicalNonEquilibrium?*/, false/*thermalNonEquilibrium?*/> + :public EquilibriumVolumeVariables { + using ParentType = EquilibriumVolumeVariables; using FluidState = typename Traits::FluidState; - using FluidSystem = typename Traits::FluidSystem; + using FS = typename Traits::FluidSystem; using ParameterCache = typename Traits::FluidSystem::ParameterCache; using Scalar = typename Traits::PrimaryVariables::value_type; using ModelTraits = typename Traits::ModelTraits; using Indices = typename ModelTraits::Indices; - static constexpr auto numPhases = ModelTraits::numPhases(); - static constexpr auto numComponents = ModelTraits::numComponents(); - static constexpr auto phase0Idx = FluidSystem::phase0Idx; - static constexpr auto phase1Idx = FluidSystem::phase1Idx; - static constexpr auto wCompIdx = FluidSystem::comp0Idx; - static constexpr auto nCompIdx = FluidSystem::comp1Idx; + static constexpr auto phase0Idx = FS::phase0Idx; + static constexpr auto phase1Idx = FS::phase1Idx; + static constexpr auto wCompIdx = FS::comp0Idx; + static constexpr auto nCompIdx = FS::comp1Idx; using DimLessNum = DimensionlessNumbers<Scalar>; - using ConstraintSolver = MiscibleMultiPhaseComposition<Scalar, FluidSystem>; - public: + /*! + * \brief Update all quantities for a given control volume + * + * \param elemSol A vector containing all primary variables connected to the element + * \param problem The object specifying the problem which ought to + * be simulated + * \param element An element which contains part of the control volume + * \param scv The sub-control volume + */ + template<class ElemSol, class Problem, class Element, class Scv> + void update(const ElemSol &elemSol, + const Problem &problem, + const Element &element, + const Scv& scv) + { + // Update parent type (also completes the fluid state) + ParentType::update(elemSol, problem, element, scv); + + ParameterCache paramCache; + paramCache.updateAll(this->fluidState_); + updateInterfacialArea(elemSol, this->fluidState_, paramCache, problem, element, scv); + } + /*! * \brief Updates the volume specific interfacial area [m^2 / m^3] between the phases. * @@ -291,7 +251,7 @@ public: // set the dimensionless numbers and obtain respective quantities. const auto globalVertexIdx = problem.fvGridGeometry().vertexMapper().subIndex(element, scv, Element::Geometry::myDimension); - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) + for (int phaseIdx = 0; phaseIdx < ModelTraits::numPhases(); ++phaseIdx) { const auto darcyMagVelocity = problem.gridVariables().volumeDarcyMagVelocity(phaseIdx, globalVertexIdx); const auto dynamicViscosity = fluidState.viscosity(phaseIdx); @@ -299,6 +259,7 @@ public: const auto kinematicViscosity = dynamicViscosity/density; // diffusion coefficient of non-wetting component in wetting phase + using FluidSystem = typename Traits::FluidSystem; const auto diffCoeff = FluidSystem::binaryDiffusionCoefficient(fluidState, paramCache, phaseIdx, @@ -313,58 +274,6 @@ public: } } - /*! - * \brief Update composition of all phases in the mutable parameters from the primary variables. - * - * \param actualFluidState Container for all the secondary variables concerning the fluids - * \param paramCache Container for cache parameters - * \param priVars The primary Variables - */ - void updateMoleFraction(FluidState& actualFluidState, - ParameterCache& paramCache, - const typename Traits::PrimaryVariables& priVars) - { - // set the mole fractions of the fluid state - for(int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - for (int compIdx = 0; compIdx < numComponents; ++compIdx) - actualFluidState.setMoleFraction( phaseIdx, - compIdx, - priVars[Indices::conti0EqIdx+phaseIdx*numComponents+compIdx] ); - - // For using the ... other way of calculating equilibrium - for(int phaseIdx=0; phaseIdx<numPhases; ++phaseIdx) - for (int compIdx = 0; compIdx < numComponents; ++compIdx) - actualFluidState.setFugacityCoefficient( phaseIdx, - compIdx, - FluidSystem::fugacityCoefficient(actualFluidState, - paramCache, - phaseIdx, - compIdx) ); - - FluidState equilFluidState; // the fluidState *on the interface* i.e. chemical equilibrium - equilFluidState.assign(actualFluidState) ; - ConstraintSolver::solve(equilFluidState, paramCache, /*setViscosity=*/false, /*setEnthalpy=*/false); - - // Set the equilibrium composition (in a kinetic model not necessarily the same as the actual mole fraction) - for(int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - for (int compIdx = 0; compIdx < numComponents; ++ compIdx) - xEquil_[phaseIdx][compIdx] = equilFluidState.moleFraction(phaseIdx, compIdx); - - // compute densities of all phases - for(int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - actualFluidState.setDensity(phaseIdx, FluidSystem::density(actualFluidState, paramCache, phaseIdx)); - } - - /*! - * \brief The mole fraction we would have in the case of chemical equilibrium - * on the interface. - * - * \param phaseIdx The index of the fluid phase - * \param compIdx The local index of the component - */ - const Scalar xEquil(const unsigned int phaseIdx, const unsigned int compIdx) const - { return xEquil_[phaseIdx][compIdx]; } - /*! * \brief The specific interfacial area between two fluid phases [m^2 / m^3] */ @@ -392,41 +301,63 @@ private: Scalar factorMassTransfer_; Scalar solidSurface_ ; Scalar interfacialArea_ ; - Scalar sherwoodNumber_[numPhases] ; - Scalar schmidtNumber_[numPhases] ; - Scalar reynoldsNumber_[numPhases] ; - Scalar xEquil_[numPhases][numComponents]; + Scalar sherwoodNumber_[ModelTraits::numPhases()] ; + Scalar schmidtNumber_[ModelTraits::numPhases()] ; + Scalar reynoldsNumber_[ModelTraits::numPhases()] ; }; // Specialization where everything is in non-equilibrium. -template<class Traits> +template<class Traits, class EquilibriumVolumeVariables> class NonEquilibriumVolumeVariablesImplementation< Traits, + EquilibriumVolumeVariables, true/*chemicalNonEquilibrium?*/, true/*thermalNonEquilibrium?*/> + :public EquilibriumVolumeVariables { + using ParentType = EquilibriumVolumeVariables; using FluidState = typename Traits::FluidState; - using FluidSystem = typename Traits::FluidSystem; + using FS = typename Traits::FluidSystem; using ParameterCache = typename Traits::FluidSystem::ParameterCache; using Scalar = typename Traits::PrimaryVariables::value_type; using ModelTraits = typename Traits::ModelTraits; using Indices = typename ModelTraits::Indices; - static constexpr auto numPhases = ModelTraits::numPhases(); - static constexpr auto numComponents = ModelTraits::numComponents(); static constexpr auto numEnergyEqFluid = ModelTraits::numEnergyEqFluid(); static constexpr auto numEnergyEqSolid = ModelTraits::numEnergyEqSolid(); - static constexpr auto phase0Idx = FluidSystem::phase0Idx; - static constexpr auto phase1Idx = FluidSystem::phase1Idx; - static constexpr auto sPhaseIdx = FluidSystem::sPhaseIdx; - static constexpr auto wCompIdx = FluidSystem::comp0Idx; - static constexpr auto nCompIdx = FluidSystem::comp1Idx; + static constexpr auto phase0Idx = FS::phase0Idx; + static constexpr auto phase1Idx = FS::phase1Idx; + static constexpr auto sPhaseIdx = FS::numPhases; + static constexpr auto wCompIdx = FS::comp0Idx; + static constexpr auto nCompIdx = FS::comp1Idx; using DimLessNum = DimensionlessNumbers<Scalar>; - using ConstraintSolver = MiscibleMultiPhaseComposition<Scalar, FluidSystem>; static_assert((numEnergyEqFluid > 1), "This model only deals with energy transfer between two fluids and one solid phase"); public: + /*! + * \brief Update all quantities for a given control volume + * + * \param elemSol A vector containing all primary variables connected to the element + * \param problem The object specifying the problem which ought to + * be simulated + * \param element An element which contains part of the control volume + * \param scv The sub-control volume + */ + template<class ElemSol, class Problem, class Element, class Scv> + void update(const ElemSol &elemSol, + const Problem &problem, + const Element &element, + const Scv& scv) + { + // Update parent type (also completes the fluid state) + ParentType::update(elemSol, problem, element, scv); + + ParameterCache paramCache; + paramCache.updateAll(this->fluidState_); + updateInterfacialArea(elemSol, this->fluidState_, paramCache, problem, element, scv); + } + /*! * \brief Updates the volume specific interfacial area [m^2 / m^3] between the phases. * @@ -514,7 +445,8 @@ public: characteristicLength_ = problem.spatialParams().characteristicLength(element, scv, elemSol); const auto vIdxGlobal = scv.dofIndex(); - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) + using FluidSystem = typename Traits::FluidSystem; + for (int phaseIdx = 0; phaseIdx < ModelTraits::numPhases(); ++phaseIdx) { const auto darcyMagVelocity = problem.gridVariables().volumeDarcyMagVelocity(phaseIdx, vIdxGlobal); const auto dynamicViscosity = fluidState.viscosity(phaseIdx); @@ -524,7 +456,7 @@ public: const auto thermalConductivity = FluidSystem::thermalConductivity(fluidState, paramCache, phaseIdx); // diffusion coefficient of non-wetting component in wetting phase - const auto porosity = problem.spatialParams().porosity(element, scv, elemSol); + const auto porosity = problem.spatialParams().porosity(element, scv); const auto diffCoeff = FluidSystem::binaryDiffusionCoefficient(fluidState, paramCache, phaseIdx, @@ -545,85 +477,6 @@ public: } } - /*! - * \brief Update composition of all phases in the mutable parameters from the primary variables. - * - * \param actualFluidState Container for all the secondary variables concerning the fluids - * \param paramCache Container for cache parameters - * \param priVars The primary Variables - */ - void updateMoleFraction(FluidState& actualFluidState, - ParameterCache& paramCache, - const typename Traits::PrimaryVariables& priVars) - { - // setting the mole fractions of the fluid state - for(int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - for (int compIdx = 0; compIdx < numComponents; ++compIdx) - actualFluidState.setMoleFraction( phaseIdx, - compIdx, - priVars[Indices::conti0EqIdx+phaseIdx*numComponents+compIdx] ); - - // For using the ... other way of calculating equilibrium - for(int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - for (int compIdx = 0; compIdx < numComponents; ++compIdx) - actualFluidState.setFugacityCoefficient( phaseIdx, - compIdx, - FluidSystem::fugacityCoefficient(actualFluidState, - paramCache, - phaseIdx, - compIdx) ); - - FluidState equilFluidState; // the fluidState *on the interface* i.e. chemical equilibrium - equilFluidState.assign(actualFluidState); - ConstraintSolver::solve(equilFluidState, paramCache, /*setViscosity=*/false, /*setEnthalpy=*/false); - - // Set the equilibrium composition (in a kinetic model not necessarily the same as the actual mole fraction) - for(int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - for (int compIdx = 0; compIdx < numComponents; ++compIdx) - xEquil_[phaseIdx][compIdx] = equilFluidState.moleFraction(phaseIdx, compIdx); - - // compute densities of all phases - for(int phaseIdx=0; phaseIdx<numPhases; ++phaseIdx) - actualFluidState.setDensity(phaseIdx, FluidSystem::density(actualFluidState, paramCache, phaseIdx)); - } - - /*! - * \brief Update the temperatures for a given control volume - * - * \param elemSol A vector containing all primary variables connected to the element - * \param problem The problem to be solved - * \param element An element which contains part of the control volume - * \param scv The sub-control volume - * \param fluidState Container for all the secondary variables concerning the fluids - */ - template<class ElemSol, class Problem, class Element, class Scv> - void updateTemperatures(const ElemSol& elemSol, - const Problem& problem, - const Element& element, - const Scv& scv, - FluidState& fluidState) - { - for(int phaseIdx=0; phaseIdx < numEnergyEqFluid; ++phaseIdx) - { - // retrieve temperature from solution vector - const Scalar T = elemSol[scv.localDofIndex()][Indices::temperature0Idx + phaseIdx]; - fluidState.setTemperature(phaseIdx, T); - } - - for(int solidPhaseIdx = numEnergyEqFluid; solidPhaseIdx < numEnergyEqFluid+numEnergyEqSolid; ++solidPhaseIdx) - temperatureSolid_ = elemSol[scv.localDofIndex()][Indices::temperature0Idx + solidPhaseIdx]; - } - - /*! - * \brief The mole fraction we would have in the case of chemical equilibrium - * on the interface. - * - * \param phaseIdx The index of the fluid phase - * \param compIdx The local index of the component - */ - const Scalar xEquil(const unsigned int phaseIdx, const unsigned int compIdx) const - { return xEquil_[phaseIdx][compIdx]; } - /*! * \brief The specific interfacial area between two fluid phases [m^2 / m^3] * \note This is _only_ required by the kinetic mass/energy modules @@ -635,8 +488,6 @@ public: return interfacialArea_[phaseIIdx][phaseJIdx]; } - //! Returns the temperature of the solid phase(s) - const Scalar temperatureSolid() const { return temperatureSolid_; } //! access function Reynolds Number const Scalar reynoldsNumber(const unsigned int phaseIdx) const { return reynoldsNumber_[phaseIdx]; } //! access function Prandtl Number @@ -656,18 +507,16 @@ public: private: //! dimensionless numbers - Scalar reynoldsNumber_[numPhases]; - Scalar prandtlNumber_[numPhases]; - Scalar nusseltNumber_[numPhases]; - Scalar schmidtNumber_[numPhases]; - Scalar sherwoodNumber_[numPhases]; + Scalar reynoldsNumber_[ModelTraits::numPhases()]; + Scalar prandtlNumber_[ModelTraits::numPhases()]; + Scalar nusseltNumber_[ModelTraits::numPhases()]; + Scalar schmidtNumber_[ModelTraits::numPhases()]; + Scalar sherwoodNumber_[ModelTraits::numPhases()]; Scalar characteristicLength_; Scalar factorEnergyTransfer_; Scalar factorMassTransfer_; Scalar solidSurface_ ; - Scalar interfacialArea_[numPhases+1][numPhases+1]; - Scalar xEquil_[numPhases][numComponents]; - Scalar temperatureSolid_; + Scalar interfacialArea_[ModelTraits::numPhases()+numEnergyEqSolid][ModelTraits::numPhases()+numEnergyEqSolid]; }; } // namespace Dumux diff --git a/dumux/porousmediumflow/richards/model.hh b/dumux/porousmediumflow/richards/model.hh index 0f64dd37b4c6b58411d8b2e07178979a200ceebc..c4dd576ae68a0299751532b2ac30a473d7e8651c 100644 --- a/dumux/porousmediumflow/richards/model.hh +++ b/dumux/porousmediumflow/richards/model.hh @@ -103,6 +103,9 @@ #include <dumux/material/components/simpleh2o.hh> #include <dumux/material/fluidsystems/h2oair.hh> #include <dumux/material/fluidstates/immiscible.hh> +#include <dumux/material/solidstates/inertsolidstate.hh> +#include <dumux/material/solidsystems/inertsolidphase.hh> +#include <dumux/material/components/constant.hh> #include <dumux/porousmediumflow/properties.hh> #include <dumux/porousmediumflow/nonisothermal/model.hh> @@ -147,12 +150,14 @@ struct RichardsModelTraits * \tparam PT The type used for permeabilities * \tparam MT The model traits */ -template<class PV, class FSY, class FST, class PT, class MT> +template<class PV, class FSY, class FST, class SSY, class SST, class PT, class MT> struct RichardsVolumeVariablesTraits { using PrimaryVariables = PV; using FluidSystem = FSY; using FluidState = FST; + using SolidSystem = SSY; + using SolidState = SST; using PermeabilityType = PT; using ModelTraits = MT; }; @@ -199,10 +204,12 @@ private: using PV = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); using FSY = typename GET_PROP_TYPE(TypeTag, FluidSystem); using FST = typename GET_PROP_TYPE(TypeTag, FluidState); + using SSY = typename GET_PROP_TYPE(TypeTag, SolidSystem); + using SST = typename GET_PROP_TYPE(TypeTag, SolidState); using MT = typename GET_PROP_TYPE(TypeTag, ModelTraits); using PT = typename GET_PROP_TYPE(TypeTag, SpatialParams)::PermeabilityType; - using Traits = RichardsVolumeVariablesTraits<PV, FSY, FST, PT, MT>; + using Traits = RichardsVolumeVariablesTraits<PV, FSY, FST, SSY, SST, PT, MT>; public: using type = RichardsVolumeVariables<Traits>; }; @@ -242,6 +249,24 @@ SET_PROP(Richards, FluidSystem) using type = FluidSystems::H2OAir<Scalar, Components::SimpleH2O<Scalar>, false>; }; +//! The two-phase model uses the immiscible fluid state +SET_PROP(Richards, SolidState) +{ +private: + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using SolidSystem = typename GET_PROP_TYPE(TypeTag, SolidSystem); +public: + using type = InertSolidState<Scalar, SolidSystem>; +}; + +// Set the fluid system +SET_PROP(Richards, SolidSystem) +{ + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using InertComponent = Components::Constant<1,Scalar>; + using type = SolidSystems::InertSolidPhase<Scalar, InertComponent>; +}; + /*! * \brief The fluid state which is used by the volume variables to * store the thermodynamic state. This should be chosen diff --git a/dumux/porousmediumflow/richards/volumevariables.hh b/dumux/porousmediumflow/richards/volumevariables.hh index 62478d4ffa9eaa37211e825e9fb2732758b6d324..0cc70307eb2ceae5cf5041490023049cc07a8ba1 100644 --- a/dumux/porousmediumflow/richards/volumevariables.hh +++ b/dumux/porousmediumflow/richards/volumevariables.hh @@ -29,6 +29,7 @@ #include <dune/common/exceptions.hh> #include <dumux/porousmediumflow/volumevariables.hh> +#include <dumux/porousmediumflow/nonisothermal/volumevariables.hh> #include <dumux/material/idealgas.hh> #include <dumux/material/constants.hh> @@ -43,19 +44,25 @@ namespace Dumux { */ template <class Traits> class RichardsVolumeVariables -: public PorousMediumFlowVolumeVariables<Traits, RichardsVolumeVariables<Traits>> +: public PorousMediumFlowVolumeVariables<Traits> + ,public EnergyVolumeVariables<Traits, RichardsVolumeVariables<Traits> > { - using ParentType = PorousMediumFlowVolumeVariables<Traits, RichardsVolumeVariables<Traits>>; + using ParentType = PorousMediumFlowVolumeVariables<Traits>; + using EnergyVolVars = EnergyVolumeVariables<Traits, RichardsVolumeVariables<Traits> >; using Scalar = typename Traits::PrimaryVariables::value_type; using PermeabilityType = typename Traits::PermeabilityType; using ModelTraits = typename Traits::ModelTraits; - + static constexpr int numComp = ParentType::numComponents(); public: //! export type of the fluid system using FluidSystem = typename Traits::FluidSystem; //! export type of the fluid state using FluidState = typename Traits::FluidState; //! export type of the fluid state + //! export type of solid state + using SolidState = typename Traits::SolidState; + //! export type of solid system + using SolidSystem = typename Traits::SolidSystem; using Indices = typename Traits::ModelTraits::Indices; //! if water diffusion in air is enabled static constexpr bool enableWaterDiffusionInAir() { return ModelTraits::enableMolecularDiffusion(); }; @@ -93,8 +100,7 @@ public: fluidState_.setSaturation(FluidSystem::liquidPhaseIdx, 0.0); fluidState_.setSaturation(FluidSystem::gasPhaseIdx, 1.0); - Scalar t = ParentType::temperature(elemSol, problem, element, scv); - fluidState_.setTemperature(t); + EnergyVolVars::updateTemperature(elemSol, problem, element, scv, fluidState_, solidState_); // get pc for sw = 0.0 const Scalar pc = MaterialLaw::pc(materialParams, 0.0); @@ -115,12 +121,12 @@ public: fluidState_.setViscosity(FluidSystem::liquidPhaseIdx, FluidSystem::viscosity(fluidState_, paramCache, FluidSystem::liquidPhaseIdx)); // compute and set the enthalpy - fluidState_.setEnthalpy(FluidSystem::liquidPhaseIdx, ParentType::enthalpy(fluidState_, paramCache, FluidSystem::liquidPhaseIdx)); - fluidState_.setEnthalpy(FluidSystem::gasPhaseIdx, ParentType::enthalpy(fluidState_, paramCache, FluidSystem::gasPhaseIdx)); + fluidState_.setEnthalpy(FluidSystem::liquidPhaseIdx, EnergyVolVars::enthalpy(fluidState_, paramCache, FluidSystem::liquidPhaseIdx)); + fluidState_.setEnthalpy(FluidSystem::gasPhaseIdx, EnergyVolVars::enthalpy(fluidState_, paramCache, FluidSystem::gasPhaseIdx)); } else if (phasePresence == Indices::bothPhases) { - completeFluidState(elemSol, problem, element, scv, fluidState_); + completeFluidState(elemSol, problem, element, scv, fluidState_, solidState_); // if we want to account for diffusion in the air phase // use Raoult to compute the water mole fraction in air @@ -140,14 +146,15 @@ public: } else if (phasePresence == Indices::liquidPhaseOnly) { - completeFluidState(elemSol, problem, element, scv, fluidState_); + completeFluidState(elemSol, problem, element, scv, fluidState_, solidState_); } ////////// // specify the other parameters ////////// relativePermeabilityWetting_ = MaterialLaw::krw(materialParams, fluidState_.saturation(FluidSystem::liquidPhaseIdx)); - porosity_ = problem.spatialParams().porosity(element, scv, elemSol); + updateSolidVolumeFractions(elemSol, problem, element, scv, solidState_, numComp); + EnergyVolVars::updateSolidEnergyParams(elemSol, problem, element, scv, solidState_); permeability_ = problem.spatialParams().permeability(element, scv, elemSol); } @@ -165,14 +172,14 @@ public: * \param fluidState The fluid state to fill. */ template<class ElemSol, class Problem, class Element, class Scv> - static void completeFluidState(const ElemSol& elemSol, - const Problem& problem, - const Element& element, - const Scv& scv, - FluidState& fluidState) + void completeFluidState(const ElemSol& elemSol, + const Problem& problem, + const Element& element, + const Scv& scv, + FluidState& fluidState, + SolidState& solidState) { - Scalar t = ParentType::temperature(elemSol, problem, element, scv); - fluidState.setTemperature(t); + EnergyVolVars::updateTemperature(elemSol, problem, element, scv, fluidState, solidState); const auto& materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol); const auto& priVars = ParentType::extractDofPriVars(elemSol, scv); @@ -202,8 +209,8 @@ public: fluidState.setViscosity(FluidSystem::liquidPhaseIdx, FluidSystem::viscosity(fluidState, paramCache, FluidSystem::liquidPhaseIdx)); // compute and set the enthalpy - fluidState.setEnthalpy(FluidSystem::liquidPhaseIdx, ParentType::enthalpy(fluidState, paramCache, FluidSystem::liquidPhaseIdx)); - fluidState.setEnthalpy(FluidSystem::gasPhaseIdx, ParentType::enthalpy(fluidState, paramCache, FluidSystem::gasPhaseIdx)); + fluidState.setEnthalpy(FluidSystem::liquidPhaseIdx, EnergyVolVars::enthalpy(fluidState, paramCache, FluidSystem::liquidPhaseIdx)); + fluidState.setEnthalpy(FluidSystem::gasPhaseIdx, EnergyVolVars::enthalpy(fluidState, paramCache, FluidSystem::gasPhaseIdx)); } /*! @@ -213,6 +220,12 @@ public: const FluidState &fluidState() const { return fluidState_; } + /*! + * \brief Returns the phase state for the control volume. + */ + const SolidState &solidState() const + { return solidState_; } + /*! * \brief Return the temperature */ @@ -226,7 +239,7 @@ public: * total volume, i.e. \f[ \Phi := \frac{V_{pore}}{V_{pore} + V_{rock}} \f] */ Scalar porosity() const - { return porosity_; } + { return solidState_.porosity(); } /*! * \brief Returns the permeability within the control volume in \f$[m^2]\f$. @@ -349,7 +362,7 @@ public: * manually do a conversion. */ Scalar waterContent(const int phaseIdx = FluidSystem::liquidPhaseIdx) const - { return saturation(phaseIdx) * porosity_; } + { return saturation(phaseIdx) * solidState_.porosity(); } /*! * \brief Returns the mole fraction of a given component in a @@ -392,8 +405,8 @@ public: protected: FluidState fluidState_; //!< the fluid state + SolidState solidState_; Scalar relativePermeabilityWetting_; //!< the relative permeability of the wetting phase - Scalar porosity_; //!< the porosity PermeabilityType permeability_; //!< the instrinsic permeability Scalar minPc_; //!< the minimum capillary pressure (entry pressure) Scalar moleFraction_[ParentType::numPhases()]; //!< The water mole fractions in water and air diff --git a/dumux/porousmediumflow/richardsnc/model.hh b/dumux/porousmediumflow/richardsnc/model.hh index d485c750174d52ea1791600c14115145a39afcd6..13fced36941309e0080ff77b9d71195ad0cdf09e 100644 --- a/dumux/porousmediumflow/richardsnc/model.hh +++ b/dumux/porousmediumflow/richardsnc/model.hh @@ -78,6 +78,9 @@ #include <dumux/material/components/constant.hh> #include <dumux/material/fluidsystems/liquidphase2c.hh> #include <dumux/material/fluidstates/compositional.hh> +#include <dumux/material/solidstates/inertsolidstate.hh> +#include <dumux/material/solidsystems/inertsolidphase.hh> +#include <dumux/material/components/constant.hh> #include <dumux/porousmediumflow/properties.hh> #include <dumux/porousmediumflow/nonisothermal/model.hh> @@ -160,11 +163,13 @@ SET_PROP(RichardsNC, VolumeVariables) private: using PV = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); using FSY = typename GET_PROP_TYPE(TypeTag, FluidSystem); + using SSY = typename GET_PROP_TYPE(TypeTag, SolidSystem); + using SST = typename GET_PROP_TYPE(TypeTag, SolidState); using FST = typename GET_PROP_TYPE(TypeTag, FluidState); using MT = typename GET_PROP_TYPE(TypeTag, ModelTraits); using PT = typename GET_PROP_TYPE(TypeTag, SpatialParams)::PermeabilityType; - using Traits = RichardsVolumeVariablesTraits<PV, FSY, FST, PT, MT>; + using Traits = RichardsVolumeVariablesTraits<PV, FSY, FST, SSY, SST, PT, MT>; public: using type = RichardsNCVolumeVariables<Traits>; }; @@ -184,6 +189,24 @@ SET_PROP(RichardsNC, FluidSystem) using type = FluidSystems::LiquidPhaseTwoC<Scalar, Components::SimpleH2O<Scalar>, Components::Constant<1, Scalar>>; }; +//! The two-phase model uses the immiscible fluid state +SET_PROP(RichardsNC, SolidState) +{ +private: + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using SolidSystem = typename GET_PROP_TYPE(TypeTag, SolidSystem); +public: + using type = InertSolidState<Scalar, SolidSystem>; +}; + +// Set the fluid system +SET_PROP(RichardsNC, SolidSystem) +{ + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using InertComponent = Components::Constant<1,Scalar>; + using type = SolidSystems::InertSolidPhase<Scalar, InertComponent>; +}; + /*! * \brief The fluid state which is used by the volume variables to * store the thermodynamic state. This should be chosen diff --git a/dumux/porousmediumflow/richardsnc/volumevariables.hh b/dumux/porousmediumflow/richardsnc/volumevariables.hh index e3c05f0ce28f44a2456c7f129d0f8112f3ee3b45..b502b234866a739d4128a26de79690c5a0a36a18 100644 --- a/dumux/porousmediumflow/richardsnc/volumevariables.hh +++ b/dumux/porousmediumflow/richardsnc/volumevariables.hh @@ -26,6 +26,7 @@ #define DUMUX_RICHARDSNC_VOLUME_VARIABLES_HH #include <dumux/porousmediumflow/volumevariables.hh> +#include <dumux/porousmediumflow/nonisothermal/volumevariables.hh> namespace Dumux { @@ -36,9 +37,11 @@ namespace Dumux { */ template <class Traits> class RichardsNCVolumeVariables -: public PorousMediumFlowVolumeVariables<Traits, RichardsNCVolumeVariables<Traits>> +: public PorousMediumFlowVolumeVariables<Traits> + ,public EnergyVolumeVariables<Traits, RichardsNCVolumeVariables<Traits> > { - using ParentType = PorousMediumFlowVolumeVariables<Traits, RichardsNCVolumeVariables<Traits>>; + using ParentType = PorousMediumFlowVolumeVariables<Traits>; + using EnergyVolVars = EnergyVolumeVariables<Traits, RichardsNCVolumeVariables<Traits> >; using Scalar = typename Traits::PrimaryVariables::value_type; using PermeabilityType = typename Traits::PermeabilityType; using Idx = typename Traits::ModelTraits::Indices; @@ -51,6 +54,10 @@ public: using FluidSystem = typename Traits::FluidSystem; //! export type of the fluid state using FluidState = typename Traits::FluidState; + //! export type of solid state + using SolidState = typename Traits::SolidState; + //! export type of solid system + using SolidSystem = typename Traits::SolidSystem; //! export indices using Indices = typename Traits::ModelTraits::Indices; //! export phase acess indices @@ -74,7 +81,7 @@ public: { ParentType::update(elemSol, problem, element, scv); - completeFluidState(elemSol, problem, element, scv, fluidState_); + completeFluidState(elemSol, problem, element, scv, fluidState_, solidState_); ////////// // specify the other parameters ////////// @@ -86,7 +93,9 @@ public: // needed to make sure we don't compute unphysical capillary pressures and thus saturations minPc_ = MaterialLaw::endPointPc(materialParams); pn_ = problem.nonWettingReferencePressure(); - porosity_ = problem.spatialParams().porosity(element, scv, elemSol); + //porosity + updateSolidVolumeFractions(elemSol, problem, element, scv, solidState_, ParentType::numComponents()); + EnergyVolVars::updateSolidEnergyParams(elemSol, problem, element, scv, solidState_); permeability_ = problem.spatialParams().permeability(element, scv, elemSol); // Second instance of a parameter cache. @@ -120,14 +129,14 @@ public: * \param fluidState The fluid state to fill. */ template<class ElemSol, class Problem, class Element, class Scv> - static void completeFluidState(const ElemSol& elemSol, - const Problem& problem, - const Element& element, - const Scv& scv, - FluidState& fluidState) + void completeFluidState(const ElemSol& elemSol, + const Problem& problem, + const Element& element, + const Scv& scv, + FluidState& fluidState, + SolidState& solidState) { - Scalar t = ParentType::temperature(elemSol, problem, element, scv); - fluidState.setTemperature(t); + EnergyVolVars::updateTemperature(elemSol, problem, element, scv, fluidState, solidState); const auto& materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol); const auto& priVars = ParentType::extractDofPriVars(elemSol, scv); @@ -169,7 +178,7 @@ public: fluidState.setViscosity(fluidSystemPhaseIdx, FluidSystem::viscosity(fluidState, paramCache, fluidSystemPhaseIdx)); // compute and set the enthalpy - fluidState.setEnthalpy(fluidSystemPhaseIdx, ParentType::enthalpy(fluidState, paramCache, fluidSystemPhaseIdx)); + fluidState.setEnthalpy(fluidSystemPhaseIdx, EnergyVolVars::enthalpy(fluidState, paramCache, fluidSystemPhaseIdx)); } /*! @@ -179,6 +188,12 @@ public: const FluidState &fluidState() const { return fluidState_; } + /*! + * \brief Returns the phase state for the control volume. + */ + const SolidState &solidState() const + { return solidState_; } + /*! * \brief Return the temperature */ @@ -192,7 +207,7 @@ public: * total volume, i.e. \f[ \Phi := \frac{V_{pore}}{V_{pore} + V_{rock}} \f] */ Scalar porosity() const - { return porosity_; } + { return solidState_.porosity(); } /*! * \brief Returns the permeability within the control volume in \f$[m^2]\f$. @@ -315,7 +330,7 @@ public: * manually do a conversion. */ Scalar waterContent(const int phaseIdx = fluidSystemPhaseIdx) const - { return saturation(phaseIdx) * porosity_; } + { return saturation(phaseIdx) * solidState_.porosity(); } /*! * \brief Return molar density \f$\mathrm{[mol/m^3]}\f$ the of the fluid phase. @@ -383,7 +398,7 @@ private: std::array<Scalar, ParentType::numComponents()-1> diffCoefficient_; Scalar relativePermeabilityWetting_; //!< the relative permeability of the wetting phase - Scalar porosity_; //!< the porosity + SolidState solidState_; PermeabilityType permeability_; //!< the instrinsic permeability Scalar pn_; //!< the reference non-wetting pressure Scalar minPc_; //!< the minimum capillary pressure (entry pressure) diff --git a/dumux/porousmediumflow/tracer/model.hh b/dumux/porousmediumflow/tracer/model.hh index 3af6b8f24ffefde83acec9320a65921f2e2a3774..492433ef7720c52de475e7b48375489b7ff376c7 100644 --- a/dumux/porousmediumflow/tracer/model.hh +++ b/dumux/porousmediumflow/tracer/model.hh @@ -55,6 +55,9 @@ #include <dumux/discretization/stationaryvelocityfield.hh> #include <dumux/material/fluidmatrixinteractions/diffusivityconstanttortuosity.hh> #include <dumux/porousmediumflow/properties.hh> +#include <dumux/material/solidstates/inertsolidstate.hh> +#include <dumux/material/solidsystems/inertsolidphase.hh> +#include <dumux/material/components/constant.hh> #include "indices.hh" #include "volumevariables.hh" @@ -94,11 +97,13 @@ struct TracerModelTraits * \tparam FSY The fluid system type * \tparam MT The model traits */ -template<class PV, class FSY, class MT> +template<class PV, class FSY, class SSY, class SST, class MT> struct TracerVolumeVariablesTraits { using PrimaryVariables = PV; using FluidSystem = FSY; + using SolidSystem = SSY; + using SolidState = SST; using ModelTraits = MT; }; @@ -128,6 +133,24 @@ public: using type = TracerModelTraits<FluidSystem::numComponents, GET_PROP_VALUE(TypeTag, UseMoles)>; }; +//! The two-phase model uses the immiscible fluid state +SET_PROP(Tracer, SolidState) +{ +private: + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using SolidSystem = typename GET_PROP_TYPE(TypeTag, SolidSystem); +public: + using type = InertSolidState<Scalar, SolidSystem>; +}; + +// Set the fluid system +SET_PROP(Tracer, SolidSystem) +{ + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using InertComponent = Components::Constant<1,Scalar>; + using type = SolidSystems::InertSolidPhase<Scalar, InertComponent>; +}; + //! Use the tracer local residual function for the tracer model SET_TYPE_PROP(Tracer, LocalResidual, TracerLocalResidual<TypeTag>); @@ -140,9 +163,11 @@ SET_PROP(Tracer, VolumeVariables) private: using PV = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); using FSY = typename GET_PROP_TYPE(TypeTag, FluidSystem); + using SSY = typename GET_PROP_TYPE(TypeTag, SolidSystem); + using SST = typename GET_PROP_TYPE(TypeTag, SolidState); using MT = typename GET_PROP_TYPE(TypeTag, ModelTraits); - using Traits = TracerVolumeVariablesTraits<PV, FSY, MT>; + using Traits = TracerVolumeVariablesTraits<PV, FSY, SSY, SST, MT>; public: using type = TracerVolumeVariables<Traits>; }; diff --git a/dumux/porousmediumflow/tracer/volumevariables.hh b/dumux/porousmediumflow/tracer/volumevariables.hh index 12e9d1641beed83e52c30ae8a2b4d6283f251d46..5c0613ba39391f84f7c96afa1280c6f70cff3470 100644 --- a/dumux/porousmediumflow/tracer/volumevariables.hh +++ b/dumux/porousmediumflow/tracer/volumevariables.hh @@ -35,16 +35,16 @@ namespace Dumux { */ template <class Traits> class TracerVolumeVariables -: public PorousMediumFlowVolumeVariables<Traits, TracerVolumeVariables<Traits>> +: public PorousMediumFlowVolumeVariables<Traits> { - using ParentType = PorousMediumFlowVolumeVariables<Traits, TracerVolumeVariables<Traits>>; - + using ParentType = PorousMediumFlowVolumeVariables<Traits>; using Scalar = typename Traits::PrimaryVariables::value_type; static constexpr bool useMoles = Traits::ModelTraits::useMoles(); public: //! export fluid system type using FluidSystem = typename Traits::FluidSystem; + using SolidState = typename Traits::SolidState; /*! * \brief Update all quantities for a given control volume @@ -64,7 +64,7 @@ public: // update parent type sets primary variables ParentType::update(elemSol, problem, element, scv); - porosity_ = problem.spatialParams().porosity(element, scv, elemSol); + updateSolidVolumeFractions(elemSol, problem, element, scv, solidState_, ParentType::numComponents()); // dispersivity_ = problem.spatialParams().dispersivity(element, scv, elemSol); // the spatial params special to the tracer model @@ -88,6 +88,12 @@ public: Scalar density(int pIdx = 0) const { return fluidDensity_; } + /*! + * \brief Returns the phase state for the control volume. + */ + const SolidState &solidState() const + { return solidState_; } + /*! * \brief Return the saturation * @@ -165,10 +171,10 @@ public: * \brief Return the average porosity \f$\mathrm{[-]}\f$ within the control volume. */ Scalar porosity() const - { return porosity_; } + { return solidState_.porosity(); } protected: - Scalar porosity_; // Effective porosity within the control volume + SolidState solidState_; Scalar fluidDensity_, fluidMolarMass_; // DispersivityType dispersivity_; std::array<Scalar, ParentType::numComponents()> diffCoeff_; diff --git a/dumux/porousmediumflow/volumevariables.hh b/dumux/porousmediumflow/volumevariables.hh index eb7961aa8231518a5a2e6f001b75cfb36a3fb010..394ad09102e223e55a2aa389e0d7fbc33e248e17 100644 --- a/dumux/porousmediumflow/volumevariables.hh +++ b/dumux/porousmediumflow/volumevariables.hh @@ -29,22 +29,6 @@ namespace Dumux { -// forward declaration -template<class Traits, class Impl, bool enableEnergyBalance> -class PorousMediumFlowVolumeVariablesImplementation; - -/*! - * \ingroup PorousmediumFlow - * \brief Base class for the model specific class which provides - * access to all volume averaged quantities. The volume variables base class - * is specialized for isothermal and non-isothermal models. - * - * \tparam Traits The volume variables traits - * \tparam Impl The implementation of the volume variables - */ -template<class Traits, class Impl> -using PorousMediumFlowVolumeVariables = PorousMediumFlowVolumeVariablesImplementation<Traits, Impl, Traits::ModelTraits::enableEnergyBalance()>; - /*! * \ingroup PorousmediumFlow * \brief The isothermal base class @@ -52,8 +36,8 @@ using PorousMediumFlowVolumeVariables = PorousMediumFlowVolumeVariablesImplement * \tparam Traits The volume variables traits * \tparam Impl The implementation of the volume variables */ -template<class Traits, class Impl> -class PorousMediumFlowVolumeVariablesImplementation<Traits, Impl, false> +template<class Traits> +class PorousMediumFlowVolumeVariables { using Scalar = typename Traits::PrimaryVariables::value_type; @@ -124,152 +108,11 @@ public: Scalar extrusionFactor() const { return extrusionFactor_; } - //! The temperature is obtained from the problem as a constant for isothermal models - template<class ElemSol, class Problem, class Element, class Scv> - static Scalar temperature(const ElemSol &elemSol, - const Problem& problem, - const Element &element, - const Scv &scv) - { - return problem.temperatureAtPos(scv.dofPosition()); - } - - //! The phase enthalpy is zero for isothermal models - //! This is needed for completing the fluid state - template<class FluidState, class ParameterCache> - static Scalar enthalpy(const FluidState& fluidState, - const ParameterCache& paramCache, - const int phaseIdx) - { - return 0; - } - private: PrimaryVariables priVars_; Scalar extrusionFactor_; }; -/*! - * \ingroup PorousmediumFlow - * \brief The non-isothermal base class - * - * \tparam Traits The volume variables traits - * \tparam Impl The implementation of the volume variables - */ -template<class Traits, class Impl> -class PorousMediumFlowVolumeVariablesImplementation<Traits, Impl, true> -: public PorousMediumFlowVolumeVariablesImplementation<Traits, Impl, false> -{ - using ParentType = PorousMediumFlowVolumeVariablesImplementation<Traits, Impl, false>; - using Scalar = typename Traits::PrimaryVariables::value_type; - -public: - //! export the type used for the primary variables - using PrimaryVariables = typename Traits::PrimaryVariables; - //! export the underlying fluid system - using FluidSystem = typename Traits::FluidSystem; - //! export the type encapsulating primary variable indices - using Indices = typename Traits::ModelTraits::Indices; - - /*! - * \brief Update all quantities for a given control volume - * - * \param priVars A vector containing the primary variables for the control volume - * \param problem The object specifying the problem which ought to - * be simulated - * \param element An element which contains part of the control volume - * \param fvGeometry The finite volume geometry for the element - * \param scvIdx Local index of the sub control volume which is inside the element - */ - template<class ElemSol, class Problem, class Element, class Scv> - void update(const ElemSol &elemSol, - const Problem &problem, - const Element &element, - const Scv &scv) - { - ParentType::update(elemSol, problem, element, scv); - - solidHeatCapacity_ = problem.spatialParams().solidHeatCapacity(element, scv, elemSol); - solidDensity_ = problem.spatialParams().solidDensity(element, scv, elemSol); - solidThermalConductivity_ = problem.spatialParams().solidThermalConductivity(element, scv, elemSol); - } - - /*! - * \brief Returns the total internal energy of a phase in the - * sub-control volume. - * - * \param phaseIdx The phase index - */ - Scalar internalEnergy(const int phaseIdx) const - { return asImp_().fluidState().internalEnergy(phaseIdx); } - - /*! - * \brief Returns the total enthalpy of a phase in the sub-control - * volume. - * - * \param phaseIdx The phase index - */ - Scalar enthalpy(const int phaseIdx) const - { return asImp_().fluidState().enthalpy(phaseIdx); } - - /*! - * \brief Returns the total heat capacity \f$\mathrm{[J/(kg K)]}\f$ of the rock matrix in - * the sub-control volume. - */ - Scalar solidHeatCapacity() const - { return solidHeatCapacity_; } - - /*! - * \brief Returns the mass density \f$\mathrm{[kg/m^3]}\f$ of the rock matrix in - * the sub-control volume. - */ - Scalar solidDensity() const - { return solidDensity_; } - - /*! - * \brief Returns the thermal conductivity \f$\mathrm{[W/(m*K)]}\f$ of a fluid phase in - * the sub-control volume. - */ - Scalar fluidThermalConductivity(const int phaseIdx) const - { return FluidSystem::thermalConductivity(asImp_().fluidState(), phaseIdx); } - - /*! - * \brief Returns the thermal conductivity \f$\mathrm{[W/(m*K)]}\f$ of the solid phase in - * the sub-control volume. - */ - Scalar solidThermalConductivity() const - { return solidThermalConductivity_; } - - //! The temperature is a primary variable for non-isothermal models - template<class ElemSol, class Problem, class Element, class Scv> - static Scalar temperature(const ElemSol &elemSol, - const Problem& problem, - const Element &element, - const Scv &scv) - { - return ParentType::extractDofPriVars(elemSol, scv)[Indices::temperatureIdx]; - } - - //! The phase enthalpy is zero for isothermal models - //! This is needed for completing the fluid state - template<class FluidState, class ParameterCache> - static Scalar enthalpy(const FluidState& fluidState, - const ParameterCache& paramCache, - const int phaseIdx) - { - return FluidSystem::enthalpy(fluidState, paramCache, phaseIdx); - } - -protected: - const Impl &asImp_() const { return *static_cast<const Impl*>(this); } - Impl &asImp_() { return *static_cast<Impl*>(this); } - -private: - Scalar solidHeatCapacity_; - Scalar solidDensity_; - Scalar solidThermalConductivity_; -}; - } // end namespace Dumux #endif diff --git a/test/porousmediumflow/1p/implicit/1pniconductionproblem.hh b/test/porousmediumflow/1p/implicit/1pniconductionproblem.hh index 960e3c5e0676402ba9dbb583eb44377579e6b8d2..05e761b332d24f88b13d345e2eeae418b385ee16 100644 --- a/test/porousmediumflow/1p/implicit/1pniconductionproblem.hh +++ b/test/porousmediumflow/1p/implicit/1pniconductionproblem.hh @@ -158,8 +158,8 @@ public: const auto porosity = this->spatialParams().porosity(someElement, someScv, someElemSol); const auto densityW = volVars.density(); const auto heatCapacityW = IapwsH2O::liquidHeatCapacity(someInitSol[temperatureIdx], someInitSol[pressureIdx]); - const auto densityS = this->spatialParams().solidDensity(someElement, someScv, someElemSol); - const auto heatCapacityS = this->spatialParams().solidHeatCapacity(someElement, someScv, someElemSol); + const auto densityS = volVars.solidDensity(); + const auto heatCapacityS = volVars.solidHeatCapacity(); const auto storage = densityW*heatCapacityW*porosity + densityS*heatCapacityS*(1 - porosity); const auto effectiveThermalConductivity = ThermalConductivityModel::effectiveThermalConductivity(volVars, this->spatialParams(), someElement, fvGeometry, someScv); diff --git a/test/porousmediumflow/1p/implicit/1pniconvectionproblem.hh b/test/porousmediumflow/1p/implicit/1pniconvectionproblem.hh index 6b2037bc79d0b287c6b291c2648ebe32deedf9b3..821711888ba171e4362879252632042f11f2cfb9 100644 --- a/test/porousmediumflow/1p/implicit/1pniconvectionproblem.hh +++ b/test/porousmediumflow/1p/implicit/1pniconvectionproblem.hh @@ -173,8 +173,8 @@ public: const auto densityW = volVars.density(); const auto heatCapacityW = IapwsH2O::liquidHeatCapacity(someInitSol[temperatureIdx], someInitSol[pressureIdx]); const auto storageW = densityW*heatCapacityW*porosity; - const auto densityS = this->spatialParams().solidDensity(someElement, someScv, someElemSol); - const auto heatCapacityS = this->spatialParams().solidHeatCapacity(someElement, someScv, someElemSol); + const auto densityS = volVars.solidDensity(); + const auto heatCapacityS = volVars.solidHeatCapacity(); const auto storageTotal = storageW + densityS*heatCapacityS*(1 - porosity); std::cout << "storage: " << storageTotal << '\n'; diff --git a/test/porousmediumflow/1p/implicit/compressible/spatialparams.hh b/test/porousmediumflow/1p/implicit/compressible/spatialparams.hh index 1de2a20b2fa4ca08b4d9c2cb1842fe3b1a37810b..593b7c5dfcba6f1584146b4be46ca9855bd8da76 100644 --- a/test/porousmediumflow/1p/implicit/compressible/spatialparams.hh +++ b/test/porousmediumflow/1p/implicit/compressible/spatialparams.hh @@ -82,18 +82,11 @@ public: } /*! - * \brief Function for defining the porosity. - * That is possibly solution dependent. + * \brief Define the porosity \f$\mathrm{[-]}\f$. * - * \param element The current element - * \param scv The sub-control volume inside the element. - * \param elemSol The solution at the dofs connected to the element. - * \return the porosity + * \param globalPos The global position */ - template<class ElementSolution> - Scalar porosity(const Element &element, - const SubControlVolume &scv, - const ElementSolution &elemSol) const + Scalar porosityAtPos(const GlobalPosition& globalPos) const { return 0.4; } private: diff --git a/test/porousmediumflow/1p/implicit/incompressible/spatialparams.hh b/test/porousmediumflow/1p/implicit/incompressible/spatialparams.hh index 882df6d77f830f6b67e61bee92278e44d50b1a4c..d0a09a32278424e5fdf4ecc9763f323b3723bf32 100644 --- a/test/porousmediumflow/1p/implicit/incompressible/spatialparams.hh +++ b/test/porousmediumflow/1p/implicit/incompressible/spatialparams.hh @@ -82,18 +82,11 @@ public: } /*! - * \brief Function for defining the porosity. - * That is possibly solution dependent. + * \brief Define the porosity \f$\mathrm{[-]}\f$. * - * \param element The current element - * \param scv The sub-control volume inside the element. - * \param elemSol The solution at the dofs connected to the element. - * \return the porosity + * \param globalPos The global position */ - template<class ElementSolution> - Scalar porosity(const Element &element, - const SubControlVolume &scv, - const ElementSolution &elemSol) const + Scalar porosityAtPos(const GlobalPosition& globalPos) const { return 0.4; } private: diff --git a/test/porousmediumflow/1p/implicit/pointsources/1psingularityspatialparams.hh b/test/porousmediumflow/1p/implicit/pointsources/1psingularityspatialparams.hh index f721802c46be12600a577a0ff990cc97583d491a..045ba97df63ebd9794f3f386a79bee98ccb4f2df 100644 --- a/test/porousmediumflow/1p/implicit/pointsources/1psingularityspatialparams.hh +++ b/test/porousmediumflow/1p/implicit/pointsources/1psingularityspatialparams.hh @@ -48,6 +48,7 @@ class OnePSingularitySpatialParams using Element = typename GridView::template Codim<0>::Entity; using ParentType = FVSpatialParamsOneP<FVGridGeometry, Scalar, OnePSingularitySpatialParams<TypeTag>>; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; public: // export permeability type using PermeabilityType = Scalar; @@ -75,20 +76,13 @@ public: return permeability_; } - /*! \brief Define the porosity in [-]. + /*! + * \brief Define the porosity \f$\mathrm{[-]}\f$. * - * \param element The element - * \param scv The sub control volume - * \param elemSol The element solution vector - * \return the porosity + * \param globalPos The global position */ - template<class ElementSolution> - Scalar porosity(const Element& element, - const SubControlVolume& scv, - const ElementSolution& elemSol) const - { - return porosity_; - } + Scalar porosityAtPos(const GlobalPosition& globalPos) const + { return porosity_; } private: Scalar permeability_, porosity_; diff --git a/test/porousmediumflow/1p/implicit/test_1pnifv_conduction.input b/test/porousmediumflow/1p/implicit/test_1pnifv_conduction.input index d422c0e066fbbef50e8b9168c1ff9d1af9f8a1e2..663d9547bfa18b0230ecec2445e27ac0bc0e58f0 100644 --- a/test/porousmediumflow/1p/implicit/test_1pnifv_conduction.input +++ b/test/porousmediumflow/1p/implicit/test_1pnifv_conduction.input @@ -19,3 +19,8 @@ AddVelocity = true # enable velocity output [MpfaTest.Vtk] AddVelocity = false # enable velocity output + +[Component] +SolidDensity = 2700 +SolidThermalConductivity = 2.8 +SolidHeatCapacity = 790 diff --git a/test/porousmediumflow/1p/implicit/test_1pnifv_convection.input b/test/porousmediumflow/1p/implicit/test_1pnifv_convection.input index dc99b4a8b04f1bdcb2d280ca96a77df96462328a..1bab248e671fa7bec7d00c97fa21ee9eed5c4fd8 100644 --- a/test/porousmediumflow/1p/implicit/test_1pnifv_convection.input +++ b/test/porousmediumflow/1p/implicit/test_1pnifv_convection.input @@ -19,3 +19,8 @@ AddVelocity = true # enable velocity output [MpfaTest.Vtk] AddVelocity = false # enable velocity output + +[Component] +SolidDensity = 2700 +solidThermalConductivity = 2.8 +solidHeatCapacity = 790 diff --git a/test/porousmediumflow/1p/implicit/tubesspatialparams.hh b/test/porousmediumflow/1p/implicit/tubesspatialparams.hh index 02ffb0103c94a233af5069101d0cb88e52a3efa3..39a710f8f700f2c5342ae8fef978ed6cf171d238 100644 --- a/test/porousmediumflow/1p/implicit/tubesspatialparams.hh +++ b/test/porousmediumflow/1p/implicit/tubesspatialparams.hh @@ -48,6 +48,8 @@ class TubesTestSpatialParams using Element = typename GridView::template Codim<0>::Entity; using ParentType = FVSpatialParamsOneP<FVGridGeometry, Scalar, TubesTestSpatialParams<TypeTag>>; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + public: // export permeability type using PermeabilityType = Scalar; @@ -93,18 +95,12 @@ public: } /*! - * \brief Returns the porosity \f$[-]\f$ + * \brief Define the porosity \f$\mathrm{[-]}\f$. * - * \param element The element - * \param scv The sub control volume - * \param elemSol The element solution vector - * \return the porosity + * \param globalPos The global position */ - template<class ElementSolution> - Scalar porosity(const Element& element, - const SubControlVolume& scv, - const ElementSolution& elemSol) const - { return 1.0; } + Scalar porosityAtPos(const GlobalPosition& globalPos) const + { return 1; } private: Scalar radius_, radiusMain_; diff --git a/test/porousmediumflow/1pnc/implicit/1p2cniconductionproblem.hh b/test/porousmediumflow/1pnc/implicit/1p2cniconductionproblem.hh index e2618e16a58814893def96f8ad2fac662fe58164..f44551cf1f4af0a594cb5b679e642f5cfb76200b 100644 --- a/test/porousmediumflow/1pnc/implicit/1p2cniconductionproblem.hh +++ b/test/porousmediumflow/1pnc/implicit/1p2cniconductionproblem.hh @@ -165,11 +165,11 @@ public: VolumeVariables volVars; volVars.update(someElemSol, *this, someElement, someScv); - const auto porosity = this->spatialParams().porosity(someElement, someScv, someElemSol); + const auto porosity = this->spatialParams().porosity(someElement, someScv); const auto densityW = volVars.density(); const auto heatCapacityW = IapwsH2O::liquidHeatCapacity(someInitSol[temperatureIdx], someInitSol[pressureIdx]); - const auto densityS = this->spatialParams().solidDensity(someElement, someScv, someElemSol); - const auto heatCapacityS = this->spatialParams().solidHeatCapacity(someElement, someScv, someElemSol); + const auto densityS = volVars.solidDensity(); + const auto heatCapacityS = volVars.solidHeatCapacity(); const auto storage = densityW*heatCapacityW*porosity + densityS*heatCapacityS*(1 - porosity); const auto effectiveThermalConductivity = ThermalConductivityModel::effectiveThermalConductivity(volVars, this->spatialParams(), someElement, fvGeometry, someScv); diff --git a/test/porousmediumflow/1pnc/implicit/1p2cniconvectionproblem.hh b/test/porousmediumflow/1pnc/implicit/1p2cniconvectionproblem.hh index f0d72e82a3b24e45cc27a4dfbd1d5b0ade849d9f..3a4624dbb6ab425e89fc1f8b79c9e1ce2b465b33 100644 --- a/test/porousmediumflow/1pnc/implicit/1p2cniconvectionproblem.hh +++ b/test/porousmediumflow/1pnc/implicit/1p2cniconvectionproblem.hh @@ -179,12 +179,12 @@ public: VolumeVariables volVars; volVars.update(someElemSol, *this, someElement, someScv); - const auto porosity = this->spatialParams().porosity(someElement, someScv, someElemSol); + const auto porosity = this->spatialParams().porosity(someElement, someScv); const auto densityW = volVars.density(); const auto heatCapacityW = IapwsH2O::liquidHeatCapacity(someInitSol[temperatureIdx], someInitSol[pressureIdx]); const auto storageW = densityW*heatCapacityW*porosity; - const auto densityS = this->spatialParams().solidDensity(someElement, someScv, someElemSol); - const auto heatCapacityS = this->spatialParams().solidHeatCapacity(someElement, someScv, someElemSol); + const auto densityS = volVars.solidDensity(); + const auto heatCapacityS = volVars.solidHeatCapacity(); const auto storageTotal = storageW + densityS*heatCapacityS*(1 - porosity); std::cout << "storage: " << storageTotal << '\n'; diff --git a/test/porousmediumflow/1pnc/implicit/1pnctestspatialparams.hh b/test/porousmediumflow/1pnc/implicit/1pnctestspatialparams.hh index 9508c38e29a944bf2de5f8b44251312cfa82aded..98e90db42a912ff2e4baa6fa70429abeaed8e0c6 100644 --- a/test/porousmediumflow/1pnc/implicit/1pnctestspatialparams.hh +++ b/test/porousmediumflow/1pnc/implicit/1pnctestspatialparams.hh @@ -60,9 +60,6 @@ public: { permeability_ = 1e-10; porosity_ = 0.4; - - // heat conductivity of granite - lambdaSolid_ = 2.8; } /*! @@ -94,55 +91,9 @@ public: const ElementSolution& elemSol) const { return 0; } - /*! - * \brief Returns the heat capacity \f$[J / (kg K)]\f$ of the rock matrix. - * - * This is only required for non-isothermal models. - * - * \param element The element - * \param scv The sub control volume - * \param elemSol The element solution vector - */ - template<class ElementSolution> - Scalar solidHeatCapacity(const Element &element, - const SubControlVolume& scv, - const ElementSolution& elemSol) const - { return 790; /*specific heat capacity of granite [J / (kg K)]*/ } - - /*! - * \brief Returns the mass density \f$[kg / m^3]\f$ of the rock matrix. - * - * This is only required for non-isothermal models. - * - * \param element The element - * \param scv The sub control volume - * \param elemSol The element solution vector - */ - template<class ElementSolution> - Scalar solidDensity(const Element &element, - const SubControlVolume& scv, - const ElementSolution& elemSol) const - { return 2700; /*density of granite [kg/m^3]*/ } - - /*! - * \brief Returns the thermal conductivity \f$\mathrm{[W/(m K)]}\f$ of the porous material. - * - * \param element The element - * \param scv The sub control volume - * \param elemSol The element solution vector - */ - template<class ElementSolution> - Scalar solidThermalConductivity(const Element &element, - const SubControlVolume& scv, - const ElementSolution& elemSol) const - { return lambdaSolid_; } - - - private: Scalar permeability_; Scalar porosity_; - Scalar lambdaSolid_; }; } // end namespace Dumux diff --git a/test/porousmediumflow/1pnc/implicit/test_1p2cni_conduction_fv.input b/test/porousmediumflow/1pnc/implicit/test_1p2cni_conduction_fv.input index 3ab7dba6e31303addf6bb77e0d930b7c45f5ed72..f5f23dac9a585d8c3bef0ce71a754b59b8a5dcb6 100644 --- a/test/porousmediumflow/1pnc/implicit/test_1p2cni_conduction_fv.input +++ b/test/porousmediumflow/1pnc/implicit/test_1p2cni_conduction_fv.input @@ -16,3 +16,8 @@ EnableGravity = 0 # disable gravity [Vtk] AddVelocity = 1 # enable velocity output + +[Component] +SolidDensity = 2700 +SolidThermalConductivity = 2.8 +SolidHeatCapacity = 790 diff --git a/test/porousmediumflow/1pnc/implicit/test_1p2cni_convection_fv.input b/test/porousmediumflow/1pnc/implicit/test_1p2cni_convection_fv.input index 052d612b11e1929cf1d4f60bedbcc8b146a77dce..1855563d8139d3d0abc06af40b2793b75dd7187a 100644 --- a/test/porousmediumflow/1pnc/implicit/test_1p2cni_convection_fv.input +++ b/test/porousmediumflow/1pnc/implicit/test_1p2cni_convection_fv.input @@ -16,3 +16,8 @@ EnableGravity = 0 # disable gravity [Vtk] AddVelocity = 1 # enable velocity output + +[Component] +SolidDensity = 2700 +SolidThermalConductivity = 2.8 +SolidHeatCapacity = 790 diff --git a/test/porousmediumflow/1pncmin/implicit/modifiedcao.hh b/test/porousmediumflow/1pncmin/implicit/modifiedcao.hh index 19aa29d3c9a1df2191dc72a25f95a1f8c5e1a722..8892c6d8aeebb8c319705f5461af27e5d2d2a774 100644 --- a/test/porousmediumflow/1pncmin/implicit/modifiedcao.hh +++ b/test/porousmediumflow/1pncmin/implicit/modifiedcao.hh @@ -46,7 +46,7 @@ public: /*! * \brief The corrected mass density \f$\mathrm{[kg/m^3]}\f$ of CaO. */ - static Scalar density() + static Scalar solidDensity(Scalar temperature) { return 1656; // This density is to be used for calculating the chemical reaction of CaO to Ca(OH)2 without considering the solid volume change. See Shao et al. (2013) diff --git a/test/porousmediumflow/1pncmin/implicit/modifiedsteamn2cao2h2.hh b/test/porousmediumflow/1pncmin/implicit/modifiedsteamn2cao2h2.hh index 1753dd0c0e9fa5b1d545e783acf18846bfa36e6a..47010e9b08f38452e871fd57f2451f00667b97e7 100644 --- a/test/porousmediumflow/1pncmin/implicit/modifiedsteamn2cao2h2.hh +++ b/test/porousmediumflow/1pncmin/implicit/modifiedsteamn2cao2h2.hh @@ -33,8 +33,6 @@ #include <dumux/material/idealgas.hh> #include <dumux/material/fluidsystems/base.hh> #include <dumux/material/components/n2.hh> -#include <dumux/material/components/h2o.hh> -#include <dumux/material/components/cao2h2.hh> #include <dumux/material/binarycoefficients/h2o_n2.hh> #include <dumux/material/components/tabulatedcomponent.hh> @@ -73,33 +71,25 @@ public: using H2O_N2 = Dumux::BinaryCoeff::H2O_N2; using N2 = Dumux::Components::N2<Scalar>; - using CaO = Dumux::ModifiedCaO<Scalar>; - using CaO2H2 = Dumux::Components::CaO2H2<Scalar>; - // the type of parameter cache objects. this fluid system does not using ParameterCache = Dumux::NullParameterCache; + /**************************************** + * Fluid phase related static parameters + ****************************************/ + //! Number of phases in the fluid system static constexpr int numPhases = 1; //gas phase: N2 and steam static constexpr int numComponents = 2; // H2O, Air - static constexpr int numSPhases = 2;// solid phases CaO and CaO2H2 TODO: Remove - static constexpr int numSComponents = 2;// CaO2H2, CaO TODO: Remove - static constexpr int gasPhaseIdx = 0; //!< index of the gas phase + static constexpr int gasPhaseIdx = 0; static constexpr int phase0Idx = gasPhaseIdx; //!< index of the only phase - static constexpr int cPhaseIdx = 1; // CaO-phaseIdx TODO: Remove - static constexpr int hPhaseIdx = 2; // CaO2H2-phaseIdx TODO: Remove static constexpr int N2Idx = 0; static constexpr int H2OIdx = 1; static constexpr int comp0Idx = N2Idx; static constexpr int comp1Idx = H2OIdx; - static constexpr int CaOIdx = 2; // CaO-phaseIdx TODO: Remove - static constexpr int CaO2H2Idx = 3; // CaO-phaseIdx TODO: Remove - /**************************************** - * Fluid phase related static parameters - ****************************************/ /*! * \brief Return the human readable name of a fluid phase @@ -110,8 +100,6 @@ public: { switch (phaseIdx) { case gasPhaseIdx: return "gas"; - case cPhaseIdx : return "CaO"; - case hPhaseIdx : return "CaOH2"; } DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx); } @@ -193,9 +181,6 @@ public: { case H2OIdx: return "H2O"; case N2Idx: return "N2"; - case CaOIdx:return "CaO"; - case CaO2H2Idx:return "CaO2H2"; - } DUNE_THROW(Dune::InvalidStateException, "Invalid component index " << compIdx); } @@ -211,60 +196,10 @@ public: { case H2OIdx: return H2O::molarMass(); case N2Idx: return N2::molarMass(); - case CaOIdx: return CaO::molarMass(); - case CaO2H2Idx: return CaO2H2::molarMass(); } DUNE_THROW(Dune::InvalidStateException, "Invalid component index " << compIdx); } - /*! - * \brief Return the mass density of the solid \f$\mathrm{[kg/m^3]}\f$. - * - * \param phaseIdx The index of the solid phase to consider - */ - static Scalar precipitateDensity(int phaseIdx) - { - if(phaseIdx==cPhaseIdx) - return CaO::density(); - if(phaseIdx==hPhaseIdx) - return CaO2H2::density(); - else - DUNE_THROW(Dune::InvalidStateException, "Invalid solid index " << phaseIdx); - return 1; - } - - /*! - * \brief Return the salt specific heat capacity \f$\mathrm{[J/molK]}\f$. - * - * \param phaseIdx The index of the solid phase to consider - */ - static Scalar precipitateHeatCapacity(int phaseIdx) - { - if(phaseIdx==cPhaseIdx) - return CaO::heatCapacity(); - if(phaseIdx==hPhaseIdx) - return CaO2H2::heatCapacity(); - else - DUNE_THROW(Dune::InvalidStateException, "Invalid solid index " << phaseIdx); - return 1; - } - - /*! - * \brief Return the molar density of the solid \f$\mathrm{[mol/m^3]}\f$. - * - * \param phaseIdx The index of the solid phase to consider - */ - static Scalar precipitateMolarDensity(int phaseIdx) - { - if(phaseIdx==1){ - return precipitateDensity(phaseIdx)/ molarMass(CaOIdx); - } - if(phaseIdx==2){ - return precipitateDensity(phaseIdx)/molarMass(CaO2H2Idx); } - else - DUNE_THROW(Dune::InvalidStateException, "Invalid solid phase index " << phaseIdx); - } - /**************************************** * thermodynamic relations ****************************************/ diff --git a/test/porousmediumflow/1pncmin/implicit/thermochemproblem.hh b/test/porousmediumflow/1pncmin/implicit/thermochemproblem.hh index 7645002da432a3a840ee7708953a887952343d37..b3a16b2adae58d74c31ce0b2cb6b340e9fc9f6fb 100644 --- a/test/porousmediumflow/1pncmin/implicit/thermochemproblem.hh +++ b/test/porousmediumflow/1pncmin/implicit/thermochemproblem.hh @@ -31,10 +31,13 @@ #include <dumux/discretization/cellcentered/mpfa/properties.hh> #include <dumux/porousmediumflow/problem.hh> #include <dumux/material/fluidmatrixinteractions/1p/thermalconductivityaverage.hh> +#include <dumux/material/components/cao2h2.hh> +#include <dumux/material/solidsystems/compositionalsolidphase.hh> #include "thermochemspatialparams.hh" #include "thermochemreaction.hh" #include "modifiedsteamn2cao2h2.hh" +#include "modifiedcao.hh" namespace Dumux @@ -59,6 +62,14 @@ SET_PROP(ThermoChemTypeTag, FluidSystem) using type = FluidSystems::ModifiedSteamN2CaO2H2<Scalar>; }; +SET_PROP(ThermoChemTypeTag, SolidSystem) +{ + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using ComponentOne = Dumux::ModifiedCaO<Scalar>; + using ComponentTwo = Components::CaO2H2<Scalar>; + using type = SolidSystems::CompositionalSolidPhase<Scalar, ComponentOne, false , ComponentTwo, false>; +}; + // // Enable velocity output // SET_BOOL_PROP(ThermoChemTypeTag, VtkAddVelocity, false); @@ -88,6 +99,7 @@ class ThermoChemProblem : public PorousMediumFlowProblem<TypeTag> using GridView = typename GET_PROP_TYPE(TypeTag, GridView); using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); + using SolidSystem = typename GET_PROP_TYPE(TypeTag, SolidSystem); using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables); using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView; @@ -118,7 +130,7 @@ class ThermoChemProblem : public PorousMediumFlowProblem<TypeTag> conti0EqIdx = Indices::conti0EqIdx, // Phase Indices - cPhaseIdx = FluidSystem::cPhaseIdx, + cPhaseIdx = SolidSystem::componentOneIdx, temperatureIdx = Indices::temperatureIdx, energyEqIdx = Indices::energyEqIdx @@ -290,17 +302,15 @@ public: const auto& volVars = elemVolVars[scv]; Scalar qMass = rrate_.thermoChemReaction(volVars); - const auto elemSol = elementSolution(element, elemVolVars, fvGeometry); - Scalar qMole = qMass/FluidSystem::molarMass(H2OIdx)*(1-this->spatialParams().porosity(element, scv, elemSol)); + Scalar qMole = qMass/FluidSystem::molarMass(H2OIdx)*(1-volVars.porosity()); // make sure not more solid reacts than present // In this test, we only consider discharge. Therefore, we use the cPhaseIdx for CaO. - if (-qMole*timeStepSize_ + volVars.precipitateVolumeFraction(cPhaseIdx)* volVars.molarDensity(cPhaseIdx) < 0 + eps_) + if (-qMole*timeStepSize_ + volVars.solidVolumeFraction(cPhaseIdx)* volVars.solidPhaseMolarDensity(cPhaseIdx) < 0 + eps_) { - qMole = -volVars.precipitateVolumeFraction(cPhaseIdx)* volVars.molarDensity(cPhaseIdx)/timeStepSize_; + qMole = -volVars.solidVolumeFraction(cPhaseIdx)* volVars.solidPhaseMolarDensity(cPhaseIdx)/timeStepSize_; } - source[conti0EqIdx+CaO2H2Idx] = qMole; source[conti0EqIdx+CaOIdx] = - qMole; source[conti0EqIdx+H2OIdx] = - qMole; @@ -354,7 +364,7 @@ public: volVars.update(elemSol, *this, element, scv); const auto dofIdxGlobal = scv.dofIndex(); permeability_[dofIdxGlobal] = this->spatialParams().permeability(element, scv, elemSol); - porosity_[dofIdxGlobal] = this->spatialParams().porosity(element, scv, elemSol); + porosity_[dofIdxGlobal] = volVars.porosity(); PrimaryVariables reactionRate; reactionRate_[dofIdxGlobal] = rrate_.thermoChemReaction(volVars); } diff --git a/test/porousmediumflow/1pncmin/implicit/thermochemreaction.hh b/test/porousmediumflow/1pncmin/implicit/thermochemreaction.hh index 2881de870d9dac35183f0ead7da08994b5a78e78..28e6cbc08b84bc68136f4721612b8cf79413369a 100644 --- a/test/porousmediumflow/1pncmin/implicit/thermochemreaction.hh +++ b/test/porousmediumflow/1pncmin/implicit/thermochemreaction.hh @@ -45,6 +45,11 @@ public: thermoChemReaction(const VolumeVariables &volVars) const { using FluidSystem = typename VolumeVariables::FluidSystem; + using SolidSystem = typename VolumeVariables::SolidSystem; + + static constexpr int cPhaseIdx = SolidSystem::componentOneIdx; + static constexpr int hPhaseIdx = SolidSystem::componentTwoIdx; + using Scalar = typename VolumeVariables::PrimaryVariables::value_type; // calculate the equilibrium temperature Teq @@ -65,19 +70,19 @@ public: Teq = -12845; Teq /= (pFactor - 16.508); //the equilibrium temperature - Scalar realSolidDensityAverage = (volVars.precipitateVolumeFraction(FluidSystem::hPhaseIdx)*volVars.density(FluidSystem::hPhaseIdx) - + volVars.precipitateVolumeFraction(FluidSystem::cPhaseIdx)*volVars.density(FluidSystem::cPhaseIdx)) - / (volVars.precipitateVolumeFraction(FluidSystem::hPhaseIdx) - + volVars.precipitateVolumeFraction(FluidSystem::cPhaseIdx)); + Scalar realSolidDensityAverage = (volVars.solidVolumeFraction(hPhaseIdx)*volVars.solidPhaseDensity(hPhaseIdx) + + volVars.solidVolumeFraction(cPhaseIdx)*volVars.solidPhaseDensity(cPhaseIdx)) + / (volVars.solidVolumeFraction(hPhaseIdx) + + volVars.solidVolumeFraction(cPhaseIdx)); - if(realSolidDensityAverage <= volVars.density(FluidSystem::cPhaseIdx)) + if(realSolidDensityAverage <= volVars.solidPhaseDensity(cPhaseIdx)) { - realSolidDensityAverage = volVars.density(FluidSystem::cPhaseIdx); + realSolidDensityAverage = volVars.solidPhaseDensity(cPhaseIdx); } - if(realSolidDensityAverage >= volVars.density(FluidSystem::hPhaseIdx)) + if(realSolidDensityAverage >= volVars.solidPhaseDensity(hPhaseIdx)) { - realSolidDensityAverage = volVars.density(FluidSystem::hPhaseIdx); + realSolidDensityAverage = volVars.solidPhaseDensity(hPhaseIdx); } Scalar qMass = 0.0; @@ -87,7 +92,7 @@ public: Scalar dXH_dt1 = 0.0; Scalar dXH_dt2 = 0.0; - Scalar xH = (realSolidDensityAverage-volVars.density(FluidSystem::cPhaseIdx))/(volVars.density(FluidSystem::hPhaseIdx)- volVars.density(FluidSystem::cPhaseIdx)); + Scalar xH = (realSolidDensityAverage-volVars.solidPhaseDensity(cPhaseIdx))/(volVars.solidPhaseDensity(hPhaseIdx)- volVars.solidPhaseDensity(cPhaseIdx)); if(xH < 1.0e-5) {xH = 1.0e-5; } if(xH >=1 ) {xH = 1 - 1e-5; } @@ -143,7 +148,7 @@ public: // no reaction at equilibrium if(Teq -T <= 0) dXH_dt = 0; - Scalar deltaRhoS = volVars.density(FluidSystem::hPhaseIdx) - volVars.density(FluidSystem::cPhaseIdx); + Scalar deltaRhoS = volVars.solidPhaseDensity(hPhaseIdx) - volVars.solidPhaseDensity(cPhaseIdx); qMass = dXH_dt*deltaRhoS; } @@ -159,6 +164,11 @@ public: thermoChemReactionSimple(const VolumeVariables &volVars) const { using FluidSystem = typename VolumeVariables::FluidSystem; + using SolidSystem = typename VolumeVariables::SolidSystem; + + static constexpr int cPhaseIdx = SolidSystem::componentOneIdx; + static constexpr int hPhaseIdx = SolidSystem::componentTwoIdx; + using Scalar = typename VolumeVariables::PrimaryVariables::value_type; // calculate the equilibrium temperature Teq @@ -179,19 +189,20 @@ public: Teq = -12845; Teq /= (pFactor - 16.508); //the equilibrium temperature - Scalar realSolidDensityAverage = (volVars.precipitateVolumeFraction(FluidSystem::hPhaseIdx)*volVars.density(FluidSystem::hPhaseIdx) - + volVars.precipitateVolumeFraction(FluidSystem::cPhaseIdx)*volVars.density(FluidSystem::cPhaseIdx)) - / (volVars.precipitateVolumeFraction(FluidSystem::hPhaseIdx) - + volVars.precipitateVolumeFraction(FluidSystem::cPhaseIdx)); - if(realSolidDensityAverage <= volVars.density(FluidSystem::cPhaseIdx)) + Scalar realSolidDensityAverage = (volVars.solidVolumeFraction(hPhaseIdx)*volVars.solidPhaseDensity(hPhaseIdx) + + volVars.solidVolumeFraction(cPhaseIdx)*volVars.solidPhaseDensity(cPhaseIdx)) + / (volVars.solidVolumeFraction(hPhaseIdx) + + volVars.solidVolumeFraction(cPhaseIdx)); + + if(realSolidDensityAverage <= volVars.solidPhaseDensity(cPhaseIdx)) { - realSolidDensityAverage = volVars.density(FluidSystem::cPhaseIdx); + realSolidDensityAverage = volVars.solidPhaseDensity(cPhaseIdx); } - if(realSolidDensityAverage >= volVars.density(FluidSystem::hPhaseIdx)) + if(realSolidDensityAverage >= volVars.solidPhaseDensity(hPhaseIdx)) { - realSolidDensityAverage = volVars.density(FluidSystem::hPhaseIdx); + realSolidDensityAverage = volVars.solidPhaseDensity(hPhaseIdx); } Scalar qMass = 0.0; @@ -201,7 +212,7 @@ public: Scalar massFracH2O_fPhase = volVars.massFraction(FluidSystem::gasPhaseIdx, FluidSystem::H2OIdx); Scalar krh = 0.2; - Scalar rHydration = - massFracH2O_fPhase* (volVars.density(FluidSystem::hPhaseIdx)- realSolidDensityAverage) + Scalar rHydration = - massFracH2O_fPhase* (volVars.solidPhaseDensity(hPhaseIdx)- realSolidDensityAverage) * krh * (T-Teq)/ Teq; Scalar qMass = rHydration; @@ -212,7 +223,7 @@ public: Scalar krd = 0.05; - Scalar rDehydration = -(volVars.density(FluidSystem::cPhaseIdx)- realSolidDensityAverage) + Scalar rDehydration = -(volVars.solidPhaseDensity(cPhaseIdx)- realSolidDensityAverage) * krd * (Teq-T)/ Teq; qMass = rDehydration; diff --git a/test/porousmediumflow/1pncmin/implicit/thermochemspatialparams.hh b/test/porousmediumflow/1pncmin/implicit/thermochemspatialparams.hh index 016c3a822ae1779e5a356c80b18829273a13fa30..6452684be4ea5b9bcd69f93910c3d92cb7ec2a41 100644 --- a/test/porousmediumflow/1pncmin/implicit/thermochemspatialparams.hh +++ b/test/porousmediumflow/1pncmin/implicit/thermochemspatialparams.hh @@ -70,17 +70,9 @@ class ThermoChemSpatialParams using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); using ModelTraits = typename GET_PROP_TYPE(TypeTag, ModelTraits); - enum { - dimWorld=GridView::dimensionworld, + enum { dimWorld=GridView::dimensionworld }; - numSPhases = ModelTraits::numSPhases(), - numPhases = ModelTraits::numPhases(), - cPhaseIdx = FluidSystem::cPhaseIdx, - hPhaseIdx = FluidSystem::hPhaseIdx - }; - - using EffectiveSolidRho = EffectiveSolidDensity<TypeTag>; - using EffectiveSolidCp = EffectiveSolidHeatCapacity<TypeTag>; + using GlobalPosition = Dune::FieldVector<Scalar, dimWorld>; public: // type used for the permeability (i.e. tensor or scalar) @@ -92,17 +84,7 @@ public: */ ThermoChemSpatialParams(std::shared_ptr<const FVGridGeometry> fvGridGeometry) : ParentType(fvGridGeometry) - { - //thermal conductivity of CaO - lambdaSolid_ = 0.4; //[W/(m*K)] Nagel et al [2013b] - rho_[cPhaseIdx-numPhases] = 1656; //[kg/m^3] density of CaO (see Shao et al. 2014) - rho_[hPhaseIdx-numPhases] = 2200; //[kg/m^3] density of Ca(OH)_2 (see Shao et al. 2014) - cp_[cPhaseIdx-numPhases] = 934; //[J/kgK] heat capacity of CaO (see Shao et al. 2014) - cp_[hPhaseIdx-numPhases] = 1530; //[J/kgK] heat capacity of Ca(OH)_2 (see Shao et al. 2014) - eps_ = 1e-6; - effSolRho_.init(*this); - effSolCp_.init(*this); - } + { } /*! Intrinsic permeability tensor K \f$[m^2]\f$ depending * on the position in the domain @@ -114,7 +96,7 @@ public: * Solution dependent permeability function */ template<class ElementSolution> - Scalar permeability(const Element& element, + PermeabilityType permeability(const Element& element, const SubControlVolume& scv, const ElementSolution& elemSol) const { return 8.53e-12; } @@ -126,91 +108,15 @@ public: * \param scv The sub-control volume * \param elemSol The element solution */ - template<class ElementSolution> - Scalar porosity(const Element& element, - const SubControlVolume& scv, - const ElementSolution& elemSol) const - { return 0.8; } - - /*! - * \brief Returns the average heat capacity \f$[J / (kg K)]\f$ of solid phases. - * - * This is only required for non-isothermal models. - * - * \param element The element - * \param scv The sub control volume - * \param elemSol The element solution vector - */ - template<class ElementSolution> - Scalar solidHeatCapacity(const Element &element, - const SubControlVolume& scv, - const ElementSolution& elemSol) const - { - return effSolCp_.effectiveSolidHeatCapacity(element, scv, elemSol); - } - - /*! - * \brief Returns the heat capacity \f$[J / (kg K)]\f$ of the pure solid phases. - */ - template<class ElementSolution> - Scalar solidPhaseHeatCapacity(const Element &element, - const SubControlVolume& scv, - const ElementSolution& elemSol, - int sPhaseIdx) const - { - return cp_[sPhaseIdx]; - } - - /*! - * \brief Returns the average mass density \f$[kg / m^3]\f$ of the solid phases. - * - * This is only required for non-isothermal models. - * - * \param element The element - * \param scv The sub control volume - * \param elemSol The element solution vector - */ - template<class ElementSolution> - Scalar solidDensity(const Element &element, - const SubControlVolume& scv, - const ElementSolution& elemSol) const - { - return effSolRho_.effectiveSolidDensity(element, scv, elemSol); - } - - /*! - * \brief Returns the mass density \f$[kg / m^3]\f$ of the pure solid phases. - */ - template<class ElementSolution> - Scalar solidPhaseDensity(const Element &element, - const SubControlVolume& scv, - const ElementSolution& elemSol, - int sPhaseIdx) const - { - return rho_[sPhaseIdx]; - } - - /*! - * \brief Returns the thermal conductivity \f$\mathrm{[W/(m K)]}\f$ of the porous material. - * - * \param element The element - * \param scv The sub control volume - * \param elemSol The element solution vector - */ - template<class ElementSolution> - Scalar solidThermalConductivity(const Element &element, - const SubControlVolume& scv, - const ElementSolution& elemSol) const - { return lambdaSolid_; } + template<class SolidState> + Scalar inertVolumeFractionAtPos(const GlobalPosition& globalPos, + SolidState& solidState, + int compIdx) const + { return 0.0; } private: Scalar eps_; - Scalar lambdaSolid_; - std::array<Scalar, numSPhases> rho_; - std::array<Scalar, numSPhases> cp_; - EffectiveSolidRho effSolRho_; - EffectiveSolidCp effSolCp_; }; }//end namespace diff --git a/test/porousmediumflow/2p/implicit/boxdfm/spatialparams.hh b/test/porousmediumflow/2p/implicit/boxdfm/spatialparams.hh index 9d71d79ede721d18f15990d7eade1d878648256f..6f9b33c23aa0882b77cbecc91f8bdd53f7d16203 100644 --- a/test/porousmediumflow/2p/implicit/boxdfm/spatialparams.hh +++ b/test/porousmediumflow/2p/implicit/boxdfm/spatialparams.hh @@ -99,6 +99,25 @@ public: return 1e-12; } + /*! + * \brief Function for defining the solid volume fraction. + * That is possibly solution dependent. + * + * \param element The current element + * \param scv The sub-control volume inside the element. + * \param elemSol The solution at the dofs connected to the element. + * \return the porosity + */ + template<class ElementSolution, class SolidState> + Scalar inertVolumeFraction(const Element& element, + const SubControlVolume& scv, + const ElementSolution& elemSol, + const SolidState& solidState, + int compIdx) const + { + return 1-porosity(element, scv, elemSol); + } + /*! * \brief Returns the porosity \f$[-]\f$ * @@ -115,6 +134,8 @@ public: return 0.15; } + + /*! * \brief Returns the parameter object for the Brooks-Corey material law. * In this test, we use element-wise distributed material parameters. diff --git a/test/porousmediumflow/2p/implicit/nonisothermal/problem.hh b/test/porousmediumflow/2p/implicit/nonisothermal/problem.hh index 1e0ffe022c0155db3e82383b8e6dac23d3d1ca2a..60fc34d13b086d35d482523acf888ce37795450a 100644 --- a/test/porousmediumflow/2p/implicit/nonisothermal/problem.hh +++ b/test/porousmediumflow/2p/implicit/nonisothermal/problem.hh @@ -62,6 +62,7 @@ SET_TYPE_PROP(Injection2PNITypeTag, Problem, InjectionProblem2PNI<TypeTag>); // Use the same fluid system as the 2p2c injection problem SET_TYPE_PROP(Injection2PNITypeTag, FluidSystem, FluidSystems::H2ON2<typename GET_PROP_TYPE(TypeTag, Scalar), false>); + } // namespace Properties /*! @@ -252,7 +253,8 @@ public: const auto initialValues = initialAtPos(globalPos); fs.setPressure(wPhaseIdx, initialValues[pressureIdx]); fs.setPressure(nPhaseIdx, initialValues[pressureIdx]); // assume pressure equality here - fs.setTemperature(initialValues[temperatureIdx]); + fs.setTemperature(wPhaseIdx,initialValues[temperatureIdx]); + fs.setTemperature(nPhaseIdx,initialValues[temperatureIdx]); // energy flux is mass flux times specific enthalpy values[energyEqIdx] = values[contiN2EqIdx]*FluidSystem::enthalpy(fs, nPhaseIdx); diff --git a/test/porousmediumflow/2p/implicit/nonisothermal/test_2pni.input b/test/porousmediumflow/2p/implicit/nonisothermal/test_2pni.input index 3b0427fc3c282b907530fb7873caecdd136d21ae..e30e238016d2716ad2d040dfe30eb3ee94d2e810 100644 --- a/test/porousmediumflow/2p/implicit/nonisothermal/test_2pni.input +++ b/test/porousmediumflow/2p/implicit/nonisothermal/test_2pni.input @@ -12,3 +12,8 @@ Name = injection2pni [Newton] WriteConvergence = 1 # write convergence behaviour to disk? + +[Component] +SolidDensity = 2700 +SolidThermalConductivity = 2.8 +SolidHeatCapacity = 790 diff --git a/test/porousmediumflow/2p1c/implicit/steaminjectionspatialparams.hh b/test/porousmediumflow/2p1c/implicit/steaminjectionspatialparams.hh index 862c7042d6a14de129ff5c839abdbe6ffc71126a..f89fb74854a0b85e212db814a314d75baf221a41 100644 --- a/test/porousmediumflow/2p1c/implicit/steaminjectionspatialparams.hh +++ b/test/porousmediumflow/2p1c/implicit/steaminjectionspatialparams.hh @@ -126,48 +126,6 @@ public: { return materialParams_; } - /*! - * \brief Returns the heat capacity \f$[J / (kg K)]\f$ of the rock matrix. - * - * This is only required for non-isothermal models. - * - * \param element The element - * \param scv The sub control volume - * \param elemSol The element solution vector - */ - template<class ElementSolution> - Scalar solidHeatCapacity(const Element &element, - const SubControlVolume& scv, - const ElementSolution& elemSol) const - { return 850.0; /*specific heat capacity of granite [J / (kg K)]*/ } - - /*! - * \brief Returns the mass density \f$[kg / m^3]\f$ of the rock matrix. - * - * This is only required for non-isothermal models. - * - * \param element The element - * \param scv The sub control volume - * \param elemSol The element solution vector - */ - template<class ElementSolution> - Scalar solidDensity(const Element &element, - const SubControlVolume& scv, - const ElementSolution& elemSol) const - { return 2650; /*density of granite [kg/m^3]*/ } - - /*! - * \brief Returns the thermal conductivity \f$\mathrm{[W/(m K)]}\f$ of the solid - * - * \param element The element - * \param scv The sub control volume - * \param elemSol The element solution vector - */ - template<class ElementSolution> - Scalar solidThermalConductivity(const Element &element, - const SubControlVolume& scv, - const ElementSolution& elemSol) const - { return 2.8; } private: MaterialLawParams materialParams_; diff --git a/test/porousmediumflow/2p1c/implicit/test_boxsteaminjection.input b/test/porousmediumflow/2p1c/implicit/test_boxsteaminjection.input index 59aa81a23af877876c9ffba67dd3c141602d507b..0cfbd646e155627593a35caa21ca70046b0cd079 100644 --- a/test/porousmediumflow/2p1c/implicit/test_boxsteaminjection.input +++ b/test/porousmediumflow/2p1c/implicit/test_boxsteaminjection.input @@ -8,3 +8,8 @@ Cells = 10 20 [Problem] Name = test_boxsteaminjection # name passed to the output routines + +[Component] +SolidDensity = 2650 +SolidThermalConductivity = 2.8 +SolidHeatCapacity = 850.0 diff --git a/test/porousmediumflow/2p1c/implicit/test_ccsteaminjection.input b/test/porousmediumflow/2p1c/implicit/test_ccsteaminjection.input index fabf21bed2ff303018d5c1d26fc55ec3f9f00e87..e103f951905162a54042b1a3a21f1b9b53cd21b9 100644 --- a/test/porousmediumflow/2p1c/implicit/test_ccsteaminjection.input +++ b/test/porousmediumflow/2p1c/implicit/test_ccsteaminjection.input @@ -8,3 +8,8 @@ Cells = 20 40 [Problem] Name = test_ccsteaminjection # name passed to the output routines + +[Component] +SolidDensity = 2650 +solidThermalConductivity = 2.8 +solidHeatCapacity = 850.0 diff --git a/test/porousmediumflow/2p2c/implicit/injectionspatialparams.hh b/test/porousmediumflow/2p2c/implicit/injectionspatialparams.hh index 02f7caccab38737242c0ada28f8f0c3b1ee96018..a1f3788418add38f4f2ca61ce0a3b8f7d6b754f5 100644 --- a/test/porousmediumflow/2p2c/implicit/injectionspatialparams.hh +++ b/test/porousmediumflow/2p2c/implicit/injectionspatialparams.hh @@ -97,9 +97,6 @@ public: finePorosity_ = 0.3; coarsePorosity_ = 0.3; - // heat conductivity of granite - lambdaSolid_ = 2.8; - // residual saturations fineMaterialParams_.setSwr(0.2); fineMaterialParams_.setSnr(0.0); @@ -151,36 +148,6 @@ public: return coarseMaterialParams_; } - /*! - * \brief Returns the heat capacity \f$[J / (kg K)]\f$ of the rock matrix. - * - * This is only required for non-isothermal models. - * - * \param globalPos The global position - */ - Scalar solidHeatCapacityAtPos(const GlobalPosition& globalPos) const - { return 790; /*specific heat capacity of granite [J / (kg K)]*/ } - - /*! - * \brief Returns the mass density \f$[kg / m^3]\f$ of the rock matrix. - * - * This is only required for non-isothermal models. - * - * \param globalPos The global position - */ - Scalar solidDensityAtPos(const GlobalPosition& globalPos) const - { return 2700; /*density of granite [kg/m^3]*/ } - - /*! - * \brief Returns the thermal conductivity \f$\mathrm{[W/(m K)]}\f$ of the solid - * - * This is only required for non-isothermal models. - * - * \param globalPos The global position - */ - Scalar solidThermalConductivityAtPos(const GlobalPosition& globalPos) const - { return lambdaSolid_; } - /*! * \brief Function for defining which phase is to be considered as the wetting phase. * @@ -202,8 +169,6 @@ private: Scalar finePorosity_; Scalar coarsePorosity_; - Scalar lambdaSolid_; - MaterialLawParams fineMaterialParams_; MaterialLawParams coarseMaterialParams_; }; diff --git a/test/porousmediumflow/2p2c/implicit/mpnccomparison/2p2c_comparison_spatialparams.hh b/test/porousmediumflow/2p2c/implicit/mpnccomparison/2p2c_comparison_spatialparams.hh index 62af464077043a65d7cfe83302f7e171398da6a5..12fac71b3dc2c30b1e1a6bf4cb2cec9fa05dd8e3 100644 --- a/test/porousmediumflow/2p2c/implicit/mpnccomparison/2p2c_comparison_spatialparams.hh +++ b/test/porousmediumflow/2p2c/implicit/mpnccomparison/2p2c_comparison_spatialparams.hh @@ -121,15 +121,10 @@ public: /*! * \brief Define the porosity \f$[-]\f$ of the soil * - * \param element The finite element - * \param fvGeometry The finite volume geometry - * \param scvIdx The local index of the sub-control volume where - * the porosity needs to be defined + * \param pos The global position of the sub-control volume. + * \return the material parameters object */ - template<class ElementSolution> - Scalar porosity(const Element &element, - const SubControlVolume &scv, - const ElementSolution &elemSol) const + Scalar porosityAtPos(const GlobalPosition& globalPos) const { return porosity_; } diff --git a/test/porousmediumflow/2p2c/implicit/test_2p2cni_fv.input b/test/porousmediumflow/2p2c/implicit/test_2p2cni_fv.input index 2355be6b36f2e433923af4a66f14dc5a6e36bff1..14fd8b735969e415c12a05115e9509a3c31190b8 100644 --- a/test/porousmediumflow/2p2c/implicit/test_2p2cni_fv.input +++ b/test/porousmediumflow/2p2c/implicit/test_2p2cni_fv.input @@ -19,3 +19,8 @@ ResidualReduction = 1e-10 [Newton] MaxRelativeShift = 1e-13 + +[Component] +SolidDensity = 2700 +SolidThermalConductivity = 2.8 +SolidHeatCapacity = 790 diff --git a/test/porousmediumflow/2p2c/implicit/waterairspatialparams.hh b/test/porousmediumflow/2p2c/implicit/waterairspatialparams.hh index 7cf346252403998927821247f08f71678e0b7557..0ee8e9234879317efb1f8369f1b1ff928dbb18fe 100644 --- a/test/porousmediumflow/2p2c/implicit/waterairspatialparams.hh +++ b/test/porousmediumflow/2p2c/implicit/waterairspatialparams.hh @@ -101,9 +101,6 @@ public: finePorosity_ = 0.3; coarsePorosity_ = 0.3; - // heat conductivity of granite - lambdaSolid_ = 2.8; - // residual saturations fineMaterialParams_.setSwr(0.2); fineMaterialParams_.setSnr(0.0); @@ -146,13 +143,6 @@ public: plotEffectiveDiffusivityModel.adddeffcurve(gnuplot, coarsePorosity_, 0.0, 1.0, "coarse"); gnuplot.plot("deff"); - gnuplot.resetAll(); - using ThermCondModel = typename GET_PROP_TYPE(TypeTag, ThermalConductivityModel); - using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); - PlotThermalConductivityModel<Scalar, ThermCondModel, FluidSystem> plotThermalConductivityModel; - plotThermalConductivityModel.addlambdaeffcurve(gnuplot, finePorosity_, 2700.0, lambdaSolid_, 0.0, 1.0, "fine"); - plotThermalConductivityModel.addlambdaeffcurve(gnuplot, coarsePorosity_, 2700.0, lambdaSolid_, 0.0, 1.0, "coarse"); - gnuplot.plot("lambdaeff"); } /*! @@ -195,34 +185,6 @@ public: return coarseMaterialParams_; } - /*! - * \brief Returns the heat capacity \f$[J / (kg K)]\f$ of the rock matrix. - * - * This is only required for non-isothermal models. - * - * \param globalPos The global positio - */ - Scalar solidHeatCapacityAtPos(const GlobalPosition& globalPos) const - { return 790; /*specific heat capacity of granite [J / (kg K)]*/ } - - /*! - * \brief Returns the mass density \f$[kg / m^3]\f$ of the rock matrix. - * - * This is only required for non-isothermal models. - * - * \param globalPos The global position - */ - Scalar solidDensityAtPos(const GlobalPosition& globalPos) const - { return 2700; /*density of granite [kg/m^3]*/ } - - /*! - * \brief Returns the thermal conductivity \f$\mathrm{[W/(m K)]}\f$ of the porous material. - * - * \param globalPos The global position - */ - Scalar solidThermalConductivityAtPos(const GlobalPosition& globalPos) const - { return lambdaSolid_; } - /*! * \brief Function for defining which phase is to be considered as the wetting phase. * @@ -244,9 +206,6 @@ private: Scalar finePorosity_; Scalar coarsePorosity_; - // heat conductivity of the solid material only - Scalar lambdaSolid_; - MaterialLawParams fineMaterialParams_; MaterialLawParams coarseMaterialParams_; diff --git a/test/porousmediumflow/2pncmin/implicit/CMakeLists.txt b/test/porousmediumflow/2pncmin/implicit/CMakeLists.txt index 0cefec1e4ed8c49b21f1a1fa98dad4a5eb507921..4b0f8239d27abf21f39cc1226fd8153402a0e511 100644 --- a/test/porousmediumflow/2pncmin/implicit/CMakeLists.txt +++ b/test/porousmediumflow/2pncmin/implicit/CMakeLists.txt @@ -7,7 +7,7 @@ dune_add_test(NAME test_2pncmin_box COMMAND ${CMAKE_SOURCE_DIR}/bin/testing/runtest.py CMD_ARGS --script fuzzy --files ${CMAKE_SOURCE_DIR}/test/references/saltflushbox2pncmin-reference.vtu - ${CMAKE_CURRENT_BINARY_DIR}/saltflushbox-00050.vtu + ${CMAKE_CURRENT_BINARY_DIR}/saltflushbox-00045.vtu --command "${CMAKE_CURRENT_BINARY_DIR}/test_2pncmin_box -ParameterFile test_2pncmin.input -Problem.Name saltflushbox") dune_add_test(NAME test_2pncmin_tpfa diff --git a/test/porousmediumflow/2pncmin/implicit/dissolutionproblem.hh b/test/porousmediumflow/2pncmin/implicit/dissolutionproblem.hh index 976f38a2313223639b5ee59539cdf4a05034644c..ccaf2bc571b6bc1892b5e896585b77d277ceff27 100644 --- a/test/porousmediumflow/2pncmin/implicit/dissolutionproblem.hh +++ b/test/porousmediumflow/2pncmin/implicit/dissolutionproblem.hh @@ -32,6 +32,10 @@ #include <dumux/porousmediumflow/problem.hh> #include <dumux/material/fluidsystems/brineair.hh> +#include <dumux/material/components/nacl.hh> +#include <dumux/material/components/granite.hh> +#include <dumux/material/solidsystems/compositionalsolidphase.hh> + #include "dissolutionspatialparams.hh" namespace Dumux @@ -62,6 +66,15 @@ SET_PROP(DissolutionTypeTag, FluidSystem) using type = FluidSystems::BrineAir<Scalar, Components::H2O<Scalar>, true/*useComplexrelations=*/>; }; +SET_PROP(DissolutionTypeTag, SolidSystem) +{ + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using ComponentOne = Components::NaCl<Scalar>; + using ComponentTwo = Components::Granite<Scalar>; + using type = SolidSystems::CompositionalSolidPhase<Scalar, ComponentOne, true, ComponentTwo, false>; +}; + + // Set the spatial parameters SET_TYPE_PROP(DissolutionTypeTag, SpatialParams, DissolutionSpatialparams<TypeTag>); @@ -99,6 +112,7 @@ class DissolutionProblem : public PorousMediumFlowProblem<TypeTag> using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables); using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; + using SolidSystem = typename GET_PROP_TYPE(TypeTag, SolidSystem); enum { @@ -120,8 +134,9 @@ class DissolutionProblem : public PorousMediumFlowProblem<TypeTag> liquidPhaseIdx = FluidSystem::liquidPhaseIdx, gasPhaseIdx = FluidSystem::gasPhaseIdx, - // TODO: this shouldn't be in the fluid system - sPhaseIdx = FluidSystem::solidPhaseIdx, + // index of the solid phase + sPhaseIdx = SolidSystem::componentOneIdx, + // Index of the primary component of G and L phase conti0EqIdx = Indices::conti0EqIdx, @@ -265,7 +280,6 @@ public: if(globalPos[0] < rmin + eps_) { - priVars[pressureIdx] = innerPressure_ ; // Inner boundary pressure bar priVars[switchIdx] = innerLiqSaturation_; // Saturation inner boundary priVars[xwNaClIdx] = massToMoleFrac_(innerSalinity_);// mole fraction salt @@ -338,14 +352,13 @@ public: Scalar massFracNaCl_Max_wPhase = this->spatialParams().solubilityLimit(); Scalar moleFracNaCl_Max_wPhase = massToMoleFrac_(massFracNaCl_Max_wPhase); Scalar moleFracNaCl_Max_nPhase = moleFracNaCl_Max_wPhase / volVars.pressure(gasPhaseIdx); - Scalar saltPorosity = this->spatialParams().minPorosity(element, scv); + Scalar saltPorosity = this->spatialParams().minimalPorosity(element, scv); // liquid phase using std::abs; Scalar precipSalt = volVars.porosity() * volVars.molarDensity(liquidPhaseIdx) * volVars.saturation(liquidPhaseIdx) * abs(moleFracNaCl_wPhase - moleFracNaCl_Max_wPhase); - if (moleFracNaCl_wPhase < moleFracNaCl_Max_wPhase) precipSalt *= -1; @@ -355,16 +368,16 @@ public: * abs(moleFracNaCl_nPhase - moleFracNaCl_Max_nPhase); // make sure we don't dissolve more salt than previously precipitated - if (precipSalt*timeStepSize_ + volVars.precipitateVolumeFraction(sPhaseIdx)* volVars.molarDensity(sPhaseIdx)< 0) - precipSalt = -volVars.precipitateVolumeFraction(sPhaseIdx)* volVars.molarDensity(sPhaseIdx)/timeStepSize_; + if (precipSalt*timeStepSize_ + volVars.solidVolumeFraction(sPhaseIdx)* volVars.solidPhaseMolarDensity(sPhaseIdx)< 0) + precipSalt = -volVars.solidVolumeFraction(sPhaseIdx)* volVars.solidPhaseMolarDensity(sPhaseIdx)/timeStepSize_; - if (volVars.precipitateVolumeFraction(sPhaseIdx) >= this->spatialParams().referencePorosity(element, scv) - saltPorosity && precipSalt > 0) + if (volVars.solidVolumeFraction(sPhaseIdx) >= this->spatialParams().referencePorosity(element, scv) - saltPorosity && precipSalt > 0) precipSalt = 0; source[conti0EqIdx + NaClIdx] += -precipSalt; source[precipNaClEqIdx] += precipSalt; - return source; + } /*! @@ -433,7 +446,6 @@ private: Scalar timeStepSize_ = 0.0; static constexpr Scalar eps_ = 1e-6; Scalar reservoirSaturation_; - Scalar Permeability_; std::vector<double> permeability_; }; diff --git a/test/porousmediumflow/2pncmin/implicit/dissolutionspatialparams.hh b/test/porousmediumflow/2pncmin/implicit/dissolutionspatialparams.hh index d9dd9ea7094ed08b43e3395b438bdda4b246d62e..a7aac0b7f421cfdb7f3e3769c7c84a0b059b19f2 100644 --- a/test/porousmediumflow/2pncmin/implicit/dissolutionspatialparams.hh +++ b/test/porousmediumflow/2pncmin/implicit/dissolutionspatialparams.hh @@ -105,32 +105,32 @@ public: * \param element The finite element * \param scv The sub-control volume */ - Scalar minPorosity(const Element& element, const SubControlVolume &scv) const + Scalar minimalPorosity(const Element& element, const SubControlVolume &scv) const { return 1e-5; } /*! - * \brief Define the reference porosity \f$[-]\f$ distribution. - * This is the porosity of the porous medium without any of the - * considered solid phases. + * \brief Define the minimum porosity \f$[-]\f$ after clogging caused by mineralization * * \param element The finite element * \param scv The sub-control volume + * \param elemSol The element solution */ - Scalar referencePorosity(const Element& element, const SubControlVolume &scv) const - { return referencePorosity_; } + template<class SolidState> + Scalar inertVolumeFractionAtPos(const GlobalPosition& globalPos, + SolidState& solidState, + int compIdx) const + { return 1-referencePorosity_; } /*! - * \brief Return the actual recent porosity \f$[-]\f$ accounting for - * clogging caused by mineralization + * \brief Define the reference porosity \f$[-]\f$ distribution. + * This is the porosity of the porous medium without any of the + * considered solid phases. * * \param element The finite element * \param scv The sub-control volume */ - template<class ElementSolution> - Scalar porosity(const Element& element, - const SubControlVolume& scv, - const ElementSolution& elemSol) const - { return poroLaw_.evaluatePorosity(element, scv, elemSol, referencePorosity_, 1e-5); } + Scalar referencePorosity(const Element& element, const SubControlVolume &scv) const + { return referencePorosity_; } /*! Intrinsic permeability tensor K \f$[m^2]\f$ depending * on the position in the domain @@ -145,12 +145,18 @@ public: const SubControlVolume& scv, const ElementSolution& elemSol) const { - const auto poro = porosity(element, scv, elemSol); - return permLaw_.evaluatePermeability(referencePermeability_, referencePorosity_, poro); + auto priVars = evalSolution(element, element.geometry(), elemSol, scv.center()); + + Scalar sumPrecipitates = 0.0; + sumPrecipitates += priVars[3 /*numComp*/]; + + using std::max; + const auto poro = max(/*minPoro*/1e-5, referencePorosity_ - sumPrecipitates); + return permLaw_.evaluatePermeability(referencePermeability_, referencePorosity_, poro); } - Scalar solidity(const SubControlVolume &scv) const - { return 1.0 - porosityAtPos(scv.center()); } +// Scalar solidity(const SubControlVolume &scv) const +// { return 1.0 - porosityAtPos(scv.center()); } Scalar solubilityLimit() const { return solubilityLimit_; } @@ -171,9 +177,6 @@ private: MaterialLawParams materialParams_; - using ModelTraits = typename GET_PROP_TYPE(TypeTag, ModelTraits); - using PorosityLaw = PorosityPrecipitation<Scalar, ModelTraits::numComponents(), ModelTraits::numSPhases()>; - PorosityLaw poroLaw_; PermeabilityKozenyCarman<PermeabilityType> permLaw_; Scalar solubilityLimit_; diff --git a/test/porousmediumflow/3p/implicit/3pniconductionproblem.hh b/test/porousmediumflow/3p/implicit/3pniconductionproblem.hh index dfa381dd2c498eb8c4373e715a686bcae4a27010..0876ebfbf350399d2f1dc78a7dbed1d745907a96 100644 --- a/test/porousmediumflow/3p/implicit/3pniconductionproblem.hh +++ b/test/porousmediumflow/3p/implicit/3pniconductionproblem.hh @@ -167,11 +167,11 @@ public: VolumeVariables volVars; volVars.update(someElemSol, *this, someElement, someScv); - const auto porosity = this->spatialParams().porosity(someElement, someScv, someElemSol); + const auto porosity = this->spatialParams().porosity(someElement, someScv); const auto densityW = volVars.density(wPhaseIdx); const auto heatCapacityW = IapwsH2O::liquidHeatCapacity(someInitSol[temperatureIdx], someInitSol[pressureIdx]); - const auto densityS = this->spatialParams().solidDensity(someElement, someScv, someElemSol); - const auto heatCapacityS = this->spatialParams().solidHeatCapacity(someElement, someScv, someElemSol); + const auto densityS = volVars.solidDensity(); + const auto heatCapacityS = volVars.solidHeatCapacity(); const auto storage = densityW*heatCapacityW*porosity + densityS*heatCapacityS*(1 - porosity); const auto effectiveThermalConductivity = ThermalConductivityModel::effectiveThermalConductivity(volVars, this->spatialParams(), someElement, fvGeometry, someScv); diff --git a/test/porousmediumflow/3p/implicit/3pniconvectionproblem.hh b/test/porousmediumflow/3p/implicit/3pniconvectionproblem.hh index f20bc51e9807ef0cc5b7cfba46b7bff8969a9292..a2d8083ee8d6ebdfe3cfbebefa8d9b4bab3cca80 100644 --- a/test/porousmediumflow/3p/implicit/3pniconvectionproblem.hh +++ b/test/porousmediumflow/3p/implicit/3pniconvectionproblem.hh @@ -176,12 +176,12 @@ public: VolumeVariables volVars; volVars.update(someElemSol, *this, someElement, someScv); - const auto porosity = this->spatialParams().porosity(someElement, someScv, someElemSol); + const auto porosity = this->spatialParams().porosity(someElement, someScv); const auto densityW = volVars.density(wPhaseIdx); const auto heatCapacityW = IapwsH2O::liquidHeatCapacity(someInitSol[temperatureIdx], someInitSol[pressureIdx]); const auto storageW = densityW*heatCapacityW*porosity; - const auto densityS = this->spatialParams().solidDensity(someElement, someScv, someElemSol); - const auto heatCapacityS = this->spatialParams().solidHeatCapacity(someElement, someScv, someElemSol); + const auto densityS = volVars.solidDensity(); + const auto heatCapacityS = volVars.solidHeatCapacity(); const auto storageTotal = storageW + densityS*heatCapacityS*(1 - porosity); std::cout << "storage: " << storageTotal << '\n'; diff --git a/test/porousmediumflow/3p/implicit/3pnispatialparams.hh b/test/porousmediumflow/3p/implicit/3pnispatialparams.hh index fd1f2b7a26558cbb992dd96e326ddcc671cea2e4..edd3fb83f9dce2e68d7a72ab0c8678ca8ad7f5c7 100644 --- a/test/porousmediumflow/3p/implicit/3pnispatialparams.hh +++ b/test/porousmediumflow/3p/implicit/3pnispatialparams.hh @@ -83,9 +83,6 @@ public: permeability_ = 1e-10; porosity_ = 0.4; - // heat conductivity of granite - lambdaSolid_ = 2.8; - // residual saturations materialParams_.setSwr(0.12); materialParams_.setSnr(0.10); @@ -131,43 +128,6 @@ public: return materialParams_; } - /*! - * \brief Returns the heat capacity \f$[J / (kg K)]\f$ of the rock matrix. - * - * This is only required for non-isothermal models. - * - * \param globalPos The global position - */ - Scalar solidHeatCapacityAtPos(const GlobalPosition& globalPos) const - { - return 790; // specific heat capacity of granite [J / (kg K)] - } - - /*! - * \brief Returns the mass density \f$[kg / m^3]\f$ of the rock matrix. - * - * This is only required for non-isothermal models. - * - * \param globalPos The global position - */ - Scalar solidDensityAtPos(const GlobalPosition& globalPos) const - { - return 2700; // density of granite [kg/m^3] - } - - /*! - * \brief Returns the thermal conductivity \f$\mathrm{[W/(m K)]}\f$ of the porous material. - * - * This is only required for non-isothermal models. - * - * \param globalPos The global position - */ - Scalar solidThermalConductivityAtPos(const GlobalPosition& globalPos) const - { - return lambdaSolid_; - } - - private: MaterialLawParams materialParams_; diff --git a/test/porousmediumflow/3p/implicit/test_3pni_fv_conduction.input b/test/porousmediumflow/3p/implicit/test_3pni_fv_conduction.input index 9fc89f231cab09b1511eb9833cf795157d28c477..4f9840b5f7e5bea1bb3bd45ee3450997de2b286b 100644 --- a/test/porousmediumflow/3p/implicit/test_3pni_fv_conduction.input +++ b/test/porousmediumflow/3p/implicit/test_3pni_fv_conduction.input @@ -14,3 +14,8 @@ EnableGravity = false # disable gravity [Vtk] AddVelocity = true #Enable velocity output + +[Component] +SolidDensity = 2700 +SolidThermalConductivity = 2.8 +SolidHeatCapacity = 790 diff --git a/test/porousmediumflow/3p/implicit/test_3pni_fv_convection.input b/test/porousmediumflow/3p/implicit/test_3pni_fv_convection.input index 8670882f2422304237826ef78bf37b51166e2d50..ddc172cec4f29f7a7c4acb22445c48649bc997b7 100644 --- a/test/porousmediumflow/3p/implicit/test_3pni_fv_convection.input +++ b/test/porousmediumflow/3p/implicit/test_3pni_fv_convection.input @@ -15,3 +15,8 @@ EnableGravity = false # disable gravity [Vtk] AddVelocity = true #Enable velocity output + +[Component] +SolidDensity = 2700 +SolidThermalConductivity = 2.8 +SolidHeatCapacity = 790 diff --git a/test/porousmediumflow/3p3c/implicit/columnxylolproblem.hh b/test/porousmediumflow/3p3c/implicit/columnxylolproblem.hh index f0b7843e9a6604e39daebbb27ed6bdb8d7068cb0..7babea070950ae18bdbd5cb9925fc3b5d5ef1d27 100644 --- a/test/porousmediumflow/3p3c/implicit/columnxylolproblem.hh +++ b/test/porousmediumflow/3p3c/implicit/columnxylolproblem.hh @@ -26,6 +26,10 @@ #define DUMUX_COLUMNXYLOLPROBLEM_HH #include <dumux/material/fluidsystems/h2oairxylene.hh> +#include <dumux/material/solidstates/compositionalsolidstate.hh> +#include <dumux/material/solidsystems/compositionalsolidphase.hh> +#include <dumux/material/components/constant.hh> + #include <dumux/discretization/cellcentered/tpfa/properties.hh> #include <dumux/discretization/box/properties.hh> #include <dumux/porousmediumflow/3p3c/model.hh> @@ -61,6 +65,25 @@ SET_TYPE_PROP(ColumnTypeTag, Problem, ColumnProblem<TypeTag>); SET_TYPE_PROP(ColumnTypeTag, FluidSystem, FluidSystems::H2OAirXylene<typename GET_PROP_TYPE(TypeTag, Scalar)>); + +SET_PROP(ColumnTypeTag, SolidSystem) +{ + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using ComponentOne = Dumux::Components::Constant<1, Scalar>; + using ComponentTwo = Dumux::Components::Constant<2, Scalar>; + using type = SolidSystems::CompositionalSolidPhase<Scalar, ComponentOne, true , ComponentTwo, true>; +}; + + +//! The two-phase model uses the immiscible fluid state +SET_PROP(ColumnTypeTag, SolidState) +{ +private: + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using SolidSystem = typename GET_PROP_TYPE(TypeTag, SolidSystem); +public: + using type = CompositionalSolidState<Scalar, SolidSystem>; +}; } diff --git a/test/porousmediumflow/3p3c/implicit/columnxylolspatialparams.hh b/test/porousmediumflow/3p3c/implicit/columnxylolspatialparams.hh index bdd69d578316f0927c4ae5a835f113e330f2296e..63a0f49067c8fcf05e7cf703ad50a3296fe74298 100644 --- a/test/porousmediumflow/3p3c/implicit/columnxylolspatialparams.hh +++ b/test/porousmediumflow/3p3c/implicit/columnxylolspatialparams.hh @@ -68,7 +68,7 @@ class ColumnSpatialParams using ParentType = FVSpatialParams<FVGridGeometry, Scalar, ColumnSpatialParams<TypeTag>>; using GlobalPosition = typename SubControlVolume::GlobalPosition; - + using SolidSystem = typename GET_PROP_TYPE(TypeTag, SolidSystem); using EffectiveLaw = RegularizedParkerVanGen3P<Scalar>; public: @@ -96,9 +96,6 @@ public: fineHeatCap_ = 850.; coarseHeatCap_ = 84000.; - // heat conductivity of granite - lambdaSolid_ = 2.8; - // residual saturations fineMaterialParams_.setSwr(0.12); fineMaterialParams_.setSnr(0.10); @@ -150,19 +147,27 @@ public: * \param scv The sub-control volume inside the element. * \param elemSol The solution at the dofs connected to the element. */ - template<class ElementSolution> - Scalar porosity(const Element& element, - const SubControlVolume& scv, - const ElementSolution& elemSol) const + template<class SolidState> + Scalar inertVolumeFractionAtPos(const GlobalPosition& globalPos, + SolidState& solidState, + int compIdx) const { - const auto& globalPos = scv.dofPosition(); - if (isFineMaterial_(globalPos)) - return finePorosity_; + if (compIdx == SolidSystem::componentOneIdx) + { + if (isFineMaterial_(globalPos)) + return 1-finePorosity_; + else + return 0; + } else - return coarsePorosity_; + { + if (isFineMaterial_(globalPos)) + return 0; + else + return 1-coarsePorosity_; + } } - /*! * \brief Function for defining the parameters needed by constitutive relationships (kr-sw, pc-sw, etc.). * @@ -183,60 +188,6 @@ public: return coarseMaterialParams_; } - /*! - * \brief Returns the heat capacity \f$[J / (kg K)]\f$ of the rock matrix. - * - * This is only required for non-isothermal models. - * - * \param element The current element - * \param scv The sub-control volume inside the element. - * \param elemSol The solution at the dofs connected to the element. - */ - template<class ElementSolution> - Scalar solidHeatCapacity(const Element& element, - const SubControlVolume& scv, - const ElementSolution& elemSol) const - { - const auto& globalPos = scv.dofPosition(); - if (isFineMaterial_(globalPos)) - return fineHeatCap_; - else - return coarseHeatCap_; - } - - /*! - * \brief Returns the mass density \f$[kg / m^3]\f$ of the rock matrix. - * - * This is only required for non-isothermal models. - * - * \param element The finite element - * \param fvGeometry The finite volume geometry - * \param scvIdx The local index of the sub-control volume - */ - template<class ElementSolution> - Scalar solidDensity(const Element &element, - const SubControlVolume& scv, - const ElementSolution& elemSol) const - { - return 2650; // density of sand [kg/m^3] - } - - /*! - * \brief Returns the thermal conductivity \f$\mathrm{[W/(m K)]}\f$ of the porous material. - * - * \param element The finite element - * \param fvGeometry The finite volume geometry - * \param scvIdx The local index of the sub-control volume where - * the heat capacity needs to be defined - */ - template<class ElementSolution> - Scalar solidThermalConductivity(const Element &element, - const SubControlVolume& scv, - const ElementSolution& elemSol) const - { - return lambdaSolid_; - } - private: bool isFineMaterial_(const GlobalPosition &globalPos) const { @@ -255,8 +206,6 @@ private: MaterialLawParams fineMaterialParams_; MaterialLawParams coarseMaterialParams_; - Scalar lambdaSolid_; - static constexpr Scalar eps_ = 1e-6; }; diff --git a/test/porousmediumflow/3p3c/implicit/kuevetteproblem.hh b/test/porousmediumflow/3p3c/implicit/kuevetteproblem.hh index 440fb7148c63b1ad6f59ba99621c5310ccf3b444..4f89f626aaf70dc8585bc1ce15e23b7dca6aecd7 100644 --- a/test/porousmediumflow/3p3c/implicit/kuevetteproblem.hh +++ b/test/porousmediumflow/3p3c/implicit/kuevetteproblem.hh @@ -29,6 +29,7 @@ #include <dune/common/float_cmp.hh> #include <dumux/material/fluidsystems/h2oairmesitylene.hh> +#include <dumux/material/components/constant.hh> #include <dumux/discretization/cellcentered/tpfa/properties.hh> #include <dumux/discretization/box/properties.hh> #include <dumux/porousmediumflow/3p3c/model.hh> @@ -65,6 +66,14 @@ SET_TYPE_PROP(KuevetteTypeTag, Problem, KuevetteProblem<TypeTag>); SET_TYPE_PROP(KuevetteTypeTag, FluidSystem, FluidSystems::H2OAirMesitylene<typename GET_PROP_TYPE(TypeTag, Scalar)>); + +// Set the fluid system +SET_PROP(KuevetteTypeTag, SolidSystem) +{ + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using InertComponent = Components::Constant<1, Scalar>; + using type = SolidSystems::InertSolidPhase<Scalar, InertComponent>; +}; } diff --git a/test/porousmediumflow/3p3c/implicit/kuevettespatialparams.hh b/test/porousmediumflow/3p3c/implicit/kuevettespatialparams.hh index fd468c120d040077df0f0e4e86ef6b35030386bd..f8e3a7feba4d36372fe346525dc50a3d902ba661 100644 --- a/test/porousmediumflow/3p3c/implicit/kuevettespatialparams.hh +++ b/test/porousmediumflow/3p3c/implicit/kuevettespatialparams.hh @@ -96,9 +96,6 @@ public: finePorosity_ = 0.42; coarsePorosity_ = 0.42; - // heat conductivity of granite - lambdaSolid_ = 2.8; - // residual saturations fineMaterialParams_.setSwr(0.12); fineMaterialParams_.setSnr(0.07); @@ -150,12 +147,8 @@ public: * \param scv The sub-control volume inside the element. * \param elemSol The solution at the dofs connected to the element. */ - template<class ElementSolution> - Scalar porosity(const Element& element, - const SubControlVolume& scv, - const ElementSolution& elemSol) const + Scalar porosityAtPos(const GlobalPosition& globalPos) const { - const auto& globalPos = scv.dofPosition(); if (isFineMaterial_(globalPos)) return finePorosity_; else @@ -183,53 +176,6 @@ public: return coarseMaterialParams_; } - /*! - * \brief Returns the heat capacity \f$[J / (kg K)]\f$ of the rock matrix. - * - * This is only required for non-isothermal models. - * - * \param element The finite element - * \param fvGeometry The finite volume geometry - * \param scvIdx The local index of the sub-control volume - */ - Scalar solidHeatCapacityAtPos(const GlobalPosition& globalPos) const - { - return 850; // specific heat capacity of sand [J / (kg K)] - } - - /*! - * \brief Returns the mass density \f$[kg / m^3]\f$ of the rock matrix. - * - * This is only required for non-isothermal models. - * - * \param element The finite element - * \param fvGeometry The finite volume geometry - * \param scvIdx The local index of the sub-control volume - */ - template<class ElementSolution> - Scalar solidDensity(const Element &element, - const SubControlVolume& scv, - const ElementSolution& elemSol) const - { - return 2650; // density of sand [kg/m^3] - } - - /*! - * \brief Returns the thermal conductivity \f$\mathrm{[W/(m K)]}\f$ of the porous material. - * - * \param element The finite element - * \param fvGeometry The finite volume geometry - * \param scvIdx The local index of the sub-control volume where - * the heat capacity needs to be defined - */ - template<class ElementSolution> - Scalar solidThermalConductivity(const Element &element, - const SubControlVolume& scv, - const ElementSolution& elemSol) const - { - return lambdaSolid_; - } - private: bool isFineMaterial_(const GlobalPosition &globalPos) const { @@ -250,7 +196,6 @@ private: MaterialLawParams fineMaterialParams_; MaterialLawParams coarseMaterialParams_; - Scalar lambdaSolid_; }; } // end namespace Dumux diff --git a/test/porousmediumflow/3p3c/implicit/test_columnxylol_fv.input b/test/porousmediumflow/3p3c/implicit/test_columnxylol_fv.input index 80efdf4037028cba0518be7849c1d6a4d7d0d54f..f383e200589b71c166be9addeecfede51c6bdf1c 100644 --- a/test/porousmediumflow/3p3c/implicit/test_columnxylol_fv.input +++ b/test/porousmediumflow/3p3c/implicit/test_columnxylol_fv.input @@ -12,3 +12,13 @@ Name = columnxylol # name passed to the output routines [Assembly] NumericDifferenceMethod = 0 # -1 backward differences, 0: central differences, +1: forward differences + +[1.Component] +SolidDensity = 2650 +SolidThermalConductivity = 2.8 +SolidHeatCapacity = 850 + +[2.Component] +SolidDensity = 2650 +SolidThermalConductivity = 2.8 +SolidHeatCapacity = 84000 diff --git a/test/porousmediumflow/3p3c/implicit/test_kuvette_fv.input b/test/porousmediumflow/3p3c/implicit/test_kuvette_fv.input index e48af1cd0e96d072b820eb0b3925fb5cf1ee53dc..757f876da79f58a5e98fe3755ecc8f1c843fa581 100644 --- a/test/porousmediumflow/3p3c/implicit/test_kuvette_fv.input +++ b/test/porousmediumflow/3p3c/implicit/test_kuvette_fv.input @@ -16,3 +16,9 @@ NumericDifferenceMethod = 0 # use central differences (backward -1, forward +1) [Newton] MaxRelativeShift = 1e-6 + +[Component] +SolidDensity = 2650 +SolidThermalConductivity = 2.8 +SolidHeatCapacity = 850 + diff --git a/test/porousmediumflow/3pwateroil/implicit/3pwateroilsagdproblem.hh b/test/porousmediumflow/3pwateroil/implicit/3pwateroilsagdproblem.hh index dbf1ad4c54b0db697d29777bf711e7faf6b275e2..32163c15f579c86bcb21500bbee4aff35f184924 100644 --- a/test/porousmediumflow/3pwateroil/implicit/3pwateroilsagdproblem.hh +++ b/test/porousmediumflow/3pwateroil/implicit/3pwateroilsagdproblem.hh @@ -28,7 +28,11 @@ #include <dumux/discretization/box/properties.hh> #include <dumux/porousmediumflow/3pwateroil/model.hh> + #include <dumux/material/fluidsystems/h2oheavyoil.hh> +#include <dumux/material/solidsystems/inertsolidphase.hh> +#include <dumux/material/components/constant.hh> + #include "3pwateroilsagdspatialparams.hh" namespace Dumux @@ -60,6 +64,15 @@ SET_TYPE_PROP(SagdTypeTag, SET_BOOL_PROP(SagdTypeTag, OnlyGasPhaseCanDisappear, true); SET_BOOL_PROP(SagdTypeTag, UseMoles, true); + +// Set the fluid system +SET_PROP(SagdTypeTag, SolidSystem) +{ + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using InertComponent = Components::Constant<1, Scalar>; + using type = SolidSystems::InertSolidPhase<Scalar, InertComponent>; +}; + } diff --git a/test/porousmediumflow/3pwateroil/implicit/3pwateroilsagdspatialparams.hh b/test/porousmediumflow/3pwateroil/implicit/3pwateroilsagdspatialparams.hh index 1a978881e60f229bf0f3f1372726e1731e43b85d..b99981e73dd889883f37b486a32347c9cafc88ce 100644 --- a/test/porousmediumflow/3pwateroil/implicit/3pwateroilsagdspatialparams.hh +++ b/test/porousmediumflow/3pwateroil/implicit/3pwateroilsagdspatialparams.hh @@ -101,13 +101,6 @@ public: finePorosity_ = 0.10; coarsePorosity_ = 0.1; - // heat conductivity of granite - lambdaSolid_ = 2.8; - - // specific heat capacities - fineHeatCap_ = 850.0; - coarseHeatCap_ = 850.0; - // residual saturations fineMaterialParams_.setSwr(0.1); fineMaterialParams_.setSwrx(0.12); //Total liquid Residual Saturation @@ -198,50 +191,6 @@ public: return coarseMaterialParams_; } - /*! - * \brief Returns the heat capacity \f$[J / (kg K)]\f$ of the rock matrix. - * - * This is only required for non-isothermal models. - * - * \param element The finite element - * \param fvGeometry The finite volume geometry - * \param scvIdx The local index of the sub-control volume - */ - Scalar solidHeatCapacityAtPos(const GlobalPosition& globalPos) const - { - if (isFineMaterial_(globalPos)) - return fineHeatCap_ ; - else - return coarseHeatCap_; - } - - /*! - * \brief Returns the mass density \f$[kg / m^3]\f$ of the rock matrix. - * - * This is only required for non-isothermal models. - * - * \param element The finite element - * \param fvGeometry The finite volume geometry - * \param scvIdx The local index of the sub-control volume - */ - Scalar solidDensityAtPos(const GlobalPosition& globalPos) const - { - return 2650; // density of sand [kg/m^3] - } - - /*! - * \brief Returns the thermal conductivity \f$\mathrm{[W/(m K)]}\f$ of the porous material. - * - * \param element The finite element - * \param fvGeometry The finite volume geometry - * \param scvIdx The local index of the sub-control volume where - * the heat capacity needs to be defined - */ - Scalar solidThermalConductivityAtPos(const GlobalPosition& globalPos) const - { - return lambdaSolid_; - } - private: bool isFineMaterial_(const GlobalPosition &pos) const @@ -258,9 +207,6 @@ private: Scalar finePorosity_; Scalar coarsePorosity_; - Scalar fineHeatCap_; - Scalar coarseHeatCap_; - MaterialLawParams fineMaterialParams_; MaterialLawParams coarseMaterialParams_; diff --git a/test/porousmediumflow/3pwateroil/implicit/test_box3pwateroil.input b/test/porousmediumflow/3pwateroil/implicit/test_box3pwateroil.input index e32430e8b76ca81b4d3b010b4b8568d86eb5205b..99a609493cd9c006ebbbec01438aced4db943a59 100644 --- a/test/porousmediumflow/3pwateroil/implicit/test_box3pwateroil.input +++ b/test/porousmediumflow/3pwateroil/implicit/test_box3pwateroil.input @@ -11,3 +11,8 @@ Name = sagd # name passed to the output routines [Newton] MaxSteps = 8 + +[Component] +SolidDensity = 2650 +solidThermalConductivity = 2.8 +solidHeatCapacity = 850 diff --git a/test/porousmediumflow/co2/implicit/heterogeneousproblem.hh b/test/porousmediumflow/co2/implicit/heterogeneousproblem.hh index d37a1ed53d3f7b5462e416b14bccfa495b3ba75e..5c0eba6e39112efef836bd3191b51a4bb5e95339 100644 --- a/test/porousmediumflow/co2/implicit/heterogeneousproblem.hh +++ b/test/porousmediumflow/co2/implicit/heterogeneousproblem.hh @@ -56,7 +56,7 @@ NEW_TYPE_TAG(HeterogeneousTypeTag, INHERITS_FROM(TwoPTwoCCO2, HeterogeneousSpati NEW_TYPE_TAG(HeterogeneousBoxTypeTag, INHERITS_FROM(BoxModel, HeterogeneousTypeTag)); NEW_TYPE_TAG(HeterogeneousCCTpfaTypeTag, INHERITS_FROM(CCTpfaModel, HeterogeneousTypeTag)); -// Set the grid type +//Set the grid type #if HAVE_DUNE_ALUGRID SET_TYPE_PROP(HeterogeneousTypeTag, Grid, Dune::ALUGrid<2, 2, Dune::cube, Dune::nonconforming>); #endif @@ -269,7 +269,7 @@ public: } vtkKxx_[eIdx] = this->spatialParams().permeability(eIdx); - vtkPorosity_[eIdx] = this->spatialParams().porosity(eIdx); + vtkPorosity_[eIdx] = 1- this->spatialParams().inertVolumeFraction(eIdx); } } diff --git a/test/porousmediumflow/co2/implicit/heterogeneousspatialparameters.hh b/test/porousmediumflow/co2/implicit/heterogeneousspatialparameters.hh index 35349ebf81fb578a52581b2be10a3a8898da83f1..f6488b9ca2d2b828950afe863d6a86e9dd75859a 100644 --- a/test/porousmediumflow/co2/implicit/heterogeneousspatialparameters.hh +++ b/test/porousmediumflow/co2/implicit/heterogeneousspatialparameters.hh @@ -170,17 +170,17 @@ public: * * \param element The current element * \param scv The sub-control volume inside the element. - * \param elemSol The solution at the dofs connected to the element. * \return porosity */ - template<class ElementSolution> - Scalar porosity(const Element& element, - const SubControlVolume& scv, - const ElementSolution& elemSol) const + template<class SolidState> + Scalar inertVolumeFraction(const Element& element, + const SubControlVolume& scv, + SolidState& solidState, + int compIdx) const { // Get the global index of the element - const auto eIdx = this->fvGridGeometry().elementMapper().index(element); - return porosity(eIdx); + const auto eIdx = this->problem().fvGridGeometry().elementMapper().index(element); + return inertVolumeFraction(eIdx); } /*! @@ -188,14 +188,14 @@ public: * * \param eIdx The element index */ - Scalar porosity(std::size_t eIdx) const + Scalar inertVolumeFraction(std::size_t eIdx) const { if (paramIdx_[eIdx] == barrierTop_) - return barrierTopPorosity_; + return 1- barrierTopPorosity_; else if (paramIdx_[eIdx] == barrierMiddle_) - return barrierMiddlePorosity_; + return 1- barrierMiddlePorosity_; else - return reservoirPorosity_; + return 1- reservoirPorosity_; } @@ -221,40 +221,6 @@ public: int wettingPhaseAtPos(const GlobalPosition& globalPos) const { return FluidSystem::BrineIdx; } - /*! - * \brief Returns the heat capacity \f$[J / (kg K)]\f$ of the rock matrix. - * - * This is only required for non-isothermal models. - * - * \param globalPos The position of the center of the element - */ - Scalar solidHeatCapacityAtPos(const GlobalPosition& globalPos) const - { - return 790; // specific heat capacity of granite [J / (kg K)] - } - - /*! - * \brief Returns the mass density \f$[kg / m^3]\f$ of the rock matrix. - * - * This is only required for non-isothermal models. - * - * \param globalPos The position of the center of the element - */ - Scalar solidDensityAtPos(const GlobalPosition& globalPos) const - { - return 2700; // density of granite [kg/m^3] - } - - /*! - * \brief Returns the thermal conductivity \f$\mathrm{[W/(m K)]}\f$ of the porous material. - * - * \param globalPos The position of the center of the element - */ - Scalar solidThermalConductivityAtPos(const GlobalPosition& globalPos) const - { - return lambdaSolid_; - } - private: int barrierTop_ = 1; int barrierMiddle_ = 2; diff --git a/test/porousmediumflow/co2/implicit/test_co2ni_fv.input b/test/porousmediumflow/co2/implicit/test_co2ni_fv.input index 78691f8c84137628fd5d0bc2011790c5eece3d02..8be1fb84b8a96373beb490d2abc5daf15c0f827e 100644 --- a/test/porousmediumflow/co2/implicit/test_co2ni_fv.input +++ b/test/porousmediumflow/co2/implicit/test_co2ni_fv.input @@ -24,3 +24,8 @@ InjectionTemperature = 305 # [K] [LinearSolver] ResidualReduction = 1e-10 + +[Component] +SolidDensity = 2700 +solidThermalConductivity = 2.8 +solidHeatCapacity = 790 diff --git a/test/porousmediumflow/mpnc/implicit/2p2ccomparison/mpnc_comparison_spatialparams.hh b/test/porousmediumflow/mpnc/implicit/2p2ccomparison/mpnc_comparison_spatialparams.hh index 1ab97c8afde639b240005454745e719dfe1dd1a5..f3fa378d701507d49b9ac7383cb430828d3e52a9 100644 --- a/test/porousmediumflow/mpnc/implicit/2p2ccomparison/mpnc_comparison_spatialparams.hh +++ b/test/porousmediumflow/mpnc/implicit/2p2ccomparison/mpnc_comparison_spatialparams.hh @@ -127,10 +127,7 @@ public: * \param scvIdx The local index of the sub-control volume where * the porosity needs to be defined */ - template<class ElementSolution> - Scalar porosity(const Element &element, - const SubControlVolume &scv, - const ElementSolution &elemSol) const + Scalar porosityAtPos(const GlobalPosition& globalPos) const { return porosity_; } diff --git a/test/porousmediumflow/mpnc/implicit/combustionproblem1c.hh b/test/porousmediumflow/mpnc/implicit/combustionproblem1c.hh index 5b81830a6600acbc60952d9e943a0a5cd9dec27c..ba9f7caf0df3b0519d0df0484e4dd84d98ade462 100644 --- a/test/porousmediumflow/mpnc/implicit/combustionproblem1c.hh +++ b/test/porousmediumflow/mpnc/implicit/combustionproblem1c.hh @@ -36,6 +36,7 @@ #include <dumux/material/fluidmatrixinteractions/2p/thermalconductivitysimplefluidlumping.hh> #include <dumux/material/constraintsolvers/computefromreferencephase.hh> +#include <dumux/material/components/constant.hh> #include "combustionspatialparams.hh" #include "combustionfluidsystem.hh" @@ -109,7 +110,13 @@ SET_INT_PROP(CombustionOneComponentTypeTag, NumEnergyEqSolid, 1); // by default chemical non equilibrium is enabled in the nonequil model, switch that off here SET_BOOL_PROP(CombustionOneComponentTypeTag, EnableChemicalNonEquilibrium, false); //################# - +// Set the fluid system +SET_PROP(CombustionOneComponentTypeTag, SolidSystem) +{ + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using InertComponent = Components::Constant<1, Scalar>; + using type = SolidSystems::InertSolidPhase<Scalar, InertComponent>; +}; } /*! * \ingroup MPNCTests diff --git a/test/porousmediumflow/mpnc/implicit/combustionspatialparams.hh b/test/porousmediumflow/mpnc/implicit/combustionspatialparams.hh index 20fde3b86e5ca03e7834041ab0a45e270ad87661..a67c174335c0f85e46c1cd5b953f0623b0f3bd87 100644 --- a/test/porousmediumflow/mpnc/implicit/combustionspatialparams.hh +++ b/test/porousmediumflow/mpnc/implicit/combustionspatialparams.hh @@ -90,10 +90,6 @@ public: porosity_ = getParam<Scalar>("SpatialParams.PorousMedium.porosity"); intrinsicPermeabilityOutFlow_ = getParam<Scalar>("SpatialParams.Outflow.permeabilityOutFlow"); porosityOutFlow_ = getParam<Scalar>("SpatialParams.Outflow.porosityOutFlow"); - solidThermalConductivityOutflow_ =getParam<Scalar>("SpatialParams.Outflow.soilThermalConductivityOutFlow"); - solidDensity_ = getParam<Scalar>("SpatialParams.soil.density"); - solidThermalConductivity_ = getParam<Scalar>("SpatialParams.soil.thermalConductivity"); - solidHeatCapacity_ = getParam<Scalar>("SpatialParams.soil.heatCapacity"); interfacialTension_ = getParam<Scalar>("Constants.interfacialTension"); Swr_ = getParam<Scalar>("SpatialParams.soil.Swr"); @@ -137,10 +133,8 @@ public: * \param scvIdx The local index of the sub-control volume where * the porosity needs to be defined */ - template<class ElementSolution> Scalar porosity(const Element &element, - const SubControlVolume &scv, - const ElementSolution &elemSol) const + const SubControlVolume &scv) const { if ( inOutFlow(scv.dofPosition()) ) return porosityOutFlow_ ; @@ -148,6 +142,16 @@ public: return porosity_ ; } + template<class SolidState> + Scalar inertVolumeFraction(const Element& element, + const SubControlVolume& scv, + SolidState& solidState, + int compIdx) const + { + return 1-porosity(element, scv); + + } + /*! * \brief Return a reference to the material parameters of the material law. * \param globalPos The position in global coordinates. */ @@ -213,44 +217,6 @@ public: { return factorMassTransfer_; } - /*! - * \brief Returns the heat capacity \f$[J / (kg K)]\f$ of the rock matrix. - * - * This is only required for non-isothermal models. - * - * \param globalPos The global position - */ - Scalar solidHeatCapacityAtPos(const GlobalPosition& globalPos) const - { return solidHeatCapacity_; } - - /*! - * \brief Returns the mass density \f$[kg / m^3]\f$ of the rock matrix. - * - * This is only required for non-isothermal models. - * - * \param globalPos The global position - */ - Scalar solidDensityAtPos(const GlobalPosition& globalPos) const - { return solidDensity_; } - - /*! - * \brief Returns the thermal conductivity \f$\mathrm{[W/(m K)]}\f$ of the porous material. - * - * This is only required for non-isothermal models. - * - * \param globalPos The global position - */ - template<class ElementSolution> - Scalar solidThermalConductivity(const Element &element, - const SubControlVolume &scv, - const ElementSolution &elemSol) const - { - if ( inOutFlow(scv.dofPosition()) ) - return solidThermalConductivityOutflow_ ; - else - return solidThermalConductivity_ ; - } - //! Return if the tested position (input) is a specific region (right end of porous medium) in the domain bool inOutFlow(const GlobalPosition & globalPos) const { return globalPos[0] > (lengthPM_ - eps_) ; } //! Return the length of the porous medium domain @@ -274,10 +240,6 @@ private: Scalar porosityOutFlow_ ; // solid parameters - Scalar solidDensity_ ; - Scalar solidThermalConductivity_ ; - Scalar solidThermalConductivityOutflow_ ; - Scalar solidHeatCapacity_ ; Scalar interfacialTension_ ; diff --git a/test/porousmediumflow/mpnc/implicit/evaporationatmosphereproblem.hh b/test/porousmediumflow/mpnc/implicit/evaporationatmosphereproblem.hh index fe56c03997b0e6eac1d9eac3ad363ead3b7e5e7c..97f557f348ecbc0628a5fe26d3b1af0806c53f75 100644 --- a/test/porousmediumflow/mpnc/implicit/evaporationatmosphereproblem.hh +++ b/test/porousmediumflow/mpnc/implicit/evaporationatmosphereproblem.hh @@ -48,10 +48,10 @@ #include <dumux/material/fluidsystems/h2on2kinetic.hh> #include <dumux/io/gnuplotinterface.hh> #include "plotoverline2d.hh" +#include <dumux/material/components/constant.hh> #include "evaporationatmospherespatialparams.hh" - namespace Dumux { /*! @@ -90,6 +90,14 @@ public: // Set the type used for scalar values SET_TYPE_PROP(EvaporationAtmosphereTypeTag, Scalar, double); + +// Set the fluid system +SET_PROP(EvaporationAtmosphereTypeTag, SolidSystem) +{ + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using InertComponent = Components::Constant<1, Scalar>; + using type = SolidSystems::InertSolidPhase<Scalar, InertComponent>; +}; } /*! diff --git a/test/porousmediumflow/mpnc/implicit/evaporationatmospherespatialparams.hh b/test/porousmediumflow/mpnc/implicit/evaporationatmospherespatialparams.hh index 4d42b7bf7d5bbd244569f98770f5a44ac84db157..b19693256905d705faa887f9d8aced3468b99360 100644 --- a/test/porousmediumflow/mpnc/implicit/evaporationatmospherespatialparams.hh +++ b/test/porousmediumflow/mpnc/implicit/evaporationatmospherespatialparams.hh @@ -152,10 +152,6 @@ public: porosityFF_ = getParam<Scalar>("SpatialParams.FreeFlow.porosity"); intrinsicPermeabilityFF_ = getParam<Scalar>("SpatialParams.FreeFlow.permeability"); - solidDensity_ = getParam<Scalar>("SpatialParams.soil.density"); - solidThermalConductivity_ = getParam<Scalar>("SpatialParams.soil.thermalConductivity"); - solidHeatCapacity_ = getParam<Scalar>("SpatialParams.soil.heatCapacity"); - aWettingNonWettingA1_ = getParam<Scalar>("SpatialParams.soil.aWettingNonWettingA1"); aWettingNonWettingA2_ = getParam<Scalar>("SpatialParams.soil.aWettingNonWettingA2"); aWettingNonWettingA3_ = getParam<Scalar>("SpatialParams.soil.aWettingNonWettingA3"); @@ -256,10 +252,8 @@ public: * \param element The finite element * \param fvGeometry The finite volume geometry * \param scvIdx The local index of the sub-control volume */ - template<class ElementSolution> Scalar porosity(const Element &element, - const SubControlVolume &scv, - const ElementSolution &elemSol) const + const SubControlVolume &scv) const { const auto& globalPos = scv.dofPosition(); @@ -271,6 +265,16 @@ public: DUNE_THROW(Dune::InvalidStateException, "You should not be here: x=" << globalPos[0] << " y= "<< globalPos[dimWorld-1]); } + template<class SolidState> + Scalar inertVolumeFraction(const Element& element, + const SubControlVolume& scv, + SolidState& solidState, + int compIdx) const + { + return 1-porosity(element, scv); + + } + template<class ElementSolution> const MaterialLawParams& materialLawParams(const Element& element, const SubControlVolume& scv, @@ -420,37 +424,6 @@ public: else DUNE_THROW(Dune::InvalidStateException, "You should not be here: x=" << globalPos[0] << " y= "<< globalPos[dimWorld-1]); } - - /*! - * \brief Returns the heat capacity \f$[J / (kg K)]\f$ of the rock matrix. - * - * This is only required for non-isothermal models. - * - * \param globalPos The global position - */ - Scalar solidHeatCapacityAtPos(const GlobalPosition& globalPos) const - { return solidHeatCapacity_ ;} // specific heat capacity of solid [J / (kg K)] - - /*! - * \brief Returns the mass density \f$[kg / m^3]\f$ of the rock matrix. - * - * This is only required for non-isothermal models. - * - * \param globalPos The global position - */ - Scalar solidDensityAtPos(const GlobalPosition& globalPos) const - {return solidDensity_ ;} // density of solid [kg/m^3] - - /*! - * \brief Returns the thermal conductivity \f$\mathrm{[W/(m K)]}\f$ of the porous material. - * - * This is only required for non-isothermal models. - * - * \param globalPos The global position - */ - Scalar solidThermalConductivityAtPos(const GlobalPosition& globalPos) const - { return solidThermalConductivity_ ;} // conductivity of solid [W / (m K ) ] - /*!\brief Give back whether the tested position (input) is a specific region (porous medium part) in the domain * * This setting ensures, that the boundary between the two domains has porous medium properties. @@ -508,11 +481,6 @@ private: Scalar characteristicLengthFF_ ; MaterialLawParams materialParamsFF_ ; - // solid parameters - Scalar solidDensity_ ; - Scalar solidThermalConductivity_ ; - Scalar solidHeatCapacity_ ; - // interfacial area parameters Scalar aWettingNonWettingA1_ ; Scalar aWettingNonWettingA2_ ; diff --git a/test/porousmediumflow/mpnc/implicit/obstaclespatialparams.hh b/test/porousmediumflow/mpnc/implicit/obstaclespatialparams.hh index 3f0d493b4dd2809d37f4b01221aa02be648444a1..f8e4d001fdceba1dca06a6f094f832a31e5d4531 100644 --- a/test/porousmediumflow/mpnc/implicit/obstaclespatialparams.hh +++ b/test/porousmediumflow/mpnc/implicit/obstaclespatialparams.hh @@ -129,10 +129,7 @@ public: * \param scvIdx The local index of the sub-control volume where * the porosity needs to be defined */ - template<class ElementSolution> - Scalar porosity(const Element &element, - const SubControlVolume &scv, - const ElementSolution &elemSol) const + Scalar porosityAtPos(const GlobalPosition& globalPos) const { return porosity_; } /*! diff --git a/test/porousmediumflow/mpnc/implicit/test_boxmpnckinetic.input b/test/porousmediumflow/mpnc/implicit/test_boxmpnckinetic.input index 36b9448b59795a6e2021b09ad2e44bee3fa890ab..8c7a9bad776f37a7cf4470d49b8389f8c914683c 100644 --- a/test/porousmediumflow/mpnc/implicit/test_boxmpnckinetic.input +++ b/test/porousmediumflow/mpnc/implicit/test_boxmpnckinetic.input @@ -35,9 +35,6 @@ porosity = 0.99 # meanPoreSize = 1e-2 # 4e-5 # characteristic length of the system [SpatialParams.soil] -density = 2600. # kg/m^3 http://www.agriinfo.in/default.aspx?page=topic&superid=4&topicid=271 -thermalConductivity = 3 # W / (m K) -heatCapacity= 817 # J / (kg K) # characteristic length, i.e. mean pore size # 40 micrometer i.e. 1e-5 for the micromodel @@ -74,3 +71,8 @@ hammer = 1e4 [Vtk] AddVelocity = 1 # enable velocity output + +[Component] +SolidDensity = 2600 +SolidThermalConductivity = 3 +SolidHeatCapacity = 817 diff --git a/test/porousmediumflow/mpnc/implicit/test_boxmpncthermalnonequil.input b/test/porousmediumflow/mpnc/implicit/test_boxmpncthermalnonequil.input index ac1f6998df6baa1f37dbd7bdfc8e37fd591ddb12..e7cf8dd89a1c3620839e98103638edd584a060c0 100644 --- a/test/porousmediumflow/mpnc/implicit/test_boxmpncthermalnonequil.input +++ b/test/porousmediumflow/mpnc/implicit/test_boxmpncthermalnonequil.input @@ -51,3 +51,8 @@ nRestart = 10000 # after so many timesteps a restart file should be written [Vtk] AddVelocity = 1 # enable velocity output + +[Component] +SolidDensity = 2600 +SolidThermalConductivity = 30 +SolidHeatCapacity = 466 diff --git a/test/porousmediumflow/richards/implicit/richardsniconductionproblem.hh b/test/porousmediumflow/richards/implicit/richardsniconductionproblem.hh index 7e170fa0c626f32d16359b92d5f9f1c6488bde08..c20bebe3ce4e39f58da7871be1f0490868317f38 100644 --- a/test/porousmediumflow/richards/implicit/richardsniconductionproblem.hh +++ b/test/porousmediumflow/richards/implicit/richardsniconductionproblem.hh @@ -160,11 +160,11 @@ public: VolumeVariables volVars; volVars.update(someElemSol, *this, someElement, someScv); - const auto porosity = this->spatialParams().porosity(someElement, someScv, someElemSol); + const auto porosity = this->spatialParams().porosity(someElement, someScv); const auto densityW = volVars.density(liquidPhaseIdx); const auto heatCapacityW = IapwsH2O::liquidHeatCapacity(someInitSol[temperatureIdx], someInitSol[pressureIdx]); - const auto densityS = this->spatialParams().solidDensity(someElement, someScv, someElemSol); - const auto heatCapacityS = this->spatialParams().solidHeatCapacity(someElement, someScv, someElemSol); + const auto densityS =volVars.solidDensity(); + const auto heatCapacityS = volVars.solidHeatCapacity(); const auto storage = densityW*heatCapacityW*porosity + densityS*heatCapacityS*(1 - porosity); const auto effectiveThermalConductivity = ThermalConductivityModel::effectiveThermalConductivity(volVars, this->spatialParams(), someElement, fvGeometry, someScv); diff --git a/test/porousmediumflow/richards/implicit/richardsniconvectionproblem.hh b/test/porousmediumflow/richards/implicit/richardsniconvectionproblem.hh index 26cdba774f7fa0296f18359e5827f110dc1df35a..647f0fb5291ce7a4838b5adff4fc7f31f755d0fe 100644 --- a/test/porousmediumflow/richards/implicit/richardsniconvectionproblem.hh +++ b/test/porousmediumflow/richards/implicit/richardsniconvectionproblem.hh @@ -174,11 +174,11 @@ public: VolumeVariables volVars; volVars.update(someElemSol, *this, someElement, someScv); - const auto porosity = this->spatialParams().porosity(someElement, someScv, someElemSol); + const auto porosity = this->spatialParams().porosity(someElement, someScv); const auto densityW = volVars.density(liquidPhaseIdx); const auto heatCapacityW = IapwsH2O::liquidHeatCapacity(someInitSol[temperatureIdx], someInitSol[pressureIdx]); - const auto densityS = this->spatialParams().solidDensity(someElement, someScv, someElemSol); - const auto heatCapacityS = this->spatialParams().solidHeatCapacity(someElement, someScv, someElemSol); + const auto densityS = volVars.solidDensity(); + const auto heatCapacityS = volVars.solidHeatCapacity(); const auto storage = densityW*heatCapacityW*porosity + densityS*heatCapacityS*(1 - porosity); const auto effectiveThermalConductivity = ThermalConductivityModel::effectiveThermalConductivity(volVars, this->spatialParams(), someElement, fvGeometry, someScv); diff --git a/test/porousmediumflow/richards/implicit/richardsnispatialparams.hh b/test/porousmediumflow/richards/implicit/richardsnispatialparams.hh index 6373c61fd7c290b8a58c787b0b22fedf43b1d2e7..d270f1cb555e458ad2c2aaea07d60bdbf084388f 100644 --- a/test/porousmediumflow/richards/implicit/richardsnispatialparams.hh +++ b/test/porousmediumflow/richards/implicit/richardsnispatialparams.hh @@ -82,10 +82,6 @@ public: permeability_ = 1e-10; porosity_ = 0.4; - // heat conductivity of granite - lambdaSolid_ = 2.8; - - // residual saturations // residual saturations materialParams_.setSwr(0.05); @@ -134,48 +130,11 @@ public: return materialParams_; } - /*! - * \brief Returns the heat capacity \f$[J / (kg K)]\f$ of the rock matrix. - * - * This is only required for non-isothermal models. - * - * \param globalPos The global position - */ - Scalar solidHeatCapacityAtPos(const GlobalPosition& globalPos) const - { - return 790; // specific heat capacity of granite [J / (kg K)] - } - - /*! - * \brief Returns the mass density \f$[kg / m^3]\f$ of the rock matrix. - * - * This is only required for non-isothermal models. - * - * \param globalPos The global position - */ - Scalar solidDensityAtPos(const GlobalPosition& globalPos) const - { - return 2700; // density of granite [kg/m^3] - } - - /*! - * \brief Returns the thermal conductivity \f$\mathrm{[W/(m K)]}\f$ of the porous material. - * - * This is only required for non-isothermal models. - * - * \param globalPos The global position - */ - Scalar solidThermalConductivityAtPos(const GlobalPosition& globalPos) const - { - return lambdaSolid_; - } - private: MaterialLawParams materialParams_; Scalar permeability_; Scalar porosity_; - Scalar lambdaSolid_; }; } // end namespace Dumux diff --git a/test/porousmediumflow/richards/implicit/test_richardsniconduction.input b/test/porousmediumflow/richards/implicit/test_richardsniconduction.input index 65a74ff7aab30a415329a78b1515707db06bfa61..0304a8a78002529433cb5d57f3fd27029fe03a02 100644 --- a/test/porousmediumflow/richards/implicit/test_richardsniconduction.input +++ b/test/porousmediumflow/richards/implicit/test_richardsniconduction.input @@ -14,3 +14,8 @@ EnableGravity= 0 # disable gravity [Newton] EnableChop = false # chop for better convergence + +[Component] +SolidDensity = 2700 +SolidThermalConductivity = 2.8 +SolidHeatCapacity = 790 diff --git a/test/porousmediumflow/richards/implicit/test_richardsniconvection.input b/test/porousmediumflow/richards/implicit/test_richardsniconvection.input index be59a892ccb35ed43722f57c706d2f07064079c8..a286867c03461c87f34f1215ef041c7520bd563f 100644 --- a/test/porousmediumflow/richards/implicit/test_richardsniconvection.input +++ b/test/porousmediumflow/richards/implicit/test_richardsniconvection.input @@ -15,3 +15,8 @@ EnableGravity = 0 # disable gravity [Newton] EnableChop = false # chop for better convergence + +[Component] +SolidDensity = 2700 +SolidThermalConductivity = 2.8 +SolidHeatCapacity = 790 diff --git a/test/porousmediumflow/richards/implicit/test_richardsnievaporation.input b/test/porousmediumflow/richards/implicit/test_richardsnievaporation.input index 5c8a107941d04b4ff22a817353c21279d746a65d..1f6701d4efafbab233c7a9037cd8dbe981e16e0e 100644 --- a/test/porousmediumflow/richards/implicit/test_richardsnievaporation.input +++ b/test/porousmediumflow/richards/implicit/test_richardsnievaporation.input @@ -15,3 +15,8 @@ UsePrimaryVariableSwitch = true [Newton] EnableChop = false # chop for better convergence + +[Component] +SolidDensity = 2700 +SolidThermalConductivity = 2.8 +SolidHeatCapacity = 790 diff --git a/test/porousmediumflow/tracer/1ptracer/1ptestspatialparams.hh b/test/porousmediumflow/tracer/1ptracer/1ptestspatialparams.hh index 06dd1b679dafc1541fd62b626bc7b72772b070df..c3e4eb0cde3f84e45a6fd13461c2c1a8552c9d23 100644 --- a/test/porousmediumflow/tracer/1ptracer/1ptestspatialparams.hh +++ b/test/porousmediumflow/tracer/1ptracer/1ptestspatialparams.hh @@ -98,15 +98,9 @@ public: * \brief Function for defining the porosity. * That is possibly solution dependent. * - * \param element The current element - * \param scv The sub-control volume inside the element. - * \param elemSol The solution at the dofs connected to the element. * \return the porosity */ - template<class ElementSolution> - Scalar porosity(const Element &element, - const SubControlVolume &scv, - const ElementSolution &elemSol) const + Scalar porosityAtPos(const GlobalPosition &globalPos) const { return 0.2; } //! Reference to the k field