Merge pull request #545 from atgeirr/fix-min-iter

Honor the min_iter parameter.
This commit is contained in:
Atgeirr Flø Rasmussen 2015-11-27 10:19:26 +01:00
commit 315862ddd4
3 changed files with 21 additions and 14 deletions

View File

@ -248,7 +248,8 @@ namespace detail {
asImpl().assemble(reservoir_state, well_state, iteration == 0);
residual_norms_history_.push_back(asImpl().computeResidualNorms());
const bool converged = asImpl().getConvergence(dt, iteration);
if (!converged) {
const bool must_solve = (iteration < nonlinear_solver.minIter()) || (!converged);
if (must_solve) {
// Compute the nonlinear update.
V dx = asImpl().solveJacobianSystem();
@ -271,7 +272,7 @@ namespace detail {
asImpl().updateState(dx, reservoir_state, well_state);
}
const bool failed = false; // Not needed in this model.
const int linear_iters = converged ? 0 : asImpl().linearIterationsLastSolve();
const int linear_iters = must_solve ? asImpl().linearIterationsLastSolve() : 0;
return IterationReport{ failed, converged, linear_iters };
}

View File

@ -113,6 +113,18 @@ namespace Opm {
/// The step-change size for the relaxation factor.
double relaxIncrement() const { return param_.relax_increment_; }
/// The relaxation type (DAMPEN or SOR).
enum RelaxType relaxType() const { return param_.relax_type_; }
/// The relaxation relative tolerance.
double relaxRelTol() const { return param_.relax_rel_tol_; }
/// The maximum number of nonlinear iterations allowed.
double maxIter() const { return param_.max_iter_; }
/// The minimum number of nonlinear iterations allowed.
double minIter() const { return param_.min_iter_; }
private:
// --------- Data members ---------
SolverParameters param_;
@ -121,12 +133,6 @@ namespace Opm {
unsigned int linearIterations_;
unsigned int nonlinearIterationsLast_;
unsigned int linearIterationsLast_;
// --------- Private methods ---------
enum RelaxType relaxType() const { return param_.relax_type_; }
double relaxRelTol() const { return param_.relax_rel_tol_; }
double maxIter() const { return param_.max_iter_; }
double minIter() const { return param_.min_iter_; }
};
} // namespace Opm

View File

@ -93,21 +93,21 @@ namespace Opm
// ---------- Main nonlinear solver loop ----------
do {
// Do the nonlinear step. If we are in a converged state, the
// model will usually do an early return without an expensive
// solve, unless the minIter() count has not been reached yet.
IterationReport report = model_->nonlinearIteration(iteration, dt, *this, reservoir_state, well_state);
if (report.failed) {
OPM_THROW(Opm::NumericalProblem, "Failed to complete a nonlinear iteration.");
}
if (report.converged) {
assert(report.linear_iterations == 0);
converged = true;
}
converged = report.converged;
linIters += report.linear_iterations;
++iteration;
} while ( (!converged && (iteration <= maxIter())) || (minIter() > iteration));
} while ( (!converged && (iteration <= maxIter())) || (iteration <= minIter()));
if (!converged) {
if (model_->terminalOutputEnabled()) {
std::cerr << "WARNING: Failed to compute converged solution in " << iteration << " iterations." << std::endl;
std::cerr << "WARNING: Failed to compute converged solution in " << iteration - 1 << " iterations." << std::endl;
}
return -1; // -1 indicates that the solver has to be restarted
}