flexiblesusy is hosted by Hepforge, IPPP Durham
FlexibleSUSY
semi_analytic_solver.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
20
22#include "error.hpp"
23#include "initial_guesser.hpp"
24#include "logger.hpp"
25#include "model.hpp"
29#include "two_scale_solver.hpp"
30
31#include <algorithm>
32
38namespace flexiblesusy {
39
47{
48 if (!c) throw SetupError("constraint pointer is NULL");
49 if (!m) throw SetupError("model pointer is NULL");
50 inner_sliders.push_back(std::make_shared<Constraint_slider>(m, c));
51}
52
64{
65 if (!mc) throw SetupError("matching condition pointer is NULL");
66 if (!m1) throw SetupError("model pointer 1 is NULL");
67 if (!m2) throw SetupError("model pointer 2 is NULL");
68 mc->set_models(m1, m2);
69 inner_sliders.push_back(std::make_shared<Matching_slider>(m1, m2, mc));
70}
71
79{
80 if (!c) throw SetupError("constraint pointer is NULL");
81 if (!m) throw SetupError("model pointer is NULL");
82 outer_sliders.push_back(std::make_shared<Constraint_slider>(m, c));
83}
84
96{
97 if (!mc) throw SetupError("matching condition pointer is NULL");
98 if (!m1) throw SetupError("model pointer 1 is NULL");
99 if (!m2) throw SetupError("model pointer 2 is NULL");
100 mc->set_models(m1, m2);
101 outer_sliders.push_back(std::make_shared<Matching_slider>(m1, m2, mc));
102}
103
118{
119 check_setup();
120
121 const int max_iterations = get_max_iterations();
122 if ((inner_sliders.empty() && outer_sliders.empty())
123 || max_iterations == 0)
124 return;
125
126 initial_guess();
127
128 iteration = 0;
129 bool accuracy_reached = false;
130 // flag for non-convergence in iteration
131 bool no_conv_inner_iteration = false;
132 RGFlow<Two_scale> inner_solver;
133 while (iteration < max_iterations && !accuracy_reached) {
134 update_running_precision();
135 // reset problem flags on each iteration step
136 clear_problems();
137 no_conv_inner_iteration = false;
138 prepare_inner_iteration(inner_solver);
139 try {
140 inner_solver.solve();
141 } catch (const NoConvergenceError&) {
142 no_conv_inner_iteration = true;
143 }
144 run_outer_sliders();
145 accuracy_reached = accuracy_goal_reached();
146 ++iteration;
147 }
148
149 if (!accuracy_reached || no_conv_inner_iteration)
150 throw NoConvergenceError(max_iterations);
151
152 VERBOSE_MSG("convergence reached after " << iteration << " iterations");
153}
154
159{
160 if (!inner_convergence_tester) {
161 throw SetupError("RGFlow<Semi_analytic>::Error: inner convergence tester must "
162 "not be NULL");
163 }
164 if (!outer_convergence_tester) {
165 throw SetupError("RGFlow<Semi_analytic>::Error: outer convergence tester must "
166 "not be NULL");
167 }
168}
169
171{
172 VERBOSE_MSG("> clearing problems ...");
173
174 for (auto& s: outer_sliders)
175 s->clear_problems();
176}
177
182{
183 inner_convergence_tester->restart();
184
185 solver.reset();
186 solver.set_convergence_tester(inner_convergence_tester);
187 solver.set_running_precision(running_precision_calculator);
188
189 for (auto& s: inner_sliders) {
190 s->clear_problems();
191 s->add_constraint_to_solver(solver);
192 }
193}
194
200{
201 if (initial_guesser)
202 initial_guesser->guess();
203}
204
206{
207 VERBOSE_MSG("> running all models (outer iteration " << iteration << ") ...");
208
209 for (auto& s: outer_sliders) {
210 s->set_precision(get_precision());
211 s->slide();
212 }
213
214 VERBOSE_MSG("> running outer sliders finished");
215}
216
223{
224 return running_precision;
225}
226
232{
233 if (running_precision_calculator)
234 running_precision = running_precision_calculator->get_precision(iteration);
235}
236
242{
243 return outer_convergence_tester->accuracy_goal_reached();
244}
245
252{
253 inner_convergence_tester = convergence_tester_;
254}
255
262{
263 outer_convergence_tester = convergence_tester_;
264}
265
267{
268 initial_guesser = ig;
269}
270
277{
278 running_precision_calculator = rp;
279}
280
286{
287 return iteration;
288}
289
295{
296 return outer_convergence_tester->max_iterations();
297}
298
306{
307 const std::vector<std::shared_ptr<Slider> > sorted_inner_sliders(sort_sliders(inner_sliders));
308 const std::vector<std::shared_ptr<Slider> > sorted_outer_sliders(sort_sliders(outer_sliders));
309 std::vector<std::shared_ptr<Slider> > sorted_sliders;
310 std::merge(sorted_inner_sliders.begin(), sorted_inner_sliders.end(),
311 sorted_outer_sliders.begin(), sorted_outer_sliders.end(),
312 std::back_inserter(sorted_sliders),
313 [](const std::shared_ptr<Slider>& s1,
314 const std::shared_ptr<Slider>& s2)
315 { return s1->get_scale() < s2->get_scale(); });
316
317 auto it = std::lower_bound(sorted_sliders.begin(), sorted_sliders.end(),
318 scale,
319 [](const std::shared_ptr<Slider>& s, double scale)
320 { return s->get_scale() < scale; });
321
322 if (it == sorted_sliders.end())
323 return nullptr;
324
325 return (*it)->get_model();
326}
327
333{
334 return get_model(scale);
335}
336
345{
346 inner_sliders.clear();
347 outer_sliders.clear();
348
349 iteration = 0;
350 inner_convergence_tester = nullptr;
351 outer_convergence_tester = nullptr;
352 initial_guesser = nullptr;
353 running_precision_calculator = nullptr;
354 running_precision = 1.0e-3;
355 scale = 0;
356}
357
363std::vector<std::shared_ptr<RGFlow<Semi_analytic>::Slider> > RGFlow<Semi_analytic>::sort_sliders(const std::vector<std::shared_ptr<RGFlow<Semi_analytic>::Slider> >& sliders) const
364{
365 std::vector<std::shared_ptr<Slider> > sorted_sliders(sliders);
366
367 std::sort(sorted_sliders.begin(), sorted_sliders.end(),
368 [](const std::shared_ptr<Slider>& s1, const std::shared_ptr<Slider>& s2)
369 { return s1->get_scale() < s2->get_scale(); });
370
371 return sorted_sliders;
372}
373
380{
381 scale = scale_;
382
383 Model* model = get_model();
384
385 if (model)
386 model->run_to(scale);
387}
388
389/* Implementation of sliders */
390
392 model->clear_problems();
393}
394
396 return model;
397}
398
400 RGFlow<Two_scale>& solver) {
401 solver.add(constraint, model);
402}
403
405 return constraint->get_scale();
406}
407
409 VERBOSE_MSG("> \trunning " << model->name() << " to scale " << constraint->get_scale() << " GeV");
410 model->run_to(constraint->get_scale());
411 VERBOSE_MSG("> \tapplying " << constraint->name());
412 constraint->apply();
413}
414
416 model->set_precision(p);
417}
418
420 m1->clear_problems();
421 m2->clear_problems();
422}
423
425 return m1;
426}
427
429 RGFlow<Two_scale>& solver) {
430 solver.add(matching, m1, m2);
431}
432
434 return matching->get_scale();
435}
436
438 VERBOSE_MSG("> \trunning " << m1->name() << " to scale " << matching->get_scale() << " GeV");
439 m1->run_to(matching->get_scale());
440 VERBOSE_MSG("> \trunning " << m2->name() << " to scale " << matching->get_scale() << " GeV");
441 m2->run_to(matching->get_scale());
442 VERBOSE_MSG("> \tmatching " << m1->name() << " -> " << m2->name());
443 matching->match();
444}
445
447 m1->set_precision(p);
448 m2->set_precision(p);
449}
450
451} // namespace flexiblesusy
virtual void run_to(double, double eps=-1.0)=0
No convergence while solving the RGEs.
Definition: error.hpp:57
Boundary condition solver (two-scale algorithm)
void solve()
solves the boundary value problem
void add(Single_scale_constraint *, Model *)
add constraint
void set_convergence_tester(Convergence_tester *)
set convergence tester
void set_running_precision(Two_scale_running_precision *)
set running precision calculator
void reset()
clear all internal data
Spectrum generator was not setup correctly.
Definition: error.hpp:46
#define VERBOSE_MSG(msg)
Definition: logger.hpp:57
const double mc
Definition: consts.hpp:104
contains the definition of the RGFlow<Semi_analytic> class
contains the definition of the RGFlow<Two_scale> class