mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
black-oil: fix some stupid errors with vaporized oil
obviously if the switching variable is interpreted as x_g^O, the gas phase is present, because in this case it is the only phase. Also, when the oil phase appears, the gas saturation is 1-Sw, not 1. (the last issue only happened in the vaporized case because the switch variable would never get the meaning of "oil component's mole fraction in the gas phase".)
This commit is contained in:
parent
95c482521a
commit
53b48b2838
@ -116,6 +116,9 @@ public:
|
|||||||
for (int elemIdx = 0; elemIdx < numElems; ++elemIdx) {
|
for (int elemIdx = 0; elemIdx < numElems; ++elemIdx) {
|
||||||
auto &fluidState = initialFluidStates_[elemIdx];
|
auto &fluidState = initialFluidStates_[elemIdx];
|
||||||
|
|
||||||
|
// get the PVT region index of the current element
|
||||||
|
int regionIdx = simulator_.problem().pvtRegionIndex(elemIdx);
|
||||||
|
|
||||||
// set the phase saturations
|
// set the phase saturations
|
||||||
for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
|
for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
|
||||||
Scalar S = opmBlackoilState.saturation()[elemIdx*numPhases + phaseIdx];
|
Scalar S = opmBlackoilState.saturation()[elemIdx*numPhases + phaseIdx];
|
||||||
@ -138,6 +141,7 @@ public:
|
|||||||
Scalar po = opmBlackoilState.pressure()[elemIdx];
|
Scalar po = opmBlackoilState.pressure()[elemIdx];
|
||||||
for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
|
for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
|
||||||
fluidState.setPressure(phaseIdx, po + (pC[phaseIdx] - pC[oilPhaseIdx]));
|
fluidState.setPressure(phaseIdx, po + (pC[phaseIdx] - pC[oilPhaseIdx]));
|
||||||
|
Scalar pg = fluidState.pressure(gasPhaseIdx);
|
||||||
|
|
||||||
// reset the phase compositions
|
// reset the phase compositions
|
||||||
for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
|
for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
|
||||||
@ -158,6 +162,10 @@ public:
|
|||||||
// mass fraction to mole fraction
|
// mass fraction to mole fraction
|
||||||
Scalar xoG = XoG*MO / (MG*(1 - XoG) + XoG*MO);
|
Scalar xoG = XoG*MO / (MG*(1 - XoG) + XoG*MO);
|
||||||
|
|
||||||
|
Scalar xoGMax = FluidSystem::saturatedOilGasMoleFraction(T, pg, regionIdx);
|
||||||
|
if (fluidState.saturation(gasPhaseIdx) > 0.0 || xoG > xoGMax)
|
||||||
|
xoG = xoGMax;
|
||||||
|
|
||||||
fluidState.setMoleFraction(oilPhaseIdx, oilCompIdx, 1 - xoG);
|
fluidState.setMoleFraction(oilPhaseIdx, oilCompIdx, 1 - xoG);
|
||||||
fluidState.setMoleFraction(oilPhaseIdx, gasCompIdx, xoG);
|
fluidState.setMoleFraction(oilPhaseIdx, gasCompIdx, xoG);
|
||||||
}
|
}
|
||||||
@ -171,6 +179,10 @@ public:
|
|||||||
// mass fraction to mole fraction
|
// mass fraction to mole fraction
|
||||||
Scalar xgO = XgO*MG / (MO*(1 - XgO) + XgO*MG);
|
Scalar xgO = XgO*MG / (MO*(1 - XgO) + XgO*MG);
|
||||||
|
|
||||||
|
Scalar xgOMax = FluidSystem::saturatedGasOilMoleFraction(T, pg, regionIdx);
|
||||||
|
if (fluidState.saturation(oilPhaseIdx) > 0.0 || xgO > xgOMax)
|
||||||
|
xgO = xgOMax;
|
||||||
|
|
||||||
fluidState.setMoleFraction(gasPhaseIdx, oilCompIdx, xgO);
|
fluidState.setMoleFraction(gasPhaseIdx, oilCompIdx, xgO);
|
||||||
fluidState.setMoleFraction(gasPhaseIdx, gasCompIdx, 1 - xgO);
|
fluidState.setMoleFraction(gasPhaseIdx, gasCompIdx, 1 - xgO);
|
||||||
}
|
}
|
||||||
|
@ -567,6 +567,12 @@ public:
|
|||||||
*/
|
*/
|
||||||
template <class Context>
|
template <class Context>
|
||||||
int pvtRegionIndex(const Context &context, int spaceIdx, int timeIdx) const
|
int pvtRegionIndex(const Context &context, int spaceIdx, int timeIdx) const
|
||||||
|
{ return pvtRegionIndex(context.globalSpaceIndex(spaceIdx, timeIdx)); }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Returns the index the relevant PVT region given a cell index
|
||||||
|
*/
|
||||||
|
int pvtRegionIndex(int elemIdx) const
|
||||||
{
|
{
|
||||||
Opm::DeckConstPtr deck = this->simulator().gridManager().deck();
|
Opm::DeckConstPtr deck = this->simulator().gridManager().deck();
|
||||||
|
|
||||||
@ -575,10 +581,7 @@ public:
|
|||||||
|
|
||||||
const auto& gridManager = this->simulator().gridManager();
|
const auto& gridManager = this->simulator().gridManager();
|
||||||
|
|
||||||
// this is quite specific to the ECFV discretization. But so is everything in an
|
int cartesianDofIdx = gridManager.cartesianCellId(elemIdx);
|
||||||
// ECL deck, i.e., we don't need to care here...
|
|
||||||
int compressedDofIdx = context.globalSpaceIndex(spaceIdx, timeIdx);
|
|
||||||
int cartesianDofIdx = gridManager.cartesianCellId(compressedDofIdx);
|
|
||||||
|
|
||||||
return deck->getKeyword("PVTNUM")->getIntData()[cartesianDofIdx] - 1;
|
return deck->getKeyword("PVTNUM")->getIntData()[cartesianDofIdx] - 1;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user