27#ifndef EWOMS_NEWTON_METHOD_HH
28#define EWOMS_NEWTON_METHOD_HH
34#include <opm/common/Exceptions.hpp>
36#include <opm/material/densead/Math.hpp>
44#include <dune/istl/istlexception.hh>
45#include <dune/common/classname.hh>
46#include <dune/common/parallel/mpihelper.hh>
55template <
class TypeTag>
74template<
class TypeTag>
76template<
class TypeTag>
78template<
class TypeTag>
80template<
class TypeTag>
82template<
class TypeTag>
86 static constexpr type value = 1e-8;
90template<
class TypeTag>
94 static constexpr type value = 1e100;
96template<
class TypeTag>
98template<
class TypeTag>
111template <
class TypeTag>
129 using Communicator =
typename Dune::MPIHelper::MPICommunicator;
130 using CollectiveCommunication =
typename Dune::Communication<typename Dune::MPIHelper::MPICommunicator>;
137 ,
comm_(
Dune::MPIHelper::getCommunicator())
142 tolerance_ = Parameters::get<TypeTag, Properties::NewtonTolerance>();
152 LinearSolverBackend::registerParameters();
154 Parameters::registerParam<TypeTag, Properties::NewtonVerbose>
155 (
"Specify whether the Newton method should inform "
156 "the user about its progress or not");
157 Parameters::registerParam<TypeTag, Properties::NewtonWriteConvergence>
158 (
"Write the convergence behaviour of the Newton "
159 "method to a VTK file");
160 Parameters::registerParam<TypeTag, Properties::NewtonTargetIterations>
161 (
"The 'optimum' number of Newton iterations per time step");
162 Parameters::registerParam<TypeTag, Properties::NewtonMaxIterations>
163 (
"The maximum number of Newton iterations per time step");
164 Parameters::registerParam<TypeTag, Properties::NewtonTolerance>
165 (
"The maximum raw error tolerated by the Newton"
166 "method for considering a solution to be converged");
167 Parameters::registerParam<TypeTag, Properties::NewtonMaxError>
168 (
"The maximum error tolerated by the Newton "
169 "method to which does not cause an abort");
254 const char *clearRemainingLine =
"\n";
255 if (isatty(fileno(stdout))) {
256 static const char blubb[] = { 0x1b,
'[',
'K',
'\r', 0 };
257 clearRemainingLine = blubb;
266 SolutionVector& nextSolution =
model().solution(0);
267 SolutionVector currentSolution(nextSolution);
268 GlobalEqVector solutionUpdate(nextSolution.size());
270 Linearizer& linearizer =
model().linearizer();
276 asImp_().begin_(nextSolution);
293 asImp_().beginIteration_();
297 currentSolution = nextSolution;
300 std::cout <<
"Linearize: r(x^k) = dS/dt + div F - q; M = grad r"
301 << clearRemainingLine
307 asImp_().linearizeDomain_();
308 asImp_().linearizeAuxiliaryEquations_();
312 auto& residual = linearizer.residual();
313 const auto& jacobian = linearizer.jacobian();
323 asImp_().preSolve_(currentSolution, residual);
327 if (asImp_().
verbose_() && isatty(fileno(stdout)))
328 std::cout << clearRemainingLine
333 asImp_().endIteration_(nextSolution, currentSolution);
341 std::cout <<
"Solve: M deltax^k = r"
342 << clearRemainingLine
350 solutionUpdate = 0.0;
357 std::cout <<
"Newton: Linear solver did not converge\n" << std::flush;
368 std::cout <<
"Update: x^(k+1) = x^k - deltax^k"
369 << clearRemainingLine
376 asImp_().postSolve_(currentSolution,
379 asImp_().update_(nextSolution, currentSolution, solutionUpdate, residual);
382 if (asImp_().
verbose_() && isatty(fileno(stdout)))
384 std::cout << clearRemainingLine
389 asImp_().endIteration_(nextSolution, currentSolution);
393 catch (
const Dune::Exception& e)
396 std::cout <<
"Newton method caught exception: \""
397 << e.what() <<
"\"\n" << std::flush;
405 catch (
const NumericalProblem& e)
408 std::cout <<
"Newton method caught exception: \""
409 << e.what() <<
"\"\n" << std::flush;
419 if (asImp_().
verbose_() && isatty(fileno(stdout)))
420 std::cout << clearRemainingLine
434 std::cout <<
"Linearization/solve/update time: "
441 <<
"\n" << std::flush;
455 asImp_().succeeded_();
477 Scalar nextDt = std::max(
problem().minTimeStepSize(),
478 oldDt/(1.0 + percent));
483 Scalar nextDt = std::max(
problem().minTimeStepSize(),
484 oldDt*(1.0 + percent/1.2));
532 return Parameters::get<TypeTag, Properties::NewtonVerbose>() && (
comm_.rank() == 0);
545 if (Parameters::get<TypeTag, Properties::NewtonWriteConvergence>())
556 const auto& comm =
simulator_.gridView().comm();
557 bool succeeded =
true;
561 catch (
const std::exception& e) {
564 std::cout <<
"rank " <<
simulator_.gridView().comm().rank()
565 <<
" caught an exception while pre-processing the problem:" << e.what()
566 <<
"\n" << std::flush;
569 succeeded = comm.min(succeeded);
572 throw NumericalProblem(
"pre processing of the problem failed");
583 model().linearizer().linearizeDomain();
588 model().linearizer().linearizeAuxiliaryEquations();
589 model().linearizer().finalize();
593 const GlobalEqVector& currentResidual)
595 const auto& constraintsMap =
model().linearizer().constraintsMap();
597 Scalar newtonMaxError = Parameters::get<TypeTag, Properties::NewtonMaxError>();
602 for (
unsigned dofIdx = 0; dofIdx < currentResidual.size(); ++dofIdx) {
604 if (dofIdx >=
model().numGridDof() ||
model().dofTotalVolume(dofIdx) <= 0.0)
609 if (constraintsMap.count(dofIdx) > 0)
613 const auto& r = currentResidual[dofIdx];
614 for (
unsigned eqIdx = 0; eqIdx < r.size(); ++eqIdx)
623 if (
error_ > newtonMaxError)
624 throw NumericalProblem(
"Newton: Error "+std::to_string(
double(
error_))
625 +
" is larger than maximum allowed error of "
626 + std::to_string(
double(newtonMaxError)));
642 const GlobalEqVector&,
643 GlobalEqVector& solutionUpdate)
648 const auto& comm =
simulator_.gridView().comm();
649 for (
unsigned i = 0; i <
model.numAuxiliaryModules(); ++i) {
650 auto& auxMod = *
model.auxiliaryModule(i);
652 bool succeeded =
true;
654 auxMod.postSolve(solutionUpdate);
656 catch (
const std::exception& e) {
659 std::cout <<
"rank " <<
simulator_.gridView().comm().rank()
660 <<
" caught an exception while post processing an auxiliary module:" << e.what()
661 <<
"\n" << std::flush;
664 succeeded = comm.min(succeeded);
667 throw NumericalProblem(
"post processing of an auxilary equation failed");
686 const SolutionVector& currentSolution,
687 const GlobalEqVector& solutionUpdate,
688 const GlobalEqVector& currentResidual)
690 const auto& constraintsMap =
model().linearizer().constraintsMap();
694 asImp_().writeConvergence_(currentSolution, solutionUpdate);
697 if (!std::isfinite(solutionUpdate.one_norm()))
698 throw NumericalProblem(
"Non-finite update!");
700 size_t numGridDof =
model().numGridDof();
701 for (
unsigned dofIdx = 0; dofIdx < numGridDof; ++dofIdx) {
703 if (constraintsMap.count(dofIdx) > 0) {
704 const auto& constraints = constraintsMap.at(dofIdx);
705 asImp_().updateConstraintDof_(dofIdx,
706 nextSolution[dofIdx],
710 asImp_().updatePrimaryVariables_(dofIdx,
711 nextSolution[dofIdx],
712 currentSolution[dofIdx],
713 solutionUpdate[dofIdx],
714 currentResidual[dofIdx]);
717 asImp_().updatePrimaryVariables_(dofIdx,
718 nextSolution[dofIdx],
719 currentSolution[dofIdx],
720 solutionUpdate[dofIdx],
721 currentResidual[dofIdx]);
725 size_t numDof =
model().numTotalDof();
726 for (
size_t dofIdx = numGridDof; dofIdx < numDof; ++dofIdx) {
727 nextSolution[dofIdx] = currentSolution[dofIdx];
728 nextSolution[dofIdx] -= solutionUpdate[dofIdx];
736 PrimaryVariables& nextValue,
737 const Constraints& constraints)
738 { nextValue = constraints; }
744 PrimaryVariables& nextValue,
745 const PrimaryVariables& currentValue,
746 const EqVector& update,
749 nextValue = currentValue;
760 const GlobalEqVector& solutionUpdate)
762 if (Parameters::get<TypeTag, Properties::NewtonWriteConvergence>()) {
776 const SolutionVector&)
780 const auto& comm =
simulator_.gridView().comm();
781 bool succeeded =
true;
785 catch (
const std::exception& e) {
788 std::cout <<
"rank " <<
simulator_.gridView().comm().rank()
789 <<
" caught an exception while letting the problem post-process:" << e.what()
790 <<
"\n" << std::flush;
793 succeeded = comm.min(succeeded);
796 throw NumericalProblem(
"post processing of the problem failed");
834 if (Parameters::get<TypeTag, Properties::NewtonWriteConvergence>())
856 {
return Parameters::get<TypeTag, Properties::NewtonTargetIterations>(); }
859 {
return Parameters::get<TypeTag, Properties::NewtonMaxIterations>(); }
862 {
return getPropValue<TypeTag, Properties::EnableConstraints>(); }
892 Implementation& asImp_()
893 {
return *
static_cast<Implementation *
>(
this); }
894 const Implementation& asImp_()
const
895 {
return *
static_cast<const Implementation *
>(
this); }
The multi-dimensional Newton method.
Definition: newtonmethod.hh:113
bool verbose_() const
Returns true if the Newton method ought to be chatty.
Definition: newtonmethod.hh:530
Timer linearizeTimer_
Definition: newtonmethod.hh:867
void end_()
Indicates that we're done solving the non-linear system of equations.
Definition: newtonmethod.hh:832
const Timer & updateTimer() const
Definition: newtonmethod.hh:523
const Timer & linearizeTimer() const
Definition: newtonmethod.hh:517
Timer solveTimer_
Definition: newtonmethod.hh:868
const Timer & solveTimer() const
Definition: newtonmethod.hh:520
bool proceed_() const
Returns true iff another Newton iteration should be done.
Definition: newtonmethod.hh:808
int numIterations() const
Returns the number of iterations done since the Newton method was invoked.
Definition: newtonmethod.hh:216
static bool enableConstraints_()
Definition: newtonmethod.hh:861
const LinearSolverBackend & linearSolver() const
Returns the linear solver backend object for external use.
Definition: newtonmethod.hh:511
void updatePrimaryVariables_(unsigned, PrimaryVariables &nextValue, const PrimaryVariables ¤tValue, const EqVector &update, const EqVector &)
Update a single primary variables object.
Definition: newtonmethod.hh:743
Scalar tolerance_
Definition: newtonmethod.hh:875
void setTolerance(Scalar value)
Set the current tolerance at which the Newton method considers itself to be converged.
Definition: newtonmethod.hh:240
int maxIterations_() const
Definition: newtonmethod.hh:858
std::ostringstream & endIterMsg()
Message that should be printed for the user after the end of an iteration.
Definition: newtonmethod.hh:492
static void registerParameters()
Register all run-time parameters for the Newton method.
Definition: newtonmethod.hh:150
Timer prePostProcessTimer_
Definition: newtonmethod.hh:866
int targetIterations_() const
Definition: newtonmethod.hh:855
void postSolve_(const SolutionVector &, const GlobalEqVector &, GlobalEqVector &solutionUpdate)
Update the error of the solution given the previous iteration.
Definition: newtonmethod.hh:641
const Timer & prePostProcessTimer() const
Definition: newtonmethod.hh:514
Scalar lastError_
Definition: newtonmethod.hh:874
bool apply()
Run the Newton method.
Definition: newtonmethod.hh:249
void writeConvergence_(const SolutionVector ¤tSolution, const GlobalEqVector &solutionUpdate)
Write the convergence behaviour of the newton method to disk.
Definition: newtonmethod.hh:759
Scalar error_
Definition: newtonmethod.hh:873
void begin_(const SolutionVector &)
Called before the Newton method is applied to an non-linear system of equations.
Definition: newtonmethod.hh:541
void failed_()
Called if the Newton method broke down.
Definition: newtonmethod.hh:843
void update_(SolutionVector &nextSolution, const SolutionVector ¤tSolution, const GlobalEqVector &solutionUpdate, const GlobalEqVector ¤tResidual)
Update the current solution with a delta vector.
Definition: newtonmethod.hh:685
void preSolve_(const SolutionVector &, const GlobalEqVector ¤tResidual)
Definition: newtonmethod.hh:592
Timer updateTimer_
Definition: newtonmethod.hh:869
const Model & model() const
Returns a reference to the numeric model.
Definition: newtonmethod.hh:209
int numIterations_
Definition: newtonmethod.hh:878
LinearSolverBackend linearSolver_
Definition: newtonmethod.hh:881
void succeeded_()
Called if the Newton method was successful.
Definition: newtonmethod.hh:851
Scalar tolerance() const
Return the current tolerance at which the Newton method considers itself to be converged.
Definition: newtonmethod.hh:233
LinearSolverBackend & linearSolver()
Returns the linear solver backend object for external use.
Definition: newtonmethod.hh:505
void linearizeDomain_()
Linearize the global non-linear system of equations associated with the spatial domain.
Definition: newtonmethod.hh:581
const Problem & problem() const
Returns a reference to the object describing the current physical problem.
Definition: newtonmethod.hh:197
Scalar suggestTimeStepSize(Scalar oldDt) const
Suggest a new time-step size based on the old time-step size.
Definition: newtonmethod.hh:469
bool converged() const
Returns true if the error of the solution is below the tolerance.
Definition: newtonmethod.hh:185
CollectiveCommunication comm_
Definition: newtonmethod.hh:885
Problem & problem()
Returns a reference to the object describing the current physical problem.
Definition: newtonmethod.hh:191
void eraseMatrix()
Causes the solve() method to discared the structure of the linear system of equations the next time i...
Definition: newtonmethod.hh:499
void updateConstraintDof_(unsigned, PrimaryVariables &nextValue, const Constraints &constraints)
Update the primary variables for a degree of freedom which is constraint.
Definition: newtonmethod.hh:735
std::ostringstream endIterMsgStream_
Definition: newtonmethod.hh:871
ConvergenceWriter convergenceWriter_
Definition: newtonmethod.hh:889
NewtonMethod(Simulator &simulator)
Definition: newtonmethod.hh:133
void finishInit()
Finialize the construction of the object.
Definition: newtonmethod.hh:178
void linearizeAuxiliaryEquations_()
Definition: newtonmethod.hh:586
Model & model()
Returns a reference to the numeric model.
Definition: newtonmethod.hh:203
Simulator & simulator_
Definition: newtonmethod.hh:864
void beginIteration_()
Indicates the beginning of a Newton iteration.
Definition: newtonmethod.hh:552
void endIteration_(const SolutionVector &, const SolutionVector &)
Indicates that one Newton iteration was finished.
Definition: newtonmethod.hh:775
void setIterationIndex(int value)
Set the index of current iteration.
Definition: newtonmethod.hh:226
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:41
Provides an encapsulation to measure the system time.
Definition: timer.hh:49
void start()
Start counting the time resources used by the simulation.
Definition: timer.hh:62
void halt()
Stop the measurement reset all timing values.
Definition: timer.hh:99
double realTimeElapsed() const
Return the real time [s] elapsed during the periods the timer was active since the last reset.
Definition: timer.hh:121
double stop()
Stop counting the time resources.
Definition: timer.hh:73
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:141
Definition: blackoilmodel.hh:72
Definition: blackoilboundaryratevector.hh:37
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:242
Specifies the type of the class which writes out the Newton convergence.
Definition: newtonmethodproperties.hh:44
GetPropType< TypeTag, Scalar > type
Definition: newtonmethod.hh:93
Definition: newtonmethodproperties.hh:68
Number of maximum iterations for the Newton method.
Definition: newtonmethodproperties.hh:83
Specifies the type of the actual Newton method.
Definition: newtonmethodproperties.hh:32
The number of iterations at which the Newton method should aim at.
Definition: newtonmethodproperties.hh:79
GetPropType< TypeTag, Scalar > type
Definition: newtonmethod.hh:85
The value for the error below which convergence is declared.
Definition: newtonmethodproperties.hh:63
Specifies whether the Newton method should print messages or not.
Definition: newtonmethodproperties.hh:40
Definition: newtonmethodproperties.hh:49
Definition: newtonmethod.hh:69