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