Version: SMASH-3.0
particledata.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2014-2023
4  * SMASH Team
5  *
6  * GNU General Public License (GPLv3 or later)
7  *
8  */
9 
10 #include "smash/particledata.h"
11 
12 #include <iomanip>
13 #include <iostream>
14 #include <optional>
15 #include <vector>
16 
17 #include "smash/constants.h"
18 #include "smash/iomanipulators.h"
19 #include "smash/logging.h"
20 
21 namespace smash {
22 
24  const double m_pole = pole_mass();
25  if (m_pole < really_small) {
26  // prevent numerical problems with massless or very light particles
27  return m_pole;
28  } else {
29  return momentum().abs();
30  }
31 }
32 
33 void ParticleData::set_history(int ncoll, uint32_t pid, ProcessType pt,
34  double time_last_coll,
35  const ParticleList &plist) {
36  if (pt != ProcessType::Wall) {
38  history_.time_last_collision = time_last_coll;
39  }
40  history_.id_process = pid;
42  switch (pt) {
43  case ProcessType::Decay:
44  case ProcessType::Wall:
45  // only store one parent
46  history_.p1 = plist[0].pdgcode();
47  history_.p2 = 0x0;
48  break;
52  // Parent particles are not updated by the elastic scatterings,
53  // hypersurface crossings or failed string processes
54  break;
67  // store two parent particles
68  history_.p1 = plist[0].pdgcode();
69  history_.p2 = plist[1].pdgcode();
70  break;
77  case ProcessType::None:
78  // nullify parents
79  history_.p1 = 0x0;
80  history_.p2 = 0x0;
81  break;
82  }
83 }
84 
85 double ParticleData::xsec_scaling_factor(double delta_time) const {
86  double time_of_interest = position_.x0() + delta_time;
87  // cross section scaling factor at the time_of_interest
88  double scaling_factor;
89 
90  if (formation_power_ <= 0.) {
91  // use a step function to form particles
92  if (time_of_interest < formation_time_) {
93  // particles will not be fully formed at time of interest
94  scaling_factor = initial_xsec_scaling_factor_;
95  } else {
96  // particles are fully formed at time of interest
97  scaling_factor = 1.;
98  }
99  } else {
100  // use smooth function to scale cross section (unless particles are already
101  // fully formed at desired time or will start to form later)
102  if (formation_time_ <= time_of_interest) {
103  // particles are fully formed when colliding
104  scaling_factor = 1.;
105  } else if (begin_formation_time_ >= time_of_interest) {
106  // particles will start formimg later
107  scaling_factor = initial_xsec_scaling_factor_;
108  } else {
109  // particles are in the process of formation at the given time
110  scaling_factor =
113  std::pow((time_of_interest - begin_formation_time_) /
116  }
117  }
118  return scaling_factor;
119 }
120 
121 std::ostream &operator<<(std::ostream &out, const ParticleData &p) {
122  out.fill(' ');
123  return out << p.type().name() << " (" << std::setw(5) << p.type().pdgcode()
124  << ")" << std::right << "{id:" << field<6> << p.id()
125  << ", process:" << field<4> << p.id_process()
126  << ", pos [fm]:" << p.position() << ", mom [GeV]:" << p.momentum()
127  << ", formation time [fm]:" << p.formation_time()
128  << ", cross section scaling factor:" << p.xsec_scaling_factor()
129  << "}";
130 }
131 
132 std::ostream &operator<<(std::ostream &out, const ParticleList &particle_list) {
133  auto column = out.tellp();
134  out << '[';
135  for (const auto &p : particle_list) {
136  if (out.tellp() - column >= 201) {
137  out << '\n';
138  column = out.tellp();
139  out << ' ';
140  }
141  out << std::setw(5) << std::setprecision(3) << p.momentum().abs3()
142  << p.type().name();
143  }
144  return out << ']';
145 }
146 
147 std::ostream &operator<<(std::ostream &out,
148  const PrintParticleListDetailed &particle_list) {
149  bool first = true;
150  out << '[';
151  for (const auto &p : particle_list.list) {
152  if (first) {
153  first = false;
154  } else {
155  out << "\n ";
156  }
157  out << p;
158  }
159  return out << ']';
160 }
161 
162 double ParticleData::formation_power_ = 0.0;
163 
165  PdgCode pdgcode, double mass, const FourVector &four_momentum, int log_area,
166  bool &mass_warning, bool &on_shell_warning) {
167  // Some preliminary tool to avoid duplication later
168  static const auto emph = einhard::Yellow_t_::ANSI();
169  static const auto restore_default = einhard::NoColor_t_::ANSI();
170  auto prepare_needed_warnings = [&mass_warning, &on_shell_warning, &mass,
171  &four_momentum](const ParticleData &p) {
172  std::array<std::optional<std::string>, 2> warnings{};
173  if (mass_warning) {
174  warnings[0] = "Provided mass of stable particle " + p.type().name() +
175  " = " + std::to_string(mass) +
176  " [GeV] is inconsistent with value = " +
177  std::to_string(p.pole_mass()) + " [GeV] from " +
178  "particles file.\nForcing E = sqrt(p^2 + m^2)" +
179  ", where m is the mass contained in the particles file." +
180  "\nFurther warnings about discrepancies between the " +
181  "input mass and the mass contained in the particles file" +
182  " will be suppressed.\n" + emph + "Please make sure" +
183  " that changing input particle properties is an " +
184  "acceptable behavior." + restore_default;
185  }
186  if (on_shell_warning) {
187  std::stringstream ss{};
188  ss << four_momentum;
189  warnings[1] =
190  "Provided 4-momentum " + ss.str() + " [GeV] and mass " +
191  std::to_string(mass) + " [GeV] do not satisfy E^2 - p^2 = m^2.\n" +
192  "This may originate from the lack of numerical" +
193  " precision in the input. Setting E to sqrt(p^2 + " +
194  "m^2).\nFurther warnings about E != sqrt(p^2 + m^2) will" +
195  " be suppressed.\n" + emph + "Please make sure that setting " +
196  "particles back on the mass shell is an acceptable behavior." +
197  restore_default;
198  }
199  return warnings;
200  };
201  auto warn_if_needed = [&log_area](bool &flag,
202  const std::optional<std::string> &message) {
203  if (flag) {
204  logg[log_area].warn(message.value());
205  flag = false;
206  }
207  };
208  auto is_particle_stable_and_with_invalid_mass =
209  [&mass](const ParticleData &p) {
210  return p.type().is_stable() &&
211  std::abs(mass - p.pole_mass()) > really_small;
212  };
213  auto is_particle_off_its_mass_shell = [&mass](const ParticleData &p) {
214  return std::abs(p.momentum().sqr() - mass * mass) > really_small;
215  };
216 
217  // Actual implementation
218  ParticleData smash_particle{ParticleType::find(pdgcode)};
219  const auto warnings = prepare_needed_warnings(smash_particle);
220  if (is_particle_stable_and_with_invalid_mass(smash_particle)) {
221  warn_if_needed(mass_warning, warnings[0]);
222  smash_particle.set_4momentum(smash_particle.pole_mass(),
223  four_momentum.threevec());
224  } else {
225  smash_particle.set_4momentum(four_momentum);
226  if (is_particle_off_its_mass_shell(smash_particle)) {
227  warn_if_needed(on_shell_warning, warnings[1]);
228  smash_particle.set_4momentum(mass, four_momentum.threevec());
229  }
230  }
231  return smash_particle;
232 }
233 
235  const ParticleData &p2,
236  double time) {
237  if (p1.pdgcode() != p2.pdgcode()) {
238  return false;
239  } else {
240  if (p1.momentum() != p2.momentum()) {
241  return false;
242  }
243  auto get_propagated_position = [&time](const ParticleData &p) {
244  const double t = p.position().x0();
245  const FourVector u(1.0, p.velocity());
246  return p.position() + u * (time - t);
247  };
248  return get_propagated_position(p1) == get_propagated_position(p2);
249  }
250 }
251 
252 } // namespace smash
The FourVector class holds relevant values in Minkowski spacetime with (+, −, −, −) metric signature.
Definition: fourvector.h:33
double abs() const
calculate the lorentz invariant absolute value
Definition: fourvector.h:464
ThreeVector threevec() const
Definition: fourvector.h:329
double x0() const
Definition: fourvector.h:313
ParticleData contains the dynamic information of a certain particle.
Definition: particledata.h:58
double formation_time_
Formation time at which the particle is fully formed given as an absolute value in the computational ...
Definition: particledata.h:459
PdgCode pdgcode() const
Get the pdgcode of the particle.
Definition: particledata.h:87
double begin_formation_time_
time when the cross section scaling factor starts to increase to 1
Definition: particledata.h:461
double xsec_scaling_factor(double delta_time=0.) const
Return the cross section scaling factor at a given time.
Definition: particledata.cc:85
void set_history(int ncoll, uint32_t pid, ProcessType pt, double time_of_or, const ParticleList &plist)
Store history information.
Definition: particledata.cc:33
static double formation_power_
Power with which the cross section scaling factor grows in time.
Definition: particledata.h:389
const FourVector & momentum() const
Get the particle's 4-momentum.
Definition: particledata.h:158
double initial_xsec_scaling_factor_
Initial cross section scaling factor.
Definition: particledata.h:466
double effective_mass() const
Get the particle's effective mass.
Definition: particledata.cc:23
FourVector position_
position in space: x0, x1, x2, x3 as t, x, y, z
Definition: particledata.h:455
double pole_mass() const
Get the particle's pole mass ("on-shell").
Definition: particledata.h:115
HistoryData history_
history information
Definition: particledata.h:468
static const ParticleType & find(PdgCode pdgcode)
Returns the ParticleType object for the given pdgcode.
Definition: particletype.cc:99
PdgCode stores a Particle Data Group Particle Numbering Scheme particle type number.
Definition: pdgcode.h:110
Collection of useful constants that are known at compile time.
std::ostream & operator<<(std::ostream &out, const ActionPtr &action)
Convenience: dereferences the ActionPtr to Action.
Definition: action.h:537
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.
Definition: action.h:24
ParticleData create_valid_smash_particle_matching_provided_quantities(PdgCode pdgcode, double mass, const FourVector &four_momentum, int log_area, bool &mass_warning, bool &on_shell_warning)
This function creates a SMASH particle validating the provided information.
ProcessType
ProcessTypes are used to identify the type of the process.
Definition: processbranch.h:39
@ FailedString
See here for a short description.
@ TwoToOne
See here for a short description.
@ MultiParticleThreeToTwo
See here for a short description.
@ StringSoftDoubleDiffractive
See here for a short description.
@ Bremsstrahlung
See here for a short description.
@ Thermalization
See here for a short description.
@ Freeforall
See here for a short description.
@ Decay
See here for a short description.
@ TwoToFive
See here for a short description.
@ None
See here for a short description.
@ StringSoftSingleDiffractiveXB
See here for a short description.
@ TwoToTwo
See here for a short description.
@ Wall
See here for a short description.
@ Elastic
See here for a short description.
@ TwoToFour
See here for a short description.
@ StringSoftAnnihilation
See here for a short description.
@ MultiParticleThreeMesonsToOne
See here for a short description.
@ StringSoftNonDiffractive
See here for a short description.
@ MultiParticleFourToTwo
See here for a short description.
@ StringSoftSingleDiffractiveAX
See here for a short description.
@ StringHard
See here for a short description.
@ HyperSurfaceCrossing
See here for a short description.
@ TwoToThree
See here for a short description.
@ MultiParticleFiveToTwo
See here for a short description.
bool are_particles_identical_at_given_time(const ParticleData &p1, const ParticleData &p2, double time)
Utility function to compare two ParticleData instances with respect to their PDG code,...
constexpr double really_small
Numerical error tolerance.
Definition: constants.h:37
double time_last_collision
Time of the last action (excluding walls), time of kinetic freeze_out for HBT analysis this time shou...
Definition: particledata.h:43
int32_t id_process
id of the last action
Definition: particledata.h:34
PdgCode p2
PdgCode of the second parent particles.
Definition: particledata.h:47
PdgCode p1
PdgCode of the first parent particles.
Definition: particledata.h:45
int32_t collisions_per_particle
Collision counter per particle, zero only for initially present particles.
Definition: particledata.h:32
ProcessType process_type
type of the last action
Definition: particledata.h:36
const ParticleList & list
Particle list.
Definition: particledata.h:493