24#ifndef DUMUX_NEWTON_SOLVER_HH
25#define DUMUX_NEWTON_SOLVER_HH
34#include <dune/common/timer.hh>
35#include <dune/common/exceptions.hh>
36#include <dune/common/parallel/mpicommunication.hh>
37#include <dune/common/parallel/mpihelper.hh>
38#include <dune/common/std/type_traits.hh>
39#include <dune/common/indices.hh>
40#include <dune/common/hybridutilities.hh>
42#include <dune/istl/bvector.hh>
43#include <dune/istl/multitypeblockvector.hh>
66template<
class Assembler>
68 = Dune::Std::is_detected_v<AssemblerGridVariablesType, Assembler>;
71template<
class Assembler,
bool exportsGr
idVars = assemblerExportsGr
idVariables<Assembler>>
76template<
class Assembler>
78{
using Type =
struct EmptyGridVariables {}; };
81template<
class Assembler>
88 template<
class Assembler>
90 ->
decltype(a.assembleJacobianAndResidual(std::declval<const typename Assembler::ResidualType&>(),
96template <
class LinearSolver,
class Res
idual>
97using NormDetector =
decltype(std::declval<LinearSolver>().norm(std::declval<Residual>()));
99template<
class LinearSolver,
class Res
idual>
101{
return Dune::Std::is_detected<NormDetector, LinearSolver, Residual>::value; }
109template<
class V,
class Scalar,
class Reduce,
class Transform>
111-> std::enable_if_t<hasDynamicIndexAccess<V>(), Scalar>
113 return std::inner_product(v1.begin(), v1.end(), v2.begin(), init, std::forward<Reduce>(r), std::forward<Transform>(t));
116template<
class V,
class Scalar,
class Reduce,
class Transform>
117auto hybridInnerProduct(
const V& v1,
const V& v2, Scalar init, Reduce&& r, Transform&& t)
118-> std::enable_if_t<hasStaticIndexAccess<V>() && !hasDynamicIndexAccess<V>(), Scalar>
120 using namespace Dune::Hybrid;
121 forEach(std::make_index_sequence<V::N()>{}, [&](
auto i){
122 init = r(init,
hybridInnerProduct(v1[Dune::index_constant<i>{}], v2[Dune::index_constant<i>{}], init, std::forward<Reduce>(r), std::forward<Transform>(t)));
130template<
class Scalar,
class V>
132-> std::enable_if_t<Dune::IsNumber<V>::value, Scalar>
134 using std::abs;
using std::max;
135 return abs(v1 - v2)/max<Scalar>(1.0, abs(v1 + v2)*0.5);
140template<
class Scalar,
class V>
142-> std::enable_if_t<!Dune::IsNumber<V>::value, Scalar>
145 [](
const auto& a,
const auto& b){
using std::max;
return max(a, b); },
146 [](
const auto& a,
const auto& b){
return maxRelativeShift<Scalar>(a, b); }
150template<
class To,
class From>
153 if constexpr (std::is_assignable<To&, From>::value)
156 else if constexpr (hasStaticIndexAccess<To>() && hasStaticIndexAccess<To>() && !hasDynamicIndexAccess<From>() && !hasDynamicIndexAccess<From>())
158 using namespace Dune::Hybrid;
159 forEach(std::make_index_sequence<To::N()>{}, [&](
auto i){
160 assign(to[Dune::index_constant<i>{}], from[Dune::index_constant<i>{}]);
164 else if constexpr (hasDynamicIndexAccess<To>() && hasDynamicIndexAccess<From>())
165 for (
decltype(to.size()) i = 0; i < to.size(); ++i)
168 else if constexpr (hasDynamicIndexAccess<To>() && Dune::IsNumber<From>::value)
170 assert(to.size() == 1);
174 else if constexpr (Dune::IsNumber<To>::value && hasDynamicIndexAccess<From>())
176 assert(from.size() == 1);
181 DUNE_THROW(Dune::Exception,
"Values are not assignable to each other!");
184template<
class T, std::enable_if_t<Dune::IsNumber<std::decay_t<T>>::value,
int> = 0>
187template<
class T, std::enable_if_t<!Dune::IsNumber<std::decay_t<T>>::value,
int> = 0>
188constexpr std::size_t
blockSize() {
return std::decay_t<T>::size(); }
190template<
class S,
bool isScalar = false>
192{
using type = std::decay_t<decltype(std::declval<S>()[0])>; };
197template<
class SolutionVector>
214 class Comm = Dune::Communication<Dune::MPIHelper::MPICommunicator> >
224 using Scalar =
typename Assembler::Scalar;
225 using JacobianMatrix =
typename Assembler::JacobianMatrix;
231 static constexpr bool assemblerExportsVariables = Detail::exportsVariables<Assembler>;
232 using PriVarSwitchVariables
233 = std::conditional_t<assemblerExportsVariables,
262 this->
linearSolver().setResidualReduction(getParamFromGroup<Scalar>(
paramGroup,
"LinearSolver.ResidualReduction", 1e-6));
265 if (enablePartialReassembly_)
266 partialReassembler_ = std::make_unique<Reassembler>(this->
assembler());
281 { shiftTolerance_ = tolerance; }
290 { residualTolerance_ = tolerance; }
299 { reductionTolerance_ = tolerance; }
341 if constexpr (!assemblerExportsVariables)
343 if (this->
assembler().isStationaryProblem())
344 DUNE_THROW(Dune::InvalidStateException,
"Using time step control with stationary problem makes no sense!");
348 for (std::size_t i = 0; i <= maxTimeStepDivisions_; ++i)
351 const bool converged = solve_(vars);
356 else if (!converged && i < maxTimeStepDivisions_)
358 if constexpr (assemblerExportsVariables)
359 DUNE_THROW(Dune::NotImplemented,
"Time step reset for new assembly methods");
363 Backend::update(vars, this->
assembler().prevSol());
364 this->
assembler().resetTimeStep(Backend::dofs(vars));
369 std::cout << Fmt::format(
"Newton solver did not converge with dt = {} seconds. ", dt)
370 << Fmt::format(
"Retrying with time step of dt = {} seconds.\n", dt*retryTimeStepReductionFactor_);
381 Fmt::format(
"Newton solver didn't converge after {} time-step divisions; dt = {}.\n",
395 const bool converged = solve_(vars);
398 Fmt::format(
"Newton solver didn't converge after {} iterations.\n",
numSteps_));
411 if constexpr (hasPriVarsSwitch<PriVarSwitchVariables>)
413 if constexpr (assemblerExportsVariables)
414 priVarSwitchAdapter_->initialize(Backend::dofs(initVars), initVars);
416 priVarSwitchAdapter_->initialize(initVars, this->
assembler().gridVariables());
419 const auto& initSol = Backend::dofs(initVars);
422 if (convergenceWriter_)
424 this->
assembler().assembleResidual(initVars);
427 auto delta = Backend::zeros(Backend::size(initSol));
428 convergenceWriter_->write(initSol, delta, this->
assembler().residual());
431 if (enablePartialReassembly_)
433 partialReassembler_->resetColors();
434 resizeDistanceFromLastLinearization_(initSol, distanceFromLastLinearization_);
455 if (enableShiftCriterion_)
487 assembleLinearSystem_(this->
assembler(), vars);
489 if (enablePartialReassembly_)
512 if constexpr (Detail::hasNorm<LinearSolver, SolutionVector>())
517 Scalar norm2 = b.two_norm2();
518 if (comm_.size() > 1)
519 norm2 = comm_.sum(norm2);
528 bool converged = solveLinearSystem_(deltaU);
531 int convergedRemote = converged;
532 if (comm_.size() > 1)
533 convergedRemote = comm_.min(converged);
537 ++numLinearSolverBreakdowns_;
539 else if (!convergedRemote) {
540 DUNE_THROW(
NumericalProblem,
"Linear solver did not converge on a remote process");
541 ++numLinearSolverBreakdowns_;
544 catch (
const Dune::Exception &e) {
547 if (comm_.size() > 1)
548 converged = comm_.min(converged);
577 if (enableShiftCriterion_ || enablePartialReassembly_)
578 newtonUpdateShift_(uLastIter, deltaU);
580 if (enablePartialReassembly_) {
600 auto reassemblyThreshold = max(reassemblyMinThreshold_,
601 min(reassemblyMaxThreshold_,
602 shift_*reassemblyShiftWeight_));
604 updateDistanceFromLastLinearization_(uLastIter, deltaU);
605 partialReassembler_->computeColors(this->
assembler(),
606 distanceFromLastLinearization_,
607 reassemblyThreshold);
610 for (
unsigned int i = 0; i < distanceFromLastLinearization_.size(); i++)
612 distanceFromLastLinearization_[i] = 0;
616 lineSearchUpdate_(vars, uLastIter, deltaU);
619 choppedUpdate_(vars, uLastIter, deltaU);
623 auto uCurrentIter = uLastIter;
624 uCurrentIter -= deltaU;
627 if (enableResidualCriterion_)
641 if constexpr (hasPriVarsSwitch<PriVarSwitchVariables>)
643 if constexpr (assemblerExportsVariables)
644 priVarSwitchAdapter_->invoke(Backend::dofs(vars), vars);
646 priVarSwitchAdapter_->invoke(vars, this->
assembler().gridVariables());
653 if (enableDynamicOutput_)
656 const auto width = Fmt::formatted_size(
"{}",
maxSteps_);
657 std::cout << Fmt::format(
"Newton iteration {:{}} done",
numSteps_, width);
659 if (enableShiftCriterion_)
660 std::cout << Fmt::format(
", maximum relative shift = {:.4e}",
shift_);
661 if (enableResidualCriterion_ && enableAbsoluteResidualCriterion_)
662 std::cout << Fmt::format(
", residual = {:.4e}",
residualNorm_);
663 else if (enableResidualCriterion_)
664 std::cout << Fmt::format(
", residual reduction = {:.4e}",
reduction_);
689 if (priVarSwitchAdapter_->switched())
692 if (enableShiftCriterion_ && !enableResidualCriterion_)
694 return shift_ <= shiftTolerance_;
696 else if (!enableShiftCriterion_ && enableResidualCriterion_)
698 if(enableAbsoluteResidualCriterion_)
703 else if (satisfyResidualAndShiftCriterion_)
705 if(enableAbsoluteResidualCriterion_)
706 return shift_ <= shiftTolerance_
709 return shift_ <= shiftTolerance_
712 else if(enableShiftCriterion_ && enableResidualCriterion_)
714 if(enableAbsoluteResidualCriterion_)
715 return shift_ <= shiftTolerance_
718 return shift_ <= shiftTolerance_
723 return shift_ <= shiftTolerance_
746 void report(std::ostream& sout = std::cout)
const
749 <<
"Newton statistics\n"
750 <<
"----------------------------------------------\n"
751 <<
"-- Total Newton iterations: " << totalWastedIter_ + totalSucceededIter_ <<
'\n'
752 <<
"-- Total wasted Newton iterations: " << totalWastedIter_ <<
'\n'
753 <<
"-- Total succeeded Newton iterations: " << totalSucceededIter_ <<
'\n'
754 <<
"-- Average iterations per solve: " << std::setprecision(3) << double(totalSucceededIter_) / double(numConverged_) <<
'\n'
755 <<
"-- Number of linear solver breakdowns: " << numLinearSolverBreakdowns_ <<
'\n'
764 totalWastedIter_ = 0;
765 totalSucceededIter_ = 0;
767 numLinearSolverBreakdowns_ = 0;
775 sout <<
"\nNewton solver configured with the following options and parameters:\n";
777 if (useLineSearch_) sout <<
" -- Newton.UseLineSearch = true\n";
778 if (useChop_) sout <<
" -- Newton.EnableChop = true\n";
779 if (enablePartialReassembly_) sout <<
" -- Newton.EnablePartialReassembly = true\n";
780 if (enableAbsoluteResidualCriterion_) sout <<
" -- Newton.EnableAbsoluteResidualCriterion = true\n";
781 if (enableShiftCriterion_) sout <<
" -- Newton.EnableShiftCriterion = true (relative shift convergence criterion)\n";
782 if (enableResidualCriterion_) sout <<
" -- Newton.EnableResidualCriterion = true\n";
783 if (satisfyResidualAndShiftCriterion_) sout <<
" -- Newton.SatisfyResidualAndShiftCriterion = true\n";
785 if (enableShiftCriterion_) sout <<
" -- Newton.MaxRelativeShift = " << shiftTolerance_ <<
'\n';
786 if (enableAbsoluteResidualCriterion_) sout <<
" -- Newton.MaxAbsoluteResidual = " << residualTolerance_ <<
'\n';
787 if (enableResidualCriterion_) sout <<
" -- Newton.ResidualReduction = " << reductionTolerance_ <<
'\n';
788 sout <<
" -- Newton.MinSteps = " <<
minSteps_ <<
'\n';
789 sout <<
" -- Newton.MaxSteps = " <<
maxSteps_ <<
'\n';
790 sout <<
" -- Newton.TargetSteps = " <<
targetSteps_ <<
'\n';
791 if (enablePartialReassembly_)
793 sout <<
" -- Newton.ReassemblyMinThreshold = " << reassemblyMinThreshold_ <<
'\n';
794 sout <<
" -- Newton.ReassemblyMaxThreshold = " << reassemblyMaxThreshold_ <<
'\n';
795 sout <<
" -- Newton.ReassemblyShiftWeight = " << reassemblyShiftWeight_ <<
'\n';
797 sout <<
" -- Newton.RetryTimeStepReductionFactor = " << retryTimeStepReductionFactor_ <<
'\n';
798 sout <<
" -- Newton.MaxTimeStepDivisions = " << maxTimeStepDivisions_ <<
'\n';
819 return oldTimeStep/(1.0 + percent);
823 return oldTimeStep*(1.0 + percent/1.2);
830 { verbosity_ = val; }
836 {
return verbosity_ ; }
842 {
return paramGroup_; }
848 { convergenceWriter_ = convWriter; }
854 { convergenceWriter_ =
nullptr; }
860 {
return retryTimeStepReductionFactor_; }
866 { retryTimeStepReductionFactor_ = factor; }
877 Backend::update(vars, uCurrentIter);
879 if constexpr (!assemblerExportsVariables)
880 this->
assembler().updateGridVariables(Backend::dofs(vars));
887 if constexpr (Detail::hasNorm<LinearSolver, SolutionVector>())
889 if constexpr (!assemblerExportsVariables)
890 this->
assembler().assembleResidual(Backend::dofs(vars));
892 this->
assembler().assembleResidual(vars);
897 if constexpr (!assemblerExportsVariables)
908 {
return enableResidualCriterion_; }
947 auto uLastIter = Backend::dofs(vars);
948 auto deltaU = Backend::dofs(vars);
951 Dune::Timer assembleTimer(
false);
952 Dune::Timer solveTimer(
false);
953 Dune::Timer updateTimer(
false);
957 bool converged =
false;
966 uLastIter = Backend::dofs(vars);
968 if (verbosity_ >= 1 && enableDynamicOutput_)
969 std::cout <<
"Assemble: r(x^k) = dS/dt + div F - q; M = grad r"
977 assembleTimer.start();
979 assembleTimer.stop();
988 const char clearRemainingLine[] = { 0x1b,
'[',
'K', 0 };
990 if (verbosity_ >= 1 && enableDynamicOutput_)
991 std::cout <<
"\rSolve: M deltax^k = r"
992 << clearRemainingLine << std::flush;
1006 if (verbosity_ >= 1 && enableDynamicOutput_)
1007 std::cout <<
"\rUpdate: x^(k+1) = x^k - deltax^k"
1008 << clearRemainingLine << std::flush;
1010 updateTimer.start();
1020 if (convergenceWriter_)
1022 this->
assembler().assembleResidual(vars);
1023 convergenceWriter_->write(Backend::dofs(vars), deltaU, this->
assembler().residual());
1047 if (verbosity_ >= 1) {
1048 const auto elapsedTot = assembleTimer.elapsed() + solveTimer.elapsed() + updateTimer.elapsed();
1049 std::cout << Fmt::format(
"Assemble/solve/update time: {:.2g}({:.2f}%)/{:.2g}({:.2f}%)/{:.2g}({:.2f}%)\n",
1050 assembleTimer.elapsed(), 100*assembleTimer.elapsed()/elapsedTot,
1051 solveTimer.elapsed(), 100*solveTimer.elapsed()/elapsedTot,
1052 updateTimer.elapsed(), 100*updateTimer.elapsed()/elapsedTot);
1059 if (verbosity_ >= 1)
1060 std::cout <<
"Newton: Caught exception: \"" << e.what() <<
"\"\n";
1074 this->
assembler().assembleJacobianAndResidual(vars, partialReassembler_.get());
1079 auto assembleLinearSystem_(
const A& assembler,
const Variables& vars)
1080 ->
typename std::enable_if_t<!
decltype(
isValid(Detail::supportsPartialReassembly())(assembler))::value,
void>
1082 this->assembler().assembleJacobianAndResidual(vars);
1092 virtual void newtonUpdateShift_(
const SolutionVector &uLastIter,
1093 const SolutionVector &deltaU)
1095 auto uNew = uLastIter;
1097 shift_ = Detail::maxRelativeShift<Scalar>(uLastIter, uNew);
1099 if (comm_.size() > 1)
1100 shift_ = comm_.max(shift_);
1103 virtual void lineSearchUpdate_(Variables &vars,
1104 const SolutionVector &uLastIter,
1105 const SolutionVector &deltaU)
1107 Scalar lambda = 1.0;
1108 auto uCurrentIter = uLastIter;
1112 Backend::axpy(-lambda, deltaU, uCurrentIter);
1113 solutionChanged_(vars, uCurrentIter);
1115 computeResidualReduction_(vars);
1117 if (reduction_ < lastReduction_ || lambda <= lineSearchMinRelaxationFactor_)
1119 endIterMsgStream_ << Fmt::format(
", residual reduction {:.4e}->{:.4e}@lambda={:.4f}", lastReduction_, reduction_, lambda);
1125 uCurrentIter = uLastIter;
1130 virtual void choppedUpdate_(Variables& vars,
1131 const SolutionVector& uLastIter,
1132 const SolutionVector& deltaU)
1134 DUNE_THROW(Dune::NotImplemented,
1135 "Chopped Newton update strategy not implemented.");
1138 virtual bool solveLinearSystem_(SolutionVector& deltaU)
1140 return solveLinearSystemImpl_(this->linearSolver(),
1141 this->assembler().jacobian(),
1143 this->assembler().residual());
1155 template<
class V = SolutionVector>
1156 typename std::enable_if_t<!isMultiTypeBlockVector<V>(),
bool>
1157 solveLinearSystemImpl_(LinearSolver& ls,
1168 using OriginalBlockType = Detail::BlockType<SolutionVector>;
1169 constexpr auto blockSize = Detail::blockSize<OriginalBlockType>();
1171 using BlockType = Dune::FieldVector<Scalar, blockSize>;
1172 Dune::BlockVector<BlockType> xTmp; xTmp.resize(Backend::size(b));
1173 Dune::BlockVector<BlockType> bTmp(xTmp);
1176 const int converged = ls.solve(A, xTmp, bTmp);
1192 template<
class LS = LinearSolver,
class V = SolutionVector>
1193 typename std::enable_if_t<linearSolverAcceptsMultiTypeMatrix<LS>() &&
1194 isMultiTypeBlockVector<V>(),
bool>
1195 solveLinearSystemImpl_(LinearSolver& ls,
1200 assert(this->checkSizesOfSubMatrices(A) &&
"Sub-blocks of MultiTypeBlockMatrix have wrong sizes!");
1201 return ls.solve(A, x, b);
1214 template<
class LS = LinearSolver,
class V = SolutionVector>
1215 typename std::enable_if_t<!linearSolverAcceptsMultiTypeMatrix<LS>() &&
1216 isMultiTypeBlockVector<V>(),
bool>
1217 solveLinearSystemImpl_(LinearSolver& ls,
1222 assert(this->checkSizesOfSubMatrices(A) &&
"Sub-blocks of MultiTypeBlockMatrix have wrong sizes!");
1228 const std::size_t numRows = M.N();
1229 assert(numRows == M.M());
1233 assert(bTmp.size() == numRows);
1236 using VectorBlock =
typename Dune::FieldVector<Scalar, 1>;
1237 using BlockVector =
typename Dune::BlockVector<VectorBlock>;
1238 BlockVector y(numRows);
1241 const bool converged = ls.solve(M, y, bTmp);
1251 void initParams_(
const std::string& group =
"")
1253 useLineSearch_ = getParamFromGroup<bool>(group,
"Newton.UseLineSearch",
false);
1254 lineSearchMinRelaxationFactor_ = getParamFromGroup<Scalar>(group,
"Newton.LineSearchMinRelaxationFactor", 0.125);
1255 useChop_ = getParamFromGroup<bool>(group,
"Newton.EnableChop",
false);
1256 if(useLineSearch_ && useChop_)
1257 DUNE_THROW(Dune::InvalidStateException,
"Use either linesearch OR chop!");
1259 enableAbsoluteResidualCriterion_ = getParamFromGroup<bool>(group,
"Newton.EnableAbsoluteResidualCriterion",
false);
1260 enableShiftCriterion_ = getParamFromGroup<bool>(group,
"Newton.EnableShiftCriterion",
true);
1261 enableResidualCriterion_ = getParamFromGroup<bool>(group,
"Newton.EnableResidualCriterion",
false) || enableAbsoluteResidualCriterion_;
1262 satisfyResidualAndShiftCriterion_ = getParamFromGroup<bool>(group,
"Newton.SatisfyResidualAndShiftCriterion",
false);
1263 enableDynamicOutput_ = getParamFromGroup<bool>(group,
"Newton.EnableDynamicOutput",
true);
1265 if (!enableShiftCriterion_ && !enableResidualCriterion_)
1267 DUNE_THROW(Dune::NotImplemented,
1268 "at least one of NewtonEnableShiftCriterion or "
1269 <<
"NewtonEnableResidualCriterion has to be set to true");
1272 setMaxRelativeShift(getParamFromGroup<Scalar>(group,
"Newton.MaxRelativeShift", 1e-8));
1273 setMaxAbsoluteResidual(getParamFromGroup<Scalar>(group,
"Newton.MaxAbsoluteResidual", 1e-5));
1274 setResidualReduction(getParamFromGroup<Scalar>(group,
"Newton.ResidualReduction", 1e-5));
1275 setTargetSteps(getParamFromGroup<int>(group,
"Newton.TargetSteps", 10));
1276 setMinSteps(getParamFromGroup<int>(group,
"Newton.MinSteps", 2));
1277 setMaxSteps(getParamFromGroup<int>(group,
"Newton.MaxSteps", 18));
1279 enablePartialReassembly_ = getParamFromGroup<bool>(group,
"Newton.EnablePartialReassembly",
false);
1280 reassemblyMinThreshold_ = getParamFromGroup<Scalar>(group,
"Newton.ReassemblyMinThreshold", 1e-1*shiftTolerance_);
1281 reassemblyMaxThreshold_ = getParamFromGroup<Scalar>(group,
"Newton.ReassemblyMaxThreshold", 1e2*shiftTolerance_);
1282 reassemblyShiftWeight_ = getParamFromGroup<Scalar>(group,
"Newton.ReassemblyShiftWeight", 1e-3);
1284 maxTimeStepDivisions_ = getParamFromGroup<std::size_t>(group,
"Newton.MaxTimeStepDivisions", 10);
1285 retryTimeStepReductionFactor_ = getParamFromGroup<Scalar>(group,
"Newton.RetryTimeStepReductionFactor", 0.5);
1287 verbosity_ = comm_.rank() == 0 ? getParamFromGroup<int>(group,
"Newton.Verbosity", 2) : 0;
1291 if (verbosity_ >= 2)
1296 void updateDistanceFromLastLinearization_(
const Sol& u,
const Sol& uDelta)
1298 if constexpr (Dune::IsNumber<Sol>::value)
1300 auto nextPriVars = u;
1301 nextPriVars -= uDelta;
1304 auto shift = Detail::maxRelativeShift<Scalar>(u, nextPriVars);
1305 distanceFromLastLinearization_[0] += shift;
1309 for (std::size_t i = 0; i < u.size(); ++i)
1311 const auto& currentPriVars(u[i]);
1312 auto nextPriVars(currentPriVars);
1313 nextPriVars -= uDelta[i];
1316 auto shift = Detail::maxRelativeShift<Scalar>(currentPriVars, nextPriVars);
1317 distanceFromLastLinearization_[i] += shift;
1322 template<
class ...Args>
1326 DUNE_THROW(Dune::NotImplemented,
"Reassembly for MultiTypeBlockVector");
1330 void resizeDistanceFromLastLinearization_(
const Sol& u, std::vector<Scalar>& dist)
1332 dist.assign(Backend::size(u), 0.0);
1335 template<
class ...Args>
1337 std::vector<Scalar>& dist)
1339 DUNE_THROW(Dune::NotImplemented,
"Reassembly for MultiTypeBlockVector");
1343 Communication comm_;
1348 Scalar shiftTolerance_;
1349 Scalar reductionTolerance_;
1350 Scalar residualTolerance_;
1353 std::size_t maxTimeStepDivisions_;
1354 Scalar retryTimeStepReductionFactor_;
1357 bool useLineSearch_;
1358 Scalar lineSearchMinRelaxationFactor_;
1360 bool enableAbsoluteResidualCriterion_;
1361 bool enableShiftCriterion_;
1362 bool enableResidualCriterion_;
1363 bool satisfyResidualAndShiftCriterion_;
1364 bool enableDynamicOutput_;
1367 std::string paramGroup_;
1370 bool enablePartialReassembly_;
1371 std::unique_ptr<Reassembler> partialReassembler_;
1372 std::vector<Scalar> distanceFromLastLinearization_;
1373 Scalar reassemblyMinThreshold_;
1374 Scalar reassemblyMaxThreshold_;
1375 Scalar reassemblyShiftWeight_;
1378 std::size_t totalWastedIter_ = 0;
1379 std::size_t totalSucceededIter_ = 0;
1380 std::size_t numConverged_ = 0;
1381 std::size_t numLinearSolverBreakdowns_ = 0;
1384 std::unique_ptr<PrimaryVariableSwitchAdapter> priVarSwitchAdapter_;
1387 std::shared_ptr<ConvergenceWriter> convergenceWriter_ =
nullptr;
Detects which entries in the Jacobian have to be recomputed.
Type traits to be used with vector types.
A helper function for class member function introspection.
Some exceptions thrown in DuMux
Backends for operations on different solution vector types or more generic variable classes to be use...
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.
Formatting based on the fmt-library which implements std::format of C++20.
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.
An adapter for the Newton to manage models with primary variable switch.
@ red
distance from last linearization is above the tolerance
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
auto hybridInnerProduct(const V &v1, const V &v2, Scalar init, Reduce &&r, Transform &&t) -> std::enable_if_t< hasDynamicIndexAccess< V >(), Scalar >
Definition: nonlinear/newtonsolver.hh:110
typename Assembler::GridVariables AssemblerGridVariablesType
Definition: nonlinear/newtonsolver.hh:65
decltype(std::declval< LinearSolver >().norm(std::declval< Residual >())) NormDetector
Definition: nonlinear/newtonsolver.hh:97
decltype(std::declval< C >()[0]) dynamicIndexAccess
Definition: nonlinear/newtonsolver.hh:104
void assign(To &to, const From &from)
Definition: nonlinear/newtonsolver.hh:151
static constexpr auto hasDynamicIndexAccess
Definition: nonlinear/newtonsolver.hh:106
static constexpr auto hasStaticIndexAccess
Definition: nonlinear/newtonsolver.hh:107
static constexpr bool hasNorm()
Definition: nonlinear/newtonsolver.hh:100
constexpr std::size_t blockSize()
Definition: nonlinear/newtonsolver.hh:185
decltype(std::declval< C >()[Dune::Indices::_0]) staticIndexAccess
Definition: nonlinear/newtonsolver.hh:105
typename BlockTypeHelper< SolutionVector, Dune::IsNumber< SolutionVector >::value >::type BlockType
Definition: nonlinear/newtonsolver.hh:198
constexpr bool assemblerExportsGridVariables
Definition: nonlinear/newtonsolver.hh:68
auto maxRelativeShift(const V &v1, const V &v2) -> std::enable_if_t< Dune::IsNumber< V >::value, Scalar >
Definition: nonlinear/newtonsolver.hh:131
typename PriVarSwitchVariablesType< Assembler, assemblerExportsGridVariables< Assembler > >::Type PriVarSwitchVariables
Definition: nonlinear/newtonsolver.hh:83
detects which entries in the Jacobian have to be recomputed
Definition: partialreassembler.hh:432
Exception thrown if a fixable numerical problem occurs.
Definition: exceptions.hh:39
A high-level interface for a PDESolver.
Definition: common/pdesolver.hh:72
Detail::AssemblerVariables< Assembler > Variables
export the type of variables that represent a numerical solution
Definition: common/pdesolver.hh:82
const LinearSolver & linearSolver() const
Access the linear solver.
Definition: common/pdesolver.hh:133
const Assembler & assembler() const
Access the assembler.
Definition: common/pdesolver.hh:121
Manages the handling of time dependent problems.
Definition: common/timeloop.hh:69
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 .
Definition: variablesbackend.hh:43
Definition: variablesbackend.hh:159
static auto multiTypeToBCRSMatrix(const MultiTypeBlockMatrix &A)
Converts the matrix to a type the IterativeSolverBackend can handle.
Definition: matrixconverter.hh:58
static void retrieveValues(MultiTypeBlockVector &x, const BlockVector &y)
Copys the entries of a Dune::BlockVector to a Dune::MultiTypeBlockVector.
Definition: matrixconverter.hh:241
static auto multiTypeToBlockVector(const MultiTypeBlockVector &b)
Converts a Dune::MultiTypeBlockVector to a plain 1x1 Dune::BlockVector.
Definition: matrixconverter.hh:215
Base class for linear solvers.
Definition: solver.hh:37
Definition: nonlinear/newtonconvergencewriter.hh:39
Definition: nonlinear/newtonsolver.hh:72
typename Assembler::GridVariables Type
Definition: nonlinear/newtonsolver.hh:72
EmptyGridVariables {} Type
Definition: nonlinear/newtonsolver.hh:78
helper struct detecting if an assembler supports partial reassembly
Definition: nonlinear/newtonsolver.hh:87
auto operator()(Assembler &&a) -> decltype(a.assembleJacobianAndResidual(std::declval< const typename Assembler::ResidualType & >(), std::declval< const PartialReassembler< Assembler > * >()))
Definition: nonlinear/newtonsolver.hh:89
Definition: nonlinear/newtonsolver.hh:192
std::decay_t< decltype(std::declval< S >()[0])> type
Definition: nonlinear/newtonsolver.hh:192
S type
Definition: nonlinear/newtonsolver.hh:195
An implementation of a Newton solver.
Definition: nonlinear/newtonsolver.hh:216
Comm Communication
Definition: nonlinear/newtonsolver.hh:240
virtual void newtonFail(Variables &u)
Called if the Newton method broke down. This method is called after newtonEnd()
Definition: nonlinear/newtonsolver.hh:735
int maxSteps_
maximum number of iterations we do before giving up
Definition: nonlinear/newtonsolver.hh:915
void setMaxSteps(int maxSteps)
Set the number of iterations after which the Newton method gives up.
Definition: nonlinear/newtonsolver.hh:329
void newtonUpdate(Variables &vars, const SolutionVector &uLastIter, const SolutionVector &deltaU)
Update the current solution with a delta vector.
Definition: nonlinear/newtonsolver.hh:573
void setResidualReduction(Scalar tolerance)
Set the maximum acceptable residual norm reduction.
Definition: nonlinear/newtonsolver.hh:298
void reportParams(std::ostream &sout=std::cout) const
Report the options and parameters this Newton is configured with.
Definition: nonlinear/newtonsolver.hh:773
int targetSteps_
optimal number of iterations we want to achieve
Definition: nonlinear/newtonsolver.hh:911
const std::string & paramGroup() const
Returns the parameter group.
Definition: nonlinear/newtonsolver.hh:841
void setRetryTimeStepReductionFactor(const Scalar factor)
Set the factor for reducing the time step after a Newton iteration has failed.
Definition: nonlinear/newtonsolver.hh:865
Scalar reduction_
Definition: nonlinear/newtonsolver.hh:920
Scalar retryTimeStepReductionFactor() const
Return the factor for reducing the time step after a Newton iteration has failed.
Definition: nonlinear/newtonsolver.hh:859
int numSteps_
actual number of steps done so far
Definition: nonlinear/newtonsolver.hh:917
int verbosity() const
Return the verbosity level.
Definition: nonlinear/newtonsolver.hh:835
void setMinSteps(int minSteps)
Set the number of minimum iterations for the Newton method.
Definition: nonlinear/newtonsolver.hh:320
int minSteps_
minimum number of iterations we do
Definition: nonlinear/newtonsolver.hh:913
virtual void newtonBegin(Variables &initVars)
Called before the Newton method is applied to an non-linear system of equations.
Definition: nonlinear/newtonsolver.hh:407
virtual void assembleLinearSystem(const Variables &vars)
Assemble the linear system of equations .
Definition: nonlinear/newtonsolver.hh:485
bool enableResidualCriterion() const
Definition: nonlinear/newtonsolver.hh:907
virtual bool newtonProceed(const Variables &varsCurrentIter, bool converged)
Returns true if another iteration should be done.
Definition: nonlinear/newtonsolver.hh:444
void solve(Variables &vars, 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:339
virtual void newtonEndStep(Variables &vars, const SolutionVector &uLastIter)
Indicates that one Newton iteration was finished.
Definition: nonlinear/newtonsolver.hh:638
virtual void solutionChanged_(Variables &vars, const SolutionVector &uCurrentIter)
Update solution-dependent quantities like grid variables after the solution has changed.
Definition: nonlinear/newtonsolver.hh:875
void report(std::ostream &sout=std::cout) const
output statistics / report
Definition: nonlinear/newtonsolver.hh:746
void solve(Variables &vars) override
Run the Newton method to solve a non-linear system. The solver is responsible for all the strategic d...
Definition: nonlinear/newtonsolver.hh:393
virtual void newtonSucceed()
Called if the Newton method ended successfully This method is called after newtonEnd()
Definition: nonlinear/newtonsolver.hh:741
void attachConvergenceWriter(std::shared_ptr< ConvergenceWriter > convWriter)
Attach a convergence writer to write out intermediate results after each iteration.
Definition: nonlinear/newtonsolver.hh:847
Scalar initialResidual_
Definition: nonlinear/newtonsolver.hh:923
Scalar lastReduction_
Definition: nonlinear/newtonsolver.hh:922
virtual void newtonBeginStep(const Variables &vars)
Indicates the beginning of a Newton iteration.
Definition: nonlinear/newtonsolver.hh:467
std::ostringstream endIterMsgStream_
message stream to be displayed at the end of iterations
Definition: nonlinear/newtonsolver.hh:930
void setVerbosity(int val)
Specifies the verbosity level.
Definition: nonlinear/newtonsolver.hh:829
typename Backend::DofVector SolutionVector
Definition: nonlinear/newtonsolver.hh:221
const Communication & comm() const
the communicator for parallel runs
Definition: nonlinear/newtonsolver.hh:270
void resetReport()
reset the statistics
Definition: nonlinear/newtonsolver.hh:762
NewtonSolver(std::shared_ptr< Assembler > assembler, std::shared_ptr< LinearSolver > linearSolver, const Communication &comm=Dune::MPIHelper::getCommunication(), const std::string ¶mGroup="")
The Constructor.
Definition: nonlinear/newtonsolver.hh:245
void setMaxAbsoluteResidual(Scalar tolerance)
Set the maximum acceptable absolute residual for declaring convergence.
Definition: nonlinear/newtonsolver.hh:289
virtual void newtonEnd()
Called if the Newton method ended (not known yet if we failed or succeeded)
Definition: nonlinear/newtonsolver.hh:679
void setTargetSteps(int targetSteps)
Set the number of iterations at which the Newton method should aim at.
Definition: nonlinear/newtonsolver.hh:311
virtual bool newtonConverged() const
Returns true if the error of the solution is below the tolerance.
Definition: nonlinear/newtonsolver.hh:685
Scalar suggestTimeStepSize(Scalar oldTimeStep) const
Suggest a new time-step size based on the old time-step size.
Definition: nonlinear/newtonsolver.hh:810
void solveLinearSystem(SolutionVector &deltaU)
Solve the linear system of equations .
Definition: nonlinear/newtonsolver.hh:504
void detachConvergenceWriter()
Detach the convergence writer to stop the output.
Definition: nonlinear/newtonsolver.hh:853
void setMaxRelativeShift(Scalar tolerance)
Set the maximum acceptable difference of any primary variable between two iterations for declaring co...
Definition: nonlinear/newtonsolver.hh:280
Scalar shift_
Definition: nonlinear/newtonsolver.hh:926
void computeResidualReduction_(const Variables &vars)
Definition: nonlinear/newtonsolver.hh:883
Scalar residualNorm_
Definition: nonlinear/newtonsolver.hh:921
Scalar lastShift_
Definition: nonlinear/newtonsolver.hh:927
An adapter for the Newton to manage models with primary variable switch.
Definition: primaryvariableswitchadapter.hh:59
Defines a high-level interface for a PDESolver.
Manages the handling of time dependent problems.
This class provides the infrastructure to write the convergence behaviour of the newton method into a...