return well iteration from simulators.

This commit is contained in:
Liu Ming 2016-06-20 16:25:35 +08:00
parent 6dfd5ec63d
commit 969f6f1d1b
7 changed files with 35 additions and 18 deletions

View File

@ -82,6 +82,7 @@ namespace Opm {
bool failed; bool failed;
bool converged; bool converged;
int linear_iterations; int linear_iterations;
int well_iterations;
}; };
@ -196,9 +197,11 @@ namespace Opm {
/// \param[in] reservoir_state reservoir state variables /// \param[in] reservoir_state reservoir state variables
/// \param[in, out] well_state well 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 /// \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, void assemble(const ReservoirState& reservoir_state,
WellState& well_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, /// \brief Compute the residual norms of the mass balance for each phase,
/// the well flux, and the well equation. /// the well flux, and the well equation.
@ -377,7 +380,8 @@ namespace Opm {
solveWellEq(const std::vector<ADB>& mob_perfcells, solveWellEq(const std::vector<ADB>& mob_perfcells,
const std::vector<ADB>& b_perfcells, const std::vector<ADB>& b_perfcells,
SolutionState& state, SolutionState& state,
WellState& well_state); WellState& well_state,
int& well_iters);
void void
addWellContributionToMassBalanceEq(const std::vector<ADB>& cq_s, addWellContributionToMassBalanceEq(const std::vector<ADB>& cq_s,

View File

@ -288,7 +288,8 @@ namespace detail {
current_relaxation_ = 1.0; current_relaxation_ = 1.0;
dx_old_ = V::Zero(sizeNonLinear()); 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()); residual_norms_history_.push_back(asImpl().computeResidualNorms());
const bool converged = asImpl().getConvergence(dt, iteration); const bool converged = asImpl().getConvergence(dt, iteration);
const bool must_solve = (iteration < nonlinear_solver.minIter()) || (!converged); 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 bool failed = false; // Not needed in this model.
const int linear_iters = must_solve ? asImpl().linearIterationsLastSolve() : 0; 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<Grid, WellModel, Implementation>:: BlackoilModelBase<Grid, WellModel, Implementation>::
assemble(const ReservoirState& reservoir_state, assemble(const ReservoirState& reservoir_state,
WellState& well_state, WellState& well_state,
const bool initial_assembly) const bool initial_assembly,
int& well_iters)
{ {
using namespace Opm::AutoDiffGrid; using namespace Opm::AutoDiffGrid;
@ -785,7 +787,7 @@ namespace detail {
asImpl().wellModel().extractWellPerfProperties(state, rq_, mob_perfcells, b_perfcells); asImpl().wellModel().extractWellPerfProperties(state, rq_, mob_perfcells, b_perfcells);
if (param_.solve_welleq_initially_ && initial_assembly) { if (param_.solve_welleq_initially_ && initial_assembly) {
// solve the well equations as a pre-processing step // 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; V aliveWells;
std::vector<ADB> cq_s; std::vector<ADB> cq_s;
@ -800,7 +802,6 @@ namespace detail {
asImpl().makeConstantState(state0); asImpl().makeConstantState(state0);
asImpl().wellModel().computeWellPotentials(mob_perfcells, b_perfcells, state0, well_state); asImpl().wellModel().computeWellPotentials(mob_perfcells, b_perfcells, state0, well_state);
} }
} }
@ -976,7 +977,8 @@ namespace detail {
solveWellEq(const std::vector<ADB>& mob_perfcells, solveWellEq(const std::vector<ADB>& mob_perfcells,
const std::vector<ADB>& b_perfcells, const std::vector<ADB>& b_perfcells,
SolutionState& state, SolutionState& state,
WellState& well_state) WellState& well_state,
int& well_iters)
{ {
V aliveWells; V aliveWells;
const int np = wells().number_of_phases; const int np = wells().number_of_phases;
@ -1041,6 +1043,7 @@ namespace detail {
} while (it < 15); } while (it < 15);
if (converged) { if (converged) {
well_iters = it;
if ( terminal_output_ ) { if ( terminal_output_ ) {
OpmLog::info("well converged iter: " + std::to_string(it)); OpmLog::info("well converged iter: " + std::to_string(it));
} }

View File

@ -107,7 +107,8 @@ namespace Opm {
/// \param[in] initial_assembly pass true if this is the first call to assemble() in this timestep /// \param[in] initial_assembly pass true if this is the first call to assemble() in this timestep
void assemble(const ReservoirState& reservoir_state, void assemble(const ReservoirState& reservoir_state,
WellState& well_state, WellState& well_state,
const bool initial_assembly); const bool initial_assembly,
int& well_iters);
using Base::numPhases; using Base::numPhases;
using Base::numMaterials; using Base::numMaterials;
@ -168,7 +169,8 @@ namespace Opm {
solveWellEq(const std::vector<ADB>& mob_perfcells, solveWellEq(const std::vector<ADB>& mob_perfcells,
const std::vector<ADB>& b_perfcells, const std::vector<ADB>& b_perfcells,
SolutionState& state, SolutionState& state,
WellState& well_state); WellState& well_state,
int& well_iters);
void void
makeConstantState(SolutionState& state) const; makeConstantState(SolutionState& state) const;

View File

@ -130,7 +130,8 @@ namespace Opm {
BlackoilMultiSegmentModel<Grid>:: BlackoilMultiSegmentModel<Grid>::
assemble(const ReservoirState& reservoir_state, assemble(const ReservoirState& reservoir_state,
WellState& well_state, WellState& well_state,
const bool initial_assembly) const bool initial_assembly,
int& well_iters)
{ {
using namespace Opm::AutoDiffGrid; using namespace Opm::AutoDiffGrid;
@ -197,7 +198,7 @@ namespace Opm {
wellModel().extractWellPerfProperties(state, rq_, mob_perfcells, b_perfcells); wellModel().extractWellPerfProperties(state, rq_, mob_perfcells, b_perfcells);
if (param_.solve_welleq_initially_ && initial_assembly) { if (param_.solve_welleq_initially_ && initial_assembly) {
// solve the well equations as a pre-processing step // 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 // the perforation flux here are different
@ -219,9 +220,10 @@ namespace Opm {
bool BlackoilMultiSegmentModel<Grid>::solveWellEq(const std::vector<ADB>& mob_perfcells, bool BlackoilMultiSegmentModel<Grid>::solveWellEq(const std::vector<ADB>& mob_perfcells,
const std::vector<ADB>& b_perfcells, const std::vector<ADB>& b_perfcells,
SolutionState& state, 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) { if (converged) {
// We must now update the state.segp and state.segqs members, // We must now update the state.segp and state.segqs members,

View File

@ -110,6 +110,7 @@ namespace Opm
// Set up for main solver loop. // Set up for main solver loop.
int linIters = 0; int linIters = 0;
bool converged = false; bool converged = false;
int wellIters = 0;
// ---------- Main nonlinear solver loop ---------- // ---------- Main nonlinear solver loop ----------
do { do {
@ -122,6 +123,7 @@ namespace Opm
} }
converged = report.converged; converged = report.converged;
linIters += report.linear_iterations; linIters += report.linear_iterations;
wellIters += report.well_iterations;
++iteration; ++iteration;
} while ( (!converged && (iteration <= maxIter())) || (iteration <= minIter())); } while ( (!converged && (iteration <= maxIter())) || (iteration <= minIter()));
@ -134,8 +136,10 @@ namespace Opm
linearIterations_ += linIters; linearIterations_ += linIters;
nonlinearIterations_ += iteration - 1; // Since the last one will always be trivial. nonlinearIterations_ += iteration - 1; // Since the last one will always be trivial.
wellIterations_ += wellIters;
linearIterationsLast_ = linIters; linearIterationsLast_ = linIters;
nonlinearIterationsLast_ = iteration; nonlinearIterationsLast_ = iteration;
wellIterationsLast_ = wellIters;
// Do model-specific post-step actions. // Do model-specific post-step actions.
model_->afterStep(dt, reservoir_state, well_state); model_->afterStep(dt, reservoir_state, well_state);

View File

@ -122,7 +122,8 @@ namespace Opm {
/// \param[in] initial_assembly pass true if this is the first call to assemble() in this timestep /// \param[in] initial_assembly pass true if this is the first call to assemble() in this timestep
void assemble(const ReservoirState& reservoir_state, void assemble(const ReservoirState& reservoir_state,
WellState& well_state, WellState& well_state,
const bool initial_assembly); const bool initial_assembly,
int& well_iters);
protected: protected:

View File

@ -492,7 +492,8 @@ namespace Opm {
void void
BlackoilPolymerModel<Grid>::assemble(const ReservoirState& reservoir_state, BlackoilPolymerModel<Grid>::assemble(const ReservoirState& reservoir_state,
WellState& well_state, WellState& well_state,
const bool initial_assembly) const bool initial_assembly,
int& well_iters)
{ {
using namespace Opm::AutoDiffGrid; using namespace Opm::AutoDiffGrid;
@ -537,7 +538,7 @@ namespace Opm {
wellModel().extractWellPerfProperties(state, rq_, mob_perfcells, b_perfcells); wellModel().extractWellPerfProperties(state, rq_, mob_perfcells, b_perfcells);
if (param_.solve_welleq_initially_ && initial_assembly) { if (param_.solve_welleq_initially_ && initial_assembly) {
// solve the well equations as a pre-processing step // 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; V aliveWells;