forked from Expander/FlexibleSUSY
/
two_scale_solver.hpp
155 lines (138 loc) · 5.4 KB
/
two_scale_solver.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// ====================================================================
// This file is part of FlexibleSUSY.
//
// FlexibleSUSY is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// FlexibleSUSY is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with FlexibleSUSY. If not, see
// <http://www.gnu.org/licenses/>.
// ====================================================================
#ifndef TWO_SCALE_SOLVER_H
#define TWO_SCALE_SOLVER_H
#include "rg_flow.hpp"
#include <memory>
#include <vector>
#include <string>
/**
* @file two_scale_solver.hpp
* @brief contains the definition of the RGFlow<Two_scale> class
*/
namespace flexiblesusy {
class Convergence_tester;
class Initial_guesser;
class Model;
class Single_scale_constraint;
class Single_scale_matching;
class Two_scale;
class Two_scale_running_precision;
/**
* @class RGFlow<Two_scale>
* @brief Boundary condition solver (two-scale algorithm)
*
* This boundary condition solver uses the two-scale algorithm to
* solve the boundary value problem: It uses RG running to iteratively
* run the models to the boundary condition (constraint) scales and
* imposes the constraints.
*
* To add constraints use the add() function. Matching conditions are
* added using the add_upwards() or add_downwards() functions,
* depending on whether the low-scale model should be matched to the
* high-scale one (add_upwards()) or vice versa (add_downwards()).
* The added constraints and matching conditions are applied in their
* given order.
*/
template<>
class RGFlow<Two_scale> {
public:
RGFlow() = default;
RGFlow(const RGFlow&) = delete;
RGFlow(RGFlow&&) = delete;
~RGFlow() = default;
RGFlow& operator=(const RGFlow&) = delete;
RGFlow& operator=(RGFlow&&) = delete;
/// add constraint
void add(Single_scale_constraint*, Model*);
/// add matching condition
void add(Single_scale_matching*, Model*, Model*);
/// get model at current scale
Model* get_model() const;
/// get number of used iterations
unsigned int number_of_iterations_done() const;
/// clear all internal data
void reset();
/// run model at given scale to given scale
void run_to(double);
/// set convergence tester
void set_convergence_tester(Convergence_tester*);
/// set running precision calculator
void set_running_precision(Two_scale_running_precision*);
/// set initial guesser
void set_initial_guesser(Initial_guesser*);
/// solves the boundary value problem
void solve();
private:
struct Slider {
public:
virtual ~Slider() {}
virtual void clear_problems() {}
virtual Model* get_model() = 0;
virtual double get_scale() = 0;
virtual void slide() {}
virtual void set_precision(double) {}
};
struct Constraint_slider : public Slider {
public:
Constraint_slider(Model* m, Single_scale_constraint* c)
: model(m), constraint(c) {}
virtual ~Constraint_slider() {}
virtual void clear_problems() override;
virtual Model* get_model() override;
virtual double get_scale() override;
virtual void slide() override;
virtual void set_precision(double) override;
private:
Model* model;
Single_scale_constraint* constraint;
};
struct Matching_slider : public Slider {
public:
Matching_slider(Model* m1_, Model* m2_, Single_scale_matching* mc)
: m1(m1_), m2(m2_), matching(mc) {}
virtual ~Matching_slider() {}
virtual void clear_problems() override;
virtual Model* get_model() override;
virtual double get_scale() override;
virtual void slide() override;
virtual void set_precision(double) override;
private:
Model *m1, *m2;
Single_scale_matching* matching;
};
std::vector<std::shared_ptr<Slider> > sliders{}; ///< sliders to be run up and down
unsigned int iteration{0}; ///< iteration number (starting at 0)
Convergence_tester* convergence_tester{nullptr}; ///< the convergence tester
Initial_guesser* initial_guesser{nullptr}; ///< does initial guess
Two_scale_running_precision* running_precision_calculator{nullptr}; ///< RG running precision calculator
double running_precision{1.0e-3}; ///< RG running precision
double scale{0.}; ///< current scale
bool accuracy_goal_reached() const; ///< check if accuracy goal is reached
void check_setup() const; ///< check the setup
void clear_problems(); ///< clear model problems
unsigned int get_max_iterations() const; ///< returns max. number of iterations
Model* get_model(double) const; ///< returns model at given scale
double get_precision(); ///< returns running precision
void initial_guess(); ///< initial guess
void run_sliders(); ///< run all sliders
std::vector<std::shared_ptr<Slider> > sort_sliders() const; ///< sort the sliders w.r.t. to scale
void update_running_precision(); ///< update the RG running precision
};
}
#endif