flexiblesusy is hosted by Hepforge, IPPP Durham
FlexibleSUSY
rkf_integrator.cpp
Go to the documentation of this file.
1// ====================================================================
2// This file is part of FlexibleSUSY.
3//
4// FlexibleSUSY is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published
6// by the Free Software Foundation, either version 3 of the License,
7// or (at your option) any later version.
8//
9// FlexibleSUSY is distributed in the hope that it will be useful, but
10// WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12// General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with FlexibleSUSY. If not, see
16// <http://www.gnu.org/licenses/>.
17// ====================================================================
18
24#include "rkf_integrator.hpp"
25#include "logger.hpp"
26#include "wrappers.hpp"
27
28#include "config.h"
29
30#ifdef ENABLE_ODEINT
31
32#include <boost/numeric/odeint/algebra/algebra_dispatcher.hpp>
33#include <boost/numeric/odeint/algebra/vector_space_algebra.hpp>
34#include <boost/numeric/odeint/external/eigen/eigen_algebra_dispatcher.hpp>
35#include <boost/numeric/odeint/external/eigen/eigen_resize.hpp>
36#include <boost/numeric/odeint/integrate/integrate_adaptive.hpp>
37#include <boost/numeric/odeint/stepper/generation.hpp>
38#include <boost/numeric/odeint/stepper/runge_kutta_fehlberg78.hpp>
39
40namespace boost {
41namespace numeric {
42namespace odeint {
43
44template <typename Scalar, int R, int C, int O, int MR, int MC>
45struct vector_space_norm_inf<Eigen::Array<Scalar,R,C,O,MR,MC> > {
46 using result_type = typename Eigen::NumTraits<Scalar>::Real;
47 result_type operator()(const Eigen::Array<Scalar,R,C,O,MR,MC>& x) const
48 {
49 return x.cwiseAbs().maxCoeff();
50 }
51};
52
53} // namespace odeint
54} // namespace numeric
55} // namespace boost
56
57namespace flexiblesusy {
58
59namespace runge_kutta {
60
73void RKF_integrator::operator()(double start, double end,
74 Eigen::ArrayXd& pars, const Derivs& derivs,
75 double tol) const
76{
77 using state_type = Eigen::ArrayXd;
78 using stepper_type = boost::numeric::odeint::runge_kutta_fehlberg78<
79 state_type, double, state_type, double,
80 boost::numeric::odeint::vector_space_algebra
81 >;
82
83 const double guess = (end - start) * 0.1; // first step size
84 const auto derivatives = [derivs] (const state_type& y, state_type& dydt, double t) -> void {
85 dydt = derivs(t, y);
86 };
87
88 const auto stepper = boost::numeric::odeint::make_controlled(tol, tol, stepper_type());
89 boost::numeric::odeint::integrate_adaptive(
90 stepper, derivatives, pars, start, end, guess, RKF_observer());
91}
92
93void RKF_integrator::RKF_observer::operator()(const Eigen::ArrayXd& state, double t) const
94{
95 if (!IsFinite(state)) {
96 int max_step_dir = 0;
97 for (int i = 0; i < state.size(); ++i) {
98 if (!IsFinite(state(i))) {
99 max_step_dir = i;
100 break;
101 }
102 }
103#ifdef ENABLE_VERBOSE
104 ERROR("RKF_integrator: non-perturbative running at Q = "
105 << std::exp(t) << " GeV of parameter y(" << max_step_dir
106 << ") = " << state(max_step_dir));
107#endif
108 throw NonPerturbativeRunningError(std::exp(t), max_step_dir, state(max_step_dir));
109 }
110}
111
112} // namespace runge_kutta
113
114} // namespace flexiblesusy
115
116#else
117
118namespace flexiblesusy {
119
120namespace runge_kutta {
121
134void RKF_integrator::operator()(double, double, Eigen::ArrayXd&, const Derivs&,
135 double) const
136{
137 throw DisabledOdeintError("Cannot call operator(), because odeint support is disabled.");
138}
139
140} // namespace runge_kutta
141
142} // namespace flexiblesusy
143
144#endif
std::function< Eigen::ArrayXd(double, const Eigen::ArrayXd &)> Derivs
void operator()(double start, double end, Eigen::ArrayXd &pars, const Derivs &derivs, double tol) const
Integrates the system over an interval.
#define ERROR(msg)
Definition: logger.hpp:65
double Real
Definition: mathdefs.hpp:12
double * end(GSL_vector &v)
iterator to end of GSL_vector
Definition: gsl_vector.cpp:254
bool IsFinite(double x) noexcept
Definition: wrappers.cpp:77
Integration of ODEs using the Runge-Kutta-Fehlberg method.
void operator()(const Eigen::ArrayXd &, double) const