fix well-convergence for well-copies

This commit is contained in:
Stein Krogstad
2023-11-08 21:07:47 +01:00
parent 73ec44d9c4
commit ee16e90ba2
6 changed files with 35 additions and 14 deletions

View File

@@ -86,7 +86,8 @@ getWellConvergence(const WellState& well_state,
const double relaxed_inner_tolerance_flow_ms_well,
const double tolerance_pressure_ms_wells,
const double relaxed_inner_tolerance_pressure_ms_well,
const bool relax_tolerance) const
const bool relax_tolerance,
const bool well_is_stopped) const
{
assert(int(B_avg.size()) == baseif_.numComponents());
@@ -160,13 +161,14 @@ getWellConvergence(const WellState& well_state,
tolerance_wells,
tolerance_wells,
max_residual_allowed},
well_is_stopped,
std::abs(linSys_.residual()[0][SPres]),
report,
deferred_logger);
// for stopped well, we do not enforce the following checking to avoid dealing with sign of near-zero values
// for BHP or THP controlled wells, we need to make sure the flow direction is correct
if (!baseif_.wellIsStopped() && baseif_.isPressureControlled(well_state)) {
if (!well_is_stopped && baseif_.isPressureControlled(well_state)) {
// checking the flow direction
const double sign = baseif_.isProducer() ? -1. : 1.;
const auto weight_total_flux = this->primary_variables_.getWQTotal() * sign;
@@ -541,7 +543,7 @@ getResidualMeasureValue(const WellState& well_state,
}
// if (count == 0), it should be converged.
assert(count != 0);
//assert(count != 0);
return sum;
}

View File

@@ -106,7 +106,8 @@ protected:
const double relaxed_inner_tolerance_flow_ms_well,
const double tolerance_pressure_ms_wells,
const double relaxed_inner_tolerance_pressure_ms_well,
const bool relax_tolerance) const;
const bool relax_tolerance,
const bool well_is_stopped) const;
std::pair<bool, std::vector<Scalar> >
getFiniteWellResiduals(const std::vector<Scalar>& B_avg,

View File

@@ -206,7 +206,8 @@ namespace Opm
this->param_.relaxed_tolerance_flow_well_,
this->param_.tolerance_pressure_ms_wells_,
this->param_.relaxed_tolerance_pressure_ms_well_,
relax_tolerance);
relax_tolerance,
this->wellIsStopped());
}
@@ -1609,25 +1610,34 @@ namespace Opm
[[maybe_unused]] int stagnate_count = 0;
bool relax_convergence = false;
this->regularize_ = false;
const auto& summary_state = ebosSimulator.vanguard().summaryState();
// Max status switch frequency should be 2 to avoid getting stuck in cycle
const int min_its_after_switch = 2;
const int min_its_after_switch = 3;
int its_since_last_switch = min_its_after_switch;
int switch_count= 0;
const auto well_status = this->wellStatus_;
const auto& summary_state = ebosSimulator.vanguard().summaryState();
const bool allow_switching = !this->wellUnderZeroRateTarget(summary_state, well_state) && (this->well_ecl_.getStatus() == WellStatus::OPEN);
// if we fail to solve eqs, we reset status/control before leaving
const auto well_status_orig = this->wellStatus_;
auto well_status_cur = well_status_orig;
int status_switch_count = 0;
// only allow switcing if well is not under zero-rate target and is open from schedule
bool allow_switching = !this->wellUnderZeroRateTarget(summary_state, well_state) && (this->well_ecl_.getStatus() == WellStatus::OPEN);
allow_switching = allow_switching && (!fixed_control || !fixed_status);
bool changed = false;
bool final_check = false;
for (; it < max_iter_number; ++it, ++debug_cost_counter_) {
its_since_last_switch++;
if (its_since_last_switch >= min_its_after_switch){
if (allow_switching && its_since_last_switch >= min_its_after_switch){
const double wqTotal = this->primary_variables_.getWQTotal().value();
changed = this->updateWellControlAndStatusLocalIteration (ebosSimulator, well_state, group_state, inj_controls, prod_controls, wqTotal, deferred_logger);
changed = this->updateWellControlAndStatusLocalIteration(ebosSimulator, well_state, group_state, inj_controls, prod_controls, wqTotal, deferred_logger, fixed_control, fixed_status);
if (changed){
its_since_last_switch = 0;
switch_count++;
if (well_status_cur != this->wellStatus_) {
well_status_cur = this->wellStatus_;
status_switch_count++;
}
}
if (!changed && final_check) {
break;
@@ -1743,6 +1753,7 @@ namespace Opm
}
deferred_logger.debug(message);
} else {
this->wellStatus_ = well_status_orig;
const std::string message = fmt::format(" Well {} did not converged in {} inner iterations ("
"{} control/status switches).", this->name(), it, switch_count);
deferred_logger.debug(message);

View File

@@ -106,6 +106,7 @@ getWellConvergence(const WellState& well_state,
const double tol_wells,
const double relaxed_tolerance_flow,
const bool relax_tolerance,
const bool well_is_stopped,
std::vector<double>& res,
DeferredLogger& deferred_logger) const
{
@@ -150,12 +151,13 @@ getWellConvergence(const WellState& well_state,
checkConvergenceControlEq(well_state,
{1.e3, 1.e4, 1.e-4, 1.e-6, maxResidualAllowed},
std::abs(this->linSys_.residual()[0][Bhp]),
well_is_stopped,
report,
deferred_logger);
// for stopped well, we do not enforce the following checking to avoid dealing with sign of near-zero values
// for BHP or THP controlled wells, we need to make sure the flow direction is correct
if (!baseif_.wellIsStopped() && baseif_.isPressureControlled(well_state)) {
if (!well_is_stopped && baseif_.isPressureControlled(well_state)) {
// checking the flow direction
const double sign = baseif_.isProducer() ? -1. : 1.;
const auto weight_total_flux = this->primary_variables_.value(PrimaryVariables::WQTotal) * sign;

View File

@@ -85,6 +85,7 @@ protected:
const double tol_wells,
const double relaxed_tolerance_flow,
const bool relax_tolerance,
const bool well_is_stopped,
std::vector<double>& res,
DeferredLogger& deferred_logger) const;

View File

@@ -1181,6 +1181,7 @@ namespace Opm
tol_wells,
this->param_.relaxed_tolerance_flow_well_,
relax_tolerance,
this->wellIsStopped(),
res,
deferred_logger);
@@ -2335,16 +2336,19 @@ namespace Opm
const auto well_status_orig = this->wellStatus_;
auto well_status_cur = well_status_orig;
int status_switch_count = 0;
// only allow switcing if well is not under zero-rate target and is open from schedule
bool allow_switching = !this->wellUnderZeroRateTarget(summary_state, well_state) && (this->well_ecl_.getStatus() == WellStatus::OPEN);
allow_switching = allow_switching && (!fixed_control && !fixed_status);
allow_switching = allow_switching && (!fixed_control || !fixed_status);
bool changed = false;
bool final_check = false;
/*
if (allow_switching) {
// ??????????????????????????????????????????
this->operability_status_.can_obtain_bhp_with_thp_limit = true;
this->operability_status_.obey_thp_limit_under_bhp_limit = true;
this->operability_status_.operable_under_only_bhp_limit = true;
}
*/
do {
its_since_last_switch++;
if (allow_switching && its_since_last_switch >= min_its_after_switch){