Don't stop wells unless global update agrees

This commit is contained in:
Stein Krogstad 2024-10-10 12:44:24 +02:00 committed by Atgeirr Flø Rasmussen
parent 0ff3d63c0a
commit a94d667462

View File

@ -827,11 +827,44 @@ namespace Opm
// only use inner well iterations for the first newton iterations.
const int iteration_idx = simulator.model().newtonMethod().numIterations();
if (iteration_idx < this->param_.max_niter_inner_well_iter_ || this->well_ecl_.isMultiSegment()) {
const auto& ws = well_state.well(this->indexOfWell());
const auto pmode_orig = ws.production_cmode;
const auto imode_orig = ws.injection_cmode;
Scalar qtotal_orig = 0.0;
const int np = well_state.numPhases();
for (int p = 0; p < np; ++p) {
qtotal_orig += ws.surface_rates[p];
}
this->operability_status_.solvable = true;
bool converged = this->iterateWellEquations(simulator, dt, well_state, group_state, deferred_logger);
// unsolvable wells are treated as not operable and will not be solved for in this iteration.
if (!converged) {
if (converged) {
const bool zero_target = this->wellUnderZeroRateTarget(simulator, well_state, deferred_logger);
if (this->wellIsStopped() && !zero_target && qtotal_orig != 0.0) {
// Well had non-zero rate, but was stopped during local well-solve. We re-open the well
// for the next global iteration, but if the zero rate persists, it will be stopped.
// This logic is introduced to prevent/ameliorate stopped/revived oscillations
this->operability_status_.resetOperability();
this->openWell();
deferred_logger.debug(" " + this->name() + " is re-opened after being stopped during local solve");
}
// Add debug info for switched controls
if (ws.production_cmode != pmode_orig || ws.injection_cmode != imode_orig) {
std::string from,to;
if (this->isInjector()) {
from = WellInjectorCMode2String(imode_orig);
to = WellInjectorCMode2String(ws.injection_cmode);
} else {
from = WellProducerCMode2String(pmode_orig);
to = WellProducerCMode2String(ws.production_cmode);
}
deferred_logger.debug(" " + this->name() + " switched from " + from + " to " + to + " during local solve");
}
} else {
// unsolvable wells are treated as not operable and will not be solved for in this iteration.
if (this->param_.shut_unsolvable_wells_)
this->operability_status_.solvable = false;
}