11 #include "MooseError.h"
12 #include "Conversion.h"
17 bracket(std::function<Real(Real)>
const & f, Real & x1, Real & x2)
29 throw MooseException(
"Bad initial range (0) used in BrentsMethod::bracket");
36 unsigned int iter = 0;
39 if (std::abs(f1) < std::abs(f2))
41 x1 += factor * (x1 - x2);
42 x1 = (x1 < eps ? eps : x1);
47 x2 += factor * (x2 - x1);
48 x2 = (x2 < eps ? eps : x2);
54 throw MooseException(
"No bracketing interval found by BrentsMethod::bracket after " +
55 Moose::stringify(n) +
" iterations");
61 root(std::function<Real(Real)>
const & f, Real x1, Real x2, Real
tol)
63 Real a = x1, b = x2, c = x2, d = 0.0, e = 0.0, min1, min2;
66 Real fc, p, q, r, s, tol1, xm;
67 unsigned int iter_max = 100;
71 throw MooseException(
"Root must be bracketed in BrentsMethod::root");
74 for (
unsigned int i = 1; i <= iter_max; ++i)
84 if (std::abs(fc) < std::abs(fb))
94 tol1 = 2.0 * eps * std::abs(b) + 0.5 *
tol;
97 if (std::abs(xm) <= tol1 || fb == 0.0)
100 if (std::abs(e) >= tol1 && std::abs(fa) > std::abs(fb))
113 p = s * (2.0 * xm * q * (q - r) - (b - a) * (r - 1.0));
114 q = (q - 1.0) * (r - 1.0) * (s - 1.0);
120 min1 = 3.0 * xm * q - std::abs(tol1 * q);
121 min2 = std::abs(e * q);
123 if (2.0 * p < (min1 < min2 ? min1 : min2))
146 if (std::abs(d) > tol1)
150 Real sgn = (xm >= 0.0 ? std::abs(tol1) : -std::abs(tol1));
157 throw MooseException(
"Maximum number of iterations exceeded in BrentsMethod::root");