Version: SMASH-3.1
smash::RootSolver1D Class Reference

#include <rootsolver.h>

A class used for calculating the root of a one-dimensional equation.

It takes care of all technicalities and provides an interface to GSL.

Definition at line 30 of file rootsolver.h.

Public Member Functions

 RootSolver1D (std::function< double(double)> eq)
 Construct a new Root Solver 1D object. More...
 
 ~RootSolver1D ()
 
std::optional< double > try_find_root (double initial_guess_low, double initial_guess_high, size_t itermax)
 Attempt to find a root in a given interval. More...
 

Static Private Member Functions

static double gsl_func (const double x, void *)
 The function of which a root should be found in the form that GSL expects. More...
 

Private Attributes

const gsl_root_fsolver_type * Solver_name_ = gsl_root_fsolver_brent
 GSL solver to use for root finding. More...
 
gsl_root_fsolver * Root_finder_ = nullptr
 GSL root finding object to take care of root finding. More...
 
double solution_precision_ = 1e-7
 Expected precision of the root. More...
 

Static Private Attributes

static std::unique_ptr< std::function< double(double)> > root_eq_
 Static pointer to the function to solve. More...
 

Constructor & Destructor Documentation

◆ RootSolver1D()

smash::RootSolver1D::RootSolver1D ( std::function< double(double)>  eq)
inlineexplicit

Construct a new Root Solver 1D object.

Parameters
[in]eqThe function of which a root is desired

Definition at line 37 of file rootsolver.h.

37  {
38  root_eq_ = std::make_unique<std::function<double(double)>>(eq);
39  }
static std::unique_ptr< std::function< double(double)> > root_eq_
Static pointer to the function to solve.
Definition: rootsolver.h:103

◆ ~RootSolver1D()

smash::RootSolver1D::~RootSolver1D ( )
inline

Definition at line 41 of file rootsolver.h.

41 { root_eq_ = nullptr; }

Member Function Documentation

◆ try_find_root()

std::optional<double> smash::RootSolver1D::try_find_root ( double  initial_guess_low,
double  initial_guess_high,
size_t  itermax 
)
inline

Attempt to find a root in a given interval.

Parameters
[in]initial_guess_lowLower boundary of the interval
[in]initial_guess_highHigher boundary of the interval
[in]itermaxmaximum number of steps for root finding
Returns
the root if it was found

Definition at line 51 of file rootsolver.h.

53  {
54  // check if root is in the given interval
55  if ((*root_eq_)(initial_guess_low) * (*root_eq_)(initial_guess_high) > 0) {
56  logg[LRootSolver].debug()
57  << "Function has same sign at both ends of the interval ["
58  << initial_guess_low << ", " << initial_guess_high
59  << "]. Root can't be found in this interval.";
60  return std::nullopt;
61  }
62  gsl_function function_GSL = {&(gsl_func), nullptr};
63  int status = GSL_CONTINUE;
64  size_t iter = 0;
65  Root_finder_ = gsl_root_fsolver_alloc(Solver_name_);
66  gsl_root_fsolver_set(Root_finder_, &function_GSL, initial_guess_low,
67  initial_guess_high);
68  do {
69  iter++;
70  status = gsl_root_fsolver_iterate(Root_finder_);
71  if (status != GSL_SUCCESS) {
72  logg[LRootSolver].debug("GSL ERROR in root finding: " +
73  static_cast<std::string>(gsl_strerror(status)));
74  break;
75  }
76  double xlow = gsl_root_fsolver_x_lower(Root_finder_);
77  double xhigh = gsl_root_fsolver_x_upper(Root_finder_);
78  status = gsl_root_test_interval(xlow, xhigh, 0, solution_precision_);
79  if (status == GSL_SUCCESS) {
80  double root = 0.5 * (xlow + xhigh);
81  gsl_root_fsolver_free(Root_finder_);
82  return root;
83  }
84  } while (status == GSL_CONTINUE && iter < itermax);
85  gsl_root_fsolver_free(Root_finder_);
86  return std::nullopt;
87  }
double solution_precision_
Expected precision of the root.
Definition: rootsolver.h:107
gsl_root_fsolver * Root_finder_
GSL root finding object to take care of root finding.
Definition: rootsolver.h:94
const gsl_root_fsolver_type * Solver_name_
GSL solver to use for root finding.
Definition: rootsolver.h:91
static double gsl_func(const double x, void *)
The function of which a root should be found in the form that GSL expects.
Definition: rootsolver.h:125
std::array< einhard::Logger<>, std::tuple_size< LogArea::AreaTuple >::value > logg
An array that stores all pre-configured Logger objects.
Definition: logging.cc:39
static constexpr int LRootSolver
Definition: rootsolver.h:25

◆ gsl_func()

static double smash::RootSolver1D::gsl_func ( const double  x,
void *   
)
inlinestaticprivate

The function of which a root should be found in the form that GSL expects.

Parameters
[in]xArgument of the function
Returns
The value of the function for the given argument x
Note
This function needs to be static because GSL uses an object of type gsl_function that has to be initialised with a pointer to a function and this cannot be created from a class non-static method as a class non-static method cannot exist as entity without an instance of that type. On the contrary, a pointer to a static member function can be used as a normal pointer to a free function, because a static method exists without needing any instance of the class.

Definition at line 125 of file rootsolver.h.

125 { return (*root_eq_)(x); }

Member Data Documentation

◆ Solver_name_

const gsl_root_fsolver_type* smash::RootSolver1D::Solver_name_ = gsl_root_fsolver_brent
private

GSL solver to use for root finding.

Definition at line 91 of file rootsolver.h.

◆ Root_finder_

gsl_root_fsolver* smash::RootSolver1D::Root_finder_ = nullptr
private

GSL root finding object to take care of root finding.

Definition at line 94 of file rootsolver.h.

◆ root_eq_

std::unique_ptr<std::function<double(double)> > smash::RootSolver1D::root_eq_
inlinestaticprivate
Initial value:
=
nullptr

Static pointer to the function to solve.

Note
This member has to be static since it is used inside the static gsl_func method. As static methods exist and can be used without a class instance, it is not possible to use non-static members inside them (non-static members are bound to a class instance).
See also
gsl_func to understand why that method needs to be static as well.

Definition at line 103 of file rootsolver.h.

◆ solution_precision_

double smash::RootSolver1D::solution_precision_ = 1e-7
private

Expected precision of the root.

Definition at line 107 of file rootsolver.h.


The documentation for this class was generated from the following file: