26#ifndef DUMUX_NEWTON_SOLVER_HH
27#define DUMUX_NEWTON_SOLVER_HH
34#include <dune/common/timer.hh>
35#include <dune/common/exceptions.hh>
36#include <dune/common/parallel/mpicollectivecommunication.hh>
37#include <dune/common/parallel/mpihelper.hh>
38#include <dune/common/std/type_traits.hh>
39#include <dune/istl/bvector.hh>
40#include <dune/istl/multitypeblockvector.hh>
60 template<
class Assembler>
62 ->
decltype(a.assembleJacobianAndResidual(std::declval<const typename Assembler::ResidualType&>(),
68template<
class Assembler>
69using DetectPVSwitch =
typename Assembler::GridVariables::VolumeVariables::PrimaryVariableSwitch;
71template<
class Assembler>
72using GetPVSwitch = Dune::Std::detected_or<int, DetectPVSwitch, Assembler>;
88 class Comm = Dune::CollectiveCommunication<Dune::MPIHelper::MPICommunicator> >
92 using Scalar =
typename Assembler::Scalar;
93 using JacobianMatrix =
typename Assembler::JacobianMatrix;
94 using SolutionVector =
typename Assembler::ResidualType;
100 static constexpr bool hasPriVarsSwitch() {
return HasPriVarsSwitch::value; };
128 if (enablePartialReassembly_)
129 partialReassembler_ = std::make_unique<Reassembler>(this->
assembler());
131 if (hasPriVarsSwitch())
133 const int priVarSwitchVerbosity = getParamFromGroup<int>(
paramGroup,
"PrimaryVariableSwitch.Verbosity", 1);
134 priVarSwitch_ = std::make_unique<PrimaryVariableSwitch>(priVarSwitchVerbosity);
150 { shiftTolerance_ = tolerance; }
159 { residualTolerance_ = tolerance; }
168 { reductionTolerance_ = tolerance; }
205 [[deprecated(
"Use attachConvergenceWriter(convWriter) and solve(x, *timeLoop) instead")]]
207 std::shared_ptr<ConvergenceWriter> convWriter)
209 if (!convergenceWriter_)
212 solve(uCurrentIter, timeLoop);
221 if (this->
assembler().isStationaryProblem())
222 DUNE_THROW(Dune::InvalidStateException,
"Using time step control with stationary problem makes no sense!");
225 for (std::size_t i = 0; i <= maxTimeStepDivisions_; ++i)
228 const bool converged = solve_(uCurrentIter);
233 else if (!converged && i < maxTimeStepDivisions_)
236 uCurrentIter = this->
assembler().prevSol();
239 this->
assembler().resetTimeStep(uCurrentIter);
242 std::cout <<
"Newton solver did not converge with dt = "
243 << timeLoop.
timeStepSize() <<
" seconds. Retrying with time step of "
244 << timeLoop.
timeStepSize() * retryTimeStepReductionFactor_ <<
" seconds\n";
253 << maxTimeStepDivisions_ <<
" time-step divisions. dt="
263 void solve(SolutionVector& uCurrentIter)
override
265 const bool converged = solve_(uCurrentIter);
283 if (convergenceWriter_)
286 SolutionVector delta(u);
288 convergenceWriter_->write(u, delta, this->
assembler().residual());
298 virtual bool newtonProceed(
const SolutionVector &uCurrentIter,
bool converged)
309 if (enableShiftCriterion_)
341 assembleLinearSystem_(this->
assembler(), uCurrentIter);
343 if (enablePartialReassembly_)
366 Scalar norm2 = b.two_norm2();
367 if (comm_.size() > 1)
368 norm2 = comm_.sum(norm2);
376 bool converged = solveLinearSystem_(deltaU);
379 int convergedRemote = converged;
380 if (comm_.size() > 1)
381 convergedRemote = comm_.min(converged);
385 "Linear solver did not converge");
387 else if (!convergedRemote) {
389 "Linear solver did not converge on a remote process");
392 catch (
const Dune::Exception &e) {
395 if (comm_.size() > 1)
396 converged = comm_.min(converged);
422 const SolutionVector &uLastIter,
423 const SolutionVector &deltaU)
425 if (enableShiftCriterion_ || enablePartialReassembly_)
426 newtonUpdateShift_(uLastIter, deltaU);
428 if (enablePartialReassembly_) {
448 auto reassemblyThreshold = max(reassemblyMinThreshold_,
449 min(reassemblyMaxThreshold_,
450 shift_*reassemblyShiftWeight_));
452 updateDistanceFromLastLinearization_(uLastIter, deltaU);
453 partialReassembler_->computeColors(this->
assembler(),
454 distanceFromLastLinearization_,
455 reassemblyThreshold);
458 for (
unsigned int i = 0; i < distanceFromLastLinearization_.size(); i++)
460 distanceFromLastLinearization_[i] = 0;
464 lineSearchUpdate_(uCurrentIter, uLastIter, deltaU);
467 choppedUpdate_(uCurrentIter, uLastIter, deltaU);
471 uCurrentIter = uLastIter;
472 uCurrentIter -= deltaU;
474 if (enableResidualCriterion_)
482 this->
assembler().updateGridVariables(uCurrentIter);
494 const SolutionVector &uLastIter)
502 if (enableDynamicOutput_)
505 auto width = std::to_string(
maxSteps_).size();
506 std::cout <<
"Newton iteration " << std::setw(width) <<
numSteps_ <<
" done";
508 auto formatFlags = std::cout.flags();
509 auto prec = std::cout.precision();
510 std::cout << std::scientific << std::setprecision(3);
512 if (enableShiftCriterion_)
513 std::cout <<
", maximum relative shift = " <<
shift_;
514 if (enableResidualCriterion_ && enableAbsoluteResidualCriterion_)
516 else if (enableResidualCriterion_)
517 std::cout <<
", residual reduction = " <<
reduction_;
519 std::cout.flags(formatFlags);
520 std::cout.precision(prec);
545 if (priVarsSwitchedInLastIteration_)
548 if (enableShiftCriterion_ && !enableResidualCriterion_)
550 return shift_ <= shiftTolerance_;
552 else if (!enableShiftCriterion_ && enableResidualCriterion_)
554 if(enableAbsoluteResidualCriterion_)
559 else if (satisfyResidualAndShiftCriterion_)
561 if(enableAbsoluteResidualCriterion_)
562 return shift_ <= shiftTolerance_
565 return shift_ <= shiftTolerance_
568 else if(enableShiftCriterion_ && enableResidualCriterion_)
570 if(enableAbsoluteResidualCriterion_)
571 return shift_ <= shiftTolerance_
574 return shift_ <= shiftTolerance_
579 return shift_ <= shiftTolerance_
602 void report(std::ostream& sout = std::cout)
const
605 <<
"Newton statistics\n"
606 <<
"----------------------------------------------\n"
607 <<
"-- Total Newton iterations: " << totalWastedIter_ + totalSucceededIter_ <<
'\n'
608 <<
"-- Total wasted Newton iterations: " << totalWastedIter_ <<
'\n'
609 <<
"-- Total succeeded Newton iterations: " << totalSucceededIter_ <<
'\n'
610 <<
"-- Average iterations per solve: " << std::setprecision(3) << double(totalSucceededIter_) / double(numConverged_) <<
'\n'
619 totalWastedIter_ = 0;
620 totalSucceededIter_ = 0;
629 sout <<
"\nNewton solver configured with the following options and parameters:\n";
631 if (useLineSearch_) sout <<
" -- Newton.UseLineSearch = true\n";
632 if (useChop_) sout <<
" -- Newton.EnableChop = true\n";
633 if (enablePartialReassembly_) sout <<
" -- Newton.EnablePartialReassembly = true\n";
634 if (enableAbsoluteResidualCriterion_) sout <<
" -- Newton.EnableAbsoluteResidualCriterion = true\n";
635 if (enableShiftCriterion_) sout <<
" -- Newton.EnableShiftCriterion = true (relative shift convergence criterion)\n";
636 if (enableResidualCriterion_) sout <<
" -- Newton.EnableResidualCriterion = true\n";
637 if (satisfyResidualAndShiftCriterion_) sout <<
" -- Newton.SatisfyResidualAndShiftCriterion = true\n";
639 if (enableShiftCriterion_) sout <<
" -- Newton.MaxRelativeShift = " << shiftTolerance_ <<
'\n';
640 if (enableAbsoluteResidualCriterion_) sout <<
" -- Newton.MaxAbsoluteResidual = " << residualTolerance_ <<
'\n';
641 if (enableResidualCriterion_) sout <<
" -- Newton.ResidualReduction = " << reductionTolerance_ <<
'\n';
642 sout <<
" -- Newton.MinSteps = " <<
minSteps_ <<
'\n';
643 sout <<
" -- Newton.MaxSteps = " <<
maxSteps_ <<
'\n';
644 sout <<
" -- Newton.TargetSteps = " <<
targetSteps_ <<
'\n';
645 if (enablePartialReassembly_)
647 sout <<
" -- Newton.ReassemblyMinThreshold = " << reassemblyMinThreshold_ <<
'\n';
648 sout <<
" -- Newton.ReassemblyMaxThreshold = " << reassemblyMaxThreshold_ <<
'\n';
649 sout <<
" -- Newton.ReassemblyShiftWeight = " << reassemblyShiftWeight_ <<
'\n';
651 sout <<
" -- Newton.RetryTimeStepReductionFactor = " << retryTimeStepReductionFactor_ <<
'\n';
652 sout <<
" -- Newton.MaxTimeStepDivisions = " << maxTimeStepDivisions_ <<
'\n';
673 return oldTimeStep/(1.0 + percent);
677 return oldTimeStep*(1.0 + percent/1.2);
683 [[deprecated(
"Has been replaced by setVerbosity(int). Will be removed after 3.1 release!")]]
685 { verbosity_ = val; }
690 [[deprecated(
"Has been replaced by int verbosity(). Will be removed after 3.1 release!")]]
692 {
return verbosity_ ; }
698 { verbosity_ = val; }
704 {
return verbosity_ ; }
710 {
return paramGroup_; }
716 { convergenceWriter_ = convWriter; }
722 { convergenceWriter_ =
nullptr; }
734 {
return enableResidualCriterion_; }
746 priVarSwitch_->reset(sol.size());
747 priVarsSwitchedInLastIteration_ =
false;
749 const auto& problem = this->
assembler().problem();
750 const auto& gridGeometry = this->
assembler().gridGeometry();
751 auto& gridVariables = this->
assembler().gridVariables();
752 priVarSwitch_->updateBoundary(problem, gridGeometry, gridVariables, sol);
767 const auto& gridGeometry = this->
assembler().gridGeometry();
768 const auto& problem = this->
assembler().problem();
769 auto& gridVariables = this->
assembler().gridVariables();
772 priVarsSwitchedInLastIteration_ = priVarSwitch_->update(uCurrentIter, gridVariables,
773 problem, gridGeometry);
775 if (priVarsSwitchedInLastIteration_)
777 for (
const auto& element : elements(gridGeometry.gridView()))
780 priVarSwitch_->updateSwitchedVolVars(problem, element, gridGeometry, gridVariables, uCurrentIter);
783 priVarSwitch_->updateSwitchedFluxVarsCache(problem, element, gridGeometry, gridVariables, uCurrentIter);
817 bool solve_(SolutionVector& uCurrentIter)
820 SolutionVector uLastIter(uCurrentIter);
821 SolutionVector deltaU(uCurrentIter);
823 Dune::Timer assembleTimer(
false);
824 Dune::Timer solveTimer(
false);
825 Dune::Timer updateTimer(
false);
827 if (enablePartialReassembly_)
829 partialReassembler_->resetColors();
830 resizeDistanceFromLastLinearization_(uCurrentIter, distanceFromLastLinearization_);
839 bool converged =
false;
848 uLastIter = uCurrentIter;
850 if (verbosity_ >= 1 && enableDynamicOutput_)
851 std::cout <<
"Assemble: r(x^k) = dS/dt + div F - q; M = grad r"
859 assembleTimer.start();
861 assembleTimer.stop();
870 const char clearRemainingLine[] = { 0x1b,
'[',
'K', 0 };
872 if (verbosity_ >= 1 && enableDynamicOutput_)
873 std::cout <<
"\rSolve: M deltax^k = r"
874 << clearRemainingLine << std::flush;
888 if (verbosity_ >= 1 && enableDynamicOutput_)
889 std::cout <<
"\rUpdate: x^(k+1) = x^k - deltax^k"
890 << clearRemainingLine << std::flush;
902 if (convergenceWriter_)
904 this->
assembler().assembleResidual(uCurrentIter);
905 convergenceWriter_->write(uCurrentIter, deltaU, this->
assembler().residual());
929 if (verbosity_ >= 1) {
930 const auto elapsedTot = assembleTimer.elapsed() + solveTimer.elapsed() + updateTimer.elapsed();
931 std::cout <<
"Assemble/solve/update time: "
932 << assembleTimer.elapsed() <<
"(" << 100*assembleTimer.elapsed()/elapsedTot <<
"%)/"
933 << solveTimer.elapsed() <<
"(" << 100*solveTimer.elapsed()/elapsedTot <<
"%)/"
934 << updateTimer.elapsed() <<
"(" << 100*updateTimer.elapsed()/elapsedTot <<
"%)"
943 std::cout <<
"Newton: Caught exception: \"" << e.what() <<
"\"\n";
953 auto assembleLinearSystem_(
const A&
assembler,
const SolutionVector& uCurrentIter)
956 this->
assembler().assembleJacobianAndResidual(uCurrentIter, partialReassembler_.get());
961 auto assembleLinearSystem_(
const A& assembler,
const SolutionVector& uCurrentIter)
962 ->
typename std::enable_if_t<!
decltype(
isValid(Detail::supportsPartialReassembly())(assembler))::value,
void>
964 this->assembler().assembleJacobianAndResidual(uCurrentIter);
974 virtual void newtonUpdateShift_(
const SolutionVector &uLastIter,
975 const SolutionVector &deltaU)
978 newtonUpdateShiftImpl_(uLastIter, deltaU);
980 if (comm_.size() > 1)
981 shift_ = comm_.max(shift_);
984 template<
class SolVec>
985 void newtonUpdateShiftImpl_(
const SolVec &uLastIter,
986 const SolVec &deltaU)
988 for (
int i = 0; i < int(uLastIter.size()); ++i) {
989 typename SolVec::block_type uNewI = uLastIter[i];
992 Scalar shiftAtDof = relativeShiftAtDof_(uLastIter[i], uNewI);
994 shift_ = max(shift_, shiftAtDof);
998 template<
class ...Args>
999 void newtonUpdateShiftImpl_(
const Dune::MultiTypeBlockVector<Args...> &uLastIter,
1000 const Dune::MultiTypeBlockVector<Args...> &deltaU)
1005 auto doUpdate = [&](
const auto subVectorIdx)
1007 this->newtonUpdateShiftImpl_(uLastIter[subVectorIdx], deltaU[subVectorIdx]);
1010 using namespace Dune::Hybrid;
1011 forEach(integralRange(Dune::Hybrid::size(uLastIter)), doUpdate);
1014 virtual void lineSearchUpdate_(SolutionVector &uCurrentIter,
1015 const SolutionVector &uLastIter,
1016 const SolutionVector &deltaU)
1018 Scalar lambda = 1.0;
1019 SolutionVector tmp(uLastIter);
1023 uCurrentIter = deltaU;
1024 uCurrentIter *= -lambda;
1025 uCurrentIter += uLastIter;
1027 computeResidualReduction_(uCurrentIter);
1029 if (reduction_ < lastReduction_ || lambda <= 0.125) {
1030 endIterMsgStream_ <<
", residual reduction " << lastReduction_ <<
"->" << reduction_ <<
"@lambda=" << lambda;
1040 virtual void choppedUpdate_(SolutionVector &uCurrentIter,
1041 const SolutionVector &uLastIter,
1042 const SolutionVector &deltaU)
1044 DUNE_THROW(Dune::NotImplemented,
1045 "Chopped Newton update strategy not implemented.");
1048 virtual bool solveLinearSystem_(SolutionVector& deltaU)
1050 return solveLinearSystemImpl_(this->linearSolver(),
1051 this->assembler().jacobian(),
1053 this->assembler().residual());
1065 template<
class V = SolutionVector>
1066 typename std::enable_if_t<!isMultiTypeBlockVector<V>(),
bool>
1067 solveLinearSystemImpl_(LinearSolver& ls,
1078 constexpr auto blockSize = JacobianMatrix::block_type::rows;
1079 using BlockType = Dune::FieldVector<Scalar, blockSize>;
1080 Dune::BlockVector<BlockType> xTmp; xTmp.resize(b.size());
1081 Dune::BlockVector<BlockType> bTmp(xTmp);
1082 for (
unsigned int i = 0; i < b.size(); ++i)
1083 for (
unsigned int j = 0; j < blockSize; ++j)
1084 bTmp[i][j] = b[i][j];
1086 const int converged = ls.solve(A, xTmp, bTmp);
1088 for (
unsigned int i = 0; i < x.size(); ++i)
1089 for (
unsigned int j = 0; j < blockSize; ++j)
1090 x[i][j] = xTmp[i][j];
1106 template<
class LS = LinearSolver,
class V = SolutionVector>
1107 typename std::enable_if_t<linearSolverAcceptsMultiTypeMatrix<LS>() &&
1108 isMultiTypeBlockVector<V>(),
bool>
1109 solveLinearSystemImpl_(LinearSolver& ls,
1115 assert(checkMatrix_(A) &&
"Sub blocks of MultiType matrix have wrong sizes!");
1118 return ls.template solve<2>(A, x, b);
1131 template<
class LS = LinearSolver,
class V = SolutionVector>
1132 typename std::enable_if_t<!linearSolverAcceptsMultiTypeMatrix<LS>() &&
1133 isMultiTypeBlockVector<V>(),
bool>
1134 solveLinearSystemImpl_(LinearSolver& ls,
1140 assert(checkMatrix_(A) &&
"Sub blocks of MultiType matrix have wrong sizes!");
1146 const std::size_t numRows = M.N();
1147 assert(numRows == M.M());
1151 assert(bTmp.size() == numRows);
1154 using VectorBlock =
typename Dune::FieldVector<Scalar, 1>;
1155 using BlockVector =
typename Dune::BlockVector<VectorBlock>;
1156 BlockVector y(numRows);
1159 const bool converged = ls.solve(M, y, bTmp);
1169 template<
class M = JacobianMatrix>
1170 typename std::enable_if_t<!isBCRSMatrix<M>(),
bool>
1171 checkMatrix_(
const JacobianMatrix& A)
1173 bool matrixHasCorrectSize =
true;
1174 using namespace Dune::Hybrid;
1176 forEach(A, [&matrixHasCorrectSize](
const auto& rowOfMultiTypeMatrix)
1178 const auto numRowsLeftMostBlock = rowOfMultiTypeMatrix[_0].N();
1180 forEach(rowOfMultiTypeMatrix, [&matrixHasCorrectSize, &numRowsLeftMostBlock](
const auto& subBlock)
1182 if (subBlock.N() != numRowsLeftMostBlock)
1183 matrixHasCorrectSize =
false;
1186 return matrixHasCorrectSize;
1190 void initParams_(
const std::string& group =
"")
1192 useLineSearch_ = getParamFromGroup<bool>(group,
"Newton.UseLineSearch");
1193 useChop_ = getParamFromGroup<bool>(group,
"Newton.EnableChop");
1194 if(useLineSearch_ && useChop_)
1195 DUNE_THROW(Dune::InvalidStateException,
"Use either linesearch OR chop!");
1197 enableAbsoluteResidualCriterion_ = getParamFromGroup<bool>(group,
"Newton.EnableAbsoluteResidualCriterion");
1198 enableShiftCriterion_ = getParamFromGroup<bool>(group,
"Newton.EnableShiftCriterion");
1199 enableResidualCriterion_ = getParamFromGroup<bool>(group,
"Newton.EnableResidualCriterion") || enableAbsoluteResidualCriterion_;
1200 satisfyResidualAndShiftCriterion_ = getParamFromGroup<bool>(group,
"Newton.SatisfyResidualAndShiftCriterion");
1201 enableDynamicOutput_ = getParamFromGroup<bool>(group,
"Newton.EnableDynamicOutput",
true);
1203 if (!enableShiftCriterion_ && !enableResidualCriterion_)
1205 DUNE_THROW(Dune::NotImplemented,
1206 "at least one of NewtonEnableShiftCriterion or "
1207 <<
"NewtonEnableResidualCriterion has to be set to true");
1210 setMaxRelativeShift(getParamFromGroup<Scalar>(group,
"Newton.MaxRelativeShift"));
1211 setMaxAbsoluteResidual(getParamFromGroup<Scalar>(group,
"Newton.MaxAbsoluteResidual"));
1212 setResidualReduction(getParamFromGroup<Scalar>(group,
"Newton.ResidualReduction"));
1213 setTargetSteps(getParamFromGroup<int>(group,
"Newton.TargetSteps"));
1214 setMinSteps(getParamFromGroup<int>(group,
"Newton.MinSteps"));
1215 setMaxSteps(getParamFromGroup<int>(group,
"Newton.MaxSteps"));
1217 enablePartialReassembly_ = getParamFromGroup<bool>(group,
"Newton.EnablePartialReassembly");
1218 reassemblyMinThreshold_ = getParamFromGroup<Scalar>(group,
"Newton.ReassemblyMinThreshold", 1e-1*shiftTolerance_);
1219 reassemblyMaxThreshold_ = getParamFromGroup<Scalar>(group,
"Newton.ReassemblyMaxThreshold", 1e2*shiftTolerance_);
1220 reassemblyShiftWeight_ = getParamFromGroup<Scalar>(group,
"Newton.ReassemblyShiftWeight", 1e-3);
1222 maxTimeStepDivisions_ = getParamFromGroup<std::size_t>(group,
"Newton.MaxTimeStepDivisions", 10);
1223 retryTimeStepReductionFactor_ = getParamFromGroup<Scalar>(group,
"Newton.RetryTimeStepReductionFactor", 0.5);
1225 verbosity_ = comm_.rank() == 0 ? getParamFromGroup<int>(group,
"Newton.Verbosity", 2) : 0;
1229 if (verbosity_ >= 2)
1234 void updateDistanceFromLastLinearization_(
const Sol& u,
const Sol& uDelta)
1236 for (
size_t i = 0; i < u.size(); ++i) {
1237 const auto& currentPriVars(u[i]);
1238 auto nextPriVars(currentPriVars);
1239 nextPriVars -= uDelta[i];
1242 auto shift = relativeShiftAtDof_(currentPriVars, nextPriVars);
1243 distanceFromLastLinearization_[i] += shift;
1247 template<
class ...Args>
1248 void updateDistanceFromLastLinearization_(
const Dune::MultiTypeBlockVector<Args...>& uLastIter,
1249 const Dune::MultiTypeBlockVector<Args...>& deltaU)
1251 DUNE_THROW(Dune::NotImplemented,
"Reassembly for MultiTypeBlockVector");
1255 void resizeDistanceFromLastLinearization_(
const Sol& u, std::vector<Scalar>& dist)
1257 dist.assign(u.size(), 0.0);
1260 template<
class ...Args>
1261 void resizeDistanceFromLastLinearization_(
const Dune::MultiTypeBlockVector<Args...>& u,
1262 std::vector<Scalar>& dist)
1264 DUNE_THROW(Dune::NotImplemented,
"Reassembly for MultiTypeBlockVector");
1274 template<
class PrimaryVariables>
1275 Scalar relativeShiftAtDof_(
const PrimaryVariables &priVars1,
1276 const PrimaryVariables &priVars2)
const
1278 Scalar result = 0.0;
1282 for (
int j = 0; j < PrimaryVariables::dimension; ++j) {
1283 Scalar eqErr = abs(priVars1[j] - priVars2[j]);
1284 eqErr /= max<Scalar>(1.0,abs(priVars1[j] + priVars2[j])/2);
1286 result = max(result, eqErr);
1292 Communication comm_;
1297 Scalar shiftTolerance_;
1298 Scalar reductionTolerance_;
1299 Scalar residualTolerance_;
1302 std::size_t maxTimeStepDivisions_;
1303 Scalar retryTimeStepReductionFactor_;
1306 bool useLineSearch_;
1308 bool enableAbsoluteResidualCriterion_;
1309 bool enableShiftCriterion_;
1310 bool enableResidualCriterion_;
1311 bool satisfyResidualAndShiftCriterion_;
1312 bool enableDynamicOutput_;
1315 std::string paramGroup_;
1318 bool enablePartialReassembly_;
1319 std::unique_ptr<Reassembler> partialReassembler_;
1320 std::vector<Scalar> distanceFromLastLinearization_;
1321 Scalar reassemblyMinThreshold_;
1322 Scalar reassemblyMaxThreshold_;
1323 Scalar reassemblyShiftWeight_;
1326 std::size_t totalWastedIter_ = 0;
1327 std::size_t totalSucceededIter_ = 0;
1328 std::size_t numConverged_ = 0;
1331 std::unique_ptr<PrimaryVariableSwitch> priVarSwitch_;
1333 bool priVarsSwitchedInLastIteration_ =
false;
1336 std::shared_ptr<ConvergenceWriter> convergenceWriter_ =
nullptr;
Detects which entries in the Jacobian have to be recomputed.
A helper function for class member function introspection.
Type traits to be used with vector types.
Some exceptions thrown in DuMux
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.
Manages the handling of time dependent problems.
Trait checking if linear solvers accept Dune::MultiTypeBlockMatrix or we need to convert the matrix.
A helper classe that converts a Dune::MultiTypeBlockMatrix into a plain Dune::BCRSMatrix.
This class provides the infrastructure to write the convergence behaviour of the newton method into a...
@ red
distance from last linearization is above the tolerance
make the local view function available whenever we use the grid geometry
Definition: adapt.hh:29
constexpr auto isValid(const Expression &t)
A function that creates a test functor to do class member introspection at compile time.
Definition: isvalid.hh:93
Property tag Indices
Definition: porousmediumflow/sequential/properties.hh:59
Dune::Std::detected_or< int, DetectPVSwitch, Assembler > GetPVSwitch
Definition: nonlinear/newtonsolver.hh:72
typename Assembler::GridVariables::VolumeVariables::PrimaryVariableSwitch DetectPVSwitch
helper aliases to extract a primary variable switch from the VolumeVariables (if defined,...
Definition: nonlinear/newtonsolver.hh:69
detects which entries in the Jacobian have to be recomputed
Definition: partialreassembler.hh:424
Exception thrown if a fixable numerical problem occurs.
Definition: exceptions.hh:39
A high-level interface for a PDESolver.
Definition: common/pdesolver.hh:46
const Assembler & assembler() const
Access the assembler.
Definition: common/pdesolver.hh:83
const LinearSolver & linearSolver() const
Access the linear solver.
Definition: common/pdesolver.hh:95
Manages the handling of time dependent problems.
Definition: timeloop.hh:65
virtual void setTimeStepSize(Scalar dt)=0
Set the current time step size to a given value.
virtual Scalar timeStepSize() const =0
Returns the suggested time step length .
static auto multiTypeToBCRSMatrix(const MultiTypeBlockMatrix &A)
Converts the matrix to a type the IterativeSolverBackend can handle.
Definition: matrixconverter.hh:59
static void retrieveValues(MultiTypeBlockVector &x, const BlockVector &y)
Copys the entries of a Dune::BlockVector to a Dune::MultiTypeBlockVector.
Definition: matrixconverter.hh:242
static auto multiTypeToBlockVector(const MultiTypeBlockVector &b)
Converts a Dune::MultiTypeBlockVector to a plain 1x1 Dune::BlockVector.
Definition: matrixconverter.hh:214
Base class for linear solvers.
Definition: dumux/linear/solver.hh:37
void setResidualReduction(double r)
set the linear solver residual reduction
Definition: dumux/linear/solver.hh:101
Definition: newtonconvergencewriter.hh:39
helper struct detecting if an assembler supports partial reassembly
Definition: nonlinear/newtonsolver.hh:59
auto operator()(Assembler &&a) -> decltype(a.assembleJacobianAndResidual(std::declval< const typename Assembler::ResidualType & >(), std::declval< const PartialReassembler< Assembler > * >()))
Definition: nonlinear/newtonsolver.hh:61
An implementation of a Newton solver.
Definition: nonlinear/newtonsolver.hh:90
void solve(SolutionVector &uCurrentIter) override
Run the Newton method to solve a non-linear system. The solver is responsible for all the strategic d...
Definition: nonlinear/newtonsolver.hh:263
Comm Communication
Definition: nonlinear/newtonsolver.hh:104
int maxSteps_
maximum number of iterations we do before giving up
Definition: nonlinear/newtonsolver.hh:793
void setMaxSteps(int maxSteps)
Set the number of iterations after which the Newton method gives up.
Definition: nonlinear/newtonsolver.hh:198
void setResidualReduction(Scalar tolerance)
Set the maximum acceptable residual norm reduction.
Definition: nonlinear/newtonsolver.hh:167
void invokePriVarSwitch_(SolutionVector &, std::false_type)
Switch primary variables if necessary, noop if there is no priVarSwitch.
Definition: nonlinear/newtonsolver.hh:758
void newtonUpdate(SolutionVector &uCurrentIter, const SolutionVector &uLastIter, const SolutionVector &deltaU)
Update the current solution with a delta vector.
Definition: nonlinear/newtonsolver.hh:421
void reportParams(std::ostream &sout=std::cout) const
Report the options and parameters this Newton is configured with.
Definition: nonlinear/newtonsolver.hh:627
void initPriVarSwitch_(SolutionVector &, std::false_type)
Initialize the privar switch, noop if there is no priVarSwitch.
Definition: nonlinear/newtonsolver.hh:739
int targetSteps_
optimal number of iterations we want to achieve
Definition: nonlinear/newtonsolver.hh:789
const std::string & paramGroup() const
Returns the parameter group.
Definition: nonlinear/newtonsolver.hh:709
Scalar reduction_
Definition: nonlinear/newtonsolver.hh:798
int numSteps_
actual number of steps done so far
Definition: nonlinear/newtonsolver.hh:795
int verbosity() const
Return the verbosity level.
Definition: nonlinear/newtonsolver.hh:703
void setMinSteps(int minSteps)
Set the number of minimum iterations for the Newton method.
Definition: nonlinear/newtonsolver.hh:189
void solve(SolutionVector &uCurrentIter, TimeLoop &timeLoop, std::shared_ptr< ConvergenceWriter > convWriter)
Run the Newton method to solve a non-linear system. Does time step control when the Newton fails to c...
Definition: nonlinear/newtonsolver.hh:206
int minSteps_
minimum number of iterations we do
Definition: nonlinear/newtonsolver.hh:791
bool enableResidualCriterion() const
Definition: nonlinear/newtonsolver.hh:733
bool verbose() const
Returns true if the Newton method ought to be chatty.
Definition: nonlinear/newtonsolver.hh:691
void report(std::ostream &sout=std::cout) const
output statistics / report
Definition: nonlinear/newtonsolver.hh:602
virtual void newtonBeginStep(const SolutionVector &u)
Indicates the beginning of a Newton iteration.
Definition: nonlinear/newtonsolver.hh:321
virtual void newtonEndStep(SolutionVector &uCurrentIter, const SolutionVector &uLastIter)
Indicates that one Newton iteration was finished.
Definition: nonlinear/newtonsolver.hh:493
void initPriVarSwitch_(SolutionVector &sol, std::true_type)
Initialize the privar switch.
Definition: nonlinear/newtonsolver.hh:744
NewtonSolver(std::shared_ptr< Assembler > assembler, std::shared_ptr< LinearSolver > linearSolver, const Communication &comm=Dune::MPIHelper::getCollectiveCommunication(), const std::string ¶mGroup="")
The Constructor.
Definition: nonlinear/newtonsolver.hh:109
virtual void newtonSucceed()
Called if the Newton method ended successfully This method is called after newtonEnd()
Definition: nonlinear/newtonsolver.hh:597
void attachConvergenceWriter(std::shared_ptr< ConvergenceWriter > convWriter)
Attach a convergence writer to write out intermediate results after each iteration.
Definition: nonlinear/newtonsolver.hh:715
Scalar initialResidual_
Definition: nonlinear/newtonsolver.hh:801
Scalar lastReduction_
Definition: nonlinear/newtonsolver.hh:800
std::ostringstream endIterMsgStream_
message stream to be displayed at the end of iterations
Definition: nonlinear/newtonsolver.hh:808
void setVerbose(bool val)
Specifies if the Newton method ought to be chatty.
Definition: nonlinear/newtonsolver.hh:684
void setVerbosity(int val)
Specifies the verbosity level.
Definition: nonlinear/newtonsolver.hh:697
void invokePriVarSwitch_(SolutionVector &uCurrentIter, std::true_type)
Switch primary variables if necessary.
Definition: nonlinear/newtonsolver.hh:763
virtual void assembleLinearSystem(const SolutionVector &uCurrentIter)
Assemble the linear system of equations .
Definition: nonlinear/newtonsolver.hh:339
const Communication & comm() const
the communicator for parallel runs
Definition: nonlinear/newtonsolver.hh:139
void resetReport()
reset the statistics
Definition: nonlinear/newtonsolver.hh:617
virtual void newtonFail(SolutionVector &u)
Called if the Newton method broke down. This method is called after newtonEnd()
Definition: nonlinear/newtonsolver.hh:591
void setMaxAbsoluteResidual(Scalar tolerance)
Set the maximum acceptable absolute residual for declaring convergence.
Definition: nonlinear/newtonsolver.hh:158
virtual void newtonEnd()
Called if the Newton method ended (not known yet if we failed or succeeded)
Definition: nonlinear/newtonsolver.hh:535
void solve(SolutionVector &uCurrentIter, TimeLoop &timeLoop) override
Run the Newton method to solve a non-linear system. Does time step control when the Newton fails to c...
Definition: nonlinear/newtonsolver.hh:219
void setTargetSteps(int targetSteps)
Set the number of iterations at which the Newton method should aim at.
Definition: nonlinear/newtonsolver.hh:180
virtual void newtonBegin(SolutionVector &u)
Called before the Newton method is applied to an non-linear system of equations.
Definition: nonlinear/newtonsolver.hh:277
virtual bool newtonConverged() const
Returns true if the error of the solution is below the tolerance.
Definition: nonlinear/newtonsolver.hh:541
Scalar suggestTimeStepSize(Scalar oldTimeStep) const
Suggest a new time-step size based on the old time-step size.
Definition: nonlinear/newtonsolver.hh:664
void solveLinearSystem(SolutionVector &deltaU)
Solve the linear system of equations .
Definition: nonlinear/newtonsolver.hh:358
void computeResidualReduction_(const SolutionVector &uCurrentIter)
Definition: nonlinear/newtonsolver.hh:726
void detachConvergenceWriter()
Detach the convergence writer to stop the output.
Definition: nonlinear/newtonsolver.hh:721
void setMaxRelativeShift(Scalar tolerance)
Set the maximum acceptable difference of any primary variable between two iterations for declaring co...
Definition: nonlinear/newtonsolver.hh:149
Scalar shift_
Definition: nonlinear/newtonsolver.hh:804
virtual bool newtonProceed(const SolutionVector &uCurrentIter, bool converged)
Returns true if another iteration should be done.
Definition: nonlinear/newtonsolver.hh:298
Scalar residualNorm_
Definition: nonlinear/newtonsolver.hh:799
Scalar lastShift_
Definition: nonlinear/newtonsolver.hh:805
Defines a high-level interface for a PDESolver.