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:
Andreas Lauser 2015-08-26 16:04:10 +02:00
parent 95c482521a
commit 53b48b2838
2 changed files with 19 additions and 4 deletions

View File

@ -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);
} }

View File

@ -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;
} }