mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Merge pull request #5851 from svenn-t/dummy_water_compositional
Compositional simulator expanded to three phases
This commit is contained in:
@@ -83,6 +83,8 @@ struct EnableDispersion { using type = UndefinedProperty; };
|
||||
//! Enable convective mixing?
|
||||
template<class TypeTag, class MyTypeTag>
|
||||
struct EnableConvectiveMixing { using type = UndefinedProperty; };
|
||||
template <class TypeTag, class MyTypeTag>
|
||||
struct EnableWater { using type = UndefinedProperty; };
|
||||
|
||||
} // namespace Opm::Properties
|
||||
|
||||
|
||||
@@ -48,16 +48,20 @@ class FlashIndices
|
||||
{
|
||||
static constexpr int numComponents = getPropValue<TypeTag, Properties::NumComponents>();
|
||||
enum { enableEnergy = getPropValue<TypeTag, Properties::EnableEnergy>() };
|
||||
enum { enableWater = getPropValue<TypeTag, Properties::EnableWater>() };
|
||||
using EnergyIndices = Opm::EnergyIndices<PVOffset + numComponents, enableEnergy>;
|
||||
|
||||
public:
|
||||
static constexpr bool waterEnabled = false;
|
||||
//! All phases active (note: immiscible/"dummy" water phase)
|
||||
static constexpr bool waterEnabled = enableWater;
|
||||
static constexpr bool gasEnabled = true;
|
||||
static constexpr bool oilEnabled = true;
|
||||
static constexpr int waterPhaseIdx = -1;
|
||||
static constexpr int numPhases = 2;
|
||||
|
||||
//! number of active phases
|
||||
static constexpr int numPhases = enableWater ? 3 : 2;
|
||||
|
||||
//! number of equations/primary variables
|
||||
static const int numEq = numComponents + EnergyIndices::numEq_;
|
||||
static const int numEq = numComponents + EnergyIndices::numEq_ + (enableWater ? 1 : 0);
|
||||
|
||||
// Primary variable indices
|
||||
|
||||
@@ -66,6 +70,9 @@ public:
|
||||
|
||||
//! Index of the molefraction of the first component
|
||||
static constexpr int z0Idx = pressure0Idx + 1;
|
||||
|
||||
//! Index of water saturation
|
||||
static constexpr int water0Idx = enableWater ? z0Idx + numComponents - 1 : -1000;
|
||||
|
||||
// equation indices
|
||||
|
||||
|
||||
@@ -76,6 +76,9 @@ class FlashIntensiveQuantities
|
||||
enum { enableEnergy = getPropValue<TypeTag, Properties::EnableEnergy>() };
|
||||
enum { dimWorld = GridView::dimensionworld };
|
||||
enum { pressure0Idx = Indices::pressure0Idx };
|
||||
enum { water0Idx = Indices::water0Idx};
|
||||
|
||||
static constexpr bool waterEnabled = Indices::waterEnabled;
|
||||
|
||||
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
|
||||
using Evaluation = GetPropType<TypeTag, Properties::Evaluation>;
|
||||
@@ -216,19 +219,26 @@ public:
|
||||
|
||||
|
||||
// Update saturation
|
||||
// \Note: the current implementation assume oil-gas system.
|
||||
Evaluation Sw = 0.0;
|
||||
if constexpr (waterEnabled) {
|
||||
Sw = priVars.makeEvaluation(water0Idx, timeIdx);
|
||||
}
|
||||
Evaluation L = fluidState_.L();
|
||||
Evaluation So = Opm::max((L * Z_L / ( L * Z_L + (1 - L) * Z_V)), 0.0);
|
||||
Evaluation Sg = Opm::max(1 - So, 0.0);
|
||||
Scalar sumS = Opm::getValue(So) + Opm::getValue(Sg);
|
||||
Evaluation So = Opm::max((1 - Sw) * (L * Z_L / ( L * Z_L + (1 - L) * Z_V)), 0.0);
|
||||
Evaluation Sg = Opm::max(1 - So - Sw, 0.0);
|
||||
Scalar sumS = Opm::getValue(So) + Opm::getValue(Sg) + Opm::getValue(Sw);
|
||||
So /= sumS;
|
||||
Sg /= sumS;
|
||||
|
||||
fluidState_.setSaturation(0, So);
|
||||
fluidState_.setSaturation(1, Sg);
|
||||
fluidState_.setSaturation(FluidSystem::oilPhaseIdx, So);
|
||||
fluidState_.setSaturation(FluidSystem::gasPhaseIdx, Sg);
|
||||
if constexpr (waterEnabled) {
|
||||
Sw /= sumS;
|
||||
fluidState_.setSaturation(FluidSystem::waterPhaseIdx, Sw);
|
||||
}
|
||||
|
||||
fluidState_.setCompressFactor(0, Z_L);
|
||||
fluidState_.setCompressFactor(1, Z_V);
|
||||
fluidState_.setCompressFactor(FluidSystem::oilPhaseIdx, Z_L);
|
||||
fluidState_.setCompressFactor(FluidSystem::gasPhaseIdx, Z_V);
|
||||
|
||||
// Print saturation
|
||||
if (flashVerbosity >= 5) {
|
||||
@@ -250,7 +260,10 @@ public:
|
||||
|
||||
// set the phase viscosity and density
|
||||
for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
|
||||
paramCache.updatePhase(fluidState_, phaseIdx);
|
||||
if (phaseIdx == static_cast<unsigned int>(FluidSystem::oilPhaseIdx)
|
||||
|| phaseIdx == static_cast<unsigned int>(FluidSystem::gasPhaseIdx)) {
|
||||
paramCache.updatePhase(fluidState_, phaseIdx);
|
||||
}
|
||||
|
||||
const Evaluation& mu = FluidSystem::viscosity(fluidState_, paramCache, phaseIdx);
|
||||
|
||||
|
||||
@@ -49,18 +49,24 @@ class FlashLocalResidual: public GetPropType<TypeTag, Properties::DiscLocalResid
|
||||
using Indices = GetPropType<TypeTag, Properties::Indices>;
|
||||
using IntensiveQuantities = GetPropType<TypeTag, Properties::IntensiveQuantities>;
|
||||
using ElementContext = GetPropType<TypeTag, Properties::ElementContext>;
|
||||
using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
|
||||
|
||||
enum { numEq = getPropValue<TypeTag, Properties::NumEq>() };
|
||||
enum { numPhases = getPropValue<TypeTag, Properties::NumPhases>() };
|
||||
enum { numComponents = getPropValue<TypeTag, Properties::NumComponents>() };
|
||||
enum { water0Idx = Indices::water0Idx };
|
||||
enum { conti0EqIdx = Indices::conti0EqIdx };
|
||||
|
||||
enum { waterPhaseIdx = FluidSystem::waterPhaseIdx };
|
||||
|
||||
enum { enableDiffusion = getPropValue<TypeTag, Properties::EnableDiffusion>() };
|
||||
using DiffusionModule = Opm::DiffusionModule<TypeTag, enableDiffusion>;
|
||||
|
||||
enum { enableEnergy = getPropValue<TypeTag, Properties::EnableEnergy>() };
|
||||
using EnergyModule = Opm::EnergyModule<TypeTag, enableEnergy>;
|
||||
|
||||
static const bool waterEnabled = Indices::waterEnabled;
|
||||
|
||||
using Toolbox = Opm::MathToolbox<Evaluation>;
|
||||
|
||||
public:
|
||||
@@ -77,15 +83,25 @@ public:
|
||||
const IntensiveQuantities& intQuants = elemCtx.intensiveQuantities(dofIdx, timeIdx);
|
||||
const auto& fs = intQuants.fluidState();
|
||||
|
||||
// compute storage term of all components within all phases
|
||||
for (unsigned compIdx = 0; compIdx < numComponents; ++compIdx) {
|
||||
unsigned eqIdx = conti0EqIdx + compIdx;
|
||||
storage[eqIdx] +=
|
||||
Toolbox::template decay<LhsEval>(fs.massFraction(phaseIdx, compIdx))
|
||||
* Toolbox::template decay<LhsEval>(fs.density(phaseIdx))
|
||||
// compute water storage term
|
||||
if (waterEnabled && phaseIdx == static_cast<unsigned int>(waterPhaseIdx)) {
|
||||
unsigned eqIdx = conti0EqIdx + numComponents;
|
||||
storage[eqIdx] =
|
||||
Toolbox::template decay<LhsEval>(fs.density(phaseIdx))
|
||||
* Toolbox::template decay<LhsEval>(fs.saturation(phaseIdx))
|
||||
* Toolbox::template decay<LhsEval>(intQuants.porosity());
|
||||
}
|
||||
else {
|
||||
// compute storage term of all components within oil/gas phases
|
||||
for (unsigned compIdx = 0; compIdx < numComponents; ++compIdx) {
|
||||
unsigned eqIdx = conti0EqIdx + compIdx;
|
||||
storage[eqIdx] +=
|
||||
Toolbox::template decay<LhsEval>(fs.massFraction(phaseIdx, compIdx))
|
||||
* Toolbox::template decay<LhsEval>(fs.density(phaseIdx))
|
||||
* Toolbox::template decay<LhsEval>(fs.saturation(phaseIdx))
|
||||
* Toolbox::template decay<LhsEval>(intQuants.porosity());
|
||||
}
|
||||
}
|
||||
|
||||
EnergyModule::addPhaseStorage(storage, elemCtx.intensiveQuantities(dofIdx, timeIdx), phaseIdx);
|
||||
}
|
||||
@@ -146,19 +162,31 @@ public:
|
||||
up.fluidState().density(phaseIdx)
|
||||
* extQuants.volumeFlux(phaseIdx);
|
||||
|
||||
for (unsigned compIdx = 0; compIdx < numComponents; ++compIdx) {
|
||||
flux[conti0EqIdx + compIdx] +=
|
||||
tmp*up.fluidState().massFraction(phaseIdx, compIdx);
|
||||
if (waterEnabled && phaseIdx == static_cast<unsigned int>(waterPhaseIdx)) {
|
||||
unsigned eqIdx = conti0EqIdx + numComponents;
|
||||
flux[eqIdx] = tmp;
|
||||
}
|
||||
else {
|
||||
for (unsigned compIdx = 0; compIdx < numComponents; ++compIdx) {
|
||||
flux[conti0EqIdx + compIdx] +=
|
||||
tmp*up.fluidState().massFraction(phaseIdx, compIdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
Evaluation tmp =
|
||||
Toolbox::value(up.fluidState().density(phaseIdx))
|
||||
* extQuants.volumeFlux(phaseIdx);
|
||||
|
||||
for (unsigned compIdx = 0; compIdx < numComponents; ++compIdx) {
|
||||
flux[conti0EqIdx + compIdx] +=
|
||||
tmp*Toolbox::value(up.fluidState().massFraction(phaseIdx, compIdx));
|
||||
|
||||
if (waterEnabled && phaseIdx == static_cast<unsigned int>(waterPhaseIdx)) {
|
||||
unsigned eqIdx = conti0EqIdx + numComponents;
|
||||
flux[eqIdx] = tmp;
|
||||
}
|
||||
else {
|
||||
for (unsigned compIdx = 0; compIdx < numComponents; ++compIdx) {
|
||||
flux[conti0EqIdx + compIdx] +=
|
||||
tmp*Toolbox::value(up.fluidState().massFraction(phaseIdx, compIdx));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,6 +135,10 @@ template<class TypeTag>
|
||||
struct EnableEnergy<TypeTag, TTag::FlashModel>
|
||||
{ static constexpr bool value = false; };
|
||||
|
||||
template<class TypeTag>
|
||||
struct EnableWater<TypeTag, TTag::MultiPhaseBaseModel>
|
||||
{ static constexpr int value = GetPropType<TypeTag, Properties::FluidSystem>::waterEnabled; };
|
||||
|
||||
} // namespace Opm::Properties
|
||||
|
||||
namespace Opm {
|
||||
|
||||
@@ -63,6 +63,8 @@ class FlashNewtonMethod : public GetPropType<TypeTag, Properties::DiscNewtonMeth
|
||||
enum { z0Idx = Indices::z0Idx };
|
||||
enum { numComponents = getPropValue<TypeTag, Properties::NumComponents>() };
|
||||
|
||||
static constexpr bool waterEnabled = Indices::waterEnabled;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* \copydoc FvBaseNewtonMethod::FvBaseNewtonMethod(Problem& )
|
||||
@@ -125,6 +127,14 @@ protected:
|
||||
for (unsigned compIdx = 0; compIdx < numComponents - 1; ++compIdx) {
|
||||
clampValue_(nextValue[z0Idx + compIdx], tol, 1-tol);
|
||||
}
|
||||
|
||||
if constexpr (waterEnabled) {
|
||||
// limit change in water saturation to 0.2
|
||||
constexpr Scalar dSwMax = 0.2;
|
||||
if (update[Indices::water0Idx] > dSwMax) {
|
||||
nextValue[Indices::water0Idx] = currentValue[Indices::water0Idx] - dSwMax;
|
||||
}
|
||||
}
|
||||
}
|
||||
private:
|
||||
void clampValue_(Scalar& val, Scalar minVal, Scalar maxVal) const
|
||||
|
||||
@@ -61,6 +61,14 @@ class FlashPrimaryVariables : public FvBasePrimaryVariables<TypeTag>
|
||||
// primary variable indices
|
||||
enum { z0Idx = Indices::z0Idx };
|
||||
enum { pressure0Idx = Indices::pressure0Idx };
|
||||
enum { water0Idx = Indices::water0Idx };
|
||||
|
||||
static constexpr bool waterEnabled = Indices::waterEnabled;
|
||||
|
||||
// phase indices
|
||||
enum { gasPhaseIdx = FluidSystem::gasPhaseIdx };
|
||||
enum { waterPhaseIdx = FluidSystem::waterPhaseIdx };
|
||||
enum { oilPhaseIdx = FluidSystem::oilPhaseIdx };
|
||||
|
||||
enum { numPhases = getPropValue<TypeTag, Properties::NumPhases>() };
|
||||
enum { numComponents = getPropValue<TypeTag, Properties::NumComponents>() };
|
||||
@@ -108,10 +116,17 @@ public:
|
||||
// the energy module
|
||||
EnergyModule::setPriVarTemperatures(*this, fluidState);
|
||||
|
||||
// assign components total fraction
|
||||
for (int i = 0; i < numComponents - 1; ++i)
|
||||
(*this)[z0Idx + i] = getValue(fluidState.moleFraction(i));
|
||||
|
||||
(*this)[pressure0Idx] = getValue(fluidState.pressure(0));
|
||||
// assign pressure
|
||||
(*this)[pressure0Idx] = getValue(fluidState.pressure(oilPhaseIdx));
|
||||
|
||||
// assign water saturation
|
||||
if constexpr (waterEnabled) {
|
||||
(*this)[water0Idx] = getValue(fluidState.saturation(waterPhaseIdx));
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -121,12 +136,15 @@ public:
|
||||
*/
|
||||
void print(std::ostream& os = std::cout) const
|
||||
{
|
||||
os << "(p_" << FluidSystem::phaseName(0) << " = "
|
||||
os << "(p_" << FluidSystem::phaseName(FluidSystem::oilPhaseIdx) << " = "
|
||||
<< this->operator[](pressure0Idx);
|
||||
for (unsigned compIdx = 0; compIdx < numComponents - 2; ++compIdx) {
|
||||
os << ", z_" << FluidSystem::componentName(compIdx) << " = "
|
||||
<< this->operator[](z0Idx + compIdx);
|
||||
}
|
||||
if constexpr (waterEnabled) {
|
||||
os << ", S_w = " << this->operator[](water0Idx);
|
||||
}
|
||||
os << ")" << std::flush;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#include <opm/material/fluidsystems/BlackOilDefaultIndexTraits.hpp>
|
||||
#include <opm/material/fluidsystems/BlackOilFluidSystem.hpp>
|
||||
#include <opm/material/fluidsystems/GenericOilGasFluidSystem.hpp>
|
||||
#include <opm/material/fluidsystems/GenericOilGasWaterFluidSystem.hpp>
|
||||
|
||||
#include <opm/output/data/Solution.hpp>
|
||||
|
||||
@@ -438,11 +438,19 @@ INSTANTIATE_TYPE(double)
|
||||
INSTANTIATE_TYPE(float)
|
||||
#endif
|
||||
|
||||
#define INSTANTIATE_COMP(NUM) \
|
||||
template<class T> using FS##NUM = GenericOilGasFluidSystem<T, NUM>; \
|
||||
#define INSTANTIATE_COMP_THREEPHASE(NUM) \
|
||||
template<class T> using FS##NUM = GenericOilGasWaterFluidSystem<T, NUM, true>; \
|
||||
template class FIPContainer<FS##NUM<double>>;
|
||||
|
||||
INSTANTIATE_COMP(0)
|
||||
#define INSTANTIATE_COMP_TWOPHASE(NUM) \
|
||||
template<class T> using GFS##NUM = GenericOilGasWaterFluidSystem<T, NUM, false>; \
|
||||
template class FIPContainer<GFS##NUM<double>>;
|
||||
|
||||
#define INSTANTIATE_COMP(NUM) \
|
||||
INSTANTIATE_COMP_THREEPHASE(NUM) \
|
||||
INSTANTIATE_COMP_TWOPHASE(NUM)
|
||||
|
||||
INSTANTIATE_COMP_THREEPHASE(0) // \Note: to register the parameter ForceDisableFluidInPlaceOutput
|
||||
INSTANTIATE_COMP(2)
|
||||
INSTANTIATE_COMP(3)
|
||||
INSTANTIATE_COMP(4)
|
||||
|
||||
@@ -362,6 +362,9 @@ public:
|
||||
Dune::FieldVector<Scalar, numComponents> z(0.0);
|
||||
Scalar sumMoles = 0.0;
|
||||
for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
|
||||
if (Indices::waterEnabled && phaseIdx == static_cast<unsigned int>(waterPhaseIdx)){
|
||||
continue;
|
||||
}
|
||||
const auto saturation = fs.saturation(phaseIdx);
|
||||
for (unsigned compIdx = 0; compIdx < numComponents; ++compIdx) {
|
||||
Scalar tmp = fs.molarity(phaseIdx, compIdx) * saturation;
|
||||
@@ -491,7 +494,7 @@ protected:
|
||||
const bool gas_active = FluidSystem::phaseIsActive(gasPhaseIdx);
|
||||
const bool oil_active = FluidSystem::phaseIsActive(oilPhaseIdx);
|
||||
|
||||
if (water_active && Indices::numPhases > 1)
|
||||
if (water_active && Indices::numPhases > 2)
|
||||
waterSaturationData = fp.get_double("SWAT");
|
||||
else
|
||||
waterSaturationData.resize(numDof);
|
||||
@@ -527,6 +530,10 @@ protected:
|
||||
- waterSaturationData[dofIdx]
|
||||
- gasSaturationData[dofIdx]);
|
||||
}
|
||||
if (water_active) {
|
||||
dofFluidState.setSaturation(FluidSystem::waterPhaseIdx,
|
||||
waterSaturationData[dofIdx]);
|
||||
}
|
||||
|
||||
//////
|
||||
// set phase pressures
|
||||
|
||||
@@ -69,17 +69,10 @@ private:
|
||||
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
|
||||
using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
|
||||
|
||||
// using Traits = ThreePhaseMaterialTraits<Scalar,
|
||||
// /*wettingPhaseIdx=*/FluidSystem::waterPhaseIdx,
|
||||
// /*nonWettingPhaseIdx=*/FluidSystem::oilPhaseIdx,
|
||||
// /*gasPhaseIdx=*/FluidSystem::gasPhaseIdx>;
|
||||
|
||||
// TODO: We should be able to use FluidSystem here and using Indices to handle the active phases
|
||||
// some more development is needed
|
||||
using Traits = ThreePhaseMaterialTraits<Scalar,
|
||||
/*wettingPhaseIdx=*/ 0,
|
||||
/*nonWettingPhaseIdx=*/ 1,
|
||||
/*gasPhaseIdx=*/ 2>;
|
||||
/*wettingPhaseIdx=*/FluidSystem::waterPhaseIdx,
|
||||
/*nonWettingPhaseIdx=*/FluidSystem::oilPhaseIdx,
|
||||
/*gasPhaseIdx=*/FluidSystem::gasPhaseIdx>;
|
||||
|
||||
public:
|
||||
using EclMaterialLawManager = ::Opm::EclMaterialLawManager<Traits>;
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include <opm/material/fluidsystems/BlackOilFluidSystem.hpp>
|
||||
#include <opm/material/fluidsystems/BlackOilDefaultIndexTraits.hpp>
|
||||
|
||||
#include <opm/material/fluidsystems/GenericOilGasFluidSystem.hpp>
|
||||
#include <opm/material/fluidsystems/GenericOilGasWaterFluidSystem.hpp>
|
||||
|
||||
#include <opm/input/eclipse/EclipseState/EclipseState.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Runspec.hpp>
|
||||
@@ -1522,12 +1522,19 @@ INSTANTIATE_TYPE(double)
|
||||
INSTANTIATE_TYPE(float)
|
||||
#endif
|
||||
|
||||
#define INSTANTIATE_COMP(NUM) \
|
||||
template<class T> using FS##NUM = GenericOilGasFluidSystem<T, NUM>; \
|
||||
#define INSTANTIATE_COMP_THREEPHASE(NUM) \
|
||||
template<class T> using FS##NUM = GenericOilGasWaterFluidSystem<T, NUM, true>; \
|
||||
template class GenericOutputBlackoilModule<FS##NUM<double>>;
|
||||
|
||||
INSTANTIATE_COMP(0) // \Note: to register the parameter ForceDisableFluidInPlaceOutput
|
||||
#define INSTANTIATE_COMP_TWOPHASE(NUM) \
|
||||
template<class T> using GFS##NUM = GenericOilGasWaterFluidSystem<T, NUM, false>; \
|
||||
template class GenericOutputBlackoilModule<GFS##NUM<double>>;
|
||||
|
||||
#define INSTANTIATE_COMP(NUM) \
|
||||
INSTANTIATE_COMP_THREEPHASE(NUM) \
|
||||
INSTANTIATE_COMP_TWOPHASE(NUM)
|
||||
|
||||
INSTANTIATE_COMP_THREEPHASE(0) // \Note: to register the parameter ForceDisableFluidInPlaceOutput
|
||||
INSTANTIATE_COMP(2)
|
||||
INSTANTIATE_COMP(3)
|
||||
INSTANTIATE_COMP(4)
|
||||
|
||||
Reference in New Issue
Block a user