mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Correct the RESV calculation for unsaturated cases
Make sure that the reservoar volumes always stays positive. i.e. we can not remove more dissolved gas from the rate than the total volume amout of gas.
This commit is contained in:
parent
975a9a6766
commit
4e9403b8f8
@ -275,7 +275,7 @@ namespace Opm {
|
|||||||
// solve the well equations as a pre-processing step
|
// solve the well equations as a pre-processing step
|
||||||
last_report_ = solveWellEq(dt);
|
last_report_ = solveWellEq(dt);
|
||||||
if (initial_step_) {
|
if (initial_step_) {
|
||||||
// update the explixit quanteties to get the initial fluid distribution in the well correct.
|
// update the explicit quantities to get the initial fluid distribution in the well correct.
|
||||||
calculateExplicitQuantities();
|
calculateExplicitQuantities();
|
||||||
last_report_ = solveWellEq(dt);
|
last_report_ = solveWellEq(dt);
|
||||||
initial_step_ = false;
|
initial_step_ = false;
|
||||||
@ -1196,9 +1196,9 @@ namespace Opm {
|
|||||||
// observed phase rates translated to
|
// observed phase rates translated to
|
||||||
// reservoir conditions. Recall sign
|
// reservoir conditions. Recall sign
|
||||||
// convention: Negative for producers.
|
// convention: Negative for producers.
|
||||||
const double target =
|
std::vector<double> hrates_resv(np);
|
||||||
- std::inner_product(distr.begin(), distr.end(),
|
rateConverter_->calcReservoirVoidageRates(fipreg, pvtreg, hrates, hrates_resv);
|
||||||
hrates.begin(), 0.0);
|
const double target = -std::accumulate(hrates_resv.begin(), hrates_resv.end(), 0.0);
|
||||||
|
|
||||||
well_controls_clear(ctrl);
|
well_controls_clear(ctrl);
|
||||||
well_controls_assert_number_of_phases(ctrl, int(np));
|
well_controls_assert_number_of_phases(ctrl, int(np));
|
||||||
|
@ -613,13 +613,16 @@ namespace Opm {
|
|||||||
coeff[iw] = 1.0 / bw;
|
coeff[iw] = 1.0 / bw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Actual Rs and Rv:
|
||||||
|
double Rs = ra.rs;
|
||||||
|
double Rv = ra.rv;
|
||||||
|
|
||||||
// Determinant of 'R' matrix
|
// Determinant of 'R' matrix
|
||||||
const double detR = 1.0 - (ra.rs * ra.rv);
|
const double detR = 1.0 - (Rs * Rv);
|
||||||
|
|
||||||
if (Details::PhaseUsed::oil(pu)) {
|
if (Details::PhaseUsed::oil(pu)) {
|
||||||
// q[o]_r = 1/(bo * (1 - rs*rv)) * (q[o]_s - rv*q[g]_s)
|
// q[o]_r = 1/(bo * (1 - rs*rv)) * (q[o]_s - rv*q[g]_s)
|
||||||
|
|
||||||
const double Rs = ra.rs;
|
|
||||||
const double bo = FluidSystem::oilPvt().inverseFormationVolumeFactor(pvtRegionIdx, T, p, Rs);
|
const double bo = FluidSystem::oilPvt().inverseFormationVolumeFactor(pvtRegionIdx, T, p, Rs);
|
||||||
const double den = bo * detR;
|
const double den = bo * detR;
|
||||||
|
|
||||||
@ -633,7 +636,6 @@ namespace Opm {
|
|||||||
if (Details::PhaseUsed::gas(pu)) {
|
if (Details::PhaseUsed::gas(pu)) {
|
||||||
// q[g]_r = 1/(bg * (1 - rs*rv)) * (q[g]_s - rs*q[o]_s)
|
// q[g]_r = 1/(bg * (1 - rs*rv)) * (q[g]_s - rs*q[o]_s)
|
||||||
|
|
||||||
const double Rv = ra.rv;
|
|
||||||
const double bg = FluidSystem::gasPvt().inverseFormationVolumeFactor(pvtRegionIdx, T, p, Rv);
|
const double bg = FluidSystem::gasPvt().inverseFormationVolumeFactor(pvtRegionIdx, T, p, Rv);
|
||||||
const double den = bg * detR;
|
const double den = bg * detR;
|
||||||
|
|
||||||
@ -689,20 +691,22 @@ namespace Opm {
|
|||||||
voidage_rates[iw] = surface_rates[iw] / bw;
|
voidage_rates[iw] = surface_rates[iw] / bw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use average Rs and Rv:
|
||||||
|
double Rs = std::min(ra.rs, surface_rates[ig]/(surface_rates[io]+1.0e-15));
|
||||||
|
double Rv = std::min(ra.rv, surface_rates[io]/(surface_rates[ig]+1.0e-15));
|
||||||
|
|
||||||
// Determinant of 'R' matrix
|
// Determinant of 'R' matrix
|
||||||
const double detR = 1.0 - (ra.rs * ra.rv);
|
const double detR = 1.0 - (Rs * Rv);
|
||||||
|
|
||||||
if (Details::PhaseUsed::oil(pu)) {
|
if (Details::PhaseUsed::oil(pu)) {
|
||||||
// q[o]_r = 1/(bo * (1 - rs*rv)) * (q[o]_s - rv*q[g]_s)
|
// q[o]_r = 1/(bo * (1 - rs*rv)) * (q[o]_s - rv*q[g]_s)
|
||||||
|
|
||||||
const double Rs = ra.rs;
|
|
||||||
const double bo = FluidSystem::oilPvt().inverseFormationVolumeFactor(pvtRegionIdx, T, p, Rs);
|
const double bo = FluidSystem::oilPvt().inverseFormationVolumeFactor(pvtRegionIdx, T, p, Rs);
|
||||||
const double den = bo * detR;
|
const double den = bo * detR;
|
||||||
|
|
||||||
voidage_rates[io] = surface_rates[io];
|
voidage_rates[io] = surface_rates[io];
|
||||||
|
|
||||||
if (Details::PhaseUsed::gas(pu)) {
|
if (Details::PhaseUsed::gas(pu)) {
|
||||||
const double Rv = ra.rv;
|
|
||||||
voidage_rates[io] -= Rv * surface_rates[ig];
|
voidage_rates[io] -= Rv * surface_rates[ig];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -712,14 +716,12 @@ namespace Opm {
|
|||||||
if (Details::PhaseUsed::gas(pu)) {
|
if (Details::PhaseUsed::gas(pu)) {
|
||||||
// q[g]_r = 1/(bg * (1 - rs*rv)) * (q[g]_s - rs*q[o]_s)
|
// q[g]_r = 1/(bg * (1 - rs*rv)) * (q[g]_s - rs*q[o]_s)
|
||||||
|
|
||||||
const double Rv = ra.rv;
|
|
||||||
const double bg = FluidSystem::gasPvt().inverseFormationVolumeFactor(pvtRegionIdx, T, p, Rv);
|
const double bg = FluidSystem::gasPvt().inverseFormationVolumeFactor(pvtRegionIdx, T, p, Rv);
|
||||||
const double den = bg * detR;
|
const double den = bg * detR;
|
||||||
|
|
||||||
voidage_rates[ig] = surface_rates[ig];
|
voidage_rates[ig] = surface_rates[ig];
|
||||||
|
|
||||||
if (Details::PhaseUsed::oil(pu)) {
|
if (Details::PhaseUsed::oil(pu)) {
|
||||||
const double Rs = ra.rs;
|
|
||||||
voidage_rates[ig] -= Rs * surface_rates[io];
|
voidage_rates[ig] -= Rs * surface_rates[io];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user