diff --git a/opm/autodiff/BlackoilModelBase.hpp b/opm/autodiff/BlackoilModelBase.hpp index 8d51cc73a..95067c4a4 100644 --- a/opm/autodiff/BlackoilModelBase.hpp +++ b/opm/autodiff/BlackoilModelBase.hpp @@ -82,6 +82,7 @@ namespace Opm { bool failed; bool converged; int linear_iterations; + int well_iterations; }; @@ -196,9 +197,11 @@ namespace Opm { /// \param[in] reservoir_state reservoir state variables /// \param[in, out] well_state well state variables /// \param[in] initial_assembly pass true if this is the first call to assemble() in this timestep + /// \return well iterations. void assemble(const ReservoirState& reservoir_state, WellState& well_state, - const bool initial_assembly); + const bool initial_assembly, + int& well_iters); /// \brief Compute the residual norms of the mass balance for each phase, /// the well flux, and the well equation. @@ -377,7 +380,8 @@ namespace Opm { solveWellEq(const std::vector& mob_perfcells, const std::vector& b_perfcells, SolutionState& state, - WellState& well_state); + WellState& well_state, + int& well_iters); void addWellContributionToMassBalanceEq(const std::vector& cq_s, diff --git a/opm/autodiff/BlackoilModelBase_impl.hpp b/opm/autodiff/BlackoilModelBase_impl.hpp index 1f12d9606..87581f577 100644 --- a/opm/autodiff/BlackoilModelBase_impl.hpp +++ b/opm/autodiff/BlackoilModelBase_impl.hpp @@ -288,7 +288,8 @@ namespace detail { current_relaxation_ = 1.0; dx_old_ = V::Zero(sizeNonLinear()); } - asImpl().assemble(reservoir_state, well_state, iteration == 0); + int well_iters = 0; + asImpl().assemble(reservoir_state, well_state, iteration == 0, well_iters); residual_norms_history_.push_back(asImpl().computeResidualNorms()); const bool converged = asImpl().getConvergence(dt, iteration); const bool must_solve = (iteration < nonlinear_solver.minIter()) || (!converged); @@ -322,7 +323,7 @@ namespace detail { } const bool failed = false; // Not needed in this model. const int linear_iters = must_solve ? asImpl().linearIterationsLastSolve() : 0; - return IterationReport{ failed, converged, linear_iters }; + return IterationReport{ failed, converged, linear_iters , well_iters}; } @@ -731,7 +732,8 @@ namespace detail { BlackoilModelBase:: assemble(const ReservoirState& reservoir_state, WellState& well_state, - const bool initial_assembly) + const bool initial_assembly, + int& well_iters) { using namespace Opm::AutoDiffGrid; @@ -785,7 +787,7 @@ namespace detail { asImpl().wellModel().extractWellPerfProperties(state, rq_, mob_perfcells, b_perfcells); if (param_.solve_welleq_initially_ && initial_assembly) { // solve the well equations as a pre-processing step - asImpl().solveWellEq(mob_perfcells, b_perfcells, state, well_state); + asImpl().solveWellEq(mob_perfcells, b_perfcells, state, well_state, well_iters); } V aliveWells; std::vector cq_s; @@ -799,8 +801,7 @@ namespace detail { SolutionState state0 = state; asImpl().makeConstantState(state0); asImpl().wellModel().computeWellPotentials(mob_perfcells, b_perfcells, state0, well_state); - } - + } } @@ -976,7 +977,8 @@ namespace detail { solveWellEq(const std::vector& mob_perfcells, const std::vector& b_perfcells, SolutionState& state, - WellState& well_state) + WellState& well_state, + int& well_iters) { V aliveWells; const int np = wells().number_of_phases; @@ -1041,6 +1043,7 @@ namespace detail { } while (it < 15); if (converged) { + well_iters = it; if ( terminal_output_ ) { OpmLog::info("well converged iter: " + std::to_string(it)); } diff --git a/opm/autodiff/BlackoilMultiSegmentModel.hpp b/opm/autodiff/BlackoilMultiSegmentModel.hpp index 774f8c238..49c925d16 100644 --- a/opm/autodiff/BlackoilMultiSegmentModel.hpp +++ b/opm/autodiff/BlackoilMultiSegmentModel.hpp @@ -107,7 +107,8 @@ namespace Opm { /// \param[in] initial_assembly pass true if this is the first call to assemble() in this timestep void assemble(const ReservoirState& reservoir_state, WellState& well_state, - const bool initial_assembly); + const bool initial_assembly, + int& well_iters); using Base::numPhases; using Base::numMaterials; @@ -168,7 +169,8 @@ namespace Opm { solveWellEq(const std::vector& mob_perfcells, const std::vector& b_perfcells, SolutionState& state, - WellState& well_state); + WellState& well_state, + int& well_iters); void makeConstantState(SolutionState& state) const; diff --git a/opm/autodiff/BlackoilMultiSegmentModel_impl.hpp b/opm/autodiff/BlackoilMultiSegmentModel_impl.hpp index 3f5d94bd5..ebe81e0f7 100644 --- a/opm/autodiff/BlackoilMultiSegmentModel_impl.hpp +++ b/opm/autodiff/BlackoilMultiSegmentModel_impl.hpp @@ -130,7 +130,8 @@ namespace Opm { BlackoilMultiSegmentModel:: assemble(const ReservoirState& reservoir_state, WellState& well_state, - const bool initial_assembly) + const bool initial_assembly, + int& well_iters) { using namespace Opm::AutoDiffGrid; @@ -197,7 +198,7 @@ namespace Opm { wellModel().extractWellPerfProperties(state, rq_, mob_perfcells, b_perfcells); if (param_.solve_welleq_initially_ && initial_assembly) { // solve the well equations as a pre-processing step - asImpl().solveWellEq(mob_perfcells, b_perfcells, state, well_state); + asImpl().solveWellEq(mob_perfcells, b_perfcells, state, well_state, well_iters); } // the perforation flux here are different @@ -219,9 +220,10 @@ namespace Opm { bool BlackoilMultiSegmentModel::solveWellEq(const std::vector& mob_perfcells, const std::vector& b_perfcells, SolutionState& state, - WellState& well_state) + WellState& well_state, + int& well_iters) { - const bool converged = Base::solveWellEq(mob_perfcells, b_perfcells, state, well_state); + const bool converged = Base::solveWellEq(mob_perfcells, b_perfcells, state, well_state, well_iters); if (converged) { // We must now update the state.segp and state.segqs members, diff --git a/opm/autodiff/NonlinearSolver_impl.hpp b/opm/autodiff/NonlinearSolver_impl.hpp index 9b52235e5..513765510 100644 --- a/opm/autodiff/NonlinearSolver_impl.hpp +++ b/opm/autodiff/NonlinearSolver_impl.hpp @@ -110,6 +110,7 @@ namespace Opm // Set up for main solver loop. int linIters = 0; bool converged = false; + int wellIters = 0; // ---------- Main nonlinear solver loop ---------- do { @@ -122,6 +123,7 @@ namespace Opm } converged = report.converged; linIters += report.linear_iterations; + wellIters += report.well_iterations; ++iteration; } while ( (!converged && (iteration <= maxIter())) || (iteration <= minIter())); @@ -134,8 +136,10 @@ namespace Opm linearIterations_ += linIters; nonlinearIterations_ += iteration - 1; // Since the last one will always be trivial. + wellIterations_ += wellIters; linearIterationsLast_ = linIters; nonlinearIterationsLast_ = iteration; + wellIterationsLast_ = wellIters; // Do model-specific post-step actions. model_->afterStep(dt, reservoir_state, well_state); diff --git a/opm/polymer/fullyimplicit/BlackoilPolymerModel.hpp b/opm/polymer/fullyimplicit/BlackoilPolymerModel.hpp index 3ae9dc16e..b11441d45 100644 --- a/opm/polymer/fullyimplicit/BlackoilPolymerModel.hpp +++ b/opm/polymer/fullyimplicit/BlackoilPolymerModel.hpp @@ -122,7 +122,8 @@ namespace Opm { /// \param[in] initial_assembly pass true if this is the first call to assemble() in this timestep void assemble(const ReservoirState& reservoir_state, WellState& well_state, - const bool initial_assembly); + const bool initial_assembly, + int& well_iters); protected: diff --git a/opm/polymer/fullyimplicit/BlackoilPolymerModel_impl.hpp b/opm/polymer/fullyimplicit/BlackoilPolymerModel_impl.hpp index 809f3aebb..46870428f 100644 --- a/opm/polymer/fullyimplicit/BlackoilPolymerModel_impl.hpp +++ b/opm/polymer/fullyimplicit/BlackoilPolymerModel_impl.hpp @@ -492,7 +492,8 @@ namespace Opm { void BlackoilPolymerModel::assemble(const ReservoirState& reservoir_state, WellState& well_state, - const bool initial_assembly) + const bool initial_assembly, + int& well_iters) { using namespace Opm::AutoDiffGrid; @@ -537,7 +538,7 @@ namespace Opm { wellModel().extractWellPerfProperties(state, rq_, mob_perfcells, b_perfcells); if (param_.solve_welleq_initially_ && initial_assembly) { // solve the well equations as a pre-processing step - Base::solveWellEq(mob_perfcells, b_perfcells, state, well_state); + Base::solveWellEq(mob_perfcells, b_perfcells, state, well_state, well_iters); } V aliveWells;