Version: SMASH-1.8
isoparticletype.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015-2019
3  * SMASH Team
4  *
5  * GNU General Public License (GPLv3 or later)
6  */
7 
9 
10 #include <boost/filesystem.hpp>
11 #include <boost/filesystem/fstream.hpp>
12 
13 #include "smash/filelock.h"
14 #include "smash/integrate.h"
15 #include "smash/kinematics.h"
16 #include "smash/logging.h"
17 
18 namespace smash {
19 static constexpr int LParticleType = LogArea::ParticleType::id;
20 
21 static IsoParticleTypeList iso_type_list;
22 static std::vector<const IsoParticleType *> iso_baryon_resonances;
23 
24 const std::vector<const IsoParticleType *>
26  if (iso_baryon_resonances.empty()) {
27  // Initialize.
28  for (const auto &res : IsoParticleType::list_all()) {
29  const auto baryon_number = res.states_[0]->pdgcode().baryon_number();
30  if (res.states_[0]->is_stable() || (baryon_number <= 0)) {
31  continue;
32  }
33  iso_baryon_resonances.push_back(&res);
34  }
35  }
36  return iso_baryon_resonances;
37 }
38 
39 IsoParticleType::IsoParticleType(const std::string &n, double m, double w,
40  unsigned int s, Parity p)
41  : name_(n), mass_(m), width_(w), spin_(s), parity_(p) {}
42 
43 const IsoParticleTypeList &IsoParticleType::list_all() { return iso_type_list; }
44 
46 static IsoParticleType *try_find_private(const std::string &name) {
47  auto found =
48  std::lower_bound(iso_type_list.begin(), iso_type_list.end(), name,
49  [](const IsoParticleType &l, const std::string &r) {
50  return l.name() < r;
51  });
52  if (found == iso_type_list.end() || found->name() != name) {
53  return {}; // The default constructor creates an invalid pointer.
54  }
55  return &*found;
56 }
57 
58 const IsoParticleType *IsoParticleType::try_find(const std::string &name) {
59  return try_find_private(name);
60 }
61 
62 const IsoParticleType &IsoParticleType::find(const std::string &name) {
63  const auto found = try_find_private(name);
64  if (!found) {
65  throw ParticleNotFoundFailure("Isospin multiplet " + name + " not found!");
66  }
67  return *found;
68 }
69 
71  auto found = try_find_private(name);
72  if (!found) {
73  throw ParticleNotFoundFailure("Isospin multiplet " + name +
74  " not found (privately)!");
75  }
76  return *found;
77 }
78 
79 bool IsoParticleType::exists(const std::string &name) {
80  const auto found = try_find_private(name);
81  return found;
82 }
83 
91 static std::string multiplet_name(std::string name) {
92  if (name.find("⁺⁺") != std::string::npos) {
93  return name.substr(0, name.length() - sizeof("⁺⁺") + 1);
94  } else if (name.find("⁺") != std::string::npos) {
95  return name.substr(0, name.length() - sizeof("⁺") + 1);
96  } else if (name.find("⁻⁻") != std::string::npos) {
97  return name.substr(0, name.length() - sizeof("⁻⁻") + 1);
98  } else if (name.find("⁻") != std::string::npos) {
99  return name.substr(0, name.length() - sizeof("⁻") + 1);
100  } else if (name.find("⁰") != std::string::npos) {
101  return name.substr(0, name.length() - sizeof("⁰") + 1);
102  } else {
103  return name;
104  }
105 }
106 
108  if (states_[0]->has_antiparticle()) {
109  ParticleTypePtr anti = states_[0]->get_antiparticle();
110  if (states_[0]->name() != multiplet_name(anti->name())) {
111  return anti->iso_multiplet();
112  } else {
113  return nullptr;
114  }
115  } else {
116  return nullptr;
117  }
118 }
119 
121  return anti_multiplet() != nullptr;
122 }
123 
124 const ParticleTypePtr IsoParticleType::find_state(const std::string &n) {
126  auto found = std::find_if(multiplet.states_.begin(), multiplet.states_.end(),
127  [&n](ParticleTypePtr p) { return p->name() == n; });
128  if (found == multiplet.states_.end()) {
129  throw std::runtime_error("Isospin state " + n + " not found!");
130  }
131  return *found;
132 }
133 
135  std::string multiname = multiplet_name(type.name());
136  IsoParticleType &multiplet = find_private(multiname);
137  return &multiplet;
138 }
139 
141  states_.push_back(&type);
142 
143  // check if isospin symmetry is fulfilled
144  if (std::abs(mass() - type.mass()) > really_small) {
145  logg[LParticleType].warn()
146  << "Isospin symmetry is broken by mass of " << type.name() << ": "
147  << type.mass() << " vs. " << mass();
148  }
149  if (std::abs(width() - type.width_at_pole()) > really_small) {
150  logg[LParticleType].warn()
151  << "Isospin symmetry is broken by width of " << type.name() << ": "
152  << type.width_at_pole() << " vs. " << width();
153  }
154  if (spin() != type.spin()) {
155  logg[LParticleType].error()
156  << "Isospin symmetry is broken by spin of " << type.name() << ": "
157  << type.spin() << " vs. " << spin();
158  }
159 }
160 
162  // create multiplet if it does not exist yet
163  std::string multiname = multiplet_name(type.name());
164  if (!exists(multiname)) {
165  iso_type_list.emplace_back(multiname, type.mass(), type.width_at_pole(),
166  type.spin(), type.parity());
167  logg[LParticleType].debug()
168  << "Creating isospin multiplet " << multiname
169  << " [ m = " << type.mass() << ", Γ = " << type.width_at_pole() << " ]";
170  }
171 
172  // sort the iso-type list by name
173  std::sort(iso_type_list.begin(), iso_type_list.end(),
174  [](const IsoParticleType &l, const IsoParticleType &r) {
175  return l.name() < r.name();
176  });
177 
178  // add the specific type to the multiplet
179  IsoParticleType &multiplet = find_private(multiname);
180  multiplet.add_state(type);
181 }
182 
185 
191 static std::unordered_map<std::string, Tabulation> NR_tabulations;
192 
198 static std::unordered_map<std::string, Tabulation> piR_tabulations;
199 
205 static std::unordered_map<std::string, Tabulation> RK_tabulations;
206 
212 static std::unordered_map<std::string, Tabulation> DeltaR_tabulations;
213 
219 static std::unordered_map<std::string, Tabulation> rhoR_tabulations;
220 
221 static bf::path generate_tabulation_path(const bf::path &dir,
222  const std::string &prefix,
223  const std::string &res_name) {
224  return dir / (prefix + res_name + ".bin");
225 }
226 
227 inline void cache_integral(
228  std::unordered_map<std::string, Tabulation> &tabulations,
229  const bf::path &dir, sha256::Hash hash, const IsoParticleType &part,
230  const IsoParticleType &res, const IsoParticleType *antires, bool unstable) {
231  constexpr double spacing = 2.0;
232  constexpr double spacing2d = 3.0;
233  const auto path = generate_tabulation_path(dir, part.name(), res.name());
234  Tabulation integral;
235  if (!dir.empty() && bf::exists(path)) {
236  std::ifstream file(path.string());
237  integral = Tabulation::from_file(file, hash);
238  if (!integral.is_empty()) {
239  // Only print message if the found tabulation was valid.
240  std::cout << "Tabulation found at " << path.filename() << '\r'
241  << std::flush;
242  }
243  }
244  if (integral.is_empty()) {
245  if (!dir.empty()) {
246  std::cout << "Caching tabulation to " << path.filename() << '\r'
247  << std::flush;
248  }
249  if (!unstable) {
250  integral = spectral_integral_semistable(integrate, *res.get_states()[0],
251  *part.get_states()[0], spacing);
252  } else {
253  integral = spectral_integral_unstable(integrate2d, *res.get_states()[0],
254  *part.get_states()[0], spacing2d);
255  }
256  if (!dir.empty()) {
257  std::ofstream file(path.string());
258  integral.write(file, hash);
259  }
260  }
261  tabulations.emplace(std::make_pair(res.name(), integral));
262  if (antires != nullptr) {
263  tabulations.emplace(std::make_pair(antires->name(), integral));
264  }
265 }
266 
268  const bf::path &tabulations_path) {
269  // To avoid race conditions, make sure we are the only ones currently storing
270  // tabulations. Otherwise, we ignore any stored tabulations and don't store
271  // our results.
272  FileLock lock(tabulations_path / "tabulations.lock");
273  const bf::path &dir = lock.acquire() ? tabulations_path : "";
274 
275  const auto nuc = IsoParticleType::try_find("N");
276  const auto pion = IsoParticleType::try_find("π");
277  const auto kaon = IsoParticleType::try_find("K");
278  const auto delta = IsoParticleType::try_find("Δ");
279  const auto rho = IsoParticleType::try_find("ρ");
280  const auto h1 = IsoParticleType::try_find("h₁(1170)");
281  for (const auto &res : IsoParticleType::list_baryon_resonances()) {
282  const auto antires = res->anti_multiplet();
283  if (nuc) {
284  cache_integral(NR_tabulations, dir, hash, *nuc, *res, antires, false);
285  }
286  if (pion) {
287  cache_integral(piR_tabulations, dir, hash, *pion, *res, antires, false);
288  }
289  if (kaon) {
290  cache_integral(RK_tabulations, dir, hash, *kaon, *res, antires, false);
291  }
292  if (delta) {
293  cache_integral(DeltaR_tabulations, dir, hash, *delta, *res, antires,
294  true);
295  }
296  }
297  if (rho) {
298  cache_integral(rhoR_tabulations, dir, hash, *rho, *rho, nullptr, true);
299  }
300  if (rho && h1) {
301  cache_integral(rhoR_tabulations, dir, hash, *rho, *h1, nullptr, true);
302  }
303 }
304 
305 double IsoParticleType::get_integral_NR(double sqrts) {
306  if (XS_NR_tabulation_ == nullptr) {
307  const auto res = states_[0]->iso_multiplet();
308  XS_NR_tabulation_ = &NR_tabulations.at(res->name());
309  }
310  return XS_NR_tabulation_->get_value_linear(sqrts);
311 }
312 
313 double IsoParticleType::get_integral_piR(double sqrts) {
314  if (XS_piR_tabulation_ == nullptr) {
315  const auto res = states_[0]->iso_multiplet();
316  XS_piR_tabulation_ = &piR_tabulations.at(res->name());
317  }
318  return XS_piR_tabulation_->get_value_linear(sqrts);
319 }
320 
321 double IsoParticleType::get_integral_RK(double sqrts) {
322  if (XS_RK_tabulation_ == nullptr) {
323  const auto res = states_[0]->iso_multiplet();
324  XS_RK_tabulation_ = &RK_tabulations.at(res->name());
325  }
326  return XS_RK_tabulation_->get_value_linear(sqrts);
327 }
328 
330  if (XS_rhoR_tabulation_ == nullptr) {
331  const auto res = states_[0]->iso_multiplet();
332  XS_rhoR_tabulation_ = &rhoR_tabulations.at(res->name());
333  }
334  return XS_rhoR_tabulation_->get_value_linear(sqrts);
335 }
336 
338  double sqrts) {
339  const auto res = states_[0]->iso_multiplet();
340  if (type_res_2->states_[0]->is_Delta()) {
341  if (XS_DeltaR_tabulation_ == nullptr) {
342  XS_DeltaR_tabulation_ = &DeltaR_tabulations.at(res->name());
343  }
345  }
346  if (type_res_2->name() == "ρ") {
347  if (XS_rhoR_tabulation_ == nullptr) {
348  XS_rhoR_tabulation_ = &rhoR_tabulations.at(res->name());
349  }
350  return XS_rhoR_tabulation_->get_value_linear(sqrts);
351  }
352  if (type_res_2->name() == "h₁(1170)") {
353  if (XS_rhoR_tabulation_ == nullptr) {
354  XS_rhoR_tabulation_ = &rhoR_tabulations.at(res->name());
355  }
356  return XS_rhoR_tabulation_->get_value_linear(sqrts);
357  }
358  std::stringstream err;
359  err << "RR=" << name() << type_res_2->name() << " is not implemented";
360  throw std::runtime_error(err.str());
361 }
362 
363 } // namespace smash
smash::spectral_integral_semistable
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:189
smash
Definition: action.h:24
smash::IsoParticleType::anti_multiplet
const IsoParticleType * anti_multiplet() const
Return a multiplet of antiparticles, if it is different from the original multiplet.
Definition: isoparticletype.cc:107
smash::IsoParticleType::width
double width() const
Returns the (average) multiplet width.
Definition: isoparticletype.h:71
smash::NR_tabulations
static std::unordered_map< std::string, Tabulation > NR_tabulations
Tabulation of all N R integrals.
Definition: isoparticletype.cc:191
smash::IsoParticleType::find
static const IsoParticleType & find(const std::string &name)
Returns the IsoParticleType object for the given name.
Definition: isoparticletype.cc:62
smash::rhoR_tabulations
static std::unordered_map< std::string, Tabulation > rhoR_tabulations
Tabulation of all rho rho integrals.
Definition: isoparticletype.cc:219
smash::ParticleType::width_at_pole
double width_at_pole() const
Definition: particletype.h:150
smash::DeltaR_tabulations
static std::unordered_map< std::string, Tabulation > DeltaR_tabulations
Tabulation of all Delta R integrals.
Definition: isoparticletype.cc:212
smash::generate_tabulation_path
static bf::path generate_tabulation_path(const bf::path &dir, const std::string &prefix, const std::string &res_name)
Definition: isoparticletype.cc:221
smash::ParticleType::iso_multiplet
IsoParticleType * iso_multiplet() const
Definition: particletype.h:185
smash::Tabulation::from_file
static Tabulation from_file(std::ifstream &stream, sha256::Hash hash)
Construct a tabulation object by reading binary data from a stream.
Definition: tabulation.cc:167
smash::spectral_integral_unstable
Tabulation spectral_integral_unstable(Integrator2dCuhre &integrate2d, const ParticleType &res1, const ParticleType &res2, double range)
Create a table for the spectral integral of two resonances.
Definition: tabulation.h:211
smash::IsoParticleType::name
const std::string & name() const
Returns the name of the multiplet.
Definition: isoparticletype.h:65
smash::IsoParticleType::get_integral_rhoR
double get_integral_rhoR(double sqrts)
Look up the tabulated resonance integral for the XX -> rhoR cross section.
Definition: isoparticletype.cc:329
smash::IsoParticleType::has_anti_multiplet
bool has_anti_multiplet() const
Check if there is a multiplet of antiparticles, which is different from the original multiplet.
Definition: isoparticletype.cc:120
smash::cache_integral
void cache_integral(std::unordered_map< std::string, Tabulation > &tabulations, const bf::path &dir, sha256::Hash hash, const IsoParticleType &part, const IsoParticleType &res, const IsoParticleType *antires, bool unstable)
Definition: isoparticletype.cc:227
smash::IsoParticleType::spin
unsigned int spin() const
Returns twice the spin of the multiplet.
Definition: isoparticletype.h:80
smash::IsoParticleType::states_
ParticleTypePtrList states_
list of states that are contained in the multiplet
Definition: isoparticletype.h:244
smash::Integrator
A C++ interface for numerical integration in one dimension with the GSL CQUAD integration functions.
Definition: integrate.h:106
smash::iso_baryon_resonances
static std::vector< const IsoParticleType * > iso_baryon_resonances
Definition: isoparticletype.cc:22
smash::ParticleType::mass
double mass() const
Definition: particletype.h:144
smash::IsoParticleType::XS_NR_tabulation_
Tabulation * XS_NR_tabulation_
A tabulation for the NN -> NR cross sections, where R is a resonance from this multiplet.
Definition: isoparticletype.h:254
smash::FileLock
Guard to create a file lock.
Definition: filelock.h:30
smash::ParticleType::spin
unsigned int spin() const
Definition: particletype.h:191
smash::multiplet_name
static std::string multiplet_name(std::string name)
Construct the name-string for an isospin multiplet from the given name-string for the particle.
Definition: isoparticletype.cc:91
smash::IsoParticleType::XS_RK_tabulation_
Tabulation * XS_RK_tabulation_
A tabulation of the spectral integral for the NK -> RK cross sections.
Definition: isoparticletype.h:249
smash::logg
std::array< einhard::Logger<>, std::tuple_size< LogArea::AreaTuple >::value > logg
An array that stores all pre-configured Logger objects.
Definition: logging.cc:39
smash::piR_tabulations
static std::unordered_map< std::string, Tabulation > piR_tabulations
Tabulation of all pi R integrals.
Definition: isoparticletype.cc:198
smash::really_small
constexpr double really_small
Numerical error tolerance.
Definition: constants.h:37
smash::IsoParticleType::tabulate_integrals
static void tabulate_integrals(sha256::Hash hash, const bf::path &tabulations_path)
Tabulate all relevant integrals.
Definition: isoparticletype.cc:267
filelock.h
smash::Tabulation::write
void write(std::ofstream &stream, sha256::Hash hash) const
Write a binary representation of the tabulation to a stream.
Definition: tabulation.cc:159
smash::IsoParticleType::XS_rhoR_tabulation_
Tabulation * XS_rhoR_tabulation_
A tabulation for the ρρ integrals.
Definition: isoparticletype.h:263
smash::ParticleTypePtr
Definition: particletype.h:663
smash::IsoParticleType::get_integral_piR
double get_integral_piR(double sqrts)
Look up the tabulated resonance integral for the XX -> piR cross section.
Definition: isoparticletype.cc:313
smash::Integrator2dCuhre
A C++ interface for numerical integration in two dimensions with the Cuba Cuhre integration function.
Definition: integrate.h:406
smash::iso_type_list
static IsoParticleTypeList iso_type_list
Definition: isoparticletype.cc:21
smash::integrate
static Integrator integrate
Definition: decaytype.cc:147
smash::IsoParticleType::find_state
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...
Definition: isoparticletype.cc:124
smash::LParticleType
static constexpr int LParticleType
Definition: isoparticletype.cc:19
isoparticletype.h
smash::IsoParticleType
Definition: isoparticletype.h:27
smash::IsoParticleType::list_baryon_resonances
static const std::vector< const IsoParticleType * > list_baryon_resonances()
Returns a list of all IsoParticleTypes that are baryon resonances.
Definition: isoparticletype.cc:25
smash::IsoParticleType::add_state
void add_state(const ParticleType &type)
Add a new state to an existing multiplet (and check if isospin symmetry is fulfilled).
Definition: isoparticletype.cc:140
smash::IsoParticleType::exists
static bool exists(const std::string &name)
Returns whether the ParticleType with the given pdgcode exists.
Definition: isoparticletype.cc:79
smash::IsoParticleType::get_integral_NR
double get_integral_NR(double sqrts)
Look up the tabulated resonance integral for the XX -> NR cross section.
Definition: isoparticletype.cc:305
smash::ParticleType
Definition: particletype.h:97
smash::ParticleType::name
const std::string & name() const
Definition: particletype.h:141
smash::IsoParticleType::XS_piR_tabulation_
Tabulation * XS_piR_tabulation_
A tabulation of the spectral integral for the dpi -> d'pi cross sections.
Definition: isoparticletype.h:247
smash::Tabulation
A class for storing a one-dimensional lookup table of floating-point values.
Definition: tabulation.h:35
smash::try_find_private
static IsoParticleType * try_find_private(const std::string &name)
Helper function for IsoParticleType::try_find and friends.
Definition: isoparticletype.cc:46
smash::IsoParticleType::mass
double mass() const
Returns the (average) multiplet mass.
Definition: isoparticletype.h:68
smash::sha256::Hash
std::array< uint8_t, HASH_SIZE > Hash
A SHA256 hash.
Definition: sha256.h:16
smash::IsoParticleType::ParticleNotFoundFailure
Definition: isoparticletype.h:154
smash::IsoParticleType::XS_DeltaR_tabulation_
Tabulation * XS_DeltaR_tabulation_
A tabulation for the NN -> RΔ cross sections, where R is a resonance from this multiplet.
Definition: isoparticletype.h:259
smash::pdg::h1
constexpr int h1
h₁(1170).
Definition: pdgcode_constants.h:90
kinematics.h
smash::IsoParticleType::try_find
static const IsoParticleType * try_find(const std::string &name)
Returns the IsoParticleType pointer for the given name.
Definition: isoparticletype.cc:58
smash::integrate2d
static Integrator2dCuhre integrate2d(1E7)
integrate.h
smash::IsoParticleType::get_integral_RK
double get_integral_RK(double sqrts)
Look up the tabulated resonance integral for the XX -> RK cross section.
Definition: isoparticletype.cc:321
logging.h
smash::IsoParticleType::find_private
static IsoParticleType & find_private(const std::string &name)
Private version of the 'find' method that returns a non-const reference.
Definition: isoparticletype.cc:70
smash::IsoParticleType::get_integral_RR
double get_integral_RR(IsoParticleType *type_res_2, double sqrts)
Look up the tabulated resonance integral for the XX -> RR cross section.
Definition: isoparticletype.cc:337
smash::Parity
Parity
Represent the parity of a particle type.
Definition: particletype.h:24
smash::pdg::p
constexpr int p
Proton.
Definition: pdgcode_constants.h:28
smash::pdg::n
constexpr int n
Neutron.
Definition: pdgcode_constants.h:30
smash::Tabulation::get_value_linear
double get_value_linear(double x, Extrapolation extrapolation=Extrapolation::Linear) const
Look up a value from the tabulation using linear interpolation.
Definition: tabulation.cc:38
smash::FileLock::acquire
bool acquire()
Try to acquire the file lock.
Definition: filelock.cc:20
smash::IsoParticleType::IsoParticleType
IsoParticleType(const std::string &n, double m, double w, unsigned int s, Parity p)
Creates a fully initialized IsoParticleType object.
Definition: isoparticletype.cc:39
smash::IsoParticleType::get_states
ParticleTypePtrList get_states() const
Returns list of states that form part of the multiplet.
Definition: isoparticletype.h:93
smash::IsoParticleType::list_all
static const IsoParticleTypeList & list_all()
Returns a list of all IsoParticleTypes.
Definition: isoparticletype.cc:43
smash::IsoParticleType::create_multiplet
static void create_multiplet(const ParticleType &type)
Add a new multiplet to the global list of IsoParticleTypes, which contains type.
Definition: isoparticletype.cc:161
smash::ParticleType::parity
Parity parity() const
Definition: particletype.h:153
smash::RK_tabulations
static std::unordered_map< std::string, Tabulation > RK_tabulations
Tabulation of all K R integrals.
Definition: isoparticletype.cc:205