Version: SMASH-2.2
smash::ScatterActionsFinder Class Reference

#include <scatteractionsfinder.h>

A simple scatter finder: Just loops through all particles and checks each pair for a collision.

It supports two collision criteria: a geometric and stochastic criterion.

Definition at line 30 of file scatteractionsfinder.h.

Inheritance diagram for smash::ScatterActionsFinder:
[legend]
Collaboration diagram for smash::ScatterActionsFinder:
[legend]

Public Member Functions

 ScatterActionsFinder (Configuration config, const ExperimentParameters &parameters)
 Constructor of the finder with the given parameters. More...
 
double collision_time (const ParticleData &p1, const ParticleData &p2, double dt, const std::vector< FourVector > &beam_momentum) const
 Determine the collision time of the two particles. More...
 
ActionList find_actions_in_cell (const ParticleList &search_list, double dt, const double gcell_vol, const std::vector< FourVector > &beam_momentum) const override
 Search for all the possible collisions within one cell. More...
 
ActionList find_actions_with_neighbors (const ParticleList &search_list, const ParticleList &neighbors_list, double dt, const std::vector< FourVector > &beam_momentum) const override
 Search for all the possible collisions among the neighboring cells. More...
 
ActionList find_actions_with_surrounding_particles (const ParticleList &search_list, const Particles &surrounding_list, double dt, const std::vector< FourVector > &beam_momentum) const override
 Search for all the possible secondary collisions between the outgoing particles and the rest. More...
 
ActionList find_final_actions (const Particles &, bool=false) const override
 Find some final collisions at the end of the simulation. More...
 
bool is_constant_elastic_isotropic () const
 If there is only one particle sort, no decays (only elastic scatterings are possible), scatterings are isotropic and cross-section fixed to elastic_parameter_ independently on momenta, then maximal cross-section is elastic_parameter_. More...
 
double max_transverse_distance_sqr (int testparticles) const
 The maximal distance over which particles can interact in case of the geometric criterion, related to the number of test particles and the maximal cross section. More...
 
void dump_reactions () const
 Prints out all the 2-> n (n > 1) reactions with non-zero cross-sections between all possible pairs of particle types. More...
 
void dump_cross_sections (const ParticleType &a, const ParticleType &b, double m_a, double m_b, bool final_state, std::vector< double > &plab) const
 Print out partial cross-sections of all processes that can occur in the collision of a(mass = m_a) and b(mass = m_b). More...
 
StringProcessget_process_string_ptr ()
 
- Public Member Functions inherited from smash::ActionFinderInterface
virtual ~ActionFinderInterface ()=default
 

Private Member Functions

ActionPtr check_collision_two_part (const ParticleData &data_a, const ParticleData &data_b, double dt, const std::vector< FourVector > &beam_momentum={}, const double gcell_vol=0.0) const
 Check for a single pair of particles (id_a, id_b) if a collision will happen in the next timestep and create a corresponding Action object in that case. More...
 
ActionPtr check_collision_multi_part (const ParticleList &plist, double dt, const double gcell_vol) const
 Check for multiple i.e. More...
 

Private Attributes

std::unique_ptr< StringProcessstring_process_interface_
 Class that deals with strings, interfacing Pythia. More...
 
const CollisionCriterion coll_crit_
 Specifies which collision criterion is used. More...
 
const double elastic_parameter_
 Elastic cross section parameter (in mb). More...
 
const int testparticles_
 Number of test particles. More...
 
const bool isotropic_
 Do all collisions isotropically. More...
 
const bool two_to_one_
 Enable 2->1 processes. More...
 
const ReactionsBitSet incl_set_
 List of included 2<->2 reactions. More...
 
const MultiParticleReactionsBitSet incl_multi_set_
 List of included multi-particle reactions. More...
 
const double scale_xs_
 Factor by which all (partial) cross sections are scaled. More...
 
const double additional_el_xs_
 Additional constant elastic cross section. More...
 
const double low_snn_cut_
 Elastic collsions between two nucleons with sqrt_s below low_snn_cut_ are excluded. More...
 
const bool strings_switch_
 Switch to turn off string excitation. More...
 
const bool use_AQM_
 Switch to control whether to use AQM or not. More...
 
const bool strings_with_probability_
 Decide whether to implement string fragmentation based on a probability. More...
 
const NNbarTreatment nnbar_treatment_
 Switch for NNbar reactions. More...
 
const double box_length_
 Box length: needed to determine coordinates of collision correctly in case of collision through the wall. More...
 
const double string_formation_time_
 Parameter for formation time. More...
 
const double maximum_cross_section_
 
const bool allow_first_collisions_within_nucleus_
 If particles within nucleus are allowed to collide for their first time. More...
 
const bool only_warn_for_high_prob_
 Switch to turn off throwing an exception for collision probabilities larger than 1. More...
 

Constructor & Destructor Documentation

◆ ScatterActionsFinder()

smash::ScatterActionsFinder::ScatterActionsFinder ( Configuration  config,
const ExperimentParameters parameters 
)

Constructor of the finder with the given parameters.

Parameters
[in]configConfiguration of smash from which we take: 1) A global elastic cross section [mb]. It will be used regardless of the species of the colliding particles. It won't be used if the value is negative. 2) An option determining whether all the scatterings are isotropic 3) Parameters of the string process
[in]parametersStruct of parameters determining whether to exclude some certain types of scatterings and switching among the methods to treat with the NNbar collisions.

Definition at line 308 of file scatteractionsfinder.cc.

310  : coll_crit_(parameters.coll_crit),
312  config.take({"Collision_Term", "Elastic_Cross_Section"}, -1.)),
313  testparticles_(parameters.testparticles),
314  isotropic_(config.take({"Collision_Term", "Isotropic"}, false)),
315  two_to_one_(parameters.two_to_one),
316  incl_set_(parameters.included_2to2),
317  incl_multi_set_(parameters.included_multi),
318  scale_xs_(parameters.scale_xs),
319  additional_el_xs_(parameters.additional_el_xs),
320  low_snn_cut_(parameters.low_snn_cut),
321  strings_switch_(parameters.strings_switch),
322  use_AQM_(parameters.use_AQM),
323  strings_with_probability_(parameters.strings_with_probability),
324  nnbar_treatment_(parameters.nnbar_treatment),
325  box_length_(parameters.box_length),
326  string_formation_time_(config.take(
327  {"Collision_Term", "String_Parameters", "Formation_Time"}, 1.)),
328  maximum_cross_section_(parameters.maximum_cross_section),
330  parameters.allow_collisions_within_nucleus),
331  only_warn_for_high_prob_(config.take(
332  {"Collision_Term", "Only_Warn_For_High_Probability"}, false)) {
334  logg[LFindScatter].info(
335  "Constant elastic isotropic cross-section mode:", " using ",
336  elastic_parameter_, " mb as maximal cross-section.");
337  }
339  throw std::invalid_argument(
340  "Multi-body reactions (like e.g. 3->1 or 3->2) are only possible with "
341  "the stochastic "
342  "collision "
343  "criterion. Change your config accordingly.");
344  }
345 
349  throw std::invalid_argument(
350  "To prevent double counting it is not possible to enable deuteron 3->2 "
351  "reactions\nand reactions involving the d' at the same time\ni.e. to "
352  "include \"Deuteron_3to2\" in `Multi_Particle_Reactions` and\n "
353  "\"PiDeuteron_to_pidprime\" "
354  "or \"NDeuteron_to_Ndprime\" in `Included_2to2` at the same time.\n"
355  "Change your config accordingly.");
356  }
357 
360  throw std::invalid_argument(
361  "Do not use the d' resonance and enable \"Deuteron_3to2\" "
362  "`Multi_Particle_Reactions` at the same time. Either use the direct "
363  "3-to-2 reactions or the d' together with \"PiDeuteron_to_pidprime\" "
364  "and \"NDeuteron_to_Ndprime\" in `Included_2to2`. Otherwise the "
365  "deuteron 3-to-2 reactions would be double counted.");
366  }
367 
372  throw std::invalid_argument(
373  "In order to conserve detailed balance, when \"NNbar_5to2\" is "
374  "included in\n`Multi_Particle_Reactions`, the `NNbarTreatment` has to "
375  "be set to \"two to five\" and vice versa.");
376  }
377 
380  throw std::invalid_argument(
381  "'NNbar' has to be in the list of allowed 2 to 2 processes "
382  "to enable annihilation to go through resonances");
383  }
384 
385  if (strings_switch_) {
386  auto subconfig = config["Collision_Term"]["String_Parameters"];
387  string_process_interface_ = make_unique<StringProcess>(
388  subconfig.take({"String_Tension"}, 1.0), string_formation_time_,
389  subconfig.take({"Gluon_Beta"}, 0.5),
390  subconfig.take({"Gluon_Pmin"}, 0.001),
391  subconfig.take({"Quark_Alpha"}, 2.0),
392  subconfig.take({"Quark_Beta"}, 7.0),
393  subconfig.take({"Strange_Supp"}, 0.16),
394  subconfig.take({"Diquark_Supp"}, 0.036),
395  subconfig.take({"Sigma_Perp"}, 0.42),
396  subconfig.take({"StringZ_A_Leading"}, 0.2),
397  subconfig.take({"StringZ_B_Leading"}, 2.0),
398  subconfig.take({"StringZ_A"}, 2.0), subconfig.take({"StringZ_B"}, 0.55),
399  subconfig.take({"String_Sigma_T"}, 0.5),
400  subconfig.take({"Form_Time_Factor"}, 1.0),
401  subconfig.take({"Mass_Dependent_Formation_Times"}, false),
402  subconfig.take({"Prob_proton_to_d_uu"}, 1. / 3.),
403  subconfig.take({"Separate_Fragment_Baryon"}, true),
404  subconfig.take({"Popcorn_Rate"}, 0.15));
405  }
406 }
static const ParticleTypePtr try_find(PdgCode pdgcode)
Returns the ParticleTypePtr for the given pdgcode.
Definition: particletype.cc:89
const int testparticles_
Number of test particles.
const MultiParticleReactionsBitSet incl_multi_set_
List of included multi-particle reactions.
const double elastic_parameter_
Elastic cross section parameter (in mb).
const bool strings_switch_
Switch to turn off string excitation.
const double additional_el_xs_
Additional constant elastic cross section.
const double scale_xs_
Factor by which all (partial) cross sections are scaled.
const bool allow_first_collisions_within_nucleus_
If particles within nucleus are allowed to collide for their first time.
const NNbarTreatment nnbar_treatment_
Switch for NNbar reactions.
const double low_snn_cut_
Elastic collsions between two nucleons with sqrt_s below low_snn_cut_ are excluded.
const bool use_AQM_
Switch to control whether to use AQM or not.
const bool isotropic_
Do all collisions isotropically.
const bool only_warn_for_high_prob_
Switch to turn off throwing an exception for collision probabilities larger than 1.
const CollisionCriterion coll_crit_
Specifies which collision criterion is used.
const ReactionsBitSet incl_set_
List of included 2<->2 reactions.
const bool two_to_one_
Enable 2->1 processes.
const double string_formation_time_
Parameter for formation time.
std::unique_ptr< StringProcess > string_process_interface_
Class that deals with strings, interfacing Pythia.
bool is_constant_elastic_isotropic() const
If there is only one particle sort, no decays (only elastic scatterings are possible),...
const double box_length_
Box length: needed to determine coordinates of collision correctly in case of collision through the w...
const bool strings_with_probability_
Decide whether to implement string fragmentation based on a probability.
@ TwoToFive
Directly create 5 pions, use with multi-particle reactions.
@ Resonances
Use intermediate Resonances.
@ NNbar_5to2
@ Deuteron_3to2
@ Stochastic
Stochastic Criteiron.
@ PiDeuteron_to_pidprime
@ NDeuteron_to_Ndprime
std::array< einhard::Logger<>, std::tuple_size< LogArea::AreaTuple >::value > logg
An array that stores all pre-configured Logger objects.
Definition: logging.cc:39
const PdgCode dprime(PdgCode::from_decimal(1000010021))
Deuteron-prime resonance.
static constexpr int LFindScatter

Member Function Documentation

◆ collision_time()

double smash::ScatterActionsFinder::collision_time ( const ParticleData p1,
const ParticleData p2,
double  dt,
const std::vector< FourVector > &  beam_momentum 
) const
inline

Determine the collision time of the two particles.

Time of the closest approach is taken as collision time, if the geometric collision criterion is used. For stochastic criterion the time is distributed uniformly within the timestep.

Parameters
[in]p1First incoming particle
[in]p2Second incoming particle
[in]dtThe maximum time interval at the current time step [fm]
[in]beam_momentum[GeV] List of beam momenta for each particle; only necessary for frozen Fermi motion
Returns
How long does it take for the two incoming particles to propagate before scattering [fm/c]. It's set equal to -1 if the two particles are not moving relative to each other.

JAM collision times from the closest approach in the two-particle center-of-mass-framem, see Hirano:2012yy [23] (5.13) and (5.14). The scatteraction is performed at the mean of these two times.

UrQMD collision time in computational frame, see Bass:1998ca [4] (3.28): position of particle 1: \(r_1\) [fm] position of particle 2: \(r_2\) [fm] velocity of particle 1: \(v_1\) velocity of particle 1: \(v_2\)

\[t_{coll} = - (r_1 - r_2) . (v_1 - v_2) / (v_1 - v_2)^2\]

[fm/c]

Definition at line 65 of file scatteractionsfinder.h.

67  {
69  return dt * random::uniform(0., 1.);
70  } else {
71  /*
72  * For frozen Fermi motion:
73  * If particles have not yet interacted and are the initial nucleons,
74  * perform action finding with beam momentum instead of Fermi motion
75  * corrected momentum. That is because the particles are propagated with
76  * the beam momentum until they interact.
77  */
78  if (p1.id() < 0 || p2.id() < 0) {
79  throw std::runtime_error("Invalid particle ID for Fermi motion");
80  }
81  const bool p1_has_no_prior_interactions =
82  (static_cast<uint64_t>(p1.id()) < // particle from
83  static_cast<uint64_t>(beam_momentum.size())) && // initial nucleus
84  (p1.get_history().collisions_per_particle == 0);
85 
86  const bool p2_has_no_prior_interactions =
87  (static_cast<uint64_t>(p2.id()) < // particle from
88  static_cast<uint64_t>(beam_momentum.size())) && // initial nucleus
89  (p2.get_history().collisions_per_particle == 0);
90 
91  const FourVector p1_mom = (p1_has_no_prior_interactions)
92  ? beam_momentum[p1.id()]
93  : p1.momentum();
94  const FourVector p2_mom = (p2_has_no_prior_interactions)
95  ? beam_momentum[p2.id()]
96  : p2.momentum();
104  const FourVector delta_x = p1.position() - p2.position();
105  const double p1_sqr = p1_mom.sqr();
106  const double p2_sqr = p2_mom.sqr();
107  const double p1_dot_x = p1_mom.Dot(delta_x);
108  const double p2_dot_x = p2_mom.Dot(delta_x);
109  const double p1_dot_p2 = p1_mom.Dot(p2_mom);
110  const double denominator = std::pow(p1_dot_p2, 2) - p1_sqr * p2_sqr;
111  if (unlikely(std::abs(denominator) < really_small * really_small)) {
112  return -1.0;
113  }
114 
115  const double time_1 = (p2_sqr * p1_dot_x - p1_dot_p2 * p2_dot_x) *
116  p1_mom.x0() / denominator;
117  const double time_2 = -(p1_sqr * p2_dot_x - p1_dot_p2 * p1_dot_x) *
118  p2_mom.x0() / denominator;
119  return (time_1 + time_2) / 2;
120  } else {
130  const ThreeVector dv_times_e1e2 =
131  p1_mom.threevec() * p2_mom.x0() - p2_mom.threevec() * p1_mom.x0();
132  const double dv_times_e1e2_sqr = dv_times_e1e2.sqr();
133  if (dv_times_e1e2_sqr < really_small) {
134  return -1.0;
135  }
136  const ThreeVector dr =
137  p1.position().threevec() - p2.position().threevec();
138  return -(dr * dv_times_e1e2) *
139  (p1_mom.x0() * p2_mom.x0() / dv_times_e1e2_sqr);
140  }
141  }
142  }
@ Covariant
Covariant Criterion.
#define unlikely(x)
Tell the branch predictor that this expression is likely false.
Definition: macros.h:16
T uniform(T min, T max)
Definition: random.h:88
constexpr double really_small
Numerical error tolerance.
Definition: constants.h:37
Here is the call graph for this function:
Here is the caller graph for this function:

◆ find_actions_in_cell()

ActionList smash::ScatterActionsFinder::find_actions_in_cell ( const ParticleList &  search_list,
double  dt,
const double  gcell_vol,
const std::vector< FourVector > &  beam_momentum 
) const
overridevirtual

Search for all the possible collisions within one cell.

This function is only used for counting the primary collisions at the beginning of each time step. (Although it's also called afterwards for searching the secondary collisions among the outgoing particles, no new actions will be found since the scattered pairs cannot scatter again.)

Parameters
[in]search_listA list of particles within one cell
[in]dtThe maximum time interval at the current time step [fm]
[in]gcell_volVolume of searched grid cell [fm^3]
[in]beam_momentum[GeV] List of beam momenta for each particle; only necessary for frozen Fermi motion
Returns
A list of possible scatter actions

Implements smash::ActionFinderInterface.

Definition at line 616 of file scatteractionsfinder.cc.

618  {
619  std::vector<ActionPtr> actions;
620  for (const ParticleData& p1 : search_list) {
621  for (const ParticleData& p2 : search_list) {
622  // Check for 2 particle scattering
623  if (p1.id() < p2.id()) {
624  ActionPtr act =
625  check_collision_two_part(p1, p2, dt, beam_momentum, gcell_vol);
626  if (act) {
627  actions.push_back(std::move(act));
628  }
629  }
630  if (incl_multi_set_.any()) {
631  // Also, check for 3 particle scatterings with stochastic criterion
632  for (const ParticleData& p3 : search_list) {
634  1 ||
636  1) {
637  if (p1.id() < p2.id() && p2.id() < p3.id()) {
638  ActionPtr act =
639  check_collision_multi_part({p1, p2, p3}, dt, gcell_vol);
640  if (act) {
641  actions.push_back(std::move(act));
642  }
643  }
644  }
645  for (const ParticleData& p4 : search_list) {
646  if (incl_multi_set_
648  if (p1.id() < p2.id() && p2.id() < p3.id() && p3.id() < p4.id()) {
649  ActionPtr act =
650  check_collision_multi_part({p1, p2, p3, p4}, dt, gcell_vol);
651  if (act) {
652  actions.push_back(std::move(act));
653  }
654  }
655  }
657  1 &&
658  search_list.size() >= 5) {
659  for (const ParticleData& p5 : search_list) {
660  if ((p1.id() < p2.id() && p2.id() < p3.id() &&
661  p3.id() < p4.id() && p4.id() < p5.id()) &&
662  (p1.is_pion() && p2.is_pion() && p3.is_pion() &&
663  p4.is_pion() && p5.is_pion())) {
664  // at the moment only pure pion 5-body reactions
665  ActionPtr act = check_collision_multi_part(
666  {p1, p2, p3, p4, p5}, dt, gcell_vol);
667  if (act) {
668  actions.push_back(std::move(act));
669  }
670  }
671  }
672  }
673  }
674  }
675  }
676  }
677  }
678  return actions;
679 }
ActionPtr check_collision_two_part(const ParticleData &data_a, const ParticleData &data_b, double dt, const std::vector< FourVector > &beam_momentum={}, const double gcell_vol=0.0) const
Check for a single pair of particles (id_a, id_b) if a collision will happen in the next timestep and...
ActionPtr check_collision_multi_part(const ParticleList &plist, double dt, const double gcell_vol) const
Check for multiple i.e.
@ A3_Nuclei_4to2
@ Meson_3to1
Here is the call graph for this function:

◆ find_actions_with_neighbors()

ActionList smash::ScatterActionsFinder::find_actions_with_neighbors ( const ParticleList &  search_list,
const ParticleList &  neighbors_list,
double  dt,
const std::vector< FourVector > &  beam_momentum 
) const
overridevirtual

Search for all the possible collisions among the neighboring cells.

This function is only used for counting the primary collisions at the beginning of each time step.

Parameters
[in]search_listA list of particles within the current cell
[in]neighbors_listA list of particles within the neighboring cell
[in]dtThe maximum time interval at the current time step [fm/c]
[in]beam_momentum[GeV] List of beam momenta for each particle; only necessary for frozen Fermi motion
Returns
A list of possible scatter actions

Implements smash::ActionFinderInterface.

Definition at line 681 of file scatteractionsfinder.cc.

683  {
684  std::vector<ActionPtr> actions;
686  // Only search in cells
687  return actions;
688  }
689  for (const ParticleData& p1 : search_list) {
690  for (const ParticleData& p2 : neighbors_list) {
691  assert(p1.id() != p2.id());
692  // Check if a collision is possible.
693  ActionPtr act = check_collision_two_part(p1, p2, dt, beam_momentum);
694  if (act) {
695  actions.push_back(std::move(act));
696  }
697  }
698  }
699  return actions;
700 }
Here is the call graph for this function:

◆ find_actions_with_surrounding_particles()

ActionList smash::ScatterActionsFinder::find_actions_with_surrounding_particles ( const ParticleList &  search_list,
const Particles surrounding_list,
double  dt,
const std::vector< FourVector > &  beam_momentum 
) const
overridevirtual

Search for all the possible secondary collisions between the outgoing particles and the rest.

Parameters
[in]search_listA list of particles within the current cell
[in]surrounding_listThe whole particle list
[in]dtThe maximum time interval at the current time step [fm/c]
[in]beam_momentum[GeV] List of beam momenta for each particle; only necessary for frozen Fermi motion
Returns
A list of possible scatter actions

Implements smash::ActionFinderInterface.

Definition at line 702 of file scatteractionsfinder.cc.

704  {
705  std::vector<ActionPtr> actions;
707  // Only search in cells
708  return actions;
709  }
710  for (const ParticleData& p2 : surrounding_list) {
711  /* don't look for collisions if the particle from the surrounding list is
712  * also in the search list */
713  auto result = std::find_if(
714  search_list.begin(), search_list.end(),
715  [&p2](const ParticleData& p) { return p.id() == p2.id(); });
716  if (result != search_list.end()) {
717  continue;
718  }
719  for (const ParticleData& p1 : search_list) {
720  // Check if a collision is possible.
721  ActionPtr act = check_collision_two_part(p1, p2, dt, beam_momentum);
722  if (act) {
723  actions.push_back(std::move(act));
724  }
725  }
726  }
727  return actions;
728 }
constexpr int p
Proton.
Here is the call graph for this function:

◆ find_final_actions()

ActionList smash::ScatterActionsFinder::find_final_actions ( const Particles ,
bool  = false 
) const
inlineoverridevirtual

Find some final collisions at the end of the simulation.

Todo:
Seems to do nothing.

Implements smash::ActionFinderInterface.

Definition at line 197 of file scatteractionsfinder.h.

198  {
199  return ActionList();
200  }

◆ is_constant_elastic_isotropic()

bool smash::ScatterActionsFinder::is_constant_elastic_isotropic ( ) const
inline

If there is only one particle sort, no decays (only elastic scatterings are possible), scatterings are isotropic and cross-section fixed to elastic_parameter_ independently on momenta, then maximal cross-section is elastic_parameter_.

This knowledge can be used for improving performance.

Returns
A boolean indicating whether all the scatterings are elastic and isotropic

Definition at line 212 of file scatteractionsfinder.h.

212  {
213  return ParticleType::list_all().size() == 1 && !two_to_one_ && isotropic_ &&
214  elastic_parameter_ > 0.;
215  }
static const ParticleTypeList & list_all()
Definition: particletype.cc:51
Here is the call graph for this function:
Here is the caller graph for this function:

◆ max_transverse_distance_sqr()

double smash::ScatterActionsFinder::max_transverse_distance_sqr ( int  testparticles) const
inline

The maximal distance over which particles can interact in case of the geometric criterion, related to the number of test particles and the maximal cross section.

Parameters
[in]testparticlesNumber of test particles.
Returns
Maximal transverse distance squared. [fm \(^{2}\)] Particle pairs whose transverse distance is larger than this are not checked for collisions in case of the default geometric collision criterion.

Definition at line 229 of file scatteractionsfinder.h.

229  {
232  testparticles * fm2_mb * M_1_PI;
233  }
constexpr double fm2_mb
mb <-> fm^2 conversion factor.
Definition: constants.h:28
Here is the call graph for this function:
Here is the caller graph for this function:

◆ dump_reactions()

void smash::ScatterActionsFinder::dump_reactions ( ) const

Prints out all the 2-> n (n > 1) reactions with non-zero cross-sections between all possible pairs of particle types.

Definition at line 730 of file scatteractionsfinder.cc.

730  {
731  constexpr double time = 0.0;
732 
733  const size_t N_isotypes = IsoParticleType::list_all().size();
734  const size_t N_pairs = N_isotypes * (N_isotypes - 1) / 2;
735 
736  std::cout << N_isotypes << " iso-particle types." << std::endl;
737  std::cout << "They can make " << N_pairs << " pairs." << std::endl;
738  std::vector<double> momentum_scan_list = {0.1, 0.3, 0.5, 1.0,
739  2.0, 3.0, 5.0, 10.0};
740  for (const IsoParticleType& A_isotype : IsoParticleType::list_all()) {
741  for (const IsoParticleType& B_isotype : IsoParticleType::list_all()) {
742  if (&A_isotype > &B_isotype) {
743  continue;
744  }
745  bool any_nonzero_cs = false;
746  std::vector<std::string> r_list;
747  for (const ParticleTypePtr A_type : A_isotype.get_states()) {
748  for (const ParticleTypePtr B_type : B_isotype.get_states()) {
749  if (A_type > B_type) {
750  continue;
751  }
752  ParticleData A(*A_type), B(*B_type);
753  for (auto mom : momentum_scan_list) {
754  A.set_4momentum(A.pole_mass(), mom, 0.0, 0.0);
755  B.set_4momentum(B.pole_mass(), -mom, 0.0, 0.0);
756  ScatterActionPtr act = make_unique<ScatterAction>(
757  A, B, time, isotropic_, string_formation_time_);
758  if (strings_switch_) {
759  act->set_string_interface(string_process_interface_.get());
760  }
761  act->add_all_scatterings(
766  const double total_cs = act->cross_section();
767  if (total_cs <= 0.0) {
768  continue;
769  }
770  any_nonzero_cs = true;
771  for (const auto& channel : act->collision_channels()) {
772  const auto type = channel->get_type();
773  std::string r;
774  if (is_string_soft_process(type) ||
775  type == ProcessType::StringHard) {
776  r = A_type->name() + B_type->name() + std::string(" → strings");
777  } else {
778  std::string r_type =
779  (type == ProcessType::Elastic)
780  ? std::string(" (el)")
781  : (channel->get_type() == ProcessType::TwoToTwo)
782  ? std::string(" (inel)")
783  : std::string(" (?)");
784  r = A_type->name() + B_type->name() + std::string(" → ") +
785  channel->particle_types()[0]->name() +
786  channel->particle_types()[1]->name() + r_type;
787  }
788  isoclean(r);
789  r_list.push_back(r);
790  }
791  }
792  }
793  }
794  std::sort(r_list.begin(), r_list.end());
795  r_list.erase(std::unique(r_list.begin(), r_list.end()), r_list.end());
796  if (any_nonzero_cs) {
797  for (auto r : r_list) {
798  std::cout << r;
799  if (r_list.back() != r) {
800  std::cout << ", ";
801  }
802  }
803  std::cout << std::endl;
804  }
805  }
806  }
807 }
static const IsoParticleTypeList & list_all()
Returns a list of all IsoParticleTypes.
@ TwoToTwo
2->2 inelastic scattering
@ Elastic
elastic scattering: particles remain the same, only momenta change
@ StringHard
hard string process involving 2->2 QCD process by PYTHIA.
void isoclean(std::string &s)
Remove ⁺, ⁻, ⁰ from string.
bool is_string_soft_process(ProcessType p)
Check if a given process type is a soft string excitation.
Here is the call graph for this function:

◆ dump_cross_sections()

void smash::ScatterActionsFinder::dump_cross_sections ( const ParticleType a,
const ParticleType b,
double  m_a,
double  m_b,
bool  final_state,
std::vector< double > &  plab 
) const

Print out partial cross-sections of all processes that can occur in the collision of a(mass = m_a) and b(mass = m_b).

Parameters
[in]aThe specie of the first incoming particle.
[in]bThe specie of the second incoming particle.
[in]m_aMass of species a [GeV].
[in]m_bMass of species b [GeV].
[in]final_stateWhether the final state cross sections should be printed.
[in]plabOptional momenta in lab frame to be evaluated [GeV]. Ignored if empty.

Definition at line 1118 of file scatteractionsfinder.cc.

1120  {
1121  typedef std::vector<std::pair<double, double>> xs_saver;
1122  std::map<std::string, xs_saver> xs_dump;
1123  std::map<std::string, double> outgoing_total_mass;
1124 
1125  ParticleData a_data(a), b_data(b);
1126  int n_momentum_points = 200;
1127  constexpr double momentum_step = 0.02;
1128  /*
1129  // Round to output precision.
1130  for (auto& p : plab) {
1131  p = std::floor((p * 100000) + 0.5) / 100000;
1132  }
1133  */
1134  if (plab.size() > 0) {
1135  n_momentum_points = plab.size();
1136  // Remove duplicates.
1137  std::sort(plab.begin(), plab.end());
1138  plab.erase(std::unique(plab.begin(), plab.end()), plab.end());
1139  }
1140  for (int i = 0; i < n_momentum_points; i++) {
1141  double momentum;
1142  if (plab.size() > 0) {
1143  momentum = pCM_from_s(s_from_plab(plab.at(i), m_a, m_b), m_a, m_b);
1144  } else {
1145  momentum = momentum_step * (i + 1);
1146  }
1147  a_data.set_4momentum(m_a, momentum, 0.0, 0.0);
1148  b_data.set_4momentum(m_b, -momentum, 0.0, 0.0);
1149  const double sqrts = (a_data.momentum() + b_data.momentum()).abs();
1150  const ParticleList incoming = {a_data, b_data};
1151  ScatterActionPtr act = make_unique<ScatterAction>(
1152  a_data, b_data, 0., isotropic_, string_formation_time_);
1153  if (strings_switch_) {
1154  act->set_string_interface(string_process_interface_.get());
1155  }
1156  act->add_all_scatterings(elastic_parameter_, two_to_one_, incl_set_,
1160  decaytree::Node tree(a.name() + b.name(), act->cross_section(), {&a, &b},
1161  {&a, &b}, {&a, &b}, {});
1162  const CollisionBranchList& processes = act->collision_channels();
1163  for (const auto& process : processes) {
1164  const double xs = process->weight();
1165  if (xs <= 0.0) {
1166  continue;
1167  }
1168  if (!final_state) {
1169  std::stringstream process_description_stream;
1170  process_description_stream << *process;
1171  const std::string& description = process_description_stream.str();
1172  double m_tot = 0.0;
1173  for (const auto& ptype : process->particle_types()) {
1174  m_tot += ptype->mass();
1175  }
1176  outgoing_total_mass[description] = m_tot;
1177  if (!xs_dump[description].empty() &&
1178  std::abs(xs_dump[description].back().first - sqrts) <
1179  really_small) {
1180  xs_dump[description].back().second += xs;
1181  } else {
1182  xs_dump[description].push_back(std::make_pair(sqrts, xs));
1183  }
1184  } else {
1185  std::stringstream process_description_stream;
1186  process_description_stream << *process;
1187  const std::string& description = process_description_stream.str();
1188  ParticleTypePtrList initial_particles = {&a, &b};
1189  ParticleTypePtrList final_particles = process->particle_types();
1190  auto& process_node =
1191  tree.add_action(description, xs, std::move(initial_particles),
1192  std::move(final_particles));
1193  decaytree::add_decays(process_node, sqrts);
1194  }
1195  }
1196  xs_dump["total"].push_back(std::make_pair(sqrts, act->cross_section()));
1197  // Total cross-section should be the first in the list -> negative mass
1198  outgoing_total_mass["total"] = -1.0;
1199  if (final_state) {
1200  // tree.print();
1201  auto final_state_xs = tree.final_state_cross_sections();
1202  deduplicate(final_state_xs);
1203  for (const auto& p : final_state_xs) {
1204  // Don't print empty columns.
1205  //
1206  // FIXME(steinberg): The better fix would be to not have them in the
1207  // first place.
1208  if (p.name_ == "") {
1209  continue;
1210  }
1211  outgoing_total_mass[p.name_] = p.mass_;
1212  xs_dump[p.name_].push_back(std::make_pair(sqrts, p.cross_section_));
1213  }
1214  }
1215  }
1216  // Get rid of cross sections that are zero.
1217  // (This only happens if their is a resonance in the final state that cannot
1218  // decay with our simplified assumptions.)
1219  for (auto it = begin(xs_dump); it != end(xs_dump);) {
1220  // Sum cross section over all energies.
1221  const xs_saver& xs = (*it).second;
1222  double sum = 0;
1223  for (const auto& p : xs) {
1224  sum += p.second;
1225  }
1226  if (sum == 0.) {
1227  it = xs_dump.erase(it);
1228  } else {
1229  ++it;
1230  }
1231  }
1232 
1233  // Nice ordering of channels by summed pole mass of products
1234  std::vector<std::string> all_channels;
1235  for (const auto& channel : xs_dump) {
1236  all_channels.push_back(channel.first);
1237  }
1238  std::sort(all_channels.begin(), all_channels.end(),
1239  [&](const std::string& str_a, const std::string& str_b) {
1240  return outgoing_total_mass[str_a] < outgoing_total_mass[str_b];
1241  });
1242 
1243  // Print header
1244  std::cout << "# Dumping partial " << a.name() << b.name()
1245  << " cross-sections in mb, energies in GeV" << std::endl;
1246  std::cout << " sqrt_s";
1247  // Align everything to 16 unicode characters.
1248  // This should be enough for the longest channel name (7 final-state
1249  // particles).
1250  for (const auto& channel : all_channels) {
1251  std::cout << utf8::fill_left(channel, 16, ' ');
1252  }
1253  std::cout << std::endl;
1254 
1255  // Print out all partial cross-sections in mb
1256  for (int i = 0; i < n_momentum_points; i++) {
1257  double momentum;
1258  if (plab.size() > 0) {
1259  momentum = pCM_from_s(s_from_plab(plab.at(i), m_a, m_b), m_a, m_b);
1260  } else {
1261  momentum = momentum_step * (i + 1);
1262  }
1263  a_data.set_4momentum(m_a, momentum, 0.0, 0.0);
1264  b_data.set_4momentum(m_b, -momentum, 0.0, 0.0);
1265  const double sqrts = (a_data.momentum() + b_data.momentum()).abs();
1266  std::printf("%9.6f", sqrts);
1267  for (const auto& channel : all_channels) {
1268  const xs_saver energy_and_xs = xs_dump[channel];
1269  size_t j = 0;
1270  for (; j < energy_and_xs.size() && energy_and_xs[j].first < sqrts; j++) {
1271  }
1272  double xs = 0.0;
1273  if (j < energy_and_xs.size() &&
1274  std::abs(energy_and_xs[j].first - sqrts) < really_small) {
1275  xs = energy_and_xs[j].second;
1276  }
1277  std::printf("%16.6f", xs); // Same alignment as in the header.
1278  }
1279  std::printf("\n");
1280  }
1281 }
static void add_decays(Node &node, double sqrts)
Add nodes for all decays possible from the given node and all of its children.
std::string fill_left(const std::string &s, size_t width, char fill=' ')
Fill string with characters to the left until the given width is reached.
static void deduplicate(std::vector< FinalStateCrossSection > &final_state_xs)
Deduplicate the final-state cross sections by summing.
T pCM_from_s(const T s, const T mass_a, const T mass_b) noexcept
Definition: kinematics.h:66
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
Here is the call graph for this function:

◆ get_process_string_ptr()

StringProcess* smash::ScatterActionsFinder::get_process_string_ptr ( )
inline
Returns
Pointer to the string process class object. If string is turned off, the null pointer is returned.

Definition at line 262 of file scatteractionsfinder.h.

262  {
263  if (strings_switch_) {
264  return string_process_interface_.get();
265  } else {
266  return NULL;
267  }
268  }

◆ check_collision_two_part()

ActionPtr smash::ScatterActionsFinder::check_collision_two_part ( const ParticleData data_a,
const ParticleData data_b,
double  dt,
const std::vector< FourVector > &  beam_momentum = {},
const double  gcell_vol = 0.0 
) const
private

Check for a single pair of particles (id_a, id_b) if a collision will happen in the next timestep and create a corresponding Action object in that case.

Two criteria for the collision decision are supported: 1. The default geometric criterion from UrQMD Bass:1998ca [4] (3.27). 2. A stochastic collision criterion as introduced in Staudenmaier:2021lrg [50].

Parameters
[in]data_aFirst incoming particle
[in]data_bSecond incoming particle
[in]dtMaximum time interval within which a collision can happen
[in]beam_momentum[GeV] List of beam momenta for each particle; only necessary for frozen Fermi motion
[in]gcell_vol(optional) volume of grid cell in which the collision is checked
Returns
A null pointer if no collision happens or an action which contains the information of the outgoing particles.

Note: gcell_vol is optional, since only find_actions_in_cell has (and needs) this information for the stochastic collision criterion.

Definition at line 408 of file scatteractionsfinder.cc.

411  {
412  /* If the two particles
413  * 1) belong to one of the two colliding nuclei, and
414  * 2) both of them have never experienced any collisions,
415  * then the collisions between them are banned. */
417  assert(data_a.id() >= 0);
418  assert(data_b.id() >= 0);
419  bool in_same_nucleus = (data_a.belongs_to() == BelongsTo::Projectile &&
420  data_b.belongs_to() == BelongsTo::Projectile) ||
421  (data_a.belongs_to() == BelongsTo::Target &&
422  data_b.belongs_to() == BelongsTo::Target);
423  bool never_interacted_before =
424  data_a.get_history().collisions_per_particle == 0 &&
425  data_b.get_history().collisions_per_particle == 0;
426  if (in_same_nucleus && never_interacted_before) {
427  return nullptr;
428  }
429  }
430 
431  // No grid or search in cell means no collision for stochastic criterion
433  gcell_vol < really_small) {
434  return nullptr;
435  }
436 
437  // Determine time of collision.
438  const double time_until_collision =
439  collision_time(data_a, data_b, dt, beam_momentum);
440 
441  // Check that collision happens in this timestep.
442  if (time_until_collision < 0. || time_until_collision >= dt) {
443  return nullptr;
444  }
445 
446  // Create ScatterAction object.
447  ScatterActionPtr act = make_unique<ScatterAction>(
448  data_a, data_b, time_until_collision, isotropic_, string_formation_time_,
449  box_length_);
450 
452  act->set_stochastic_pos_idx();
453  }
454 
455  if (strings_switch_) {
456  act->set_string_interface(string_process_interface_.get());
457  }
458 
459  // Distance squared calculation not needed for stochastic criterion
460  const double distance_squared =
462  ? act->transverse_distance_sqr()
464  ? act->cov_transverse_distance_sqr()
465  : 0.0;
466 
467  // Don't calculate cross section if the particles are very far apart.
468  // Not needed for stochastic criterion because of cell structure.
470  distance_squared >= max_transverse_distance_sqr(testparticles_)) {
471  return nullptr;
472  }
473 
474  // Add various subprocesses.
475  act->add_all_scatterings(elastic_parameter_, two_to_one_, incl_set_,
479 
480  double xs =
481  act->cross_section() * fm2_mb / static_cast<double>(testparticles_);
482 
483  // Take cross section scaling factors into account
484  xs *= data_a.xsec_scaling_factor(time_until_collision);
485  xs *= data_b.xsec_scaling_factor(time_until_collision);
486 
488  const double v_rel = act->relative_velocity();
489  /* Collision probability for 2-particle scattering, see
490  * \iref{Staudenmaier:2021lrg}. */
491  const double prob = xs * v_rel * dt / gcell_vol;
492 
493  logg[LFindScatter].debug(
494  "Stochastic collison criterion parameters (2-particles):\nprob = ",
495  prob, ", xs = ", xs, ", v_rel = ", v_rel, ", dt = ", dt,
496  ", gcell_vol = ", gcell_vol, ", testparticles = ", testparticles_);
497 
498  if (prob > 1.) {
499  std::stringstream err;
500  err << "Probability larger than 1 for stochastic rates. ( P_22 = " << prob
501  << " )\nConsider using smaller timesteps.";
503  logg[LFindScatter].warn(err.str());
504  } else {
505  throw std::runtime_error(err.str());
506  }
507  }
508 
509  // probability criterion
510  double random_no = random::uniform(0., 1.);
511  if (random_no > prob) {
512  return nullptr;
513  }
514 
517  // just collided with this particle
518  if (data_a.id_process() > 0 && data_a.id_process() == data_b.id_process()) {
519  logg[LFindScatter].debug("Skipping collided particles at time ",
520  data_a.position().x0(), " due to process ",
521  data_a.id_process(), "\n ", data_a, "\n<-> ",
522  data_b);
523 
524  return nullptr;
525  }
526 
527  // Cross section for collision criterion
528  const double cross_section_criterion = xs * M_1_PI;
529 
530  // distance criterion according to cross_section
531  if (distance_squared >= cross_section_criterion) {
532  return nullptr;
533  }
534 
535  logg[LFindScatter].debug("particle distance squared: ", distance_squared,
536  "\n ", data_a, "\n<-> ", data_b);
537  }
538 
539  // Using std::move here is redundant with newer compilers, but required for
540  // supporting GCC 4.8. Once we drop this support, std::move should be removed.
541  return std::move(act);
542 }
double max_transverse_distance_sqr(int testparticles) const
The maximal distance over which particles can interact in case of the geometric criterion,...
double collision_time(const ParticleData &p1, const ParticleData &p2, double dt, const std::vector< FourVector > &beam_momentum) const
Determine the collision time of the two particles.
@ Geometric
(Default) geometric criterion.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_collision_multi_part()

ActionPtr smash::ScatterActionsFinder::check_collision_multi_part ( const ParticleList &  plist,
double  dt,
const double  gcell_vol 
) const
private

Check for multiple i.e.

more than 2 particles if a collision will happen in the next timestep and create a corresponding Action object in that case.

This is only possible for the stochastic collision criterion, which is introduced in Staudenmaier:2021lrg [50]. Following the same general idea as for the 2-particle scatterings, probabilities for multi-particle scatterings can be derived.

Parameters
[in]plistList of incoming particles
[in]dtMaximum time interval within which a collision can happen
[in]gcell_volvolume of grid cell in which the collision is checked
Returns
A null pointer if no collision happens or an action which contains the information of the outgoing particles.

Definition at line 544 of file scatteractionsfinder.cc.

545  {
546  /* If all particles
547  * 1) belong to the two colliding nuclei
548  * 2) are within the same nucleus
549  * 3) have never experienced any collisons,
550  * then the collision between them are banned also for multi-particle
551  * interactions. */
553  bool all_projectile =
554  std::all_of(plist.begin(), plist.end(), [&](const ParticleData& data) {
555  return data.belongs_to() == BelongsTo::Projectile;
556  });
557  bool all_target =
558  std::all_of(plist.begin(), plist.end(), [&](const ParticleData& data) {
559  return data.belongs_to() == BelongsTo::Target;
560  });
561  bool none_collided =
562  std::all_of(plist.begin(), plist.end(), [&](const ParticleData& data) {
563  return data.get_history().collisions_per_particle == 0;
564  });
565  if ((all_projectile || all_target) && none_collided) {
566  return nullptr;
567  }
568  }
569  // No grid or search in cell
570  if (gcell_vol < really_small) {
571  return nullptr;
572  }
573 
574  /* Optimisation for later: Already check here at the beginning
575  * if collision with plist is possible before constructing actions. */
576 
577  // 1. Determine time of collision.
578  const double time_until_collision = dt * random::uniform(0., 1.);
579 
580  // 2. Create ScatterAction object.
581  ScatterActionMultiPtr act =
582  make_unique<ScatterActionMulti>(plist, time_until_collision);
583 
584  act->set_stochastic_pos_idx();
585 
586  // 3. Add possible final states (dt and gcell_vol for probability calculation)
587  act->add_possible_reactions(dt, gcell_vol, incl_multi_set_);
588 
589  /* 4. Return total collision probability
590  * Scales with 1 over the number of testpartciles to the power of the
591  * number of incoming particles - 1 */
592  const double prob =
593  act->get_total_weight() / std::pow(testparticles_, plist.size() - 1);
594 
595  // 5. Check that probability is smaller than one
596  if (prob > 1.) {
597  std::stringstream err;
598  err << "Probability larger than 1 for stochastic rates. ( P_nm = " << prob
599  << " )\nConsider using smaller timesteps.";
601  logg[LFindScatter].warn(err.str());
602  } else {
603  throw std::runtime_error(err.str());
604  }
605  }
606 
607  // 6. Perform probability decisions
608  double random_no = random::uniform(0., 1.);
609  if (random_no > prob) {
610  return nullptr;
611  }
612 
613  return std::move(act);
614 }
bool all_of(Container &&c, UnaryPredicate &&p)
Convenience wrapper for std::all_of that operates on a complete container.
Definition: algorithms.h:80
Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ string_process_interface_

std::unique_ptr<StringProcess> smash::ScatterActionsFinder::string_process_interface_
private

Class that deals with strings, interfacing Pythia.

Definition at line 317 of file scatteractionsfinder.h.

◆ coll_crit_

const CollisionCriterion smash::ScatterActionsFinder::coll_crit_
private

Specifies which collision criterion is used.

Definition at line 319 of file scatteractionsfinder.h.

◆ elastic_parameter_

const double smash::ScatterActionsFinder::elastic_parameter_
private

Elastic cross section parameter (in mb).

Definition at line 321 of file scatteractionsfinder.h.

◆ testparticles_

const int smash::ScatterActionsFinder::testparticles_
private

Number of test particles.

Definition at line 323 of file scatteractionsfinder.h.

◆ isotropic_

const bool smash::ScatterActionsFinder::isotropic_
private

Do all collisions isotropically.

Definition at line 325 of file scatteractionsfinder.h.

◆ two_to_one_

const bool smash::ScatterActionsFinder::two_to_one_
private

Enable 2->1 processes.

Definition at line 327 of file scatteractionsfinder.h.

◆ incl_set_

const ReactionsBitSet smash::ScatterActionsFinder::incl_set_
private

List of included 2<->2 reactions.

Definition at line 329 of file scatteractionsfinder.h.

◆ incl_multi_set_

const MultiParticleReactionsBitSet smash::ScatterActionsFinder::incl_multi_set_
private

List of included multi-particle reactions.

Definition at line 331 of file scatteractionsfinder.h.

◆ scale_xs_

const double smash::ScatterActionsFinder::scale_xs_
private

Factor by which all (partial) cross sections are scaled.

Definition at line 333 of file scatteractionsfinder.h.

◆ additional_el_xs_

const double smash::ScatterActionsFinder::additional_el_xs_
private

Additional constant elastic cross section.

Definition at line 335 of file scatteractionsfinder.h.

◆ low_snn_cut_

const double smash::ScatterActionsFinder::low_snn_cut_
private

Elastic collsions between two nucleons with sqrt_s below low_snn_cut_ are excluded.

Definition at line 340 of file scatteractionsfinder.h.

◆ strings_switch_

const bool smash::ScatterActionsFinder::strings_switch_
private

Switch to turn off string excitation.

Definition at line 342 of file scatteractionsfinder.h.

◆ use_AQM_

const bool smash::ScatterActionsFinder::use_AQM_
private

Switch to control whether to use AQM or not.

Definition at line 344 of file scatteractionsfinder.h.

◆ strings_with_probability_

const bool smash::ScatterActionsFinder::strings_with_probability_
private

Decide whether to implement string fragmentation based on a probability.

Definition at line 346 of file scatteractionsfinder.h.

◆ nnbar_treatment_

const NNbarTreatment smash::ScatterActionsFinder::nnbar_treatment_
private

Switch for NNbar reactions.

Definition at line 348 of file scatteractionsfinder.h.

◆ box_length_

const double smash::ScatterActionsFinder::box_length_
private

Box length: needed to determine coordinates of collision correctly in case of collision through the wall.

Ignored if negative.

Definition at line 354 of file scatteractionsfinder.h.

◆ string_formation_time_

const double smash::ScatterActionsFinder::string_formation_time_
private

Parameter for formation time.

Definition at line 356 of file scatteractionsfinder.h.

◆ maximum_cross_section_

const double smash::ScatterActionsFinder::maximum_cross_section_
private
See also
input_collision_term_

Definition at line 358 of file scatteractionsfinder.h.

◆ allow_first_collisions_within_nucleus_

const bool smash::ScatterActionsFinder::allow_first_collisions_within_nucleus_
private

If particles within nucleus are allowed to collide for their first time.

Definition at line 360 of file scatteractionsfinder.h.

◆ only_warn_for_high_prob_

const bool smash::ScatterActionsFinder::only_warn_for_high_prob_
private

Switch to turn off throwing an exception for collision probabilities larger than 1.

In larger production runs it is ok, if the probability rarely slips over 1.

Definition at line 366 of file scatteractionsfinder.h.


The documentation for this class was generated from the following files: