Version: SMASH-2.0
isoparticletype.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015-2020
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(), res.name());
233  Tabulation integral;
234  if (!dir.empty() && bf::exists(path)) {
235  std::ifstream file(path.string());
236  integral = Tabulation::from_file(file, hash);
237  if (!integral.is_empty()) {
238  // Only print message if the found tabulation was valid.
239  std::cout << "Tabulation found at " << path.filename() << '\r'
240  << std::flush;
241  }
242  }
243  if (integral.is_empty()) {
244  if (!dir.empty()) {
245  std::cout << "Caching tabulation to " << path.filename() << '\r'
246  << std::flush;
247  }
248  if (!unstable) {
249  integral = spectral_integral_semistable(integrate, *res.get_states()[0],
250  *part.get_states()[0], spacing);
251  } else {
252  integral = spectral_integral_unstable(integrate2d, *res.get_states()[0],
253  *part.get_states()[0], spacing2d);
254  }
255  if (!dir.empty()) {
256  std::ofstream file(path.string());
257  integral.write(file, hash);
258  }
259  }
260  tabulations.emplace(std::make_pair(res.name(), integral));
261  if (antires != nullptr) {
262  tabulations.emplace(std::make_pair(antires->name(), integral));
263  }
264 }
265 
267  const bf::path &tabulations_path) {
268  // To avoid race conditions, make sure we are the only ones currently storing
269  // tabulations. Otherwise, we ignore any stored tabulations and don't store
270  // our results.
271  FileLock lock(tabulations_path / "tabulations.lock");
272  const bf::path &dir = lock.acquire() ? tabulations_path : "";
273 
274  const auto nuc = IsoParticleType::try_find("N");
275  const auto pion = IsoParticleType::try_find("π");
276  const auto kaon = IsoParticleType::try_find("K");
277  const auto delta = IsoParticleType::try_find("Δ");
278  const auto rho = IsoParticleType::try_find("ρ");
279  const auto h1 = IsoParticleType::try_find("h₁(1170)");
280  for (const auto &res : IsoParticleType::list_baryon_resonances()) {
281  const auto antires = res->anti_multiplet();
282  if (nuc) {
283  cache_integral(NR_tabulations, dir, hash, *nuc, *res, antires, false);
284  }
285  if (pion) {
286  cache_integral(piR_tabulations, dir, hash, *pion, *res, antires, false);
287  }
288  if (kaon) {
289  cache_integral(RK_tabulations, dir, hash, *kaon, *res, antires, false);
290  }
291  if (delta) {
292  cache_integral(DeltaR_tabulations, dir, hash, *delta, *res, antires,
293  true);
294  }
295  }
296  if (rho) {
297  cache_integral(rhoR_tabulations, dir, hash, *rho, *rho, nullptr, true);
298  }
299  if (rho && h1) {
300  cache_integral(rhoR_tabulations, dir, hash, *rho, *h1, nullptr, true);
301  }
302 }
303 
304 double IsoParticleType::get_integral_NR(double sqrts) {
305  if (XS_NR_tabulation_ == nullptr) {
306  const auto res = states_[0]->iso_multiplet();
307  XS_NR_tabulation_ = &NR_tabulations.at(res->name());
308  }
309  return XS_NR_tabulation_->get_value_linear(sqrts);
310 }
311 
312 double IsoParticleType::get_integral_piR(double sqrts) {
313  if (XS_piR_tabulation_ == nullptr) {
314  const auto res = states_[0]->iso_multiplet();
315  XS_piR_tabulation_ = &piR_tabulations.at(res->name());
316  }
317  return XS_piR_tabulation_->get_value_linear(sqrts);
318 }
319 
320 double IsoParticleType::get_integral_RK(double sqrts) {
321  if (XS_RK_tabulation_ == nullptr) {
322  const auto res = states_[0]->iso_multiplet();
323  XS_RK_tabulation_ = &RK_tabulations.at(res->name());
324  }
325  return XS_RK_tabulation_->get_value_linear(sqrts);
326 }
327 
329  if (XS_rhoR_tabulation_ == nullptr) {
330  const auto res = states_[0]->iso_multiplet();
331  XS_rhoR_tabulation_ = &rhoR_tabulations.at(res->name());
332  }
333  return XS_rhoR_tabulation_->get_value_linear(sqrts);
334 }
335 
337  double sqrts) {
338  const auto res = states_[0]->iso_multiplet();
339  if (type_res_2->states_[0]->is_Delta()) {
340  if (XS_DeltaR_tabulation_ == nullptr) {
341  XS_DeltaR_tabulation_ = &DeltaR_tabulations.at(res->name());
342  }
344  }
345  if (type_res_2->name() == "ρ") {
346  if (XS_rhoR_tabulation_ == nullptr) {
347  XS_rhoR_tabulation_ = &rhoR_tabulations.at(res->name());
348  }
349  return XS_rhoR_tabulation_->get_value_linear(sqrts);
350  }
351  if (type_res_2->name() == "h₁(1170)") {
352  if (XS_rhoR_tabulation_ == nullptr) {
353  XS_rhoR_tabulation_ = &rhoR_tabulations.at(res->name());
354  }
355  return XS_rhoR_tabulation_->get_value_linear(sqrts);
356  }
357  std::stringstream err;
358  err << "RR=" << name() << type_res_2->name() << " is not implemented";
359  throw std::runtime_error(err.str());
360 }
361 
362 } // 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:106
smash::IsoParticleType::width
double width() const
Returns the (average) multiplet width.
Definition: isoparticletype.h:72
smash::NR_tabulations
static std::unordered_map< std::string, Tabulation > NR_tabulations
Tabulation of all N R integrals.
Definition: isoparticletype.cc:190
smash::IsoParticleType::find
static const IsoParticleType & find(const std::string &name)
Returns the IsoParticleType object for the given name.
Definition: isoparticletype.cc:61
smash::rhoR_tabulations
static std::unordered_map< std::string, Tabulation > rhoR_tabulations
Tabulation of all rho rho integrals.
Definition: isoparticletype.cc:218
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:211
smash::Integrator2d
A C++ interface for numerical integration in two dimensions with the Cuba Cuhre integration function.
Definition: integrate.h:219
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:220
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::IsoParticleType::name
const std::string & name() const
Returns the name of the multiplet.
Definition: isoparticletype.h:66
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:328
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:119
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:226
smash::IsoParticleType::spin
unsigned int spin() const
Returns twice the spin of the multiplet.
Definition: isoparticletype.h:81
smash::IsoParticleType::states_
ParticleTypePtrList states_
list of states that are contained in the multiplet
Definition: isoparticletype.h:245
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:21
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:255
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:90
smash::IsoParticleType::XS_RK_tabulation_
Tabulation * XS_RK_tabulation_
A tabulation of the spectral integral for the NK -> RK cross sections.
Definition: isoparticletype.h:250
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:197
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:266
smash::spectral_integral_unstable
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
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:264
smash::ParticleTypePtr
Definition: particletype.h:665
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:312
smash::iso_type_list
static IsoParticleTypeList iso_type_list
Definition: isoparticletype.cc:20
smash::integrate
static Integrator integrate
Definition: decaytype.cc:144
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:123
smash::LParticleType
static constexpr int LParticleType
Definition: isoparticletype.cc:18
isoparticletype.h
smash::IsoParticleType
Definition: isoparticletype.h:28
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:24
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:139
smash::IsoParticleType::exists
static bool exists(const std::string &name)
Returns whether the ParticleType with the given pdgcode exists.
Definition: isoparticletype.cc:78
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:304
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:248
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:45
smash::IsoParticleType::mass
double mass() const
Returns the (average) multiplet mass.
Definition: isoparticletype.h:69
smash::sha256::Hash
std::array< uint8_t, HASH_SIZE > Hash
A SHA256 hash.
Definition: sha256.h:25
smash::IsoParticleType::ParticleNotFoundFailure
Definition: isoparticletype.h:155
smash::integrate2d
static Integrator2d integrate2d(1E7)
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:260
smash::pdg::h1
constexpr int h1
h₁(1170).
Definition: pdgcode_constants.h:90
smash::IsoParticleType::try_find
static const IsoParticleType * try_find(const std::string &name)
Returns the IsoParticleType pointer for the given name.
Definition: isoparticletype.cc:57
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:320
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:69
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:336
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:38
smash::IsoParticleType::get_states
ParticleTypePtrList get_states() const
Returns list of states that form part of the multiplet.
Definition: isoparticletype.h:94
smash::IsoParticleType::list_all
static const IsoParticleTypeList & list_all()
Returns a list of all IsoParticleTypes.
Definition: isoparticletype.cc:42
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:160
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:204