flexiblesusy is hosted by Hepforge, IPPP Durham
FlexibleSUSY
coupling_monitor.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
19#include "coupling_monitor.hpp"
20
21#include "error.hpp"
22#include "logger.hpp"
23
24#include <algorithm>
25#include <cmath>
26#include <fstream>
27#include <iomanip>
28#include <iostream>
29
30namespace flexiblesusy {
31
32namespace {
33
34const int column_width{16};
35
36struct Scale_comp {
37 bool operator() (const Coupling_monitor::Tuple& i,
38 const Coupling_monitor::Tuple& j) const {
39 return i.first < j.first;
40 }
41};
42
43} // anonymous namespace
44
46 const Data_getter& data_getter_,
47 const std::vector<std::string>& parameter_names_)
48 : data_getter(data_getter_), parameter_names(parameter_names_)
49{
50}
51
59{
60 if (couplings.empty()) {
61 ERROR("Data container is empty!");
62 return Tuple(0.0, Eigen::ArrayXd(1));
63 }
64
65 // find gauge couplings at the greatest scale
66 auto maxScale
67 = max_element(couplings.begin(), couplings.end(), Scale_comp());
68
69 return *maxScale;
70}
71
76{
77 couplings.clear();
78}
79
86{
87 if (!fout.good() || couplings.empty()) {
88 return;
89 }
90
91 fout << std::left << std::setw(column_width) << "scale";
92
93 for (const auto& p: parameter_names) {
94 fout << std::left << std::setw(column_width) << p;
95 }
96
97 fout << '\n';
98}
99
105void Coupling_monitor::write_comment_line(std::ostream& fout) const
106{
107 if (!fout.good() || couplings.empty())
108 return;
109
110 fout << std::left << std::setw(column_width) << "# [1] scale";
111
112 for (std::size_t i = 0; i < parameter_names.size(); ++i) {
113 fout << std::left << std::setw(column_width)
114 << '[' + std::to_string(i+2) + "] " + parameter_names[i];
115 }
116
117 fout << '\n';
118}
119
126void Coupling_monitor::write_to_file(const std::string& file_name, bool overwrite) const
127{
128 if (couplings.empty())
129 return;
130
131 const std::ios_base::openmode openmode
132 = (overwrite ? std::ios::out : std::ios::app);
133
134 std::ofstream filestr(file_name, openmode);
135 VERBOSE_MSG("Coupling_monitor<>::write_to_file: opening file: "
136 << file_name);
137 if (filestr.fail()) {
138 ERROR("can't open file " << file_name
139 << " for writing running couplings");
140 return;
141 }
142
143 write_comment_line(filestr);
145
146 // write data
147 for (const auto& c: couplings) {
148 if (!filestr.good()) {
149 ERROR("file " << file_name << " is corrupted");
150 break;
151 }
152
153 filestr << std::left << std::setw(column_width) << c.first;
154
155 // write all gauge couplings in order
156 for (int i = 0; i < c.second.size(); ++i) {
157 filestr << std::left << std::setw(column_width) << c.second(i);
158 }
159
160 filestr << '\n';
161 }
162
163 filestr.close();
164 VERBOSE_MSG("Coupling_monitor<>::write_to_file: file written: "
165 << file_name);
166}
167
177void Coupling_monitor::run(double q1, double q2,
178 int number_of_steps, bool include_endpoint)
179{
180 if (q1 <= 0.0 || q2 <= 0.0) {
181 ERROR("negative scales are not allowed: q1=" << q1 << ", q2=" << q2);
182 return;
183 }
184
185 if (number_of_steps < 1) {
186 number_of_steps = 1;
187 }
188
189 // if the endpoint should be included, the scale loop must run from
190 // (n == 0) to (n == number_of_steps); otherwise it runs from (n == 0) to (n
191 // == number_of_steps - 1)
192 const int endpoint_offset = include_endpoint ? 1 : 0;
193
194 // run from q1 to q2
195 for (int n = 0; n < number_of_steps + endpoint_offset; ++n) {
196 const double lq1 = std::log(q1);
197 const double lq2 = std::log(q2);
198 const double scale = std::exp(lq1 + n * (lq2 - lq1) / number_of_steps);
199 try {
200 couplings.emplace_back(scale, data_getter(scale));
201 } catch (const Error&) {
202 ERROR("Coupling_monitor::run: run to scale "
203 << scale << " failed");
204 break;
205 }
206 }
207
208 std::sort(couplings.begin(), couplings.end(), Scale_comp());
209}
210
211} // namespace flexiblesusy
void write_to_file(const std::string &, bool overwrite=true) const
write couplings to file
std::function< Eigen::ArrayXd(double)> Data_getter
function to return parameter values at given scale
void write_parameter_names_line(std::ostream &) const
write line with parameter names
void run(double, double, int number_of_steps=20, bool include_endpoint=false)
get couplings at all scales
std::vector< Tuple > couplings
all couplings at all scales
std::pair< double, Eigen::ArrayXd > Tuple
tuple of scale and couplings
Tuple get_max_scale() const
get maximum scale
Coupling_monitor(const Data_getter &, const std::vector< std::string > &)
void clear()
delete all saved couplings
std::vector< std::string > parameter_names
parameter names
Data_getter data_getter
returns parameters at given scale
void write_comment_line(std::ostream &) const
write a comment line
#define ERROR(msg)
Definition: logger.hpp:65
#define VERBOSE_MSG(msg)
Definition: logger.hpp:57
const int column_width
width of columns in output table
std::string to_string(char a)
Complex< T > log(const Complex< T > &z) noexcept
Definition: complex.hpp:54