Refactor primary variable switching meaning

The primary variable meaning enums are split into three
water, gas and pressure to allow for all combination
of the variables. This simplify the code and logic
it also make it easier to add more swithing options.
This commit is contained in:
Tor Harald Sandve
2022-11-23 15:35:56 +01:00
parent 6cd200a254
commit 2d70d08fdc
8 changed files with 514 additions and 740 deletions

View File

@@ -619,17 +619,14 @@ public:
Evaluation pbub = fs.pressure(oilPhaseIdx);
if (priVars.primaryVarsMeaning() == PrimaryVariables::Sw_po_Sg) {
if (priVars.primaryVarsMeaningWater() == PrimaryVariables::Sw) {
static const Scalar thresholdWaterFilledCell = 1.0 - 1e-6;
Scalar Sw = 0.0;
if (Indices::waterEnabled)
Sw = priVars.makeEvaluation(Indices::waterSaturationIdx, timeIdx).value();
if (Sw >= thresholdWaterFilledCell)
Scalar sw = priVars.makeEvaluation(Indices::waterSaturationIdx, timeIdx).value();
if (sw >= thresholdWaterFilledCell)
rs_ = 0.0; // water only, zero rs_ ...
}
if (priVars.primaryVarsMeaning() == PrimaryVariables::Sw_po_Rs) {
if (priVars.primaryVarsMeaningGas() == PrimaryVariables::Rs) {
rs_ = priVars.makeEvaluation(Indices::compositionSwitchIdx, timeIdx);
const Evaluation zLim = ExtboModule::zLim(pvtRegionIdx);
if (zFraction_ > zLim) {
@@ -642,7 +639,7 @@ public:
xVolume_ = ExtboModule::xVolume(pvtRegionIdx, pbub, zFraction_);
}
if (priVars.primaryVarsMeaning() == PrimaryVariables::Sw_pg_Rv) {
if (priVars.primaryVarsMeaningGas() == PrimaryVariables::Rv) {
rv_ = priVars.makeEvaluation(Indices::compositionSwitchIdx, timeIdx);
Evaluation rvsat = ExtboModule::rv(pvtRegionIdx, pbub, zFraction_);
bg_ = ExtboModule::bg(pvtRegionIdx, pbub, zFraction_) + ExtboModule::gasCmp(pvtRegionIdx, zFraction_)*(rv_-rvsat);

View File

@@ -96,10 +96,20 @@ struct BlackOilIndices
// Primary variable indices
////////
//! The index of the water saturation
/*!
* \brief Index of the switching variable which determines the composistion of the water phase
*
* Depending on the phases present, this variable is either interpreted as
* water saturation or vapporized water in gas phase
*/
static const int waterSaturationIdx = PVOffset + 0;
//! Index of the oil pressure in a vector of primary variables
/*!
* \brief Index of the switching variable which determines the pressure
*
* Depending on the phases present, this variable is either interpreted as the
* pressure of the oil phase, gas phase (if no oil) or water phase (if only water)
*/
static const int pressureSwitchIdx = PVOffset + 1;
/*!

View File

@@ -184,44 +184,28 @@ public:
// extract the water and the gas saturations for convenience
Evaluation Sw = 0.0;
if constexpr (waterEnabled) {
if (priVars.primaryVarsMeaning() == PrimaryVariables::OnePhase_p) {
Sw = 1.0;
} else if (priVars.primaryVarsMeaning() != PrimaryVariables::Rvw_po_Sg && priVars.primaryVarsMeaning() != PrimaryVariables::Rvw_pg_Rv) {
if (priVars.primaryVarsMeaningWater() == PrimaryVariables::Sw) {
Sw = priVars.makeEvaluation(Indices::waterSaturationIdx, timeIdx);
} else if (priVars.primaryVarsMeaningWater() == PrimaryVariables::W_disabled){
// water is enabled but is not a primary variable i.e. one phase case
Sw = 1.0;
}
}
Evaluation Sg = 0.0;
if constexpr (compositionSwitchEnabled)
{
if (priVars.primaryVarsMeaning() == PrimaryVariables::Sw_po_Sg) {
// -> threephase case
assert( priVars.primaryVarsMeaning() != PrimaryVariables::OnePhase_p );
if constexpr (gasEnabled) {
if (priVars.primaryVarsMeaningGas() == PrimaryVariables::Sg) {
Sg = priVars.makeEvaluation(Indices::compositionSwitchIdx, timeIdx);
} else if (priVars.primaryVarsMeaning() == PrimaryVariables::Sw_pg_Rv) {
// -> gas-water case
} else if (priVars.primaryVarsMeaningGas() == PrimaryVariables::Rv) {
Sg = 1.0 - Sw;
// deal with solvent
if (enableSolvent)
Sg -= priVars.makeEvaluation(Indices::solventSaturationIdx, timeIdx);
} else if (priVars.primaryVarsMeaning() == PrimaryVariables::Rvw_po_Sg) {
// -> oil-gas case
Sg = priVars.makeEvaluation(Indices::compositionSwitchIdx, timeIdx);
} else if (priVars.primaryVarsMeaning() == PrimaryVariables::Rvw_pg_Rv) {
// -> gas case
Sg = 1.0;
} else
{
assert(priVars.primaryVarsMeaning() == PrimaryVariables::Sw_po_Rs);
// -> oil-water case
Sg = 0.0;
} else if (priVars.primaryVarsMeaningGas() == PrimaryVariables::G_disabled) {
if constexpr (waterEnabled) {
Sg = 1.0 - Sw; // two phase water + gas
} else {
// one phase case
Sg = 1.0;
}
}
}
if constexpr (gasEnabled && waterEnabled && !oilEnabled) {
Sg = 1.0 - Sw;
}
Valgrind::CheckDefined(Sg);
Valgrind::CheckDefined(Sw);
@@ -249,14 +233,18 @@ public:
problem.updateRelperms(mobility_, dirMob_, fluidState_, globalSpaceIdx);
// oil is the reference phase for pressure
if (priVars.primaryVarsMeaning() == PrimaryVariables::Sw_pg_Rv || priVars.primaryVarsMeaning() == PrimaryVariables::Rvw_pg_Rv) {
if (priVars.primaryVarsMeaningPressure() == PrimaryVariables::Pg) {
const Evaluation& pg = priVars.makeEvaluation(Indices::pressureSwitchIdx, timeIdx);
for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
if (FluidSystem::phaseIsActive(phaseIdx))
fluidState_.setPressure(phaseIdx, pg + (pC[phaseIdx] - pC[gasPhaseIdx]));
}
else {
//} else if (priVars.primaryVarsMeaningPressure() == PrimaryVariables::Pw) {
// const Evaluation& pw = priVars.makeEvaluation(Indices::pressureSwitchIdx, timeIdx);
// for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
// if (FluidSystem::phaseIsActive(phaseIdx))
// fluidState_.setPressure(phaseIdx, pw + (pC[phaseIdx] - pC[waterPhaseIdx]));
} else {
//assert(FluidSystem::phaseIsActive(oilPhaseIdx));
const Evaluation& po = priVars.makeEvaluation(Indices::pressureSwitchIdx, timeIdx);
for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
if (FluidSystem::phaseIsActive(phaseIdx))
@@ -277,141 +265,48 @@ public:
// take the meaning of the switching primary variable into account for the gas
// and oil phase compositions
if (priVars.primaryVarsMeaning() == PrimaryVariables::Sw_po_Sg) {
// in the threephase case, gas and oil phases are potentially present, i.e.,
// we use the compositions of the gas-saturated oil and oil-saturated gas.
if (FluidSystem::enableDissolvedGas()) {
const Evaluation& RsSat = enableExtbo ? asImp_().rs() :
FluidSystem::saturatedDissolutionFactor(fluidState_,
oilPhaseIdx,
pvtRegionIdx,
SoMax);
fluidState_.setRs(min(RsMax, RsSat));
}
else if constexpr (compositionSwitchEnabled)
fluidState_.setRs(0.0);
if (FluidSystem::enableVaporizedOil()) {
const Evaluation& RvSat = enableExtbo ? asImp_().rv() :
FluidSystem::saturatedDissolutionFactor(fluidState_,
gasPhaseIdx,
pvtRegionIdx,
SoMax);
fluidState_.setRv(min(RvMax, RvSat));
}
else if constexpr (compositionSwitchEnabled)
fluidState_.setRv(0.0);
if (FluidSystem::enableVaporizedWater()) {
const Evaluation& RvwSat = FluidSystem::saturatedVaporizationFactor(fluidState_,
gasPhaseIdx,
pvtRegionIdx);
fluidState_.setRvw(RvwSat);
}
}
else if (priVars.primaryVarsMeaning() == PrimaryVariables::Rvw_po_Sg) {
// The switching variable is the water-gas ratio Rvw
const auto& Rvw = priVars.makeEvaluation(Indices::waterSaturationIdx, timeIdx);
fluidState_.setRvw(Rvw);
if (FluidSystem::enableDissolvedGas()) {
const Evaluation& RsSat = enableExtbo ? asImp_().rs() :
FluidSystem::saturatedDissolutionFactor(fluidState_,
oilPhaseIdx,
pvtRegionIdx,
SoMax);
fluidState_.setRs(min(RsMax, RsSat));
}
else if constexpr (compositionSwitchEnabled)
fluidState_.setRs(0.0);
if (FluidSystem::enableVaporizedOil()) {
const Evaluation& RvSat = enableExtbo ? asImp_().rv() :
FluidSystem::saturatedDissolutionFactor(fluidState_,
gasPhaseIdx,
pvtRegionIdx,
SoMax);
fluidState_.setRv(min(RvMax, RvSat));
}
else if constexpr (compositionSwitchEnabled)
fluidState_.setRv(0.0);
}
else if (priVars.primaryVarsMeaning() == PrimaryVariables::Rvw_pg_Rv) {
// The switching variable is the water-gas ratio Rvw
const auto& Rvw = priVars.makeEvaluation(Indices::waterSaturationIdx, timeIdx);
fluidState_.setRvw(Rvw);
const auto& Rv = priVars.makeEvaluation(Indices::compositionSwitchIdx, timeIdx);
fluidState_.setRv(Rv);
if (FluidSystem::enableDissolvedGas()) {
// the oil phase is not present, but we need to compute its "composition" for
// the gravity correction anyway
const auto& RsSat = enableExtbo ? asImp_().rs() :
FluidSystem::saturatedDissolutionFactor(fluidState_,
oilPhaseIdx,
pvtRegionIdx,
SoMax);
fluidState_.setRs(min(RsMax, RsSat));
}
else {
fluidState_.setRs(0.0);
}
}
else if (priVars.primaryVarsMeaning() == PrimaryVariables::Sw_po_Rs) {
// if the switching variable is the mole fraction of the gas component in the
// oil phase, we can directly set the composition of the oil phase
if (priVars.primaryVarsMeaningGas() == PrimaryVariables::Rs) {
const auto& Rs = priVars.makeEvaluation(Indices::compositionSwitchIdx, timeIdx);
fluidState_.setRs(min(RsMax, Rs));
if (FluidSystem::enableVaporizedOil()) {
// the gas phase is not present, but we need to compute its "composition"
// for the gravity correction anyway
const auto& RvSat = enableExtbo ? asImp_().rv() :
FluidSystem::saturatedDissolutionFactor(fluidState_,
gasPhaseIdx,
pvtRegionIdx,
SoMax);
fluidState_.setRv(min(RvMax, RvSat));
}
else
fluidState_.setRv(0.0);
if (FluidSystem::enableVaporizedWater()) {
const Evaluation& RvwSat = FluidSystem::saturatedVaporizationFactor(fluidState_,
gasPhaseIdx,
pvtRegionIdx);
fluidState_.setRvw(RvwSat);
}
}
else if (priVars.primaryVarsMeaning() == PrimaryVariables::Sw_pg_Rv) {
const auto& Rv = priVars.makeEvaluation(Indices::compositionSwitchIdx, timeIdx);
fluidState_.setRv(Rv);
if (FluidSystem::enableDissolvedGas()) {
// the oil phase is not present, but we need to compute its "composition" for
// the gravity correction anyway
const auto& RsSat = enableExtbo ? asImp_().rs() :
fluidState_.setRs(Rs);
} else {
if (FluidSystem::enableDissolvedGas()) { // Add So > 0? i.e. if only water set rs = 0)
const Evaluation& RsSat = enableExtbo ? asImp_().rs() :
FluidSystem::saturatedDissolutionFactor(fluidState_,
oilPhaseIdx,
pvtRegionIdx,
SoMax);
fluidState_.setRs(min(RsMax, RsSat));
} else {
fluidState_.setRs(0.0);
}
else if constexpr (compositionSwitchEnabled)
fluidState_.setRs(0.0);
}
if (FluidSystem::enableVaporizedWater()) {
if (priVars.primaryVarsMeaningGas() == PrimaryVariables::Rv) {
const auto& Rv = priVars.makeEvaluation(Indices::compositionSwitchIdx, timeIdx);
fluidState_.setRv(Rv);
} else {
if (FluidSystem::enableVaporizedOil() ) { // Add Sg > 0? i.e. if only water set rv = 0)
const Evaluation& RvSat = enableExtbo ? asImp_().rv() :
FluidSystem::saturatedDissolutionFactor(fluidState_,
gasPhaseIdx,
pvtRegionIdx,
SoMax);
fluidState_.setRv(min(RvMax, RvSat));
}
else if constexpr (compositionSwitchEnabled)
fluidState_.setRv(0.0);
}
if (priVars.primaryVarsMeaningWater() == PrimaryVariables::Rvw) {
const auto& Rvw = priVars.makeEvaluation(Indices::waterSaturationIdx, timeIdx);
fluidState_.setRvw(Rvw);
} else {
if (FluidSystem::enableVaporizedWater()) { // Add Sg > 0? i.e. if only water set rv = 0)
const Evaluation& RvwSat = FluidSystem::saturatedVaporizationFactor(fluidState_,
gasPhaseIdx,
pvtRegionIdx);
fluidState_.setRvw(RvwSat);
}
} else {
assert(priVars.primaryVarsMeaning() == PrimaryVariables::OnePhase_p);
}
typename FluidSystem::template ParameterCache<Evaluation> paramCache;

View File

@@ -423,13 +423,13 @@ public:
// if the primary variable is either the gas saturation, Rs or Rv
assert(int(Indices::compositionSwitchIdx) == int(pvIdx));
auto pvMeaning = this->solution(0)[globalDofIdx].primaryVarsMeaning();
if (pvMeaning == PrimaryVariables::Sw_po_Sg)
auto pvMeaning = this->solution(0)[globalDofIdx].primaryVarsMeaningGas();
if (pvMeaning == PrimaryVariables::Sg)
return 1.0; // gas saturation
else if (pvMeaning == PrimaryVariables::Sw_po_Rs)
else if (pvMeaning == PrimaryVariables::Rs)
return 1.0/250.; // gas dissolution factor
else {
assert(pvMeaning == PrimaryVariables::Sw_pg_Rv);
assert(pvMeaning == PrimaryVariables::Rv);
return 1.0/0.025; // oil vaporization factor
}
@@ -475,7 +475,10 @@ public:
outstream << priVars[eqIdx] << " ";
// write the pseudo primary variables
outstream << priVars.primaryVarsMeaning() << " ";
outstream << priVars.primaryVarsMeaningGas() << " ";
outstream << priVars.primaryVarsMeaningWater() << " ";
outstream << priVars.primaryVarsMeaningPressure() << " ";
outstream << priVars.pvtRegionIndex() << " ";
SolventModule::serializeEntity(*this, outstream, dof);
@@ -507,8 +510,14 @@ public:
}
// read the pseudo primary variables
unsigned primaryVarsMeaning;
instream >> primaryVarsMeaning;
unsigned primaryVarsMeaningGas;
instream >> primaryVarsMeaningGas;
unsigned primaryVarsMeaningWater;
instream >> primaryVarsMeaningWater;
unsigned primaryVarsMeaningPressure;
instream >> primaryVarsMeaningPressure;
unsigned pvtRegionIdx;
instream >> pvtRegionIdx;
@@ -521,8 +530,13 @@ public:
PolymerModule::deserializeEntity(*this, instream, dof);
EnergyModule::deserializeEntity(*this, instream, dof);
using PVM = typename PrimaryVariables::PrimaryVarsMeaning;
priVars.setPrimaryVarsMeaning(static_cast<PVM>(primaryVarsMeaning));
using PVM_G = typename PrimaryVariables::PrimaryVarsMeaningGas;
using PVM_W = typename PrimaryVariables::PrimaryVarsMeaningWater;
using PVM_P = typename PrimaryVariables::PrimaryVarsMeaningPressure;
priVars.setPrimaryVarsMeaningGas(static_cast<PVM_G>(primaryVarsMeaningGas));
priVars.setPrimaryVarsMeaningWater(static_cast<PVM_W>(primaryVarsMeaningWater));
priVars.setPrimaryVarsMeaningPressure(static_cast<PVM_P>(primaryVarsMeaningPressure));
priVars.setPvtRegionIndex(pvtRegionIdx);
}

View File

@@ -249,7 +249,6 @@ protected:
static constexpr bool enableEnergy = Indices::temperatureIdx >= 0;
static constexpr bool enableFoam = Indices::foamConcentrationIdx >= 0;
static constexpr bool enableBrine = Indices::saltConcentrationIdx >= 0;
static constexpr bool compositionSwitchEnabled = Indices::compositionSwitchIdx >= 0;
static constexpr bool enableMICP = Indices::microbialConcentrationIdx >= 0;
currentValue.checkDefined();
@@ -262,19 +261,16 @@ protected:
Scalar deltaSg = 0.0;
Scalar deltaSs = 0.0;
if (Indices::waterEnabled && FluidSystem::numActivePhases() > 1
&& currentValue.primaryVarsMeaning() != PrimaryVariables::Rvw_po_Sg
&& currentValue.primaryVarsMeaning() != PrimaryVariables::Rvw_pg_Rv) {
if (currentValue.primaryVarsMeaningWater() == PrimaryVariables::Sw)
{
deltaSw = update[Indices::waterSaturationIdx];
deltaSo = -deltaSw;
deltaSo -= deltaSw;
}
if (compositionSwitchEnabled && (currentValue.primaryVarsMeaning() == PrimaryVariables::Sw_po_Sg
|| currentValue.primaryVarsMeaning() == PrimaryVariables::Rvw_po_Sg)) {
if (currentValue.primaryVarsMeaningGas() == PrimaryVariables::Sg)
{
deltaSg = update[Indices::compositionSwitchIdx];
deltaSo -= deltaSg;
}
if (enableSolvent) {
deltaSs = update[Indices::solventSaturationIdx];
deltaSo -= deltaSs;
@@ -307,10 +303,9 @@ protected:
}
// water saturation delta
else if (pvIdx == Indices::waterSaturationIdx)
if (currentValue.primaryVarsMeaning() != PrimaryVariables::Rvw_po_Sg
&& currentValue.primaryVarsMeaning() != PrimaryVariables::Rvw_pg_Rv)
if (currentValue.primaryVarsMeaningWater() == PrimaryVariables::Sw)
delta *= satAlpha;
else{
else {
//Ensure Rvw factor does not become negative
if (delta > currentValue[ Indices::waterSaturationIdx])
delta = currentValue[ Indices::waterSaturationIdx];
@@ -321,10 +316,10 @@ protected:
// interpretation since it can represent Sg, Rs or Rv. For now, we only
// limit saturation deltas and ensure that the R factors do not become
// negative.
if (currentValue.primaryVarsMeaning() == PrimaryVariables::Sw_po_Sg
|| currentValue.primaryVarsMeaning() == PrimaryVariables::Rvw_po_Sg)
if (currentValue.primaryVarsMeaningGas() == PrimaryVariables::Sg)
delta *= satAlpha;
else {
//Ensure Rv and Rs factor does not become negative
if (delta > currentValue[Indices::compositionSwitchIdx])
delta = currentValue[Indices::compositionSwitchIdx];
}

File diff suppressed because it is too large Load Diff

View File

@@ -733,7 +733,7 @@ public:
//oil is the reference phase for pressure
const auto linearizationType = elemCtx.linearizationType();
if (priVars.primaryVarsMeaning() == PrimaryVariables::Sw_pg_Rv)
if (priVars.primaryVarsMeaningPressure() == PrimaryVariables::Pg)
pgMisc = priVars.makeEvaluation(Indices::pressureSwitchIdx, timeIdx, linearizationType);
else {
const Evaluation& po = priVars.makeEvaluation(Indices::pressureSwitchIdx, timeIdx, linearizationType);

View File

@@ -204,8 +204,11 @@ public:
this->resizeScalarBuffer_(oilSaturationRatio_);
this->resizeScalarBuffer_(gasSaturationRatio_);
}
if (primaryVarsMeaningOutput_())
this->resizeScalarBuffer_(primaryVarsMeaning_);
if (primaryVarsMeaningOutput_()) {
this->resizeScalarBuffer_(primaryVarsMeaningPressure_);
this->resizeScalarBuffer_(primaryVarsMeaningWater_);
this->resizeScalarBuffer_(primaryVarsMeaningGas_);
}
}
/*!
@@ -289,9 +292,14 @@ public:
waterFormationVolumeFactor_[globalDofIdx] =
1.0/FluidSystem::template inverseFormationVolumeFactor<FluidState, Scalar>(fs, waterPhaseIdx, pvtRegionIdx);
if (primaryVarsMeaningOutput_())
primaryVarsMeaning_[globalDofIdx] =
primaryVars.primaryVarsMeaning();
if (primaryVarsMeaningOutput_()) {
primaryVarsMeaningWater_[globalDofIdx] =
primaryVars.primaryVarsMeaningWater();
primaryVarsMeaningGas_[globalDofIdx] =
primaryVars.primaryVarsMeaningGas();
primaryVarsMeaningPressure_[globalDofIdx] =
primaryVars.primaryVarsMeaningPressure();
}
}
}
@@ -327,8 +335,11 @@ public:
this->commitScalarBuffer_(baseWriter, "saturation ratio_gas", gasSaturationRatio_);
}
if (primaryVarsMeaningOutput_())
this->commitScalarBuffer_(baseWriter, "primary vars meaning", primaryVarsMeaning_);
if (primaryVarsMeaningOutput_()) {
this->commitScalarBuffer_(baseWriter, "primary vars meaning water", primaryVarsMeaningWater_);
this->commitScalarBuffer_(baseWriter, "primary vars meaning gas", primaryVarsMeaningGas_);
this->commitScalarBuffer_(baseWriter, "primary vars meaning pressure", primaryVarsMeaningPressure_);
}
}
private:
@@ -411,7 +422,11 @@ private:
ScalarBuffer oilSaturationRatio_;
ScalarBuffer gasSaturationRatio_;
ScalarBuffer primaryVarsMeaning_;
ScalarBuffer primaryVarsMeaningPressure_;
ScalarBuffer primaryVarsMeaningWater_;
ScalarBuffer primaryVarsMeaningGas_;
};
} // namespace Opm