mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
fix well-convergence for well-copies
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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){
|
||||
|
||||
Reference in New Issue
Block a user