https://mooseframework.inl.gov
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 
20 Real
21 f(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 }
const std::vector< double > x
Real f(Real x)
Test function for Brents method.
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&#39;s method.
Definition: BrentsMethod.C:66
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Brent&#39;s method is used to find the root of a function f(x), i.e., find x such that f(x) = 0...
Definition: BrentsMethod.h:26
TEST(BrentsMethod, bracket)
void bracket(std::function< Real(Real)> const &f, Real &x1, Real &x2)
Function to bracket a root of a given function.
Definition: BrentsMethod.C:17