more treatment for zero rate wells in updateWellStateWithTarget

This commit is contained in:
Kai Bao 2017-03-21 17:04:42 +01:00
parent f70bb960dd
commit 4b5e1dfadc

View File

@ -2499,29 +2499,30 @@ namespace Opm {
// break; // break;
case SURFACE_RATE: case SURFACE_RATE:
// assign target value as initial guess for injectors and // checking the number of the phases under control
// single phase producers (orat, grat, wrat) int numPhasesWithTargetsUnderThisControl = 0;
for (int phase = 0; phase < np; ++phase) {
if (distr[phase] > 0.0) {
numPhasesWithTargetsUnderThisControl += 1;
}
}
assert(numPhasesWithTargetsUnderThisControl > 0);
const WellType& well_type = wells().type[well_index]; const WellType& well_type = wells().type[well_index];
if (well_type == INJECTOR) { if (well_type == INJECTOR) {
// assign target value as initial guess for injectors
// only handles single phase control at the moment
assert(numPhasesWithTargetsUnderThisControl == 1);
for (int phase = 0; phase < np; ++phase) { for (int phase = 0; phase < np; ++phase) {
const double& compi = wells().comp_frac[np * well_index + phase]; if (distr[phase] > 0.) {
if (compi > 0.0) { xw.wellRates()[np*well_index + phase] = target / distr[phase];
assert(distr[phase] > 0.);
xw.wellRates()[np*well_index + phase] = target * compi / distr[phase];
} else { } else {
xw.wellRates()[np * well_index + phase] = target * compi; xw.wellRates()[np * well_index + phase] = 0.;
} }
} }
} else if (well_type == PRODUCER) { } else if (well_type == PRODUCER) {
// checking the number of the phases under control
int numPhasesWithTargetsUnderThisControl = 0;
for (int phase = 0; phase < np; ++phase) {
if (distr[phase] > 0.0) {
numPhasesWithTargetsUnderThisControl += 1;
}
}
assert(numPhasesWithTargetsUnderThisControl > 0);
// update the rates of phases under control based on the target, // update the rates of phases under control based on the target,
// and also update rates of phases not under control to keep the rate ratio, // and also update rates of phases not under control to keep the rate ratio,
@ -2540,17 +2541,17 @@ namespace Opm {
xw.wellRates()[np * well_index + phase] *= scaling_factor; xw.wellRates()[np * well_index + phase] *= scaling_factor;
} }
} else { // scaling factor is not well defied when orignal_rates_under_phase_control is zero } else { // scaling factor is not well defied when orignal_rates_under_phase_control is zero
if (orignal_rates_under_phase_control == 0.0) { // separating targets equally between phases under control
// only handle single-phase control const double target_rate_devided = target / numPhasesWithTargetsUnderThisControl;
if (numPhasesWithTargetsUnderThisControl == 1) { for (int phase = 0; phase < np; ++phase) {
for (int phase = 0; phase < np; ++phase) { if (distr[phase] > 0.0) {
if (distr[phase] > 0.0) { xw.wellRates()[np * well_index + phase] = target_rate_devided / distr[phase];
xw.wellRates()[np * well_index + phase] = target; } else {
} // this only happens for SURFACE_RATE control
} xw.wellRates()[np * well_index + phase] = target_rate_devided;
} }
} }
} }
} else { } else {
OPM_THROW(std::logic_error, "Expected PRODUCER or INJECTOR type of well"); OPM_THROW(std::logic_error, "Expected PRODUCER or INJECTOR type of well");
} }
@ -2603,12 +2604,37 @@ namespace Opm {
xw.wellSolutions()[GFrac*nw + well_index] = g[Gas] * xw.wellRates()[np*well_index + Gas] / tot_well_rate ; xw.wellSolutions()[GFrac*nw + well_index] = g[Gas] * xw.wellRates()[np*well_index + Gas] / tot_well_rate ;
} }
} else { } else {
if (active_[ Water ]) { const WellType& well_type = wells().type[well_index];
xw.wellSolutions()[WFrac*nw + well_index] = wells().comp_frac[np*well_index + Water]; if (well_type == INJECTOR) {
} // only single phase injection handled
if (active_[Water]) {
if (distr[Water] > 0.0) {
xw.wellSolutions()[WFrac * nw + well_index] = 1.0;
} else {
xw.wellSolutions()[WFrac * nw + well_index] = 0.0;
}
}
if (active_[ Gas ]) { if (active_[Gas]) {
xw.wellSolutions()[GFrac*nw + well_index] = wells().comp_frac[np*well_index + Gas]; if (distr[Gas] > 0.0) {
xw.wellSolutions()[GFrac * nw + well_index] = 1.0;
} else {
xw.wellSolutions()[GFrac * nw + well_index] = 0.0;
}
}
// TODO: it is possible to leave injector as a oil well,
// when F_w and F_g both equals to zero, not sure under what kind of circumstance
// this will happen.
} else if (well_type == PRODUCER) { // producers
if (active_[Water]) {
xw.wellSolutions()[WFrac * nw + well_index] = 1.0 / np;
}
if (active_[Gas]) {
xw.wellSolutions()[GFrac * nw + well_index] = 1.0 / np;
}
} else {
OPM_THROW(std::logic_error, "Expected PRODUCER or INJECTOR type of well");
} }
} }