Version: SMASH-3.0
scatteraction.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/scatteraction.h"
11 
12 #include <cmath>
13 
14 #include "Pythia8/Pythia.h"
15 
16 #include "smash/angles.h"
17 #include "smash/constants.h"
18 #include "smash/crosssections.h"
19 #include "smash/fpenvironment.h"
20 #include "smash/logging.h"
21 #include "smash/pdgcode.h"
22 #include "smash/pow.h"
23 #include "smash/random.h"
24 
25 namespace smash {
26 static constexpr int LScatterAction = LogArea::ScatterAction::id;
27 
29  const ParticleData &in_part_b, double time,
30  bool isotropic, double string_formation_time,
31  double box_length)
32  : Action({in_part_a, in_part_b}, time),
33  total_cross_section_(0.),
34  isotropic_(isotropic),
35  string_formation_time_(string_formation_time) {
36  box_length_ = box_length;
37 }
38 
39 void ScatterAction::add_collision(CollisionBranchPtr p) {
40  add_process<CollisionBranch>(p, collision_channels_, total_cross_section_);
41 }
42 
43 void ScatterAction::add_collisions(CollisionBranchList pv) {
44  add_processes<CollisionBranch>(std::move(pv), collision_channels_,
46 }
47 
49  logg[LScatterAction].debug("Incoming particles: ", incoming_particles_);
50 
51  /* Decide for a particular final state. */
52  const CollisionBranch *proc = choose_channel<CollisionBranch>(
54  process_type_ = proc->get_type();
57 
58  logg[LScatterAction].debug("Chosen channel: ", process_type_,
60 
61  /* The production point of the new particles. */
62  FourVector middle_point = get_interaction_point();
63 
64  switch (process_type_) {
66  /* 2->2 elastic scattering */
68  break;
70  /* resonance formation */
72  break;
74  /* 2->2 inelastic scattering */
75  /* Sample the particle momenta in CM system. */
77  break;
81  /* 2->m scattering */
83  break;
91  break;
92  default:
94  "ScatterAction::generate_final_state: Invalid process type " +
95  std::to_string(static_cast<int>(process_type_)) + " was requested. " +
96  "(PDGcode1=" + incoming_particles_[0].pdgcode().string() +
97  ", PDGcode2=" + incoming_particles_[1].pdgcode().string() + ")");
98  }
99 
100  for (ParticleData &new_particle : outgoing_particles_) {
101  // Boost to the computational frame
102  new_particle.boost_momentum(
104  /* Set positions of the outgoing particles */
105  if (proc->get_type() != ProcessType::Elastic) {
106  new_particle.set_4position(middle_point);
107  }
108  }
109 }
110 
112  const ScatterActionsFinderParameters &finder_parameters) {
115  CollisionBranchList processes =
116  xs.generate_collision_list(finder_parameters, string_process_);
117 
118  /* Add various subprocesses.*/
119  add_collisions(std::move(processes));
120 
121  /* If the string processes are not triggered by a probability, then they
122  * always happen as long as the parametrized total cross section is larger
123  * than the sum of the cross sections of the non-string processes, and the
124  * square root s exceeds the threshold by at least 0.9 GeV. The cross section
125  * of the string processes are counted by taking the difference between the
126  * parametrized total and the sum of the non-strings. */
127  if (!finder_parameters.strings_with_probability &&
128  xs.string_probability(finder_parameters)) {
129  const double xs_diff =
130  xs.high_energy(finder_parameters.transition_high_energy) -
131  cross_section();
132  if (xs_diff > 0.) {
134  finder_parameters.use_AQM));
135  }
136  }
137 }
138 
140  return total_cross_section_ * incoming_particles_[0].xsec_scaling_factor() *
141  incoming_particles_[1].xsec_scaling_factor();
142 }
143 
145  return partial_cross_section_ * incoming_particles_[0].xsec_scaling_factor() *
146  incoming_particles_[1].xsec_scaling_factor();
147 }
148 
150  return total_momentum().velocity();
151 }
152 
153 double ScatterAction::gamma_cm() const {
154  return (1. / std::sqrt(1.0 - beta_cm().sqr()));
155 }
156 
157 double ScatterAction::mandelstam_s() const { return total_momentum().sqr(); }
158 
160  const double m1 = incoming_particles_[0].effective_mass();
161  const double m2 = incoming_particles_[1].effective_mass();
162  return pCM(sqrt_s(), m1, m2);
163 }
164 
166  const double m1 = incoming_particles_[0].effective_mass();
167  const double m2 = incoming_particles_[1].effective_mass();
168  return pCM_sqr(sqrt_s(), m1, m2);
169 }
170 
172  const double m1 = incoming_particles()[0].effective_mass();
173  const double m2 = incoming_particles()[1].effective_mass();
174  const double m_s = mandelstam_s();
175  const double lamb = lambda_tilde(m_s, m1 * m1, m2 * m2);
176  return std::sqrt(lamb) / (2. * incoming_particles()[0].momentum().x0() *
177  incoming_particles()[1].momentum().x0());
178 }
179 
181  // local copy of particles (since we need to boost them)
184  /* Boost particles to center-of-momentum frame. */
185  const ThreeVector velocity = beta_cm();
186  p_a.boost(velocity);
187  p_b.boost(velocity);
188  const ThreeVector pos_diff =
189  p_a.position().threevec() - p_b.position().threevec();
190  const ThreeVector mom_diff =
191  p_a.momentum().threevec() - p_b.momentum().threevec();
192 
193  logg[LScatterAction].debug("Particle ", incoming_particles_,
194  " position difference [fm]: ", pos_diff,
195  ", momentum difference [GeV]: ", mom_diff);
196 
197  const double dp2 = mom_diff.sqr();
198  const double dr2 = pos_diff.sqr();
199  /* Zero momentum leads to infite distance. */
200  if (dp2 < really_small) {
201  return dr2;
202  }
203  const double dpdr = pos_diff * mom_diff;
204 
205  /* UrQMD squared distance criterion, in the center of momentum frame:
206  * position of particle a: x_a
207  * position of particle b: x_b
208  * momentum of particle a: p_a
209  * momentum of particle b: p_b
210  * d^2_{coll} = (x_a - x_b)^2 - ((x_a - x_b) . (p_a - p_b))^2 / (p_a - p_b)^2
211  */
212  const double result = dr2 - dpdr * dpdr / dp2;
213  return result > 0.0 ? result : 0.0;
214 }
215 
217  // local copy of particles (since we need to boost them)
220 
221  const FourVector delta_x = p_a.position() - p_b.position();
222  const double mom_diff_sqr =
223  (p_a.momentum().threevec() - p_b.momentum().threevec()).sqr();
224  const double x_sqr = delta_x.sqr();
225 
226  if (mom_diff_sqr < really_small) {
227  return -x_sqr;
228  }
229 
230  const double p_a_sqr = p_a.momentum().sqr();
231  const double p_b_sqr = p_b.momentum().sqr();
232  const double p_a_dot_x = p_a.momentum().Dot(delta_x);
233  const double p_b_dot_x = p_b.momentum().Dot(delta_x);
234  const double p_a_dot_p_b = p_a.momentum().Dot(p_b.momentum());
235 
236  const double b_sqr =
237  -x_sqr -
238  (p_a_sqr * std::pow(p_b_dot_x, 2) + p_b_sqr * std::pow(p_a_dot_x, 2) -
239  2 * p_a_dot_p_b * p_a_dot_x * p_b_dot_x) /
240  (std::pow(p_a_dot_p_b, 2) - p_a_sqr * p_b_sqr);
241  return b_sqr > 0.0 ? b_sqr : 0.0;
242 }
243 
252 static double high_energy_bpp(double plab) {
253  double mandelstam_s = s_from_plab(plab, nucleon_mass, nucleon_mass);
254  return 7.6 + 0.66 * std::log(mandelstam_s);
255 }
256 
269 static double Cugnon_bpp(double plab) {
270  if (plab < 2.) {
271  double p8 = pow_int(plab, 8);
272  return 5.5 * p8 / (7.7 + p8);
273  } else {
274  return std::min(high_energy_bpp(plab), 5.334 + 0.67 * (plab - 2.));
275  }
276 }
277 
288 static double Cugnon_bnp(double plab) {
289  if (plab < 0.225) {
290  return 0.;
291  } else if (plab < 0.6) {
292  return 16.53 * (plab - 0.225);
293  } else if (plab < 1.6) {
294  return -1.63 * plab + 7.16;
295  } else {
296  return Cugnon_bpp(plab);
297  }
298 }
299 
300 void ScatterAction::sample_angles(std::pair<double, double> masses,
301  double kinetic_energy_cm) {
304  // We potentially have more than two particles, so the following angular
305  // distributions don't work. Instead we just keep the angular
306  // distributions generated by string fragmentation.
307  return;
308  }
309  assert(outgoing_particles_.size() == 2);
310 
311  // NN scattering is anisotropic currently
312  const bool nn_scattering = incoming_particles_[0].type().is_nucleon() &&
313  incoming_particles_[1].type().is_nucleon();
314  /* Elastic process is anisotropic and
315  * the angular distribution is based on the NN elastic scattering. */
316  const bool el_scattering = process_type_ == ProcessType::Elastic;
317 
318  const double mass_in_a = incoming_particles_[0].effective_mass();
319  const double mass_in_b = incoming_particles_[1].effective_mass();
320 
323 
324  const double mass_a = masses.first;
325  const double mass_b = masses.second;
326 
327  const std::array<double, 2> t_range = get_t_range<double>(
328  kinetic_energy_cm, mass_in_a, mass_in_b, mass_a, mass_b);
329  Angles phitheta;
330  if (el_scattering && !isotropic_) {
334  double mandelstam_s_new = 0.;
335  if (nn_scattering) {
336  mandelstam_s_new = mandelstam_s();
337  } else {
338  /* In the case of elastic collisions other than NN collisions,
339  * there is an ambiguity on how to get the lab-frame momentum (plab),
340  * since the incoming particles can have different masses.
341  * Right now, we first obtain the center-of-mass momentum
342  * of the collision (pcom_now).
343  * Then, the lab-frame momentum is evaluated from the mandelstam s,
344  * which yields the original center-of-mass momentum
345  * when nucleon mass is assumed. */
346  const double pcm_now = pCM_from_s(mandelstam_s(), mass_in_a, mass_in_b);
347  mandelstam_s_new =
348  4. * std::sqrt(pcm_now * pcm_now + nucleon_mass * nucleon_mass);
349  }
350  double bb, a, plab = plab_from_s(mandelstam_s_new);
351  if (nn_scattering &&
352  p_a->pdgcode().antiparticle_sign() ==
353  p_b->pdgcode().antiparticle_sign() &&
354  std::abs(p_a->type().charge() + p_b->type().charge()) == 1) {
355  // proton-neutron and antiproton-antineutron
356  bb = std::max(Cugnon_bnp(plab), really_small);
357  a = (plab < 0.8) ? 1. : 0.64 / (plab * plab);
358  } else {
359  /* all others including pp, nn and AQM elastic processes
360  * This is applied for all particle pairs, which are allowed to
361  * interact elastically. */
362  bb = std::max(Cugnon_bpp(plab), really_small);
363  a = 1.;
364  }
365  double t = random::expo(bb, t_range[0], t_range[1]);
366  if (random::canonical() > 1. / (1. + a)) {
367  t = t_range[0] + t_range[1] - t;
368  }
369  // determine scattering angles in center-of-mass frame
370  phitheta = Angles(2. * M_PI * random::canonical(),
371  1. - 2. * (t - t_range[0]) / (t_range[1] - t_range[0]));
372  } else if (nn_scattering && p_a->pdgcode().is_Delta() &&
373  p_b->pdgcode().is_nucleon() &&
374  p_a->pdgcode().antiparticle_sign() ==
375  p_b->pdgcode().antiparticle_sign() &&
376  !isotropic_) {
380  const double plab = plab_from_s(mandelstam_s());
381  const double bb = std::max(Cugnon_bpp(plab), really_small);
382  double t = random::expo(bb, t_range[0], t_range[1]);
383  if (random::canonical() > 0.5) {
384  t = t_range[0] + t_range[1] - t; // symmetrize
385  }
386  phitheta = Angles(2. * M_PI * random::canonical(),
387  1. - 2. * (t - t_range[0]) / (t_range[1] - t_range[0]));
388  } else if (nn_scattering && p_b->pdgcode().is_nucleon() && !isotropic_ &&
389  (p_a->type().is_Nstar() || p_a->type().is_Deltastar())) {
391  const std::array<double, 4> p{1.46434, 5.80311, -6.89358, 1.94302};
392  const double a = p[0] + mass_a * (p[1] + mass_a * (p[2] + mass_a * p[3]));
393  /* If the resonance is so heavy that the index "a" exceeds 30,
394  * the power function turns out to be too sharp. Take t directly to be
395  * t_0 in such a case. */
396  double t = t_range[0];
397  if (a < 30) {
398  t = random::power(-a, t_range[0], t_range[1]);
399  }
400  if (random::canonical() > 0.5) {
401  t = t_range[0] + t_range[1] - t; // symmetrize
402  }
403  phitheta = Angles(2. * M_PI * random::canonical(),
404  1. - 2. * (t - t_range[0]) / (t_range[1] - t_range[0]));
405  } else {
406  /* isotropic angular distribution */
407  phitheta.distribute_isotropically();
408  }
409 
410  ThreeVector pscatt = phitheta.threevec();
411  // 3-momentum of first incoming particle in center-of-mass frame
412  ThreeVector pcm =
413  incoming_particles_[0].momentum().lorentz_boost(beta_cm()).threevec();
414  pscatt.rotate_z_axis_to(pcm);
415 
416  // final-state CM momentum
417  const double p_f = pCM(kinetic_energy_cm, mass_a, mass_b);
418  if (!(p_f > 0.0)) {
419  logg[LScatterAction].warn("Particle: ", p_a->pdgcode(),
420  " radial momentum: ", p_f);
421  logg[LScatterAction].warn("Etot: ", kinetic_energy_cm, " m_a: ", mass_a,
422  " m_b: ", mass_b);
423  }
424  p_a->set_4momentum(mass_a, pscatt * p_f);
425  p_b->set_4momentum(mass_b, -pscatt * p_f);
426 
427  /* Debug message is printed before boost, so that p_a and p_b are
428  * the momenta in the center of mass frame and thus opposite to
429  * each other.*/
430  logg[LScatterAction].debug("p_a: ", *p_a, "\np_b: ", *p_b);
431 }
432 
434  // copy initial particles into final state
437  // resample momenta
438  sample_angles({outgoing_particles_[0].effective_mass(),
439  outgoing_particles_[1].effective_mass()},
440  sqrt_s());
441 }
442 
444  // create new particles
447 }
448 
452  logg[LScatterAction].debug("2->", outgoing_particles_.size(),
453  " scattering:", incoming_particles_, " -> ",
455 }
456 
458  if (outgoing_particles_.size() != 1) {
459  std::string s =
460  "resonance_formation: "
461  "Incorrect number of particles in final state: ";
462  s += std::to_string(outgoing_particles_.size()) + " (";
463  s += incoming_particles_[0].pdgcode().string() + " + ";
464  s += incoming_particles_[1].pdgcode().string() + ")";
465  throw InvalidResonanceFormation(s);
466  }
467  // Set the momentum of the formed resonance in its rest frame.
468  outgoing_particles_[0].set_4momentum(
469  total_momentum_of_outgoing_particles().abs(), 0., 0., 0.);
471  /* this momentum is evaluated in the computational frame. */
472  logg[LScatterAction].debug("Momentum of the new particle: ",
473  outgoing_particles_[0].momentum());
474 }
475 
476 /* This function generates the outgoing state when
477  * ScatterAction::string_excitation() is used */
478 
482  /* Check momentum difference for debugging */
483  FourVector out_mom;
484  for (ParticleData data : outgoing_particles_) {
485  out_mom += data.momentum();
486  }
487  logg[LPythia].debug("Incoming momenta string:", total_momentum());
488  logg[LPythia].debug("Outgoing momenta string:", out_mom);
489 }
490 
491 /* This function will generate outgoing particles in computational frame
492  * from a hard process.
493  * The way to excite soft strings is based on the UrQMD model */
494 
496  assert(incoming_particles_.size() == 2);
497  // Disable floating point exception trap for Pythia
498  {
499  DisableFloatTraps guard;
500  /* initialize the string_process_ object for this particular collision */
502  /* implement collision */
503  bool success = false;
504  int ntry = 0;
505  const int ntry_max = 10000;
506  while (!success && ntry < ntry_max) {
507  ntry++;
508  switch (process_type_) {
510  /* single diffractive to A+X */
511  success = string_process_->next_SDiff(true);
512  break;
514  /* single diffractive to X+B */
515  success = string_process_->next_SDiff(false);
516  break;
518  /* double diffractive */
519  success = string_process_->next_DDiff();
520  break;
522  /* soft non-diffractive */
523  success = string_process_->next_NDiffSoft();
524  break;
526  /* soft BBbar 2 mesonic annihilation */
527  success = string_process_->next_BBbarAnn();
528  break;
530  success = string_process_->next_NDiffHard();
531  break;
532  default:
533  logg[LPythia].error("Unknown string process required.");
534  success = false;
535  }
536  }
537  if (ntry == ntry_max) {
538  /* If pythia fails to form a string, it is usually because the energy
539  * is not large enough. In this case, annihilation is then enforced. If
540  * this process still does not not produce any results, it defaults to
541  * an elastic collision. */
542  bool success_newtry = false;
543 
544  /* Check if the initial state is a baryon-antibaryon state.*/
545  PdgCode part1 = incoming_particles_[0].pdgcode(),
546  part2 = incoming_particles_[1].pdgcode();
547  bool is_BBbar_Pair = (part1.baryon_number() != 0) &&
548  (part1.baryon_number() == -part2.baryon_number());
549 
550  /* Decide on the new process .*/
551  if (is_BBbar_Pair) {
553  } else {
555  }
556  /* Perform the new process*/
557  int ntry_new = 0;
558  while (!success_newtry && ntry_new < ntry_max) {
559  ntry_new++;
560  if (is_BBbar_Pair) {
561  success_newtry = string_process_->next_BBbarAnn();
562  } else {
563  success_newtry = string_process_->next_DDiff();
564  }
565  }
566 
567  if (success_newtry) {
569  }
570 
571  if (!success_newtry) {
572  /* If annihilation fails:
573  * Particles are normally added after process selection for
574  * strings, outgoing_particles is still uninitialized, and memory
575  * needs to be allocated. We also shift the process_type_ to elastic
576  * so that sample_angles does a proper treatment. */
577  outgoing_particles_.reserve(2);
582  }
583  } else {
585  }
586  }
587 }
588 
589 void ScatterAction::format_debug_output(std::ostream &out) const {
590  out << "Scatter of " << incoming_particles_;
591  if (outgoing_particles_.empty()) {
592  out << " (not performed)";
593  } else {
594  out << " to " << outgoing_particles_;
595  }
596 }
597 
598 } // namespace smash
Thrown for example when ScatterAction is called to perform with a wrong number of final-state particl...
Definition: action.h:330
Action is the base class for a generic process that takes a number of incoming particles and transfor...
Definition: action.h:35
void sample_2body_phasespace()
Sample the full 2-body phase-space (masses, momenta, angles) in the center-of-mass frame for the fina...
Definition: action.cc:302
FourVector total_momentum_of_outgoing_particles() const
Calculate the total kinetic momentum of the outgoing particles.
Definition: action.cc:157
void assign_formation_time_to_outgoing_particles()
Assign the formation time to the outgoing particles.
Definition: action.cc:188
std::pair< FourVector, FourVector > get_potential_at_interaction_point() const
Get the skyrme and asymmetry potential at the interaction point.
Definition: action.cc:112
ParticleList outgoing_particles_
Initially this stores only the PDG codes of final-state particles.
Definition: action.h:353
FourVector total_momentum() const
Sum of 4-momenta of incoming particles.
Definition: action.h:379
virtual void sample_manybody_phasespace()
Sample the full n-body phase-space (masses, momenta, angles) in the center-of-mass frame for the fina...
Definition: action.cc:442
const double time_of_execution_
Time at which the action is supposed to be performed (absolute time in the lab frame in fm).
Definition: action.h:359
const ParticleList & incoming_particles() const
Get the list of particles that go into the action.
Definition: action.cc:58
double sqrt_s() const
Determine the total energy in the center-of-mass frame [GeV].
Definition: action.h:271
ParticleList incoming_particles_
List with data of incoming particles.
Definition: action.h:345
FourVector get_interaction_point() const
Get the interaction point.
Definition: action.cc:68
static double lambda_tilde(double a, double b, double c)
Little helper function that calculates the lambda function (sometimes written with a tilde to better ...
Definition: action.h:315
ProcessType process_type_
type of process
Definition: action.h:362
Angles provides a common interface for generating directions: i.e., two angles that should be interpr...
Definition: angles.h:59
ThreeVector threevec() const
Definition: angles.h:288
void distribute_isotropically()
Populate the object with a new direction.
Definition: angles.h:199
CollisionBranch is a derivative of ProcessBranch, which is used to represent particular final-state c...
ProcessType get_type() const override
The cross section class assembels everything that is needed to calculate the cross section and return...
Definition: crosssections.h:31
double string_probability(const ScatterActionsFinderParameters &finder_parameters) const
CollisionBranchList string_excitation(double total_string_xs, StringProcess *string_process, bool use_AQM) const
Determine the cross section for string excitations, which is given by the difference between the para...
CollisionBranchList generate_collision_list(const ScatterActionsFinderParameters &finder_parameters, StringProcess *string_process) const
Generate a list of all possible collisions between the incoming particles with the given c....
double high_energy(const StringTransitionParameters &transition_high_energy) const
Determine the parametrized total cross section at high energies for the given collision,...
Guard type that safely disables floating point traps for the scope in which it is placed.
Definition: fpenvironment.h:79
The FourVector class holds relevant values in Minkowski spacetime with (+, −, −, −) metric signature.
Definition: fourvector.h:33
double sqr() const
calculate the square of the vector (which is a scalar)
Definition: fourvector.h:460
ThreeVector threevec() const
Definition: fourvector.h:329
double Dot(const FourVector &a) const
calculate the scalar product with another four-vector
Definition: fourvector.h:456
ThreeVector velocity() const
Get the velocity (3-vector divided by zero component).
Definition: fourvector.h:333
ParticleData contains the dynamic information of a certain particle.
Definition: particledata.h:58
PdgCode pdgcode() const
Get the pdgcode of the particle.
Definition: particledata.h:87
void set_4momentum(const FourVector &momentum_vector)
Set the particle's 4-momentum directly.
Definition: particledata.h:164
const ParticleType & type() const
Get the type of the particle.
Definition: particledata.h:128
const FourVector & momentum() const
Get the particle's 4-momentum.
Definition: particledata.h:158
void boost(const ThreeVector &v)
Apply a full Lorentz boost of momentum and position.
Definition: particledata.h:323
const FourVector & position() const
Get the particle's position in Minkowski space.
Definition: particledata.h:204
bool is_Nstar() const
Definition: particletype.h:227
int32_t charge() const
The charge of the particle.
Definition: particletype.h:188
bool is_Deltastar() const
Definition: particletype.h:236
PdgCode stores a Particle Data Group Particle Numbering Scheme particle type number.
Definition: pdgcode.h:110
int antiparticle_sign() const
Definition: pdgcode.h:650
int baryon_number() const
Definition: pdgcode.h:380
bool is_nucleon() const
Definition: pdgcode.h:396
bool is_Delta() const
Definition: pdgcode.h:420
ParticleList particle_list() const
double weight() const
Thrown when ScatterAction is called to perform with unknown ProcessType.
bool isotropic_
Do this collision isotropically?
void add_collision(CollisionBranchPtr p)
Add a new collision channel.
void resonance_formation()
Perform a 2->1 resonance-formation process.
ThreeVector beta_cm() const
Get the velocity of the center of mass of the scattering/incoming particles in the calculation frame.
double partial_cross_section_
Partial cross-section to the chosen outgoing channel.
double relative_velocity() const
Get the relative velocity of the two incoming particles.
double mandelstam_s() const
Determine the Mandelstam s variable,.
double get_partial_weight() const override
Get the partial cross section of the chosen channel.
StringProcess * string_process_
Pointer to interface class for strings.
void create_string_final_state()
Creates the final states for string-processes after they are performed.
double cm_momentum_squared() const
Get the squared momentum of the center of mass of the incoming particles in the calculation frame.
void generate_final_state() override
Generate the final-state of the scattering process.
void add_all_scatterings(const ScatterActionsFinderParameters &finder_parameters)
Add all possible scattering subprocesses for this action object.
void two_to_many_scattering()
Perform an inelastic two-to-many-body scattering (more than 2)
double get_total_weight() const override
Get the total cross section of scattering particles.
void string_excitation()
Todo(ryu): document better - it is not really UrQMD-based, isn't it? Perform the UrQMD-based string e...
void elastic_scattering()
Perform an elastic two-body scattering, i.e. just exchange momentum.
void inelastic_scattering()
Perform an inelastic two-body scattering, i.e. new particles are formed.
ScatterAction(const ParticleData &in_part1, const ParticleData &in_part2, double time, bool isotropic=false, double string_formation_time=1.0, double box_length=-1.0)
Construct a ScatterAction object.
void sample_angles(std::pair< double, double > masses, double kinetic_energy_cm) override
Sample final-state angles in a 2->2 collision (possibly anisotropic).
void add_collisions(CollisionBranchList pv)
Add several new collision channels at once.
double total_cross_section_
Total hadronic cross section.
double gamma_cm() const
Get the gamma factor corresponding to a boost to the center of mass frame of the colliding particles.
double cm_momentum() const
Get the momentum of the center of mass of the incoming particles in the calculation frame.
double cov_transverse_distance_sqr() const
Calculate the transverse distance of the two incoming particles in their local rest frame written in ...
virtual double cross_section() const
Get the total cross section of the scattering particles.
CollisionBranchList collision_channels_
List of possible collisions.
double transverse_distance_sqr() const
Calculate the transverse distance of the two incoming particles in their local rest frame.
bool next_SDiff(bool is_AB_to_AX)
Single-diffractive process is based on single pomeron exchange described in Ingelman:1984ns .
bool next_NDiffSoft()
Soft Non-diffractive process is modelled in accordance with dual-topological approach Capella:1978ig ...
bool next_DDiff()
Double-diffractive process ( A + B -> X + X ) is similar to the single-diffractive process,...
ParticleList get_final_state()
a function to get the final state particle list which is called after the collision
bool next_BBbarAnn()
Baryon-antibaryon annihilation process Based on what UrQMD Bass:1998ca , Bleicher:1999xi does,...
void init(const ParticleList &incoming, double tcoll)
initialization feed intial particles, time of collision and gamma factor of the center of mass.
bool next_NDiffHard()
Hard Non-diffractive process is based on PYTHIA 8 with partonic showers and interactions.
The ThreeVector class represents a physical three-vector with the components .
Definition: threevector.h:31
double sqr() const
Definition: threevector.h:266
void rotate_z_axis_to(ThreeVector &r)
Rotate the z-axis onto the vector r.
Definition: threevector.h:326
Collection of useful constants that are known at compile time.
std::array< einhard::Logger<>, std::tuple_size< LogArea::AreaTuple >::value > logg
An array that stores all pre-configured Logger objects.
Definition: logging.cc:39
void format_debug_output(std::ostream &out) const override
Writes information about this scatter action to the out stream.
constexpr int p
Proton.
T power(T n, T xMin, T xMax)
Draws a random number according to a power-law distribution ~ x^n.
Definition: random.h:203
T expo(T A, T x1, T x2)
Draws a random number x from an exponential distribution exp(A*x), where A is assumed to be positive,...
Definition: random.h:166
T canonical()
Definition: random.h:113
Definition: action.h:24
double plab_from_s(double mandelstam_s, double mass)
Convert Mandelstam-s to p_lab in a fixed-target collision.
Definition: kinematics.h:157
static double Cugnon_bnp(double plab)
Computes the B coefficients from the Cugnon parametrization of the angular distribution in elastic np...
T pCM(const T sqrts, const T mass_a, const T mass_b) noexcept
Definition: kinematics.h:79
T pCM_sqr(const T sqrts, const T mass_a, const T mass_b) noexcept
Definition: kinematics.h:91
@ FailedString
See here for a short description.
@ TwoToOne
See here for a short description.
@ StringSoftDoubleDiffractive
See here for a short description.
@ TwoToFive
See here for a short description.
@ StringSoftSingleDiffractiveXB
See here for a short description.
@ TwoToTwo
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.
@ StringSoftNonDiffractive
See here for a short description.
@ StringSoftSingleDiffractiveAX
See here for a short description.
@ StringHard
See here for a short description.
@ TwoToThree
See here for a short description.
static double high_energy_bpp(double plab)
Computes the B coefficients from the STAR fit, see fig.
constexpr double nucleon_mass
Nucleon mass in GeV.
Definition: constants.h:58
constexpr T pow_int(const T base, unsigned const exponent)
Efficient template for calculating integer powers using squaring.
Definition: pow.h:23
T pCM_from_s(const T s, const T mass_a, const T mass_b) noexcept
Definition: kinematics.h:66
constexpr double really_small
Numerical error tolerance.
Definition: constants.h:37
static constexpr int LScatterAction
static constexpr int LPythia
Definition: stringprocess.h:26
bool is_string_soft_process(ProcessType p)
Check if a given process type is a soft string excitation.
double s_from_plab(double plab, double m_P, double m_T)
Convert p_lab to Mandelstam-s for a fixed-target setup, with a projectile of mass m_P and momentum pl...
Definition: kinematics.h:265
static double Cugnon_bpp(double plab)
Computes the B coefficients from the Cugnon parametrization of the angular distribution in elastic pp...
Helper structure for ScatterActionsFinder.
const bool strings_with_probability
This indicates whether the string fragmentation is swiched on with a probability smoothly increasing ...
const bool use_AQM
Switch to control whether to use AQM or not.
const StringTransitionParameters transition_high_energy
Constants related to transition between low collision energies - mediated via resonances - and high c...