27#ifndef EWOMS_NEWTON_METHOD_HH
28#define EWOMS_NEWTON_METHOD_HH
30#include <dune/common/classname.hh>
31#include <dune/common/parallel/mpihelper.hh>
33#include <dune/istl/istlexception.hh>
35#include <opm/common/Exceptions.hpp>
37#include <opm/material/densead/Math.hpp>
63template <
class TypeTag>
79template<
class TypeTag>
83template<
class TypeTag>
98template <
class TypeTag>
116 using Communicator =
typename Dune::MPIHelper::MPICommunicator;
117 using CollectiveCommunication =
typename Dune::Communication<typename Dune::MPIHelper::MPICommunicator>;
126 ,
comm_(
Dune::MPIHelper::getCommunicator())
137 LinearSolverBackend::registerParameters();
193 {
params_.tolerance_ = value; }
203 const SolutionVector& currentSolution,
204 const GlobalEqVector& solutionUpdate,
205 const GlobalEqVector& currentResidual)
207 asImp_().update_(nextSolution, currentSolution, solutionUpdate, currentResidual);
218 const bool istty = isatty(fileno(stdout));
223 const char* clearRemainingLine =
"\n";
225 static const char ansiClear[] = { 0x1b,
'[',
'K',
'\r', 0 };
226 clearRemainingLine = ansiClear;
235 SolutionVector& nextSolution =
model().solution(0);
236 SolutionVector currentSolution(nextSolution);
237 GlobalEqVector solutionUpdate(nextSolution.size());
239 Linearizer& linearizer =
model().linearizer();
245 asImp_().begin_(nextSolution);
262 asImp_().beginIteration_();
266 currentSolution = nextSolution;
269 std::cout <<
"Linearize: r(x^k) = dS/dt + div F - q; M = grad r"
270 << clearRemainingLine
276 asImp_().linearizeDomain_();
277 asImp_().linearizeAuxiliaryEquations_();
281 auto& residual = linearizer.residual();
282 const auto& jacobian = linearizer.jacobian();
292 asImp_().preSolve_(currentSolution, residual);
297 std::cout << clearRemainingLine << std::flush;
302 asImp_().endIteration_(nextSolution, currentSolution);
310 std::cout <<
"Solve: M deltax^k = r"
311 << clearRemainingLine
319 solutionUpdate = 0.0;
326 std::cout <<
"Newton: Linear solver did not converge\n" << std::flush;
338 std::cout <<
"Update: x^(k+1) = x^k - deltax^k"
339 << clearRemainingLine
346 asImp_().postSolve_(currentSolution,
349 asImp_().update_(nextSolution, currentSolution, solutionUpdate, residual);
354 std::cout << clearRemainingLine
360 asImp_().endIteration_(nextSolution, currentSolution);
364 catch (
const Dune::Exception& e)
367 std::cout <<
"Newton method caught exception: \""
368 << e.what() <<
"\"\n" << std::flush;
377 catch (
const NumericalProblem& e)
380 std::cout <<
"Newton method caught exception: \""
381 << e.what() <<
"\"\n" << std::flush;
393 std::cout << clearRemainingLine
408 std::cout <<
"Linearization/solve/update time: "
415 <<
"\n" << std::flush;
429 asImp_().succeeded_();
449 const int nit =
problem().iterationContext().iteration();
452 Scalar percent = Scalar(overshoot) /
params_.targetIterations_;
453 Scalar nextDt = std::max(
problem().minTimeStepSize(),
454 oldDt / (Scalar{1.0} + percent));
458 Scalar percent = Scalar(
params_.targetIterations_ - nit) /
params_.targetIterations_;
459 Scalar nextDt = std::max(
problem().minTimeStepSize(),
460 oldDt*(Scalar{1.0} + percent / Scalar{1.2}));
519 problem().resetIterationForNewTimestep();
521 if (
params_.writeConvergence_) {
533 const auto& comm =
simulator_.gridView().comm();
534 bool succeeded =
true;
538 catch (
const std::exception& e) {
541 std::cout <<
"rank " <<
simulator_.gridView().comm().rank()
542 <<
" caught an exception while pre-processing the problem:" << e.what()
543 <<
"\n" << std::flush;
546 succeeded = comm.min(succeeded);
549 throw NumericalProblem(
"pre processing of the problem failed");
560 {
model().linearizer().linearizeDomain(); }
564 model().linearizer().linearizeAuxiliaryEquations();
565 model().linearizer().finalize();
569 const GlobalEqVector& currentResidual)
571 const auto& constraintsMap =
model().linearizer().constraintsMap();
573 Scalar newtonMaxError =
params_.maxError_;
578 for (
unsigned dofIdx = 0; dofIdx < currentResidual.size(); ++dofIdx) {
580 if (dofIdx >=
model().numGridDof() ||
model().dofTotalVolume(dofIdx) <= 0.0) {
586 if (constraintsMap.count(dofIdx) > 0) {
591 const auto& r = currentResidual[dofIdx];
592 for (
unsigned eqIdx = 0; eqIdx < r.size(); ++eqIdx) {
602 if (
error_ > newtonMaxError) {
604 " is larger than maximum allowed error of " +
622 const GlobalEqVector&,
623 GlobalEqVector& solutionUpdate)
627 const auto& comm =
simulator_.gridView().comm();
628 for (
unsigned i = 0; i <
simulator_.model().numAuxiliaryModules(); ++i) {
629 bool succeeded =
true;
631 simulator_.model().auxiliaryModule(i)->postSolve(solutionUpdate);
633 catch (
const std::exception& e) {
636 std::cout <<
"rank " <<
simulator_.gridView().comm().rank()
637 <<
" caught an exception while post processing an auxiliary module:" << e.what()
638 <<
"\n" << std::flush;
641 succeeded = comm.min(succeeded);
644 throw NumericalProblem(
"post processing of an auxilary equation failed");
664 const SolutionVector& currentSolution,
665 const GlobalEqVector& solutionUpdate,
666 const GlobalEqVector& currentResidual)
668 const auto& constraintsMap =
model().linearizer().constraintsMap();
672 asImp_().writeConvergence_(currentSolution, solutionUpdate);
675 if (!std::isfinite(solutionUpdate.one_norm())) {
676 throw NumericalProblem(
"Non-finite update!");
679 std::size_t numGridDof =
model().numGridDof();
680 for (
unsigned dofIdx = 0; dofIdx < numGridDof; ++dofIdx) {
682 if (constraintsMap.count(dofIdx) > 0) {
683 const auto& constraints = constraintsMap.at(dofIdx);
684 asImp_().updateConstraintDof_(dofIdx,
685 nextSolution[dofIdx],
689 asImp_().updatePrimaryVariables_(dofIdx,
690 nextSolution[dofIdx],
691 currentSolution[dofIdx],
692 solutionUpdate[dofIdx],
693 currentResidual[dofIdx]);
697 asImp_().updatePrimaryVariables_(dofIdx,
698 nextSolution[dofIdx],
699 currentSolution[dofIdx],
700 solutionUpdate[dofIdx],
701 currentResidual[dofIdx]);
706 std::size_t numDof =
model().numTotalDof();
707 for (std::size_t dofIdx = numGridDof; dofIdx < numDof; ++dofIdx) {
708 nextSolution[dofIdx] = currentSolution[dofIdx];
709 nextSolution[dofIdx] -= solutionUpdate[dofIdx];
717 PrimaryVariables& nextValue,
718 const Constraints& constraints)
719 { nextValue = constraints; }
725 PrimaryVariables& nextValue,
726 const PrimaryVariables& currentValue,
727 const EqVector& update,
730 nextValue = currentValue;
741 const GlobalEqVector& solutionUpdate)
743 if (
params_.writeConvergence_) {
757 const SolutionVector&)
761 const auto& comm =
simulator_.gridView().comm();
762 bool succeeded =
true;
766 catch (
const std::exception& e) {
769 std::cout <<
"rank " <<
simulator_.gridView().comm().rank()
770 <<
" caught an exception while letting the problem post-process:" << e.what()
771 <<
"\n" << std::flush;
774 succeeded = comm.min(succeeded);
777 throw NumericalProblem(
"post processing of the problem failed");
781 std::cout <<
"Newton iteration " <<
problem().iterationContext().iteration() <<
""
792 if (
problem().iterationContext().iteration() < 1) {
800 else if (
problem().iterationContext().iteration() >=
params_.maxIterations_) {
817 if (
params_.writeConvergence_) {
839 {
return getPropValue<TypeTag, Properties::EnableConstraints>(); }
868 Implementation& asImp_()
869 {
return *
static_cast<Implementation *
>(
this); }
871 const Implementation& asImp_()
const
872 {
return *
static_cast<const Implementation *
>(
this); }
The multi-dimensional Newton method.
Definition: newtonmethod.hh:100
bool verbose_() const
Returns true if the Newton method ought to be chatty.
Definition: newtonmethod.hh:506
Timer linearizeTimer_
Definition: newtonmethod.hh:844
void end_()
Indicates that we're done solving the non-linear system of equations.
Definition: newtonmethod.hh:815
const Timer & updateTimer() const
Definition: newtonmethod.hh:499
const Timer & linearizeTimer() const
Definition: newtonmethod.hh:493
Timer solveTimer_
Definition: newtonmethod.hh:845
const Timer & solveTimer() const
Definition: newtonmethod.hh:496
bool proceed_() const
Returns true iff another Newton iteration should be done.
Definition: newtonmethod.hh:790
static bool enableConstraints_()
Definition: newtonmethod.hh:838
const LinearSolverBackend & linearSolver() const
Returns the linear solver backend object for external use.
Definition: newtonmethod.hh:487
void updatePrimaryVariables_(unsigned, PrimaryVariables &nextValue, const PrimaryVariables ¤tValue, const EqVector &update, const EqVector &)
Update a single primary variables object.
Definition: newtonmethod.hh:724
void setTolerance(Scalar value)
Set the current tolerance at which the Newton method considers itself to be converged.
Definition: newtonmethod.hh:192
std::ostringstream & endIterMsg()
Message that should be printed for the user after the end of an iteration.
Definition: newtonmethod.hh:468
static void registerParameters()
Register all run-time parameters for the Newton method.
Definition: newtonmethod.hh:135
Timer prePostProcessTimer_
Definition: newtonmethod.hh:843
void postSolve_(const SolutionVector &, const GlobalEqVector &, GlobalEqVector &solutionUpdate)
Update the error of the solution given the previous iteration.
Definition: newtonmethod.hh:621
const Timer & prePostProcessTimer() const
Definition: newtonmethod.hh:490
Scalar lastError_
Definition: newtonmethod.hh:851
bool apply()
Run the Newton method.
Definition: newtonmethod.hh:216
void writeConvergence_(const SolutionVector ¤tSolution, const GlobalEqVector &solutionUpdate)
Write the convergence behaviour of the newton method to disk.
Definition: newtonmethod.hh:740
Scalar error_
Definition: newtonmethod.hh:850
bool lastSolveFailed_
Definition: newtonmethod.hh:855
void begin_(const SolutionVector &)
Called before the Newton method is applied to an non-linear system of equations.
Definition: newtonmethod.hh:515
void failed_()
Called if the Newton method broke down.
Definition: newtonmethod.hh:827
void update_(SolutionVector &nextSolution, const SolutionVector ¤tSolution, const GlobalEqVector &solutionUpdate, const GlobalEqVector ¤tResidual)
Update the current solution with a delta vector.
Definition: newtonmethod.hh:663
void preSolve_(const SolutionVector &, const GlobalEqVector ¤tResidual)
Definition: newtonmethod.hh:568
Timer updateTimer_
Definition: newtonmethod.hh:846
const Model & model() const
Returns a reference to the numeric model.
Definition: newtonmethod.hh:178
LinearSolverBackend linearSolver_
Definition: newtonmethod.hh:857
void succeeded_()
Called if the Newton method was successful.
Definition: newtonmethod.hh:835
Scalar tolerance() const
Return the current tolerance at which the Newton method considers itself to be converged.
Definition: newtonmethod.hh:185
LinearSolverBackend & linearSolver()
Returns the linear solver backend object for external use.
Definition: newtonmethod.hh:481
void linearizeDomain_()
Linearize the global non-linear system of equations associated with the spatial domain.
Definition: newtonmethod.hh:559
const Problem & problem() const
Returns a reference to the object describing the current physical problem.
Definition: newtonmethod.hh:166
Scalar suggestTimeStepSize(Scalar oldDt) const
Suggest a new time-step size based on the old time-step size.
Definition: newtonmethod.hh:443
bool converged() const
Returns true if the error of the solution is below the tolerance.
Definition: newtonmethod.hh:154
CollectiveCommunication comm_
Definition: newtonmethod.hh:861
Problem & problem()
Returns a reference to the object describing the current physical problem.
Definition: newtonmethod.hh:160
NewtonMethodParams< Scalar > params_
Definition: newtonmethod.hh:852
void eraseMatrix()
Causes the solve() method to discared the structure of the linear system of equations the next time i...
Definition: newtonmethod.hh:475
void applyUpdate(SolutionVector &nextSolution, const SolutionVector ¤tSolution, const GlobalEqVector &solutionUpdate, const GlobalEqVector ¤tResidual)
Public wrapper for applying a Newton update to a solution vector.
Definition: newtonmethod.hh:202
void updateConstraintDof_(unsigned, PrimaryVariables &nextValue, const Constraints &constraints)
Update the primary variables for a degree of freedom which is constraint.
Definition: newtonmethod.hh:716
std::ostringstream endIterMsgStream_
Definition: newtonmethod.hh:848
ConvergenceWriter convergenceWriter_
Definition: newtonmethod.hh:865
NewtonMethod(Simulator &simulator)
Definition: newtonmethod.hh:120
void finishInit()
Finialize the construction of the object.
Definition: newtonmethod.hh:147
void linearizeAuxiliaryEquations_()
Definition: newtonmethod.hh:562
Model & model()
Returns a reference to the numeric model.
Definition: newtonmethod.hh:172
Simulator & simulator_
Definition: newtonmethod.hh:841
void beginIteration_()
Indicates the beginning of a Newton iteration.
Definition: newtonmethod.hh:529
void endIteration_(const SolutionVector &, const SolutionVector &)
Indicates that one Newton iteration was finished.
Definition: newtonmethod.hh:756
A convergence writer for the Newton method which does nothing.
Definition: nullconvergencewriter.hh:51
A simple class which makes sure that a timer gets stopped if an exception is thrown.
Definition: timerguard.hh:42
Provides an encapsulation to measure the system time.
Definition: timer.hpp:46
void start()
Start counting the time resources used by the simulation.
void halt()
Stop the measurement reset all timing values.
double realTimeElapsed() const
Return the real time [s] elapsed during the periods the timer was active since the last reset.
double stop()
Stop counting the time resources.
Declare the properties used by the infrastructure code of the finite volume discretizations.
Declares the properties required by the black oil model.
Definition: fvbaseprimaryvariables.hh:161
Definition: blackoilmodel.hh:75
Definition: blackoilbioeffectsmodules.hh:45
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property (equivalent to old macro GET_PROP_TYPE(....
Definition: propertysystem.hh:233
std::string to_string(const ConvergenceReport::ReservoirFailure::Type t)
Struct holding the parameters for NewtonMethod.
Definition: newtonmethodparams.hpp:71
static void registerParameters()
Registers the parameters in parameter system.
Specifies the type of the class which writes out the Newton convergence.
Definition: newtonmethodproperties.hh:40
Specifies the type of the actual Newton method.
Definition: newtonmethodproperties.hh:32
Definition: newtonmethod.hh:74