https://mooseframework.inl.gov
Loading...
Searching...
No Matches
BrentsMethodTest.C
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
3//*
4//* All rights reserved, see COPYRIGHT for full restrictions
5//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6//*
7//* Licensed under LGPL 2.1, please see LICENSE for details
8//* https://www.gnu.org/licenses/lgpl-2.1.html
9
10#include "gtest/gtest.h"
11#include "BrentsMethod.h"
12
20Real
21f(Real x)
22{
23 return std::log(1.0 + x) * std::tanh(x / 3.0) + x / 4.0 - 3;
24}
25
27{
28 // Initial guess for bracketing interval does not bracket root
29 Real x1 = 0.5;
30 Real x2 = 1.0;
31
32 auto func = [](Real x) { return f(x); };
33
34 // Call bracket to determine the bracketing interval
35 BrentsMethod::bracket(func, x1, x2);
36
37 // The product of the function f(x) at the bracketing interval (x1, x2) must
38 // be negative to bracket a root
39 EXPECT_LT(f(x1) * f(x2), 0.0);
40
41 // Test that a warning is thrown if the initial guesses are equal
42 try
43 {
44 // Trigger identical initial guess error
45 BrentsMethod::bracket(func, x1, x1);
46 FAIL() << "missing expected exception";
47 }
48 catch (const std::exception & e)
49 {
50 std::string msg(e.what());
51 ASSERT_TRUE(msg.find("Bad initial range (0) used in BrentsMethod::bracket") !=
52 std::string::npos)
53 << "failed with unexpected error: " << msg;
54 }
55
56 // Test that a warning is thrown if no bracketing interval is found after 50 iterations.
57 try
58 {
59 // Trigger no bracketing interval warning by adding 4 to f(x), whereby no real root exists
60 auto func2 = [](Real x) { return f(x) + 4.0; };
61
62 BrentsMethod::bracket(func2, x1, x2);
63 FAIL() << "missing expected exception";
64 }
65 catch (const std::exception & e)
66 {
67 std::string msg(e.what());
68 ASSERT_TRUE(
69 msg.find("No bracketing interval found by BrentsMethod::bracket after 50 iterations") !=
70 std::string::npos)
71 << "failed with unexpected error: " << msg;
72 }
73}
74
76{
77 // Bracketing interval that does bracket root
78 Real x1 = 0.5;
79 Real x2 = 10.0;
80
81 auto func = [](Real x) { return f(x); };
82
83 // Check that the root is 5.170302597
84 EXPECT_NEAR(5.170302597, BrentsMethod::root(func, x1, x2), 1e-8);
85
86 // Test that a warning is thrown if the supplied interval does not bracket the root
87 try
88 {
89 // Trigger no bracketing interval error
90 x2 = 1.0;
91 BrentsMethod::root(func, x1, x2);
92 FAIL() << "missing expected exception";
93 }
94 catch (const std::exception & e)
95 {
96 std::string msg(e.what());
97 ASSERT_TRUE(msg.find("Root must be bracketed in BrentsMethod::root") != std::string::npos)
98 << "failed with unexpected error: " << msg;
99 }
100}
TEST(BrentsMethod, bracket)
Real f(Real x)
Test function for Brents method.
const std::vector< double > x
Brent's method is used to find the root of a function f(x), i.e., find x such that f(x) = 0.
Real root(std::function< Real(Real)> const &f, Real x1, Real x2, Real tol=1.0e-12)
Finds the root of a function using Brent's method.
void bracket(std::function< Real(Real)> const &f, Real &x1, Real &x2)
Function to bracket a root of a given function.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real