Merge pull request #4572 from GitPaean/tightenging_tolerance_for_zero_rate_wells

stricter tolerance for wells with zero rate target
This commit is contained in:
Kai Bao 2023-04-14 11:19:35 +02:00 committed by GitHub
commit ceba5c468b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 37 additions and 19 deletions

View File

@ -1394,7 +1394,10 @@ namespace Opm {
const int iterationIdx = ebosSimulator_.model().newtonMethod().numIterations(); const int iterationIdx = ebosSimulator_.model().newtonMethod().numIterations();
for (const auto& well : well_container_) { for (const auto& well : well_container_) {
if (well->isOperableAndSolvable() || well->wellIsStopped()) { if (well->isOperableAndSolvable() || well->wellIsStopped()) {
local_report += well->getWellConvergence(this->wellState(), B_avg, local_deferredLogger, iterationIdx > param_.strict_outer_iter_wells_ ); const auto& summary_state = ebosSimulator_.vanguard().summaryState();
local_report += well->getWellConvergence(
summary_state, this->wellState(), B_avg, local_deferredLogger,
iterationIdx > param_.strict_outer_iter_wells_);
} else { } else {
ConvergenceReport report; ConvergenceReport report;
using CR = ConvergenceReport; using CR = ConvergenceReport;

View File

@ -96,10 +96,11 @@ namespace Opm
DeferredLogger& deferred_logger) const override; DeferredLogger& deferred_logger) const override;
/// check whether the well equations get converged for this well /// check whether the well equations get converged for this well
virtual ConvergenceReport getWellConvergence(const WellState& well_state, virtual ConvergenceReport getWellConvergence(const SummaryState& summary_state,
const WellState& well_state,
const std::vector<double>& B_avg, const std::vector<double>& B_avg,
DeferredLogger& deferred_logger, DeferredLogger& deferred_logger,
const bool relax_tolerance = false) const override; const bool relax_tolerance) const override;
/// Ax = Ax - C D^-1 B x /// Ax = Ax - C D^-1 B x
virtual void apply(const BVector& x, BVector& Ax) const override; virtual void apply(const BVector& x, BVector& Ax) const override;

View File

@ -185,7 +185,8 @@ namespace Opm
template <typename TypeTag> template <typename TypeTag>
ConvergenceReport ConvergenceReport
MultisegmentWell<TypeTag>:: MultisegmentWell<TypeTag>::
getWellConvergence(const WellState& well_state, getWellConvergence(const SummaryState& /* summary_state */,
const WellState& well_state,
const std::vector<double>& B_avg, const std::vector<double>& B_avg,
DeferredLogger& deferred_logger, DeferredLogger& deferred_logger,
const bool relax_tolerance) const const bool relax_tolerance) const
@ -199,6 +200,7 @@ namespace Opm
this->param_.tolerance_pressure_ms_wells_, this->param_.tolerance_pressure_ms_wells_,
this->param_.relaxed_tolerance_pressure_ms_well_, this->param_.relaxed_tolerance_pressure_ms_well_,
relax_tolerance); relax_tolerance);
} }
@ -780,10 +782,10 @@ namespace Opm
// perforation pressure is the wellbore pressure corrected to perforation depth // perforation pressure is the wellbore pressure corrected to perforation depth
// (positive sign due to convention in segments_.perforation_depth_diff() ) // (positive sign due to convention in segments_.perforation_depth_diff() )
perf_press = segment_pressure + perf_seg_press_diff; perf_press = segment_pressure + perf_seg_press_diff;
// cell pressure corrected to perforation depth // cell pressure corrected to perforation depth
const Value cell_press_at_perf = pressure_cell - cell_perf_press_diff; const Value cell_press_at_perf = pressure_cell - cell_perf_press_diff;
// Pressure drawdown (also used to determine direction of flow) // Pressure drawdown (also used to determine direction of flow)
const Value drawdown = cell_press_at_perf - perf_press; const Value drawdown = cell_press_at_perf - perf_press;
@ -1419,7 +1421,8 @@ namespace Opm
this->regularize_ = true; this->regularize_ = true;
} }
const auto report = getWellConvergence(well_state, Base::B_avg_, deferred_logger, relax_convergence); const auto& summary_state = ebosSimulator.vanguard().summaryState();
const auto report = getWellConvergence(summary_state, well_state, Base::B_avg_, deferred_logger, relax_convergence);
if (report.converged()) { if (report.converged()) {
converged = true; converged = true;
break; break;
@ -1455,7 +1458,7 @@ namespace Opm
++stagnate_count; ++stagnate_count;
if (stagnate_count == 6) { if (stagnate_count == 6) {
sstr << " well " << this->name() << " observes severe stagnation and/or oscillation. We relax the tolerance and check for convergence. \n"; sstr << " well " << this->name() << " observes severe stagnation and/or oscillation. We relax the tolerance and check for convergence. \n";
const auto reportStag = getWellConvergence(well_state, Base::B_avg_, deferred_logger, true); const auto reportStag = getWellConvergence(summary_state, well_state, Base::B_avg_, deferred_logger, true);
if (reportStag.converged()) { if (reportStag.converged()) {
converged = true; converged = true;
sstr << " well " << this->name() << " manages to get converged with relaxed tolerances in " << it << " inner iterations"; sstr << " well " << this->name() << " manages to get converged with relaxed tolerances in " << it << " inner iterations";
@ -1482,7 +1485,6 @@ namespace Opm
this->regularize_ = true; this->regularize_ = true;
deferred_logger.debug(sstr.str()); deferred_logger.debug(sstr.str());
} }
const auto& summary_state = ebosSimulator.vanguard().summaryState();
updateWellState(summary_state, dx_well, well_state, deferred_logger, relaxation_factor); updateWellState(summary_state, dx_well, well_state, deferred_logger, relaxation_factor);
initPrimaryVariablesEvaluation(); initPrimaryVariablesEvaluation();
} }

View File

@ -144,10 +144,11 @@ namespace Opm
void initPrimaryVariablesEvaluation() override; void initPrimaryVariablesEvaluation() override;
/// check whether the well equations get converged for this well /// check whether the well equations get converged for this well
virtual ConvergenceReport getWellConvergence(const WellState& well_state, virtual ConvergenceReport getWellConvergence(const SummaryState& summary_state,
const WellState& well_state,
const std::vector<double>& B_avg, const std::vector<double>& B_avg,
DeferredLogger& deferred_logger, DeferredLogger& deferred_logger,
const bool relax_tolerance = false) const override; const bool relax_tolerance) const override;
/// Ax = Ax - C D^-1 B x /// Ax = Ax - C D^-1 B x
virtual void apply(const BVector& x, BVector& Ax) const override; virtual void apply(const BVector& x, BVector& Ax) const override;

View File

@ -1404,7 +1404,8 @@ namespace Opm
template<typename TypeTag> template<typename TypeTag>
ConvergenceReport ConvergenceReport
StandardWell<TypeTag>:: StandardWell<TypeTag>::
getWellConvergence(const WellState& well_state, getWellConvergence(const SummaryState& summary_state,
const WellState& well_state,
const std::vector<double>& B_avg, const std::vector<double>& B_avg,
DeferredLogger& deferred_logger, DeferredLogger& deferred_logger,
const bool relax_tolerance) const const bool relax_tolerance) const
@ -1413,15 +1414,21 @@ namespace Opm
// For the polymer, energy and foam cases, there is one more mass balance equations of reservoir than wells // For the polymer, energy and foam cases, there is one more mass balance equations of reservoir than wells
assert((int(B_avg.size()) == this->num_components_) || has_polymer || has_energy || has_foam || has_brine || has_zFraction || has_micp); assert((int(B_avg.size()) == this->num_components_) || has_polymer || has_energy || has_foam || has_brine || has_zFraction || has_micp);
// using sricter tolerance for stopped wells and wells under zero rate target control.
constexpr double stricter_factor = 1.e-4;
const double tol_wells = this->stopppedOrZeroRateTarget(summary_state, well_state) ?
this->param_.tolerance_wells_ * stricter_factor : this->param_.tolerance_wells_;
std::vector<double> res; std::vector<double> res;
ConvergenceReport report = this->StdWellEval::getWellConvergence(well_state, ConvergenceReport report = this->StdWellEval::getWellConvergence(well_state,
B_avg, B_avg,
this->param_.max_residual_allowed_, this->param_.max_residual_allowed_,
this->param_.tolerance_wells_, tol_wells,
this->param_.relaxed_tolerance_flow_well_, this->param_.relaxed_tolerance_flow_well_,
relax_tolerance, relax_tolerance,
res, res,
deferred_logger); deferred_logger);
checkConvergenceExtraEqs(res, report); checkConvergenceExtraEqs(res, report);
return report; return report;
@ -2084,7 +2091,7 @@ namespace Opm
this->linSys_.extract(jacobian); this->linSys_.extract(jacobian);
} }
template <typename TypeTag> template <typename TypeTag>
void void
StandardWell<TypeTag>::addWellPressureEquations(PressureMatrix& jacobian, StandardWell<TypeTag>::addWellPressureEquations(PressureMatrix& jacobian,
@ -2102,7 +2109,7 @@ namespace Opm
well_state); well_state);
} }
template<typename TypeTag> template<typename TypeTag>
typename StandardWell<TypeTag>::EvalWell typename StandardWell<TypeTag>::EvalWell
@ -2507,6 +2514,7 @@ namespace Opm
bool converged; bool converged;
bool relax_convergence = false; bool relax_convergence = false;
this->regularize_ = false; this->regularize_ = false;
const auto& summary_state = ebosSimulator.vanguard().summaryState();
do { do {
assembleWellEqWithoutIteration(ebosSimulator, dt, inj_controls, prod_controls, well_state, group_state, deferred_logger); assembleWellEqWithoutIteration(ebosSimulator, dt, inj_controls, prod_controls, well_state, group_state, deferred_logger);
@ -2515,7 +2523,7 @@ namespace Opm
this->regularize_ = true; this->regularize_ = true;
} }
auto report = getWellConvergence(well_state, Base::B_avg_, deferred_logger, relax_convergence); auto report = getWellConvergence(summary_state, well_state, Base::B_avg_, deferred_logger, relax_convergence);
converged = report.converged(); converged = report.converged();
if (converged) { if (converged) {
@ -2523,7 +2531,6 @@ namespace Opm
} }
++it; ++it;
const auto& summary_state = ebosSimulator.vanguard().summaryState();
solveEqAndUpdateWellState(summary_state, well_state, deferred_logger); solveEqAndUpdateWellState(summary_state, well_state, deferred_logger);
// TODO: when this function is used for well testing purposes, will need to check the controls, so that we will obtain convergence // TODO: when this function is used for well testing purposes, will need to check the controls, so that we will obtain convergence

View File

@ -154,7 +154,11 @@ public:
virtual void initPrimaryVariablesEvaluation() = 0; virtual void initPrimaryVariablesEvaluation() = 0;
virtual ConvergenceReport getWellConvergence(const WellState& well_state, const std::vector<double>& B_avg, DeferredLogger& deferred_logger, const bool relax_tolerance) const = 0; virtual ConvergenceReport getWellConvergence(const SummaryState& summary_state,
const WellState& well_state,
const std::vector<double>& B_avg,
DeferredLogger& deferred_logger,
const bool relax_tolerance) const = 0;
void assembleWellEq(const Simulator& ebosSimulator, void assembleWellEq(const Simulator& ebosSimulator,
const double dt, const double dt,