Himalaya
Himalaya_interface.cpp
Go to the documentation of this file.
1 // ====================================================================
2 // This file is part of Himalaya.
3 //
4 // Himalaya is licenced under the GNU General Public License (GNU GPL)
5 // version 3.
6 // ====================================================================
7 
9 
11 #include "himalaya/misc/Logger.hpp"
12 #include "himalaya/misc/Powers.hpp"
13 
14 #include <cmath>
15 #include <iostream>
16 #include <stdexcept>
17 #include <string>
18 #include <tuple>
19 #include <utility>
20 
21 #include <Eigen/Eigenvalues>
22 
23 /**
24  * @file Himalaya_interface.cpp
25  *
26  * @brief Definition of the helper functions for the MSSM input
27  * parameters
28  */
29 
30 namespace himalaya {
31 
32 namespace {
33 
34 int sign(double x) noexcept
35 {
36  return x >= 0. ? 1 : -1;
37 }
38 
39 double calc_cw2(double mW, double mZ) noexcept
40 {
41  const double cw2 = pow2(mW/mZ);
42  return std::isfinite(cw2) ? cw2 : 1.0;
43 }
44 
45 double calc_sw2(double mW, double mZ) noexcept
46 {
47  return 1.0 - calc_cw2(mW, mZ);
48 }
49 
50 double calc_v2(double vu, double vd) noexcept
51 {
52  return pow2(vu) + pow2(vd);
53 }
54 
55 double calc_cos2beta(double vu, double vd) noexcept
56 {
57  return (pow2(vd) - pow2(vu))/calc_v2(vu, vd);
58 }
59 
60 /// sorts two eigenvalues
61 void sort_ev(V2& ev, double& theta) noexcept
62 {
63  if (ev(0) > ev(1)) {
64  std::swap(ev(0), ev(1));
65  theta += 0.5*Pi;
66  }
67 }
68 
69 /// calculates mass eigenvalues (in GeV), sin(2*theta) and theta
70 std::tuple<V2,double,double> calculate_MSf_s2f(const RM22& M)
71 {
72  const Eigen::SelfAdjointEigenSolver<RM22> es(M);
73  RM22 ev = es.eigenvectors().real();
74  V2 ew = es.eigenvalues();
75 
76  if (ew.minCoeff() < 0.) {
77  throw std::runtime_error(
78  "DR sfermion masses are tachyonic: mst1^2 = " + std::to_string(ew(0))
79  + ", mst2^2 = " + std::to_string(ew(1)));
80  }
81 
82  ew = ew.unaryExpr([](double x){ return std::sqrt(x); });
83 
84  // extract mixing angle in the convention of hep-ph/0105096
85  double theta = 0.;
86 
87  if (sign(ev(0,0)) == sign(ev(1,1))) {
88  theta = std::acos(std::abs(ev(0,0)));
89  } else {
90  theta = std::acos(std::abs(ev(0,1)));
91  ev.col(0).swap(ev.col(1));
92  std::swap(ew(0), ew(1));
93  }
94 
95  theta = sign(M(0,1) / (M(0,0) - M(1,1))) * std::abs(theta);
96 
97  sort_ev(ew, theta);
98 
99  return std::make_tuple(ew, std::sin(2 * theta), theta);
100 }
101 
102 RM33 h_svd(const RM33& M)
103 {
104  Eigen::JacobiSVD<RM33> svd(M);
105  return svd.singularValues().reverse().asDiagonal();
106 }
107 
108 } // anonymous namespace
109 
111 {
112  const double cos_2beta = calc_cos2beta(vu, vd);
113  const double sw2 = calc_sw2(MW, MZ);
114  const double msq2 = std::pow(
115  mq2(0,0)*mu2(0,0) // sup L, sup R
116  *mq2(0,0)*md2(0,0) // sdown L, sdown R
117  *mq2(1,1)*mu2(1,1) // scharm L, scharm R
118  *mq2(1,1)*md2(1,1) // sstrange L, sstrange R
119  *(mq2(2, 2) + pow2(Mb) - (0.5 - sw2/3) * pow2(MZ) * cos_2beta) // sbottom L
120  *(md2(2, 2) + pow2(Mb) - sw2/3 * pow2(MZ) * cos_2beta), // sbottom R
121  0.1);
122 
123  return msq2;
124 }
125 
126 /**
127  * Checks if the stop/sbottom masses and mixing angles are provided. Otherwise calculate them.
128  * Checks if the stop/sbottom masses are ordered in the right way. If these masses are wrongly ordered
129  * the right ordering will be introduced.
130  * Checks if the stops/sbottom masses are degenerated and introduce a small shift to the 1st stop/sbottom mass in this case.
131  * @param verbose a bool which suppresses the information of the calculation if set to flase
132  */
134 {
135  // check if soft-breaking parameters are greater than zero
136  if (mq2.minCoeff() < 0. || md2.minCoeff() < 0. || mu2.minCoeff() < 0. ||
137  ml2.minCoeff() < 0. || me2.minCoeff() < 0.) {
138  throw std::runtime_error(
139  "Soft-breaking squared sfermion mass parameters "
140  "must be greater than zero!");
141  }
142 
143  // The implemented 2- and 3-loop contributions assumed that M3 > 0.
144  // For this reason the gluino phase factor is absent from the
145  // expressions (i.e. has always been set to 1) and cannot be
146  // adjusted in case M3 < 0.
147  if (MG < 0.) {
148  throw std::runtime_error("Gluino mass parameter must not be negative!");
149  }
150 
151  // force gluino mass to be positive
152  MG = std::abs(MG);
153 
154  // diagonalize all yukawa matrices
155  Yu = h_svd(Yu);
156  Yd = h_svd(Yd);
157  Ye = h_svd(Ye);
158 
159  if (std::isnan(vu) || vu <= 0.) {
160  throw std::runtime_error("Invalid value of vu given!");
161  }
162 
163  if (std::isnan(vd) || vd <= 0.) {
164  throw std::runtime_error("Invalid value of vd given!");
165  }
166 
167  // calculate all other masses
168  if (std::isnan(MW)) {
169  MW = 0.5*g2*std::sqrt(calc_v2(vu, vd));
170  }
171  if (std::isnan(MZ)) {
172  MZ = 0.5*std::sqrt((0.6*pow2(g1) + pow2(g2))*calc_v2(vu, vd));
173  }
174  if (std::isnan(Mt)) {
175  Mt = inv_sqrt2*Yu(2,2)*vu;
176  }
177  if (std::isnan(Mb)) {
178  Mb = inv_sqrt2*Yd(2,2)*vd;
179  }
180  if (std::isnan(Mtau)) {
181  Mtau = inv_sqrt2*Ye(2,2)*vd;
182  }
183 
184  // check if stop/sbottom masses and/or mixing angles are nan. If so, calculate these quantities.
185  if (std::isnan(MSt(0)) || std::isnan(MSt(1)) || std::isnan(s2t) || std::isnan(theta_t)) {
186  const double tan_beta = vu / vd;
187  const double cos_2beta = calc_cos2beta(vu, vd);
188  const double Xt = Mt * (Au(2,2) - mu / tan_beta);
189  const double sw2 = calc_sw2(MW, MZ);
190  RM22 stopMatrix;
191  stopMatrix << mq2(2, 2) + pow2(Mt) + (0.5 - 2*sw2/3) * pow2(MZ) * cos_2beta, Xt,
192  Xt, mu2(2, 2) + pow2(Mt) + 2*sw2/3 * pow2(MZ) * cos_2beta;
193 
194  std::tie(MSt, s2t, theta_t) = calculate_MSf_s2f(stopMatrix);
195 
196  if (verbose) {
197  INFO_MSG("Stop masses or mixing angle not provided. Calculated values:\n" <<
198  "\tstop masses: " << MSt(0) << " GeV, " << MSt(1) << " GeV,\n" <<
199  "\tmixing angle sin(2*theta_t) = " << s2t << ", theta_t = " << theta_t);
200  }
201  }
202 
203  if (std::isnan(MSb(0)) || std::isnan(MSb(1)) || std::isnan(s2b) || std::isnan(theta_b)) {
204  const double tan_beta = vu / vd;
205  const double cos_2beta = calc_cos2beta(vu, vd);
206  const double Xb = Mb * (Ad(2,2) - mu * tan_beta);
207  const double sw2 = calc_sw2(MW, MZ);
208  RM22 sbottomMatrix;
209  sbottomMatrix << mq2(2, 2) + pow2(Mb) - (0.5 - sw2/3) * pow2(MZ) * cos_2beta, Xb,
210  Xb, md2(2, 2) + pow2(Mb) - sw2/3 * pow2(MZ) * cos_2beta;
211 
212  std::tie(MSb, s2b, theta_b) = calculate_MSf_s2f(sbottomMatrix);
213 
214  if (verbose) {
215  INFO_MSG("Sbottom masses or mixing angle not provided. Calculated values:\n" <<
216  "\tsbottom masses: " << MSb(0) << " GeV, " << MSb(1) << " GeV,\n" <<
217  "\tmixing angle sin(2*theta_b) = " << s2b << ", theta_b = " << theta_b);
218  }
219  }
220 
221  if (std::isnan(MStau(0)) || std::isnan(MStau(1)) || std::isnan(s2tau) || std::isnan(theta_tau)) {
222  const double tan_beta = vu / vd;
223  const double cos_2beta = calc_cos2beta(vu, vd);
224  const double Xtau = Mtau * (Ae(2,2) - mu * tan_beta);
225  const double sw2 = calc_sw2(MW, MZ);
226  RM22 stauMatrix;
227  stauMatrix << ml2(2, 2) + pow2(Mtau) - (0.5 - sw2) * pow2(MZ) * cos_2beta, Xtau,
228  Xtau, me2(2, 2) + pow2(Mtau) - sw2 * pow2(MZ) * cos_2beta;
229 
230  std::tie(MStau, s2tau, theta_tau) = calculate_MSf_s2f(stauMatrix);
231 
232  if (verbose) {
233  INFO_MSG("Stau masses or mixing angle not provided. Calculated values:\n" <<
234  "\tstau masses: " << MStau(0) << " GeV, " << MStau(1) << " GeV,\n" <<
235  "\tmixing angle sin(2*theta_tau) = " << s2tau << ", theta_tau = " << theta_tau);
236  }
237  }
238 
239  // sort stops/sbottoms/staus
240  sort_ev(MSt, s2t);
241  sort_ev(MSb, s2b);
242  sort_ev(MStau, s2tau);
243 
244  // check if the stop/sbottom masses are degenerated. If this is the
245  // case one could get spurious poles in Pietro's code. To avoid
246  // this numerical issue we shift the stop/bottom 1 mass by a
247  // relative (but small) value.
248  const double eps = 1e-8;
249 
250  if (std::abs(MSt(0) - MSt(1)) < eps) {
251  MSt(0) = MSt(1) / (1. + eps);
252  }
253 
254  if (std::abs(MSb(0) - MSb(1)) < eps) {
255  MSb(0) = MSb(0) / (1. + eps);
256  }
257 
258  if (std::abs(mq2(2, 2) - mu2(2, 2)) < eps) {
259  mq2(2,2) = mu2(2,2) / (1. + eps);
260  }
261 }
262 
263 std::ostream& operator<<(std::ostream& ostr, const Parameters& pars)
264 {
265  ostr << "Himalaya parameters\n"
266  << "===================\n"
267  << "scale = " << pars.scale << '\n'
268  << "mu = " << pars.mu << '\n'
269  << "g1 = " << pars.g1 << '\n'
270  << "g2 = " << pars.g2 << '\n'
271  << "g3 = " << pars.g3 << '\n'
272  << "vd = " << pars.vd << '\n'
273  << "vu = " << pars.vu << '\n'
274  << "mq2 = {{" << pars.mq2(0,0) << ", " << pars.mq2(0,1) << ", " << pars.mq2(0,2) << "}, "
275  "{" << pars.mq2(1,0) << ", " << pars.mq2(1,1) << ", " << pars.mq2(1,2) << "}, "
276  "{" << pars.mq2(2,0) << ", " << pars.mq2(2,1) << ", " << pars.mq2(2,2) << "}}\n"
277  << "md2 = {{" << pars.md2(0,0) << ", " << pars.md2(0,1) << ", " << pars.md2(0,2) << "}, "
278  "{" << pars.md2(1,0) << ", " << pars.md2(1,1) << ", " << pars.md2(1,2) << "}, "
279  "{" << pars.md2(2,0) << ", " << pars.md2(2,1) << ", " << pars.md2(2,2) << "}}\n"
280  << "mu2 = {{" << pars.mu2(0,0) << ", " << pars.mu2(0,1) << ", " << pars.mu2(0,2) << "}, "
281  "{" << pars.mu2(1,0) << ", " << pars.mu2(1,1) << ", " << pars.mu2(1,2) << "}, "
282  "{" << pars.mu2(2,0) << ", " << pars.mu2(2,1) << ", " << pars.mu2(2,2) << "}}\n"
283  << "ml2 = {{" << pars.ml2(0,0) << ", " << pars.ml2(0,1) << ", " << pars.ml2(0,2) << "}, "
284  "{" << pars.ml2(1,0) << ", " << pars.ml2(1,1) << ", " << pars.ml2(1,2) << "}, "
285  "{" << pars.ml2(2,0) << ", " << pars.ml2(2,1) << ", " << pars.ml2(2,2) << "}}\n"
286  << "me2 = {{" << pars.me2(0,0) << ", " << pars.me2(0,1) << ", " << pars.me2(0,2) << "}, "
287  "{" << pars.me2(1,0) << ", " << pars.me2(1,1) << ", " << pars.me2(1,2) << "}, "
288  "{" << pars.me2(2,0) << ", " << pars.me2(2,1) << ", " << pars.me2(2,2) << "}}\n"
289  << "Au = {{" << pars.Au(0,0) << ", " << pars.Au(0,1) << ", " << pars.Au(0,2) << "}, "
290  "{" << pars.Au(1,0) << ", " << pars.Au(1,1) << ", " << pars.Au(1,2) << "}, "
291  "{" << pars.Au(2,0) << ", " << pars.Au(2,1) << ", " << pars.Au(2,2) << "}}\n"
292  << "Ad = {{" << pars.Ad(0,0) << ", " << pars.Ad(0,1) << ", " << pars.Ad(0,2) << "}, "
293  "{" << pars.Ad(1,0) << ", " << pars.Ad(1,1) << ", " << pars.Ad(1,2) << "}, "
294  "{" << pars.Ad(2,0) << ", " << pars.Ad(2,1) << ", " << pars.Ad(2,2) << "}}\n"
295  << "Ae = {{" << pars.Ae(0,0) << ", " << pars.Ae(0,1) << ", " << pars.Ae(0,2) << "}, "
296  "{" << pars.Ae(1,0) << ", " << pars.Ae(1,1) << ", " << pars.Ae(1,2) << "}, "
297  "{" << pars.Ae(2,0) << ", " << pars.Ae(2,1) << ", " << pars.Ae(2,2) << "}}\n"
298  << "Yu = {{" << pars.Yu(0,0) << ", " << pars.Yu(0,1) << ", " << pars.Yu(0,2) << "}, "
299  "{" << pars.Yu(1,0) << ", " << pars.Yu(1,1) << ", " << pars.Yu(1,2) << "}, "
300  "{" << pars.Yu(2,0) << ", " << pars.Yu(2,1) << ", " << pars.Yu(2,2) << "}}\n"
301  << "Yd = {{" << pars.Yd(0,0) << ", " << pars.Yd(0,1) << ", " << pars.Yd(0,2) << "}, "
302  "{" << pars.Yd(1,0) << ", " << pars.Yd(1,1) << ", " << pars.Yd(1,2) << "}, "
303  "{" << pars.Yd(2,0) << ", " << pars.Yd(2,1) << ", " << pars.Yd(2,2) << "}}\n"
304  << "Ye = {{" << pars.Ye(0,0) << ", " << pars.Ye(0,1) << ", " << pars.Ye(0,2) << "}, "
305  "{" << pars.Ye(1,0) << ", " << pars.Ye(1,1) << ", " << pars.Ye(1,2) << "}, "
306  "{" << pars.Ye(2,0) << ", " << pars.Ye(2,1) << ", " << pars.Ye(2,2) << "}}\n"
307  << "M1 = " << pars.M1 << '\n'
308  << "M2 = " << pars.M2 << '\n'
309  << "MG = " << pars.MG << '\n'
310  << "MW = " << pars.MW << '\n'
311  << "MZ = " << pars.MZ << '\n'
312  << "Mt = " << pars.Mt << '\n'
313  << "Mb = " << pars.Mb << '\n'
314  << "Mtau = " << pars.Mtau << '\n'
315  << "MA = " << pars.MA << '\n'
316  << "MSt = {" << pars.MSt(0) << ", " << pars.MSt(1) << "}\n"
317  << "MSb = {" << pars.MSb(0) << ", " << pars.MSb(1) << "}\n"
318  << "MStau = {" << pars.MStau(0) << ", " << pars.MStau(1) << "}\n"
319  << "s2t = " << pars.s2t << '\n'
320  << "s2b = " << pars.s2b << '\n'
321  << "s2tau = " << pars.s2tau << '\n';
322 
323  return ostr;
324 }
325 
326 } // namespace himalaya
double vu
VEV of up Higgs, with v = Sqrt[vu^2 + vd^2] ~ 246 GeV.
Definition: H3.cpp:14
RM33 Yu
up-type yukawa coupling matrix
RM33 Ad
trilinear down type squark-Higgs coupling matrix
void validate(bool verbose)
validates the parameter set
double vd
VEV of down Higgs, with v = Sqrt[vu^2 + vd^2] ~ 246 GeV.
Definition of the MSSM input parameters.
double g2
gauge coupling g2
double theta_tau
stau mixing angle
double theta_t
stop mixing angle
RM33 Ae
trilinear electron type squark-Higgs coupling matrix
Implementation of logging macros.
void svd(const Eigen::Matrix< Scalar, M, N > &m, Eigen::Array< Real, MIN_(M, N), 1 > &s, Eigen::Matrix< Scalar, M, M > &u, Eigen::Matrix< Scalar, N, N > &vh)
Definition: Linalg.hpp:287
double s2b
sine of 2 times the sbottom mixing angle
RM33 ml2
soft-breaking squared left-handed slepton mass parameters
double Mtau
tau lepton
double s2t
sine of 2 times the stop mixing angle
double mu
mu parameter, convention of [Phys.Rept. 117 (1985) 75-263]
double calculateMsq2() const
calculates average light squark mass squared
RM33 mq2
soft-breaking squared left-handed squark mass parameters
RM33 Yd
down-type yukawa coupling matrix
RM33 mu2
soft-breaking squared right-handed up-squark mass parameters
double theta_b
sbottom mixing angle
Eigen::Matrix3d RM33
real 3x3 matrix
double scale
renormalization scale
RM33 md2
soft-breaking squared right-handed down-squark mass parameters
double MA
CP-odd Higgs.
double g3
gauge coupling g3 SU(3)
double g1
GUT-normalized gauge coupling g1, with gY = g1*Sqrt[3/5].
std::ostream & operator<<(std::ostream &ostr, const HierarchyObject &ho)
double s2tau
sine of 2 times the stau mixing angle
Eigen::Matrix2d RM22
real 2x2 matrix
Definition: Linalg.hpp:1521
RM33 Ye
electron-type yukawa coupling matrix
#define INFO_MSG(message)
Definition: Logger.hpp:65
Eigen::Vector2d V2
real 2-vector
Definition: Linalg.hpp:1520
RM33 me2
soft-breaking squared right-handed slepton mass parameters
RM33 Au
trilinear up type squark-Higgs coupling matrix