diff --git a/opm/simulators/wells/BlackoilWellModel_impl.hpp b/opm/simulators/wells/BlackoilWellModel_impl.hpp index d36fd0360..6bf8a6d59 100644 --- a/opm/simulators/wells/BlackoilWellModel_impl.hpp +++ b/opm/simulators/wells/BlackoilWellModel_impl.hpp @@ -1365,7 +1365,10 @@ namespace Opm { const int iterationIdx = ebosSimulator_.model().newtonMethod().numIterations(); for (const auto& well : well_container_) { 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 { ConvergenceReport report; using CR = ConvergenceReport; diff --git a/opm/simulators/wells/MultisegmentWell.hpp b/opm/simulators/wells/MultisegmentWell.hpp index 2faa477ec..55afa2b3e 100644 --- a/opm/simulators/wells/MultisegmentWell.hpp +++ b/opm/simulators/wells/MultisegmentWell.hpp @@ -96,10 +96,11 @@ namespace Opm DeferredLogger& deferred_logger) const override; /// 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& B_avg, DeferredLogger& deferred_logger, - const bool relax_tolerance = false) const override; + const bool relax_tolerance) const override; /// Ax = Ax - C D^-1 B x virtual void apply(const BVector& x, BVector& Ax) const override; diff --git a/opm/simulators/wells/MultisegmentWell_impl.hpp b/opm/simulators/wells/MultisegmentWell_impl.hpp index 53aae50ab..8e2b826d0 100644 --- a/opm/simulators/wells/MultisegmentWell_impl.hpp +++ b/opm/simulators/wells/MultisegmentWell_impl.hpp @@ -185,7 +185,8 @@ namespace Opm template ConvergenceReport MultisegmentWell:: - getWellConvergence(const WellState& well_state, + getWellConvergence(const SummaryState& /* summary_state */, + const WellState& well_state, const std::vector& B_avg, DeferredLogger& deferred_logger, const bool relax_tolerance) const @@ -199,6 +200,7 @@ namespace Opm this->param_.tolerance_pressure_ms_wells_, this->param_.relaxed_tolerance_pressure_ms_well_, relax_tolerance); + } @@ -780,10 +782,10 @@ namespace Opm // perforation pressure is the wellbore pressure corrected to perforation depth // (positive sign due to convention in segments_.perforation_depth_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; - + // Pressure drawdown (also used to determine direction of flow) const Value drawdown = cell_press_at_perf - perf_press; @@ -1419,7 +1421,8 @@ namespace Opm 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()) { converged = true; break; @@ -1455,7 +1458,7 @@ namespace Opm ++stagnate_count; if (stagnate_count == 6) { 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()) { converged = true; sstr << " well " << this->name() << " manages to get converged with relaxed tolerances in " << it << " inner iterations"; @@ -1482,7 +1485,6 @@ namespace Opm this->regularize_ = true; deferred_logger.debug(sstr.str()); } - const auto& summary_state = ebosSimulator.vanguard().summaryState(); updateWellState(summary_state, dx_well, well_state, deferred_logger, relaxation_factor); initPrimaryVariablesEvaluation(); } diff --git a/opm/simulators/wells/StandardWell.hpp b/opm/simulators/wells/StandardWell.hpp index df3fdcb15..fe3c5f3b3 100644 --- a/opm/simulators/wells/StandardWell.hpp +++ b/opm/simulators/wells/StandardWell.hpp @@ -144,10 +144,11 @@ namespace Opm void initPrimaryVariablesEvaluation() override; /// 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& B_avg, DeferredLogger& deferred_logger, - const bool relax_tolerance = false) const override; + const bool relax_tolerance) const override; /// Ax = Ax - C D^-1 B x virtual void apply(const BVector& x, BVector& Ax) const override; diff --git a/opm/simulators/wells/StandardWell_impl.hpp b/opm/simulators/wells/StandardWell_impl.hpp index 757c9393d..e8482b4e9 100644 --- a/opm/simulators/wells/StandardWell_impl.hpp +++ b/opm/simulators/wells/StandardWell_impl.hpp @@ -1403,7 +1403,8 @@ namespace Opm template ConvergenceReport StandardWell:: - getWellConvergence(const WellState& well_state, + getWellConvergence(const SummaryState& summary_state, + const WellState& well_state, const std::vector& B_avg, DeferredLogger& deferred_logger, const bool relax_tolerance) const @@ -1412,15 +1413,21 @@ namespace Opm // 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); + // 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 res; ConvergenceReport report = this->StdWellEval::getWellConvergence(well_state, B_avg, this->param_.max_residual_allowed_, - this->param_.tolerance_wells_, + tol_wells, this->param_.relaxed_tolerance_flow_well_, relax_tolerance, res, deferred_logger); + checkConvergenceExtraEqs(res, report); return report; @@ -2083,7 +2090,7 @@ namespace Opm this->linSys_.extract(jacobian); } - + template void StandardWell::addWellPressureEquations(PressureMatrix& jacobian, @@ -2101,7 +2108,7 @@ namespace Opm well_state); } - + template typename StandardWell::EvalWell @@ -2506,6 +2513,7 @@ namespace Opm bool converged; bool relax_convergence = false; this->regularize_ = false; + const auto& summary_state = ebosSimulator.vanguard().summaryState(); do { assembleWellEqWithoutIteration(ebosSimulator, dt, inj_controls, prod_controls, well_state, group_state, deferred_logger); @@ -2514,7 +2522,7 @@ namespace Opm 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(); if (converged) { @@ -2522,7 +2530,6 @@ namespace Opm } ++it; - const auto& summary_state = ebosSimulator.vanguard().summaryState(); 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 diff --git a/opm/simulators/wells/WellInterface.hpp b/opm/simulators/wells/WellInterface.hpp index d540960c4..1ad8e7dcd 100644 --- a/opm/simulators/wells/WellInterface.hpp +++ b/opm/simulators/wells/WellInterface.hpp @@ -154,7 +154,11 @@ public: virtual void initPrimaryVariablesEvaluation() = 0; - virtual ConvergenceReport getWellConvergence(const WellState& well_state, const std::vector& 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& B_avg, + DeferredLogger& deferred_logger, + const bool relax_tolerance) const = 0; void assembleWellEq(const Simulator& ebosSimulator, const double dt,