blackoil: introduce saturated{Oil,Gas}{Density,Viscosity}() methods and use them in the fluid system
this eliminates minor differences with the current opm-core PVT classes which were due to extrapolation of the untersaturated tables. (Also, the result should be slightly faster if both, oil and gas are present.) I'm not really sure if this is always a good thing, though: It implies discontinuities at the saturated <-> undersaturated transition which may sometimes deter convergence rates of the non-linear solver.
This commit is contained in:
parent
b7b1d91c94
commit
126375db7d
@ -313,12 +313,22 @@ public:
|
||||
switch (phaseIdx) {
|
||||
case waterPhaseIdx: return waterDensity<LhsEval>(T, p, regionIdx);
|
||||
case gasPhaseIdx: {
|
||||
const auto& Rv = getRv_<LhsEval>(fluidState, regionIdx);
|
||||
return gasDensity<LhsEval>(T, p, Rv, regionIdx);
|
||||
if (fluidState.saturation(oilPhaseIdx) > 0.0)
|
||||
return gasPvt_->saturatedDensity(regionIdx, T, p);
|
||||
else {
|
||||
// undersaturated oil
|
||||
const auto& Rv = getRv_<LhsEval>(fluidState, regionIdx);
|
||||
return gasPvt_->density(regionIdx, T, p, Rv);
|
||||
}
|
||||
}
|
||||
case oilPhaseIdx: {
|
||||
const auto& Rs = getRs_<LhsEval>(fluidState, regionIdx);
|
||||
return oilDensity<LhsEval>(T, p, Rs, regionIdx);
|
||||
if (fluidState.saturation(gasPhaseIdx) > 0.0)
|
||||
return oilPvt_->saturatedDensity(regionIdx, T, p);
|
||||
else {
|
||||
// undersaturated gas
|
||||
const auto& Rs = getRs_<LhsEval>(fluidState, regionIdx);
|
||||
return oilPvt_->density(regionIdx, T, p, Rs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -366,14 +376,24 @@ public:
|
||||
|
||||
switch (phaseIdx) {
|
||||
case oilPhaseIdx: {
|
||||
const auto& Rs = getRs_<LhsEval>(fluidState, regionIdx);
|
||||
return oilPvt_->viscosity(regionIdx, T, p, Rs);
|
||||
if (fluidState.saturation(gasPhaseIdx) > 0.0)
|
||||
return oilPvt_->saturatedViscosity(regionIdx, T, p);
|
||||
else {
|
||||
// undersaturated oil
|
||||
const auto& Rs = getRs_<LhsEval>(fluidState, regionIdx);
|
||||
return oilPvt_->viscosity(regionIdx, T, p, Rs);
|
||||
}
|
||||
}
|
||||
case waterPhaseIdx:
|
||||
return waterPvt_->viscosity(regionIdx, T, p);
|
||||
case gasPhaseIdx: {
|
||||
const auto& Rv = getRv_<LhsEval>(fluidState, regionIdx);
|
||||
return gasPvt_->viscosity(regionIdx, T, p, Rv);
|
||||
if (fluidState.saturation(oilPhaseIdx) > 0.0)
|
||||
return gasPvt_->saturatedViscosity(regionIdx, T, p);
|
||||
else {
|
||||
// undersaturated gas
|
||||
const auto& Rv = getRv_<LhsEval>(fluidState, regionIdx);
|
||||
return gasPvt_->viscosity(regionIdx, T, p, Rv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -415,14 +435,18 @@ public:
|
||||
static LhsEval saturatedOilFormationVolumeFactor(const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
unsigned regionIdx)
|
||||
{
|
||||
Valgrind::CheckDefined(pressure);
|
||||
{ return oilPvt_->saturatedFormationVolumeFactor(regionIdx, temperature, pressure); }
|
||||
|
||||
// calculate the mass fractions of gas and oil
|
||||
const auto& Rs = gasDissolutionFactor(temperature, pressure, regionIdx);
|
||||
|
||||
return oilFormationVolumeFactor(temperature, pressure, Rs, regionIdx);
|
||||
}
|
||||
/*!
|
||||
* \brief Returns the gas formation volume factor \f$B_o\f$ of saturated gas for a given pressure
|
||||
*
|
||||
* \param pressure The pressure of interest [Pa]
|
||||
*/
|
||||
template <class LhsEval>
|
||||
static LhsEval saturatedGasFormationVolumeFactor(const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
unsigned regionIdx)
|
||||
{ return gasPvt_->saturatedFormationVolumeFactor(regionIdx, temperature, pressure); }
|
||||
|
||||
/*!
|
||||
* \brief Return the formation volume factor of water.
|
||||
@ -558,7 +582,7 @@ public:
|
||||
static LhsEval saturatedOilGasMassFraction(const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
unsigned regionIdx)
|
||||
{ return oilPvt_->saturatedOilGasMassFraction(regionIdx, temperature, pressure); }
|
||||
{ return oilPvt_->saturatedGasMassFraction(regionIdx, temperature, pressure); }
|
||||
|
||||
/*!
|
||||
* \brief The maximum mole fraction of the gas component in the oil phase.
|
||||
@ -567,7 +591,7 @@ public:
|
||||
static LhsEval saturatedOilGasMoleFraction(const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
unsigned regionIdx)
|
||||
{ return oilPvt_->saturatedOilGasMoleFraction(regionIdx, temperature, pressure); }
|
||||
{ return oilPvt_->saturatedGasMoleFraction(regionIdx, temperature, pressure); }
|
||||
|
||||
/*!
|
||||
* \brief Returns the saturation pressure of the oil phase [Pa] depending on its mass
|
||||
@ -588,7 +612,7 @@ public:
|
||||
static LhsEval saturatedGasOilMassFraction(const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
unsigned regionIdx)
|
||||
{ return gasPvt_->saturatedGasOilMassFraction(regionIdx, temperature, pressure); }
|
||||
{ return gasPvt_->saturatedOilMassFraction(regionIdx, temperature, pressure); }
|
||||
|
||||
/*!
|
||||
* \brief The maximum mole fraction of the oil component in the gas phase.
|
||||
@ -597,7 +621,7 @@ public:
|
||||
static LhsEval saturatedGasOilMoleFraction(const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
unsigned regionIdx)
|
||||
{ return gasPvt_->saturatedGasOilMoleFraction(regionIdx, temperature, pressure); }
|
||||
{ return gasPvt_->saturatedOilMoleFraction(regionIdx, temperature, pressure); }
|
||||
|
||||
/*!
|
||||
* \brief Return the normalized formation volume factor of (potentially)
|
||||
@ -627,11 +651,7 @@ public:
|
||||
static LhsEval saturatedOilDensity(const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
unsigned regionIdx)
|
||||
{
|
||||
// mass fraction of gas-saturated oil
|
||||
const LhsEval& Rs = gasDissolutionFactor(temperature, pressure, regionIdx);
|
||||
return oilPvt_->density(regionIdx, temperature, pressure, Rs);
|
||||
}
|
||||
{ return oilPvt_->saturatedOilDensity(regionIdx, temperature, pressure); }
|
||||
|
||||
/*!
|
||||
* \brief Return the formation volume factor of gas.
|
||||
@ -653,6 +673,15 @@ public:
|
||||
unsigned regionIdx)
|
||||
{ return gasPvt_->density(regionIdx, temperature, pressure, Rv); }
|
||||
|
||||
/*!
|
||||
* \brief Return the density of gas-saturated oil.
|
||||
*/
|
||||
template <class LhsEval>
|
||||
static LhsEval saturatedGasDensity(const LhsEval& temperature,
|
||||
const LhsEval& pressure,
|
||||
unsigned regionIdx)
|
||||
{ return oilPvt_->saturatedGasDensity(regionIdx, temperature, pressure); }
|
||||
|
||||
/*!
|
||||
* \brief Return the density of water.
|
||||
*/
|
||||
|
@ -113,9 +113,7 @@ public:
|
||||
Scalar rhoRefOil,
|
||||
Scalar /*rhoRefGas*/,
|
||||
Scalar /*rhoRefWater*/)
|
||||
{
|
||||
oilReferenceDensity_[regionIdx] = rhoRefOil;
|
||||
}
|
||||
{ oilReferenceDensity_[regionIdx] = rhoRefOil; }
|
||||
|
||||
/*!
|
||||
* \brief Initialize the reference densities of all fluids for a given PVT region
|
||||
@ -165,20 +163,26 @@ public:
|
||||
void initEnd(const GasPvtMultiplexer */*gasPvt*/)
|
||||
{ }
|
||||
|
||||
/*!
|
||||
* \brief Returns the dynamic viscosity [Pa s] of the fluid phase given a set of parameters.
|
||||
*/
|
||||
template <class Evaluation>
|
||||
Evaluation viscosity(unsigned regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure,
|
||||
const Evaluation& Rs) const
|
||||
const Evaluation& /*Rs*/) const
|
||||
{ return saturatedViscosity(regionIdx, temperature, pressure); }
|
||||
|
||||
/*!
|
||||
* \brief Returns the dynamic viscosity [Pa s] of gas saturated oil given a pressure.
|
||||
*/
|
||||
template <class Evaluation>
|
||||
Evaluation saturatedViscosity(unsigned regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& 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 BoMuoRef = oilViscosity_[regionIdx]*oilReferenceFormationVolumeFactor_[regionIdx];
|
||||
const Evaluation& Bo = formationVolumeFactor(regionIdx, temperature, pressure, Rs);
|
||||
const Evaluation& Bo = saturatedFormationVolumeFactor(regionIdx, temperature, pressure);
|
||||
|
||||
Scalar pRef = oilReferencePressure_[regionIdx];
|
||||
const Evaluation& Y =
|
||||
@ -191,13 +195,23 @@ public:
|
||||
* \brief Returns the density [kg/m^3] of the fluid phase given a set of parameters.
|
||||
*/
|
||||
template <class Evaluation>
|
||||
Evaluation density(unsigned regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure,
|
||||
const Evaluation& Rs) const
|
||||
Evaluation density(unsigned regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure,
|
||||
const Evaluation& /*Rs*/) const
|
||||
{ return saturatedDensity(regionIdx, temperature, pressure); }
|
||||
|
||||
/*!
|
||||
* \brief Returns the density [kg/m^3] of gas saturated oil given a pressure.
|
||||
*/
|
||||
template <class Evaluation>
|
||||
Evaluation saturatedDensity(unsigned regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const
|
||||
{
|
||||
const Evaluation& Bo = formationVolumeFactor(regionIdx, temperature, pressure, Rs);
|
||||
Scalar rhooRef = oilReferenceDensity_[regionIdx];
|
||||
|
||||
const Evaluation& Bo = saturatedFormationVolumeFactor(regionIdx, temperature, pressure);
|
||||
return rhooRef/Bo;
|
||||
}
|
||||
|
||||
@ -205,10 +219,22 @@ public:
|
||||
* \brief Returns the formation volume factor [-] of the fluid phase.
|
||||
*/
|
||||
template <class Evaluation>
|
||||
Evaluation formationVolumeFactor(unsigned regionIdx,
|
||||
const Evaluation& /*temperature*/,
|
||||
const Evaluation& pressure,
|
||||
const Evaluation& /*Rs*/) const
|
||||
Evaluation formationVolumeFactor(unsigned regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure,
|
||||
const Evaluation& /*Rs*/) const
|
||||
{ return saturatedFormationVolumeFactor(regionIdx, temperature, pressure); }
|
||||
|
||||
/*!
|
||||
* \brief Returns the formation volume factor [-] of gas saturated oil.
|
||||
*
|
||||
* Note that constant compressibility oil is a special case of dead oil and dead oil
|
||||
* is always gas saturated by by definition.
|
||||
*/
|
||||
template <class Evaluation>
|
||||
Evaluation saturatedFormationVolumeFactor(unsigned regionIdx,
|
||||
const Evaluation& /*temperature*/,
|
||||
const Evaluation& pressure) const
|
||||
{
|
||||
// cf. ECLiPSE 2011 technical description, p. 116
|
||||
Scalar pRef = oilReferencePressure_[regionIdx];
|
||||
@ -223,9 +249,9 @@ public:
|
||||
* a set of parameters.
|
||||
*/
|
||||
template <class Evaluation>
|
||||
Evaluation fugacityCoefficientOil(unsigned /*regionIdx*/,
|
||||
const Evaluation& /*temperature*/,
|
||||
const Evaluation& pressure) const
|
||||
Evaluation fugacityCoefficientOil(unsigned /*regionIdx*/,
|
||||
const Evaluation& /*temperature*/,
|
||||
const Evaluation& pressure) const
|
||||
{
|
||||
// set the oil component fugacity coefficient in oil phase
|
||||
// arbitrarily. we use some pseudo-realistic value for the vapor
|
||||
@ -234,9 +260,9 @@ public:
|
||||
}
|
||||
|
||||
template <class Evaluation>
|
||||
Evaluation fugacityCoefficientWater(unsigned regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const
|
||||
Evaluation fugacityCoefficientWater(unsigned regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const
|
||||
{
|
||||
// assume that the affinity of the water component to the oil phase is many orders
|
||||
// of magnitude smaller than that of the oil component
|
||||
@ -244,9 +270,9 @@ public:
|
||||
}
|
||||
|
||||
template <class Evaluation>
|
||||
Evaluation fugacityCoefficientGas(unsigned regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const
|
||||
Evaluation fugacityCoefficientGas(unsigned regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const
|
||||
{
|
||||
// assume that the affinity of the gas component to the oil phase is many orders
|
||||
// of magnitude smaller than that of the oil component
|
||||
@ -257,9 +283,9 @@ public:
|
||||
* \brief Returns the gas dissolution factor \f$R_s\f$ [m^3/m^3] of the oil phase.
|
||||
*/
|
||||
template <class Evaluation>
|
||||
Evaluation gasDissolutionFactor(unsigned /*regionIdx*/,
|
||||
const Evaluation& /*temperature*/,
|
||||
const Evaluation& /*pressure*/) const
|
||||
Evaluation gasDissolutionFactor(unsigned /*regionIdx*/,
|
||||
const Evaluation& /*temperature*/,
|
||||
const Evaluation& /*pressure*/) const
|
||||
{ return 0.0; /* this is dead oil! */ }
|
||||
|
||||
/*!
|
||||
@ -275,15 +301,15 @@ public:
|
||||
{ return 0.0; /* this is dead oil, so there isn't any meaningful saturation pressure! */ }
|
||||
|
||||
template <class Evaluation>
|
||||
Evaluation saturatedOilGasMassFraction(unsigned /*regionIdx*/,
|
||||
const Evaluation& /*temperature*/,
|
||||
const Evaluation& /*pressure*/) const
|
||||
Evaluation saturatedGasMassFraction(unsigned /*regionIdx*/,
|
||||
const Evaluation& /*temperature*/,
|
||||
const Evaluation& /*pressure*/) const
|
||||
{ return 0.0; /* this is dead oil! */ }
|
||||
|
||||
template <class Evaluation>
|
||||
Evaluation saturatedOilGasMoleFraction(unsigned /*regionIdx*/,
|
||||
const Evaluation& /*temperature*/,
|
||||
const Evaluation& /*pressure*/) const
|
||||
Evaluation saturatedGasMoleFraction(unsigned /*regionIdx*/,
|
||||
const Evaluation& /*temperature*/,
|
||||
const Evaluation& /*pressure*/) const
|
||||
{ return 0.0; /* this is dead oil! */ }
|
||||
|
||||
private:
|
||||
|
@ -163,9 +163,18 @@ public:
|
||||
*/
|
||||
template <class Evaluation>
|
||||
Evaluation viscosity(unsigned regionIdx,
|
||||
const Evaluation& /*temperature*/,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure,
|
||||
const Evaluation& /*Rs*/) const
|
||||
{ return saturatedViscosity(regionIdx, temperature, pressure); }
|
||||
|
||||
/*!
|
||||
* \brief Returns the dynamic viscosity [Pa s] of gas saturated oil given a pressure.
|
||||
*/
|
||||
template <class Evaluation>
|
||||
Evaluation saturatedViscosity(unsigned regionIdx,
|
||||
const Evaluation& /*temperature*/,
|
||||
const Evaluation& pressure) const
|
||||
{
|
||||
const Evaluation& invBo = inverseOilB_[regionIdx].eval(pressure, /*extrapolate=*/true);
|
||||
const Evaluation& invMuoBo = inverseOilBMu_[regionIdx].eval(pressure, /*extrapolate=*/true);
|
||||
@ -180,11 +189,20 @@ public:
|
||||
Evaluation density(unsigned regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure,
|
||||
const Evaluation& Rs) const
|
||||
const Evaluation& /*Rs*/) const
|
||||
{ return saturatedDensity(regionIdx, temperature, pressure); }
|
||||
|
||||
/*!
|
||||
* \brief Returns the density [kg/m^3] of gas saturated oil given a pressure.
|
||||
*/
|
||||
template <class Evaluation>
|
||||
Evaluation saturatedDensity(unsigned regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const
|
||||
{
|
||||
Scalar rhooRef = oilReferenceDensity_[regionIdx];
|
||||
|
||||
const Evaluation& Bo = formationVolumeFactor(regionIdx, temperature, pressure, Rs);
|
||||
const Evaluation& Bo = saturatedFormationVolumeFactor(regionIdx, temperature, pressure);
|
||||
return rhooRef/Bo;
|
||||
}
|
||||
|
||||
@ -198,6 +216,17 @@ public:
|
||||
const Evaluation& /*Rs*/) const
|
||||
{ return 1.0 / inverseOilB_[regionIdx].eval(pressure, /*extrapolate=*/true); }
|
||||
|
||||
/*!
|
||||
* \brief Returns the formation volume factor [-] of saturated oil.
|
||||
*
|
||||
* Note that by definition, dead oil is always gas saturated.
|
||||
*/
|
||||
template <class Evaluation>
|
||||
Evaluation saturatedFormationVolumeFactor(unsigned regionIdx,
|
||||
const Evaluation& /*temperature*/,
|
||||
const Evaluation& pressure) 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.
|
||||
@ -255,15 +284,15 @@ public:
|
||||
{ return 0.0; /* this is dead oil, so there isn't any meaningful saturation pressure! */ }
|
||||
|
||||
template <class Evaluation>
|
||||
Evaluation saturatedOilGasMassFraction(unsigned /*regionIdx*/,
|
||||
const Evaluation& /*temperature*/,
|
||||
const Evaluation& /*pressure*/) const
|
||||
Evaluation saturatedGasMassFraction(unsigned /*regionIdx*/,
|
||||
const Evaluation& /*temperature*/,
|
||||
const Evaluation& /*pressure*/) const
|
||||
{ return 0.0; /* this is dead oil! */ }
|
||||
|
||||
template <class Evaluation>
|
||||
Evaluation saturatedOilGasMoleFraction(unsigned /*regionIdx*/,
|
||||
const Evaluation& /*temperature*/,
|
||||
const Evaluation& /*pressure*/) const
|
||||
Evaluation saturatedGasMoleFraction(unsigned /*regionIdx*/,
|
||||
const Evaluation& /*temperature*/,
|
||||
const Evaluation& /*pressure*/) const
|
||||
{ return 0.0; /* this is dead oil! */ }
|
||||
|
||||
private:
|
||||
|
@ -191,9 +191,18 @@ public:
|
||||
*/
|
||||
template <class Evaluation>
|
||||
Evaluation viscosity(unsigned regionIdx,
|
||||
const Evaluation& /*temperature*/,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure,
|
||||
const Evaluation& /*Rv*/) const
|
||||
{ return saturatedViscosity(regionIdx, temperature, pressure); }
|
||||
|
||||
/*!
|
||||
* \brief Returns the dynamic viscosity [Pa s] of oil saturated gas at given pressure.
|
||||
*/
|
||||
template <class Evaluation>
|
||||
Evaluation saturatedViscosity(unsigned regionIdx,
|
||||
const Evaluation& /*temperature*/,
|
||||
const Evaluation& pressure) const
|
||||
{
|
||||
const Evaluation& invBg = inverseGasB_[regionIdx].eval(pressure, /*extrapolate=*/true);
|
||||
const Evaluation& invMugBg = inverseGasBMu_[regionIdx].eval(pressure, /*extrapolate=*/true);
|
||||
@ -209,9 +218,18 @@ public:
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure,
|
||||
const Evaluation& Rv) const
|
||||
{ return saturatedViscosity(regionIdx, temperature, pressure); }
|
||||
|
||||
/*!
|
||||
* \brief Returns the density [kg/m^3] of oil saturated gas at given pressure.
|
||||
*/
|
||||
template <class Evaluation>
|
||||
Evaluation saturatedDensity(unsigned regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const
|
||||
{
|
||||
// gas formation volume factor at reservoir pressure
|
||||
const Evaluation& Bg = formationVolumeFactor(regionIdx, temperature, pressure, Rv);
|
||||
const Evaluation& Bg = saturatedFormationVolumeFactor(regionIdx, temperature, pressure);
|
||||
return gasReferenceDensity_[regionIdx]/Bg;
|
||||
}
|
||||
|
||||
@ -220,9 +238,18 @@ public:
|
||||
*/
|
||||
template <class Evaluation>
|
||||
Evaluation formationVolumeFactor(unsigned regionIdx,
|
||||
const Evaluation& /*temperature*/,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure,
|
||||
const Evaluation& /*Rv*/) const
|
||||
{ return saturatedFormationVolumeFactor(regionIdx, temperature, pressure); }
|
||||
|
||||
/*!
|
||||
* \brief Returns the formation volume factor [-] of oil saturated gas at given pressure.
|
||||
*/
|
||||
template <class Evaluation>
|
||||
Evaluation saturatedFormationVolumeFactor(unsigned regionIdx,
|
||||
const Evaluation& /*temperature*/,
|
||||
const Evaluation& pressure) const
|
||||
{ return 1.0/inverseGasB_[regionIdx].eval(pressure, /*extrapolate=*/true); }
|
||||
|
||||
/*!
|
||||
@ -280,15 +307,15 @@ public:
|
||||
{ return 0.0; /* this is dry gas! */ }
|
||||
|
||||
template <class Evaluation>
|
||||
Evaluation saturatedGasOilMassFraction(unsigned /*regionIdx*/,
|
||||
const Evaluation& /*temperature*/,
|
||||
const Evaluation& /*pressure*/) const
|
||||
Evaluation saturatedOilMassFraction(unsigned /*regionIdx*/,
|
||||
const Evaluation& /*temperature*/,
|
||||
const Evaluation& /*pressure*/) const
|
||||
{ return 0.0; /* this is dry gas! */ }
|
||||
|
||||
template <class Evaluation>
|
||||
Evaluation saturatedGasOilMoleFraction(unsigned /*regionIdx*/,
|
||||
const Evaluation& /*temperature*/,
|
||||
const Evaluation& /*pressure*/) const
|
||||
Evaluation saturatedOilMoleFraction(unsigned /*regionIdx*/,
|
||||
const Evaluation& /*temperature*/,
|
||||
const Evaluation& /*pressure*/) const
|
||||
{ return 0.0; /* this is dry gas! */ }
|
||||
|
||||
private:
|
||||
|
@ -147,6 +147,15 @@ public:
|
||||
const Evaluation& Rv) const
|
||||
{ OPM_GAS_PVT_MULTIPLEXER_CALL(return pvtImpl.viscosity(regionIdx, temperature, pressure, Rv)); return 0; }
|
||||
|
||||
/*!
|
||||
* \brief Returns the dynamic viscosity [Pa s] of oil saturated gas given a set of parameters.
|
||||
*/
|
||||
template <class Evaluation = Scalar>
|
||||
Evaluation saturatedViscosity(unsigned regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const
|
||||
{ OPM_GAS_PVT_MULTIPLEXER_CALL(return pvtImpl.saturatedViscosity(regionIdx, temperature, pressure)); return 0; }
|
||||
|
||||
/*!
|
||||
* \brief Returns the formation volume factor [-] of the fluid phase.
|
||||
*/
|
||||
@ -157,6 +166,15 @@ public:
|
||||
const Evaluation& Rv) const
|
||||
{ OPM_GAS_PVT_MULTIPLEXER_CALL(return pvtImpl.formationVolumeFactor(regionIdx, temperature, pressure, Rv)); return 0; }
|
||||
|
||||
/*!
|
||||
* \brief Returns the formation volume factor [-] of oil saturated gas given a set of parameters.
|
||||
*/
|
||||
template <class Evaluation = Scalar>
|
||||
Evaluation saturatedFormationVolumeFactor(unsigned regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const
|
||||
{ OPM_GAS_PVT_MULTIPLEXER_CALL(return pvtImpl.saturatedFormationVolumeFactor(regionIdx, temperature, pressure)); return 0; }
|
||||
|
||||
/*!
|
||||
* \brief Returns the density [kg/m^3] of the fluid phase given a set of parameters.
|
||||
*/
|
||||
@ -167,6 +185,15 @@ public:
|
||||
const Evaluation& Rv) const
|
||||
{ OPM_GAS_PVT_MULTIPLEXER_CALL(return pvtImpl.density(regionIdx, temperature, pressure, Rv)); return 0; }
|
||||
|
||||
/*!
|
||||
* \brief Returns the density [kg/m^3] of oil saturated gas given a set of parameters.
|
||||
*/
|
||||
template <class Evaluation = Scalar>
|
||||
Evaluation saturatedDensity(unsigned regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const
|
||||
{ OPM_GAS_PVT_MULTIPLEXER_CALL(return pvtImpl.saturatedDensity(regionIdx, temperature, pressure)); return 0; }
|
||||
|
||||
/*!
|
||||
* \brief Returns the fugacity coefficient [Pa] of the gas component in the gas phase
|
||||
* given a set of parameters.
|
||||
@ -215,20 +242,20 @@ public:
|
||||
* and pressure [-].
|
||||
*/
|
||||
template <class Evaluation = Scalar>
|
||||
Evaluation saturatedGasOilMassFraction(unsigned regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const
|
||||
{ OPM_GAS_PVT_MULTIPLEXER_CALL(return pvtImpl.saturatedGasOilMassFraction(regionIdx, temperature, pressure)); return 0; }
|
||||
Evaluation saturatedOilMassFraction(unsigned regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const
|
||||
{ OPM_GAS_PVT_MULTIPLEXER_CALL(return pvtImpl.saturatedOilMassFraction(regionIdx, temperature, pressure)); return 0; }
|
||||
|
||||
/*!
|
||||
* \brief Returns the gas mole fraction of oil-saturated gas at a given temperatire
|
||||
* and pressure [-].
|
||||
*/
|
||||
template <class Evaluation = Scalar>
|
||||
Evaluation saturatedGasOilMoleFraction(unsigned regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const
|
||||
{ OPM_GAS_PVT_MULTIPLEXER_CALL(return pvtImpl.saturatedGasOilMoleFraction(regionIdx, temperature, pressure)); return 0; }
|
||||
Evaluation saturatedOilMoleFraction(unsigned regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const
|
||||
{ OPM_GAS_PVT_MULTIPLEXER_CALL(return pvtImpl.saturatedOilMoleFraction(regionIdx, temperature, pressure)); return 0; }
|
||||
|
||||
|
||||
GasPvtApproach gasPvtApproach() const
|
||||
|
@ -82,10 +82,14 @@ public:
|
||||
Scalar MO = 175e-3; // [kg/mol]
|
||||
Scalar MG = Opm::Constants<Scalar>::R*T*rhoRefG / p; // [kg/mol], consequence of the ideal gas law
|
||||
Scalar MW = 18.0e-3; // [kg/mol]
|
||||
|
||||
// TODO (?): the molar mass of the components can possibly specified
|
||||
// explicitly in the deck.
|
||||
setMolarMasses(regionIdx, MO, MG, MW);
|
||||
}
|
||||
|
||||
// initialize the internal table objects
|
||||
for (unsigned regionIdx = 0; regionIdx < numRegions; ++ regionIdx) {
|
||||
const auto& pvtoTable = pvtoTables[regionIdx];
|
||||
|
||||
const auto saturatedTable = pvtoTable.getOuterTable();
|
||||
@ -93,15 +97,16 @@ public:
|
||||
|
||||
auto& oilMu = oilMuTable_[regionIdx];
|
||||
auto& invOilB = inverseOilBTable_[regionIdx];
|
||||
auto& invSatOilB = inverseSaturatedOilBTable_[regionIdx];
|
||||
auto& gasDissolutionFac = gasDissolutionFactorTable_[regionIdx];
|
||||
|
||||
gasDissolutionFac.setXYArrays(saturatedTable->numRows(),
|
||||
saturatedTable->getPressureColumn(),
|
||||
saturatedTable->getGasSolubilityColumn());
|
||||
std::vector<Scalar> invSatOilBArray;
|
||||
|
||||
// extract the table for the gas dissolution and the oil formation volume factors
|
||||
for (unsigned outerIdx = 0; outerIdx < saturatedTable->numRows(); ++ outerIdx) {
|
||||
Scalar Rs = saturatedTable->getGasSolubilityColumn()[outerIdx];
|
||||
Scalar BoSat = saturatedTable->getOilFormationFactorColumn()[outerIdx];
|
||||
|
||||
invSatOilBArray.push_back(1.0/BoSat);
|
||||
|
||||
invOilB.appendXPos(Rs);
|
||||
oilMu.appendXPos(Rs);
|
||||
@ -121,6 +126,14 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// update the tables for the formation volume factor and for the gas
|
||||
// dissolution factor of saturated oil
|
||||
invSatOilB.setXYContainers(saturatedTable->getPressureColumn(),
|
||||
invSatOilBArray);
|
||||
gasDissolutionFac.setXYContainers(saturatedTable->getPressureColumn(),
|
||||
saturatedTable->getGasSolubilityColumn());
|
||||
|
||||
|
||||
// make sure to have at least two sample points per mole fraction
|
||||
for (unsigned xIdx = 0; xIdx < invOilB.numX(); ++xIdx) {
|
||||
// a single sample point is definitely needed
|
||||
@ -185,6 +198,8 @@ public:
|
||||
gasReferenceDensity_.resize(numRegions);
|
||||
inverseOilBTable_.resize(numRegions);
|
||||
inverseOilBMuTable_.resize(numRegions);
|
||||
inverseSaturatedOilBTable_.resize(numRegions);
|
||||
inverseSaturatedOilBMuTable_.resize(numRegions);
|
||||
oilMuTable_.resize(numRegions);
|
||||
gasDissolutionFactorTable_.resize(numRegions);
|
||||
saturationPressureSpline_.resize(numRegions);
|
||||
@ -355,12 +370,21 @@ public:
|
||||
assert(oilMu.numX() == invOilB.numX());
|
||||
|
||||
auto& invOilBMu = inverseOilBMuTable_[regionIdx];
|
||||
auto& invSatOilB = inverseSaturatedOilBTable_[regionIdx];
|
||||
auto& invSatOilBMu = inverseSaturatedOilBMuTable_[regionIdx];
|
||||
|
||||
std::vector<Scalar> satPressuresArray;
|
||||
std::vector<Scalar> invSatOilBArray;
|
||||
std::vector<Scalar> invSatOilBMuArray;
|
||||
for (unsigned rsIdx = 0; rsIdx < oilMu.numX(); ++rsIdx) {
|
||||
invOilBMu.appendXPos(oilMu.xAt(rsIdx));
|
||||
|
||||
assert(oilMu.numY(rsIdx) == invOilB.numY(rsIdx));
|
||||
|
||||
satPressuresArray.push_back(oilMu.yAt(rsIdx, 0));
|
||||
invSatOilBArray.push_back(invOilB.valueAt(rsIdx, 0));
|
||||
invSatOilBMuArray.push_back(invOilB.valueAt(rsIdx, 0)*1.0/oilMu.valueAt(rsIdx, 0));
|
||||
|
||||
size_t numPressures = oilMu.numY(rsIdx);
|
||||
for (unsigned pIdx = 0; pIdx < numPressures; ++pIdx)
|
||||
invOilBMu.appendSamplePoint(rsIdx,
|
||||
@ -369,6 +393,9 @@ public:
|
||||
1/oilMu.valueAt(rsIdx, pIdx));
|
||||
}
|
||||
|
||||
invSatOilB.setXYContainers(satPressuresArray, invSatOilBArray);
|
||||
invSatOilBMu.setXYContainers(satPressuresArray, invSatOilBMuArray);
|
||||
|
||||
updateSaturationPressureSpline_(regionIdx);
|
||||
}
|
||||
}
|
||||
@ -389,6 +416,21 @@ public:
|
||||
return invBo/invMuoBo;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the dynamic viscosity [Pa s] of the fluid phase given a set of parameters.
|
||||
*/
|
||||
template <class Evaluation>
|
||||
Evaluation saturatedViscosity(unsigned regionIdx,
|
||||
const Evaluation& /*temperature*/,
|
||||
const Evaluation& pressure) const
|
||||
{
|
||||
// ATTENTION: Rs is the first axis!
|
||||
const Evaluation& invBo = inverseSaturatedOilBTable_[regionIdx].eval(pressure, /*extrapolate=*/true);
|
||||
const Evaluation& invMuoBo = inverseSaturatedOilBMuTable_[regionIdx].eval(pressure, /*extrapolate=*/true);
|
||||
|
||||
return invBo/invMuoBo;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the density [kg/m^3] of the fluid phase given a set of parameters.
|
||||
*/
|
||||
@ -416,6 +458,33 @@ public:
|
||||
return rhoo;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the density [kg/m^3] of gas saturated oil for a given pressure.
|
||||
*/
|
||||
template <class Evaluation>
|
||||
Evaluation saturatedDensity(unsigned regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const
|
||||
{
|
||||
Scalar rhooRef = oilReferenceDensity_[regionIdx];
|
||||
Scalar rhogRef = gasReferenceDensity_[regionIdx];
|
||||
Valgrind::CheckDefined(rhooRef);
|
||||
Valgrind::CheckDefined(rhogRef);
|
||||
|
||||
const Evaluation& Bo = saturatedFormationVolumeFactor(regionIdx, temperature, pressure);
|
||||
Valgrind::CheckDefined(Bo);
|
||||
|
||||
Evaluation 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.
|
||||
const Evaluation& RsSat = gasDissolutionFactor(regionIdx, temperature, pressure);
|
||||
rhoo += rhogRef*RsSat/Bo;
|
||||
|
||||
return rhoo;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the formation volume factor [-] of the fluid phase.
|
||||
*/
|
||||
@ -429,6 +498,18 @@ public:
|
||||
return 1.0 / inverseOilBTable_[regionIdx].eval(Rs, pressure, /*extrapolate=*/true);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the formation volume factor [-] of the fluid phase.
|
||||
*/
|
||||
template <class Evaluation>
|
||||
Evaluation saturatedFormationVolumeFactor(unsigned regionIdx,
|
||||
const Evaluation& /*temperature*/,
|
||||
const Evaluation& pressure) const
|
||||
{
|
||||
// ATTENTION: Rs is represented by the _first_ axis!
|
||||
return 1.0 / inverseSaturatedOilBTable_[regionIdx].eval(pressure, /*extrapolate=*/true);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the fugacity coefficient [Pa] of a component in the fluid phase given
|
||||
* a set of parameters.
|
||||
@ -466,7 +547,7 @@ public:
|
||||
//
|
||||
// first, retrieve the mole fraction of gas a saturated oil
|
||||
// would exhibit at the given pressure
|
||||
const Evaluation& x_oGSat = saturatedOilGasMoleFraction(regionIdx, temperature, pressure);
|
||||
const Evaluation& x_oGSat = saturatedGasMoleFraction(regionIdx, temperature, pressure);
|
||||
|
||||
// then, scale the gas component's gas phase fugacity
|
||||
// coefficient, so that the oil phase ends up at the right
|
||||
@ -521,9 +602,9 @@ public:
|
||||
}
|
||||
|
||||
template <class Evaluation>
|
||||
Evaluation saturatedOilGasMassFraction(unsigned regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const
|
||||
Evaluation saturatedGasMassFraction(unsigned regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const
|
||||
{
|
||||
Scalar rho_gRef = gasReferenceDensity_[regionIdx];
|
||||
Scalar rho_oRef = oilReferenceDensity_[regionIdx];
|
||||
@ -539,12 +620,12 @@ public:
|
||||
}
|
||||
|
||||
template <class Evaluation>
|
||||
Evaluation saturatedOilGasMoleFraction(unsigned regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const
|
||||
Evaluation saturatedGasMoleFraction(unsigned regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const
|
||||
{
|
||||
// calculate the mass fractions of gas and oil
|
||||
const Evaluation& XoG = saturatedOilGasMassFraction(regionIdx, temperature, pressure);
|
||||
const Evaluation& XoG = saturatedGasMassFraction(regionIdx, temperature, pressure);
|
||||
Valgrind::CheckDefined(XoG);
|
||||
|
||||
// which can be converted to mole fractions, given the
|
||||
@ -590,6 +671,8 @@ private:
|
||||
std::vector<TabulatedTwoDFunction> inverseOilBTable_;
|
||||
std::vector<TabulatedTwoDFunction> oilMuTable_;
|
||||
std::vector<TabulatedTwoDFunction> inverseOilBMuTable_;
|
||||
std::vector<TabulatedOneDFunction> inverseSaturatedOilBTable_;
|
||||
std::vector<TabulatedOneDFunction> inverseSaturatedOilBMuTable_;
|
||||
std::vector<TabulatedOneDFunction> gasDissolutionFactorTable_;
|
||||
std::vector<Spline> saturationPressureSpline_;
|
||||
};
|
||||
|
@ -138,6 +138,24 @@ public:
|
||||
const Evaluation& Rs) const
|
||||
{ OPM_OIL_PVT_MULTIPLEXER_CALL(return pvtImpl.viscosity(regionIdx, temperature, pressure, Rs)); return 0; }
|
||||
|
||||
/*!
|
||||
* \brief Returns the dynamic viscosity [Pa s] of the fluid phase given a set of parameters.
|
||||
*/
|
||||
template <class Evaluation>
|
||||
Evaluation saturatedViscosity(unsigned regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const
|
||||
{ OPM_OIL_PVT_MULTIPLEXER_CALL(return pvtImpl.saturatedViscosity(regionIdx, temperature, pressure)); return 0; }
|
||||
|
||||
/*!
|
||||
* \brief Returns the formation volume factor [-] of the fluid phase.
|
||||
*/
|
||||
template <class Evaluation>
|
||||
Evaluation saturatedFormationVolumeFactor(unsigned regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const
|
||||
{ OPM_OIL_PVT_MULTIPLEXER_CALL(return pvtImpl.saturatedFormationVolumeFactor(regionIdx, temperature, pressure)); return 0; }
|
||||
|
||||
/*!
|
||||
* \brief Returns the formation volume factor [-] of the fluid phase.
|
||||
*/
|
||||
@ -158,6 +176,15 @@ public:
|
||||
const Evaluation& Rs) const
|
||||
{ OPM_OIL_PVT_MULTIPLEXER_CALL(return pvtImpl.density(regionIdx, temperature, pressure, Rs)); return 0; }
|
||||
|
||||
/*!
|
||||
* \brief Returns the dynamic viscosity [Pa s] of the fluid phase given a set of parameters.
|
||||
*/
|
||||
template <class Evaluation>
|
||||
Evaluation saturatedDensity(unsigned regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const
|
||||
{ OPM_OIL_PVT_MULTIPLEXER_CALL(return pvtImpl.saturatedDensity(regionIdx, temperature, pressure)); return 0; }
|
||||
|
||||
/*!
|
||||
* \brief Returns the fugacity coefficient [-] of the oil component in the oil phase
|
||||
* given a pressure and a temperature.
|
||||
@ -218,10 +245,10 @@ public:
|
||||
* will be thrown...
|
||||
*/
|
||||
template <class Evaluation>
|
||||
Evaluation saturatedOilGasMassFraction(unsigned regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const
|
||||
{ OPM_OIL_PVT_MULTIPLEXER_CALL(return pvtImpl.saturatedOilGasMassFraction(regionIdx, temperature, pressure)); return 0; }
|
||||
Evaluation saturatedGasMassFraction(unsigned regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const
|
||||
{ OPM_OIL_PVT_MULTIPLEXER_CALL(return pvtImpl.saturatedGasMassFraction(regionIdx, temperature, pressure)); return 0; }
|
||||
|
||||
/*!
|
||||
* \brief Returns the gas mole fraction of gas-saturated oil at a given temperatire
|
||||
@ -231,10 +258,10 @@ public:
|
||||
* will be thrown...
|
||||
*/
|
||||
template <class Evaluation>
|
||||
Evaluation saturatedOilGasMoleFraction(unsigned regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const
|
||||
{ OPM_OIL_PVT_MULTIPLEXER_CALL(return pvtImpl.saturatedOilGasMoleFraction(regionIdx, temperature, pressure)); return 0; }
|
||||
Evaluation saturatedGasMoleFraction(unsigned regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const
|
||||
{ OPM_OIL_PVT_MULTIPLEXER_CALL(return pvtImpl.saturatedGasMoleFraction(regionIdx, temperature, pressure)); return 0; }
|
||||
|
||||
void setApproach(OilPvtApproach oilPvtApproach)
|
||||
{
|
||||
|
@ -96,19 +96,29 @@ public:
|
||||
|
||||
auto& gasMu = gasMu_[regionIdx];
|
||||
auto& invGasB = inverseGasB_[regionIdx];
|
||||
auto& invSatGasB = inverseSaturatedGasB_[regionIdx];
|
||||
auto& invSatGasBMu = inverseSaturatedGasBMu_[regionIdx];
|
||||
auto& oilVaporizationFac = oilVaporizationFactorTable_[regionIdx];
|
||||
|
||||
oilVaporizationFac.setXYArrays(saturatedTable->numRows(),
|
||||
saturatedTable->getPressureColumn(),
|
||||
saturatedTable->getOilSolubilityColumn());
|
||||
saturatedTable->getPressureColumn(),
|
||||
saturatedTable->getOilSolubilityColumn());
|
||||
|
||||
std::vector<Scalar> invSatGasBArray;
|
||||
std::vector<Scalar> invSatGasBMuArray;
|
||||
|
||||
// extract the table for the gas dissolution and the oil formation volume factors
|
||||
for (size_t outerIdx = 0; outerIdx < saturatedTable->numRows(); ++ outerIdx) {
|
||||
Scalar pg = saturatedTable->getPressureColumn()[outerIdx];
|
||||
Scalar B = saturatedTable->getGasFormationFactorColumn()[outerIdx];
|
||||
Scalar mu = saturatedTable->getGasViscosityColumn()[outerIdx];
|
||||
|
||||
invGasB.appendXPos(pg);
|
||||
gasMu.appendXPos(pg);
|
||||
|
||||
invSatGasBArray.push_back(1.0/B);
|
||||
invSatGasBMuArray.push_back(1.0/(mu*B));
|
||||
|
||||
assert(invGasB.numX() == outerIdx + 1);
|
||||
assert(gasMu.numX() == outerIdx + 1);
|
||||
|
||||
@ -124,7 +134,10 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// make sure to have at least two sample points per mole fraction
|
||||
invSatGasB.setXYContainers(saturatedTable->getPressureColumn(), invSatGasBArray);
|
||||
invSatGasBMu.setXYContainers(saturatedTable->getPressureColumn(), invSatGasBMuArray);
|
||||
|
||||
// make sure to have at least two sample points per R_v value
|
||||
for (size_t xIdx = 0; xIdx < invGasB.numX(); ++xIdx) {
|
||||
// a single sample point is definitely needed
|
||||
assert(invGasB.numY(xIdx) > 0);
|
||||
@ -188,6 +201,8 @@ public:
|
||||
gasReferenceDensity_.resize(numRegions);
|
||||
inverseGasB_.resize(numRegions);
|
||||
inverseGasBMu_.resize(numRegions);
|
||||
inverseSaturatedGasB_.resize(numRegions);
|
||||
inverseSaturatedGasBMu_.resize(numRegions);
|
||||
gasMu_.resize(numRegions);
|
||||
oilVaporizationFactorTable_.resize(numRegions);
|
||||
saturationPressureSpline_.resize(numRegions);
|
||||
@ -362,20 +377,32 @@ public:
|
||||
assert(gasMu.numX() == invGasB.numX());
|
||||
|
||||
auto& invGasBMu = inverseGasBMu_[regionIdx];
|
||||
auto& invSatGasB = inverseSaturatedGasB_[regionIdx];
|
||||
auto& invSatGasBMu = inverseSaturatedGasBMu_[regionIdx];
|
||||
|
||||
std::vector<Scalar> satPressuresArray;
|
||||
std::vector<Scalar> invSatGasBArray;
|
||||
std::vector<Scalar> invSatGasBMuArray;
|
||||
for (size_t pIdx = 0; pIdx < gasMu.numX(); ++pIdx) {
|
||||
invGasBMu.appendXPos(gasMu.xAt(pIdx));
|
||||
|
||||
assert(gasMu.numY(pIdx) == invGasB.numY(pIdx));
|
||||
|
||||
size_t numPressures = gasMu.numY(pIdx);
|
||||
for (size_t rvIdx = 0; rvIdx < numPressures; ++rvIdx)
|
||||
satPressuresArray.push_back(gasMu.xAt(pIdx));
|
||||
invSatGasBArray.push_back(invGasB.valueAt(pIdx, 0));
|
||||
invSatGasBMuArray.push_back(invGasB.valueAt(pIdx, 0)*1.0/gasMu.xAt(pIdx));
|
||||
|
||||
size_t numRv = gasMu.numY(pIdx);
|
||||
for (size_t rvIdx = 0; rvIdx < numRv; ++rvIdx)
|
||||
invGasBMu.appendSamplePoint(pIdx,
|
||||
gasMu.yAt(pIdx, rvIdx),
|
||||
invGasB.valueAt(pIdx, rvIdx)*
|
||||
1/gasMu.valueAt(pIdx, rvIdx));
|
||||
}
|
||||
|
||||
invSatGasB.setXYContainers(satPressuresArray, invSatGasBArray);
|
||||
invSatGasBMu.setXYContainers(satPressuresArray, invSatGasBMuArray);
|
||||
|
||||
updateSaturationPressureSpline_(regionIdx);
|
||||
}
|
||||
}
|
||||
@ -395,6 +422,20 @@ public:
|
||||
return invBg/invMugBg;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the dynamic viscosity [Pa s] of oil saturated gas at a given pressure.
|
||||
*/
|
||||
template <class Evaluation>
|
||||
Evaluation saturatedViscosity(unsigned regionIdx,
|
||||
const Evaluation& /*temperature*/,
|
||||
const Evaluation& pressure) const
|
||||
{
|
||||
const Evaluation& invBg = inverseSaturatedGasB_[regionIdx].eval(pressure, /*extrapolate=*/true);
|
||||
const Evaluation& invMugBg = inverseSaturatedGasBMu_[regionIdx].eval(pressure, /*extrapolate=*/true);
|
||||
|
||||
return invBg/invMugBg;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the density [kg/m^3] of the fluid phase given a set of parameters.
|
||||
*/
|
||||
@ -406,13 +447,36 @@ public:
|
||||
{
|
||||
const Evaluation& Bg = formationVolumeFactor(regionIdx, temperature, pressure, Rv);
|
||||
|
||||
Scalar rhooRef = oilReferenceDensity_[regionIdx];
|
||||
Scalar rhogRef = gasReferenceDensity_[regionIdx];
|
||||
Evaluation rhog = rhogRef/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.
|
||||
rhog += (rhogRef*Rv)/Bg;
|
||||
rhog += (rhooRef*Rv)/Bg;
|
||||
|
||||
return rhog;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the density [kg/m^3] of oil saturated gas at a given pressure.
|
||||
*/
|
||||
template <class Evaluation>
|
||||
Evaluation saturatedDensity(unsigned regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const
|
||||
{
|
||||
Scalar rhooRef = oilReferenceDensity_[regionIdx];
|
||||
Scalar rhogRef = gasReferenceDensity_[regionIdx];
|
||||
Valgrind::CheckDefined(rhooRef);
|
||||
Valgrind::CheckDefined(rhogRef);
|
||||
|
||||
const Evaluation& Bg = saturatedFormationVolumeFactor(regionIdx, temperature, pressure);
|
||||
|
||||
Evaluation rhog = rhogRef/Bg;
|
||||
const Evaluation& RvSat = oilVaporizationFactor(regionIdx, temperature, pressure);
|
||||
rhog += (rhooRef*RvSat)/Bg;
|
||||
|
||||
return rhog;
|
||||
}
|
||||
@ -427,6 +491,15 @@ public:
|
||||
const Evaluation& Rv) const
|
||||
{ return 1.0 / inverseGasB_[regionIdx].eval(pressure, Rv, /*extrapolate=*/true); }
|
||||
|
||||
/*!
|
||||
* \brief Returns the formation volume factor [-] of oil saturated gas at a given pressure.
|
||||
*/
|
||||
template <class Evaluation>
|
||||
Evaluation saturatedFormationVolumeFactor(unsigned regionIdx,
|
||||
const Evaluation& /*temperature*/,
|
||||
const Evaluation& pressure) const
|
||||
{ return 1.0 / inverseSaturatedGasB_[regionIdx].eval(pressure, /*extrapolate=*/true); }
|
||||
|
||||
/*!
|
||||
* \brief Returns the fugacity coefficient [Pa] of a component in the fluid phase given
|
||||
* a set of parameters.
|
||||
@ -450,7 +523,7 @@ public:
|
||||
//
|
||||
// first, retrieve the mole fraction of gas a saturated oil would exhibit at the
|
||||
// given pressure
|
||||
const Evaluation& x_gOSat = saturatedGasOilMoleFraction(regionIdx, temperature, pressure);
|
||||
const Evaluation& x_gOSat = saturatedOilMoleFraction(regionIdx, temperature, pressure);
|
||||
|
||||
// then, scale the oil component's gas phase fugacity coefficient, so that the
|
||||
// gas phase ends up at the right composition if we were doing a flash experiment
|
||||
@ -513,9 +586,9 @@ public:
|
||||
}
|
||||
|
||||
template <class Evaluation>
|
||||
Evaluation saturatedGasOilMassFraction(unsigned regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const
|
||||
Evaluation saturatedOilMassFraction(unsigned regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const
|
||||
{
|
||||
Scalar rho_gRef = gasReferenceDensity_[regionIdx];
|
||||
Scalar rho_oRef = oilReferenceDensity_[regionIdx];
|
||||
@ -532,12 +605,12 @@ public:
|
||||
}
|
||||
|
||||
template <class Evaluation>
|
||||
Evaluation saturatedGasOilMoleFraction(unsigned regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const
|
||||
Evaluation saturatedOilMoleFraction(unsigned regionIdx,
|
||||
const Evaluation& temperature,
|
||||
const Evaluation& pressure) const
|
||||
{
|
||||
// calculate the mass fractions of gas and oil
|
||||
const Evaluation& Rv = saturatedGasOilMassFraction(regionIdx, temperature, pressure);
|
||||
const Evaluation& Rv = saturatedOilMassFraction(regionIdx, temperature, pressure);
|
||||
|
||||
// which can be converted to mole fractions, given the
|
||||
// components' molar masses
|
||||
@ -578,8 +651,10 @@ private:
|
||||
std::vector<Scalar> gasReferenceDensity_;
|
||||
std::vector<Scalar> oilReferenceDensity_;
|
||||
std::vector<TabulatedTwoDFunction> inverseGasB_;
|
||||
std::vector<TabulatedOneDFunction> inverseSaturatedGasB_;
|
||||
std::vector<TabulatedTwoDFunction> gasMu_;
|
||||
std::vector<TabulatedTwoDFunction> inverseGasBMu_;
|
||||
std::vector<TabulatedOneDFunction> inverseSaturatedGasBMu_;
|
||||
std::vector<TabulatedOneDFunction> oilVaporizationFactorTable_;
|
||||
std::vector<Spline> saturationPressureSpline_;
|
||||
};
|
||||
|
@ -42,6 +42,9 @@
|
||||
#include <opm/material/fluidsystems/blackoilpvt/OilPvtMultiplexer.hpp>
|
||||
#include <opm/material/fluidsystems/blackoilpvt/WaterPvtMultiplexer.hpp>
|
||||
|
||||
#include <opm/material/localad/Evaluation.hpp>
|
||||
#include <opm/material/localad/Math.hpp>
|
||||
|
||||
#include <opm/material/fluidsystems/BlackOilFluidSystem.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/Parser/Parser.hpp>
|
||||
@ -124,6 +127,119 @@ static const char* deckString1 =
|
||||
"/\n"
|
||||
"\n";
|
||||
|
||||
template <class Evaluation, class OilPvt, class GasPvt, class WaterPvt>
|
||||
void ensurePvtApi(const OilPvt& oilPvt, const GasPvt& gasPvt, const WaterPvt& waterPvt)
|
||||
{
|
||||
// we don't want to run this, we just want to make sure that it compiles
|
||||
while (0) {
|
||||
Evaluation temperature = 273.15 + 20.0;
|
||||
Evaluation pressure = 1e5;
|
||||
Evaluation Rs = 0.0;
|
||||
Evaluation Rv = 0.0;
|
||||
Evaluation OPM_UNUSED tmp;
|
||||
|
||||
/////
|
||||
// water PVT API
|
||||
/////
|
||||
tmp = waterPvt.viscosity(/*regionIdx=*/0,
|
||||
temperature,
|
||||
pressure);
|
||||
tmp = waterPvt.density(/*regionIdx=*/0,
|
||||
temperature,
|
||||
pressure);
|
||||
tmp = waterPvt.fugacityCoefficientOil(/*regionIdx=*/0,
|
||||
temperature,
|
||||
pressure);
|
||||
tmp = waterPvt.fugacityCoefficientGas(/*regionIdx=*/0,
|
||||
temperature,
|
||||
pressure);
|
||||
tmp = waterPvt.fugacityCoefficientWater(/*regionIdx=*/0,
|
||||
temperature,
|
||||
pressure);
|
||||
|
||||
/////
|
||||
// oil PVT API
|
||||
/////
|
||||
tmp = oilPvt.viscosity(/*regionIdx=*/0,
|
||||
temperature,
|
||||
pressure,
|
||||
Rs);
|
||||
tmp = oilPvt.density(/*regionIdx=*/0,
|
||||
temperature,
|
||||
pressure,
|
||||
Rs);
|
||||
tmp = oilPvt.formationVolumeFactor(/*regionIdx=*/0,
|
||||
temperature,
|
||||
pressure,
|
||||
Rs);
|
||||
tmp = oilPvt.saturatedViscosity(/*regionIdx=*/0,
|
||||
temperature,
|
||||
pressure);
|
||||
tmp = oilPvt.saturatedDensity(/*regionIdx=*/0,
|
||||
temperature,
|
||||
pressure);
|
||||
tmp = oilPvt.saturatedFormationVolumeFactor(/*regionIdx=*/0,
|
||||
temperature,
|
||||
pressure);
|
||||
tmp = oilPvt.saturatedGasMassFraction(/*regionIdx=*/0,
|
||||
temperature,
|
||||
pressure);
|
||||
tmp = oilPvt.saturatedGasMoleFraction(/*regionIdx=*/0,
|
||||
temperature,
|
||||
pressure);
|
||||
tmp = oilPvt.fugacityCoefficientOil(/*regionIdx=*/0,
|
||||
temperature,
|
||||
pressure);
|
||||
tmp = oilPvt.fugacityCoefficientGas(/*regionIdx=*/0,
|
||||
temperature,
|
||||
pressure);
|
||||
tmp = oilPvt.fugacityCoefficientWater(/*regionIdx=*/0,
|
||||
temperature,
|
||||
pressure);
|
||||
|
||||
/////
|
||||
// gas PVT API
|
||||
/////
|
||||
tmp = gasPvt.viscosity(/*regionIdx=*/0,
|
||||
temperature,
|
||||
pressure,
|
||||
Rv);
|
||||
tmp = gasPvt.density(/*regionIdx=*/0,
|
||||
temperature,
|
||||
pressure,
|
||||
Rv);
|
||||
tmp = gasPvt.saturatedViscosity(/*regionIdx=*/0,
|
||||
temperature,
|
||||
pressure);
|
||||
tmp = gasPvt.saturatedDensity(/*regionIdx=*/0,
|
||||
temperature,
|
||||
pressure);
|
||||
tmp = gasPvt.saturatedFormationVolumeFactor(/*regionIdx=*/0,
|
||||
temperature,
|
||||
pressure);
|
||||
tmp = gasPvt.formationVolumeFactor(/*regionIdx=*/0,
|
||||
temperature,
|
||||
pressure,
|
||||
Rv);
|
||||
tmp = gasPvt.saturatedOilMassFraction(/*regionIdx=*/0,
|
||||
temperature,
|
||||
pressure);
|
||||
tmp = gasPvt.saturatedOilMoleFraction(/*regionIdx=*/0,
|
||||
temperature,
|
||||
pressure);
|
||||
|
||||
tmp = gasPvt.fugacityCoefficientOil(/*regionIdx=*/0,
|
||||
temperature,
|
||||
pressure);
|
||||
tmp = gasPvt.fugacityCoefficientGas(/*regionIdx=*/0,
|
||||
temperature,
|
||||
pressure);
|
||||
tmp = gasPvt.fugacityCoefficientWater(/*regionIdx=*/0,
|
||||
temperature,
|
||||
pressure);
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
typedef double Scalar;
|
||||
@ -207,6 +323,11 @@ int main()
|
||||
oilPvt.initEnd(&gasPvt);
|
||||
waterPvt.initEnd();
|
||||
|
||||
struct Foo;
|
||||
typedef Opm::LocalAd::Evaluation<Scalar, Foo, 1> FooEval;
|
||||
ensurePvtApi<Scalar>(oilPvt, gasPvt, waterPvt);
|
||||
ensurePvtApi<FooEval>(oilPvt, gasPvt, waterPvt);
|
||||
|
||||
// make sure that the BlackOil fluid system's initFromDeck() method compiles.
|
||||
typedef Opm::FluidSystems::BlackOil<Scalar> BlackOilFluidSystem;
|
||||
BlackOilFluidSystem::initFromDeck(deck, eclState);
|
||||
|
Loading…
Reference in New Issue
Block a user