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 <initializer_list>
23#include <map>
24#include <vector>
25#include <string>
26
27#include <boost/core/demangle.hpp>
28#include <boost/range/algorithm/equal.hpp>
29
30#include "always_false.hpp"
31#include "cxx_qft/fields.hpp"
32
33namespace flexiblesusy {
34
35class Decay {
36public:
37
38template <typename T>
40 int pid_in_, std::initializer_list<int> pids_out_, double width_, T&& proc_string_)
41 : pid_in{pid_in_}
42 , pids_out{pids_out_}
43 , width{width_}
44 , proc_string{std::forward<T>(proc_string_)}
45 {
46 std::sort(pids_out.begin(), pids_out.end());
47 }
48 ~Decay() = default;
49 Decay(const Decay&) = default;
50 Decay(Decay&&) = default;
51 Decay& operator=(const Decay&) = default;
52 Decay& operator=(Decay&&) = default;
53
54 int get_initial_particle_id() const { return pid_in; }
55 const std::vector<int>& get_final_state_particle_ids() const {
56 return pids_out;
57 }
58 std::size_t get_final_state_size() const { return pids_out.size(); }
59
60 double get_width() const { return width; }
61 std::string get_proc_string() const { return proc_string; }
62 void set_width(double w) { width = w; }
63
64private:
65 int pid_in{0};
66 std::vector<int> pids_out{};
67 double width{0.};
68 std::string proc_string;
69};
70
71std::size_t hash_decay(const Decay& decay);
72
74private:
75 /* map is slower than unordered_map but will preserve order of entries */
76 using List_type = std::map<std::size_t, Decay>;
77public:
78 using iterator = List_type::iterator;
79 using const_iterator = List_type::const_iterator;
80
81 explicit Decays_list(int);
82 ~Decays_list() = default;
83 Decays_list(const Decays_list&) = default;
85 Decays_list& operator=(const Decays_list&) = default;
87
88 iterator begin() noexcept { return decays.begin(); }
89 const_iterator begin() const noexcept { return decays.begin(); }
90 const_iterator cbegin() const noexcept { return decays.cbegin(); }
91 iterator end() noexcept { return decays.end(); }
92 const_iterator end() const noexcept { return decays.end(); }
93 const_iterator cend() const noexcept { return decays.end(); }
94
95 std::size_t size() const noexcept { return decays.size(); }
96
97 void clear();
98
99 template <typename T>
100 void set_decay(double width, std::initializer_list<int> pids_out, T&& proc_string)
101 {
102 const Decay decay(initial_pdg, pids_out, width, std::forward<T>(proc_string));
103 const auto decay_hash = hash_decay(decay);
104
105 const auto pos = decays.find(decay_hash);
106 if (pos != std::end(decays)) {
107 total_width -= pos->second.get_width();
108 pos->second.set_width(width);
109 } else {
110 decays.insert(pos, std::make_pair(decay_hash, decay));
111 }
112
113 // some channels give small negative withs
114 // we later check if for channels with width < 0
115 // |width/total_width| < threshold
116 // for that it makes more sense to calculate total_width
117 // as the sum of |width|
118 total_width += std::abs(width);
119 }
120
121 int get_particle_id() const { return initial_pdg; }
122 const Decay& get_decay(std::initializer_list<int> products) const;
123 double get_total_width() const { return total_width; }
124
125private:
128 double total_width{0.};
129};
130
132std::vector<Decay> sort_decays_list(const Decays_list&);
133
134std::string strip_field_namespace(std::string const&);
135
136template<typename Field>
137std::string field_as_string(std::array<int, Field::numberOfFieldIndices> const& idx) {
138 const std::string field = strip_field_namespace(boost::core::demangle(typeid(Field).name()));
139 if constexpr (Field::numberOfFieldIndices == 0) {
140 return field;
141 }
142 else if constexpr (Field::numberOfFieldIndices == 1) {
143 // in the output we count particles from 1 (not 0)
144 return field + "(" + std::to_string(idx[0]+1) + ")";
145 }
146 else {
147 static_assert(always_false<Field>, "Field is expected to have 0 or 1 index");
148 }
149}
150
151template<typename FieldIn, typename FieldOut1, typename FieldOut2>
153 std::array<int, FieldIn::numberOfFieldIndices> const in,
154 std::array<int, FieldOut1::numberOfFieldIndices> const out1,
155 std::array<int, FieldOut2::numberOfFieldIndices> const out2) {
156
157 std::string process_string =
158 field_as_string<FieldIn>(in) + " -> " +
159 field_as_string<FieldOut1>(out1) + " " + field_as_string<FieldOut2>(out2);
160
161 return process_string;
162}
163
164// returns a squared color generator for a 3 point amplitude with FieldIn, FieldOut1 and FieldOut2
165// averaged over inital state colors
166// the generator is guessed from color representations of FieldIn, FieldOut1 and FieldOut2
167// This is not a bulletproof solution and might fail in general but is enough for
168// decays of color singlets
169
170template<typename FieldIn, typename FieldOut1, typename FieldOut2>
171constexpr double squared_color_generator() noexcept {
172 if constexpr (cxx_diagrams::fields::is_singlet_v<FieldIn>) {
173 // 1 -> 1, 1
174 if constexpr (cxx_diagrams::fields::is_singlet_v<FieldOut1> && cxx_diagrams::fields::is_singlet_v<FieldOut2>) {
175 return 1.;
176 }
177 // 1 -> 3, -3
178 else if constexpr (
179 (cxx_diagrams::fields::is_triplet_v<FieldOut1> && cxx_diagrams::fields::is_anti_triplet_v<FieldOut2>)
180 || (cxx_diagrams::fields::is_anti_triplet_v<FieldOut1> && cxx_diagrams::fields::is_triplet_v<FieldOut2>)
181 ) {
182 return 3.;
183 }
184 // 1 -> 8, 8
185 else if constexpr (cxx_diagrams::fields::is_octet_v<FieldOut1> && cxx_diagrams::fields::is_octet_v<FieldOut2>) {
186 return 8.;
187 }
188 else {
189 static_assert(always_false<FieldIn, FieldOut1, FieldOut2>, "Unknow colour structure in decay");
190 }
191 }
192 else if constexpr (cxx_diagrams::fields::is_triplet_v<FieldIn>) {
193 // 3 -> 1, 3
194 if constexpr (
195 (cxx_diagrams::fields::is_triplet_v<FieldOut1> && cxx_diagrams::fields::is_singlet_v<FieldOut2>)
196 || (cxx_diagrams::fields::is_singlet_v<FieldOut1> && cxx_diagrams::fields::is_triplet_v<FieldOut2>)
197 ) {
198 return 1.;
199 }
200 // 3 -> 3, 8
201 else if constexpr (
202 (cxx_diagrams::fields::is_triplet_v<FieldIn> && cxx_diagrams::fields::is_octet_v<FieldOut2>)
203 || (cxx_diagrams::fields::is_octet_v<FieldOut1> && cxx_diagrams::fields::is_triplet_v<FieldOut2>)
204 ) {
205 return 4.;
206 }
207 else {
208 static_assert(always_false<FieldIn, FieldOut1, FieldOut2>, "Unknow colour structure in decay");
209 }
210 }
211 else if constexpr (cxx_diagrams::fields::is_anti_triplet_v<FieldIn>) {
212 // -3 -> 1, -3
213 if constexpr (
214 (cxx_diagrams::fields::is_anti_triplet_v<FieldOut1> && cxx_diagrams::fields::is_singlet_v<FieldOut2>)
215 || (cxx_diagrams::fields::is_singlet_v<FieldOut1> && cxx_diagrams::fields::is_anti_triplet_v<FieldOut2>)
216 ) {
217 return 1.;
218 }
219 // -3 -> -3, 8
220 else if constexpr (
221 (cxx_diagrams::fields::is_anti_triplet_v<FieldIn> && cxx_diagrams::fields::is_octet_v<FieldOut2>)
222 || (cxx_diagrams::fields::is_octet_v<FieldOut1> && cxx_diagrams::fields::is_anti_triplet_v<FieldOut2>)
223 ) {
224 return 4.;
225 }
226 else {
227 static_assert(always_false<FieldIn, FieldOut1, FieldOut2>, "Unknow colour structure in decay");
228 }
229 }
230 else if constexpr (cxx_diagrams::fields::is_octet_v<FieldIn>) {
231 // 8 -> 1, 8
232 if constexpr (
233 (cxx_diagrams::fields::is_octet_v<FieldOut1> && cxx_diagrams::fields::is_singlet_v<FieldOut2>)
234 || (cxx_diagrams::fields::is_singlet_v<FieldOut1> && cxx_diagrams::fields::is_octet_v<FieldOut2>)
235 ) {
236 return 1.;
237 }
238 else if constexpr (
239 (cxx_diagrams::fields::is_triplet_v<FieldOut1> && cxx_diagrams::fields::is_anti_triplet_v<FieldOut2>)
240 || (cxx_diagrams::fields::is_anti_triplet_v<FieldOut1> && cxx_diagrams::fields::is_triplet_v<FieldOut2>)
241 ) {
242 return 1./2.;
243 }
244 // 8 -> 8, 8 with identical particles in the final state
245 // because of symmetry of the final state it must be proportional to d^2
246 else if constexpr (
247 cxx_diagrams::fields::is_octet_v<FieldOut1> && cxx_diagrams::fields::is_octet_v<FieldOut2> && std::is_same_v<FieldOut1, FieldOut2>
248 ) {
249 // color: d^2 = (2 (4 - 5 Nc^2 + Nc^4) TR)/Nc = 40/3
250 // average: 1/8
251 return 40/24.;
252 }
253 // 8 -> 8, 8 with differnt particles in the final state
254 else if constexpr (
255 cxx_diagrams::fields::is_octet_v<FieldOut1> && cxx_diagrams::fields::is_octet_v<FieldOut2> && !std::is_same_v<FieldOut1, FieldOut2>
256 ) {
257 // color: f^2 = 2 Nc (-1 + Nc^2) TR = 24
258 // average: 1/8
259 return 3.;
260 }
261 else {
262 static_assert(always_false<FieldIn, FieldOut1, FieldOut2>, "Unknow colour structure in decay");
263 }
264 }
265}
266
267template <typename Field1, typename Field2>
270{
271 if constexpr (!std::is_same_v<Field1, Field2>) {
272 return 1.;
273 }
274 else {
275 if (boost::range::equal(idx1, idx2)) {
276 return 0.5;
277 }
278 else {
279 return 1.;
280 }
281 }
282}
283
284// utility functions for H->V*V*
285double hVV_4body(double *q2, size_t dim, void *params);
287 double mHOS {};
288 double mVOS {};
289 double GammaV {};
290};
291
292} // namespace flexiblesusy
293
294#endif
std::string proc_string
Definition: decay.hpp:68
Decay(const Decay &)=default
Decay(int pid_in_, std::initializer_list< int > pids_out_, double width_, T &&proc_string_)
Definition: decay.hpp:39
std::vector< int > pids_out
Definition: decay.hpp:66
void set_width(double w)
Definition: decay.hpp:62
Decay & operator=(Decay &&)=default
Decay(Decay &&)=default
int get_initial_particle_id() const
Definition: decay.hpp:54
const std::vector< int > & get_final_state_particle_ids() const
Definition: decay.hpp:55
std::size_t get_final_state_size() const
Definition: decay.hpp:58
std::string get_proc_string() const
Definition: decay.hpp:61
Decay & operator=(const Decay &)=default
double get_width() const
Definition: decay.hpp:60
const_iterator cbegin() const noexcept
Definition: decay.hpp:90
void set_decay(double width, std::initializer_list< int > pids_out, T &&proc_string)
Definition: decay.hpp:100
iterator begin() noexcept
Definition: decay.hpp:88
const_iterator cend() const noexcept
Definition: decay.hpp:93
iterator end() noexcept
Definition: decay.hpp:91
List_type::const_iterator const_iterator
Definition: decay.hpp:79
int get_particle_id() const
Definition: decay.hpp:121
List_type::iterator iterator
Definition: decay.hpp:78
const_iterator end() const noexcept
Definition: decay.hpp:92
double get_total_width() const
Definition: decay.hpp:123
Decays_list(const Decays_list &)=default
Decays_list(Decays_list &&)=default
const Decay & get_decay(std::initializer_list< int > products) const
Definition: decay.cpp:67
const_iterator begin() const noexcept
Definition: decay.hpp:89
std::map< std::size_t, Decay > List_type
Definition: decay.hpp:76
Decays_list & operator=(Decays_list &&)=default
Decays_list & operator=(const Decays_list &)=default
std::size_t size() const noexcept
Definition: decay.hpp:95
std::string field_as_string(std::array< int, Field::numberOfFieldIndices > const &idx)
Definition: decay.hpp:137
std::string strip_field_namespace(std::string const &s)
Definition: decay.cpp:109
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:152
double * end(GSL_vector &v)
iterator to end of GSL_vector
Definition: gsl_vector.cpp:254
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:268
std::string to_string(char a)
constexpr double squared_color_generator() noexcept
Definition: decay.hpp:171
double hVV_4body(double *q2, size_t, void *params)
Definition: decay.cpp:122
std::vector< Decay > sort_decays_list(const Decays_list &decays_list)
sort decays w.r.t. their width
Definition: decay.cpp:91
std::size_t hash_decay(const Decay &decay)
Definition: decay.cpp:49
std::array< int, Field::numberOfFieldIndices > type
Definition: fields.hpp:55