make all fluid systems local-AD aware
also, adapt the unit test make sure they can be used synchronously with function evaluations as well as scalars.
This commit is contained in:
parent
e009e640c5
commit
26c8553902
@ -160,8 +160,8 @@ public:
|
||||
* \copydoc Doxygen::fluidSystemBaseParams
|
||||
* \copydoc Doxygen::phaseIdxParam
|
||||
*/
|
||||
template <class FluidState, class ParameterCache>
|
||||
static Scalar density(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar, class ParameterCache = NullParameterCache>
|
||||
static LhsEval density(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
@ -183,8 +183,8 @@ public:
|
||||
* \copydoc Doxygen::phaseIdxParam
|
||||
* \copydoc Doxygen::compIdxParam
|
||||
*/
|
||||
template <class FluidState, class ParameterCache>
|
||||
static Scalar fugacityCoefficient(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar, class ParameterCache = NullParameterCache>
|
||||
static LhsEval fugacityCoefficient(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx,
|
||||
int compIdx)
|
||||
@ -198,8 +198,8 @@ public:
|
||||
* \copydoc Doxygen::fluidSystemBaseParams
|
||||
* \copydoc Doxygen::phaseIdxParam
|
||||
*/
|
||||
template <class FluidState, class ParameterCache>
|
||||
static Scalar viscosity(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar, class ParameterCache = NullParameterCache>
|
||||
static LhsEval viscosity(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
@ -223,8 +223,8 @@ public:
|
||||
* \copydoc Doxygen::phaseIdxParam
|
||||
* \copydoc Doxygen::compIdxParam
|
||||
*/
|
||||
template <class FluidState, class ParameterCache>
|
||||
static Scalar diffusionCoefficient(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar, class ParameterCache = NullParameterCache>
|
||||
static LhsEval diffusionCoefficient(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx,
|
||||
int compIdx)
|
||||
@ -239,8 +239,8 @@ public:
|
||||
* \copydoc Doxygen::fluidSystemBaseParams
|
||||
* \copydoc Doxygen::phaseIdxParam
|
||||
*/
|
||||
template <class FluidState, class ParameterCache>
|
||||
static Scalar enthalpy(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar, class ParameterCache = NullParameterCache>
|
||||
static LhsEval enthalpy(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
@ -253,8 +253,8 @@ public:
|
||||
* \copydoc Doxygen::fluidSystemBaseParams
|
||||
* \copydoc Doxygen::phaseIdxParam
|
||||
*/
|
||||
template <class FluidState, class ParameterCache>
|
||||
static Scalar thermalConductivity(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar, class ParameterCache = NullParameterCache>
|
||||
static LhsEval thermalConductivity(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
@ -267,8 +267,8 @@ public:
|
||||
* \copydoc Doxygen::fluidSystemBaseParams
|
||||
* \copydoc Doxygen::phaseIdxParam
|
||||
*/
|
||||
template <class FluidState, class ParameterCache>
|
||||
static Scalar heatCapacity(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar, class ParameterCache = NullParameterCache>
|
||||
static LhsEval heatCapacity(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
|
@ -38,27 +38,17 @@
|
||||
#include <array>
|
||||
|
||||
namespace Opm {
|
||||
template <class Scalar>
|
||||
class OilPvtInterface;
|
||||
|
||||
template <class Scalar>
|
||||
class GasPvtInterface;
|
||||
|
||||
template <class Scalar>
|
||||
class WaterPvtInterface;
|
||||
|
||||
namespace FluidSystems {
|
||||
|
||||
/*!
|
||||
* \brief A fluid system which uses the black-oil parameters
|
||||
* to calculate termodynamically meaningful quantities.
|
||||
*/
|
||||
template <class Scalar>
|
||||
class BlackOil : public BaseFluidSystem<Scalar, BlackOil<Scalar> >
|
||||
template <class Scalar, class Evaluation = Scalar>
|
||||
class BlackOil : public BaseFluidSystem<Scalar, BlackOil<Scalar, Evaluation> >
|
||||
{
|
||||
typedef Opm::GasPvtInterface<Scalar> GasPvtInterface;
|
||||
typedef Opm::OilPvtInterface<Scalar> OilPvtInterface;
|
||||
typedef Opm::WaterPvtInterface<Scalar> WaterPvtInterface;
|
||||
typedef Opm::GasPvtInterface<Scalar, Evaluation> GasPvtInterface;
|
||||
typedef Opm::OilPvtInterface<Scalar, Evaluation> OilPvtInterface;
|
||||
typedef Opm::WaterPvtInterface<Scalar, Evaluation> WaterPvtInterface;
|
||||
|
||||
public:
|
||||
//! \copydoc BaseFluidSystem::ParameterCache
|
||||
@ -286,26 +276,29 @@ public:
|
||||
* thermodynamic relations
|
||||
****************************************/
|
||||
//! \copydoc BaseFluidSystem::density
|
||||
template <class FluidState>
|
||||
static Scalar density(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval density(const FluidState &fluidState,
|
||||
ParameterCache ¶mCache,
|
||||
const int phaseIdx)
|
||||
{
|
||||
assert(0 <= phaseIdx && phaseIdx <= numPhases);
|
||||
|
||||
Scalar p = fluidState.pressure(phaseIdx);
|
||||
Scalar T = fluidState.temperature(phaseIdx);
|
||||
typedef typename FluidState::Scalar FsEval;
|
||||
typedef Opm::MathToolbox<FsEval> FsToolbox;
|
||||
|
||||
const auto& p = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
const auto& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
int regionIdx = paramCache.regionIndex();
|
||||
|
||||
switch (phaseIdx) {
|
||||
case waterPhaseIdx: return waterDensity(T, p, regionIdx);
|
||||
case waterPhaseIdx: return waterDensity<LhsEval>(T, p, regionIdx);
|
||||
case gasPhaseIdx: {
|
||||
Scalar XgO = fluidState.massFraction(gasPhaseIdx, oilCompIdx);
|
||||
return gasDensity(T, p, XgO, regionIdx);
|
||||
const auto& XgO = FsToolbox::template toLhs<LhsEval>(fluidState.massFraction(gasPhaseIdx, oilCompIdx));
|
||||
return gasDensity<LhsEval>(T, p, XgO, regionIdx);
|
||||
}
|
||||
case oilPhaseIdx: {
|
||||
Scalar XoG = fluidState.massFraction(oilPhaseIdx, gasCompIdx);
|
||||
return oilDensity(T, p, XoG, regionIdx);
|
||||
const auto& XoG = FsToolbox::template toLhs<LhsEval>(fluidState.massFraction(oilPhaseIdx, gasCompIdx));
|
||||
return oilDensity<LhsEval>(T, p, XoG, regionIdx);
|
||||
}
|
||||
}
|
||||
|
||||
@ -313,8 +306,8 @@ public:
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::fugacityCoefficient
|
||||
template <class FluidState>
|
||||
static Scalar fugacityCoefficient(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval fugacityCoefficient(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx,
|
||||
int compIdx)
|
||||
@ -322,40 +315,44 @@ public:
|
||||
assert(0 <= phaseIdx && phaseIdx <= numPhases);
|
||||
assert(0 <= compIdx && compIdx <= numComponents);
|
||||
|
||||
Scalar p = fluidState.pressure(phaseIdx);
|
||||
Scalar T = fluidState.temperature(phaseIdx);
|
||||
typedef Opm::MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
const auto& p = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
const auto& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
int regionIdx = paramCache.regionIndex();
|
||||
|
||||
switch (phaseIdx) {
|
||||
case waterPhaseIdx: return fugCoefficientInWater(compIdx, T, p, regionIdx);
|
||||
case gasPhaseIdx: return fugCoefficientInGas(compIdx, T, p, regionIdx);
|
||||
case oilPhaseIdx: return fugCoefficientInOil(compIdx, T, p, regionIdx);
|
||||
case waterPhaseIdx: return fugCoefficientInWater<LhsEval>(compIdx, T, p, regionIdx);
|
||||
case gasPhaseIdx: return fugCoefficientInGas<LhsEval>(compIdx, T, p, regionIdx);
|
||||
case oilPhaseIdx: return fugCoefficientInOil<LhsEval>(compIdx, T, p, regionIdx);
|
||||
}
|
||||
|
||||
OPM_THROW(std::logic_error, "Unhandled phase or component index");
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::viscosity
|
||||
template <class FluidState>
|
||||
static Scalar viscosity(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval viscosity(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
assert(0 <= phaseIdx && phaseIdx <= numPhases);
|
||||
|
||||
Scalar p = fluidState.pressure(phaseIdx);
|
||||
Scalar T = fluidState.temperature(phaseIdx);
|
||||
typedef Opm::MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
const auto& p = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
const auto& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
int regionIdx = paramCache.regionIndex();
|
||||
|
||||
switch (phaseIdx) {
|
||||
case oilPhaseIdx: {
|
||||
Scalar XoG = fluidState.massFraction(oilPhaseIdx, gasCompIdx);
|
||||
const auto& XoG = FsToolbox::template toLhs<LhsEval>(fluidState.massFraction(oilPhaseIdx, gasCompIdx));
|
||||
return oilPvt_->viscosity(regionIdx, T, p, XoG);
|
||||
}
|
||||
case waterPhaseIdx:
|
||||
return waterPvt_->viscosity(regionIdx, T, p);
|
||||
case gasPhaseIdx: {
|
||||
Scalar XgO = fluidState.massFraction(gasPhaseIdx, oilCompIdx);
|
||||
const auto& XgO = FsToolbox::template toLhs<LhsEval>(fluidState.massFraction(gasPhaseIdx, oilCompIdx));
|
||||
return gasPvt_->viscosity(regionIdx, T, p, XgO);
|
||||
}
|
||||
}
|
||||
@ -394,14 +391,15 @@ public:
|
||||
*
|
||||
* \param pressure The pressure of interest [Pa]
|
||||
*/
|
||||
static Scalar saturatedOilFormationVolumeFactor(Scalar temperature,
|
||||
Scalar pressure,
|
||||
template <class LhsEval>
|
||||
static LhsEval saturatedOilFormationVolumeFactor(const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
int regionIdx)
|
||||
{
|
||||
Valgrind::CheckDefined(pressure);
|
||||
|
||||
// calculate the mass fractions of gas and oil
|
||||
Scalar XoG = saturatedOilGasMassFraction(temperature, pressure, regionIdx);
|
||||
const auto& XoG = saturatedOilGasMassFraction(temperature, pressure, regionIdx);
|
||||
|
||||
// ATTENTION: XoG is represented by the _first_ axis!
|
||||
return oilFormationVolumeFactor(temperature, pressure, XoG, regionIdx);
|
||||
@ -410,7 +408,10 @@ public:
|
||||
/*!
|
||||
* \brief Return the formation volume factor of water.
|
||||
*/
|
||||
static Scalar waterFormationVolumeFactor(Scalar temperature, Scalar pressure, int regionIdx)
|
||||
template <class LhsEval>
|
||||
static LhsEval waterFormationVolumeFactor(const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
int regionIdx)
|
||||
{ return waterPvt_->formationVolumeFactor(regionIdx, temperature, pressure); }
|
||||
|
||||
/*!
|
||||
@ -418,7 +419,10 @@ public:
|
||||
*
|
||||
* \param pressure The pressure of interest [Pa]
|
||||
*/
|
||||
static Scalar gasDissolutionFactor(Scalar temperature, Scalar pressure, int regionIdx)
|
||||
template <class LhsEval>
|
||||
static LhsEval gasDissolutionFactor(const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
int regionIdx)
|
||||
{ return oilPvt_->gasDissolutionFactor(regionIdx, temperature, pressure); }
|
||||
|
||||
/*!
|
||||
@ -426,7 +430,10 @@ public:
|
||||
*
|
||||
* \param pressure The pressure of interest [Pa]
|
||||
*/
|
||||
static Scalar oilVaporizationFactor(Scalar temperature, Scalar pressure, int regionIdx)
|
||||
template <class LhsEval>
|
||||
static LhsEval oilVaporizationFactor(const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
int regionIdx)
|
||||
{ return gasPvt_->oilVaporizationFactor(regionIdx, temperature, pressure); }
|
||||
|
||||
/*!
|
||||
@ -435,7 +442,11 @@ public:
|
||||
* \param compIdx The index of the component of interest
|
||||
* \param pressure The pressure of interest [Pa]
|
||||
*/
|
||||
static Scalar fugCoefficientInWater(int compIdx, Scalar temperature, Scalar pressure, int regionIdx)
|
||||
template <class LhsEval>
|
||||
static LhsEval fugCoefficientInWater(int compIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
int regionIdx)
|
||||
{ return waterPvt_->fugacityCoefficient(regionIdx, temperature, pressure, compIdx); }
|
||||
|
||||
/*!
|
||||
@ -444,7 +455,11 @@ public:
|
||||
* \param compIdx The index of the component of interest
|
||||
* \param pressure The pressure of interest [Pa]
|
||||
*/
|
||||
static Scalar fugCoefficientInGas(int compIdx, Scalar temperature, Scalar pressure, int regionIdx)
|
||||
template <class LhsEval>
|
||||
static LhsEval fugCoefficientInGas(int compIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
int regionIdx)
|
||||
{ return gasPvt_->fugacityCoefficient(regionIdx, temperature, pressure, compIdx); }
|
||||
|
||||
/*!
|
||||
@ -453,7 +468,11 @@ public:
|
||||
* \param compIdx The index of the component of interest
|
||||
* \param pressure The pressure of interest [Pa]
|
||||
*/
|
||||
static Scalar fugCoefficientInOil(int compIdx, Scalar temperature, Scalar pressure, int regionIdx)
|
||||
template <class LhsEval>
|
||||
static LhsEval fugCoefficientInOil(int compIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
int regionIdx)
|
||||
{ return oilPvt_->fugacityCoefficient(regionIdx, temperature, pressure, compIdx); }
|
||||
|
||||
/*!
|
||||
@ -462,75 +481,109 @@ public:
|
||||
*
|
||||
* \param XoG The mass fraction of the gas component in the oil phase [-]
|
||||
*/
|
||||
static Scalar oilSaturationPressure(Scalar temperature, Scalar XoG, int regionIdx)
|
||||
template <class LhsEval>
|
||||
static LhsEval oilSaturationPressure(const LhsEval& temperature,
|
||||
const LhsEval& XoG,
|
||||
int regionIdx)
|
||||
{ return oilPvt_->oilSaturationPressure(regionIdx, temperature, XoG); }
|
||||
|
||||
/*!
|
||||
* \brief The maximum mass fraction of the gas component in the oil phase.
|
||||
*/
|
||||
static Scalar saturatedOilGasMassFraction(Scalar temperature, Scalar pressure, int regionIdx)
|
||||
template <class LhsEval>
|
||||
static LhsEval saturatedOilGasMassFraction(const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
int regionIdx)
|
||||
{ return oilPvt_->saturatedOilGasMassFraction(regionIdx, temperature, pressure); }
|
||||
|
||||
/*!
|
||||
* \brief The maximum mole fraction of the gas component in the oil phase.
|
||||
*/
|
||||
static Scalar saturatedOilGasMoleFraction(Scalar temperature, Scalar pressure, int regionIdx)
|
||||
template <class LhsEval>
|
||||
static LhsEval saturatedOilGasMoleFraction(const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
int regionIdx)
|
||||
{ return oilPvt_->saturatedOilGasMoleFraction(regionIdx, temperature, pressure); }
|
||||
|
||||
/*!
|
||||
* \brief The maximum mass fraction of the oil component in the gas phase.
|
||||
*/
|
||||
static Scalar saturatedGasOilMassFraction(Scalar temperature, Scalar pressure, int regionIdx)
|
||||
template <class LhsEval>
|
||||
static LhsEval saturatedGasOilMassFraction(const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
int regionIdx)
|
||||
{ return gasPvt_->saturatedGasOilMassFraction(regionIdx, temperature, pressure); }
|
||||
|
||||
/*!
|
||||
* \brief The maximum mole fraction of the oil component in the gas phase.
|
||||
*/
|
||||
static Scalar saturatedGasOilMoleFraction(Scalar temperature, Scalar pressure, int regionIdx)
|
||||
template <class LhsEval>
|
||||
static LhsEval saturatedGasOilMoleFraction(const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
int regionIdx)
|
||||
{ return gasPvt_->saturatedGasOilMoleFraction(regionIdx, temperature, pressure); }
|
||||
|
||||
/*!
|
||||
* \brief Return the normalized formation volume factor of (potentially)
|
||||
* under-saturated oil.
|
||||
*/
|
||||
static Scalar oilFormationVolumeFactor(Scalar temperature,
|
||||
Scalar pressure,
|
||||
Scalar XoG,
|
||||
template <class LhsEval>
|
||||
static LhsEval oilFormationVolumeFactor(const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
const LhsEval& XoG,
|
||||
int regionIdx)
|
||||
{ return oilPvt_->formationVolumeFactor(regionIdx, temperature, pressure, XoG); }
|
||||
|
||||
/*!
|
||||
* \brief Return the density of (potentially) under-saturated oil.
|
||||
*/
|
||||
static Scalar oilDensity(Scalar temperature, Scalar pressure, Scalar XoG, int regionIdx)
|
||||
template <class LhsEval>
|
||||
static LhsEval oilDensity(const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
const LhsEval& XoG,
|
||||
int regionIdx)
|
||||
{ return oilPvt_->density(regionIdx, temperature, pressure, XoG); }
|
||||
|
||||
/*!
|
||||
* \brief Return the density of gas-saturated oil.
|
||||
*/
|
||||
static Scalar saturatedOilDensity(Scalar temperature, Scalar pressure, int regionIdx)
|
||||
template <class LhsEval>
|
||||
static LhsEval saturatedOilDensity(const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
int regionIdx)
|
||||
{
|
||||
// mass fraction of gas-saturated oil
|
||||
Scalar XoG = saturatedOilGasMassFraction(temperature, pressure, regionIdx);
|
||||
const LhsEval& XoG = saturatedOilGasMassFraction(temperature, pressure, regionIdx);
|
||||
return oilPvt_->density(regionIdx, temperature, pressure, XoG);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Return the formation volume factor of gas.
|
||||
*/
|
||||
static Scalar gasFormationVolumeFactor(Scalar temperature, Scalar pressure, Scalar XgO, int regionIdx)
|
||||
template <class LhsEval>
|
||||
static LhsEval gasFormationVolumeFactor(const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
const LhsEval& XgO,
|
||||
int regionIdx)
|
||||
{ return gasPvt_->formationVolumeFactor(regionIdx, temperature, pressure, XgO); }
|
||||
|
||||
/*!
|
||||
* \brief Return the density of dry gas.
|
||||
*/
|
||||
static Scalar gasDensity(Scalar temperature, Scalar pressure, Scalar XgO, int regionIdx)
|
||||
template <class LhsEval>
|
||||
static LhsEval gasDensity(const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
const LhsEval& XgO,
|
||||
int regionIdx)
|
||||
{ return gasPvt_->density(regionIdx, temperature, pressure, XgO); }
|
||||
|
||||
/*!
|
||||
* \brief Return the density of water.
|
||||
*/
|
||||
static Scalar waterDensity(Scalar temperature, Scalar pressure, int regionIdx)
|
||||
template <class LhsEval>
|
||||
static LhsEval waterDensity(const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
int regionIdx)
|
||||
{ return waterPvt_->density(regionIdx, temperature, pressure); }
|
||||
|
||||
private:
|
||||
@ -540,9 +593,9 @@ private:
|
||||
referenceDensity_.resize(numRegions);
|
||||
}
|
||||
|
||||
static std::shared_ptr<const Opm::GasPvtInterface<Scalar> > gasPvt_;
|
||||
static std::shared_ptr<const Opm::OilPvtInterface<Scalar> > oilPvt_;
|
||||
static std::shared_ptr<const Opm::WaterPvtInterface<Scalar> > waterPvt_;
|
||||
static std::shared_ptr<const Opm::GasPvtInterface<Scalar, Evaluation> > gasPvt_;
|
||||
static std::shared_ptr<const Opm::OilPvtInterface<Scalar, Evaluation> > oilPvt_;
|
||||
static std::shared_ptr<const Opm::WaterPvtInterface<Scalar, Evaluation> > waterPvt_;
|
||||
|
||||
static bool enableDissolvedGas_;
|
||||
static bool enableVaporizedOil_;
|
||||
@ -554,39 +607,39 @@ private:
|
||||
static std::vector<std::array<Scalar, /*numComponents=*/3> > molarMass_;
|
||||
};
|
||||
|
||||
template <class Scalar>
|
||||
template <class Scalar, class Evaluation>
|
||||
const Scalar
|
||||
BlackOil<Scalar>::surfaceTemperature = 273.15 + 15.56; // [K]
|
||||
BlackOil<Scalar, Evaluation>::surfaceTemperature = 273.15 + 15.56; // [K]
|
||||
|
||||
template <class Scalar>
|
||||
template <class Scalar, class Evaluation>
|
||||
const Scalar
|
||||
BlackOil<Scalar>::surfacePressure = 101325.0; // [Pa]
|
||||
BlackOil<Scalar, Evaluation>::surfacePressure = 101325.0; // [Pa]
|
||||
|
||||
template <class Scalar>
|
||||
bool BlackOil<Scalar>::enableDissolvedGas_;
|
||||
template <class Scalar, class Evaluation>
|
||||
bool BlackOil<Scalar, Evaluation>::enableDissolvedGas_;
|
||||
|
||||
template <class Scalar>
|
||||
bool BlackOil<Scalar>::enableVaporizedOil_;
|
||||
template <class Scalar, class Evaluation>
|
||||
bool BlackOil<Scalar, Evaluation>::enableVaporizedOil_;
|
||||
|
||||
template <class Scalar>
|
||||
std::shared_ptr<const OilPvtInterface<Scalar> >
|
||||
BlackOil<Scalar>::oilPvt_;
|
||||
template <class Scalar, class Evaluation>
|
||||
std::shared_ptr<const OilPvtInterface<Scalar, Evaluation> >
|
||||
BlackOil<Scalar, Evaluation>::oilPvt_;
|
||||
|
||||
template <class Scalar>
|
||||
std::shared_ptr<const GasPvtInterface<Scalar> >
|
||||
BlackOil<Scalar>::gasPvt_;
|
||||
template <class Scalar, class Evaluation>
|
||||
std::shared_ptr<const GasPvtInterface<Scalar, Evaluation> >
|
||||
BlackOil<Scalar, Evaluation>::gasPvt_;
|
||||
|
||||
template <class Scalar>
|
||||
std::shared_ptr<const WaterPvtInterface<Scalar> >
|
||||
BlackOil<Scalar>::waterPvt_;
|
||||
template <class Scalar, class Evaluation>
|
||||
std::shared_ptr<const WaterPvtInterface<Scalar, Evaluation> >
|
||||
BlackOil<Scalar, Evaluation>::waterPvt_;
|
||||
|
||||
template <class Scalar>
|
||||
template <class Scalar, class Evaluation>
|
||||
std::vector<std::array<Scalar, 3> >
|
||||
BlackOil<Scalar>::referenceDensity_;
|
||||
BlackOil<Scalar, Evaluation>::referenceDensity_;
|
||||
|
||||
template <class Scalar>
|
||||
template <class Scalar, class Evaluation>
|
||||
std::vector<std::array<Scalar, 3> >
|
||||
BlackOil<Scalar>::molarMass_;
|
||||
BlackOil<Scalar, Evaluation>::molarMass_;
|
||||
}} // namespace Opm, FluidSystems
|
||||
|
||||
#endif
|
||||
|
@ -226,27 +226,30 @@ public:
|
||||
/*!
|
||||
* \copydoc BaseFluidSystem::density
|
||||
*/
|
||||
template <class FluidState>
|
||||
static Scalar density(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval density(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
typedef MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
typedef MathToolbox<LhsEval> LhsToolbox;
|
||||
|
||||
assert(0 <= phaseIdx && phaseIdx < numPhases);
|
||||
|
||||
Scalar temperature = fluidState.temperature(phaseIdx);
|
||||
Scalar pressure = fluidState.pressure(phaseIdx);
|
||||
const LhsEval& temperature = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const LhsEval& pressure = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
|
||||
if (phaseIdx == liquidPhaseIdx) {
|
||||
// use normalized composition for to calculate the density
|
||||
// (the relations don't seem to take non-normalized
|
||||
// compositions too well...)
|
||||
Scalar xlBrine = std::min(1.0, std::max(0.0, fluidState.moleFraction(liquidPhaseIdx, BrineIdx)));
|
||||
Scalar xlCO2 = std::min(1.0, std::max(0.0, fluidState.moleFraction(liquidPhaseIdx, CO2Idx)));
|
||||
Scalar sumx = xlBrine + xlCO2;
|
||||
LhsEval xlBrine = LhsToolbox::min(1.0, LhsToolbox::max(0.0, FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(liquidPhaseIdx, BrineIdx))));
|
||||
LhsEval xlCO2 = LhsToolbox::min(1.0, LhsToolbox::max(0.0, FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(liquidPhaseIdx, CO2Idx))));
|
||||
LhsEval sumx = xlBrine + xlCO2;
|
||||
xlBrine /= sumx;
|
||||
xlCO2 /= sumx;
|
||||
|
||||
Scalar result = liquidDensity_(temperature,
|
||||
LhsEval result = liquidDensity_(temperature,
|
||||
pressure,
|
||||
xlBrine,
|
||||
xlCO2);
|
||||
@ -260,13 +263,13 @@ public:
|
||||
// use normalized composition for to calculate the density
|
||||
// (the relations don't seem to take non-normalized
|
||||
// compositions too well...)
|
||||
Scalar xgBrine = std::min(1.0, std::max(0.0, fluidState.moleFraction(gasPhaseIdx, BrineIdx)));
|
||||
Scalar xgCO2 = std::min(1.0, std::max(0.0, fluidState.moleFraction(gasPhaseIdx, CO2Idx)));
|
||||
Scalar sumx = xgBrine + xgCO2;
|
||||
LhsEval xgBrine = LhsToolbox::min(1.0, LhsToolbox::max(0.0, FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(gasPhaseIdx, BrineIdx))));
|
||||
LhsEval xgCO2 = LhsToolbox::min(1.0, LhsToolbox::max(0.0, FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(gasPhaseIdx, CO2Idx))));
|
||||
LhsEval sumx = xgBrine + xgCO2;
|
||||
xgBrine /= sumx;
|
||||
xgCO2 /= sumx;
|
||||
|
||||
Scalar result = gasDensity_(temperature,
|
||||
LhsEval result = gasDensity_(temperature,
|
||||
pressure,
|
||||
xgBrine,
|
||||
xgCO2);
|
||||
@ -277,26 +280,28 @@ public:
|
||||
/*!
|
||||
* \copydoc BaseFluidSystem::viscosity
|
||||
*/
|
||||
template <class FluidState>
|
||||
static Scalar viscosity(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval viscosity(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
typedef MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
assert(0 <= phaseIdx && phaseIdx < numPhases);
|
||||
|
||||
Scalar temperature = fluidState.temperature(phaseIdx);
|
||||
Scalar pressure = fluidState.pressure(phaseIdx);
|
||||
const LhsEval& temperature = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const LhsEval& pressure = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
|
||||
if (phaseIdx == liquidPhaseIdx) {
|
||||
// assume pure brine for the liquid phase. TODO: viscosity
|
||||
// of mixture
|
||||
Scalar result = Brine::liquidViscosity(temperature, pressure);
|
||||
LhsEval result = Brine::liquidViscosity(temperature, pressure);
|
||||
Valgrind::CheckDefined(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
assert(phaseIdx == gasPhaseIdx);
|
||||
Scalar result = CO2::gasViscosity(temperature, pressure);
|
||||
LhsEval result = CO2::gasViscosity(temperature, pressure);
|
||||
Valgrind::CheckDefined(result);
|
||||
return result;
|
||||
}
|
||||
@ -304,12 +309,15 @@ public:
|
||||
/*!
|
||||
* \copydoc BaseFluidSystem::fugacityCoefficient
|
||||
*/
|
||||
template <class FluidState>
|
||||
static Scalar fugacityCoefficient(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval fugacityCoefficient(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx,
|
||||
int compIdx)
|
||||
{
|
||||
typedef MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
typedef MathToolbox<LhsEval> LhsToolbox;
|
||||
|
||||
assert(0 <= phaseIdx && phaseIdx < numPhases);
|
||||
assert(0 <= compIdx && compIdx < numComponents);
|
||||
|
||||
@ -317,18 +325,18 @@ public:
|
||||
// use the fugacity coefficients of an ideal gas. the
|
||||
// actual value of the fugacity is not relevant, as long
|
||||
// as the relative fluid compositions are observed,
|
||||
return 1.0;
|
||||
return LhsToolbox::createConstant(1.0);
|
||||
|
||||
Scalar temperature = fluidState.temperature(phaseIdx);
|
||||
Scalar pressure = fluidState.pressure(phaseIdx);
|
||||
const LhsEval& temperature = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const LhsEval& pressure = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
assert(temperature > 0);
|
||||
assert(pressure > 0);
|
||||
|
||||
// calulate the equilibrium composition for the given
|
||||
// temperature and pressure. TODO: calculateMoleFractions()
|
||||
// could use some cleanup.
|
||||
Scalar xlH2O, xgH2O;
|
||||
Scalar xlCO2, xgCO2;
|
||||
LhsEval xlH2O, xgH2O;
|
||||
LhsEval xlCO2, xgCO2;
|
||||
BinaryCoeffBrineCO2::calculateMoleFractions(temperature,
|
||||
pressure,
|
||||
Brine_IAPWS::salinity,
|
||||
@ -337,8 +345,8 @@ public:
|
||||
xgH2O);
|
||||
|
||||
// normalize the phase compositions
|
||||
xlCO2 = std::max(0.0, std::min(1.0, xlCO2));
|
||||
xgH2O = std::max(0.0, std::min(1.0, xgH2O));
|
||||
xlCO2 = LhsToolbox::max(0.0, LhsToolbox::min(1.0, xlCO2));
|
||||
xgH2O = LhsToolbox::max(0.0, LhsToolbox::min(1.0, xgH2O));
|
||||
|
||||
xlH2O = 1.0 - xlCO2;
|
||||
xgCO2 = 1.0 - xgH2O;
|
||||
@ -358,14 +366,16 @@ public:
|
||||
/*!
|
||||
* \copydoc BaseFluidSystem::diffusionCoefficient
|
||||
*/
|
||||
template <class FluidState>
|
||||
static Scalar diffusionCoefficient(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval diffusionCoefficient(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx,
|
||||
int compIdx)
|
||||
{
|
||||
Scalar temperature = fluidState.temperature(phaseIdx);
|
||||
Scalar pressure = fluidState.pressure(phaseIdx);
|
||||
typedef MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
const LhsEval& temperature = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const LhsEval& pressure = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
if (phaseIdx == liquidPhaseIdx)
|
||||
return BinaryCoeffBrineCO2::liquidDiffCoeff(temperature, pressure);
|
||||
|
||||
@ -376,19 +386,22 @@ public:
|
||||
/*!
|
||||
* \copydoc BaseFluidSystem::enthalpy
|
||||
*/
|
||||
template <class FluidState>
|
||||
static Scalar enthalpy(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval enthalpy(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
typedef MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
typedef MathToolbox<LhsEval> LhsToolbox;
|
||||
|
||||
assert(0 <= phaseIdx && phaseIdx < numPhases);
|
||||
|
||||
Scalar temperature = fluidState.temperature(phaseIdx);
|
||||
Scalar pressure = fluidState.pressure(phaseIdx);
|
||||
const LhsEval& temperature = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const LhsEval& pressure = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
|
||||
if (phaseIdx == liquidPhaseIdx) {
|
||||
Scalar XlCO2 = fluidState.massFraction(phaseIdx, CO2Idx);
|
||||
Scalar result = liquidEnthalpyBrineCO2_(temperature,
|
||||
const LhsEval& XlCO2 = FsToolbox::template toLhs<LhsEval>(fluidState.massFraction(phaseIdx, CO2Idx));
|
||||
const LhsEval& result = liquidEnthalpyBrineCO2_(temperature,
|
||||
pressure,
|
||||
Brine_IAPWS::salinity,
|
||||
XlCO2);
|
||||
@ -396,10 +409,10 @@ public:
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
Scalar XCO2 = fluidState.massFraction(gasPhaseIdx, CO2Idx);
|
||||
Scalar XBrine = fluidState.massFraction(gasPhaseIdx, BrineIdx);
|
||||
const LhsEval& XCO2 = FsToolbox::template toLhs<LhsEval>(fluidState.massFraction(gasPhaseIdx, CO2Idx));
|
||||
const LhsEval& XBrine = FsToolbox::template toLhs<LhsEval>(fluidState.massFraction(gasPhaseIdx, BrineIdx));
|
||||
|
||||
Scalar result = 0;
|
||||
LhsEval result = LhsToolbox::createConstant(0);
|
||||
result += XBrine * Brine::gasEnthalpy(temperature, pressure);
|
||||
result += XCO2 * CO2::gasEnthalpy(temperature, pressure);
|
||||
Valgrind::CheckDefined(result);
|
||||
@ -410,17 +423,19 @@ public:
|
||||
/*!
|
||||
* \copydoc BaseFluidSystem::thermalConductivity
|
||||
*/
|
||||
template <class FluidState>
|
||||
static Scalar thermalConductivity(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval thermalConductivity(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
typedef MathToolbox<LhsEval> LhsToolbox;
|
||||
|
||||
// TODO way too simple!
|
||||
if (phaseIdx == liquidPhaseIdx)
|
||||
return 0.6; // conductivity of water[W / (m K ) ]
|
||||
return LhsToolbox::createConstant(0.6); // conductivity of water[W / (m K ) ]
|
||||
|
||||
// gas phase
|
||||
return 0.025; // conductivity of air [W / (m K ) ]
|
||||
return LhsToolbox::createConstant(0.025); // conductivity of air [W / (m K ) ]
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -435,32 +450,37 @@ public:
|
||||
* \param phaseIdx The index of the fluid phase to consider
|
||||
* \tparam FluidState the fluid state class
|
||||
*/
|
||||
template <class FluidState>
|
||||
static Scalar heatCapacity(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval heatCapacity(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
typedef MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
assert(0 <= phaseIdx && phaseIdx < numPhases);
|
||||
|
||||
const LhsEval& temperature = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const LhsEval& pressure = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
|
||||
if(phaseIdx == liquidPhaseIdx)
|
||||
return H2O::liquidHeatCapacity(fluidState.temperature(phaseIdx),
|
||||
fluidState.pressure(phaseIdx));
|
||||
return H2O::liquidHeatCapacity(temperature, pressure);
|
||||
else
|
||||
return CO2::gasHeatCapacity(fluidState.temperature(phaseIdx),
|
||||
fluidState.pressure(phaseIdx));
|
||||
return CO2::gasHeatCapacity(temperature, pressure);
|
||||
}
|
||||
|
||||
private:
|
||||
static Scalar gasDensity_(Scalar T,
|
||||
Scalar pg,
|
||||
Scalar xgH2O,
|
||||
Scalar xgCO2)
|
||||
template <class LhsEval>
|
||||
static LhsEval gasDensity_(const LhsEval& T,
|
||||
const LhsEval& pg,
|
||||
const LhsEval& xgH2O,
|
||||
const LhsEval& xgCO2)
|
||||
{
|
||||
Valgrind::CheckDefined(T);
|
||||
Valgrind::CheckDefined(pg);
|
||||
Valgrind::CheckDefined(xgH2O);
|
||||
Valgrind::CheckDefined(xgCO2);
|
||||
|
||||
Scalar gasDensity = CO2::gasDensity(T, pg);
|
||||
return gasDensity;
|
||||
return CO2::gasDensity(T, pg);
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
@ -469,10 +489,11 @@ private:
|
||||
/* rho_{b,CO2} = rho_w + contribution(salt) + contribution(CO2) */
|
||||
/* */
|
||||
/***********************************************************************/
|
||||
static Scalar liquidDensity_(Scalar T,
|
||||
Scalar pl,
|
||||
Scalar xlH2O,
|
||||
Scalar xlCO2)
|
||||
template <class LhsEval>
|
||||
static LhsEval liquidDensity_(const LhsEval& T,
|
||||
const LhsEval& pl,
|
||||
const LhsEval& xlH2O,
|
||||
const LhsEval& xlCO2)
|
||||
{
|
||||
Valgrind::CheckDefined(T);
|
||||
Valgrind::CheckDefined(pl);
|
||||
@ -490,28 +511,31 @@ private:
|
||||
"defined below 250MPa (is " << pl << "Pa)");
|
||||
}
|
||||
|
||||
Scalar rho_brine = Brine::liquidDensity(T, pl);
|
||||
Scalar rho_pure = H2O::liquidDensity(T, pl);
|
||||
Scalar rho_lCO2 = liquidDensityWaterCO2_(T, pl, xlH2O, xlCO2);
|
||||
Scalar contribCO2 = rho_lCO2 - rho_pure;
|
||||
const LhsEval& rho_brine = Brine::liquidDensity(T, pl);
|
||||
const LhsEval& rho_pure = H2O::liquidDensity(T, pl);
|
||||
const LhsEval& rho_lCO2 = liquidDensityWaterCO2_(T, pl, xlH2O, xlCO2);
|
||||
const LhsEval& contribCO2 = rho_lCO2 - rho_pure;
|
||||
|
||||
return rho_brine + contribCO2;
|
||||
}
|
||||
|
||||
static Scalar liquidDensityWaterCO2_(Scalar temperature,
|
||||
Scalar pl,
|
||||
Scalar xlH2O,
|
||||
Scalar xlCO2)
|
||||
template <class LhsEval>
|
||||
static LhsEval liquidDensityWaterCO2_(const LhsEval& temperature,
|
||||
const LhsEval& pl,
|
||||
const LhsEval& /*xlH2O*/,
|
||||
const LhsEval& xlCO2)
|
||||
{
|
||||
const Scalar M_CO2 = CO2::molarMass();
|
||||
const Scalar M_H2O = H2O::molarMass();
|
||||
Scalar M_CO2 = CO2::molarMass();
|
||||
Scalar M_H2O = H2O::molarMass();
|
||||
|
||||
const Scalar tempC = temperature - 273.15; /* tempC : temperature in °C */
|
||||
const Scalar rho_pure = H2O::liquidDensity(temperature, pl);
|
||||
xlH2O = 1.0 - xlCO2; // xlH2O is available, but in case of a pure gas phase
|
||||
// the value of M_T for the virtual liquid phase can become very large
|
||||
const Scalar M_T = M_H2O * xlH2O + M_CO2 * xlCO2;
|
||||
const Scalar V_phi =
|
||||
const LhsEval& tempC = temperature - 273.15; /* tempC : temperature in °C */
|
||||
const LhsEval& rho_pure = H2O::liquidDensity(temperature, pl);
|
||||
// calculate the mole fraction of CO2 in the liquid. note that xlH2O is available
|
||||
// as a function parameter, but in the case of a pure gas phase the value of M_T
|
||||
// for the virtual liquid phase can become very large
|
||||
const LhsEval xlH2O = 1.0 - xlCO2;
|
||||
const LhsEval& M_T = M_H2O * xlH2O + M_CO2 * xlCO2;
|
||||
const LhsEval& V_phi =
|
||||
(37.51 +
|
||||
tempC*(-9.585e-2 +
|
||||
tempC*(8.74e-4 -
|
||||
@ -519,41 +543,43 @@ private:
|
||||
return 1/ (xlCO2 * V_phi/M_T + M_H2O * xlH2O / (rho_pure * M_T));
|
||||
}
|
||||
|
||||
static Scalar liquidEnthalpyBrineCO2_(Scalar T,
|
||||
Scalar p,
|
||||
Scalar S,
|
||||
Scalar X_CO2_w)
|
||||
template <class LhsEval>
|
||||
static LhsEval liquidEnthalpyBrineCO2_(const LhsEval& T,
|
||||
const LhsEval& p,
|
||||
Scalar S, // salinity
|
||||
const LhsEval& X_CO2_w)
|
||||
{
|
||||
typedef MathToolbox<LhsEval> LhsToolbox;
|
||||
|
||||
/* X_CO2_w : mass fraction of CO2 in brine */
|
||||
|
||||
/* same function as enthalpy_brine, only extended by CO2 content */
|
||||
|
||||
/*Numerical coefficents from PALLISER*/
|
||||
static const Scalar f[] = {
|
||||
static Scalar f[] = {
|
||||
2.63500E-1, 7.48368E-6, 1.44611E-6, -3.80860E-10
|
||||
};
|
||||
|
||||
/*Numerical coefficents from MICHAELIDES for the enthalpy of brine*/
|
||||
static const Scalar a[4][3] = {
|
||||
static Scalar a[4][3] = {
|
||||
{ 9633.6, -4080.0, +286.49 },
|
||||
{ +166.58, +68.577, -4.6856 },
|
||||
{ -0.90963, -0.36524, +0.249667E-1 },
|
||||
{ +0.17965E-2, +0.71924E-3, -0.4900E-4 }
|
||||
};
|
||||
|
||||
Scalar theta, h_NaCl;
|
||||
Scalar m, h_ls1, d_h;
|
||||
Scalar S_lSAT, delta_h;
|
||||
int i, j;
|
||||
Scalar delta_hCO2, hg, hw;
|
||||
LhsEval theta, h_NaCl;
|
||||
LhsEval h_ls1, d_h;
|
||||
LhsEval delta_h;
|
||||
LhsEval delta_hCO2, hg, hw;
|
||||
|
||||
theta = T - 273.15;
|
||||
|
||||
S_lSAT = f[0] + f[1]*theta + f[2]*theta*theta + f[3]*theta*theta*theta;
|
||||
/*Regularization*/
|
||||
if (S>S_lSAT) {
|
||||
// Regularization
|
||||
Scalar scalarTheta = LhsToolbox::value(theta);
|
||||
Scalar S_lSAT = f[0] + scalarTheta*(f[1] + scalarTheta*(f[2] + scalarTheta*f[3]));
|
||||
if (S > S_lSAT)
|
||||
S = S_lSAT;
|
||||
}
|
||||
|
||||
hw = H2O::liquidEnthalpy(T, p) /1E3; /* kJ/kg */
|
||||
|
||||
@ -561,14 +587,14 @@ private:
|
||||
/*U=*/h_NaCl = (3.6710E4*T + 0.5*(6.2770E1)*T*T - ((6.6670E-2)/3)*T*T*T
|
||||
+((2.8000E-5)/4)*(T*T*T*T))/(58.44E3)- 2.045698e+02; /* kJ/kg */
|
||||
|
||||
m = (1E3/58.44)*(S/(1-S));
|
||||
i = 0;
|
||||
j = 0;
|
||||
Scalar m = 1E3/58.44 * S/(1-S);
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
d_h = 0;
|
||||
|
||||
for (i = 0; i<=3; i++) {
|
||||
for (j=0; j<=2; j++) {
|
||||
d_h = d_h + a[i][j] * pow(theta, i) * pow(m, j);
|
||||
d_h = d_h + a[i][j] * LhsToolbox::pow(theta, static_cast<Scalar>(i)) * std::pow(m, j);
|
||||
}
|
||||
}
|
||||
/* heat of dissolution for halite according to Michaelides 1971 */
|
||||
|
@ -98,7 +98,8 @@ public:
|
||||
*
|
||||
* \copydetails Doxygen::temperatureParam
|
||||
*/
|
||||
static Scalar vaporPressure(Scalar temperature)
|
||||
template <class Evaluation>
|
||||
static Evaluation vaporPressure(const Evaluation& temperature)
|
||||
{ return Component::vaporPressure(temperature); }
|
||||
|
||||
/*!
|
||||
@ -106,7 +107,8 @@ public:
|
||||
*
|
||||
* \copydetails Doxygen::TpParams
|
||||
*/
|
||||
static Scalar density(Scalar temperature, Scalar pressure)
|
||||
template <class Evaluation>
|
||||
static Evaluation density(const Evaluation& temperature, const Evaluation& pressure)
|
||||
{ return Component::gasDensity(temperature, pressure); }
|
||||
|
||||
/*!
|
||||
@ -115,7 +117,8 @@ public:
|
||||
* \param temperature The temperature of interest [K]
|
||||
* \param density The density of interest [kg / m^3]
|
||||
*/
|
||||
static Scalar pressure(Scalar temperature, Scalar density)
|
||||
template <class Evaluation>
|
||||
static Evaluation pressure(const Evaluation& temperature, const Evaluation& density)
|
||||
{ return Component::gasPressure(temperature, density); }
|
||||
|
||||
/*!
|
||||
@ -123,7 +126,8 @@ public:
|
||||
*
|
||||
* \copydetails Doxygen::TpParams
|
||||
*/
|
||||
static const Scalar enthalpy(Scalar temperature, Scalar pressure)
|
||||
template <class Evaluation>
|
||||
static Evaluation enthalpy(const Evaluation& temperature, const Evaluation& pressure)
|
||||
{ return Component::gasEnthalpy(temperature, pressure); }
|
||||
|
||||
/*!
|
||||
@ -131,7 +135,8 @@ public:
|
||||
*
|
||||
* \copydetails Doxygen::TpParams
|
||||
*/
|
||||
static const Scalar internalEnergy(Scalar temperature, Scalar pressure)
|
||||
template <class Evaluation>
|
||||
static Evaluation internalEnergy(const Evaluation& temperature, const Evaluation& pressure)
|
||||
{ return Component::gasInternalEnergy(temperature, pressure); }
|
||||
|
||||
/*!
|
||||
@ -139,7 +144,8 @@ public:
|
||||
*
|
||||
* \copydetails Doxygen::TpParams
|
||||
*/
|
||||
static Scalar viscosity(Scalar temperature, Scalar pressure)
|
||||
template <class Evaluation>
|
||||
static Evaluation viscosity(const Evaluation& temperature, const Evaluation& pressure)
|
||||
{ return Component::gasViscosity(temperature, pressure); }
|
||||
|
||||
/*!
|
||||
@ -147,7 +153,8 @@ public:
|
||||
*
|
||||
* \copydetails Doxygen::TpParams
|
||||
*/
|
||||
static Scalar thermalConductivity(Scalar temperature, Scalar pressure)
|
||||
template <class Evaluation>
|
||||
static Evaluation thermalConductivity(const Evaluation& temperature, const Evaluation& pressure)
|
||||
{ return Component::gasThermalConductivity(temperature, pressure); }
|
||||
|
||||
/*!
|
||||
@ -155,7 +162,8 @@ public:
|
||||
*
|
||||
* \copydetails Doxygen::TpParams
|
||||
*/
|
||||
static Scalar heatCapacity(Scalar temperature, Scalar pressure)
|
||||
template <class Evaluation>
|
||||
static Evaluation heatCapacity(const Evaluation& temperature, const Evaluation& pressure)
|
||||
{ return Component::gasHeatCapacity(temperature, pressure); }
|
||||
};
|
||||
} // namespace Opm
|
||||
|
@ -249,17 +249,20 @@ public:
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::density
|
||||
template <class FluidState>
|
||||
static Scalar density(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval density(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
typedef Opm::MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
typedef Opm::MathToolbox<LhsEval> LhsToolbox;
|
||||
|
||||
assert(0 <= phaseIdx && phaseIdx < numPhases);
|
||||
|
||||
Scalar T = fluidState.temperature(phaseIdx);
|
||||
Scalar p;
|
||||
const auto& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
LhsEval p;
|
||||
if (isCompressible(phaseIdx))
|
||||
p = fluidState.pressure(phaseIdx);
|
||||
p = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
else {
|
||||
// random value which will hopefully cause things to blow
|
||||
// up if it is used in a calculation!
|
||||
@ -268,9 +271,9 @@ public:
|
||||
}
|
||||
|
||||
|
||||
Scalar sumMoleFrac = 0;
|
||||
LhsEval sumMoleFrac = 0;
|
||||
for (int compIdx = 0; compIdx < numComponents; ++compIdx)
|
||||
sumMoleFrac += fluidState.moleFraction(phaseIdx, compIdx);
|
||||
sumMoleFrac += FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(phaseIdx, compIdx));
|
||||
|
||||
if (phaseIdx == liquidPhaseIdx)
|
||||
{
|
||||
@ -280,15 +283,13 @@ public:
|
||||
else
|
||||
{
|
||||
// See: Ochs 2008 (2.6)
|
||||
Scalar rholH2O = H2O::liquidDensity(T, p);
|
||||
Scalar clH2O = rholH2O/H2O::molarMass();
|
||||
const LhsEval& rholH2O = H2O::liquidDensity(T, p);
|
||||
const LhsEval& clH2O = rholH2O/H2O::molarMass();
|
||||
|
||||
return
|
||||
clH2O
|
||||
* (H2O::molarMass()*fluidState.moleFraction(liquidPhaseIdx, H2OIdx)
|
||||
+
|
||||
Air::molarMass()*fluidState.moleFraction(liquidPhaseIdx, AirIdx))
|
||||
/ sumMoleFrac;
|
||||
const auto& xlH2O = FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(liquidPhaseIdx, H2OIdx));
|
||||
const auto& xlAir = FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(liquidPhaseIdx, AirIdx));
|
||||
|
||||
return clH2O*(H2O::molarMass()*xlH2O + Air::molarMass()*xlAir)/sumMoleFrac;
|
||||
}
|
||||
}
|
||||
else if (phaseIdx == gasPhaseIdx)
|
||||
@ -297,34 +298,35 @@ public:
|
||||
// for the gas phase assume an ideal gas
|
||||
return
|
||||
IdealGas::molarDensity(T, p)
|
||||
* fluidState.averageMolarMass(gasPhaseIdx)
|
||||
/ std::max(1e-5, sumMoleFrac);
|
||||
* FsToolbox::template toLhs<LhsEval>(fluidState.averageMolarMass(gasPhaseIdx))
|
||||
/ LhsToolbox::max(1e-5, sumMoleFrac);
|
||||
|
||||
Scalar partialPressureH2O =
|
||||
fluidState.moleFraction(gasPhaseIdx, H2OIdx) *
|
||||
fluidState.pressure(gasPhaseIdx);
|
||||
LhsEval partialPressureH2O =
|
||||
FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(gasPhaseIdx, H2OIdx))
|
||||
*FsToolbox::template toLhs<LhsEval>(fluidState.pressure(gasPhaseIdx));
|
||||
|
||||
Scalar partialPressureAir =
|
||||
fluidState.moleFraction(gasPhaseIdx, AirIdx) *
|
||||
fluidState.pressure(gasPhaseIdx);
|
||||
LhsEval partialPressureAir =
|
||||
FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(gasPhaseIdx, AirIdx))
|
||||
*FsToolbox::template toLhs<LhsEval>(fluidState.pressure(gasPhaseIdx));
|
||||
|
||||
return
|
||||
H2O::gasDensity(T, partialPressureH2O) +
|
||||
Air::gasDensity(T, partialPressureAir);
|
||||
return H2O::gasDensity(T, partialPressureH2O) + Air::gasDensity(T, partialPressureAir);
|
||||
}
|
||||
OPM_THROW(std::logic_error, "Invalid phase index " << phaseIdx);
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::viscosity
|
||||
template <class FluidState>
|
||||
static Scalar viscosity(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval viscosity(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
typedef Opm::MathToolbox<LhsEval> LhsToolbox;
|
||||
typedef Opm::MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
assert(0 <= phaseIdx && phaseIdx < numPhases);
|
||||
|
||||
Scalar T = fluidState.temperature(phaseIdx);
|
||||
Scalar p = fluidState.pressure(phaseIdx);
|
||||
const auto& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const auto& p = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
|
||||
if (phaseIdx == liquidPhaseIdx)
|
||||
{
|
||||
@ -348,10 +350,9 @@ public:
|
||||
*
|
||||
*/
|
||||
|
||||
Scalar muResult = 0;
|
||||
const Scalar mu[numComponents] = {
|
||||
H2O::gasViscosity(T,
|
||||
H2O::vaporPressure(T)),
|
||||
LhsEval muResult = 0;
|
||||
const LhsEval mu[numComponents] = {
|
||||
H2O::gasViscosity(T, H2O::vaporPressure(T)),
|
||||
Air::gasViscosity(T, p)
|
||||
};
|
||||
|
||||
@ -363,17 +364,20 @@ public:
|
||||
|
||||
for (int i = 0; i < numComponents; ++i)
|
||||
{
|
||||
Scalar divisor = 0;
|
||||
LhsEval divisor = 0;
|
||||
for (int j = 0; j < numComponents; ++j)
|
||||
{
|
||||
Scalar phiIJ = 1 + std::sqrt(mu[i]/mu[j]) * // 1 + (mu[i]/mu[j]^1/2
|
||||
LhsEval phiIJ =
|
||||
1 +
|
||||
LhsToolbox::sqrt(mu[i]/mu[j]) * // 1 + (mu[i]/mu[j]^1/2
|
||||
std::pow(M[j]/M[i], 1./4.0); // (M[i]/M[j])^1/4
|
||||
|
||||
phiIJ *= phiIJ;
|
||||
phiIJ /= std::sqrt(8*(1 + M[i]/M[j]));
|
||||
divisor += fluidState.moleFraction(phaseIdx, j)*phiIJ;
|
||||
divisor += FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(phaseIdx, j))*phiIJ;
|
||||
}
|
||||
muResult += fluidState.moleFraction(phaseIdx, i)*mu[i] / divisor;
|
||||
const auto& xAlphaI = FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(phaseIdx, i));
|
||||
muResult += xAlphaI*mu[i]/divisor;
|
||||
}
|
||||
return muResult;
|
||||
}
|
||||
@ -382,17 +386,19 @@ public:
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::fugacityCoefficient
|
||||
template <class FluidState>
|
||||
static Scalar fugacityCoefficient(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval fugacityCoefficient(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx,
|
||||
int compIdx)
|
||||
{
|
||||
typedef Opm::MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
assert(0 <= phaseIdx && phaseIdx < numPhases);
|
||||
assert(0 <= compIdx && compIdx < numComponents);
|
||||
|
||||
Scalar T = fluidState.temperature(phaseIdx);
|
||||
Scalar p = fluidState.pressure(phaseIdx);
|
||||
const auto& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const auto& p = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
|
||||
if (phaseIdx == liquidPhaseIdx) {
|
||||
if (compIdx == H2OIdx)
|
||||
@ -406,14 +412,16 @@ public:
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::diffusionCoefficient
|
||||
template <class FluidState>
|
||||
static Scalar binaryDiffusionCoefficient(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval binaryDiffusionCoefficient(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx,
|
||||
int compIdx)
|
||||
{
|
||||
Scalar T = fluidState.temperature(phaseIdx);
|
||||
Scalar p = fluidState.pressure(phaseIdx);
|
||||
typedef Opm::MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
const auto& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const auto& p = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
|
||||
if (phaseIdx == liquidPhaseIdx)
|
||||
return BinaryCoeff::H2O_Air::liquidDiffCoeff(T, p);
|
||||
@ -423,13 +431,15 @@ public:
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::enthalpy
|
||||
template <class FluidState>
|
||||
static Scalar enthalpy(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval enthalpy(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
Scalar T = fluidState.temperature(phaseIdx);
|
||||
Scalar p = fluidState.pressure(phaseIdx);
|
||||
typedef Opm::MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
const auto& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const auto& p = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
Valgrind::CheckDefined(T);
|
||||
Valgrind::CheckDefined(p);
|
||||
|
||||
@ -441,48 +451,52 @@ public:
|
||||
|
||||
else if (phaseIdx == gasPhaseIdx)
|
||||
{
|
||||
Scalar result = 0.0;
|
||||
LhsEval result = 0.0;
|
||||
result +=
|
||||
H2O::gasEnthalpy(T, p) *
|
||||
fluidState.massFraction(gasPhaseIdx, H2OIdx);
|
||||
FsToolbox::template toLhs<LhsEval>(fluidState.massFraction(gasPhaseIdx, H2OIdx));
|
||||
|
||||
result +=
|
||||
Air::gasEnthalpy(T, p) *
|
||||
fluidState.massFraction(gasPhaseIdx, AirIdx);
|
||||
FsToolbox::template toLhs<LhsEval>(fluidState.massFraction(gasPhaseIdx, AirIdx));
|
||||
return result;
|
||||
}
|
||||
OPM_THROW(std::logic_error, "Invalid phase index " << phaseIdx);
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::thermalConductivity
|
||||
template <class FluidState>
|
||||
static Scalar thermalConductivity(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval thermalConductivity(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
typedef MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
assert(0 <= phaseIdx && phaseIdx < numPhases);
|
||||
|
||||
Scalar temperature = fluidState.temperature(phaseIdx) ;
|
||||
Scalar pressure = fluidState.pressure(phaseIdx);
|
||||
const LhsEval& temperature =
|
||||
FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const LhsEval& pressure =
|
||||
FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
|
||||
if (phaseIdx == liquidPhaseIdx){// liquid phase
|
||||
if (phaseIdx == liquidPhaseIdx)
|
||||
return H2O::liquidThermalConductivity(temperature, pressure);
|
||||
}
|
||||
else{// gas phase
|
||||
Scalar lambdaDryAir = Air::gasThermalConductivity(temperature, pressure);
|
||||
else { // gas phase
|
||||
const LhsEval& lambdaDryAir = Air::gasThermalConductivity(temperature, pressure);
|
||||
|
||||
if (useComplexRelations){
|
||||
Scalar xAir = fluidState.moleFraction(phaseIdx, AirIdx);
|
||||
Scalar xH2O = fluidState.moleFraction(phaseIdx, H2OIdx);
|
||||
Scalar lambdaAir = xAir * lambdaDryAir;
|
||||
const LhsEval& xAir =
|
||||
FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(phaseIdx, AirIdx));
|
||||
const LhsEval& xH2O =
|
||||
FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(phaseIdx, H2OIdx));
|
||||
LhsEval lambdaAir = xAir*lambdaDryAir;
|
||||
|
||||
// Assuming Raoult's, Daltons law and ideal gas
|
||||
// in order to obtain the partial density of water in the air phase
|
||||
Scalar partialPressure = pressure * xH2O;
|
||||
LhsEval partialPressure = pressure*xH2O;
|
||||
|
||||
Scalar lambdaH2O =
|
||||
xH2O
|
||||
* H2O::gasThermalConductivity(temperature, partialPressure);
|
||||
LhsEval lambdaH2O =
|
||||
xH2O*H2O::gasThermalConductivity(temperature, partialPressure);
|
||||
return lambdaAir + lambdaH2O;
|
||||
}
|
||||
else
|
||||
|
@ -194,44 +194,46 @@ public:
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::density
|
||||
template <class FluidState>
|
||||
static Scalar density(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval density(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
Scalar T = fluidState.temperature(phaseIdx) ;
|
||||
typedef Opm::MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
const LhsEval& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
|
||||
if (phaseIdx == waterPhaseIdx) {
|
||||
// See: Ochs 2008
|
||||
Scalar p = H2O::liquidIsCompressible()?fluidState.pressure(phaseIdx):1e100;
|
||||
Scalar rholH2O = H2O::liquidDensity(T, p);
|
||||
Scalar clH2O = rholH2O/H2O::molarMass();
|
||||
const LhsEval& p =
|
||||
H2O::liquidIsCompressible()
|
||||
? FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx))
|
||||
: 1e100;
|
||||
|
||||
const LhsEval& rholH2O = H2O::liquidDensity(T, p);
|
||||
const LhsEval& clH2O = rholH2O/H2O::molarMass();
|
||||
|
||||
// this assumes each dissolved molecule displaces exactly one
|
||||
// water molecule in the liquid
|
||||
return
|
||||
clH2O*(H2O::molarMass()*fluidState.moleFraction(waterPhaseIdx, H2OIdx)
|
||||
+
|
||||
Air::molarMass()*fluidState.moleFraction(waterPhaseIdx, airIdx)
|
||||
+
|
||||
NAPL::molarMass()*fluidState.moleFraction(waterPhaseIdx, NAPLIdx));
|
||||
clH2O*(H2O::molarMass()*FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(waterPhaseIdx, H2OIdx)) +
|
||||
Air::molarMass()*FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(waterPhaseIdx, airIdx)) +
|
||||
NAPL::molarMass()*FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(waterPhaseIdx, NAPLIdx)));
|
||||
}
|
||||
else if (phaseIdx == naplPhaseIdx) {
|
||||
// assume pure NAPL for the NAPL phase
|
||||
Scalar p = NAPL::liquidIsCompressible()?fluidState.pressure(phaseIdx):1e100;
|
||||
const LhsEval& p =
|
||||
NAPL::liquidIsCompressible()
|
||||
? FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx))
|
||||
: 1e100;
|
||||
return NAPL::liquidDensity(T, p);
|
||||
}
|
||||
|
||||
assert (phaseIdx == gasPhaseIdx);
|
||||
Scalar pH2O =
|
||||
fluidState.moleFraction(gasPhaseIdx, H2OIdx) *
|
||||
fluidState.pressure(gasPhaseIdx);
|
||||
Scalar pAir =
|
||||
fluidState.moleFraction(gasPhaseIdx, airIdx) *
|
||||
fluidState.pressure(gasPhaseIdx);
|
||||
Scalar pNAPL =
|
||||
fluidState.moleFraction(gasPhaseIdx, NAPLIdx) *
|
||||
fluidState.pressure(gasPhaseIdx);
|
||||
const LhsEval& pg = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(gasPhaseIdx));
|
||||
const LhsEval& pH2O = FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(gasPhaseIdx, H2OIdx))*pg;
|
||||
const LhsEval& pAir = FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(gasPhaseIdx, airIdx))*pg;
|
||||
const LhsEval& pNAPL = FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(gasPhaseIdx, NAPLIdx))*pg;
|
||||
return
|
||||
H2O::gasDensity(T, pH2O) +
|
||||
Air::gasDensity(T, pAir) +
|
||||
@ -239,13 +241,15 @@ public:
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::viscosity
|
||||
template <class FluidState>
|
||||
static Scalar viscosity(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval viscosity(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
Scalar T = fluidState.temperature(phaseIdx);
|
||||
Scalar p = fluidState.pressure(phaseIdx);
|
||||
typedef Opm::MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
const LhsEval& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const LhsEval& p = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
|
||||
if (phaseIdx == waterPhaseIdx) {
|
||||
// assume pure water viscosity
|
||||
@ -271,8 +275,7 @@ public:
|
||||
* divisions
|
||||
* -- compare e.g. with Promo Class p. 32/33
|
||||
*/
|
||||
Scalar muResult;
|
||||
const Scalar mu[numComponents] = {
|
||||
const LhsEval mu[numComponents] = {
|
||||
H2O::gasViscosity(T, H2O::vaporPressure(T)),
|
||||
Air::gasViscosity(T, p),
|
||||
NAPL::gasViscosity(T, NAPL::vaporPressure(T))
|
||||
@ -284,51 +287,46 @@ public:
|
||||
NAPL::molarMass()
|
||||
};
|
||||
|
||||
Scalar muAW = mu[airIdx]*fluidState.moleFraction(gasPhaseIdx, airIdx)
|
||||
+ mu[H2OIdx]*fluidState.moleFraction(gasPhaseIdx, H2OIdx)
|
||||
/ (fluidState.moleFraction(gasPhaseIdx, airIdx)
|
||||
+ fluidState.moleFraction(gasPhaseIdx, H2OIdx));
|
||||
Scalar xAW = fluidState.moleFraction(gasPhaseIdx, airIdx)
|
||||
+ fluidState.moleFraction(gasPhaseIdx, H2OIdx);
|
||||
|
||||
Scalar MAW = (fluidState.moleFraction(gasPhaseIdx, airIdx)*Air::molarMass()
|
||||
+ fluidState.moleFraction(gasPhaseIdx, H2OIdx)*H2O::molarMass())
|
||||
/ xAW;
|
||||
const LhsEval& xgAir = FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(gasPhaseIdx, airIdx));
|
||||
const LhsEval& xgH2O = FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(gasPhaseIdx, H2OIdx));
|
||||
const LhsEval& xgNapl = FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(gasPhaseIdx, NAPLIdx));
|
||||
const LhsEval& xgAW = xgAir + xgH2O;
|
||||
const LhsEval& muAW = (mu[airIdx]*xgAir + mu[H2OIdx]*xgH2O)/xgAW;
|
||||
const LhsEval& MAW = (xgAir*Air::molarMass() + xgH2O*H2O::molarMass())/xgAW;
|
||||
|
||||
Scalar phiCAW = 0.3; // simplification for this particular system
|
||||
/* actually like this
|
||||
* Scalar phiCAW = std::pow(1.+std::sqrt(mu[NAPLIdx]/muAW)*std::pow(MAW/M[NAPLIdx],0.25),2)
|
||||
* / std::sqrt(8.*(1.+M[NAPLIdx]/MAW));
|
||||
*/
|
||||
Scalar phiAWC = phiCAW * muAW*M[NAPLIdx]/(mu[NAPLIdx]*MAW);
|
||||
const LhsEval& phiAWC = phiCAW * muAW*M[NAPLIdx]/(mu[NAPLIdx]*MAW);
|
||||
|
||||
muResult = (xAW*muAW)/(xAW+fluidState.moleFraction(gasPhaseIdx, NAPLIdx)*phiAWC)
|
||||
+ (fluidState.moleFraction(gasPhaseIdx, NAPLIdx) * mu[NAPLIdx])
|
||||
/ (fluidState.moleFraction(gasPhaseIdx, NAPLIdx) + xAW*phiCAW);
|
||||
return muResult;
|
||||
return (xgAW*muAW)/(xgAW + xgNapl*phiAWC) + (xgNapl*mu[NAPLIdx])/(xgNapl + xgAW*phiCAW);
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::diffusionCoefficient
|
||||
template <class FluidState>
|
||||
static Scalar diffusionCoefficient(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval diffusionCoefficient(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx,
|
||||
int compIdx)
|
||||
{
|
||||
return 0;
|
||||
#if 0
|
||||
Scalar T = fluidState.temperature(phaseIdx) ;
|
||||
Scalar p = fluidState.pressure(phaseIdx);
|
||||
Scalar diffCont;
|
||||
typedef Opm::MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
const LhsEval& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const LhsEval& p = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
LhsEval diffCont;
|
||||
|
||||
if (phaseIdx==gasPhaseIdx) {
|
||||
Scalar diffAC = Opm::BinaryCoeff::Air_Mesitylene::gasDiffCoeff(T, p);
|
||||
Scalar diffWC = Opm::BinaryCoeff::H2O_Mesitylene::gasDiffCoeff(T, p);
|
||||
Scalar diffAW = Opm::BinaryCoeff::H2O_Air::gasDiffCoeff(T, p);
|
||||
const LhsEval& diffAC = Opm::BinaryCoeff::Air_Mesitylene::gasDiffCoeff(T, p);
|
||||
const LhsEval& diffWC = Opm::BinaryCoeff::H2O_Mesitylene::gasDiffCoeff(T, p);
|
||||
const LhsEval& diffAW = Opm::BinaryCoeff::H2O_Air::gasDiffCoeff(T, p);
|
||||
|
||||
const Scalar xga = fluidState.moleFraction(gasPhaseIdx, airIdx);
|
||||
const Scalar xgw = fluidState.moleFraction(gasPhaseIdx, H2OIdx);
|
||||
const Scalar xgc = fluidState.moleFraction(gasPhaseIdx, NAPLIdx);
|
||||
const LhsEval& xga = FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(gasPhaseIdx, airIdx));
|
||||
const LhsEval& xgw = FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(gasPhaseIdx, H2OIdx));
|
||||
const LhsEval& xgc = FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(gasPhaseIdx, NAPLIdx));
|
||||
|
||||
if (compIdx==NAPLIdx) return (1 - xgw)/(xga/diffAW + xgc/diffWC);
|
||||
else if (compIdx==H2OIdx) return (1 - xgc)/(xgw/diffWC + xga/diffAC);
|
||||
@ -337,13 +335,13 @@ public:
|
||||
"is constraint by sum of diffusive fluxes = 0 !\n");
|
||||
}
|
||||
else if (phaseIdx==waterPhaseIdx){
|
||||
Scalar diffACl = 1.e-9; // BinaryCoeff::Air_Mesitylene::liquidDiffCoeff(temperature, pressure);
|
||||
Scalar diffWCl = 1.e-9; // BinaryCoeff::H2O_Mesitylene::liquidDiffCoeff(temperature, pressure);
|
||||
Scalar diffAWl = 1.e-9; // BinaryCoeff::H2O_Air::liquidDiffCoeff(temperature, pressure);
|
||||
const LhsEval& diffACl = 1.e-9; // BinaryCoeff::Air_Mesitylene::liquidDiffCoeff(temperature, pressure);
|
||||
const LhsEval& diffWCl = 1.e-9; // BinaryCoeff::H2O_Mesitylene::liquidDiffCoeff(temperature, pressure);
|
||||
const LhsEval& diffAWl = 1.e-9; // BinaryCoeff::H2O_Air::liquidDiffCoeff(temperature, pressure);
|
||||
|
||||
Scalar xwa = fluidState.moleFraction(waterPhaseIdx, airIdx);
|
||||
Scalar xww = fluidState.moleFraction(waterPhaseIdx, H2OIdx);
|
||||
Scalar xwc = fluidState.moleFraction(waterPhaseIdx, NAPLIdx);
|
||||
const LhsEval& xwa = FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(waterPhaseIdx, airIdx));
|
||||
const LhsEval& xww = FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(waterPhaseIdx, H2OIdx));
|
||||
const LhsEval& xwc = FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(waterPhaseIdx, NAPLIdx));
|
||||
|
||||
switch (compIdx) {
|
||||
case NAPLIdx:
|
||||
@ -368,17 +366,19 @@ public:
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::fugacityCoefficient
|
||||
template <class FluidState>
|
||||
static Scalar fugacityCoefficient(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval fugacityCoefficient(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx,
|
||||
int compIdx)
|
||||
{
|
||||
typedef Opm::MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
assert(0 <= phaseIdx && phaseIdx < numPhases);
|
||||
assert(0 <= compIdx && compIdx < numComponents);
|
||||
|
||||
Scalar T = fluidState.temperature(phaseIdx);
|
||||
Scalar p = fluidState.pressure(phaseIdx);
|
||||
const LhsEval& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const LhsEval& p = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
Valgrind::CheckDefined(T);
|
||||
Valgrind::CheckDefined(p);
|
||||
|
||||
@ -397,7 +397,7 @@ public:
|
||||
// other components, i.e. the fugacity cofficient is much
|
||||
// smaller.
|
||||
else if (phaseIdx == naplPhaseIdx) {
|
||||
Scalar phiNapl = NAPL::vaporPressure(T)/p;
|
||||
const LhsEval& phiNapl = NAPL::vaporPressure(T)/p;
|
||||
if (compIdx == NAPLIdx)
|
||||
return phiNapl;
|
||||
else if (compIdx == airIdx)
|
||||
@ -415,13 +415,15 @@ public:
|
||||
|
||||
|
||||
//! \copydoc BaseFluidSystem::enthalpy
|
||||
template <class FluidState>
|
||||
static Scalar enthalpy(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval enthalpy(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
Scalar T = fluidState.temperature(phaseIdx) ;
|
||||
Scalar p = fluidState.pressure(phaseIdx);
|
||||
typedef Opm::MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
const LhsEval& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const LhsEval& p = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
|
||||
if (phaseIdx == waterPhaseIdx) {
|
||||
return H2O::liquidEnthalpy(T, p);
|
||||
@ -431,10 +433,10 @@ public:
|
||||
}
|
||||
else if (phaseIdx == gasPhaseIdx) {
|
||||
// gas phase enthalpy depends strongly on composition
|
||||
Scalar result = 0;
|
||||
result += H2O::gasEnthalpy(T, p) * fluidState.massFraction(gasPhaseIdx, H2OIdx);
|
||||
result += NAPL::gasEnthalpy(T, p) * fluidState.massFraction(gasPhaseIdx, airIdx);
|
||||
result += Air::gasEnthalpy(T, p) * fluidState.massFraction(gasPhaseIdx, NAPLIdx);
|
||||
LhsEval result = 0;
|
||||
result += H2O::gasEnthalpy(T, p) * FsToolbox::template toLhs<LhsEval>(fluidState.massFraction(gasPhaseIdx, H2OIdx));
|
||||
result += NAPL::gasEnthalpy(T, p) * FsToolbox::template toLhs<LhsEval>(fluidState.massFraction(gasPhaseIdx, airIdx));
|
||||
result += Air::gasEnthalpy(T, p) * FsToolbox::template toLhs<LhsEval>(fluidState.massFraction(gasPhaseIdx, NAPLIdx));
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -442,22 +444,26 @@ public:
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::thermalConductivity
|
||||
template <class FluidState>
|
||||
static Scalar thermalConductivity(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval thermalConductivity(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
typedef Opm::MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
assert(0 <= phaseIdx && phaseIdx < numPhases);
|
||||
|
||||
Scalar T = fluidState.temperature(phaseIdx) ;
|
||||
Scalar p = fluidState.pressure(phaseIdx);
|
||||
|
||||
if (phaseIdx == waterPhaseIdx){ // water phase
|
||||
const LhsEval& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const LhsEval& p = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
|
||||
return H2O::liquidThermalConductivity(T, p);
|
||||
}
|
||||
else if (phaseIdx == gasPhaseIdx) { // gas phase
|
||||
Scalar lambdaDryAir = Air::gasThermalConductivity(T, p);
|
||||
return lambdaDryAir;
|
||||
const LhsEval& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const LhsEval& p = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
|
||||
return Air::gasThermalConductivity(T, p);
|
||||
}
|
||||
|
||||
assert(phaseIdx == naplPhaseIdx);
|
||||
|
@ -161,62 +161,66 @@ public:
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::density
|
||||
template <class FluidState>
|
||||
static Scalar density(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval density(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
typedef Opm::MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
if (phaseIdx == waterPhaseIdx) {
|
||||
const auto& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const auto& p = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
|
||||
// See: Ochs 2008
|
||||
// \todo: proper citation
|
||||
Scalar rholH2O = H2O::liquidDensity(fluidState.temperature(phaseIdx), fluidState.pressure(phaseIdx));
|
||||
Scalar clH2O = rholH2O/H2O::molarMass();
|
||||
const LhsEval& rholH2O = H2O::liquidDensity(T, p);
|
||||
const LhsEval& clH2O = rholH2O/H2O::molarMass();
|
||||
|
||||
const auto& xwH2O = FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(waterPhaseIdx, H2OIdx));
|
||||
const auto& xwAir = FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(waterPhaseIdx, airIdx));
|
||||
const auto& xwNapl = FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(waterPhaseIdx, NAPLIdx));
|
||||
// this assumes each dissolved molecule displaces exactly one
|
||||
// water molecule in the liquid
|
||||
return
|
||||
clH2O*(H2O::molarMass()*fluidState.moleFraction(waterPhaseIdx, H2OIdx)
|
||||
+
|
||||
Air::molarMass()*fluidState.moleFraction(waterPhaseIdx, airIdx)
|
||||
+
|
||||
NAPL::molarMass()*fluidState.moleFraction(waterPhaseIdx, NAPLIdx));
|
||||
return clH2O*(H2O::molarMass()*xwH2O + Air::molarMass()*xwAir + NAPL::molarMass()*xwNapl);
|
||||
}
|
||||
else if (phaseIdx == naplPhaseIdx) {
|
||||
// assume pure NAPL for the NAPL phase
|
||||
Scalar pressure = NAPL::liquidIsCompressible()?fluidState.pressure(phaseIdx):1e100;
|
||||
return NAPL::liquidDensity(fluidState.temperature(phaseIdx), pressure);
|
||||
const auto& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
return NAPL::liquidDensity(T, LhsEval(1e100));
|
||||
}
|
||||
|
||||
assert (phaseIdx == gasPhaseIdx);
|
||||
Scalar pH2O =
|
||||
fluidState.moleFraction(gasPhaseIdx, H2OIdx) *
|
||||
fluidState.pressure(gasPhaseIdx);
|
||||
Scalar pAir =
|
||||
fluidState.moleFraction(gasPhaseIdx, airIdx) *
|
||||
fluidState.pressure(gasPhaseIdx);
|
||||
Scalar pNAPL =
|
||||
fluidState.moleFraction(gasPhaseIdx, NAPLIdx) *
|
||||
fluidState.pressure(gasPhaseIdx);
|
||||
const auto& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const auto& p = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
|
||||
const LhsEval& pH2O = FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(gasPhaseIdx, H2OIdx))*p;
|
||||
const LhsEval& pAir = FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(gasPhaseIdx, airIdx))*p;
|
||||
const LhsEval& pNAPL = FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(gasPhaseIdx, NAPLIdx))*p;
|
||||
return
|
||||
H2O::gasDensity(fluidState.temperature(phaseIdx), pH2O) +
|
||||
Air::gasDensity(fluidState.temperature(phaseIdx), pAir) +
|
||||
NAPL::gasDensity(fluidState.temperature(phaseIdx), pNAPL);
|
||||
H2O::gasDensity(T, pH2O) +
|
||||
Air::gasDensity(T, pAir) +
|
||||
NAPL::gasDensity(T, pNAPL);
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::viscosity
|
||||
template <class FluidState>
|
||||
static Scalar viscosity(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval viscosity(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
typedef Opm::MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
const auto& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const auto& p = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
|
||||
if (phaseIdx == waterPhaseIdx) {
|
||||
// assume pure water viscosity
|
||||
return H2O::liquidViscosity(fluidState.temperature(phaseIdx),
|
||||
fluidState.pressure(phaseIdx));
|
||||
return H2O::liquidViscosity(T, p);
|
||||
}
|
||||
else if (phaseIdx == naplPhaseIdx) {
|
||||
// assume pure NAPL viscosity
|
||||
return NAPL::liquidViscosity(fluidState.temperature(phaseIdx), fluidState.pressure(phaseIdx));
|
||||
return NAPL::liquidViscosity(T, p);
|
||||
}
|
||||
|
||||
assert (phaseIdx == gasPhaseIdx);
|
||||
@ -232,11 +236,10 @@ public:
|
||||
* divisions
|
||||
* -- compare e.g. with Promo Class p. 32/33
|
||||
*/
|
||||
Scalar muResult;
|
||||
const Scalar mu[numComponents] = {
|
||||
H2O::gasViscosity(fluidState.temperature(phaseIdx), H2O::vaporPressure(fluidState.temperature(phaseIdx))),
|
||||
Air::simpleGasViscosity(fluidState.temperature(phaseIdx), fluidState.pressure(phaseIdx)),
|
||||
NAPL::gasViscosity(fluidState.temperature(phaseIdx), NAPL::vaporPressure(fluidState.temperature(phaseIdx)))
|
||||
const LhsEval mu[numComponents] = {
|
||||
H2O::gasViscosity(T, H2O::vaporPressure(T)),
|
||||
Air::simpleGasViscosity(T, p),
|
||||
NAPL::gasViscosity(T, NAPL::vaporPressure(T))
|
||||
};
|
||||
// molar masses
|
||||
const Scalar M[numComponents] = {
|
||||
@ -245,50 +248,45 @@ public:
|
||||
NAPL::molarMass()
|
||||
};
|
||||
|
||||
Scalar muAW = mu[airIdx]*fluidState.moleFraction(gasPhaseIdx, airIdx)
|
||||
+ mu[H2OIdx]*fluidState.moleFraction(gasPhaseIdx, H2OIdx)
|
||||
/ (fluidState.moleFraction(gasPhaseIdx, airIdx)
|
||||
+ fluidState.moleFraction(gasPhaseIdx, H2OIdx));
|
||||
Scalar xAW = fluidState.moleFraction(gasPhaseIdx, airIdx)
|
||||
+ fluidState.moleFraction(gasPhaseIdx, H2OIdx);
|
||||
const auto& xgAir = FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(gasPhaseIdx, airIdx));
|
||||
const auto& xgH2O = FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(gasPhaseIdx, H2OIdx));
|
||||
const auto& xgNapl = FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(gasPhaseIdx, NAPLIdx));
|
||||
|
||||
Scalar MAW = (fluidState.moleFraction(gasPhaseIdx, airIdx)*Air::molarMass()
|
||||
+ fluidState.moleFraction(gasPhaseIdx, H2OIdx)*H2O::molarMass())
|
||||
/ xAW;
|
||||
|
||||
/* TODO, please check phiCAW for the Xylene case here */
|
||||
const LhsEval& xgAW = xgAir + xgH2O;
|
||||
const LhsEval& muAW = (mu[airIdx]*xgAir + mu[H2OIdx]*xgH2O)/ xgAW;
|
||||
|
||||
const LhsEval& MAW = (xgAir*Air::molarMass() + xgH2O*H2O::molarMass())/xgAW;
|
||||
|
||||
Scalar phiCAW = 0.3; // simplification for this particular system
|
||||
/* actually like this
|
||||
* Scalar phiCAW = std::pow(1.+std::sqrt(mu[NAPLIdx]/muAW)*std::pow(MAW/M[NAPLIdx],0.25),2)
|
||||
* / std::sqrt(8.*(1.+M[NAPLIdx]/MAW));
|
||||
*/
|
||||
Scalar phiAWC = phiCAW * muAW*M[NAPLIdx]/(mu[NAPLIdx]*MAW);
|
||||
const LhsEval& phiAWC = phiCAW * muAW*M[NAPLIdx]/(mu[NAPLIdx]*MAW);
|
||||
|
||||
muResult = (xAW*muAW)/(xAW+fluidState.moleFraction(gasPhaseIdx, NAPLIdx)*phiAWC)
|
||||
+ (fluidState.moleFraction(gasPhaseIdx, NAPLIdx) * mu[NAPLIdx])
|
||||
/ (fluidState.moleFraction(gasPhaseIdx, NAPLIdx) + xAW*phiCAW);
|
||||
return muResult;
|
||||
return (xgAW*muAW)/(xgAW+xgNapl*phiAWC) + (xgNapl*mu[NAPLIdx])/(xgNapl + xgAW*phiCAW);
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::diffusionCoefficient
|
||||
template <class FluidState>
|
||||
static Scalar diffusionCoefficient(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval diffusionCoefficient(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx,
|
||||
int compIdx)
|
||||
{
|
||||
Scalar diffCont;
|
||||
typedef Opm::MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
if (phaseIdx==gasPhaseIdx) {
|
||||
Scalar diffAC = Opm::BinaryCoeff::Air_Xylene::gasDiffCoeff(fluidState.temperature(phaseIdx), fluidState.pressure(phaseIdx));
|
||||
Scalar diffWC = Opm::BinaryCoeff::H2O_Xylene::gasDiffCoeff(fluidState.temperature(phaseIdx), fluidState.pressure(phaseIdx));
|
||||
Scalar diffAW = Opm::BinaryCoeff::H2O_Air::gasDiffCoeff(fluidState.temperature(phaseIdx), fluidState.pressure(phaseIdx));
|
||||
const auto& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const auto& p = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
|
||||
const Scalar xga = fluidState.moleFraction(gasPhaseIdx, airIdx);
|
||||
const Scalar xgw = fluidState.moleFraction(gasPhaseIdx, H2OIdx);
|
||||
const Scalar xgc = fluidState.moleFraction(gasPhaseIdx, NAPLIdx);
|
||||
const LhsEval& diffAC = Opm::BinaryCoeff::Air_Xylene::gasDiffCoeff(T, p);
|
||||
const LhsEval& diffWC = Opm::BinaryCoeff::H2O_Xylene::gasDiffCoeff(T, p);
|
||||
const LhsEval& diffAW = Opm::BinaryCoeff::H2O_Air::gasDiffCoeff(T, p);
|
||||
|
||||
const LhsEval& xga = FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(gasPhaseIdx, airIdx));
|
||||
const LhsEval& xgw = FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(gasPhaseIdx, H2OIdx));
|
||||
const LhsEval& xgc = FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(gasPhaseIdx, NAPLIdx));
|
||||
|
||||
if (compIdx==NAPLIdx) return (1.- xgw)/(xga/diffAW + xgc/diffWC);
|
||||
else if (compIdx==H2OIdx) return (1.- xgc)/(xgw/diffWC + xga/diffAC);
|
||||
@ -300,17 +298,15 @@ public:
|
||||
Scalar diffWCl = 1.e-9; // BinaryCoeff::H2O_Xylene::liquidDiffCoeff(temperature, pressure);
|
||||
Scalar diffAWl = 1.e-9; // BinaryCoeff::H2O_Air::liquidDiffCoeff(temperature, pressure);
|
||||
|
||||
Scalar xwa = fluidState.moleFraction(waterPhaseIdx, airIdx);
|
||||
Scalar xww = fluidState.moleFraction(waterPhaseIdx, H2OIdx);
|
||||
Scalar xwc = fluidState.moleFraction(waterPhaseIdx, NAPLIdx);
|
||||
const LhsEval& xwa = FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(waterPhaseIdx, airIdx));
|
||||
const LhsEval& xww = FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(waterPhaseIdx, H2OIdx));
|
||||
const LhsEval& xwc = FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(waterPhaseIdx, NAPLIdx));
|
||||
|
||||
switch (compIdx) {
|
||||
case NAPLIdx:
|
||||
diffCont = (1.- xww)/(xwa/diffAWl + xwc/diffWCl);
|
||||
return diffCont;
|
||||
return (1.- xww)/(xwa/diffAWl + xwc/diffWCl);
|
||||
case airIdx:
|
||||
diffCont = (1.- xwc)/(xww/diffWCl + xwa/diffACl);
|
||||
return diffCont;
|
||||
return (1.- xwc)/(xww/diffWCl + xwa/diffACl);
|
||||
case H2OIdx:
|
||||
OPM_THROW(std::logic_error,
|
||||
"Diffusivity of water in the water phase "
|
||||
@ -326,17 +322,19 @@ public:
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::fugacityCoefficient
|
||||
template <class FluidState>
|
||||
static Scalar fugacityCoefficient(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval fugacityCoefficient(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx,
|
||||
int compIdx)
|
||||
{
|
||||
typedef Opm::MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
assert(0 <= phaseIdx && phaseIdx < numPhases);
|
||||
assert(0 <= compIdx && compIdx < numComponents);
|
||||
|
||||
Scalar T = fluidState.temperature(phaseIdx);
|
||||
Scalar p = fluidState.pressure(phaseIdx);
|
||||
const auto& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const auto& p = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
|
||||
if (phaseIdx == waterPhaseIdx) {
|
||||
if (compIdx == H2OIdx)
|
||||
@ -353,7 +351,7 @@ public:
|
||||
// other components, i.e. the fugacity cofficient is much
|
||||
// smaller.
|
||||
if (phaseIdx == naplPhaseIdx) {
|
||||
Scalar phiNapl = NAPL::vaporPressure(T)/p;
|
||||
const LhsEval& phiNapl = NAPL::vaporPressure(T)/p;
|
||||
if (compIdx == NAPLIdx)
|
||||
return phiNapl;
|
||||
else if (compIdx == airIdx)
|
||||
@ -369,28 +367,31 @@ public:
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::enthalpy
|
||||
template <class FluidState>
|
||||
static Scalar enthalpy(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval enthalpy(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
typedef Opm::MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
const auto& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const auto& p = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
|
||||
if (phaseIdx == waterPhaseIdx) {
|
||||
return H2O::liquidEnthalpy(fluidState.temperature(phaseIdx), fluidState.pressure(phaseIdx));
|
||||
return H2O::liquidEnthalpy(T, p);
|
||||
}
|
||||
else if (phaseIdx == naplPhaseIdx) {
|
||||
return NAPL::liquidEnthalpy(fluidState.temperature(phaseIdx), fluidState.pressure(phaseIdx));
|
||||
return NAPL::liquidEnthalpy(T, p);
|
||||
}
|
||||
else if (phaseIdx == gasPhaseIdx) { // gas phase enthalpy depends strongly on composition
|
||||
Scalar hgc = NAPL::gasEnthalpy(fluidState.temperature(phaseIdx),
|
||||
fluidState.pressure(phaseIdx));
|
||||
Scalar hgw = H2O::gasEnthalpy(fluidState.temperature(phaseIdx),
|
||||
fluidState.pressure(phaseIdx));
|
||||
Scalar hga = Air::gasEnthalpy(fluidState.temperature(phaseIdx), fluidState.pressure(phaseIdx)); // pressure is only a dummy here (not dependent on pressure, just temperature)
|
||||
const LhsEval& hgc = NAPL::gasEnthalpy(T, p);
|
||||
const LhsEval& hgw = H2O::gasEnthalpy(T, p);
|
||||
const LhsEval& hga = Air::gasEnthalpy(T, p);
|
||||
|
||||
Scalar result = 0;
|
||||
result += hgw * fluidState.massFraction(gasPhaseIdx, H2OIdx);
|
||||
result += hga * fluidState.massFraction(gasPhaseIdx, airIdx);
|
||||
result += hgc * fluidState.massFraction(gasPhaseIdx, NAPLIdx);
|
||||
LhsEval result = 0;
|
||||
result += hgw * FsToolbox::template toLhs<LhsEval>(fluidState.massFraction(gasPhaseIdx, H2OIdx));
|
||||
result += hga * FsToolbox::template toLhs<LhsEval>(fluidState.massFraction(gasPhaseIdx, airIdx));
|
||||
result += hgc * FsToolbox::template toLhs<LhsEval>(fluidState.massFraction(gasPhaseIdx, NAPLIdx));
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -398,28 +399,32 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
static Scalar waterPhaseDensity_(Scalar T, Scalar pw, Scalar xww, Scalar xwa, Scalar xwc)
|
||||
template <class LhsEval>
|
||||
static LhsEval waterPhaseDensity_(const LhsEval& T,
|
||||
const LhsEval& pw,
|
||||
const LhsEval& xww,
|
||||
const LhsEval& xwa,
|
||||
const LhsEval& xwc)
|
||||
{
|
||||
Scalar rholH2O = H2O::liquidDensity(T, pw);
|
||||
Scalar clH2O = rholH2O/H2O::molarMass();
|
||||
const LhsEval& rholH2O = H2O::liquidDensity(T, pw);
|
||||
const LhsEval& clH2O = rholH2O/H2O::molarMass();
|
||||
|
||||
// this assumes each dissolved molecule displaces exactly one
|
||||
// water molecule in the liquid
|
||||
return
|
||||
clH2O*(xww*H2O::molarMass() + xwa*Air::molarMass() + xwc*NAPL::molarMass());
|
||||
return clH2O*(xww*H2O::molarMass() + xwa*Air::molarMass() + xwc*NAPL::molarMass());
|
||||
}
|
||||
|
||||
static Scalar gasPhaseDensity_(Scalar T, Scalar pg, Scalar xgw, Scalar xga, Scalar xgc)
|
||||
{
|
||||
return H2O::gasDensity(T, pg*xgw) + Air::gasDensity(T, pg*xga) + NAPL::gasDensity(T, pg*xgc);
|
||||
}
|
||||
|
||||
static Scalar NAPLPhaseDensity_(Scalar T, Scalar pn)
|
||||
{
|
||||
return
|
||||
NAPL::liquidDensity(T, pn);
|
||||
}
|
||||
template <class LhsEval>
|
||||
static LhsEval gasPhaseDensity_(const LhsEval& T,
|
||||
const LhsEval& pg,
|
||||
const LhsEval& xgw,
|
||||
const LhsEval& xga,
|
||||
const LhsEval& xgc)
|
||||
{ return H2O::gasDensity(T, pg*xgw) + Air::gasDensity(T, pg*xga) + NAPL::gasDensity(T, pg*xgc); }
|
||||
|
||||
template <class LhsEval>
|
||||
static LhsEval NAPLPhaseDensity_(const LhsEval& T, const LhsEval& pn)
|
||||
{ return NAPL::liquidDensity(T, pn); }
|
||||
};
|
||||
} // namespace FluidSystems
|
||||
} // namespace Opm
|
||||
|
@ -256,26 +256,26 @@ public:
|
||||
/*!
|
||||
* \copydoc BaseFluidSystem::density
|
||||
*
|
||||
* If useComplexRelations == true, we apply
|
||||
* Formula (2.6) from S.O.Ochs:
|
||||
* "Development of a multiphase multicomponent
|
||||
* model for PEMFC - Technical report: IRTG-NUPUS",
|
||||
* If useComplexRelations == true, we apply Formula (2.6) from S.O.Ochs: "Development
|
||||
* of a multiphase multicomponent model for PEMFC - Technical report: IRTG-NUPUS",
|
||||
* University of Stuttgart, 2008
|
||||
*/
|
||||
template <class FluidState>
|
||||
static Scalar density(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval density(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
assert(0 <= phaseIdx && phaseIdx < numPhases);
|
||||
|
||||
Scalar T = fluidState.temperature(phaseIdx);
|
||||
Scalar p = fluidState.pressure(phaseIdx);
|
||||
typedef Opm::MathToolbox<LhsEval> LhsToolbox;
|
||||
typedef Opm::MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
Scalar sumMoleFrac = 0;
|
||||
const auto& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const auto& p = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
|
||||
LhsEval sumMoleFrac = 0;
|
||||
for (int compIdx = 0; compIdx < numComponents; ++compIdx)
|
||||
sumMoleFrac += fluidState.moleFraction(phaseIdx, compIdx);
|
||||
Valgrind::CheckDefined(sumMoleFrac);
|
||||
sumMoleFrac += FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(phaseIdx, compIdx));
|
||||
|
||||
// liquid phase
|
||||
if (phaseIdx == liquidPhaseIdx) {
|
||||
@ -285,94 +285,101 @@ public:
|
||||
else
|
||||
{
|
||||
// See: Ochs 2008
|
||||
Scalar rholH2O = H2O::liquidDensity(T, p);
|
||||
Scalar clH2O = rholH2O/H2O::molarMass();
|
||||
const auto& rholH2O = H2O::liquidDensity(T, p);
|
||||
const auto& clH2O = rholH2O/H2O::molarMass();
|
||||
|
||||
const auto& xlH2O = FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(liquidPhaseIdx, H2OIdx));
|
||||
const auto& xlN2 = FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(liquidPhaseIdx, N2Idx));
|
||||
|
||||
// this assumes each nitrogen molecule displaces exactly one
|
||||
// water molecule in the liquid
|
||||
return
|
||||
clH2O
|
||||
* (H2O::molarMass()*fluidState.moleFraction(liquidPhaseIdx, H2OIdx)
|
||||
+
|
||||
N2::molarMass()*fluidState.moleFraction(liquidPhaseIdx, N2Idx))
|
||||
/ sumMoleFrac;
|
||||
return clH2O*(H2O::molarMass()*xlH2O + N2::molarMass()*xlN2)/sumMoleFrac;
|
||||
}
|
||||
}
|
||||
|
||||
// gas phase
|
||||
assert(phaseIdx == gasPhaseIdx);
|
||||
|
||||
if (!useComplexRelations)
|
||||
// for the gas phase assume an ideal gas
|
||||
return
|
||||
IdealGas::molarDensity(T, p)
|
||||
* fluidState.averageMolarMass(gasPhaseIdx)
|
||||
/ std::max(1e-5, sumMoleFrac);
|
||||
* FsToolbox::template toLhs<LhsEval>(fluidState.averageMolarMass(gasPhaseIdx))
|
||||
/ LhsToolbox::max(1e-5, sumMoleFrac);
|
||||
|
||||
// assume ideal mixture: steam and nitrogen don't "see" each
|
||||
// other
|
||||
Scalar rho_gH2O = H2O::gasDensity(T, p*fluidState.moleFraction(gasPhaseIdx, H2OIdx));
|
||||
Scalar rho_gN2 = N2::gasDensity(T, p*fluidState.moleFraction(gasPhaseIdx, N2Idx));
|
||||
return (rho_gH2O + rho_gN2) / std::max(1e-5, sumMoleFrac);
|
||||
const auto& xgH2O = FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(gasPhaseIdx, H2OIdx));
|
||||
const auto& xgN2 = FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(gasPhaseIdx, N2Idx));
|
||||
const auto& rho_gH2O = H2O::gasDensity(T, p*xgH2O);
|
||||
const auto& rho_gN2 = N2::gasDensity(T, p*xgN2);
|
||||
return (rho_gH2O + rho_gN2)/LhsToolbox::max(1e-5, sumMoleFrac);
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::viscosity
|
||||
template <class FluidState>
|
||||
static Scalar viscosity(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval viscosity(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
assert(0 <= phaseIdx && phaseIdx < numPhases);
|
||||
|
||||
Scalar T = fluidState.temperature(phaseIdx);
|
||||
Scalar p = fluidState.pressure(phaseIdx);
|
||||
typedef Opm::MathToolbox<LhsEval> LhsToolbox;
|
||||
typedef Opm::MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
const auto& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const auto& p = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
|
||||
// liquid phase
|
||||
if (phaseIdx == liquidPhaseIdx) {
|
||||
if (phaseIdx == liquidPhaseIdx)
|
||||
// assume pure water for the liquid phase
|
||||
return H2O::liquidViscosity(T, p);
|
||||
}
|
||||
|
||||
// gas phase
|
||||
assert(phaseIdx == gasPhaseIdx);
|
||||
|
||||
if (!useComplexRelations)
|
||||
{
|
||||
// assume pure nitrogen for the gas phase
|
||||
return N2::gasViscosity(T, p);
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
/* Wilke method. See:
|
||||
*
|
||||
* See: R. Reid, et al.: The Properties of Gases and Liquids,
|
||||
* 4th edition, McGraw-Hill, 1987, 407-410
|
||||
* 5th edition, McGraw-Hill, 20001, p. 9.21/22
|
||||
*/
|
||||
Scalar muResult = 0;
|
||||
const Scalar mu[numComponents] = {
|
||||
LhsEval muResult = 0;
|
||||
const LhsEval mu[numComponents] = {
|
||||
H2O::gasViscosity(T, H2O::vaporPressure(T)),
|
||||
N2::gasViscosity(T, p)
|
||||
};
|
||||
|
||||
Scalar sumx = 0.0;
|
||||
LhsEval sumx = 0.0;
|
||||
for (int compIdx = 0; compIdx < numComponents; ++compIdx)
|
||||
sumx += fluidState.moleFraction(phaseIdx, compIdx);
|
||||
sumx = std::max(1e-10, sumx);
|
||||
sumx += FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(phaseIdx, compIdx));
|
||||
sumx = LhsToolbox::max(1e-10, sumx);
|
||||
|
||||
for (int i = 0; i < numComponents; ++i) {
|
||||
Scalar divisor = 0;
|
||||
LhsEval divisor = 0;
|
||||
for (int j = 0; j < numComponents; ++j) {
|
||||
Scalar phiIJ = 1 + std::sqrt(mu[i]/mu[j]) * std::pow(molarMass(j)/molarMass(i), 1/4.0);
|
||||
LhsEval phiIJ = 1 + LhsToolbox::sqrt(mu[i]/mu[j]) * std::pow(molarMass(j)/molarMass(i), 1/4.0);
|
||||
phiIJ *= phiIJ;
|
||||
phiIJ /= std::sqrt(8*(1 + molarMass(i)/molarMass(j)));
|
||||
divisor += fluidState.moleFraction(phaseIdx, j)/sumx * phiIJ;
|
||||
divisor +=
|
||||
FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(phaseIdx, j))
|
||||
/sumx*phiIJ;
|
||||
}
|
||||
muResult += fluidState.moleFraction(phaseIdx, i)/sumx * mu[i] / divisor;
|
||||
muResult +=
|
||||
FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(phaseIdx, i))
|
||||
/sumx*mu[i]/divisor;
|
||||
}
|
||||
return muResult;
|
||||
}
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::fugacityCoefficient
|
||||
template <class FluidState>
|
||||
static Scalar fugacityCoefficient(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval fugacityCoefficient(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx,
|
||||
int compIdx)
|
||||
@ -380,8 +387,10 @@ public:
|
||||
assert(0 <= phaseIdx && phaseIdx < numPhases);
|
||||
assert(0 <= compIdx && compIdx < numComponents);
|
||||
|
||||
Scalar T = fluidState.temperature(phaseIdx);
|
||||
Scalar p = fluidState.pressure(phaseIdx);
|
||||
typedef Opm::MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
const auto& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const auto& p = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
|
||||
// liquid phase
|
||||
if (phaseIdx == liquidPhaseIdx) {
|
||||
@ -390,21 +399,25 @@ public:
|
||||
return Opm::BinaryCoeff::H2O_N2::henry(T)/p;
|
||||
}
|
||||
|
||||
assert(phaseIdx == gasPhaseIdx);
|
||||
|
||||
// for the gas phase, assume an ideal gas when it comes to
|
||||
// fugacity (-> fugacity == partial pressure)
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::diffusionCoefficient
|
||||
template <class FluidState>
|
||||
static Scalar diffusionCoefficient(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval diffusionCoefficient(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx,
|
||||
int compIdx)
|
||||
|
||||
{
|
||||
Scalar T = fluidState.temperature(phaseIdx);
|
||||
Scalar p = fluidState.pressure(phaseIdx);
|
||||
typedef Opm::MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
const auto& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const auto& p = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
|
||||
// liquid phase
|
||||
if (phaseIdx == liquidPhaseIdx)
|
||||
@ -416,13 +429,15 @@ public:
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::enthalpy
|
||||
template <class FluidState>
|
||||
static Scalar enthalpy(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval enthalpy(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
Scalar T = fluidState.temperature(phaseIdx);
|
||||
Scalar p = fluidState.pressure(phaseIdx);
|
||||
typedef Opm::MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
const auto& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const auto& p = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
Valgrind::CheckDefined(T);
|
||||
Valgrind::CheckDefined(p);
|
||||
|
||||
@ -431,84 +446,86 @@ public:
|
||||
// TODO: correct way to deal with the solutes???
|
||||
return H2O::liquidEnthalpy(T, p);
|
||||
}
|
||||
|
||||
// gas phase
|
||||
else {
|
||||
assert(phaseIdx == gasPhaseIdx);
|
||||
|
||||
// assume ideal mixture: Molecules of one component don't
|
||||
// "see" the molecules of the other component, which means
|
||||
// that the total specific enthalpy is the sum of the
|
||||
// "partial specific enthalpies" of the components.
|
||||
Scalar hH2O =
|
||||
fluidState.massFraction(gasPhaseIdx, H2OIdx)
|
||||
* H2O::gasEnthalpy(T, p);
|
||||
Scalar hN2 =
|
||||
fluidState.massFraction(gasPhaseIdx, N2Idx)
|
||||
* N2::gasEnthalpy(T, p);
|
||||
const auto& XgH2O = FsToolbox::template toLhs<LhsEval>(fluidState.massFraction(gasPhaseIdx, H2OIdx));
|
||||
const auto& XgN2 = FsToolbox::template toLhs<LhsEval>(fluidState.massFraction(gasPhaseIdx, N2Idx));
|
||||
|
||||
LhsEval hH2O = XgH2O*H2O::gasEnthalpy(T, p);
|
||||
LhsEval hN2 = XgN2*N2::gasEnthalpy(T, p);
|
||||
return hH2O + hN2;
|
||||
}
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::thermalConductivity
|
||||
template <class FluidState>
|
||||
static Scalar thermalConductivity(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval thermalConductivity(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
assert(0 <= phaseIdx && phaseIdx < numPhases);
|
||||
|
||||
Scalar temperature = fluidState.temperature(phaseIdx) ;
|
||||
Scalar pressure = fluidState.pressure(phaseIdx);
|
||||
typedef Opm::MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
if (phaseIdx == liquidPhaseIdx) { // liquid phase
|
||||
return H2O::liquidThermalConductivity(temperature, pressure);
|
||||
}
|
||||
else { // gas phase
|
||||
Scalar lambdaDryN2 = N2::gasThermalConductivity(temperature, pressure);
|
||||
const auto& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const auto& p = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
if (phaseIdx == liquidPhaseIdx) // liquid phase
|
||||
return H2O::liquidThermalConductivity(T, p);
|
||||
|
||||
// gas phase
|
||||
assert(phaseIdx == gasPhaseIdx);
|
||||
|
||||
if (useComplexRelations){
|
||||
Scalar xN2 = fluidState.moleFraction(phaseIdx, N2Idx);
|
||||
Scalar xH2O = fluidState.moleFraction(phaseIdx, H2OIdx);
|
||||
Scalar lambdaN2 = xN2 * lambdaDryN2;
|
||||
// return the sum of the partial conductivity of Nitrogen and Steam
|
||||
const auto& xH2O = FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(phaseIdx, H2OIdx));
|
||||
const auto& xN2 = FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(phaseIdx, N2Idx));
|
||||
|
||||
// Assuming Raoult's, Daltons law and ideal gas
|
||||
// in order to obtain the partial density of water in the air phase
|
||||
Scalar partialPressure = pressure * xH2O;
|
||||
// Assuming Raoult's, Daltons law and ideal gas in order to obtain the
|
||||
// partial pressures in the gas phase
|
||||
const auto& lambdaN2 = N2::gasThermalConductivity(T, p*xN2);
|
||||
const auto& lambdaH2O = H2O::gasThermalConductivity(T, p*xH2O);
|
||||
|
||||
Scalar lambdaH2O =
|
||||
xH2O
|
||||
* H2O::gasThermalConductivity(temperature, partialPressure);
|
||||
return lambdaN2 + lambdaH2O;
|
||||
}
|
||||
else
|
||||
return lambdaDryN2; // conductivity of Nitrogen [W / (m K ) ]
|
||||
}
|
||||
// return the conductivity of dry Nitrogen
|
||||
return N2::gasThermalConductivity(T, p);
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::heatCapacity
|
||||
template <class FluidState>
|
||||
static Scalar heatCapacity(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval heatCapacity(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
if (phaseIdx == liquidPhaseIdx) {
|
||||
return H2O::liquidHeatCapacity(fluidState.temperature(phaseIdx),
|
||||
fluidState.pressure(phaseIdx));
|
||||
}
|
||||
typedef Opm::MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
const auto& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const auto& p = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
const auto& xAlphaH2O = FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(phaseIdx, H2OIdx));
|
||||
const auto& xAlphaN2 = FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(phaseIdx, N2Idx));
|
||||
const auto& XAlphaH2O = FsToolbox::template toLhs<LhsEval>(fluidState.massFraction(phaseIdx, H2OIdx));
|
||||
const auto& XAlphaN2 = FsToolbox::template toLhs<LhsEval>(fluidState.massFraction(phaseIdx, N2Idx));
|
||||
|
||||
if (phaseIdx == liquidPhaseIdx)
|
||||
return H2O::liquidHeatCapacity(T, p);
|
||||
|
||||
assert(phaseIdx == gasPhaseIdx);
|
||||
|
||||
// for the gas phase, assume ideal mixture, i.e. molecules of
|
||||
// one component don't "see" the molecules of the other
|
||||
// component
|
||||
|
||||
Scalar c_pN2;
|
||||
Scalar c_pH2O;
|
||||
LhsEval c_pN2;
|
||||
LhsEval c_pH2O;
|
||||
// let the water and nitrogen components do things their own way
|
||||
if (useComplexRelations) {
|
||||
c_pN2 = N2::gasHeatCapacity(fluidState.temperature(phaseIdx),
|
||||
fluidState.pressure(phaseIdx)
|
||||
* fluidState.moleFraction(phaseIdx, N2Idx));
|
||||
|
||||
c_pH2O = H2O::gasHeatCapacity(fluidState.temperature(phaseIdx),
|
||||
fluidState.pressure(phaseIdx)
|
||||
* fluidState.moleFraction(phaseIdx, H2OIdx));
|
||||
c_pN2 = N2::gasHeatCapacity(T, p*xAlphaN2);
|
||||
c_pH2O = H2O::gasHeatCapacity(T, p*xAlphaH2O);
|
||||
}
|
||||
else {
|
||||
// assume an ideal gas for both components. See:
|
||||
@ -524,10 +541,9 @@ public:
|
||||
c_pH2O = c_pH2Omolar/molarMass(H2OIdx);
|
||||
}
|
||||
|
||||
// mangle both components together
|
||||
return
|
||||
c_pH2O*fluidState.massFraction(gasPhaseIdx, H2OIdx)
|
||||
+ c_pN2*fluidState.massFraction(gasPhaseIdx, N2Idx);
|
||||
// mingle both components together. this assumes that there is no "cross
|
||||
// interaction" between both flavors of molecules.
|
||||
return XAlphaH2O*c_pH2O + XAlphaN2*c_pN2;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -245,19 +245,21 @@ public:
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::density
|
||||
template <class FluidState>
|
||||
static Scalar density(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval density(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
typedef Opm::MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
assert(0 <= phaseIdx && phaseIdx < numPhases);
|
||||
|
||||
Scalar T = fluidState.temperature(phaseIdx);
|
||||
Scalar p = fluidState.pressure(phaseIdx);
|
||||
const auto& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const auto& p = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
|
||||
Scalar sumMoleFrac = 0;
|
||||
LhsEval sumMoleFrac = 0;
|
||||
for (int compIdx = 0; compIdx < numComponents; ++compIdx)
|
||||
sumMoleFrac += fluidState.moleFraction(phaseIdx, compIdx);
|
||||
sumMoleFrac += FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(phaseIdx, compIdx));
|
||||
|
||||
assert(phaseIdx == liquidPhaseIdx);
|
||||
|
||||
@ -267,47 +269,49 @@ public:
|
||||
else
|
||||
{
|
||||
// See: Ochs 2008
|
||||
Scalar rholH2O = H2O::liquidDensity(T, p);
|
||||
Scalar clH2O = rholH2O/H2O::molarMass();
|
||||
const LhsEval& rholH2O = H2O::liquidDensity(T, p);
|
||||
const LhsEval& clH2O = rholH2O/H2O::molarMass();
|
||||
|
||||
const auto& xlH2O = FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(liquidPhaseIdx, H2OIdx));
|
||||
const auto& xlN2 = FsToolbox::template toLhs<LhsEval>(fluidState.moleFraction(liquidPhaseIdx, N2Idx));
|
||||
|
||||
// this assumes each nitrogen molecule displaces exactly one
|
||||
// water molecule in the liquid
|
||||
return
|
||||
clH2O
|
||||
* (H2O::molarMass()*fluidState.moleFraction(liquidPhaseIdx, H2OIdx)
|
||||
+
|
||||
N2::molarMass()*fluidState.moleFraction(liquidPhaseIdx, N2Idx))
|
||||
/ sumMoleFrac;
|
||||
return clH2O*(H2O::molarMass()*xlH2O + N2::molarMass()*xlN2)/sumMoleFrac;
|
||||
}
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::viscosity
|
||||
template <class FluidState>
|
||||
static Scalar viscosity(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval viscosity(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
typedef Opm::MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
assert(phaseIdx == liquidPhaseIdx);
|
||||
|
||||
Scalar T = fluidState.temperature(phaseIdx);
|
||||
Scalar p = fluidState.pressure(phaseIdx);
|
||||
const auto& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const auto& p = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
|
||||
// assume pure water for the liquid phase
|
||||
return H2O::liquidViscosity(T, p);
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::fugacityCoefficient
|
||||
template <class FluidState>
|
||||
static Scalar fugacityCoefficient(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval fugacityCoefficient(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx,
|
||||
int compIdx)
|
||||
{
|
||||
typedef Opm::MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
assert(phaseIdx == liquidPhaseIdx);
|
||||
assert(0 <= compIdx && compIdx < numComponents);
|
||||
|
||||
Scalar T = fluidState.temperature(phaseIdx);
|
||||
Scalar p = fluidState.pressure(phaseIdx);
|
||||
const auto& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const auto& p = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
|
||||
if (compIdx == H2OIdx)
|
||||
return H2O::vaporPressure(T)/p;
|
||||
@ -315,31 +319,35 @@ public:
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::diffusionCoefficient
|
||||
template <class FluidState>
|
||||
static Scalar diffusionCoefficient(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval diffusionCoefficient(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx,
|
||||
int compIdx)
|
||||
|
||||
{
|
||||
typedef Opm::MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
assert(phaseIdx == liquidPhaseIdx);
|
||||
|
||||
Scalar T = fluidState.temperature(phaseIdx);
|
||||
Scalar p = fluidState.pressure(phaseIdx);
|
||||
const auto& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const auto& p = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
|
||||
return BinaryCoeff::H2O_N2::liquidDiffCoeff(T, p);
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::enthalpy
|
||||
template <class FluidState>
|
||||
static Scalar enthalpy(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval enthalpy(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
typedef Opm::MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
assert (phaseIdx == liquidPhaseIdx);
|
||||
|
||||
Scalar T = fluidState.temperature(phaseIdx);
|
||||
Scalar p = fluidState.pressure(phaseIdx);
|
||||
const auto& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const auto& p = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
Valgrind::CheckDefined(T);
|
||||
Valgrind::CheckDefined(p);
|
||||
|
||||
@ -348,32 +356,38 @@ public:
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::thermalConductivity
|
||||
template <class FluidState>
|
||||
static Scalar thermalConductivity(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval thermalConductivity(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
const int phaseIdx)
|
||||
{
|
||||
typedef Opm::MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
assert(phaseIdx == liquidPhaseIdx);
|
||||
|
||||
if(useComplexRelations){
|
||||
Scalar temperature = fluidState.temperature(phaseIdx) ;
|
||||
Scalar pressure = fluidState.pressure(phaseIdx);
|
||||
return H2O::liquidThermalConductivity(temperature, pressure);
|
||||
const auto& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const auto& p = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
return H2O::liquidThermalConductivity(T, p);
|
||||
}
|
||||
else
|
||||
return 0.578078; // conductivity of water[W / (m K ) ] IAPWS evaluated at p=.1 MPa, T=8C
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::heatCapacity
|
||||
template <class FluidState>
|
||||
static Scalar heatCapacity(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval heatCapacity(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
typedef Opm::MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
assert (phaseIdx == liquidPhaseIdx);
|
||||
|
||||
return H2O::liquidHeatCapacity(fluidState.temperature(phaseIdx),
|
||||
fluidState.pressure(phaseIdx));
|
||||
const auto& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const auto& p = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
|
||||
return H2O::liquidHeatCapacity(T, p);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -74,35 +74,43 @@ public:
|
||||
{ return Component::triplePressure(); }
|
||||
|
||||
//! \copydoc GasPhase::vaporPressure
|
||||
static Scalar vaporPressure(Scalar temperature)
|
||||
template <class Evaluation>
|
||||
static Evaluation vaporPressure(const Evaluation& temperature)
|
||||
{ return Component::vaporPressure(temperature); }
|
||||
|
||||
//! \copydoc GasPhase::density
|
||||
static Scalar density(Scalar temperature, Scalar pressure)
|
||||
template <class Evaluation>
|
||||
static Evaluation density(const Evaluation& temperature, const Evaluation& pressure)
|
||||
{ return Component::liquidDensity(temperature, pressure); }
|
||||
|
||||
//! \copydoc GasPhase::pressure
|
||||
static Scalar pressure(Scalar temperature, Scalar density)
|
||||
template <class Evaluation>
|
||||
static Evaluation pressure(const Evaluation& temperature, const Evaluation& density)
|
||||
{ return Component::liquidPressure(temperature, density); }
|
||||
|
||||
//! \copydoc GasPhase::enthalpy
|
||||
static const Scalar enthalpy(Scalar temperature, Scalar pressure)
|
||||
template <class Evaluation>
|
||||
static const Evaluation enthalpy(const Evaluation& temperature, const Evaluation& pressure)
|
||||
{ return Component::liquidEnthalpy(temperature, pressure); }
|
||||
|
||||
//! \copydoc GasPhase::internalEnergy
|
||||
static const Scalar internalEnergy(Scalar temperature, Scalar pressure)
|
||||
template <class Evaluation>
|
||||
static const Evaluation internalEnergy(const Evaluation& temperature, const Evaluation& pressure)
|
||||
{ return Component::liquidInternalEnergy(temperature, pressure); }
|
||||
|
||||
//! \copydoc GasPhase::viscosity
|
||||
static Scalar viscosity(Scalar temperature, Scalar pressure)
|
||||
template <class Evaluation>
|
||||
static Evaluation viscosity(const Evaluation& temperature, const Evaluation& pressure)
|
||||
{ return Component::liquidViscosity(temperature, pressure); }
|
||||
|
||||
//! \copydoc GasPhase::thermalConductivity
|
||||
static Scalar thermalConductivity(Scalar temperature, Scalar pressure)
|
||||
template <class Evaluation>
|
||||
static Evaluation thermalConductivity(const Evaluation& temperature, const Evaluation& pressure)
|
||||
{ return Component::liquidThermalConductivity(temperature, pressure); }
|
||||
|
||||
//! \copydoc GasPhase::heatCapacity
|
||||
static Scalar heatCapacity(Scalar temperature, Scalar pressure)
|
||||
template <class Evaluation>
|
||||
static Evaluation heatCapacity(const Evaluation& temperature, const Evaluation& pressure)
|
||||
{ return Component::liquidHeatCapacity(temperature, pressure); }
|
||||
};
|
||||
} // namespace Opm
|
||||
|
@ -126,7 +126,7 @@ public:
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::molarMass
|
||||
static const Scalar molarMass(int compIdx)
|
||||
static Scalar molarMass(int compIdx)
|
||||
{
|
||||
//assert(0 <= compIdx && compIdx < numComponents);
|
||||
|
||||
@ -138,7 +138,7 @@ public:
|
||||
*
|
||||
* \param compIdx The index of the component to consider
|
||||
*/
|
||||
static const Scalar criticalTemperature(int compIdx)
|
||||
static Scalar criticalTemperature(int compIdx)
|
||||
{
|
||||
//assert(0 <= compIdx && compIdx < numComponents);
|
||||
|
||||
@ -150,7 +150,7 @@ public:
|
||||
*
|
||||
* \param compIdx The index of the component to consider
|
||||
*/
|
||||
static const Scalar criticalPressure(int compIdx)
|
||||
static Scalar criticalPressure(int compIdx)
|
||||
{
|
||||
//assert(0 <= compIdx && compIdx < numComponents);
|
||||
|
||||
@ -162,7 +162,7 @@ public:
|
||||
*
|
||||
* \param compIdx The index of the component to consider
|
||||
*/
|
||||
static const Scalar acentricFactor(int compIdx)
|
||||
static Scalar acentricFactor(int compIdx)
|
||||
{
|
||||
//assert(0 <= compIdx && compIdx < numComponents);
|
||||
|
||||
@ -178,34 +178,38 @@ public:
|
||||
{ }
|
||||
|
||||
//! \copydoc BaseFluidSystem::density
|
||||
template <class FluidState>
|
||||
static Scalar density(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval density(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
typedef Opm::MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
assert(0 <= phaseIdx && phaseIdx < numPhases);
|
||||
|
||||
Scalar temperature = fluidState.temperature(phaseIdx);
|
||||
Scalar pressure = fluidState.pressure(phaseIdx);
|
||||
return Fluid::density(temperature, pressure);
|
||||
const auto& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const auto& p = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
return Fluid::density(T, p);
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::viscosity
|
||||
template <class FluidState>
|
||||
static Scalar viscosity(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval viscosity(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
typedef Opm::MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
assert(0 <= phaseIdx && phaseIdx < numPhases);
|
||||
|
||||
Scalar temperature = fluidState.temperature(phaseIdx);
|
||||
Scalar pressure = fluidState.pressure(phaseIdx);
|
||||
return Fluid::viscosity(temperature, pressure);
|
||||
const auto& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const auto& p = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
return Fluid::viscosity(T, p);
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::fugacityCoefficient
|
||||
template <class FluidState>
|
||||
static Scalar fugacityCoefficient(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval fugacityCoefficient(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx,
|
||||
int compIdx)
|
||||
@ -223,42 +227,48 @@ public:
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::enthalpy
|
||||
template <class FluidState>
|
||||
static Scalar enthalpy(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval enthalpy(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
typedef Opm::MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
assert(0 <= phaseIdx && phaseIdx < numPhases);
|
||||
|
||||
Scalar temperature = fluidState.temperature(phaseIdx);
|
||||
Scalar pressure = fluidState.pressure(phaseIdx);
|
||||
return Fluid::enthalpy(temperature, pressure);
|
||||
const auto& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const auto& p = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
return Fluid::enthalpy(T, p);
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::thermalConductivity
|
||||
template <class FluidState>
|
||||
static Scalar thermalConductivity(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval thermalConductivity(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
typedef Opm::MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
assert(0 <= phaseIdx && phaseIdx < numPhases);
|
||||
|
||||
Scalar temperature = fluidState.temperature(phaseIdx);
|
||||
Scalar pressure = fluidState.pressure(phaseIdx);
|
||||
return Fluid::thermalConductivity(temperature, pressure);
|
||||
const auto& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const auto& p = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
return Fluid::thermalConductivity(T, p);
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::heatCapacity
|
||||
template <class FluidState>
|
||||
static Scalar heatCapacity(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval heatCapacity(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
typedef Opm::MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
assert(0 <= phaseIdx && phaseIdx < numPhases);
|
||||
|
||||
Scalar temperature = fluidState.temperature(phaseIdx);
|
||||
Scalar pressure = fluidState.pressure(phaseIdx);
|
||||
return Fluid::heatCapacity(temperature, pressure);
|
||||
const auto& T = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const auto& p = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
return Fluid::heatCapacity(T, p);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -352,23 +352,27 @@ public:
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::density
|
||||
template <class FluidState>
|
||||
template <class FluidState, class Evaluation = Scalar>
|
||||
static Scalar density(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
assert(0 <= phaseIdx && phaseIdx < numPhases);
|
||||
static_assert(std::is_same<Evaluation, Scalar>::value,
|
||||
"The SPE-5 fluid system is currently only implemented for the scalar case.");
|
||||
|
||||
return fluidState.averageMolarMass(phaseIdx)/paramCache.molarVolume(phaseIdx);
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::viscosity
|
||||
template <class FluidState>
|
||||
template <class FluidState, class Evaluation = Scalar>
|
||||
static Scalar viscosity(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
assert(0 <= phaseIdx && phaseIdx <= numPhases);
|
||||
static_assert(std::is_same<Evaluation, Scalar>::value,
|
||||
"The SPE-5 fluid system is currently only implemented for the scalar case.");
|
||||
|
||||
if (phaseIdx == gasPhaseIdx) {
|
||||
// given by SPE-5 in table on page 64. we use a constant
|
||||
@ -387,7 +391,7 @@ public:
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::fugacityCoefficient
|
||||
template <class FluidState>
|
||||
template <class FluidState, class Evaluation = Scalar>
|
||||
static Scalar fugacityCoefficient(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx,
|
||||
@ -395,6 +399,8 @@ public:
|
||||
{
|
||||
assert(0 <= phaseIdx && phaseIdx <= numPhases);
|
||||
assert(0 <= compIdx && compIdx <= numComponents);
|
||||
static_assert(std::is_same<Evaluation, Scalar>::value,
|
||||
"The SPE-5 fluid system is currently only implemented for the scalar case.");
|
||||
|
||||
if (phaseIdx == oilPhaseIdx || phaseIdx == gasPhaseIdx)
|
||||
return PengRobinsonMixture::computeFugacityCoefficient(fluidState,
|
||||
|
@ -52,7 +52,7 @@ namespace FluidSystems {
|
||||
*/
|
||||
template <class Scalar, class WettingPhase, class NonwettingPhase>
|
||||
class TwoPhaseImmiscible
|
||||
: public BaseFluidSystem<Scalar, TwoPhaseImmiscible<Scalar, WettingPhase, NonwettingPhase> >
|
||||
: public BaseFluidSystem<Scalar, TwoPhaseImmiscible<Scalar, WettingPhase, NonwettingPhase> >
|
||||
{
|
||||
// do not try to instanciate this class, it has only static members!
|
||||
TwoPhaseImmiscible()
|
||||
@ -216,42 +216,48 @@ public:
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::density
|
||||
template <class FluidState>
|
||||
static Scalar density(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval density(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
typedef MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
assert(0 <= phaseIdx && phaseIdx < numPhases);
|
||||
|
||||
Scalar temperature = fluidState.temperature(phaseIdx);
|
||||
Scalar pressure = fluidState.pressure(phaseIdx);
|
||||
const auto& temperature = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const auto& pressure = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
if (phaseIdx == wettingPhaseIdx)
|
||||
return WettingPhase::density(temperature, pressure);
|
||||
return NonwettingPhase::density(temperature, pressure);
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::viscosity
|
||||
template <class FluidState>
|
||||
static Scalar viscosity(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval viscosity(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
typedef MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
assert(0 <= phaseIdx && phaseIdx < numPhases);
|
||||
|
||||
Scalar temperature = fluidState.temperature(phaseIdx);
|
||||
Scalar pressure = fluidState.pressure(phaseIdx);
|
||||
const auto& temperature = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const auto& pressure = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
if (phaseIdx == wettingPhaseIdx)
|
||||
return WettingPhase::viscosity(temperature, pressure);
|
||||
return NonwettingPhase::viscosity(temperature, pressure);
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::fugacityCoefficient
|
||||
template <class FluidState>
|
||||
static Scalar fugacityCoefficient(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval fugacityCoefficient(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx,
|
||||
int compIdx)
|
||||
{
|
||||
typedef MathToolbox<LhsEval> LhsToolbox;
|
||||
|
||||
assert(0 <= phaseIdx && phaseIdx < numPhases);
|
||||
assert(0 <= compIdx && compIdx < numComponents);
|
||||
|
||||
@ -260,50 +266,56 @@ public:
|
||||
// the component in the fluid. Probably that's not worth
|
||||
// the effort, since the fugacity coefficient of the other
|
||||
// component is infinite anyway...
|
||||
return 1.0;
|
||||
return std::numeric_limits<Scalar>::infinity();
|
||||
return LhsToolbox::createConstant(1.0);
|
||||
return LhsToolbox::createConstant(std::numeric_limits<Scalar>::infinity());
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::enthalpy
|
||||
template <class FluidState>
|
||||
static Scalar enthalpy(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval enthalpy(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
typedef MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
assert(0 <= phaseIdx && phaseIdx < numPhases);
|
||||
|
||||
Scalar temperature = fluidState.temperature(phaseIdx);
|
||||
Scalar pressure = fluidState.pressure(phaseIdx);
|
||||
const auto& temperature = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const auto& pressure = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
if (phaseIdx == wettingPhaseIdx)
|
||||
return WettingPhase::enthalpy(temperature, pressure);
|
||||
return NonwettingPhase::enthalpy(temperature, pressure);
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::thermalConductivity
|
||||
template <class FluidState>
|
||||
static Scalar thermalConductivity(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval thermalConductivity(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
typedef MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
assert(0 <= phaseIdx && phaseIdx < numPhases);
|
||||
|
||||
Scalar temperature = fluidState.temperature(phaseIdx);
|
||||
Scalar pressure = fluidState.pressure(phaseIdx);
|
||||
const auto& temperature = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const auto& pressure = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
if (phaseIdx == wettingPhaseIdx)
|
||||
return WettingPhase::thermalConductivity(temperature, pressure);
|
||||
return NonwettingPhase::thermalConductivity(temperature, pressure);
|
||||
}
|
||||
|
||||
//! \copydoc BaseFluidSystem::heatCapacity
|
||||
template <class FluidState>
|
||||
static Scalar heatCapacity(const FluidState &fluidState,
|
||||
template <class FluidState, class LhsEval = typename FluidState::Scalar>
|
||||
static LhsEval heatCapacity(const FluidState &fluidState,
|
||||
const ParameterCache ¶mCache,
|
||||
int phaseIdx)
|
||||
{
|
||||
typedef MathToolbox<typename FluidState::Scalar> FsToolbox;
|
||||
|
||||
assert(0 <= phaseIdx && phaseIdx < numPhases);
|
||||
|
||||
Scalar temperature = fluidState.temperature(phaseIdx);
|
||||
Scalar pressure = fluidState.pressure(phaseIdx);
|
||||
const auto& temperature = FsToolbox::template toLhs<LhsEval>(fluidState.temperature(phaseIdx));
|
||||
const auto& pressure = FsToolbox::template toLhs<LhsEval>(fluidState.pressure(phaseIdx));
|
||||
if (phaseIdx == wettingPhaseIdx)
|
||||
return WettingPhase::heatCapacity(temperature, pressure);
|
||||
return NonwettingPhase::heatCapacity(temperature, pressure);
|
||||
|
@ -40,10 +40,16 @@ namespace Opm {
|
||||
* \brief This class represents the Pressure-Volume-Temperature relations of the oil phase
|
||||
* without dissolved gas and constant compressibility/"viscosibility".
|
||||
*/
|
||||
template <class Scalar>
|
||||
class ConstantCompressibilityOilPvt : public OilPvtInterface<Scalar>
|
||||
template <class Scalar, class Evaluation = Scalar>
|
||||
class ConstantCompressibilityOilPvt : public OilPvtInterfaceTemplateWrapper<Scalar,
|
||||
Evaluation,
|
||||
ConstantCompressibilityOilPvt<Scalar, Evaluation> >
|
||||
{
|
||||
typedef FluidSystems::BlackOil<Scalar> BlackOilFluidSystem;
|
||||
friend class OilPvtInterfaceTemplateWrapper<Scalar,
|
||||
Evaluation,
|
||||
ConstantCompressibilityOilPvt<Scalar, Evaluation> >;
|
||||
|
||||
typedef FluidSystems::BlackOil<Scalar, Evaluation> BlackOilFluidSystem;
|
||||
|
||||
typedef Opm::Tabulated1DFunction<Scalar> TabulatedOneDFunction;
|
||||
typedef std::vector<std::pair<Scalar, Scalar> > SamplingPoints;
|
||||
@ -133,22 +139,24 @@ public:
|
||||
void initEnd()
|
||||
{ }
|
||||
|
||||
private:
|
||||
/*!
|
||||
* \brief Returns the dynamic viscosity [Pa s] of the fluid phase given a set of parameters.
|
||||
*/
|
||||
Scalar viscosity(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
Scalar XoG) const OPM_FINAL
|
||||
template <class LhsEval>
|
||||
LhsEval viscosity_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
const LhsEval& XoG) const
|
||||
{
|
||||
// Eclipse calculates the viscosity in a weird way: it
|
||||
// calcultes the product of B_w and mu_w and then divides the
|
||||
// result by B_w...
|
||||
Scalar BoMuoRef = oilViscosity_[regionIdx]*oilReferenceFormationVolumeFactor_[regionIdx];
|
||||
Scalar Bo = formationVolumeFactor(regionIdx, temperature, pressure, XoG);
|
||||
const LhsEval& Bo = formationVolumeFactor_(regionIdx, temperature, pressure, XoG);
|
||||
|
||||
Scalar pRef = oilReferencePressure_[regionIdx];
|
||||
Scalar Y =
|
||||
const LhsEval& Y =
|
||||
(oilCompressibility_[regionIdx] - oilViscosibility_[regionIdx])
|
||||
* (pressure - pRef);
|
||||
return BoMuoRef/((1 + Y*(1 + Y/2))*Bo);
|
||||
@ -157,12 +165,13 @@ public:
|
||||
/*!
|
||||
* \brief Returns the density [kg/m^3] of the fluid phase given a set of parameters.
|
||||
*/
|
||||
Scalar density(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
Scalar XoG) const OPM_FINAL
|
||||
template <class LhsEval>
|
||||
LhsEval density_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
const LhsEval& XoG) const
|
||||
{
|
||||
Scalar Bo = formationVolumeFactor(regionIdx, temperature, pressure, XoG);
|
||||
const LhsEval& Bo = formationVolumeFactor_(regionIdx, temperature, pressure, XoG);
|
||||
Scalar rhooRef = BlackOilFluidSystem::referenceDensity(oilPhaseIdx, regionIdx);
|
||||
return rhooRef/Bo;
|
||||
}
|
||||
@ -170,14 +179,15 @@ public:
|
||||
/*!
|
||||
* \brief Returns the formation volume factor [-] of the fluid phase.
|
||||
*/
|
||||
Scalar formationVolumeFactor(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
Scalar XoG) const OPM_FINAL
|
||||
template <class LhsEval>
|
||||
LhsEval formationVolumeFactor_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
const LhsEval& XoG) const
|
||||
{
|
||||
// cf. ECLiPSE 2011 technical description, p. 116
|
||||
Scalar pRef = oilReferencePressure_[regionIdx];
|
||||
Scalar X = oilCompressibility_[regionIdx]*(pressure - pRef);
|
||||
const LhsEval& X = oilCompressibility_[regionIdx]*(pressure - pRef);
|
||||
|
||||
Scalar BoRef = oilReferenceFormationVolumeFactor_[regionIdx];
|
||||
return BoRef/(1 + X*(1 + X/2));
|
||||
@ -187,15 +197,16 @@ public:
|
||||
* \brief Returns the fugacity coefficient [Pa] of a component in the fluid phase given
|
||||
* a set of parameters.
|
||||
*/
|
||||
Scalar fugacityCoefficient(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
int compIdx) const OPM_FINAL
|
||||
template <class LhsEval>
|
||||
LhsEval fugacityCoefficient_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
int compIdx) const
|
||||
{
|
||||
// set the oil component fugacity coefficient in oil phase
|
||||
// arbitrarily. we use some pseudo-realistic value for the vapor
|
||||
// pressure to ease physical interpretation of the results
|
||||
Scalar phi_oO = 20e3/pressure;
|
||||
const LhsEval& phi_oO = 20e3/pressure;
|
||||
|
||||
if (compIdx == BlackOilFluidSystem::oilCompIdx)
|
||||
return phi_oO;
|
||||
@ -213,10 +224,15 @@ public:
|
||||
/*!
|
||||
* \brief Returns the gas dissolution factor \f$R_s\f$ [m^3/m^3] of the oil phase.
|
||||
*/
|
||||
Scalar gasDissolutionFactor(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const OPM_FINAL
|
||||
{ return 0.0; /* this is dead oil! */ }
|
||||
template <class LhsEval>
|
||||
LhsEval gasDissolutionFactor_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure) const
|
||||
{
|
||||
typedef Opm::MathToolbox<LhsEval> Toolbox;
|
||||
|
||||
return Toolbox::createConstant(0.0); /* this is dead oil! */
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the saturation pressure of the oil phase [Pa]
|
||||
@ -224,20 +240,35 @@ public:
|
||||
*
|
||||
* \param XoG The mass fraction of the gas component in the oil phase [-]
|
||||
*/
|
||||
Scalar oilSaturationPressure(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar XoG) const OPM_FINAL
|
||||
{ return 0.0; /* this is dead oil, so there isn't any meaningful saturation pressure! */ }
|
||||
template <class LhsEval>
|
||||
LhsEval oilSaturationPressure_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& XoG) const
|
||||
{
|
||||
typedef Opm::MathToolbox<LhsEval> Toolbox;
|
||||
|
||||
Scalar saturatedOilGasMassFraction(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const OPM_FINAL
|
||||
{ return 0.0; /* this is dead oil! */ }
|
||||
return Toolbox::createConstant(0.0); /* this is dead oil, so there isn't any meaningful saturation pressure! */
|
||||
}
|
||||
|
||||
Scalar saturatedOilGasMoleFraction(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const OPM_FINAL
|
||||
{ return 0.0; /* this is dead oil! */ }
|
||||
template <class LhsEval>
|
||||
LhsEval saturatedOilGasMassFraction_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure) const
|
||||
{
|
||||
typedef Opm::MathToolbox<LhsEval> Toolbox;
|
||||
|
||||
return Toolbox::createConstant(0.0); /* this is dead oil! */
|
||||
}
|
||||
|
||||
template <class LhsEval>
|
||||
LhsEval saturatedOilGasMoleFraction_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure) const
|
||||
{
|
||||
typedef Opm::MathToolbox<LhsEval> Toolbox;
|
||||
|
||||
return Toolbox::createConstant(0.0); /* this is dead oil! */
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<Scalar> oilReferencePressure_;
|
||||
|
@ -26,7 +26,6 @@
|
||||
#include "WaterPvtInterface.hpp"
|
||||
|
||||
#include <opm/material/common/OpmFinal.hpp>
|
||||
|
||||
#if HAVE_OPM_PARSER
|
||||
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||
#endif
|
||||
@ -39,10 +38,13 @@ namespace Opm {
|
||||
* \brief This class represents the Pressure-Volume-Temperature relations of the gas phase
|
||||
* without vaporized oil.
|
||||
*/
|
||||
template <class Scalar>
|
||||
class ConstantCompressibilityWaterPvt : public WaterPvtInterface<Scalar>
|
||||
template <class Scalar, class Evaluation = Scalar>
|
||||
class ConstantCompressibilityWaterPvt
|
||||
: public WaterPvtInterfaceTemplateWrapper<Scalar, Evaluation, ConstantCompressibilityWaterPvt<Scalar, Evaluation> >
|
||||
{
|
||||
typedef FluidSystems::BlackOil<Scalar> BlackOilFluidSystem;
|
||||
friend class WaterPvtInterfaceTemplateWrapper<Scalar, Evaluation, ConstantCompressibilityWaterPvt<Scalar, Evaluation> >;
|
||||
|
||||
typedef FluidSystems::BlackOil<Scalar, Evaluation> BlackOilFluidSystem;
|
||||
|
||||
typedef Opm::Tabulated1DFunction<Scalar> TabulatedOneDFunction;
|
||||
typedef std::vector<std::pair<Scalar, Scalar> > SamplingPoints;
|
||||
@ -132,21 +134,23 @@ public:
|
||||
void initEnd()
|
||||
{ }
|
||||
|
||||
private:
|
||||
/*!
|
||||
* \brief Returns the dynamic viscosity [Pa s] of the fluid phase given a set of parameters.
|
||||
*/
|
||||
Scalar viscosity(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const OPM_FINAL
|
||||
template <class LhsEval>
|
||||
LhsEval viscosity_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure) const
|
||||
{
|
||||
// Eclipse calculates the viscosity in a weird way: it
|
||||
// calcultes the product of B_w and mu_w and then divides the
|
||||
// result by B_w...
|
||||
Scalar BwMuwRef = waterViscosity_[regionIdx]*waterReferenceFormationVolumeFactor_[regionIdx];
|
||||
Scalar Bw = formationVolumeFactor(regionIdx, temperature, pressure);
|
||||
const LhsEval& Bw = formationVolumeFactor_(regionIdx, temperature, pressure);
|
||||
|
||||
Scalar pRef = waterReferencePressure_[regionIdx];
|
||||
Scalar Y =
|
||||
const LhsEval& Y =
|
||||
(waterCompressibility_[regionIdx] - waterViscosibility_[regionIdx])
|
||||
* (pressure - pRef);
|
||||
return BwMuwRef/((1 + Y*(1 + Y/2))*Bw);
|
||||
@ -155,11 +159,12 @@ public:
|
||||
/*!
|
||||
* \brief Returns the density [kg/m^3] of the fluid phase given a set of parameters.
|
||||
*/
|
||||
Scalar density(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const OPM_FINAL
|
||||
template <class LhsEval>
|
||||
LhsEval density_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure) const
|
||||
{
|
||||
Scalar Bw = formationVolumeFactor(regionIdx, temperature, pressure);
|
||||
const LhsEval& Bw = formationVolumeFactor_(regionIdx, temperature, pressure);
|
||||
Scalar rhowRef = BlackOilFluidSystem::referenceDensity(waterPhaseIdx, regionIdx);
|
||||
return rhowRef/Bw;
|
||||
}
|
||||
@ -167,13 +172,14 @@ public:
|
||||
/*!
|
||||
* \brief Returns the formation volume factor [-] of the fluid phase.
|
||||
*/
|
||||
Scalar formationVolumeFactor(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const OPM_FINAL
|
||||
template <class LhsEval>
|
||||
LhsEval formationVolumeFactor_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure) const
|
||||
{
|
||||
// cf. ECLiPSE 2011 technical description, p. 116
|
||||
Scalar pRef = waterReferencePressure_[regionIdx];
|
||||
Scalar X = waterCompressibility_[regionIdx]*(pressure - pRef);
|
||||
const LhsEval& X = waterCompressibility_[regionIdx]*(pressure - pRef);
|
||||
|
||||
Scalar BwRef = waterReferenceFormationVolumeFactor_[regionIdx];
|
||||
|
||||
@ -185,10 +191,11 @@ public:
|
||||
* \brief Returns the fugacity coefficient [Pa] of a component in the fluid phase given
|
||||
* a set of parameters.
|
||||
*/
|
||||
Scalar fugacityCoefficient(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
int compIdx) const OPM_FINAL
|
||||
template <class LhsEval>
|
||||
LhsEval fugacityCoefficient_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
int compIdx) const
|
||||
{
|
||||
// set the affinity of the gas and oil components to the water phase to be 10
|
||||
// orders of magnitute smaller than that of the water component. for this we use
|
||||
|
@ -40,10 +40,16 @@ namespace Opm {
|
||||
* \brief This class represents the Pressure-Volume-Temperature relations of the oil phase
|
||||
* without dissolved gas.
|
||||
*/
|
||||
template <class Scalar>
|
||||
class DeadOilPvt : public OilPvtInterface<Scalar>
|
||||
template <class Scalar, class Evaluation = Scalar>
|
||||
class DeadOilPvt : public OilPvtInterfaceTemplateWrapper<Scalar,
|
||||
Evaluation,
|
||||
DeadOilPvt<Scalar, Evaluation> >
|
||||
{
|
||||
typedef FluidSystems::BlackOil<Scalar> BlackOilFluidSystem;
|
||||
friend class OilPvtInterfaceTemplateWrapper<Scalar,
|
||||
Evaluation,
|
||||
DeadOilPvt<Scalar, Evaluation> >;
|
||||
|
||||
typedef FluidSystems::BlackOil<Scalar, Evaluation> BlackOilFluidSystem;
|
||||
|
||||
typedef Opm::Tabulated1DFunction<Scalar> TabulatedOneDFunction;
|
||||
typedef std::vector<std::pair<Scalar, Scalar> > SamplingPoints;
|
||||
@ -96,8 +102,8 @@ public:
|
||||
{
|
||||
assert(pvdoTable.numRows() > 1);
|
||||
|
||||
const std::vector<Scalar>& BColumn(pvdoTable.getFormationFactorColumn());
|
||||
std::vector<Scalar> invBColumn(pvdoTable.getFormationFactorColumn());
|
||||
const auto& BColumn(pvdoTable.getFormationFactorColumn());
|
||||
std::vector<Scalar> invBColumn(BColumn.size());
|
||||
for (unsigned i = 0; i < invBColumn.size(); ++i)
|
||||
invBColumn[i] = 1/BColumn[i];
|
||||
|
||||
@ -141,16 +147,18 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
/*!
|
||||
* \brief Returns the dynamic viscosity [Pa s] of the fluid phase given a set of parameters.
|
||||
*/
|
||||
Scalar viscosity(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
Scalar XoG) const OPM_FINAL
|
||||
template <class LhsEval>
|
||||
LhsEval viscosity_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
const LhsEval& XoG) const
|
||||
{
|
||||
Scalar invBo = inverseOilB_[regionIdx].eval(pressure, /*extrapolate=*/true);
|
||||
Scalar invMuoBo = inverseOilBMu_[regionIdx].eval(pressure, /*extrapolate=*/true);
|
||||
const LhsEval& invBo = inverseOilB_[regionIdx].eval(pressure, /*extrapolate=*/true);
|
||||
const LhsEval& invMuoBo = inverseOilBMu_[regionIdx].eval(pressure, /*extrapolate=*/true);
|
||||
|
||||
return invBo/invMuoBo;
|
||||
}
|
||||
@ -158,39 +166,42 @@ public:
|
||||
/*!
|
||||
* \brief Returns the density [kg/m^3] of the fluid phase given a set of parameters.
|
||||
*/
|
||||
Scalar density(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
Scalar XoG) const OPM_FINAL
|
||||
template <class LhsEval>
|
||||
LhsEval density_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
const LhsEval& XoG) const
|
||||
{
|
||||
Scalar rhooRef = BlackOilFluidSystem::referenceDensity(oilPhaseIdx, regionIdx);
|
||||
|
||||
Scalar Bo = formationVolumeFactor(regionIdx, temperature, pressure, XoG);
|
||||
const LhsEval& Bo = formationVolumeFactor_(regionIdx, temperature, pressure, XoG);
|
||||
return rhooRef/Bo;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the formation volume factor [-] of the fluid phase.
|
||||
*/
|
||||
Scalar formationVolumeFactor(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
Scalar XoG) const OPM_FINAL
|
||||
template <class LhsEval>
|
||||
LhsEval formationVolumeFactor_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
const LhsEval& XoG) const
|
||||
{ return 1.0 / inverseOilB_[regionIdx].eval(pressure, /*extrapolate=*/true); }
|
||||
|
||||
/*!
|
||||
* \brief Returns the fugacity coefficient [Pa] of a component in the fluid phase given
|
||||
* a set of parameters.
|
||||
*/
|
||||
Scalar fugacityCoefficient(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
int compIdx) const OPM_FINAL
|
||||
template <class LhsEval>
|
||||
LhsEval fugacityCoefficient_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
int compIdx) const
|
||||
{
|
||||
// set the oil component fugacity coefficient in oil phase
|
||||
// arbitrarily. we use some pseudo-realistic value for the vapor
|
||||
// pressure to ease physical interpretation of the results
|
||||
Scalar phi_oO = 20e3/pressure;
|
||||
const LhsEval& phi_oO = 20e3/pressure;
|
||||
|
||||
if (compIdx == BlackOilFluidSystem::oilCompIdx)
|
||||
return phi_oO;
|
||||
@ -208,10 +219,15 @@ public:
|
||||
/*!
|
||||
* \brief Returns the gas dissolution factor \f$R_s\f$ [m^3/m^3] of the oil phase.
|
||||
*/
|
||||
Scalar gasDissolutionFactor(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const OPM_FINAL
|
||||
{ return 0.0; /* this is dead oil! */ }
|
||||
template <class LhsEval>
|
||||
LhsEval gasDissolutionFactor_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure) const
|
||||
{
|
||||
typedef Opm::MathToolbox<LhsEval> Toolbox;
|
||||
|
||||
return Toolbox::createConstant(0.0); /* this is dead oil! */
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the saturation pressure of the oil phase [Pa]
|
||||
@ -219,20 +235,35 @@ public:
|
||||
*
|
||||
* \param XoG The mass fraction of the gas component in the oil phase [-]
|
||||
*/
|
||||
Scalar oilSaturationPressure(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar XoG) const OPM_FINAL
|
||||
{ return 0.0; /* this is dead oil, so there isn't any meaningful saturation pressure! */ }
|
||||
template <class LhsEval>
|
||||
LhsEval oilSaturationPressure_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& XoG) const
|
||||
{
|
||||
typedef Opm::MathToolbox<LhsEval> Toolbox;
|
||||
|
||||
Scalar saturatedOilGasMassFraction(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const OPM_FINAL
|
||||
{ return 0.0; /* this is dead oil! */ }
|
||||
return Toolbox::createConstant(0.0); /* this is dead oil, so there isn't any meaningful saturation pressure! */
|
||||
}
|
||||
|
||||
Scalar saturatedOilGasMoleFraction(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const OPM_FINAL
|
||||
{ return 0.0; /* this is dead oil! */ }
|
||||
template <class LhsEval>
|
||||
LhsEval saturatedOilGasMassFraction_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure) const
|
||||
{
|
||||
typedef Opm::MathToolbox<LhsEval> Toolbox;
|
||||
|
||||
return Toolbox::createConstant(0.0); /* this is dead oil! */
|
||||
}
|
||||
|
||||
template <class LhsEval>
|
||||
LhsEval saturatedOilGasMoleFraction_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure) const
|
||||
{
|
||||
typedef Opm::MathToolbox<LhsEval> Toolbox;
|
||||
|
||||
return Toolbox::createConstant(0.0); /* this is dead oil! */
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<TabulatedOneDFunction> inverseOilB_;
|
||||
|
@ -40,10 +40,13 @@ namespace Opm {
|
||||
* \brief This class represents the Pressure-Volume-Temperature relations of the gas phase
|
||||
* without vaporized oil.
|
||||
*/
|
||||
template <class Scalar>
|
||||
class DryGasPvt : public GasPvtInterface<Scalar>
|
||||
template <class Scalar, class Evaluation = Scalar>
|
||||
class DryGasPvt
|
||||
: public GasPvtInterfaceTemplateWrapper<Scalar, Evaluation, DryGasPvt<Scalar, Evaluation> >
|
||||
{
|
||||
typedef FluidSystems::BlackOil<Scalar> BlackOilFluidSystem;
|
||||
friend class GasPvtInterfaceTemplateWrapper<Scalar, Evaluation, DryGasPvt<Scalar, Evaluation> >;
|
||||
|
||||
typedef FluidSystems::BlackOil<Scalar, Evaluation> BlackOilFluidSystem;
|
||||
|
||||
typedef Opm::Tabulated1DFunction<Scalar> TabulatedOneDFunction;
|
||||
typedef std::vector<std::pair<Scalar, Scalar> > SamplingPoints;
|
||||
@ -133,16 +136,18 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
/*!
|
||||
* \brief Returns the dynamic viscosity [Pa s] of the fluid phase given a set of parameters.
|
||||
*/
|
||||
Scalar viscosity(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
Scalar XgO) const OPM_FINAL
|
||||
template <class LhsEval>
|
||||
LhsEval viscosity_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
const LhsEval& XgO) const
|
||||
{
|
||||
Scalar invBg = inverseGasB_[regionIdx].eval(pressure, /*extrapolate=*/true);
|
||||
Scalar invMugBg = inverseGasBMu_[regionIdx].eval(pressure, /*extrapolate=*/true);
|
||||
const LhsEval& invBg = inverseGasB_[regionIdx].eval(pressure, /*extrapolate=*/true);
|
||||
const LhsEval& invMugBg = inverseGasBMu_[regionIdx].eval(pressure, /*extrapolate=*/true);
|
||||
|
||||
return invBg/invMugBg;
|
||||
}
|
||||
@ -150,38 +155,43 @@ public:
|
||||
/*!
|
||||
* \brief Returns the density [kg/m^3] of the fluid phase given a set of parameters.
|
||||
*/
|
||||
Scalar density(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
Scalar XgO) const OPM_FINAL
|
||||
template <class LhsEval>
|
||||
LhsEval density_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
const LhsEval& XgO) const
|
||||
{
|
||||
// gas formation volume factor at reservoir pressure
|
||||
Scalar Bg = formationVolumeFactor(regionIdx, temperature, pressure, XgO);
|
||||
const LhsEval& Bg = formationVolumeFactor_(regionIdx, temperature, pressure, XgO);
|
||||
return BlackOilFluidSystem::referenceDensity(gasPhaseIdx, regionIdx)/Bg;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the formation volume factor [-] of the fluid phase.
|
||||
*/
|
||||
Scalar formationVolumeFactor(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
Scalar XgO) const OPM_FINAL
|
||||
template <class LhsEval>
|
||||
LhsEval formationVolumeFactor_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
const LhsEval& XgO) const
|
||||
{ return 1.0/inverseGasB_[regionIdx].eval(pressure, /*extrapolate=*/true); }
|
||||
|
||||
/*!
|
||||
* \brief Returns the fugacity coefficient [Pa] of a component in the fluid phase given
|
||||
* a set of parameters.
|
||||
*/
|
||||
Scalar fugacityCoefficient(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
int compIdx) const OPM_FINAL
|
||||
template <class LhsEval>
|
||||
LhsEval fugacityCoefficient_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
int compIdx) const
|
||||
{
|
||||
typedef Opm::MathToolbox<LhsEval> Toolbox;
|
||||
|
||||
// make the gas component more affine to the gas phase than the other components
|
||||
if (compIdx == BlackOilFluidSystem::gasCompIdx)
|
||||
return 1;
|
||||
return 1e6;
|
||||
return Toolbox::createConstant(1.0);
|
||||
return Toolbox::createConstant(1e6);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -190,28 +200,44 @@ public:
|
||||
*
|
||||
* \param XgO The mass fraction of the oil component in the gas phase [-]
|
||||
*/
|
||||
Scalar gasSaturationPressure(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar XgO) const OPM_FINAL
|
||||
{ return 0.0; } // this is dry gas!
|
||||
template <class LhsEval>
|
||||
LhsEval gasSaturationPressure_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& XgO) const
|
||||
{
|
||||
typedef Opm::MathToolbox<LhsEval> Toolbox;
|
||||
return Toolbox::createConstant(0.0); // this is dry gas!
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the gas dissolution factor \f$R_s\f$ [m^3/m^3] of the oil phase.
|
||||
*/
|
||||
Scalar oilVaporizationFactor(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const OPM_FINAL
|
||||
{ return 0.0; } // this is dry gas!
|
||||
template <class LhsEval>
|
||||
LhsEval oilVaporizationFactor_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure) const
|
||||
{
|
||||
typedef Opm::MathToolbox<LhsEval> Toolbox;
|
||||
return Toolbox::createConstant(0.0); // this is dry gas!
|
||||
}
|
||||
|
||||
Scalar saturatedGasOilMassFraction(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const OPM_FINAL
|
||||
{ return 0.0; } // this is dry gas!
|
||||
template <class LhsEval>
|
||||
LhsEval saturatedGasOilMassFraction_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure) const
|
||||
{
|
||||
typedef Opm::MathToolbox<LhsEval> Toolbox;
|
||||
return Toolbox::createConstant(0.0); // this is dry gas!
|
||||
}
|
||||
|
||||
Scalar saturatedGasOilMoleFraction(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const OPM_FINAL
|
||||
{ return 0.0; } // this is dry gas!
|
||||
template <class LhsEval>
|
||||
LhsEval saturatedGasOilMoleFraction_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure) const
|
||||
{
|
||||
typedef Opm::MathToolbox<LhsEval> Toolbox;
|
||||
return Toolbox::createConstant(0.0); // this is dry gas!
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<TabulatedOneDFunction> inverseGasB_;
|
||||
|
@ -23,8 +23,9 @@
|
||||
#ifndef OPM_GAS_PVT_INTERFACE_HPP
|
||||
#define OPM_GAS_PVT_INTERFACE_HPP
|
||||
|
||||
namespace Opm {
|
||||
#include <opm/material/common/OpmFinal.hpp>
|
||||
|
||||
namespace Opm {
|
||||
/*!
|
||||
* \brief This class represents the Pressure-Volume-Temperature relations of the gas
|
||||
* phase in the black-oil model.
|
||||
@ -37,38 +38,54 @@ namespace Opm {
|
||||
* Note that, since the application for this class is the black oil fluid system, the API
|
||||
* exposed by this class is pretty specific to the black oil model.
|
||||
*/
|
||||
template <class Scalar>
|
||||
template <class Scalar, class Evaluation = Scalar>
|
||||
class GasPvtInterface
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* \brief Returns the dynamic viscosity [Pa s] of the fluid phase given a set of parameters.
|
||||
*/
|
||||
virtual Evaluation viscosity(int regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure,
|
||||
const Evaluation& XgO) const = 0;
|
||||
virtual Scalar viscosity(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
Scalar XoG) const = 0;
|
||||
Scalar XgO) const = 0;
|
||||
|
||||
/*!
|
||||
* \brief Returns the formation volume factor [-] of the fluid phase.
|
||||
*/
|
||||
virtual Evaluation formationVolumeFactor(int regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure,
|
||||
const Evaluation& XgO) const = 0;
|
||||
virtual Scalar formationVolumeFactor(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
Scalar XoG) const = 0;
|
||||
Scalar XgO) const = 0;
|
||||
|
||||
/*!
|
||||
* \brief Returns the density [kg/m^3] of the fluid phase given a set of parameters.
|
||||
*/
|
||||
virtual Evaluation density(int regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure,
|
||||
const Evaluation& XgO) const = 0;
|
||||
virtual Scalar density(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
Scalar XoG) const = 0;
|
||||
Scalar XgO) const = 0;
|
||||
|
||||
/*!
|
||||
* \brief Returns the fugacity coefficient [Pa] of a component in the fluid phase given
|
||||
* a set of parameters.
|
||||
*/
|
||||
virtual Evaluation fugacityCoefficient(int regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure,
|
||||
int compIdx) const = 0;
|
||||
virtual Scalar fugacityCoefficient(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
@ -77,6 +94,9 @@ public:
|
||||
/*!
|
||||
* \brief Returns the oil vaporization factor \f$R_v\f$ [m^3/m^3] of oil saturated gas.
|
||||
*/
|
||||
virtual Evaluation oilVaporizationFactor(int regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const = 0;
|
||||
virtual Scalar oilVaporizationFactor(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const = 0;
|
||||
@ -87,6 +107,9 @@ public:
|
||||
*
|
||||
* \param XgO The mass fraction of the oil component in the gas phase [-]
|
||||
*/
|
||||
virtual Evaluation gasSaturationPressure(int regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& XgO) const = 0;
|
||||
virtual Scalar gasSaturationPressure(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar XgO) const = 0;
|
||||
@ -95,6 +118,9 @@ public:
|
||||
* \brief Returns the gas mass fraction of oil-saturated gas at a given temperatire
|
||||
* and pressure [-].
|
||||
*/
|
||||
virtual Evaluation saturatedGasOilMassFraction(int regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const = 0;
|
||||
virtual Scalar saturatedGasOilMassFraction(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const = 0;
|
||||
@ -103,11 +129,182 @@ public:
|
||||
* \brief Returns the gas mole fraction of oil-saturated gas at a given temperatire
|
||||
* and pressure [-].
|
||||
*/
|
||||
virtual Evaluation saturatedGasOilMoleFraction(int regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const = 0;
|
||||
virtual Scalar saturatedGasOilMoleFraction(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const = 0;
|
||||
};
|
||||
|
||||
template <class Scalar>
|
||||
class GasPvtInterface<Scalar, Scalar>
|
||||
{
|
||||
public:
|
||||
virtual Scalar viscosity(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
Scalar XgO) const = 0;
|
||||
virtual Scalar formationVolumeFactor(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
Scalar XgO) const = 0;
|
||||
virtual Scalar density(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
Scalar XgO) const = 0;
|
||||
virtual Scalar fugacityCoefficient(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
int compIdx) const = 0;
|
||||
virtual Scalar oilVaporizationFactor(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const = 0;
|
||||
virtual Scalar gasSaturationPressure(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar XgO) const = 0;
|
||||
virtual Scalar saturatedGasOilMassFraction(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const = 0;
|
||||
virtual Scalar saturatedGasOilMoleFraction(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const = 0;
|
||||
};
|
||||
|
||||
template <class Scalar, class Evaluation, class Implementation>
|
||||
class GasPvtInterfaceTemplateWrapper : public GasPvtInterface<Scalar, Evaluation>
|
||||
{
|
||||
const Implementation& asImp_() const
|
||||
{ return *static_cast<const Implementation*>(this); }
|
||||
|
||||
public:
|
||||
virtual Evaluation viscosity(int regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure,
|
||||
const Evaluation& XgO) const OPM_FINAL
|
||||
{ return asImp_().viscosity_(regionIdx, temperature, pressure, XgO); };
|
||||
virtual Scalar viscosity(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
Scalar XgO) const OPM_FINAL
|
||||
{ return asImp_().viscosity_(regionIdx, temperature, pressure, XgO); };
|
||||
|
||||
virtual Evaluation formationVolumeFactor(int regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure,
|
||||
const Evaluation& XgO) const OPM_FINAL
|
||||
{ return asImp_().formationVolumeFactor_(regionIdx, temperature, pressure, XgO); };
|
||||
virtual Scalar formationVolumeFactor(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
Scalar XgO) const OPM_FINAL
|
||||
{ return asImp_().formationVolumeFactor_(regionIdx, temperature, pressure, XgO); };
|
||||
|
||||
virtual Evaluation density(int regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure,
|
||||
const Evaluation& XgO) const OPM_FINAL
|
||||
{ return asImp_().density_(regionIdx, temperature, pressure, XgO); };
|
||||
virtual Scalar density(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
Scalar XgO) const OPM_FINAL
|
||||
{ return asImp_().density_(regionIdx, temperature, pressure, XgO); };
|
||||
|
||||
virtual Evaluation fugacityCoefficient(int regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure,
|
||||
int compIdx) const OPM_FINAL
|
||||
{ return asImp_().fugacityCoefficient_(regionIdx, temperature, pressure, compIdx); };
|
||||
virtual Scalar fugacityCoefficient(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
int compIdx) const OPM_FINAL
|
||||
{ return asImp_().fugacityCoefficient_(regionIdx, temperature, pressure, compIdx); };
|
||||
|
||||
virtual Evaluation oilVaporizationFactor(int regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const OPM_FINAL
|
||||
{ return asImp_().oilVaporizationFactor_(regionIdx, temperature, pressure); };
|
||||
virtual Scalar oilVaporizationFactor(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const OPM_FINAL
|
||||
{ return asImp_().oilVaporizationFactor_(regionIdx, temperature, pressure); };
|
||||
|
||||
virtual Evaluation gasSaturationPressure(int regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& XgO) const OPM_FINAL
|
||||
{ return asImp_().gasSaturationPressure_(regionIdx, temperature, XgO); };
|
||||
virtual Scalar gasSaturationPressure(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar XgO) const OPM_FINAL
|
||||
{ return asImp_().gasSaturationPressure_(regionIdx, temperature, XgO); };
|
||||
|
||||
virtual Evaluation saturatedGasOilMassFraction(int regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const OPM_FINAL
|
||||
{ return asImp_().saturatedGasOilMassFraction_(regionIdx, temperature, pressure); };
|
||||
virtual Scalar saturatedGasOilMassFraction(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const OPM_FINAL
|
||||
{ return asImp_().saturatedGasOilMassFraction_(regionIdx, temperature, pressure); };
|
||||
|
||||
virtual Evaluation saturatedGasOilMoleFraction(int regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const OPM_FINAL
|
||||
{ return asImp_().saturatedGasOilMoleFraction_(regionIdx, temperature, pressure); };
|
||||
virtual Scalar saturatedGasOilMoleFraction(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const OPM_FINAL
|
||||
{ return asImp_().saturatedGasOilMoleFraction_(regionIdx, temperature, pressure); };
|
||||
};
|
||||
|
||||
template <class Scalar, class Implementation>
|
||||
class GasPvtInterfaceTemplateWrapper<Scalar, Scalar, Implementation>
|
||||
: public GasPvtInterface<Scalar, Scalar>
|
||||
{
|
||||
const Implementation& asImp_() const
|
||||
{ return *static_cast<const Implementation*>(this); }
|
||||
|
||||
public:
|
||||
virtual Scalar viscosity(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
Scalar XgO) const OPM_FINAL
|
||||
{ return asImp_().viscosity_(regionIdx, temperature, pressure, XgO); };
|
||||
virtual Scalar formationVolumeFactor(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
Scalar XgO) const OPM_FINAL
|
||||
{ return asImp_().formationVolumeFactor_(regionIdx, temperature, pressure, XgO); };
|
||||
virtual Scalar density(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
Scalar XgO) const OPM_FINAL
|
||||
{ return asImp_().density_(regionIdx, temperature, pressure, XgO); };
|
||||
virtual Scalar fugacityCoefficient(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
int compIdx) const OPM_FINAL
|
||||
{ return asImp_().fugacityCoefficient_(regionIdx, temperature, pressure, compIdx); };
|
||||
virtual Scalar oilVaporizationFactor(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const OPM_FINAL
|
||||
{ return asImp_().oilVaporizationFactor_(regionIdx, temperature, pressure); };
|
||||
virtual Scalar gasSaturationPressure(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar XgO) const OPM_FINAL
|
||||
{ return asImp_().gasSaturationPressure_(regionIdx, temperature, XgO); };
|
||||
virtual Scalar saturatedGasOilMassFraction(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const OPM_FINAL
|
||||
{ return asImp_().saturatedGasOilMassFraction_(regionIdx, temperature, pressure); };
|
||||
virtual Scalar saturatedGasOilMoleFraction(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const OPM_FINAL
|
||||
{ return asImp_().saturatedGasOilMoleFraction_(regionIdx, temperature, pressure); };
|
||||
};
|
||||
|
||||
} // namespace Opm
|
||||
|
||||
#endif
|
||||
|
@ -40,10 +40,12 @@ namespace Opm {
|
||||
* \brief This class represents the Pressure-Volume-Temperature relations of the oil phas
|
||||
* with dissolved gas.
|
||||
*/
|
||||
template <class Scalar>
|
||||
class LiveOilPvt : public OilPvtInterface<Scalar>
|
||||
template <class Scalar, class Evaluation = Scalar>
|
||||
class LiveOilPvt : public OilPvtInterfaceTemplateWrapper<Scalar, Evaluation, LiveOilPvt<Scalar, Evaluation> >
|
||||
{
|
||||
typedef FluidSystems::BlackOil<Scalar> BlackOilFluidSystem;
|
||||
friend class OilPvtInterfaceTemplateWrapper<Scalar, Evaluation, LiveOilPvt<Scalar, Evaluation> >;
|
||||
|
||||
typedef FluidSystems::BlackOil<Scalar, Evaluation> BlackOilFluidSystem;
|
||||
|
||||
typedef Opm::UniformXTabulated2DFunction<Scalar> TabulatedTwoDFunction;
|
||||
typedef Opm::Tabulated1DFunction<Scalar> TabulatedOneDFunction;
|
||||
@ -61,11 +63,11 @@ class LiveOilPvt : public OilPvtInterface<Scalar>
|
||||
public:
|
||||
void setNumRegions(int numRegions)
|
||||
{
|
||||
if (static_cast<int>(inverseOilB_.size()) < numRegions) {
|
||||
inverseOilB_.resize(numRegions);
|
||||
inverseOilBMu_.resize(numRegions);
|
||||
oilMu_.resize(numRegions);
|
||||
gasDissolutionFactor_.resize(numRegions);
|
||||
if (static_cast<int>(inverseOilBTable_.size()) < numRegions) {
|
||||
inverseOilBTable_.resize(numRegions);
|
||||
inverseOilBMuTable_.resize(numRegions);
|
||||
oilMuTable_.resize(numRegions);
|
||||
gasDissolutionFactorTable_.resize(numRegions);
|
||||
saturationPressureSpline_.resize(numRegions);
|
||||
}
|
||||
}
|
||||
@ -76,7 +78,7 @@ public:
|
||||
* \param samplePoints A container of (x,y) values.
|
||||
*/
|
||||
void setSaturatedOilGasDissolutionFactor(int regionIdx, const SamplingPoints &samplePoints)
|
||||
{ gasDissolutionFactor_[regionIdx].setContainerOfTuples(samplePoints); }
|
||||
{ gasDissolutionFactorTable_[regionIdx].setContainerOfTuples(samplePoints); }
|
||||
|
||||
/*!
|
||||
* \brief Initialize the function for the oil formation volume factor
|
||||
@ -89,14 +91,14 @@ public:
|
||||
*/
|
||||
void setSaturatedOilFormationVolumeFactor(int regionIdx, const SamplingPoints &samplePoints)
|
||||
{
|
||||
auto& invOilB = inverseOilB_[regionIdx];
|
||||
auto& invOilB = inverseOilBTable_[regionIdx];
|
||||
|
||||
auto &Rs = gasDissolutionFactor_[regionIdx];
|
||||
auto &Rs = gasDissolutionFactorTable_[regionIdx];
|
||||
|
||||
Scalar T = BlackOilFluidSystem::surfaceTemperature;
|
||||
|
||||
Scalar RsMin = 0.0;
|
||||
Scalar RsMax = Rs.eval(gasDissolutionFactor_[regionIdx].xMax(), /*extrapolate=*/true);
|
||||
Scalar RsMax = Rs.eval(gasDissolutionFactorTable_[regionIdx].xMax(), /*extrapolate=*/true);
|
||||
|
||||
Scalar poMin = samplePoints.front().first;
|
||||
Scalar poMax = samplePoints.back().first;
|
||||
@ -123,7 +125,7 @@ public:
|
||||
for (size_t pIdx = 0; pIdx < nP; ++pIdx) {
|
||||
Scalar po = poMin + (poMax - poMin)*pIdx/nP;
|
||||
|
||||
Scalar poSat = oilSaturationPressure(regionIdx, T, XoG);
|
||||
Scalar poSat = oilSaturationPressure_(regionIdx, T, XoG);
|
||||
Scalar BoSat = oilFormationVolumeFactorSpline.eval(poSat, /*extrapolate=*/true);
|
||||
Scalar drhoo_dp = (1.1200 - 1.1189)/((5000 - 4000)*6894.76);
|
||||
Scalar rhoo = BlackOilFluidSystem::referenceDensity(oilPhaseIdx, regionIdx)/BoSat*(1 + drhoo_dp*(po - poSat));
|
||||
@ -148,7 +150,7 @@ public:
|
||||
* and not the other way around.
|
||||
*/
|
||||
void setInverseOilFormationVolumeFactor(int regionIdx, const TabulatedTwoDFunction& invBo)
|
||||
{ inverseOilB_[regionIdx] = invBo; }
|
||||
{ inverseOilBTable_[regionIdx] = invBo; }
|
||||
|
||||
/*!
|
||||
* \brief Initialize the viscosity of the oil phase.
|
||||
@ -156,7 +158,7 @@ public:
|
||||
* This is a function of \f$(R_s, p_o)\f$...
|
||||
*/
|
||||
void setOilViscosity(int regionIdx, const TabulatedTwoDFunction& muo)
|
||||
{ oilMu_[regionIdx] = muo; }
|
||||
{ oilMuTable_[regionIdx] = muo; }
|
||||
|
||||
/*!
|
||||
* \brief Initialize the phase viscosity for gas saturated oil
|
||||
@ -167,10 +169,10 @@ public:
|
||||
*/
|
||||
void setSaturatedOilViscosity(int regionIdx, const SamplingPoints &samplePoints )
|
||||
{
|
||||
auto& gasDissolutionFactor = gasDissolutionFactor_[regionIdx];
|
||||
auto& gasDissolutionFactor = gasDissolutionFactorTable_[regionIdx];
|
||||
|
||||
Scalar RsMin = 0.0;
|
||||
Scalar RsMax = gasDissolutionFactor.eval(gasDissolutionFactor_[regionIdx].xMax(), /*extrapolate=*/true);
|
||||
Scalar RsMax = gasDissolutionFactor.eval(gasDissolutionFactorTable_[regionIdx].xMax(), /*extrapolate=*/true);
|
||||
|
||||
Scalar poMin = samplePoints.front().first;
|
||||
Scalar poMax = samplePoints.back().first;
|
||||
@ -186,13 +188,13 @@ public:
|
||||
for (size_t RsIdx = 0; RsIdx < nRs; ++RsIdx) {
|
||||
Scalar Rs = RsMin + (RsMax - RsMin)*RsIdx/nRs;
|
||||
|
||||
oilMu_[regionIdx].appendXPos(Rs);
|
||||
oilMuTable_[regionIdx].appendXPos(Rs);
|
||||
|
||||
for (size_t pIdx = 0; pIdx < nP; ++pIdx) {
|
||||
Scalar po = poMin + (poMax - poMin)*pIdx/nP;
|
||||
Scalar muo = muoSpline.eval(po, /*extrapolate=*/true);
|
||||
|
||||
oilMu_[regionIdx].appendSamplePoint(RsIdx, po, muo);
|
||||
oilMuTable_[regionIdx].appendSamplePoint(RsIdx, po, muo);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -206,9 +208,9 @@ public:
|
||||
const auto saturatedTable = pvtoTable.getOuterTable();
|
||||
assert(saturatedTable->numRows() > 1);
|
||||
|
||||
auto& oilMu = oilMu_[regionIdx];
|
||||
auto& invOilB = inverseOilB_[regionIdx];
|
||||
auto& gasDissolutionFactor = gasDissolutionFactor_[regionIdx];
|
||||
auto& oilMu = oilMuTable_[regionIdx];
|
||||
auto& invOilB = inverseOilBTable_[regionIdx];
|
||||
auto& gasDissolutionFactor = gasDissolutionFactorTable_[regionIdx];
|
||||
|
||||
gasDissolutionFactor.setXYArrays(saturatedTable->numRows(),
|
||||
saturatedTable->getPressureColumn(),
|
||||
@ -301,15 +303,15 @@ public:
|
||||
void initEnd()
|
||||
{
|
||||
// calculate the final 2D functions which are used for interpolation.
|
||||
int numRegions = oilMu_.size();
|
||||
int numRegions = oilMuTable_.size();
|
||||
for (int regionIdx = 0; regionIdx < numRegions; ++ regionIdx) {
|
||||
// calculate the table which stores the inverse of the product of the oil
|
||||
// formation volume factor and the oil viscosity
|
||||
const auto& oilMu = oilMu_[regionIdx];
|
||||
const auto& invOilB = inverseOilB_[regionIdx];
|
||||
const auto& oilMu = oilMuTable_[regionIdx];
|
||||
const auto& invOilB = inverseOilBTable_[regionIdx];
|
||||
assert(oilMu.numX() == invOilB.numX());
|
||||
|
||||
auto& invOilBMu = inverseOilBMu_[regionIdx];
|
||||
auto& invOilBMu = inverseOilBMuTable_[regionIdx];
|
||||
|
||||
for (int rsIdx = 0; rsIdx < oilMu.numX(); ++rsIdx) {
|
||||
invOilBMu.appendXPos(oilMu.xAt(rsIdx));
|
||||
@ -328,22 +330,24 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
/*!
|
||||
* \brief Returns the dynamic viscosity [Pa s] of the fluid phase given a set of parameters.
|
||||
*/
|
||||
Scalar viscosity(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
Scalar XoG) const OPM_FINAL
|
||||
template <class LhsEval>
|
||||
LhsEval viscosity_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
const LhsEval& XoG) const
|
||||
{
|
||||
Scalar Rs =
|
||||
const LhsEval& Rs =
|
||||
XoG/(1 - XoG)
|
||||
* BlackOilFluidSystem::referenceDensity(oilPhaseIdx, regionIdx)
|
||||
/ BlackOilFluidSystem::referenceDensity(gasPhaseIdx, regionIdx);
|
||||
* (BlackOilFluidSystem::referenceDensity(oilPhaseIdx, regionIdx)
|
||||
/ BlackOilFluidSystem::referenceDensity(gasPhaseIdx, regionIdx));
|
||||
|
||||
// ATTENTION: Rs is the first axis!
|
||||
Scalar invBo = inverseOilB_[regionIdx].eval(Rs, pressure, /*extrapolate=*/true);
|
||||
Scalar invMuoBo = inverseOilBMu_[regionIdx].eval(Rs, pressure, /*extrapolate=*/true);
|
||||
const LhsEval& invBo = inverseOilBTable_[regionIdx].eval(Rs, pressure, /*extrapolate=*/true);
|
||||
const LhsEval& invMuoBo = inverseOilBMuTable_[regionIdx].eval(Rs, pressure, /*extrapolate=*/true);
|
||||
|
||||
return invBo/invMuoBo;
|
||||
}
|
||||
@ -351,21 +355,26 @@ public:
|
||||
/*!
|
||||
* \brief Returns the density [kg/m^3] of the fluid phase given a set of parameters.
|
||||
*/
|
||||
Scalar density(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
Scalar XoG) const OPM_FINAL
|
||||
template <class LhsEval>
|
||||
LhsEval density_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
const LhsEval& XoG) const
|
||||
{
|
||||
Scalar rhooRef = BlackOilFluidSystem::referenceDensity(oilPhaseIdx, regionIdx);
|
||||
Scalar rhogRef = BlackOilFluidSystem::referenceDensity(gasPhaseIdx, regionIdx);
|
||||
Valgrind::CheckDefined(rhooRef);
|
||||
Valgrind::CheckDefined(rhogRef);
|
||||
|
||||
Scalar Bo = formationVolumeFactor(regionIdx, temperature, pressure, XoG);
|
||||
Scalar rhoo = rhooRef/Bo;
|
||||
const LhsEval& Bo = formationVolumeFactor_(regionIdx, temperature, pressure, XoG);
|
||||
Valgrind::CheckDefined(Bo);
|
||||
|
||||
LhsEval rhoo = rhooRef/Bo;
|
||||
|
||||
// the oil formation volume factor just represents the partial density of the oil
|
||||
// component in the oil phase. to get the total density of the phase, we have to
|
||||
// add the partial density of the gas component.
|
||||
Scalar Rs = XoG/(1 - XoG) * rhooRef/rhogRef;
|
||||
const LhsEval Rs = XoG/(1 - XoG) * rhooRef/rhogRef;
|
||||
rhoo += rhogRef*Rs/Bo;
|
||||
|
||||
return rhoo;
|
||||
@ -374,33 +383,37 @@ public:
|
||||
/*!
|
||||
* \brief Returns the formation volume factor [-] of the fluid phase.
|
||||
*/
|
||||
Scalar formationVolumeFactor(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
Scalar XoG) const OPM_FINAL
|
||||
template <class LhsEval>
|
||||
LhsEval formationVolumeFactor_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
const LhsEval& XoG) const
|
||||
{
|
||||
Scalar Rs =
|
||||
const LhsEval& Rs =
|
||||
XoG/(1-XoG)
|
||||
*BlackOilFluidSystem::referenceDensity(oilPhaseIdx, regionIdx)
|
||||
/BlackOilFluidSystem::referenceDensity(gasPhaseIdx, regionIdx);
|
||||
*(BlackOilFluidSystem::referenceDensity(oilPhaseIdx, regionIdx)
|
||||
/BlackOilFluidSystem::referenceDensity(gasPhaseIdx, regionIdx));
|
||||
Valgrind::CheckDefined(Rs);
|
||||
Valgrind::CheckDefined(XoG);
|
||||
|
||||
// ATTENTION: Rs is represented by the _first_ axis!
|
||||
return 1.0 / inverseOilB_[regionIdx].eval(Rs, pressure, /*extrapolate=*/true);
|
||||
return 1.0 / inverseOilBTable_[regionIdx].eval(Rs, pressure, /*extrapolate=*/true);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the fugacity coefficient [Pa] of a component in the fluid phase given
|
||||
* a set of parameters.
|
||||
*/
|
||||
Scalar fugacityCoefficient(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
int compIdx) const OPM_FINAL
|
||||
template <class LhsEval>
|
||||
LhsEval fugacityCoefficient_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
int compIdx) const
|
||||
{
|
||||
// set the oil component fugacity coefficient in oil phase
|
||||
// arbitrarily. we use some pseudo-realistic value for the vapor
|
||||
// pressure to ease physical interpretation of the results
|
||||
Scalar phi_oO = 20e3/pressure;
|
||||
const LhsEval& phi_oO = 20e3/pressure;
|
||||
|
||||
if (compIdx == BlackOilFluidSystem::oilCompIdx)
|
||||
return phi_oO;
|
||||
@ -416,27 +429,27 @@ public:
|
||||
//
|
||||
// first, retrieve the mole fraction of gas a saturated oil
|
||||
// would exhibit at the given pressure
|
||||
Scalar x_oGSat = saturatedOilGasMoleFraction(regionIdx, temperature, pressure);
|
||||
const LhsEval& x_oGSat = saturatedOilGasMoleFraction_(regionIdx, temperature, pressure);
|
||||
|
||||
// then, scale the gas component's gas phase fugacity
|
||||
// coefficient, so that the oil phase ends up at the right
|
||||
// composition if we were doing a flash experiment
|
||||
Scalar phi_gG = BlackOilFluidSystem::fugCoefficientInGas(gasCompIdx,
|
||||
const LhsEval& phi_gG = BlackOilFluidSystem::fugCoefficientInGas(gasCompIdx,
|
||||
temperature,
|
||||
pressure,
|
||||
regionIdx);
|
||||
|
||||
|
||||
return phi_gG / x_oGSat;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the gas dissolution factor \f$R_s\f$ [m^3/m^3] of the oil phase.
|
||||
*/
|
||||
Scalar gasDissolutionFactor(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const OPM_FINAL
|
||||
{ return gasDissolutionFactor_[regionIdx].eval(pressure, /*extrapolate=*/true); }
|
||||
template <class LhsEval>
|
||||
LhsEval gasDissolutionFactor_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure) const
|
||||
{ return gasDissolutionFactorTable_[regionIdx].eval(pressure, /*extrapolate=*/true); }
|
||||
|
||||
/*!
|
||||
* \brief Returns the saturation pressure of the oil phase [Pa]
|
||||
@ -444,34 +457,38 @@ public:
|
||||
*
|
||||
* \param XoG The mass fraction of the gas component in the oil phase [-]
|
||||
*/
|
||||
Scalar oilSaturationPressure(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar XoG) const OPM_FINAL
|
||||
template <class LhsEval>
|
||||
LhsEval oilSaturationPressure_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& XoG) const
|
||||
{
|
||||
typedef Opm::MathToolbox<LhsEval> Toolbox;
|
||||
|
||||
// use the saturation pressure spline to get a pretty good initial value
|
||||
Scalar pSat = saturationPressureSpline_[regionIdx].eval(XoG, /*extrapolate=*/true);
|
||||
LhsEval pSat = saturationPressureSpline_[regionIdx].eval(XoG, /*extrapolate=*/true);
|
||||
LhsEval eps = pSat*1e-11;
|
||||
|
||||
// Newton method to do the remaining work. If the initial
|
||||
// value is good, this should only take two to three
|
||||
// iterations...
|
||||
for (int i = 0; i < 20; ++i) {
|
||||
Scalar f = saturatedOilGasMassFraction(regionIdx, temperature, pSat) - XoG;
|
||||
Scalar eps = pSat*1e-11;
|
||||
Scalar fPrime = ((saturatedOilGasMassFraction(regionIdx, temperature, pSat + eps) - XoG) - f)/eps;
|
||||
const LhsEval& f = saturatedOilGasMassFraction_(regionIdx, temperature, pSat) - XoG;
|
||||
const LhsEval& fPrime = ((saturatedOilGasMassFraction_(regionIdx, temperature, pSat + eps) - XoG) - f)/eps;
|
||||
|
||||
Scalar delta = f/fPrime;
|
||||
const LhsEval& delta = f/fPrime;
|
||||
pSat -= delta;
|
||||
|
||||
if (std::abs(delta) < pSat * 1e-10)
|
||||
if (std::abs(Toolbox::value(delta)) < Toolbox::value(pSat) * 1e-10)
|
||||
return pSat;
|
||||
}
|
||||
|
||||
OPM_THROW(NumericalIssue, "Could find the oil saturation pressure for X_o^G = " << XoG);
|
||||
}
|
||||
|
||||
Scalar saturatedOilGasMassFraction(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const OPM_FINAL
|
||||
template <class LhsEval>
|
||||
LhsEval saturatedOilGasMassFraction_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure) const
|
||||
{
|
||||
Scalar rho_gRef = BlackOilFluidSystem::referenceDensity(gasPhaseIdx, regionIdx);
|
||||
Scalar rho_oRef = BlackOilFluidSystem::referenceDensity(oilPhaseIdx, regionIdx);
|
||||
@ -479,35 +496,35 @@ public:
|
||||
// calculate the mass of the gas component [kg/m^3] in the oil phase. This is
|
||||
// equivalent to the gas dissolution factor [m^3/m^3] at current pressure times
|
||||
// the gas density [kg/m^3] at standard pressure
|
||||
Scalar rho_oG = gasDissolutionFactor(regionIdx, temperature, pressure) * rho_gRef;
|
||||
const LhsEval& rho_oG = gasDissolutionFactorTable_[regionIdx].eval(pressure, /*extrapolate=*/true) * rho_gRef;
|
||||
|
||||
// we now have the total density of saturated oil and the partial density of the
|
||||
// gas component within it. The gas mass fraction is the ratio of these two.
|
||||
return rho_oG/(rho_oRef + rho_oG);
|
||||
}
|
||||
|
||||
Scalar saturatedOilGasMoleFraction(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const OPM_FINAL
|
||||
template <class LhsEval>
|
||||
LhsEval saturatedOilGasMoleFraction_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure) const
|
||||
{
|
||||
// calculate the mass fractions of gas and oil
|
||||
Scalar XoG = saturatedOilGasMassFraction(regionIdx, temperature, pressure);
|
||||
const LhsEval& XoG = saturatedOilGasMassFraction_(regionIdx, temperature, pressure);
|
||||
|
||||
// which can be converted to mole fractions, given the
|
||||
// components' molar masses
|
||||
Scalar MG = BlackOilFluidSystem::molarMass(gasCompIdx, regionIdx);
|
||||
Scalar MO = BlackOilFluidSystem::molarMass(oilCompIdx, regionIdx);
|
||||
|
||||
Scalar avgMolarMass = MO/(1 + XoG*(MO/MG - 1));
|
||||
Scalar xoG = XoG*avgMolarMass/MG;
|
||||
LhsEval avgMolarMass = MO/(1 + XoG*(MO/MG - 1));
|
||||
LhsEval xoG = XoG*avgMolarMass/MG;
|
||||
|
||||
return xoG;
|
||||
}
|
||||
|
||||
private:
|
||||
void updateSaturationPressureSpline_(int regionIdx)
|
||||
{
|
||||
auto& gasDissolutionFactor = gasDissolutionFactor_[regionIdx];
|
||||
auto& gasDissolutionFactor = gasDissolutionFactorTable_[regionIdx];
|
||||
|
||||
// create the spline representing saturation pressure
|
||||
// depending of the mass fraction in gas
|
||||
@ -518,7 +535,9 @@ private:
|
||||
Scalar XoG = 0;
|
||||
for (int i=0; i <= n; ++ i) {
|
||||
Scalar pSat = gasDissolutionFactor.xMin() + i*delta;
|
||||
XoG = saturatedOilGasMassFraction(regionIdx, /*temperature=*/1e100, pSat);
|
||||
XoG = saturatedOilGasMassFraction_(regionIdx,
|
||||
/*temperature=*/Scalar(1e100),
|
||||
pSat);
|
||||
|
||||
std::pair<Scalar, Scalar> val(XoG, pSat);
|
||||
pSatSamplePoints.push_back(val);
|
||||
@ -527,10 +546,10 @@ private:
|
||||
/*type=*/Spline::Monotonic);
|
||||
}
|
||||
|
||||
std::vector<TabulatedTwoDFunction> inverseOilB_;
|
||||
std::vector<TabulatedTwoDFunction> oilMu_;
|
||||
std::vector<TabulatedTwoDFunction> inverseOilBMu_;
|
||||
std::vector<TabulatedOneDFunction> gasDissolutionFactor_;
|
||||
std::vector<TabulatedTwoDFunction> inverseOilBTable_;
|
||||
std::vector<TabulatedTwoDFunction> oilMuTable_;
|
||||
std::vector<TabulatedTwoDFunction> inverseOilBMuTable_;
|
||||
std::vector<TabulatedOneDFunction> gasDissolutionFactorTable_;
|
||||
std::vector<Spline> saturationPressureSpline_;
|
||||
};
|
||||
|
||||
|
@ -23,8 +23,9 @@
|
||||
#ifndef OPM_OIL_PVT_INTERFACE_HPP
|
||||
#define OPM_OIL_PVT_INTERFACE_HPP
|
||||
|
||||
namespace Opm {
|
||||
#include <opm/material/common/OpmFinal.hpp>
|
||||
|
||||
namespace Opm {
|
||||
/*!
|
||||
* \brief This class represents the Pressure-Volume-Temperature relations of the oil
|
||||
* phase in the black-oil model.
|
||||
@ -37,9 +38,117 @@ namespace Opm {
|
||||
* Note that, since the application for this class is the black-oil fluid system, the API
|
||||
* exposed by this class is pretty specific to the black-oil model.
|
||||
*/
|
||||
template <class Scalar>
|
||||
template <class Scalar, class Evaluation = Scalar>
|
||||
class OilPvtInterface
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* \brief Returns the dynamic viscosity [Pa s] of the fluid phase given a set of parameters.
|
||||
*/
|
||||
virtual Evaluation viscosity(int regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure,
|
||||
const Evaluation& XoG) const = 0;
|
||||
virtual Scalar viscosity(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
Scalar XoG) const = 0;
|
||||
|
||||
/*!
|
||||
* \brief Returns the formation volume factor [-] of the fluid phase.
|
||||
*/
|
||||
virtual Evaluation formationVolumeFactor(int regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure,
|
||||
const Evaluation& XoG) const = 0;
|
||||
virtual Scalar formationVolumeFactor(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
Scalar XoG) const = 0;
|
||||
|
||||
/*!
|
||||
* \brief Returns the density [kg/m^3] of the fluid phase given a set of parameters.
|
||||
*/
|
||||
virtual Evaluation density(int regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure,
|
||||
const Evaluation& XoG) const = 0;
|
||||
virtual Scalar density(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
Scalar XoG) const = 0;
|
||||
|
||||
/*!
|
||||
* \brief Returns the fugacity coefficient [Pa] of a component in the fluid phase given
|
||||
* a set of parameters.
|
||||
*/
|
||||
virtual Evaluation fugacityCoefficient(int regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure,
|
||||
int compIdx) const = 0;
|
||||
virtual Scalar fugacityCoefficient(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
int compIdx) const = 0;
|
||||
|
||||
/*!
|
||||
* \brief Returns the gas dissolution factor \f$R_s\f$ [m^3/m^3] of saturated oil.
|
||||
*/
|
||||
virtual Evaluation gasDissolutionFactor(int regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const = 0;
|
||||
virtual Scalar gasDissolutionFactor(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const = 0;
|
||||
|
||||
/*!
|
||||
* \brief Returns the saturation pressure [Pa] of oil given the mass fraction of the
|
||||
* gas component in the oil phase.
|
||||
*
|
||||
* Calling this method only makes sense for live oil. All other implementations of
|
||||
* the black-oil PVT interface will just throw an exception...
|
||||
*/
|
||||
virtual Evaluation oilSaturationPressure(int regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& XoG) const = 0;
|
||||
virtual Scalar oilSaturationPressure(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar XoG) const = 0;
|
||||
|
||||
/*!
|
||||
* \brief Returns the gas mass fraction of gas-saturated oil at a given temperatire
|
||||
* and pressure [-].
|
||||
*
|
||||
* Calling this method only makes sense for oil. For all other phases an exception
|
||||
* will be thrown...
|
||||
*/
|
||||
virtual Evaluation saturatedOilGasMassFraction(int regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const = 0;
|
||||
virtual Scalar saturatedOilGasMassFraction(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const = 0;
|
||||
|
||||
/*!
|
||||
* \brief Returns the gas mole fraction of gas-saturated oil at a given temperatire
|
||||
* and pressure [-].
|
||||
*
|
||||
* Calling this method only makes sense for oil. For all other phases an exception
|
||||
* will be thrown...
|
||||
*/
|
||||
virtual Evaluation saturatedOilGasMoleFraction(int regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const = 0;
|
||||
virtual Scalar saturatedOilGasMoleFraction(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const = 0;
|
||||
};
|
||||
|
||||
// if Evaluation == Scalar, the PVT interface provides only the scalar variants of the
|
||||
// methods.
|
||||
template <class Scalar>
|
||||
class OilPvtInterface<Scalar, Scalar>
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* \brief Returns the dynamic viscosity [Pa s] of the fluid phase given a set of parameters.
|
||||
@ -115,6 +224,144 @@ public:
|
||||
Scalar pressure) const = 0;
|
||||
};
|
||||
|
||||
// To prevent the need for most code duplication, derived classes can use this class to
|
||||
// call templated variants of all the methods
|
||||
template <class Scalar, class Evaluation, class Implementation>
|
||||
class OilPvtInterfaceTemplateWrapper
|
||||
: public OilPvtInterface<Scalar, Evaluation>
|
||||
{
|
||||
Evaluation viscosity(int regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure,
|
||||
const Evaluation& XoG) const OPM_FINAL
|
||||
{ return asImp_().template viscosity_<Evaluation>(regionIdx, temperature, pressure, XoG); }
|
||||
Scalar viscosity(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
Scalar XoG) const OPM_FINAL
|
||||
{ return asImp_().template viscosity_<Scalar>(regionIdx, temperature, pressure, XoG); }
|
||||
|
||||
Evaluation formationVolumeFactor(int regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure,
|
||||
const Evaluation& XoG) const OPM_FINAL
|
||||
{ return asImp_().template formationVolumeFactor_<Evaluation>(regionIdx, temperature, pressure, XoG); }
|
||||
Scalar formationVolumeFactor(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
Scalar XoG) const OPM_FINAL
|
||||
{ return asImp_().template formationVolumeFactor_<Scalar>(regionIdx, temperature, pressure, XoG); }
|
||||
|
||||
Evaluation density(int regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure,
|
||||
const Evaluation& XoG) const OPM_FINAL
|
||||
{ return asImp_().template density_<Evaluation>(regionIdx, temperature, pressure, XoG); }
|
||||
Scalar density(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
Scalar XoG) const OPM_FINAL
|
||||
{ return asImp_().template density_<Scalar>(regionIdx, temperature, pressure, XoG); }
|
||||
|
||||
Evaluation fugacityCoefficient(int regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure,
|
||||
int compIdx) const OPM_FINAL
|
||||
{ return asImp_().template fugacityCoefficient_<Evaluation>(regionIdx, temperature, pressure, compIdx); }
|
||||
Scalar fugacityCoefficient(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
int compIdx) const OPM_FINAL
|
||||
{ return asImp_().template fugacityCoefficient_<Scalar>(regionIdx, temperature, pressure, compIdx); }
|
||||
|
||||
Evaluation gasDissolutionFactor(int regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const OPM_FINAL
|
||||
{ return asImp_().template gasDissolutionFactor_<Evaluation>(regionIdx, temperature, pressure); }
|
||||
Scalar gasDissolutionFactor(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const OPM_FINAL
|
||||
{ return asImp_().template gasDissolutionFactor_<Scalar>(regionIdx, temperature, pressure); }
|
||||
|
||||
Evaluation oilSaturationPressure(int regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& XoG) const OPM_FINAL
|
||||
{ return asImp_().template oilSaturationPressure_<Evaluation>(regionIdx, temperature, XoG); }
|
||||
Scalar oilSaturationPressure(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar XoG) const OPM_FINAL
|
||||
{ return asImp_().template oilSaturationPressure_<Scalar>(regionIdx, temperature, XoG); }
|
||||
|
||||
Evaluation saturatedOilGasMassFraction(int regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const OPM_FINAL
|
||||
{ return asImp_().template saturatedOilGasMassFraction_<Evaluation>(regionIdx, temperature, pressure); }
|
||||
Scalar saturatedOilGasMassFraction(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const OPM_FINAL
|
||||
{ return asImp_().template saturatedOilGasMassFraction_<Scalar>(regionIdx, temperature, pressure); }
|
||||
|
||||
Evaluation saturatedOilGasMoleFraction(int regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const OPM_FINAL
|
||||
{ return asImp_().template saturatedOilGasMoleFraction_<Evaluation>(regionIdx, temperature, pressure); }
|
||||
Scalar saturatedOilGasMoleFraction(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const OPM_FINAL
|
||||
{ return asImp_().template saturatedOilGasMoleFraction_<Scalar>(regionIdx, temperature, pressure); }
|
||||
|
||||
private:
|
||||
const Implementation& asImp_() const
|
||||
{ return *static_cast<const Implementation*>(this); }
|
||||
};
|
||||
|
||||
template <class Scalar, class Implementation>
|
||||
class OilPvtInterfaceTemplateWrapper<Scalar, Scalar, Implementation>
|
||||
: public OilPvtInterface<Scalar, Scalar>
|
||||
{
|
||||
Scalar viscosity(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
Scalar XoG) const OPM_FINAL
|
||||
{ return asImp_().template viscosity_<Scalar>(regionIdx, temperature, pressure, XoG); }
|
||||
Scalar formationVolumeFactor(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
Scalar XoG) const OPM_FINAL
|
||||
{ return asImp_().template formationVolumeFactor_<Scalar>(regionIdx, temperature, pressure, XoG); }
|
||||
Scalar density(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
Scalar XoG) const OPM_FINAL
|
||||
{ return asImp_().template density_<Scalar>(regionIdx, temperature, pressure, XoG); }
|
||||
Scalar fugacityCoefficient(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
int compIdx) const OPM_FINAL
|
||||
{ return asImp_().template fugacityCoefficient_<Scalar>(regionIdx, temperature, pressure, compIdx); }
|
||||
Scalar gasDissolutionFactor(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const OPM_FINAL
|
||||
{ return asImp_().template gasDissolutionFactor_<Scalar>(regionIdx, temperature, pressure); }
|
||||
Scalar oilSaturationPressure(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar XoG) const OPM_FINAL
|
||||
{ return asImp_().template oilSaturationPressure_<Scalar>(regionIdx, temperature, XoG); }
|
||||
Scalar saturatedOilGasMassFraction(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const OPM_FINAL
|
||||
{ return asImp_().template saturatedOilGasMassFraction_<Scalar>(regionIdx, temperature, pressure); }
|
||||
Scalar saturatedOilGasMoleFraction(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const OPM_FINAL
|
||||
{ return asImp_().template saturatedOilGasMoleFraction_<Scalar>(regionIdx, temperature, pressure); }
|
||||
|
||||
private:
|
||||
const Implementation& asImp_() const
|
||||
{ return *static_cast<const Implementation*>(this); }
|
||||
};
|
||||
|
||||
|
||||
} // namespace Opm
|
||||
|
||||
#endif
|
||||
|
@ -23,8 +23,9 @@
|
||||
#ifndef OPM_WATER_PVT_INTERFACE_HPP
|
||||
#define OPM_WATER_PVT_INTERFACE_HPP
|
||||
|
||||
namespace Opm {
|
||||
#include <opm/material/common/OpmFinal.hpp>
|
||||
|
||||
namespace Opm {
|
||||
/*!
|
||||
* \brief This class represents the Pressure-Volume-Temperature relations of the water
|
||||
* phase in the black-oil model.
|
||||
@ -37,13 +38,16 @@ namespace Opm {
|
||||
* Note that, since the application for this class is the black oil fluid system, the API
|
||||
* exposed by this class is pretty specific to the black-oil model.
|
||||
*/
|
||||
template <class Scalar>
|
||||
template <class Scalar, class Evaluation = Scalar>
|
||||
class WaterPvtInterface
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* \brief Returns the dynamic viscosity [Pa s] of the fluid phase given a set of parameters.
|
||||
*/
|
||||
virtual Evaluation viscosity(int regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const = 0;
|
||||
virtual Scalar viscosity(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const = 0;
|
||||
@ -51,6 +55,9 @@ public:
|
||||
/*!
|
||||
* \brief Returns the formation volume factor [-] of the fluid phase.
|
||||
*/
|
||||
virtual Evaluation formationVolumeFactor(int regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const = 0;
|
||||
virtual Scalar formationVolumeFactor(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const = 0;
|
||||
@ -58,6 +65,9 @@ public:
|
||||
/*!
|
||||
* \brief Returns the density [kg/m^3] of the fluid phase given a set of parameters.
|
||||
*/
|
||||
virtual Evaluation density(int regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const = 0;
|
||||
virtual Scalar density(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const = 0;
|
||||
@ -66,12 +76,112 @@ public:
|
||||
* \brief Returns the fugacity coefficient [Pa] of a component in the fluid phase given
|
||||
* a set of parameters.
|
||||
*/
|
||||
virtual Evaluation fugacityCoefficient(int regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure,
|
||||
int compIdx) const = 0;
|
||||
virtual Scalar fugacityCoefficient(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
int compIdx) const = 0;
|
||||
};
|
||||
|
||||
template <class Scalar>
|
||||
class WaterPvtInterface<Scalar, Scalar>
|
||||
{
|
||||
public:
|
||||
virtual Scalar viscosity(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const = 0;
|
||||
|
||||
virtual Scalar formationVolumeFactor(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const = 0;
|
||||
virtual Scalar density(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const = 0;
|
||||
virtual Scalar fugacityCoefficient(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
int compIdx) const = 0;
|
||||
};
|
||||
|
||||
template <class Scalar, class Evaluation, class Implementation>
|
||||
class WaterPvtInterfaceTemplateWrapper : public WaterPvtInterface<Scalar, Evaluation>
|
||||
{
|
||||
const Implementation& asImp_() const
|
||||
{ return *static_cast<const Implementation*>(this); }
|
||||
|
||||
public:
|
||||
Evaluation viscosity(int regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const OPM_FINAL
|
||||
{ return asImp_().viscosity_(regionIdx, temperature, pressure); }
|
||||
Scalar viscosity(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const OPM_FINAL
|
||||
{ return asImp_().viscosity_(regionIdx, temperature, pressure); }
|
||||
|
||||
Evaluation formationVolumeFactor(int regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const OPM_FINAL
|
||||
{ return asImp_().formationVolumeFactor_(regionIdx, temperature, pressure); }
|
||||
Scalar formationVolumeFactor(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const OPM_FINAL
|
||||
{ return asImp_().formationVolumeFactor_(regionIdx, temperature, pressure); }
|
||||
|
||||
Evaluation density(int regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const OPM_FINAL
|
||||
{ return asImp_().density_(regionIdx, temperature, pressure); }
|
||||
Scalar density(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const OPM_FINAL
|
||||
{ return asImp_().density_(regionIdx, temperature, pressure); }
|
||||
|
||||
Evaluation fugacityCoefficient(int regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure,
|
||||
int compIdx) const OPM_FINAL
|
||||
{ return asImp_().fugacityCoefficient_(regionIdx, temperature, pressure, compIdx); }
|
||||
Scalar fugacityCoefficient(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
int compIdx) const OPM_FINAL
|
||||
{ return asImp_().fugacityCoefficient_(regionIdx, temperature, pressure, compIdx); }
|
||||
};
|
||||
|
||||
template <class Scalar, class Implementation>
|
||||
class WaterPvtInterfaceTemplateWrapper<Scalar, Scalar, Implementation>
|
||||
: public WaterPvtInterface<Scalar, Scalar>
|
||||
{
|
||||
const Implementation& asImp_() const
|
||||
{ return *static_cast<const Implementation*>(this); }
|
||||
|
||||
public:
|
||||
Scalar viscosity(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const OPM_FINAL
|
||||
{ return asImp_().viscosity_(regionIdx, temperature, pressure); }
|
||||
|
||||
Scalar formationVolumeFactor(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const OPM_FINAL
|
||||
{ return asImp_().formationVolumeFactor_(regionIdx, temperature, pressure); }
|
||||
|
||||
Scalar density(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const OPM_FINAL
|
||||
{ return asImp_().density_(regionIdx, temperature, pressure); }
|
||||
|
||||
Scalar fugacityCoefficient(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
int compIdx) const OPM_FINAL
|
||||
{ return asImp_().fugacityCoefficient_(regionIdx, temperature, pressure, compIdx); }
|
||||
};
|
||||
|
||||
} // namespace Opm
|
||||
|
||||
#endif
|
||||
|
@ -35,15 +35,17 @@
|
||||
#endif
|
||||
|
||||
namespace Opm {
|
||||
|
||||
/*!
|
||||
* \brief This class represents the Pressure-Volume-Temperature relations of the gas phas
|
||||
* with vaporized oil.
|
||||
*/
|
||||
template <class Scalar>
|
||||
class WetGasPvt : public GasPvtInterface<Scalar>
|
||||
template <class Scalar, class Evaluation = Scalar>
|
||||
class WetGasPvt
|
||||
: public GasPvtInterfaceTemplateWrapper<Scalar, Evaluation, WetGasPvt<Scalar, Evaluation> >
|
||||
{
|
||||
typedef FluidSystems::BlackOil<Scalar> BlackOilFluidSystem;
|
||||
friend class GasPvtInterfaceTemplateWrapper<Scalar, Evaluation, WetGasPvt<Scalar, Evaluation> >;
|
||||
|
||||
typedef FluidSystems::BlackOil<Scalar, Evaluation> BlackOilFluidSystem;
|
||||
|
||||
typedef Opm::UniformXTabulated2DFunction<Scalar> TabulatedTwoDFunction;
|
||||
typedef Opm::Tabulated1DFunction<Scalar> TabulatedOneDFunction;
|
||||
@ -64,7 +66,7 @@ public:
|
||||
inverseGasB_.resize(numRegions);
|
||||
inverseGasBMu_.resize(numRegions);
|
||||
gasMu_.resize(numRegions);
|
||||
oilVaporizationFactor_.resize(numRegions);
|
||||
oilVaporizationFactorTable_.resize(numRegions);
|
||||
saturationPressureSpline_.resize(numRegions);
|
||||
}
|
||||
|
||||
@ -74,7 +76,7 @@ public:
|
||||
* \param samplePoints A container of (x,y) values.
|
||||
*/
|
||||
void setSaturatedGasOilVaporizationFactor(int regionIdx, const SamplingPoints &samplePoints)
|
||||
{ oilVaporizationFactor_[regionIdx].setContainerOfTuples(samplePoints); }
|
||||
{ oilVaporizationFactorTable_[regionIdx].setContainerOfTuples(samplePoints); }
|
||||
|
||||
/*!
|
||||
* \brief Initialize the function for the gas formation volume factor
|
||||
@ -89,12 +91,12 @@ public:
|
||||
{
|
||||
auto& invGasB = inverseGasB_[regionIdx];
|
||||
|
||||
auto &Rv = oilVaporizationFactor_[regionIdx];
|
||||
auto &Rv = oilVaporizationFactorTable_[regionIdx];
|
||||
|
||||
Scalar T = BlackOilFluidSystem::surfaceTemperature;
|
||||
|
||||
Scalar RvMin = 0.0;
|
||||
Scalar RvMax = Rv.eval(oilVaporizationFactor_[regionIdx].xMax(), /*extrapolate=*/true);
|
||||
Scalar RvMax = Rv.eval(oilVaporizationFactorTable_[regionIdx].xMax(), /*extrapolate=*/true);
|
||||
|
||||
Scalar poMin = samplePoints.front().first;
|
||||
Scalar poMax = samplePoints.back().first;
|
||||
@ -165,10 +167,10 @@ public:
|
||||
*/
|
||||
void setSaturatedGasViscosity(int regionIdx, const SamplingPoints &samplePoints )
|
||||
{
|
||||
auto& oilVaporizationFactor = oilVaporizationFactor_[regionIdx];
|
||||
auto& oilVaporizationFactor = oilVaporizationFactorTable_[regionIdx];
|
||||
|
||||
Scalar RvMin = 0.0;
|
||||
Scalar RvMax = oilVaporizationFactor.eval(oilVaporizationFactor_[regionIdx].xMax(), /*extrapolate=*/true);
|
||||
Scalar RvMax = oilVaporizationFactor.eval(oilVaporizationFactorTable_[regionIdx].xMax(), /*extrapolate=*/true);
|
||||
|
||||
Scalar poMin = samplePoints.front().first;
|
||||
Scalar poMax = samplePoints.back().first;
|
||||
@ -206,7 +208,7 @@ public:
|
||||
|
||||
auto& gasMu = gasMu_[regionIdx];
|
||||
auto& invGasB = inverseGasB_[regionIdx];
|
||||
auto& oilVaporizationFactor = oilVaporizationFactor_[regionIdx];
|
||||
auto& oilVaporizationFactor = oilVaporizationFactorTable_[regionIdx];
|
||||
|
||||
oilVaporizationFactor.setXYArrays(saturatedTable->numRows(),
|
||||
saturatedTable->getPressureColumn(),
|
||||
@ -326,21 +328,23 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
/*!
|
||||
* \brief Returns the dynamic viscosity [Pa s] of the fluid phase given a set of parameters.
|
||||
*/
|
||||
Scalar viscosity(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
Scalar XgO) const OPM_FINAL
|
||||
template <class LhsEval>
|
||||
LhsEval viscosity_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
const LhsEval& XgO) const
|
||||
{
|
||||
Scalar Rv =
|
||||
const LhsEval& Rv =
|
||||
XgO/(1 - XgO)
|
||||
* BlackOilFluidSystem::referenceDensity(oilPhaseIdx, regionIdx)
|
||||
/ BlackOilFluidSystem::referenceDensity(gasPhaseIdx, regionIdx);
|
||||
* (BlackOilFluidSystem::referenceDensity(oilPhaseIdx, regionIdx)
|
||||
/ BlackOilFluidSystem::referenceDensity(gasPhaseIdx, regionIdx));
|
||||
|
||||
Scalar invBg = inverseGasB_[regionIdx].eval(pressure, Rv, /*extrapolate=*/true);
|
||||
Scalar invMugBg = inverseGasBMu_[regionIdx].eval(pressure, Rv, /*extrapolate=*/true);
|
||||
const LhsEval& invBg = inverseGasB_[regionIdx].eval(pressure, Rv, /*extrapolate=*/true);
|
||||
const LhsEval& invMugBg = inverseGasBMu_[regionIdx].eval(pressure, Rv, /*extrapolate=*/true);
|
||||
|
||||
return invBg/invMugBg;
|
||||
}
|
||||
@ -348,22 +352,23 @@ public:
|
||||
/*!
|
||||
* \brief Returns the density [kg/m^3] of the fluid phase given a set of parameters.
|
||||
*/
|
||||
Scalar density(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
Scalar XgO) const OPM_FINAL
|
||||
template <class LhsEval>
|
||||
LhsEval density_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
const LhsEval& XgO) const
|
||||
{
|
||||
Scalar rhooRef = BlackOilFluidSystem::referenceDensity(oilPhaseIdx, regionIdx);
|
||||
Scalar rhogRef = BlackOilFluidSystem::referenceDensity(gasPhaseIdx, regionIdx);
|
||||
|
||||
Scalar Bg = formationVolumeFactor(regionIdx, temperature, pressure, XgO);
|
||||
Scalar rhoo = rhooRef/Bg;
|
||||
const LhsEval& Bg = formationVolumeFactor_(regionIdx, temperature, pressure, XgO);
|
||||
LhsEval rhoo = rhooRef/Bg;
|
||||
|
||||
// the oil formation volume factor just represents the partial density of the gas
|
||||
// component in the gas phase. to get the total density of the phase, we have to
|
||||
// add the partial density of the oil component.
|
||||
Scalar Rv = XgO/(1 - XgO) * rhooRef/rhogRef;
|
||||
rhoo += rhogRef*Rv/Bg;
|
||||
const LhsEval& Rv = XgO/(1 - XgO) * (rhooRef/rhogRef);
|
||||
rhoo += (rhogRef*Rv)/Bg;
|
||||
|
||||
return rhoo;
|
||||
}
|
||||
@ -371,12 +376,13 @@ public:
|
||||
/*!
|
||||
* \brief Returns the formation volume factor [-] of the fluid phase.
|
||||
*/
|
||||
Scalar formationVolumeFactor(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
Scalar XgO) const OPM_FINAL
|
||||
template <class LhsEval>
|
||||
LhsEval formationVolumeFactor_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
const LhsEval& XgO) const
|
||||
{
|
||||
Scalar Rv =
|
||||
const LhsEval& Rv =
|
||||
XgO/(1-XgO)
|
||||
*BlackOilFluidSystem::referenceDensity(oilPhaseIdx, regionIdx)
|
||||
/BlackOilFluidSystem::referenceDensity(gasPhaseIdx, regionIdx);
|
||||
@ -388,15 +394,18 @@ public:
|
||||
* \brief Returns the fugacity coefficient [Pa] of a component in the fluid phase given
|
||||
* a set of parameters.
|
||||
*/
|
||||
Scalar fugacityCoefficient(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure,
|
||||
int compIdx) const OPM_FINAL
|
||||
template <class LhsEval>
|
||||
LhsEval fugacityCoefficient_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
int compIdx) const
|
||||
{
|
||||
typedef Opm::MathToolbox<LhsEval> Toolbox;
|
||||
|
||||
// set the oil component fugacity coefficient in oil phase
|
||||
// arbitrarily. we use some pseudo-realistic value for the vapor
|
||||
// pressure to ease physical interpretation of the results
|
||||
Scalar phi_gG = 1.0;
|
||||
LhsEval phi_gG = Toolbox::createConstant(1.0);
|
||||
|
||||
if (compIdx == BlackOilFluidSystem::gasCompIdx)
|
||||
return phi_gG;
|
||||
@ -411,27 +420,27 @@ public:
|
||||
//
|
||||
// first, retrieve the mole fraction of gas a saturated oil
|
||||
// would exhibit at the given pressure
|
||||
Scalar x_gOSat = saturatedGasOilMoleFraction(regionIdx, temperature, pressure);
|
||||
const LhsEval& x_gOSat = saturatedGasOilMoleFraction_(regionIdx, temperature, pressure);
|
||||
|
||||
// then, scale the oil component's gas phase fugacity
|
||||
// coefficient, so that the oil phase ends up at the right
|
||||
// composition if we were doing a flash experiment
|
||||
Scalar phi_oO = BlackOilFluidSystem::fugCoefficientInOil(oilCompIdx,
|
||||
const LhsEval& phi_oO = BlackOilFluidSystem::fugCoefficientInOil(oilCompIdx,
|
||||
temperature,
|
||||
pressure,
|
||||
regionIdx);
|
||||
|
||||
|
||||
return phi_oO / x_gOSat;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the gas dissolution factor \f$R_s\f$ [m^3/m^3] of the oil phase.
|
||||
*/
|
||||
Scalar oilVaporizationFactor(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const OPM_FINAL
|
||||
{ return oilVaporizationFactor_[regionIdx].eval(pressure, /*extrapolate=*/true); }
|
||||
template <class LhsEval>
|
||||
LhsEval oilVaporizationFactor_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure) const
|
||||
{ return oilVaporizationFactorTable_[regionIdx].eval(pressure, /*extrapolate=*/true); }
|
||||
|
||||
/*!
|
||||
* \brief Returns the saturation pressure of the gas phase [Pa]
|
||||
@ -439,34 +448,38 @@ public:
|
||||
*
|
||||
* \param XgO The mass fraction of the oil component in the gas phase [-]
|
||||
*/
|
||||
Scalar gasSaturationPressure(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar XgO) const OPM_FINAL
|
||||
template <class LhsEval>
|
||||
LhsEval gasSaturationPressure_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& XgO) const
|
||||
{
|
||||
typedef Opm::MathToolbox<LhsEval> Toolbox;
|
||||
|
||||
// use the saturation pressure spline to get a pretty good initial value
|
||||
Scalar pSat = saturationPressureSpline_[regionIdx].eval(XgO, /*extrapolate=*/true);
|
||||
LhsEval pSat = saturationPressureSpline_[regionIdx].eval(XgO, /*extrapolate=*/true);
|
||||
const LhsEval& eps = pSat*1e-11;
|
||||
|
||||
// Newton method to do the remaining work. If the initial
|
||||
// value is good, this should only take two to three
|
||||
// iterations...
|
||||
for (int i = 0; i < 20; ++i) {
|
||||
Scalar f = saturatedGasOilMassFraction(regionIdx, temperature, pSat) - XgO;
|
||||
Scalar eps = pSat*1e-11;
|
||||
Scalar fPrime = ((saturatedGasOilMassFraction(regionIdx, temperature, pSat + eps) - XgO) - f)/eps;
|
||||
const LhsEval& f = saturatedGasOilMassFraction_(regionIdx, temperature, pSat) - XgO;
|
||||
const LhsEval& fPrime = ((saturatedGasOilMassFraction_(regionIdx, temperature, pSat + eps) - XgO) - f)/eps;
|
||||
|
||||
Scalar delta = f/fPrime;
|
||||
const LhsEval& delta = f/fPrime;
|
||||
pSat -= delta;
|
||||
|
||||
if (std::abs(delta) < pSat * 1e-10)
|
||||
if (std::abs(Toolbox::value(delta)) < std::abs(Toolbox::value(pSat)) * 1e-10)
|
||||
return pSat;
|
||||
}
|
||||
|
||||
OPM_THROW(NumericalIssue, "Could find the gas saturation pressure for X_g^O = " << XgO);
|
||||
}
|
||||
|
||||
Scalar saturatedGasOilMassFraction(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const OPM_FINAL
|
||||
template <class LhsEval>
|
||||
LhsEval saturatedGasOilMassFraction_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure) const
|
||||
{
|
||||
Scalar rho_gRef = BlackOilFluidSystem::referenceDensity(gasPhaseIdx, regionIdx);
|
||||
Scalar rho_oRef = BlackOilFluidSystem::referenceDensity(oilPhaseIdx, regionIdx);
|
||||
@ -474,27 +487,28 @@ public:
|
||||
// calculate the mass of the oil component [kg/m^3] in the oil phase. This is
|
||||
// equivalent to the gas dissolution factor [m^3/m^3] at current pressure times
|
||||
// the gas density [kg/m^3] at standard pressure
|
||||
Scalar rho_oG = oilVaporizationFactor(regionIdx, temperature, pressure) * rho_gRef;
|
||||
const LhsEval& rho_oG = oilVaporizationFactor_(regionIdx, temperature, pressure) * rho_gRef;
|
||||
|
||||
// we now have the total density of saturated oil and the partial density of the
|
||||
// oil component within it. The gas mass fraction is the ratio of these two.
|
||||
return rho_oG/(rho_oRef + rho_oG);
|
||||
}
|
||||
|
||||
Scalar saturatedGasOilMoleFraction(int regionIdx,
|
||||
Scalar temperature,
|
||||
Scalar pressure) const OPM_FINAL
|
||||
template <class LhsEval>
|
||||
LhsEval saturatedGasOilMoleFraction_(int regionIdx,
|
||||
const LhsEval& temperature,
|
||||
const LhsEval& pressure) const
|
||||
{
|
||||
// calculate the mass fractions of gas and oil
|
||||
Scalar XgO = saturatedGasOilMassFraction(regionIdx, temperature, pressure);
|
||||
const LhsEval& XgO = saturatedGasOilMassFraction_(regionIdx, temperature, pressure);
|
||||
|
||||
// which can be converted to mole fractions, given the
|
||||
// components' molar masses
|
||||
Scalar MG = BlackOilFluidSystem::molarMass(gasCompIdx, regionIdx);
|
||||
Scalar MO = BlackOilFluidSystem::molarMass(oilCompIdx, regionIdx);
|
||||
|
||||
Scalar avgMolarMass = MO/(1 + (1 - XgO)*(MO/MG - 1));
|
||||
Scalar xgO = XgO*avgMolarMass/MG;
|
||||
const LhsEval& avgMolarMass = MO/(1 + (1 - XgO)*(MO/MG - 1));
|
||||
const LhsEval& xgO = XgO*avgMolarMass/MG;
|
||||
|
||||
return xgO;
|
||||
}
|
||||
@ -502,7 +516,7 @@ public:
|
||||
private:
|
||||
void updateSaturationPressureSpline_(int regionIdx)
|
||||
{
|
||||
auto& oilVaporizationFactor = oilVaporizationFactor_[regionIdx];
|
||||
auto& oilVaporizationFactor = oilVaporizationFactorTable_[regionIdx];
|
||||
|
||||
// create the spline representing saturation pressure
|
||||
// depending of the mass fraction in gas
|
||||
@ -513,7 +527,7 @@ private:
|
||||
Scalar XgO = 0;
|
||||
for (int i=0; i <= n; ++ i) {
|
||||
Scalar pSat = oilVaporizationFactor.xMin() + i*delta;
|
||||
XgO = saturatedGasOilMassFraction(regionIdx, /*temperature=*/1e100, pSat);
|
||||
XgO = saturatedGasOilMassFraction_(regionIdx, /*temperature=*/Scalar(1e100), pSat);
|
||||
|
||||
std::pair<Scalar, Scalar> val(XgO, pSat);
|
||||
pSatSamplePoints.push_back(val);
|
||||
@ -525,7 +539,7 @@ private:
|
||||
std::vector<TabulatedTwoDFunction> inverseGasB_;
|
||||
std::vector<TabulatedTwoDFunction> gasMu_;
|
||||
std::vector<TabulatedTwoDFunction> inverseGasBMu_;
|
||||
std::vector<TabulatedOneDFunction> oilVaporizationFactor_;
|
||||
std::vector<TabulatedOneDFunction> oilVaporizationFactorTable_;
|
||||
std::vector<Spline> saturationPressureSpline_;
|
||||
};
|
||||
|
||||
|
@ -253,7 +253,7 @@ void checkFluidState(const BaseFluidState &fs)
|
||||
/*!
|
||||
* \brief Checks whether a fluid system adheres to the specification.
|
||||
*/
|
||||
template <class Scalar, class FluidSystem>
|
||||
template <class Scalar, class FluidSystem, class RhsEval, class LhsEval>
|
||||
void checkFluidSystem()
|
||||
{
|
||||
std::cout << "Testing fluid system '" << Opm::className<FluidSystem>() << "'\n";
|
||||
@ -263,7 +263,8 @@ void checkFluidSystem()
|
||||
enum { numPhases = FluidSystem::numPhases };
|
||||
enum { numComponents = FluidSystem::numComponents };
|
||||
|
||||
HairSplittingFluidState<Scalar, FluidSystem> fs;
|
||||
typedef HairSplittingFluidState<RhsEval, FluidSystem> FluidState;
|
||||
FluidState fs;
|
||||
fs.allowTemperature(true);
|
||||
fs.allowPressure(true);
|
||||
fs.allowComposition(true);
|
||||
@ -290,7 +291,8 @@ void checkFluidSystem()
|
||||
|
||||
// some value to make sure the return values of the fluid system
|
||||
// are convertible to scalars
|
||||
Scalar OPM_UNUSED val;
|
||||
LhsEval OPM_UNUSED val;
|
||||
Scalar OPM_UNUSED scalarVal;
|
||||
|
||||
// actually check the fluid system API
|
||||
try { FluidSystem::init(); } catch (...) {};
|
||||
@ -299,22 +301,35 @@ void checkFluidSystem()
|
||||
fs.allowPressure(FluidSystem::isCompressible(phaseIdx));
|
||||
fs.allowComposition(true);
|
||||
fs.allowDensity(false);
|
||||
try { val = FluidSystem::density(fs, paramCache, phaseIdx); } catch (...) {};
|
||||
try { auto OPM_UNUSED tmpVal = FluidSystem::density(fs, paramCache, phaseIdx); static_assert(std::is_same<decltype(tmpVal), RhsEval>::value, "The default return value must be the scalar used by the fluid state!"); } catch (...) {};
|
||||
try { val = FluidSystem::template density<FluidState, LhsEval>(fs, paramCache, phaseIdx); } catch (...) {};
|
||||
try { scalarVal = FluidSystem::template density<FluidState, Scalar>(fs, paramCache, phaseIdx); } catch (...) {};
|
||||
|
||||
fs.allowPressure(true);
|
||||
fs.allowDensity(true);
|
||||
try { val = FluidSystem::viscosity(fs, paramCache, phaseIdx); } catch (...) {};
|
||||
try { val = FluidSystem::enthalpy(fs, paramCache, phaseIdx); } catch (...) {};
|
||||
try { val = FluidSystem::heatCapacity(fs, paramCache, phaseIdx); } catch (...) {};
|
||||
try { val = FluidSystem::thermalConductivity(fs, paramCache, phaseIdx); } catch (...) {};
|
||||
try { auto OPM_UNUSED tmpVal = FluidSystem::viscosity(fs, paramCache, phaseIdx); static_assert(std::is_same<decltype(tmpVal), RhsEval>::value, "The default return value must be the scalar used by the fluid state!"); } catch (...) {};
|
||||
try { auto OPM_UNUSED tmpVal = FluidSystem::enthalpy(fs, paramCache, phaseIdx); static_assert(std::is_same<decltype(tmpVal), RhsEval>::value, "The default return value must be the scalar used by the fluid state!"); } catch (...) {};
|
||||
try { auto OPM_UNUSED tmpVal = FluidSystem::heatCapacity(fs, paramCache, phaseIdx); static_assert(std::is_same<decltype(tmpVal), RhsEval>::value, "The default return value must be the scalar used by the fluid state!"); } catch (...) {};
|
||||
try { auto OPM_UNUSED tmpVal = FluidSystem::thermalConductivity(fs, paramCache, phaseIdx); static_assert(std::is_same<decltype(tmpVal), RhsEval>::value, "The default return value must be the scalar used by the fluid state!"); } catch (...) {};
|
||||
try { val = FluidSystem::template viscosity<FluidState, LhsEval>(fs, paramCache, phaseIdx); } catch (...) {};
|
||||
try { val = FluidSystem::template enthalpy<FluidState, LhsEval>(fs, paramCache, phaseIdx); } catch (...) {};
|
||||
try { val = FluidSystem::template heatCapacity<FluidState, LhsEval>(fs, paramCache, phaseIdx); } catch (...) {};
|
||||
try { val = FluidSystem::template thermalConductivity<FluidState, LhsEval>(fs, paramCache, phaseIdx); } catch (...) {};
|
||||
try { scalarVal = FluidSystem::template viscosity<FluidState, Scalar>(fs, paramCache, phaseIdx); } catch (...) {};
|
||||
try { scalarVal = FluidSystem::template enthalpy<FluidState, Scalar>(fs, paramCache, phaseIdx); } catch (...) {};
|
||||
try { scalarVal = FluidSystem::template heatCapacity<FluidState, Scalar>(fs, paramCache, phaseIdx); } catch (...) {};
|
||||
try { scalarVal = FluidSystem::template thermalConductivity<FluidState, Scalar>(fs, paramCache, phaseIdx); } catch (...) {};
|
||||
|
||||
for (int compIdx = 0; compIdx < numComponents; ++ compIdx) {
|
||||
fs.allowComposition(!FluidSystem::isIdealMixture(phaseIdx));
|
||||
try { val = FluidSystem::fugacityCoefficient(fs, paramCache, phaseIdx, compIdx); } catch (...) {};
|
||||
try { auto OPM_UNUSED tmpVal = FluidSystem::fugacityCoefficient(fs, paramCache, phaseIdx, compIdx); static_assert(std::is_same<decltype(tmpVal), RhsEval>::value, "The default return value must be the scalar used by the fluid state!"); } catch (...) {};
|
||||
try { val = FluidSystem::template fugacityCoefficient<FluidState, LhsEval>(fs, paramCache, phaseIdx, compIdx); } catch (...) {};
|
||||
try { scalarVal = FluidSystem::template fugacityCoefficient<FluidState, Scalar>(fs, paramCache, phaseIdx, compIdx); } catch (...) {};
|
||||
fs.allowComposition(true);
|
||||
try { val = FluidSystem::diffusionCoefficient(fs, paramCache, phaseIdx, compIdx); } catch (...) {};
|
||||
try { auto OPM_UNUSED tmpVal = FluidSystem::diffusionCoefficient(fs, paramCache, phaseIdx, compIdx); static_assert(std::is_same<decltype(tmpVal), RhsEval>::value, "The default return value must be the scalar used by the fluid state!"); } catch (...) {};
|
||||
try { val = FluidSystem::template diffusionCoefficient<FluidState, LhsEval>(fs, paramCache, phaseIdx, compIdx); } catch (...) {};
|
||||
try { scalarVal = FluidSystem::template fugacityCoefficient<FluidState, Scalar>(fs, paramCache, phaseIdx, compIdx); } catch (...) {};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// test for phaseName(), isLiquid() and isIdealGas()
|
||||
@ -324,7 +339,7 @@ void checkFluidSystem()
|
||||
bVal = FluidSystem::isIdealGas(phaseIdx);
|
||||
}
|
||||
|
||||
// test for componentName()
|
||||
// test for molarMass() and componentName()
|
||||
for (int compIdx = 0; compIdx < numComponents; ++ compIdx) {
|
||||
val = FluidSystem::molarMass(compIdx);
|
||||
std::string OPM_UNUSED name = FluidSystem::componentName(compIdx);
|
||||
|
@ -24,6 +24,9 @@
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <opm/material/localad/Evaluation.hpp>
|
||||
#include <opm/material/localad/Math.hpp>
|
||||
|
||||
#include "checkFluidSystem.hpp"
|
||||
|
||||
// include all fluid systems in opm-material
|
||||
@ -45,8 +48,7 @@
|
||||
#include <opm/material/fluidstates/NonEquilibriumFluidState.hpp>
|
||||
#include <opm/material/fluidstates/ImmiscibleFluidState.hpp>
|
||||
|
||||
// include the tables for CO2 which are delivered with opm-material by
|
||||
// default
|
||||
// include the tables for CO2 which are delivered with opm-material by default
|
||||
#include <opm/material/common/UniformTabulated2DFunction.hpp>
|
||||
|
||||
namespace Opm {
|
||||
@ -77,19 +79,10 @@ public:
|
||||
};
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
// check the API of all fluid states
|
||||
template <class Scalar>
|
||||
void testAllFluidStates()
|
||||
{
|
||||
typedef double Scalar;
|
||||
typedef Opm::H2O<Scalar> H2O;
|
||||
typedef Opm::N2<Scalar> N2;
|
||||
|
||||
typedef Opm::LiquidPhase<Scalar, H2O> Liquid;
|
||||
typedef Opm::GasPhase<Scalar, N2> Gas;
|
||||
|
||||
MyMpiHelper mpiHelper(argc, argv);
|
||||
|
||||
// check all fluid states
|
||||
{
|
||||
typedef Opm::FluidSystems::H2ON2<Scalar, /*enableComplexRelations=*/false> FluidSystem;
|
||||
|
||||
// CompositionalFluidState
|
||||
@ -118,75 +111,105 @@ int main(int argc, char **argv)
|
||||
// SaturationOverlayFluidState
|
||||
{ Opm::SaturationOverlayFluidState<BaseFluidState> fs(baseFs);
|
||||
checkFluidState<Scalar>(fs); }
|
||||
}
|
||||
}
|
||||
|
||||
template <class Scalar, class Evaluation, class LhsEval = Evaluation>
|
||||
void testAllFluidSystems()
|
||||
{
|
||||
typedef Opm::H2O<Scalar> H2O;
|
||||
typedef Opm::N2<Scalar> N2;
|
||||
|
||||
typedef Opm::LiquidPhase<Scalar, H2O> Liquid;
|
||||
typedef Opm::GasPhase<Scalar, N2> Gas;
|
||||
|
||||
// black-oil
|
||||
{ typedef Opm::FluidSystems::BlackOil<Scalar> FluidSystem;
|
||||
if (false) checkFluidSystem<Scalar, FluidSystem>(); }
|
||||
{ typedef Opm::FluidSystems::BlackOil<Scalar, Evaluation> FluidSystem;
|
||||
if (false) checkFluidSystem<Scalar, FluidSystem, Evaluation, LhsEval>(); }
|
||||
|
||||
// Brine -- CO2
|
||||
{ typedef Opm::FluidSystems::BrineCO2<Scalar, Opm::FluidSystemsTest::CO2Tables> FluidSystem;
|
||||
checkFluidSystem<Scalar, FluidSystem>(); }
|
||||
checkFluidSystem<Scalar, FluidSystem, Evaluation, LhsEval>(); }
|
||||
|
||||
// H2O -- N2
|
||||
{ typedef Opm::FluidSystems::H2ON2<Scalar, /*enableComplexRelations=*/false> FluidSystem;
|
||||
checkFluidSystem<Scalar, FluidSystem>(); }
|
||||
checkFluidSystem<Scalar, FluidSystem, Evaluation, LhsEval>(); }
|
||||
|
||||
{ typedef Opm::FluidSystems::H2ON2<Scalar, /*enableComplexRelations=*/true> FluidSystem;
|
||||
checkFluidSystem<Scalar, FluidSystem>(); }
|
||||
checkFluidSystem<Scalar, FluidSystem, Evaluation, LhsEval>(); }
|
||||
|
||||
// H2O -- N2 -- liquid phase
|
||||
{ typedef Opm::FluidSystems::H2ON2LiquidPhase<Scalar, /*enableComplexRelations=*/false> FluidSystem;
|
||||
checkFluidSystem<Scalar, FluidSystem>(); }
|
||||
checkFluidSystem<Scalar, FluidSystem, Evaluation, LhsEval>(); }
|
||||
|
||||
{ typedef Opm::FluidSystems::H2ON2LiquidPhase<Scalar, /*enableComplexRelations=*/true> FluidSystem;
|
||||
checkFluidSystem<Scalar, FluidSystem>(); }
|
||||
checkFluidSystem<Scalar, FluidSystem, Evaluation, LhsEval>(); }
|
||||
|
||||
// H2O -- Air
|
||||
{ typedef Opm::SimpleH2O<Scalar> H2O;
|
||||
const bool enableComplexRelations=false;
|
||||
typedef Opm::FluidSystems::H2OAir<Scalar, H2O, enableComplexRelations> FluidSystem;
|
||||
checkFluidSystem<Scalar, FluidSystem>(); }
|
||||
checkFluidSystem<Scalar, FluidSystem, Evaluation, LhsEval>(); }
|
||||
|
||||
{ typedef Opm::SimpleH2O<Scalar> H2O;
|
||||
const bool enableComplexRelations=true;
|
||||
typedef Opm::FluidSystems::H2OAir<Scalar, H2O, enableComplexRelations> FluidSystem;
|
||||
checkFluidSystem<Scalar, FluidSystem>(); }
|
||||
checkFluidSystem<Scalar, FluidSystem, Evaluation, LhsEval>(); }
|
||||
|
||||
{ typedef Opm::H2O<Scalar> H2O;
|
||||
const bool enableComplexRelations=false;
|
||||
typedef Opm::FluidSystems::H2OAir<Scalar, H2O, enableComplexRelations> FluidSystem;
|
||||
checkFluidSystem<Scalar, FluidSystem>(); }
|
||||
checkFluidSystem<Scalar, FluidSystem, Evaluation, LhsEval>(); }
|
||||
|
||||
{ typedef Opm::H2O<Scalar> H2O;
|
||||
const bool enableComplexRelations=true;
|
||||
typedef Opm::FluidSystems::H2OAir<Scalar, H2O, enableComplexRelations> FluidSystem;
|
||||
checkFluidSystem<Scalar, FluidSystem>(); }
|
||||
checkFluidSystem<Scalar, FluidSystem, Evaluation, LhsEval>(); }
|
||||
|
||||
// H2O -- Air -- Mesitylene
|
||||
{ typedef Opm::FluidSystems::H2OAirMesitylene<Scalar> FluidSystem;
|
||||
checkFluidSystem<Scalar, FluidSystem>(); }
|
||||
checkFluidSystem<Scalar, FluidSystem, Evaluation, LhsEval>(); }
|
||||
|
||||
// H2O -- Air -- Xylene
|
||||
{ typedef Opm::FluidSystems::H2OAirXylene<Scalar> FluidSystem;
|
||||
checkFluidSystem<Scalar, FluidSystem>(); }
|
||||
checkFluidSystem<Scalar, FluidSystem, Evaluation, LhsEval>(); }
|
||||
|
||||
// 2p-immiscible
|
||||
{ typedef Opm::FluidSystems::TwoPhaseImmiscible<Scalar, Liquid, Liquid> FluidSystem;
|
||||
checkFluidSystem<Scalar, FluidSystem>(); }
|
||||
checkFluidSystem<Scalar, FluidSystem, Evaluation, LhsEval>(); }
|
||||
|
||||
{ typedef Opm::FluidSystems::TwoPhaseImmiscible<Scalar, Liquid, Gas> FluidSystem;
|
||||
checkFluidSystem<Scalar, FluidSystem>(); }
|
||||
checkFluidSystem<Scalar, FluidSystem, Evaluation, LhsEval>(); }
|
||||
|
||||
{ typedef Opm::FluidSystems::TwoPhaseImmiscible<Scalar, Gas, Liquid> FluidSystem;
|
||||
checkFluidSystem<Scalar, FluidSystem>(); }
|
||||
checkFluidSystem<Scalar, FluidSystem, Evaluation, LhsEval>(); }
|
||||
|
||||
// 1p
|
||||
{ typedef Opm::FluidSystems::SinglePhase<Scalar, Liquid> FluidSystem;
|
||||
checkFluidSystem<Scalar, FluidSystem>(); }
|
||||
checkFluidSystem<Scalar, FluidSystem, Evaluation, LhsEval>(); }
|
||||
|
||||
{ typedef Opm::FluidSystems::SinglePhase<Scalar, Gas> FluidSystem;
|
||||
checkFluidSystem<Scalar, FluidSystem>(); }
|
||||
checkFluidSystem<Scalar, FluidSystem, Evaluation, LhsEval>(); }
|
||||
}
|
||||
|
||||
class TestAdTag;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
typedef double Scalar;
|
||||
typedef Opm::LocalAd::Evaluation<Scalar, TestAdTag, 3> Evaluation;
|
||||
|
||||
MyMpiHelper mpiHelper(argc, argv);
|
||||
|
||||
// ensure that all fluid states are API-compliant
|
||||
testAllFluidStates<Scalar>();
|
||||
testAllFluidStates<Evaluation>();
|
||||
|
||||
// ensure that all fluid systems are API-compliant: Each fluid system must be usable
|
||||
// for both, scalars and function evaluations. The fluid systems for function
|
||||
// evaluations must also be usable for scalars.
|
||||
testAllFluidSystems<Scalar, Scalar>();
|
||||
testAllFluidSystems<Scalar, Evaluation>();
|
||||
testAllFluidSystems<Scalar, Evaluation, Scalar>();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user