mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
adding function iterateWellEqWithSwitching
when we do the local solve for well equations, control/status will be updated during the iteration process, such that the converged well gets correct control/status regarding to the current reservoir state. various change in the other parts of the code were made to make the function work as intended.
This commit is contained in:
@@ -2155,6 +2155,98 @@ namespace Opm
|
||||
}
|
||||
|
||||
|
||||
template<typename TypeTag>
|
||||
bool
|
||||
StandardWell<TypeTag>::
|
||||
iterateWellEqWithSwitching(const Simulator& ebosSimulator,
|
||||
const double dt,
|
||||
const Well::InjectionControls& inj_controls,
|
||||
const Well::ProductionControls& prod_controls,
|
||||
WellState& well_state,
|
||||
const GroupState& group_state,
|
||||
DeferredLogger& deferred_logger)
|
||||
{
|
||||
const int max_iter = this->param_.max_inner_iter_wells_;
|
||||
|
||||
int it = 0;
|
||||
bool converged;
|
||||
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;
|
||||
int its_since_last_switch = min_its_after_switch;
|
||||
int switch_count= 0;
|
||||
const auto well_status = this->wellStatus_;
|
||||
const bool allow_switching = !this->wellUnderZeroRateTarget(summary_state, well_state) && (this->well_ecl_.getStatus() == WellStatus::OPEN);
|
||||
bool changed = false;
|
||||
bool final_check = false;
|
||||
do {
|
||||
its_since_last_switch++;
|
||||
if (allow_switching && its_since_last_switch >= min_its_after_switch){
|
||||
const double wqTotal = this->primary_variables_.eval(WQTotal).value();
|
||||
changed = this->updateWellControlAndStatusLocalIteration(ebosSimulator, well_state, group_state, inj_controls, prod_controls, wqTotal, deferred_logger);
|
||||
if (changed){
|
||||
its_since_last_switch = 0;
|
||||
switch_count++;
|
||||
}
|
||||
if (!changed && final_check) {
|
||||
break;
|
||||
} else {
|
||||
final_check = false;
|
||||
}
|
||||
}
|
||||
|
||||
assembleWellEqWithoutIteration(ebosSimulator, dt, inj_controls, prod_controls, well_state, group_state, deferred_logger);
|
||||
|
||||
if (it > this->param_.strict_inner_iter_wells_) {
|
||||
relax_convergence = true;
|
||||
this->regularize_ = true;
|
||||
}
|
||||
|
||||
auto report = getWellConvergence(summary_state, well_state, Base::B_avg_, deferred_logger, relax_convergence);
|
||||
|
||||
converged = report.converged();
|
||||
if (converged) {
|
||||
// if equations are sufficiently linear they might converge in less than min_its_after_switch
|
||||
// in this case, make sure all constraints are satisfied before returning
|
||||
if (switch_count > 0 && its_since_last_switch < min_its_after_switch) {
|
||||
final_check = true;
|
||||
its_since_last_switch = min_its_after_switch;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
++it;
|
||||
solveEqAndUpdateWellState(summary_state, well_state, deferred_logger);
|
||||
initPrimaryVariablesEvaluation();
|
||||
} while (it < max_iter);
|
||||
|
||||
if (converged) {
|
||||
if (allow_switching){
|
||||
// update operability if status change
|
||||
const bool is_stopped = this->wellIsStopped();
|
||||
if (this->wellHasTHPConstraints(summary_state)){
|
||||
this->operability_status_.can_obtain_bhp_with_thp_limit = !is_stopped;
|
||||
this->operability_status_.obey_thp_limit_under_bhp_limit = !is_stopped;
|
||||
} else {
|
||||
this->operability_status_.operable_under_only_bhp_limit = !is_stopped;
|
||||
}
|
||||
// We reset the well status to it's original state. Status is updated
|
||||
// on the outside based on operability status
|
||||
this->wellStatus_ = well_status;
|
||||
}
|
||||
} else {
|
||||
std::ostringstream sstr;
|
||||
sstr << " Well " << this->name() << " did not converge in " << it << " inner iterations (" << switch_count << " control/status switches).";
|
||||
deferred_logger.debug(sstr.str());
|
||||
// add operability here as well ?
|
||||
}
|
||||
return converged;
|
||||
}
|
||||
|
||||
template<typename TypeTag>
|
||||
std::vector<double>
|
||||
StandardWell<TypeTag>::
|
||||
|
||||
Reference in New Issue
Block a user