flexiblesusy is hosted by Hepforge, IPPP Durham
FlexibleSUSY
decay.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 DECAY_H
20#define DECAY_H
21
22#include <algorithm>
23#include <initializer_list>
24#include <map>
25#include <string>
26#include <vector>
27
28#include <boost/core/demangle.hpp>
29
30#include "wrappers.hpp"
31#include "always_false.hpp"
32#include "cxx_qft/fields.hpp"
33#include "cxx_qft/vertices.hpp"
34
35namespace flexiblesusy {
36
37class Decay {
38public:
39
40template <typename T>
42 int pid_in_, std::initializer_list<int> pids_out_, double width_, T&& proc_string_)
43 : pid_in{pid_in_}
44 , pids_out{pids_out_}
45 , width{width_}
46 , proc_string{std::forward<T>(proc_string_)}
47 {
48 std::sort(pids_out.begin(), pids_out.end());
49 }
50 ~Decay() = default;
51 Decay(const Decay&) = default;
52 Decay(Decay&&) = default;
53 Decay& operator=(const Decay&) = default;
54 Decay& operator=(Decay&&) = default;
55
56 int get_initial_particle_id() const { return pid_in; }
57 const std::vector<int>& get_final_state_particle_ids() const {
58 return pids_out;
59 }
60 std::size_t get_final_state_size() const { return pids_out.size(); }
61
62 double get_width() const { return width; }
63 std::string get_proc_string() const { return proc_string; }
64 void set_width(double w) { width = w; }
65
66private:
67 int pid_in{0};
68 std::vector<int> pids_out{};
69 double width{0.};
70 std::string proc_string;
71};
72
74public:
75 std::string particle {};
76 int pdgid {};
77 double mass {};
78 double width {};
79 double width_sm {};
80 double invWidth {0.};
81 int CP {};
82 std::pair<std::string, std::complex<double>> dd {};
83 std::pair<std::string, std::complex<double>> uu {};
84 std::pair<std::string, std::complex<double>> ss {};
85 std::pair<std::string, std::complex<double>> cc {};
86 std::pair<std::string, std::complex<double>> bb {};
87 std::pair<std::string, std::complex<double>> tt {};
88 std::pair<std::string, std::complex<double>> ee {};
89 std::pair<std::string, std::complex<double>> mumu {};
90 std::pair<std::string, std::complex<double>> tautau {};
91 std::pair<std::string, std::complex<double>> emu {};
92 std::pair<std::string, std::complex<double>> etau {};
93 std::pair<std::string, std::complex<double>> mutau {};
94 std::pair<std::string, double> WW {};
95 std::pair<std::string, double> ZZ {};
96 std::pair<std::string, double> Zgam {};
97 std::pair<std::string, double> gamgam {};
98 std::pair<std::string, double> gg = {};
99 double lam {};
100 double undetectedWidth {0.};
101
102 double get_undetected_width() const { return undetectedWidth; }
103 void calculate_undetected_br(bool withTop) {
105 if (undetectedWidth < 0 && std::abs(undetectedWidth)/width < 1e-10) {
106 undetectedWidth = 0.;
107 }
108 }
109};
110
112public:
115
116 std::vector<NeutralHiggsEffectiveCouplings>::iterator begin() noexcept { return effective_coupling_list.begin(); }
117 std::vector<NeutralHiggsEffectiveCouplings>::const_iterator begin() const noexcept { return effective_coupling_list.begin(); }
118 std::vector<NeutralHiggsEffectiveCouplings>::const_iterator cbegin() const noexcept { return effective_coupling_list.cbegin(); }
119 std::vector<NeutralHiggsEffectiveCouplings>::iterator end() noexcept { return effective_coupling_list.end(); }
120 std::vector<NeutralHiggsEffectiveCouplings>::const_iterator end() const noexcept { return effective_coupling_list.end(); }
121 std::vector<NeutralHiggsEffectiveCouplings>::const_iterator cend() const noexcept { return effective_coupling_list.end(); }
122
124 return effective_coupling_list[index];
125 }
126
127 void add_coupling(std::string const&, std::array<int, 2> const&, std::pair<std::string, double> const&, double);
128 void add_coupling(std::string const&, std::array<int, 2> const&, std::pair<std::string, std::complex<double>> const&, double);
129 void set_invisible_width(std::string const& p, double);
131
132 std::size_t size() const noexcept { return effective_coupling_list.size(); }
133
134private:
135 std::vector<NeutralHiggsEffectiveCouplings> effective_coupling_list {};
136};
137
138std::size_t hash_decay(const Decay& decay);
139
141private:
142 /* map is slower than unordered_map but will preserve order of entries */
143 using List_type = std::map<std::size_t, Decay>;
144public:
145 using iterator = List_type::iterator;
146 using const_iterator = List_type::const_iterator;
147
148 explicit Decays_list(int);
149 ~Decays_list() = default;
150 Decays_list(const Decays_list&) = default;
154
155 iterator begin() noexcept { return decays.begin(); }
156 const_iterator begin() const noexcept { return decays.begin(); }
157 const_iterator cbegin() const noexcept { return decays.cbegin(); }
158 iterator end() noexcept { return decays.end(); }
159 const_iterator end() const noexcept { return decays.end(); }
160 const_iterator cend() const noexcept { return decays.end(); }
161
162 std::size_t size() const noexcept { return decays.size(); }
163
164 void clear();
165
166 template <typename T>
167 void set_decay(double width, std::initializer_list<int> pids_out, T&& proc_string)
168 {
169 const Decay decay(initial_pdg, pids_out, width, std::forward<T>(proc_string));
170 const auto decay_hash = hash_decay(decay);
171
172 const auto pos = decays.find(decay_hash);
173 if (pos != std::end(decays)) {
174 total_width -= pos->second.get_width();
175 pos->second.set_width(width);
176 } else {
177 decays.insert(pos, std::make_pair(decay_hash, std::move(decay)));
178 }
179
180 // some channels give small negative withs
181 // we later check if for channels with width < 0
182 // |width/total_width| < threshold
183 // for that it makes more sense to calculate total_width
184 // as the sum of |width|
185 total_width += std::abs(width);
186 }
187
188 int get_particle_id() const { return initial_pdg; }
189 const Decay& get_decay(std::initializer_list<int> products) const;
190 double get_total_width() const { return total_width; }
191
192private:
195 double total_width{0.};
196};
197
199std::vector<Decay> sort_decays_list(const Decays_list&);
200
201std::string strip_field_namespace(std::string const&);
202
203template<typename Field>
204std::string field_as_string(std::array<int, Field::numberOfFieldIndices> const& idx) {
205 const std::string field = strip_field_namespace(boost::core::demangle(typeid(Field).name()));
206 if constexpr (Field::numberOfFieldIndices == 0) {
207 return field;
208 }
209 else if constexpr (Field::numberOfFieldIndices == 1) {
210 // in the output we count particles from 1 (not 0)
211 return field + "(" + std::to_string(idx[0]+1) + ")";
212 }
213 else {
214 static_assert(always_false<Field>, "Field is expected to have 0 or 1 index");
215 }
216}
217
218template<typename FieldIn, typename FieldOut1, typename FieldOut2>
220 std::array<int, FieldIn::numberOfFieldIndices> const in,
221 std::array<int, FieldOut1::numberOfFieldIndices> const out1,
222 std::array<int, FieldOut2::numberOfFieldIndices> const out2) {
223
224 std::string process_string =
225 field_as_string<FieldIn>(in) + " -> " +
226 field_as_string<FieldOut1>(out1) + " " + field_as_string<FieldOut2>(out2);
227
228 return process_string;
229}
230
231// returns a squared color generator for a 3 point amplitude with FieldIn, FieldOut1 and FieldOut2
232// averaged over inital state colors
233// the generator is guessed from color representations of FieldIn, FieldOut1 and FieldOut2
234// This is not a bulletproof solution and might fail in general but is enough for
235// decays of color singlets
236
237template<typename FieldIn, typename FieldOut1, typename FieldOut2>
238constexpr double squared_color_generator() noexcept {
240 // 1 -> 1, 1
242 return 1.;
243 }
244 // 1 -> 3, -3
245 else if constexpr (
248 ) {
249 return 3.;
250 }
251 // 1 -> 8, 8
253 return 8.;
254 }
255 else {
256 static_assert(always_false<FieldIn, FieldOut1, FieldOut2>, "Unknow colour structure in decay");
257 }
258 }
260 // 3 -> 1, 3
261 if constexpr (
264 ) {
265 return 1.;
266 }
267 // 3 -> 3, 8
268 else if constexpr (
271 ) {
272 return 16/3.;
273 }
274 else {
275 static_assert(always_false<FieldIn, FieldOut1, FieldOut2>, "Unknow colour structure in decay");
276 }
277 }
279 // -3 -> 1, -3
280 if constexpr (
283 ) {
284 return 1.;
285 }
286 // -3 -> -3, 8
287 else if constexpr (
290 ) {
291 return 16/3.;
292 }
293 else {
294 static_assert(always_false<FieldIn, FieldOut1, FieldOut2>, "Unknow colour structure in decay");
295 }
296 }
298 // 8 -> 1, 8
299 if constexpr (
302 ) {
303 return 1.;
304 }
305 else if constexpr (
308 ) {
309 return 2.;
310 }
311 // 8 -> 8, 8 with identical particles in the final state
312 // because of symmetry of the final state it must be proportional to d^2
313 else if constexpr (
315 ) {
316 // color: d^2 = (2 (4 - 5 Nc^2 + Nc^4) TR)/Nc = 40/3
317 // average: 1/8
318 return 40/24.;
319 }
320 // 8 -> 8, 8 with differnt particles in the final state
321 else if constexpr (
323 ) {
324 // color: f^2 = 2 Nc (-1 + Nc^2) TR = 24
325 // average: 1/8
326 return 3.;
327 }
328 else {
329 static_assert(always_false<FieldIn, FieldOut1, FieldOut2>, "Unknow colour structure in decay");
330 }
331 }
332}
333
334template <typename Field1, typename Field2>
337{
338 if constexpr (!std::is_same_v<Field1, Field2>) {
339 return 1.;
340 }
341 else {
342 if (boost::range::equal(idx1, idx2)) {
343 return 0.5;
344 }
345 else {
346 return 1.;
347 }
348 }
349}
350
351// utility functions for H->V*V*
352double hVV_4body(double *q2, size_t dim, void *params);
354 double mHOS {};
355 double mVOS {};
356 double GammaV {};
357};
358
359enum PDG_id_pairs: int {
360 dd = 0,
361 uu = 1,
362 ss = 2,
363 cc = 3,
364 bb = 4,
365 tt = 5,
366 ee = 6,
367 mumu = 7,
369 WW = 9,
370 ZZ = 10,
371 gamgam = 11,
372 Zgam = 12,
373 gg = 13,
374 emu = 14,
375 etau = 15,
376 mutau = 16,
379
380} // namespace flexiblesusy
381
382#endif
std::string proc_string
Definition decay.hpp:70
Decay(const Decay &)=default
Decay(int pid_in_, std::initializer_list< int > pids_out_, double width_, T &&proc_string_)
Definition decay.hpp:41
std::vector< int > pids_out
Definition decay.hpp:68
void set_width(double w)
Definition decay.hpp:64
Decay & operator=(Decay &&)=default
Decay(Decay &&)=default
int get_initial_particle_id() const
Definition decay.hpp:56
const std::vector< int > & get_final_state_particle_ids() const
Definition decay.hpp:57
std::size_t get_final_state_size() const
Definition decay.hpp:60
std::string get_proc_string() const
Definition decay.hpp:63
Decay & operator=(const Decay &)=default
double get_width() const
Definition decay.hpp:62
const_iterator cbegin() const noexcept
Definition decay.hpp:157
void set_decay(double width, std::initializer_list< int > pids_out, T &&proc_string)
Definition decay.hpp:167
iterator begin() noexcept
Definition decay.hpp:155
const_iterator cend() const noexcept
Definition decay.hpp:160
iterator end() noexcept
Definition decay.hpp:158
List_type::const_iterator const_iterator
Definition decay.hpp:146
int get_particle_id() const
Definition decay.hpp:188
List_type::iterator iterator
Definition decay.hpp:145
const_iterator end() const noexcept
Definition decay.hpp:159
double get_total_width() const
Definition decay.hpp:190
Decays_list(const Decays_list &)=default
Decays_list(Decays_list &&)=default
const Decay & get_decay(std::initializer_list< int > products) const
Definition decay.cpp:87
const_iterator begin() const noexcept
Definition decay.hpp:156
std::map< std::size_t, Decay > List_type
Definition decay.hpp:143
Decays_list & operator=(Decays_list &&)=default
Decays_list & operator=(const Decays_list &)=default
std::size_t size() const noexcept
Definition decay.hpp:162
std::vector< NeutralHiggsEffectiveCouplings >::const_iterator cbegin() const noexcept
Definition decay.hpp:118
void push_back(NeutralHiggsEffectiveCouplings &&el)
Definition decay.hpp:130
std::vector< NeutralHiggsEffectiveCouplings >::const_iterator cend() const noexcept
Definition decay.hpp:121
NeutralHiggsEffectiveCouplings const & operator[](int index) const
Definition decay.hpp:123
std::vector< NeutralHiggsEffectiveCouplings >::const_iterator begin() const noexcept
Definition decay.hpp:117
std::vector< NeutralHiggsEffectiveCouplings > effective_coupling_list
Definition decay.hpp:135
void add_coupling(std::string const &, std::array< int, 2 > const &, std::pair< std::string, double > const &, double)
Definition decay.cpp:172
void set_invisible_width(std::string const &p, double)
Definition decay.cpp:156
std::vector< NeutralHiggsEffectiveCouplings >::iterator begin() noexcept
Definition decay.hpp:116
std::vector< NeutralHiggsEffectiveCouplings >::iterator end() noexcept
Definition decay.hpp:119
std::vector< NeutralHiggsEffectiveCouplings >::const_iterator end() const noexcept
Definition decay.hpp:120
std::size_t size() const noexcept
Definition decay.hpp:132
std::pair< std::string, std::complex< double > > tautau
Definition decay.hpp:90
std::pair< std::string, std::complex< double > > uu
Definition decay.hpp:83
std::pair< std::string, double > ZZ
Definition decay.hpp:95
std::pair< std::string, std::complex< double > > dd
Definition decay.hpp:82
std::pair< std::string, std::complex< double > > tt
Definition decay.hpp:87
std::pair< std::string, std::complex< double > > ee
Definition decay.hpp:88
std::pair< std::string, std::complex< double > > cc
Definition decay.hpp:85
std::pair< std::string, double > WW
Definition decay.hpp:94
std::pair< std::string, std::complex< double > > mumu
Definition decay.hpp:89
std::pair< std::string, std::complex< double > > mutau
Definition decay.hpp:93
std::pair< std::string, double > gamgam
Definition decay.hpp:97
std::pair< std::string, double > gg
Definition decay.hpp:98
std::pair< std::string, std::complex< double > > ss
Definition decay.hpp:84
std::pair< std::string, std::complex< double > > etau
Definition decay.hpp:92
std::pair< std::string, double > Zgam
Definition decay.hpp:96
std::pair< std::string, std::complex< double > > emu
Definition decay.hpp:91
std::pair< std::string, std::complex< double > > bb
Definition decay.hpp:86
std::string field_as_string(std::array< int, Field::numberOfFieldIndices > const &idx)
Definition decay.hpp:204
std::string strip_field_namespace(std::string const &s)
Definition decay.cpp:129
std::string create_process_string(std::array< int, FieldIn::numberOfFieldIndices > const in, std::array< int, FieldOut1::numberOfFieldIndices > const out1, std::array< int, FieldOut2::numberOfFieldIndices > const out2)
Definition decay.hpp:219
double final_state_symmetry_factor(typename cxx_diagrams::field_indices< Field1 >::type const &idx1, typename cxx_diagrams::field_indices< Field2 >::type const &idx2)
Definition decay.hpp:335
constexpr double squared_color_generator() noexcept
Definition decay.hpp:238
@ NUMBER_OF_PDG_IDS
Definition decay.hpp:377
double hVV_4body(double *q2, size_t, void *params)
Definition decay.cpp:142
std::vector< Decay > sort_decays_list(const Decays_list &decays_list)
sort decays w.r.t. their width
Definition decay.cpp:111
std::size_t hash_decay(const Decay &decay)
Definition decay.cpp:69
std::array< int, Field::numberOfFieldIndices > type
Definition fields.hpp:59