12#ifndef DUMUX_COMMON_SCALAR_ROOT_FINDING_HH 
   13#define DUMUX_COMMON_SCALAR_ROOT_FINDING_HH 
   34template<
class Scalar, 
class ResFunc, 
class DerivFunc,
 
   35         typename std::enable_if_t<std::is_invocable_r_v<Scalar, ResFunc, Scalar> &&
 
   36                                   std::is_invocable_r_v<Scalar, DerivFunc, Scalar>>...>
 
   38                            const Scalar tol = 1e-13, 
const int maxIter = 200)
 
   41    Scalar r = residual(xNew);
 
   44    Scalar relativeShift = std::numeric_limits<Scalar>::max();
 
   45    while (relativeShift > tol && n > 0)
 
   47        xNew = xOld - r/derivative(xOld);
 
   50        using std::abs; 
using std::max;
 
   51        relativeShift = abs(xOld-xNew)/max(abs(xOld), abs(xNew));
 
   58        DUNE_THROW(
NumericalProblem, 
"Residual is not finite: " << r << 
" after " << maxIter - n << 
" iterations!");
 
   60    if (relativeShift > tol)
 
   61        DUNE_THROW(
NumericalProblem, 
"Scalar newton solver did not converge after " << maxIter << 
" iterations!");
 
 
   75template<
class Scalar, 
class ResFunc,
 
   76          typename std::enable_if_t<std::is_invocable_r_v<Scalar, ResFunc, Scalar>>...>
 
   78                            const Scalar tol = 1e-13, 
const int maxIter = 200)
 
   81    auto derivative = [&](
const auto x){ 
return (residual(x + eps)-residual(x))/eps; };
 
 
   97template<
class Scalar, 
class ResFunc,
 
   98         typename std::enable_if_t<std::is_invocable_r_v<Scalar, ResFunc, Scalar>>...>
 
  100                           const Scalar tol = 1e-13, 
const int maxIter = 200)
 
  103    Scalar fa = residual(a);
 
  104    Scalar fb = residual(b);
 
  110        DUNE_THROW(
NumericalProblem, 
"Brent's algorithm failed: [a,b] does not contain any, or no uniquely defined root!");
 
  113    using std::abs; 
using std::swap;
 
  114    if (abs(fa) < abs(fb))
 
  126    for (
int i = 0; i < maxIter; ++i)
 
  130        if (abs(b-a) < tol*max(abs(a), abs(b)))
 
  134        if (fa != fc && fb != fc)
 
  136            const auto fab = fa-fb;
 
  137            const auto fac = fa-fc;
 
  138            const auto fbc = fb-fc;
 
  139            s = a*fb*fc/(fab*fac) - b*fa*fc/(fab*fbc) + c*fa*fb/(fac*fbc);
 
  145            s = b - fb*(b-a)/(fb-fa);
 
  149        if ( (s < (3*a + b)*0.25 || s > b)
 
  150             || (flag && abs(s-b) >= abs(b-c)*0.5)
 
  151             || (!flag && abs(s-b) >= abs(c-d)*0.5)
 
  152             || (flag && abs(b-c) < tol*max(abs(b), abs(c)))
 
  153             || (!flag && abs(c-d) < tol*max(abs(c), abs(d))) )
 
  180        if (abs(fa) < abs(fb))
 
  187    DUNE_THROW(
NumericalProblem, 
"Brent's algorithm didn't converge after " << maxIter << 
" iterations!");
 
 
static Scalar epsilon(const Scalar value, const Scalar baseEps=1e-10)
Computes the epsilon used for numeric differentiation.
Definition numericdifferentiation.hh:36
Exception thrown if a fixable numerical problem occurs.
Definition exceptions.hh:27
Some exceptions thrown in DuMux
Scalar findScalarRootNewton(Scalar xOld, const ResFunc &residual, const DerivFunc &derivative, const Scalar tol=1e-13, const int maxIter=200)
Newton's root finding algorithm for scalar functions (secant method)
Definition findscalarroot.hh:37
Scalar findScalarRootBrent(Scalar a, Scalar b, const ResFunc &residual, const Scalar tol=1e-13, const int maxIter=200)
Brent's root finding algorithm for scalar functions.
Definition findscalarroot.hh:99
A class for numeric differentiation.
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.