diff --git a/dumux/material/fluidsystems/brineco2.hh b/dumux/material/fluidsystems/brineco2.hh index 800cecd550a9a7e0d011cd105ab8c53c661629fc..7c1c603735878c7a30d1fb19f0b0eb599c739493 100644 --- a/dumux/material/fluidsystems/brineco2.hh +++ b/dumux/material/fluidsystems/brineco2.hh @@ -88,10 +88,11 @@ namespace Detail { * \ingroup Fluidsystems * \brief Default policy for the Brine-CO2 fluid system */ -template<bool salinityIsConstant> +template<bool salinityIsConstant, bool fastButSimplifiedRelations = false> struct BrineCO2DefaultPolicy { static constexpr bool useConstantSalinity() { return salinityIsConstant; } + static constexpr bool useCO2GasDensityAsGasMixtureDensity() { return fastButSimplifiedRelations; } }; /*! @@ -330,6 +331,10 @@ public: static void init(Scalar startTemp, Scalar endTemp, int tempSteps, Scalar startPressure, Scalar endPressure, int pressureSteps) { + std::cout << "The Brine-CO2 fluid system was configured with the following policy:\n"; + std::cout << " - use constant salinity: " << std::boolalpha << Policy::useConstantSalinity() << "\n"; + std::cout << " - use CO2 gas density as gas mixture density: " << std::boolalpha << Policy::useCO2GasDensityAsGasMixtureDensity() << std::endl; + // maybe set salinity of the constant salinity brine if (useConstantSalinity) ConstantSalinityBrine::constantSalinity = getParam<Scalar>("FluidSystem.Salinity", 0.3); @@ -351,11 +356,19 @@ public: static Scalar density(const FluidState& fluidState, int phaseIdx) { if (phaseIdx == liquidPhaseIdx) - return liquidDensity_(fluidState); + return liquidDensityMixture_(fluidState); - // in the end it comes down to a simplification of just CO2 else if (phaseIdx == gasPhaseIdx) - return CO2::gasDensity(fluidState.temperature(phaseIdx), fluidState.pressure(phaseIdx)); + { + if (Policy::useCO2GasDensityAsGasMixtureDensity()) + // use the CO2 gas density only and neglect compositional effects + return CO2::gasDensity(fluidState.temperature(phaseIdx), fluidState.pressure(phaseIdx)); + else + //account for compositional effects (water) in the gas phase + return gasDensityMixture_(fluidState.temperature(phaseIdx), + fluidState.pressure(phaseIdx), + fluidState.moleFraction(phaseIdx, comp0Idx)); + } DUNE_THROW(Dune::InvalidStateException, "Invalid phase index."); } @@ -709,15 +722,14 @@ public: private: - /***********************************************************************/ - /* */ - /* Total brine density with dissolved CO2 */ - /* rho_{b,CO2} = rho_w + contribution(salt) + contribution(CO2) */ - /* */ - /***********************************************************************/ - // computes the density of the liquid phase + /*! + * \brief Liquid-phase density calculation of a mixture of brine and CO2 accounting for compositional effects. + * + * \param fluidState An arbitrary fluid state + * \return liquidDensity the liquid-phase density + */ template<class FluidState> - static Scalar liquidDensity_(const FluidState& fluidState) + static Scalar liquidDensityMixture_(const FluidState& fluidState) { const auto T = fluidState.temperature(liquidPhaseIdx); const auto p = fluidState.pressure(liquidPhaseIdx); @@ -777,7 +789,17 @@ private: return rho_brine + contribCO2; } - // computes the density of the liquid water/CO2 mixture + + /*! + * \brief Liquid-phase density for a mixture of CO2 in pure water. + * \note this is used by liquidDensityMixture_ + * + * \param temperature The temperature + * \param pl the liquid-phase pressure + * \param xlH2O the liquid-phase H2O mole fraction + * \param xlCO2 the liquid-phase CO2 mole fraction + * \return the density of a mixture of CO2 in pure water + */ static Scalar liquidDensityWaterCO2_(Scalar temperature, Scalar pl, Scalar xlH2O, @@ -799,6 +821,23 @@ private: tempC*5.044e-7))) / 1.0e6; return 1/(xlCO2 * V_phi/M_T + M_H2O * xlH2O / (rho_pure * M_T)); } + + /*! + * \brief Gas-phase density calculation accounting for compositional effects. + * + * \param temperature The temperature + * \param pg the gas-phase pressure + * \param xgH2O the gas-phase H2O mole fraction + * \return the gas-phase density + */ + static Scalar gasDensityMixture_(Scalar temperature, Scalar pg, Scalar xgH2O) + { + const Scalar pH2O = xgH2O*pg; //Dalton' Law + const Scalar pCO2 = pg - pH2O; + const Scalar gasDensityCO2 = CO2::gasDensity(temperature, pCO2); + const Scalar gasDensityH2O = H2O::gasDensity(temperature, pH2O); + return gasDensityCO2 + gasDensityH2O; + } }; } // end namespace FluidSystems diff --git a/test/material/fluidsystems/test_fluidsystems.cc b/test/material/fluidsystems/test_fluidsystems.cc index 0053bab8693165f821a0a83c3f02f881dcbd5e65..d86f1be3969ccfbc554021cd5c5c446cdb0ed07d 100644 --- a/test/material/fluidsystems/test_fluidsystems.cc +++ b/test/material/fluidsystems/test_fluidsystems.cc @@ -177,6 +177,16 @@ int main() using FluidSystem = FluidSystems::BrineCO2< Scalar, HeterogeneousCO2Tables::CO2Tables, H2OType, FluidSystems::BrineCO2DefaultPolicy</*useConstantSalinity=*/false> >; success += checkFluidSystem<Scalar, FluidSystem>( false ); } + { using H2OType = Components::TabulatedComponent<Components::H2O<Scalar>>; + using FluidSystem = FluidSystems::BrineCO2< Scalar, HeterogeneousCO2Tables::CO2Tables, + H2OType, FluidSystems::BrineCO2DefaultPolicy</*useConstantSalinity=*/true, + /*fastButSimplifiedRelations*/true> >; + success += checkFluidSystem<Scalar, FluidSystem>( false ); } + { using H2OType = Components::TabulatedComponent<Components::H2O<Scalar>>; + using FluidSystem = FluidSystems::BrineCO2< Scalar, HeterogeneousCO2Tables::CO2Tables, + H2OType, FluidSystems::BrineCO2DefaultPolicy</*useConstantSalinity=*/false, + /*fastButSimplifiedRelations*/true> >; + success += checkFluidSystem<Scalar, FluidSystem>( false ); } // H2O -- Air { using H2OType = Components::SimpleH2O<Scalar>; diff --git a/test/porousmediumflow/co2/implicit/heterogeneousproblem.hh b/test/porousmediumflow/co2/implicit/heterogeneousproblem.hh index f1d36d4c344e0c170e2c498cc039cccadad4207c..b41d26dee4e94f7c01b7d05905c901477027929a 100644 --- a/test/porousmediumflow/co2/implicit/heterogeneousproblem.hh +++ b/test/porousmediumflow/co2/implicit/heterogeneousproblem.hh @@ -34,6 +34,8 @@ #include <dumux/porousmediumflow/problem.hh> #include <dumux/porousmediumflow/co2/model.hh> +#include <dumux/material/components/tabulatedcomponent.hh> +#include <dumux/material/components/h2o.hh> #include <dumux/material/fluidsystems/brineco2.hh> #include <dumux/discretization/box/scvftoscvboundarytypes.hh> @@ -69,8 +71,11 @@ SET_TYPE_PROP(HeterogeneousTypeTag, SpatialParams, HeterogeneousSpatialParams<ty typename GET_PROP_TYPE(TypeTag, Scalar)>); // Set fluid configuration -SET_TYPE_PROP(HeterogeneousTypeTag, FluidSystem, FluidSystems::BrineCO2<typename GET_PROP_TYPE(TypeTag, Scalar), - HeterogeneousCO2Tables::CO2Tables>); +SET_TYPE_PROP(HeterogeneousTypeTag, FluidSystem, + FluidSystems::BrineCO2<typename GET_PROP_TYPE(TypeTag, Scalar), + HeterogeneousCO2Tables::CO2Tables, + Components::TabulatedComponent<Components::H2O<typename GET_PROP_TYPE(TypeTag, Scalar)>>, + FluidSystems::BrineCO2DefaultPolicy</*constantSalinity=*/true, /*simpleButFast=*/true>>); // Use Moles SET_BOOL_PROP(HeterogeneousTypeTag, UseMoles, false);