implemented simple salt/brine option
This commit is contained in:
parent
8d5d8ad26c
commit
1841b05b16
@ -88,6 +88,7 @@ template <class ScalarT,
|
|||||||
bool enableTemperature = false,
|
bool enableTemperature = false,
|
||||||
bool enableEnergy = false,
|
bool enableEnergy = false,
|
||||||
bool enableDissolution = true,
|
bool enableDissolution = true,
|
||||||
|
bool enableSaltWater = false,
|
||||||
unsigned numStoragePhases = FluidSystem::numPhases>
|
unsigned numStoragePhases = FluidSystem::numPhases>
|
||||||
class BlackOilFluidState
|
class BlackOilFluidState
|
||||||
{
|
{
|
||||||
@ -132,6 +133,10 @@ public:
|
|||||||
Opm::Valgrind::CheckDefined(*Rv_);
|
Opm::Valgrind::CheckDefined(*Rv_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (enableSaltWater) {
|
||||||
|
Opm::Valgrind::CheckDefined(*saltconcentration_);
|
||||||
|
}
|
||||||
|
|
||||||
if (enableTemperature || enableEnergy)
|
if (enableTemperature || enableEnergy)
|
||||||
Opm::Valgrind::CheckDefined(*temperature_);
|
Opm::Valgrind::CheckDefined(*temperature_);
|
||||||
#endif // NDEBUG
|
#endif // NDEBUG
|
||||||
@ -155,6 +160,9 @@ public:
|
|||||||
setRv(Opm::BlackOil::getRv_<FluidSystem, FluidState, Scalar>(fs, pvtRegionIdx));
|
setRv(Opm::BlackOil::getRv_<FluidSystem, FluidState, Scalar>(fs, pvtRegionIdx));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (enableSaltWater){
|
||||||
|
setSaltconcentration(Opm::BlackOil::getSaltconcentration_<FluidSystem, FluidState, Scalar>(fs, pvtRegionIdx));
|
||||||
|
}
|
||||||
for (unsigned storagePhaseIdx = 0; storagePhaseIdx < numStoragePhases; ++storagePhaseIdx) {
|
for (unsigned storagePhaseIdx = 0; storagePhaseIdx < numStoragePhases; ++storagePhaseIdx) {
|
||||||
unsigned phaseIdx = storageToCanonicalPhaseIndex_(storagePhaseIdx);
|
unsigned phaseIdx = storageToCanonicalPhaseIndex_(storagePhaseIdx);
|
||||||
setSaturation(phaseIdx, fs.saturation(phaseIdx));
|
setSaturation(phaseIdx, fs.saturation(phaseIdx));
|
||||||
@ -243,6 +251,12 @@ public:
|
|||||||
void setRv(const Scalar& newRv)
|
void setRv(const Scalar& newRv)
|
||||||
{ *Rv_ = newRv; }
|
{ *Rv_ = newRv; }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Set the salt concentration.
|
||||||
|
*/
|
||||||
|
void setSaltconcentration(const Scalar& newSaltconcentration)
|
||||||
|
{ *saltconcentration_ = newSaltconcentration; }
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Return the pressure of a fluid phase [Pa]
|
* \brief Return the pressure of a fluid phase [Pa]
|
||||||
*/
|
*/
|
||||||
@ -311,6 +325,19 @@ public:
|
|||||||
return *Rv_;
|
return *Rv_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Return the concentration of salt in water
|
||||||
|
*/
|
||||||
|
const Scalar& saltconcentration() const
|
||||||
|
{
|
||||||
|
if (!enableSaltWater) {
|
||||||
|
static Scalar null = 0.0;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *saltconcentration_;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Return the PVT region where the current fluid state is assumed to be part of.
|
* \brief Return the PVT region where the current fluid state is assumed to be part of.
|
||||||
*
|
*
|
||||||
@ -517,6 +544,7 @@ private:
|
|||||||
std::array<Scalar, numStoragePhases> density_;
|
std::array<Scalar, numStoragePhases> density_;
|
||||||
Opm::ConditionalStorage<enableDissolution,Scalar> Rs_;
|
Opm::ConditionalStorage<enableDissolution,Scalar> Rs_;
|
||||||
Opm::ConditionalStorage<enableDissolution, Scalar> Rv_;
|
Opm::ConditionalStorage<enableDissolution, Scalar> Rv_;
|
||||||
|
Opm::ConditionalStorage<enableSaltWater, Scalar> saltconcentration_;
|
||||||
unsigned short pvtRegionIdx_;
|
unsigned short pvtRegionIdx_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -79,6 +79,21 @@ auto getRv_(typename std::enable_if<HasMember_Rv<FluidState>::value, const Fluid
|
|||||||
-> decltype(Opm::decay<LhsEval>(fluidState.Rv()))
|
-> decltype(Opm::decay<LhsEval>(fluidState.Rv()))
|
||||||
{ return Opm::decay<LhsEval>(fluidState.Rv()); }
|
{ return Opm::decay<LhsEval>(fluidState.Rv()); }
|
||||||
|
|
||||||
|
template <class FluidSystem, class FluidState, class LhsEval>
|
||||||
|
LhsEval getSaltconcentration_(typename std::enable_if<!HasMember_Rs<FluidState>::value, const FluidState&>::type fluidState,
|
||||||
|
unsigned regionIdx)
|
||||||
|
{
|
||||||
|
//const auto& XoG =
|
||||||
|
// Opm::decay<LhsEval>(fluidState.massFraction(FluidSystem::oilPhaseIdx, FluidSystem::gasCompIdx));
|
||||||
|
//return FluidSystem::convertXoGToRs(XoG, regionIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class FluidSystem, class FluidState, class LhsEval>
|
||||||
|
auto getSaltconcentration_(typename std::enable_if<HasMember_Rs<FluidState>::value, const FluidState&>::type fluidState,
|
||||||
|
unsigned regionIdx OPM_UNUSED)
|
||||||
|
-> decltype(Opm::decay<LhsEval>(fluidState.saltconcentration()))
|
||||||
|
{ return Opm::decay<LhsEval>(fluidState.saltconcentration()); }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -0,0 +1,210 @@
|
|||||||
|
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
|
// vi: set et ts=4 sw=4 sts=4:
|
||||||
|
/*
|
||||||
|
This file is part of the Open Porous Media project (OPM).
|
||||||
|
|
||||||
|
OPM is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OPM is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Consult the COPYING file in the top-level source directory of this
|
||||||
|
module for the precise wording of the license and the list of
|
||||||
|
copyright holders.
|
||||||
|
*/
|
||||||
|
/*!
|
||||||
|
* \file
|
||||||
|
* \copydoc Opm::ConstantCompressibilitySaltWaterPvt
|
||||||
|
*/
|
||||||
|
#ifndef OPM_CONSTANT_COMPRESSIBILITY_SALTWATER_PVT_HPP
|
||||||
|
#define OPM_CONSTANT_COMPRESSIBILITY_SALTWATER_PVT_HPP
|
||||||
|
|
||||||
|
#include <opm/material/common/Tabulated1DFunction.hpp>
|
||||||
|
|
||||||
|
#if HAVE_ECL_INPUT
|
||||||
|
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||||
|
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
|
||||||
|
#include <opm/parser/eclipse/Deck/DeckRecord.hpp>
|
||||||
|
#include <opm/parser/eclipse/Deck/DeckItem.hpp>
|
||||||
|
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||||
|
#include <opm/parser/eclipse/EclipseState/Tables/PvtwsaltTable.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace Opm {
|
||||||
|
template <class Scalar, bool enableThermal, bool enableSaltWater>
|
||||||
|
class WaterPvtMultiplexer;
|
||||||
|
/*!
|
||||||
|
* \brief This class represents the Pressure-Volume-Temperature relations of the gas phase
|
||||||
|
* without vaporized oil.
|
||||||
|
*/
|
||||||
|
template <class Scalar>
|
||||||
|
class ConstantCompressibilitySaltWaterPvt
|
||||||
|
{
|
||||||
|
typedef Opm::Tabulated1DFunction<Scalar> TabulatedOneDFunction;
|
||||||
|
typedef typename Opm::Tabulated1DFunction<Scalar> TabulatedFunction;
|
||||||
|
typedef std::vector<std::pair<Scalar, Scalar> > SamplingPoints;
|
||||||
|
|
||||||
|
public:
|
||||||
|
#if HAVE_ECL_INPUT
|
||||||
|
/*!
|
||||||
|
* \brief Sets the pressure-dependent water viscosity and density
|
||||||
|
* using a table stemming from the Eclipse PVTWSALT keyword.
|
||||||
|
*/
|
||||||
|
void initFromDeck(const Deck& deck, const EclipseState& eclState)
|
||||||
|
{
|
||||||
|
const auto& tableManager = eclState.getTableManager();
|
||||||
|
size_t numRegions = tableManager.getTabdims().getNumPVTTables();
|
||||||
|
const auto& densityKeyword = deck.getKeyword("DENSITY");
|
||||||
|
|
||||||
|
formationVolumeTables_.resize(numRegions);
|
||||||
|
compressibilityTables_.resize(numRegions);
|
||||||
|
viscosityTables_.resize(numRegions);
|
||||||
|
viscosibilityTables_.resize(numRegions);
|
||||||
|
referencePressure_.resize(numRegions);
|
||||||
|
|
||||||
|
const auto& pvtwsaltTables = tableManager.getPvtwSaltTables();
|
||||||
|
if(!pvtwsaltTables.empty()){
|
||||||
|
assert(numRegions == pvtwsaltTables.size());
|
||||||
|
for (unsigned regionIdx = 0; regionIdx < numRegions; ++ regionIdx) {
|
||||||
|
const auto& pvtwsaltTable = pvtwsaltTables[regionIdx];
|
||||||
|
const auto& c = pvtwsaltTable.getSaltConcentrationColumn();
|
||||||
|
|
||||||
|
const auto& B = pvtwsaltTable.getFormationVolumeFactorColumn();
|
||||||
|
formationVolumeTables_[regionIdx].setXYContainers(c, B);
|
||||||
|
|
||||||
|
const auto& compressibility = pvtwsaltTable.getCompressibilityColumn();
|
||||||
|
compressibilityTables_[regionIdx].setXYContainers(c, compressibility);
|
||||||
|
|
||||||
|
const auto& viscositytable = pvtwsaltTable.getViscosityColumn();
|
||||||
|
viscosityTables_[regionIdx].setXYContainers(c, viscositytable);
|
||||||
|
|
||||||
|
const auto& viscosibility = pvtwsaltTable.getViscosibilityColumn();
|
||||||
|
viscosibilityTables_[regionIdx].setXYContainers(c, viscosibility);
|
||||||
|
referencePressure_[regionIdx] = pvtwsaltTable.getReferencePressureValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw std::runtime_error("PVTWSALT must be specified in SALTWATER runs\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t numPvtwRegions = numRegions;
|
||||||
|
setNumRegions(numPvtwRegions);
|
||||||
|
|
||||||
|
for (unsigned regionIdx = 0; regionIdx < numPvtwRegions; ++ regionIdx) {
|
||||||
|
auto densityRecord = densityKeyword.getRecord(regionIdx);
|
||||||
|
|
||||||
|
waterReferenceDensity_[regionIdx] =
|
||||||
|
densityRecord.getItem("WATER").getSIDouble(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
initEnd();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void setNumRegions(size_t numRegions)
|
||||||
|
{
|
||||||
|
waterReferenceDensity_.resize(numRegions);
|
||||||
|
|
||||||
|
for (unsigned regionIdx = 0; regionIdx < numRegions; ++regionIdx) {
|
||||||
|
setReferenceDensities(regionIdx, 650.0, 1.0, 1000.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Set the water reference density [kg / m^3]
|
||||||
|
*/
|
||||||
|
void setReferenceDensities(unsigned regionIdx,
|
||||||
|
Scalar /*rhoRefOil*/,
|
||||||
|
Scalar /*rhoRefGas*/,
|
||||||
|
Scalar rhoRefWater)
|
||||||
|
{ waterReferenceDensity_[regionIdx] = rhoRefWater; }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Finish initializing the water phase PVT properties.
|
||||||
|
*/
|
||||||
|
void initEnd()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Return the number of PVT regions which are considered by this PVT-object.
|
||||||
|
*/
|
||||||
|
unsigned numRegions() const
|
||||||
|
{ return waterReferenceDensity_.size(); }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Returns the specific enthalpy [J/kg] of water given a set of parameters.
|
||||||
|
*/
|
||||||
|
template <class Evaluation>
|
||||||
|
Evaluation internalEnergy(unsigned regionIdx OPM_UNUSED,
|
||||||
|
const Evaluation& temperature OPM_UNUSED,
|
||||||
|
const Evaluation& pressure OPM_UNUSED) const
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Requested the enthalpy of water but the thermal option is not enabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \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& saltwaterconcentration) const
|
||||||
|
{
|
||||||
|
// cf. ECLiPSE 2013.2 technical description, p. 114
|
||||||
|
Scalar pRef = referencePressure_[regionIdx];
|
||||||
|
const Evaluation C = compressibilityTables_[regionIdx].eval(saltwaterconcentration, /*extrapolate=*/true);
|
||||||
|
const Evaluation Cv = viscosibilityTables_[regionIdx].eval(saltwaterconcentration, /*extrapolate=*/true);
|
||||||
|
const Evaluation BwRef = formationVolumeTables_[regionIdx].eval(saltwaterconcentration, /*extrapolate=*/true);
|
||||||
|
const Evaluation Y = (C-Cv)* (pressure - pRef);
|
||||||
|
Evaluation MuwRef = viscosityTables_[regionIdx].eval(saltwaterconcentration, /*extrapolate=*/true);
|
||||||
|
|
||||||
|
const Evaluation& bw = inverseFormationVolumeFactor(regionIdx, temperature, pressure, saltwaterconcentration);
|
||||||
|
|
||||||
|
return MuwRef*BwRef*bw/(1 + Y*(1 + Y/2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Returns the formation volume factor [-] of the fluid phase.
|
||||||
|
*/
|
||||||
|
template <class Evaluation>
|
||||||
|
Evaluation inverseFormationVolumeFactor(unsigned regionIdx,
|
||||||
|
const Evaluation& /*temperature*/,
|
||||||
|
const Evaluation& pressure,
|
||||||
|
const Evaluation& saltwaterconcentration) const
|
||||||
|
{
|
||||||
|
Scalar pRef = referencePressure_[regionIdx];
|
||||||
|
|
||||||
|
const Evaluation BwRef = formationVolumeTables_[regionIdx].eval(saltwaterconcentration, /*extrapolate=*/true);
|
||||||
|
const Evaluation C = compressibilityTables_[regionIdx].eval(saltwaterconcentration, /*extrapolate=*/true);
|
||||||
|
const Evaluation X = C * (pressure - pRef);
|
||||||
|
|
||||||
|
return (1.0 + X*(1.0 + X/2.0))/BwRef;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<TabulatedFunction> formationVolumeTables_;
|
||||||
|
std::vector<TabulatedFunction> compressibilityTables_;
|
||||||
|
std::vector<TabulatedFunction> viscosityTables_;
|
||||||
|
std::vector<TabulatedFunction> viscosibilityTables_;
|
||||||
|
std::vector<Scalar> referencePressure_;
|
||||||
|
std::vector<Scalar> waterReferenceDensity_;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Opm
|
||||||
|
|
||||||
|
#endif
|
@ -184,16 +184,18 @@ public:
|
|||||||
throw std::runtime_error("Requested the enthalpy of water but the thermal option is not enabled");
|
throw std::runtime_error("Requested the enthalpy of water but the thermal option is not enabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns the dynamic viscosity [Pa s] of the fluid phase given a set of parameters.
|
* \brief Returns the dynamic viscosity [Pa s] of the fluid phase given a set of parameters.
|
||||||
*/
|
*/
|
||||||
template <class Evaluation>
|
template <class Evaluation>
|
||||||
Evaluation viscosity(unsigned regionIdx,
|
Evaluation viscosity(unsigned regionIdx,
|
||||||
const Evaluation& temperature,
|
const Evaluation& temperature,
|
||||||
const Evaluation& pressure) const
|
const Evaluation& pressure,
|
||||||
|
const Evaluation& saltconcentration) const
|
||||||
{
|
{
|
||||||
Scalar BwMuwRef = waterViscosity_[regionIdx]*waterReferenceFormationVolumeFactor_[regionIdx];
|
Scalar BwMuwRef = waterViscosity_[regionIdx]*waterReferenceFormationVolumeFactor_[regionIdx];
|
||||||
const Evaluation& bw = inverseFormationVolumeFactor(regionIdx, temperature, pressure);
|
const Evaluation& bw = inverseFormationVolumeFactor(regionIdx, temperature, pressure, saltconcentration);
|
||||||
|
|
||||||
Scalar pRef = waterReferencePressure_[regionIdx];
|
Scalar pRef = waterReferencePressure_[regionIdx];
|
||||||
const Evaluation& Y =
|
const Evaluation& Y =
|
||||||
@ -208,7 +210,8 @@ public:
|
|||||||
template <class Evaluation>
|
template <class Evaluation>
|
||||||
Evaluation inverseFormationVolumeFactor(unsigned regionIdx,
|
Evaluation inverseFormationVolumeFactor(unsigned regionIdx,
|
||||||
const Evaluation& /*temperature*/,
|
const Evaluation& /*temperature*/,
|
||||||
const Evaluation& pressure) const
|
const Evaluation& pressure,
|
||||||
|
const Evaluation& /*saltconcentration*/) const
|
||||||
{
|
{
|
||||||
// cf. ECLiPSE 2011 technical description, p. 116
|
// cf. ECLiPSE 2011 technical description, p. 116
|
||||||
Scalar pRef = waterReferencePressure_[regionIdx];
|
Scalar pRef = waterReferencePressure_[regionIdx];
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#define OPM_WATER_PVT_MULTIPLEXER_HPP
|
#define OPM_WATER_PVT_MULTIPLEXER_HPP
|
||||||
|
|
||||||
#include "ConstantCompressibilityWaterPvt.hpp"
|
#include "ConstantCompressibilityWaterPvt.hpp"
|
||||||
|
#include "ConstantCompressibilitySaltWaterPvt.hpp"
|
||||||
#include "WaterPvtThermal.hpp"
|
#include "WaterPvtThermal.hpp"
|
||||||
|
|
||||||
#define OPM_WATER_PVT_MULTIPLEXER_CALL(codeToCall) \
|
#define OPM_WATER_PVT_MULTIPLEXER_CALL(codeToCall) \
|
||||||
@ -37,6 +38,11 @@
|
|||||||
codeToCall; \
|
codeToCall; \
|
||||||
break; \
|
break; \
|
||||||
} \
|
} \
|
||||||
|
case ConstantCompressibilitySaltWaterPvt: { \
|
||||||
|
auto& pvtImpl = getRealPvt<ConstantCompressibilitySaltWaterPvt>(); \
|
||||||
|
codeToCall; \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
case ThermalWaterPvt: { \
|
case ThermalWaterPvt: { \
|
||||||
auto& pvtImpl = getRealPvt<ThermalWaterPvt>(); \
|
auto& pvtImpl = getRealPvt<ThermalWaterPvt>(); \
|
||||||
codeToCall; \
|
codeToCall; \
|
||||||
@ -51,7 +57,7 @@ namespace Opm {
|
|||||||
* \brief This class represents the Pressure-Volume-Temperature relations of the water
|
* \brief This class represents the Pressure-Volume-Temperature relations of the water
|
||||||
* phase in the black-oil model.
|
* phase in the black-oil model.
|
||||||
*/
|
*/
|
||||||
template <class Scalar, bool enableThermal = true>
|
template <class Scalar, bool enableThermal = true, bool enableSaltWater = true>
|
||||||
class WaterPvtMultiplexer
|
class WaterPvtMultiplexer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -59,6 +65,7 @@ public:
|
|||||||
|
|
||||||
enum WaterPvtApproach {
|
enum WaterPvtApproach {
|
||||||
NoWaterPvt,
|
NoWaterPvt,
|
||||||
|
ConstantCompressibilitySaltWaterPvt,
|
||||||
ConstantCompressibilityWaterPvt,
|
ConstantCompressibilityWaterPvt,
|
||||||
ThermalWaterPvt
|
ThermalWaterPvt
|
||||||
};
|
};
|
||||||
@ -86,6 +93,10 @@ public:
|
|||||||
delete &getRealPvt<ConstantCompressibilityWaterPvt>();
|
delete &getRealPvt<ConstantCompressibilityWaterPvt>();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ConstantCompressibilitySaltWaterPvt: {
|
||||||
|
delete &getRealPvt<ConstantCompressibilitySaltWaterPvt>();
|
||||||
|
break;
|
||||||
|
}
|
||||||
case ThermalWaterPvt: {
|
case ThermalWaterPvt: {
|
||||||
delete &getRealPvt<ThermalWaterPvt>();
|
delete &getRealPvt<ThermalWaterPvt>();
|
||||||
break;
|
break;
|
||||||
@ -111,6 +122,8 @@ public:
|
|||||||
setApproach(ThermalWaterPvt);
|
setApproach(ThermalWaterPvt);
|
||||||
else if (deck.hasKeyword("PVTW"))
|
else if (deck.hasKeyword("PVTW"))
|
||||||
setApproach(ConstantCompressibilityWaterPvt);
|
setApproach(ConstantCompressibilityWaterPvt);
|
||||||
|
else if (enableSaltWater && deck.hasKeyword("PVTWSALT"))
|
||||||
|
setApproach(ConstantCompressibilitySaltWaterPvt);
|
||||||
|
|
||||||
OPM_WATER_PVT_MULTIPLEXER_CALL(pvtImpl.initFromDeck(deck, eclState));
|
OPM_WATER_PVT_MULTIPLEXER_CALL(pvtImpl.initFromDeck(deck, eclState));
|
||||||
}
|
}
|
||||||
@ -141,7 +154,37 @@ public:
|
|||||||
Evaluation viscosity(unsigned regionIdx,
|
Evaluation viscosity(unsigned regionIdx,
|
||||||
const Evaluation& temperature,
|
const Evaluation& temperature,
|
||||||
const Evaluation& pressure) const
|
const Evaluation& pressure) const
|
||||||
{ OPM_WATER_PVT_MULTIPLEXER_CALL(return pvtImpl.viscosity(regionIdx, temperature, pressure)); return 0; }
|
{
|
||||||
|
// assert(realWaterPvt_ != ConstantCompressibilitySaltWaterPvt );
|
||||||
|
const Evaluation saltconcentration = 0.0;
|
||||||
|
OPM_WATER_PVT_MULTIPLEXER_CALL(return pvtImpl.viscosity(regionIdx, temperature, pressure, saltconcentration));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \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& saltconcentration) const
|
||||||
|
{
|
||||||
|
OPM_WATER_PVT_MULTIPLEXER_CALL(return pvtImpl.viscosity(regionIdx, temperature, pressure, saltconcentration));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Returns the formation volume factor [-] of the fluid phase.
|
||||||
|
*/
|
||||||
|
template <class Evaluation>
|
||||||
|
Evaluation inverseFormationVolumeFactor(unsigned regionIdx,
|
||||||
|
const Evaluation& temperature,
|
||||||
|
const Evaluation& pressure,
|
||||||
|
const Evaluation& saltconcentration) const
|
||||||
|
{ OPM_WATER_PVT_MULTIPLEXER_CALL(return pvtImpl.inverseFormationVolumeFactor(regionIdx, temperature, pressure, saltconcentration));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns the formation volume factor [-] of the fluid phase.
|
* \brief Returns the formation volume factor [-] of the fluid phase.
|
||||||
@ -150,7 +193,11 @@ public:
|
|||||||
Evaluation inverseFormationVolumeFactor(unsigned regionIdx,
|
Evaluation inverseFormationVolumeFactor(unsigned regionIdx,
|
||||||
const Evaluation& temperature,
|
const Evaluation& temperature,
|
||||||
const Evaluation& pressure) const
|
const Evaluation& pressure) const
|
||||||
{ OPM_WATER_PVT_MULTIPLEXER_CALL(return pvtImpl.inverseFormationVolumeFactor(regionIdx, temperature, pressure)); return 0; }
|
{
|
||||||
|
const Evaluation saltconcentration = 0.0;
|
||||||
|
OPM_WATER_PVT_MULTIPLEXER_CALL(return pvtImpl.inverseFormationVolumeFactor(regionIdx, temperature, pressure, saltconcentration));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void setApproach(WaterPvtApproach appr)
|
void setApproach(WaterPvtApproach appr)
|
||||||
{
|
{
|
||||||
@ -159,6 +206,10 @@ public:
|
|||||||
realWaterPvt_ = new Opm::ConstantCompressibilityWaterPvt<Scalar>;
|
realWaterPvt_ = new Opm::ConstantCompressibilityWaterPvt<Scalar>;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ConstantCompressibilitySaltWaterPvt:
|
||||||
|
realWaterPvt_ = new Opm::ConstantCompressibilitySaltWaterPvt<Scalar>;
|
||||||
|
break;
|
||||||
|
|
||||||
case ThermalWaterPvt:
|
case ThermalWaterPvt:
|
||||||
realWaterPvt_ = new Opm::WaterPvtThermal<Scalar>;
|
realWaterPvt_ = new Opm::WaterPvtThermal<Scalar>;
|
||||||
break;
|
break;
|
||||||
@ -193,6 +244,20 @@ public:
|
|||||||
return *static_cast<Opm::ConstantCompressibilityWaterPvt<Scalar>* >(realWaterPvt_);
|
return *static_cast<Opm::ConstantCompressibilityWaterPvt<Scalar>* >(realWaterPvt_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <WaterPvtApproach approachV>
|
||||||
|
typename std::enable_if<approachV == ConstantCompressibilitySaltWaterPvt, Opm::ConstantCompressibilitySaltWaterPvt<Scalar> >::type& getRealPvt()
|
||||||
|
{
|
||||||
|
assert(approach() == approachV);
|
||||||
|
return *static_cast<Opm::ConstantCompressibilitySaltWaterPvt<Scalar>* >(realWaterPvt_);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <WaterPvtApproach approachV>
|
||||||
|
typename std::enable_if<approachV == ConstantCompressibilitySaltWaterPvt, const Opm::ConstantCompressibilitySaltWaterPvt<Scalar> >::type& getRealPvt() const
|
||||||
|
{
|
||||||
|
assert(approach() == approachV);
|
||||||
|
return *static_cast<Opm::ConstantCompressibilitySaltWaterPvt<Scalar>* >(realWaterPvt_);
|
||||||
|
}
|
||||||
|
|
||||||
template <WaterPvtApproach approachV>
|
template <WaterPvtApproach approachV>
|
||||||
typename std::enable_if<approachV == ThermalWaterPvt, Opm::WaterPvtThermal<Scalar> >::type& getRealPvt()
|
typename std::enable_if<approachV == ThermalWaterPvt, Opm::WaterPvtThermal<Scalar> >::type& getRealPvt()
|
||||||
{
|
{
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace Opm {
|
namespace Opm {
|
||||||
template <class Scalar, bool enableThermal>
|
template <class Scalar, bool enableThermal, bool enableSaltWater>
|
||||||
class WaterPvtMultiplexer;
|
class WaterPvtMultiplexer;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -56,7 +56,7 @@ class WaterPvtThermal
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef Opm::Tabulated1DFunction<Scalar> TabulatedOneDFunction;
|
typedef Opm::Tabulated1DFunction<Scalar> TabulatedOneDFunction;
|
||||||
typedef WaterPvtMultiplexer<Scalar, /*enableThermal=*/false> IsothermalPvt;
|
typedef WaterPvtMultiplexer<Scalar, /*enableThermal=*/false, false> IsothermalPvt;
|
||||||
|
|
||||||
WaterPvtThermal()
|
WaterPvtThermal()
|
||||||
{
|
{
|
||||||
@ -269,9 +269,10 @@ public:
|
|||||||
template <class Evaluation>
|
template <class Evaluation>
|
||||||
Evaluation viscosity(unsigned regionIdx,
|
Evaluation viscosity(unsigned regionIdx,
|
||||||
const Evaluation& temperature,
|
const Evaluation& temperature,
|
||||||
const Evaluation& pressure) const
|
const Evaluation& pressure,
|
||||||
|
const Evaluation& saltwaterconcentration) const
|
||||||
{
|
{
|
||||||
const auto& isothermalMu = isothermalPvt_->viscosity(regionIdx, temperature, pressure);
|
const auto& isothermalMu = isothermalPvt_->viscosity(regionIdx, temperature, pressure, saltwaterconcentration);
|
||||||
if (!enableThermalViscosity())
|
if (!enableThermalViscosity())
|
||||||
return isothermalMu;
|
return isothermalMu;
|
||||||
|
|
||||||
@ -289,10 +290,11 @@ public:
|
|||||||
template <class Evaluation>
|
template <class Evaluation>
|
||||||
Evaluation inverseFormationVolumeFactor(unsigned regionIdx,
|
Evaluation inverseFormationVolumeFactor(unsigned regionIdx,
|
||||||
const Evaluation& temperature,
|
const Evaluation& temperature,
|
||||||
const Evaluation& pressure) const
|
const Evaluation& pressure,
|
||||||
|
const Evaluation& saltwaterconcentration) const
|
||||||
{
|
{
|
||||||
if (!enableThermalDensity())
|
if (!enableThermalDensity())
|
||||||
return isothermalPvt_->inverseFormationVolumeFactor(regionIdx, temperature, pressure);
|
return isothermalPvt_->inverseFormationVolumeFactor(regionIdx, temperature, pressure, saltwaterconcentration);
|
||||||
|
|
||||||
Scalar BwRef = pvtwRefB_[regionIdx];
|
Scalar BwRef = pvtwRefB_[regionIdx];
|
||||||
Scalar TRef = watdentRefTemp_[regionIdx];
|
Scalar TRef = watdentRefTemp_[regionIdx];
|
||||||
|
@ -247,7 +247,8 @@ inline void testAll()
|
|||||||
refTmp = 1.1e-3; // the deck value is given in cP, while the SI units use Pa s...
|
refTmp = 1.1e-3; // the deck value is given in cP, while the SI units use Pa s...
|
||||||
tmp = constCompWaterPvt.viscosity(/*regionIdx=*/0,
|
tmp = constCompWaterPvt.viscosity(/*regionIdx=*/0,
|
||||||
/*temperature=*/273.15 + 20.0,
|
/*temperature=*/273.15 + 20.0,
|
||||||
/*pressure=*/1e5);
|
/*pressure=*/1e5,
|
||||||
|
/*saltconcentration=*/0.0);
|
||||||
if (std::abs(tmp - refTmp) > tolerance)
|
if (std::abs(tmp - refTmp) > tolerance)
|
||||||
throw std::logic_error("The reference water viscosity at region 0 is supposed to be "+std::to_string(refTmp)
|
throw std::logic_error("The reference water viscosity at region 0 is supposed to be "+std::to_string(refTmp)
|
||||||
+". (is "+std::to_string(tmp)+")");
|
+". (is "+std::to_string(tmp)+")");
|
||||||
@ -255,7 +256,8 @@ inline void testAll()
|
|||||||
refTmp = 1.2e-3;
|
refTmp = 1.2e-3;
|
||||||
tmp = constCompWaterPvt.viscosity(/*regionIdx=*/1,
|
tmp = constCompWaterPvt.viscosity(/*regionIdx=*/1,
|
||||||
/*temperature=*/273.15 + 20.0,
|
/*temperature=*/273.15 + 20.0,
|
||||||
/*pressure=*/2e5);
|
/*pressure=*/2e5,
|
||||||
|
/*saltconcentration=*/0.0);
|
||||||
if (std::abs(tmp - refTmp) > tolerance)
|
if (std::abs(tmp - refTmp) > tolerance)
|
||||||
throw std::logic_error("The reference water viscosity at region 1 is supposed to be "+std::to_string(refTmp)
|
throw std::logic_error("The reference water viscosity at region 1 is supposed to be "+std::to_string(refTmp)
|
||||||
+". (is "+std::to_string(tmp)+")");
|
+". (is "+std::to_string(tmp)+")");
|
||||||
|
Loading…
Reference in New Issue
Block a user