flexiblesusy is hosted by Hepforge, IPPP Durham
FlexibleSUSY
convergence_tester_drbar.hpp
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
19#ifndef CONVERGENCE_TESTER_DRBAR_H
20#define CONVERGENCE_TESTER_DRBAR_H
21
23#include "error.hpp"
24#include "logger.hpp"
25#include "numerics2.hpp"
26#include "wrappers.hpp"
27
28#include <functional>
29#include <limits>
30
31namespace flexiblesusy {
32
33template <class Model>
35public:
36 using Scale_getter = std::function<double()>;
37
38 Convergence_tester_DRbar(const Model*, double, const Scale_getter& sg = Scale_getter());
39 virtual ~Convergence_tester_DRbar() = default;
40
41 virtual bool accuracy_goal_reached() override;
42 virtual double get_accuracy_goal() const { return accuracy_goal; }
43 virtual int max_iterations() const override { return max_it; }
44 virtual void restart() override;
45
46 double get_current_accuracy() const { return current_accuracy; }
48 void set_max_iterations(int it) { max_it = it; }
50 template <typename F>
51 void set_scale_getter(F&& sg) { scale_getter = std::forward<F>(sg); }
52
53protected:
55 int get_iteration() const { return it_count; }
61 virtual double max_rel_diff() const = 0;
62
63private:
64 const Model* model{nullptr};
68 int it_count{0};
69 int max_it{40};
70 double accuracy_goal{1e-4};
71 double current_accuracy{std::numeric_limits<double>::infinity()};
72
73 double scale_difference() const;
74 double rel_scale_difference() const;
75 void run_to_scale();
76};
77
78template <class Model>
80(const Model* model_, double accuracy_goal_, const Scale_getter& sg)
82 , model(model_)
83 , scale_getter(sg)
84 , max_it(static_cast<int>(-log10(accuracy_goal_) * 10))
85 , accuracy_goal(accuracy_goal_)
86{
87 if (!model)
88 throw SetupError("Convergence_tester_DRbar<Model>: "
89 "model pointer must not be zero!");
90}
91
92template <class Model>
94{
95 current_model = *model;
96 bool precision_reached = false;
97
98 if (it_count > 0) {
99 run_to_scale();
100 const double scale_accuracy_goal = accuracy_goal * 16*Sqr(Pi);
101 if (rel_scale_difference() < scale_accuracy_goal) {
102 current_accuracy = max_rel_diff();
103 precision_reached = current_accuracy < accuracy_goal;
104 VERBOSE_MSG("Convergence_tester_DRbar: current accuracy = "
105 << current_accuracy
106 << ", accuracy goal = " << accuracy_goal);
107 } else {
108 VERBOSE_MSG("scale has changed by " << scale_difference()
109 << " GeV (" << rel_scale_difference()
110 << "), skipping parameter comparison");
111 }
112 }
113
114 // save old model parameters
115 last_iteration_model = current_model;
116 ++it_count;
117
118 return precision_reached;
119}
120
121template <class Model>
123{
124 return current_model.get_scale() - last_iteration_model.get_scale();
125}
126
127template <class Model>
129 const
130{
131 const double diff = scale_difference();
132 const double last_scale = last_iteration_model.get_scale();
133 if (!is_zero(last_scale))
134 return diff / last_scale;
135 return std::numeric_limits<double>::infinity();
136}
137
138template <class Model>
140{
141 if (scale_getter) {
142 const double scale = scale_getter();
143 current_model.run_to(scale);
144 current_model.calculate_DRbar_masses();
145 last_iteration_model.run_to(scale);
146 last_iteration_model.calculate_DRbar_masses();
147 }
148}
149
150template <class Model>
152{
153 it_count = 0;
154 current_model = Model();
155 last_iteration_model = Model();
156}
157
158} // namespace flexiblesusy
159
160#endif
Model last_iteration_model
model state at last iteration
void set_max_iterations(int it)
set maximum number of iterations
const Model & get_last_iteration_model() const
get model state during last iteration
Model current_model
model state at current iteration
double scale_difference() const
absolute scale difference
void run_to_scale()
runs models to comparison scale
const Model & get_current_iteration_model() const
get model at current iteration
double rel_scale_difference() const
relative scale difference
Scale_getter scale_getter
function to retrieve scale
virtual double max_rel_diff() const =0
maximum relative difference to last iteration
Convergence_tester_DRbar(const Model *, double, const Scale_getter &sg=Scale_getter())
int get_iteration() const
get current iteration number
Spectrum generator was not setup correctly.
Definition: error.hpp:46
#define VERBOSE_MSG(msg)
Definition: logger.hpp:57
std::enable_if_t< std::is_unsigned< T >::value, bool > is_zero(T a, T prec=std::numeric_limits< T >::epsilon()) noexcept
compares a number for being close to zero
Definition: numerics2.hpp:46
constexpr std::complex< T > Sqr(const std::complex< T > &a) noexcept
Definition: wrappers.hpp:631
static constexpr double Pi
Definition: wrappers.hpp:44