Version: SMASH-1.5
isoparticletype.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015-2018
3  * SMASH Team
4  *
5  * GNU General Public License (GPLv3 or later)
6  */
7 
9 
10 #include "smash/integrate.h"
11 #include "smash/kinematics.h"
12 #include "smash/logging.h"
13 
14 namespace smash {
15 
16 static IsoParticleTypeList iso_type_list;
17 
18 IsoParticleType::IsoParticleType(const std::string &n, double m, double w,
19  unsigned int s, Parity p)
20  : name_(n), mass_(m), width_(w), spin_(s), parity_(p) {}
21 
22 const IsoParticleTypeList &IsoParticleType::list_all() { return iso_type_list; }
23 
25 static IsoParticleType *try_find_private(const std::string &name) {
26  auto found =
27  std::lower_bound(iso_type_list.begin(), iso_type_list.end(), name,
28  [](const IsoParticleType &l, const std::string &r) {
29  return l.name() < r;
30  });
31  if (found == iso_type_list.end() || found->name() != name) {
32  return {}; // The default constructor creates an invalid pointer.
33  }
34  return &*found;
35 }
36 
37 const IsoParticleType *IsoParticleType::try_find(const std::string &name) {
38  return try_find_private(name);
39 }
40 
41 const IsoParticleType &IsoParticleType::find(const std::string &name) {
42  const auto found = try_find_private(name);
43  if (!found) {
44  throw ParticleNotFoundFailure("Isospin multiplet " + name + " not found!");
45  }
46  return *found;
47 }
48 
50  auto found = try_find_private(name);
51  if (!found) {
52  throw ParticleNotFoundFailure("Isospin multiplet " + name +
53  " not found (privately)!");
54  }
55  return *found;
56 }
57 
58 bool IsoParticleType::exists(const std::string &name) {
59  const auto found = try_find_private(name);
60  return found;
61 }
62 
70 static std::string multiplet_name(std::string name) {
71  if (name.find("⁺⁺") != std::string::npos) {
72  return name.substr(0, name.length() - sizeof("⁺⁺") + 1);
73  } else if (name.find("⁺") != std::string::npos) {
74  return name.substr(0, name.length() - sizeof("⁺") + 1);
75  } else if (name.find("⁻⁻") != std::string::npos) {
76  return name.substr(0, name.length() - sizeof("⁻⁻") + 1);
77  } else if (name.find("⁻") != std::string::npos) {
78  return name.substr(0, name.length() - sizeof("⁻") + 1);
79  } else if (name.find("⁰") != std::string::npos) {
80  return name.substr(0, name.length() - sizeof("⁰") + 1);
81  } else {
82  return name;
83  }
84 }
85 
87  if (states_[0]->has_antiparticle()) {
88  ParticleTypePtr anti = states_[0]->get_antiparticle();
89  return multiplet_name(states_[0]->name()) != multiplet_name(anti->name());
90  } else {
91  return false;
92  }
93 }
94 
95 const ParticleTypePtr IsoParticleType::find_state(const std::string &n) {
97  auto found = std::find_if(multiplet.states_.begin(), multiplet.states_.end(),
98  [&n](ParticleTypePtr p) { return p->name() == n; });
99  if (found == multiplet.states_.end()) {
100  throw std::runtime_error("Isospin state " + n + " not found!");
101  }
102  return *found;
103 }
104 
106  std::string multiname = multiplet_name(type.name());
107  IsoParticleType &multiplet = find_private(multiname);
108  return &multiplet;
109 }
110 
112  states_.push_back(&type);
113 
114  // check if isospin symmetry is fulfilled
115  const auto &log = logger<LogArea::ParticleType>();
116  if (std::abs(mass() - type.mass()) > really_small) {
117  log.warn() << "Isospin symmetry is broken by mass of " << type.name()
118  << ": " << type.mass() << " vs. " << mass();
119  }
120  if (std::abs(width() - type.width_at_pole()) > really_small) {
121  log.warn() << "Isospin symmetry is broken by width of " << type.name()
122  << ": " << type.width_at_pole() << " vs. " << width();
123  }
124  if (spin() != type.spin()) {
125  log.error() << "Isospin symmetry is broken by spin of " << type.name()
126  << ": " << type.spin() << " vs. " << spin();
127  }
128 }
129 
131  const auto &log = logger<LogArea::ParticleType>();
132 
133  // create multiplet if it does not exist yet
134  std::string multiname = multiplet_name(type.name());
135  if (!exists(multiname)) {
136  iso_type_list.emplace_back(multiname, type.mass(), type.width_at_pole(),
137  type.spin(), type.parity());
138  log.debug() << "Creating isospin multiplet " << multiname
139  << " [ m = " << type.mass() << ", Γ = " << type.width_at_pole()
140  << " ]";
141  }
142 
143  // sort the iso-type list by name
144  std::sort(iso_type_list.begin(), iso_type_list.end(),
145  [](const IsoParticleType &l, const IsoParticleType &r) {
146  return l.name() < r.name();
147  });
148 
149  // add the specific type to the multiplet
150  IsoParticleType &multiplet = find_private(multiname);
151  multiplet.add_state(type);
152 }
153 
154 static /*thread_local (see #3075)*/ Integrator integrate;
155 
156 double IsoParticleType::get_integral_NR(double sqrts) {
157  if (XS_NR_tabulation_ == nullptr) {
158  // initialize tabulation
159  /* TODO(weil): Move this lazy init to a global initialization function,
160  * in order to avoid race conditions in multi-threading. */
161  ParticleTypePtr type_res = states_[0];
164  spectral_integral_semistable(integrate, *type_res, *nuc, 2.0);
165  }
166  return XS_NR_tabulation_->get_value_linear(sqrts);
167 }
168 
169 double IsoParticleType::get_integral_piR(double sqrts) {
170  if (XS_piR_tabulation_ == nullptr) {
171  // initialize tabulation
172  /* TODO(weil): Move this lazy init to a global initialization function,
173  * in order to avoid race conditions in multi-threading. */
174  ParticleTypePtr type_res = states_[0];
177  spectral_integral_semistable(integrate, *type_res, *pion, 2.0);
178  }
179  return XS_piR_tabulation_->get_value_linear(sqrts);
180 }
181 
182 double IsoParticleType::get_integral_RK(double sqrts) {
183  if (XS_RK_tabulation_ == nullptr) {
184  // initialize tabulation
185  /* TODO(weil): Move this lazy init to a global initialization function,
186  * in order to avoid race conditions in multi-threading. */
187  ParticleTypePtr type_res = states_[0];
190  spectral_integral_semistable(integrate, *type_res, *kaon, 2.0);
191  }
192  return XS_RK_tabulation_->get_value_linear(sqrts);
193 }
194 
195 static /*thread_local (see #3075)*/ Integrator2dCuhre integrate2d;
196 
198  double sqrts) {
199  auto search = XS_RR_tabulations.find(find(type_res_2));
200  if (search != XS_RR_tabulations.end()) {
201  return search->second->get_value_linear(sqrts);
202  }
203  IsoParticleType *key = find(type_res_2);
204  XS_RR_tabulations.emplace(key,
205  integrate_RR(find(type_res_2)->get_states()[0]));
206  return XS_RR_tabulations.at(key)->get_value_linear(sqrts);
207 }
208 
210  ParticleTypePtr res1 = states_[0];
211  const double m1_min = res1->min_mass_kinematic();
212  const double m2_min = res2->min_mass_kinematic();
213  return make_unique<Tabulation>(m1_min + m2_min, 3., 125, [&](double srts) {
214  const double m1_max = srts - m2_min;
215  const double m2_max = srts - m1_min;
216  const auto result =
217  integrate2d(m1_min, m1_max, m2_min, m2_max, [&](double m1, double m2) {
218  return spec_func_integrand_2res(srts, m1, m2, *res1, *res2);
219  });
220  return result.value();
221  });
222 }
223 
224 } // namespace smash
static const IsoParticleType & find(const std::string &name)
Returns the IsoParticleType object for the given name.
static Integrator2dCuhre integrate2d(1E7)
ParticleTypePtrList get_states() const
Returns list of states that form part of the multiplet.
double mass() const
Definition: particletype.h:134
constexpr double really_small
Numerical error tolerance.
Definition: constants.h:34
static IsoParticleType & find_private(const std::string &name)
Private version of the &#39;find&#39; method that returns a non-const reference.
double get_integral_piR(double sqrts)
Look up the tabulated resonance integral for the XX -> piR cross section.
double width_at_pole() const
Definition: particletype.h:140
Parity parity() const
Definition: particletype.h:143
double width() const
Returns the (average) multiplet width.
double spec_func_integrand_2res(double sqrts, double res_mass_1, double res_mass_2, const ParticleType &t1, const ParticleType &t2)
Spectral function integrand for GSL integration, with two resonances in the final state...
Definition: tabulation.h:132
std::unordered_map< IsoParticleType *, TabulationPtr > XS_RR_tabulations
A tabulation list for the NN -> RR&#39; cross sections, where R is this multiplet and R&#39; is a baryon reso...
double get_integral_RR(const ParticleType &type_res_2, double sqrts)
Look up the tabulated resonance integral for the XX -> RR cross section.
Parity
Represent the parity of a particle type.
Definition: particletype.h:24
static std::string multiplet_name(std::string name)
Construct the name-string for an isospin multiplet from the given name-string for the particle...
double get_integral_NR(double sqrts)
Look up the tabulated resonance integral for the XX -> NR cross section.
static IsoParticleTypeList iso_type_list
double get_integral_RK(double sqrts)
Look up the tabulated resonance integral for the XX -> RK cross section.
static IsoParticleType * try_find_private(const std::string &name)
Helper function for IsoParticleType::try_find and friends.
A C++ interface for numerical integration in two dimensions with the Cuba Cuhre integration function...
Definition: integrate.h:406
static bool exists(const std::string &name)
Returns whether the ParticleType with the given pdgcode exists.
std::unique_ptr< Tabulation > spectral_integral_semistable(Integrator &integrate, const ParticleType &resonance, const ParticleType &stable, double range)
Create a table for the spectral integral of a resonance and a stable particle.
Definition: tabulation.h:156
unsigned int spin() const
Returns twice the spin of the multiplet.
TabulationPtr XS_RK_tabulation_
A tabulation of the spectral integral for the NK -> RK cross sections.
Throw when requested particle could not be found.
ParticleTypePtrList states_
list of states that are contained in the multiplet
Particle type contains the static properties of a particle species.
Definition: particletype.h:87
IsoParticleType is a class to represent isospin multiplets.
static void create_multiplet(const ParticleType &type)
Add a new multiplet to the global list of IsoParticleTypes, which contains type.
void add_state(const ParticleType &type)
Add a new state to an existing multiplet (and check if isospin symmetry is fulfilled).
unsigned int spin() const
Definition: particletype.h:181
static const IsoParticleType * try_find(const std::string &name)
Returns the IsoParticleType pointer for the given name.
static const ParticleTypePtr find_state(const std::string &name)
Returns the ParticleType object for the given name, by first finding the correct multiplet and then l...
double mass() const
Returns the (average) multiplet mass.
constexpr int p
Proton.
TabulationPtr XS_NR_tabulation_
A tabulation for the NN -> NR cross sections, where R is a resonance from this multiplet.
TabulationPtr XS_piR_tabulation_
A tabulation of the spectral integral for the dpi -> d&#39;pi cross sections.
IsoParticleType(const std::string &n, double m, double w, unsigned int s, Parity p)
Creates a fully initialized IsoParticleType object.
A C++ interface for numerical integration in one dimension with the GSL CQUAD integration functions...
Definition: integrate.h:106
double min_mass_kinematic() const
The minimum mass of the resonance that is kinematically allowed.
A pointer-like interface to global references to ParticleType objects.
Definition: particletype.h:660
bool has_anti_multiplet() const
Check if there is a multiplet of antiparticles, which is different from the original multiplet...
constexpr int n
Neutron.
TabulationPtr integrate_RR(ParticleTypePtr &type_res_2)
Utility function to help compute various XX->RR spectral integrals.
const std::string & name() const
Returns the name of the multiplet.
Definition: action.h:24
static const IsoParticleTypeList & list_all()
Returns a list of all IsoParticleTypes.
static Integrator integrate
Definition: decaytype.cc:147
const std::string & name() const
Definition: particletype.h:131