Version: SMASH-1.7
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 31 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, const std::vector< bool > &nucleon_has_interacted, int N_tot, int N_proj)
 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 cell_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, 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 (const ParticleData &data_a, const ParticleData &data_b, double dt, const std::vector< FourVector > &beam_momentum={}, const double cell_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...
 

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 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 std::vector< bool > & nucleon_has_interacted_
 Parameter to record whether the nucleon has experienced a collision or not. More...
 
const int N_tot_
 Record the total number of the nucleons in the two colliding nuclei. More...
 
const int N_proj_
 Record the number of the nucleons in the projectile. More...
 
const double string_formation_time_
 Parameter for formation time. More...
 

Constructor & Destructor Documentation

smash::ScatterActionsFinder::ScatterActionsFinder ( Configuration  config,
const ExperimentParameters parameters,
const std::vector< bool > &  nucleon_has_interacted,
int  N_tot,
int  N_proj 
)

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.
[in]nucleon_has_interactedFlags to record whether an initial nucleon has interacted with another particle not from the same nucleus. The flags are used if we want to exclude the first collisions among the nucleons within the same nucleus.
[in]N_totTotal number of the initial nucleons. This number, as well as the next parameter, will be used to determine whether two intial nucleons are within the same nucleus if we'd like to exclude the first collisions among them.
[in]N_projTotal projectile number

Definition at line 218 of file scatteractionsfinder.cc.

221  : coll_crit_(config.take({"Collision_Term", "Collision_Criterion"},
224  config.take({"Collision_Term", "Elastic_Cross_Section"}, -1.)),
225  testparticles_(parameters.testparticles),
226  isotropic_(config.take({"Collision_Term", "Isotropic"}, false)),
227  two_to_one_(parameters.two_to_one),
228  incl_set_(parameters.included_2to2),
229  low_snn_cut_(parameters.low_snn_cut),
230  strings_switch_(parameters.strings_switch),
231  use_AQM_(parameters.use_AQM),
232  strings_with_probability_(parameters.strings_with_probability),
233  nnbar_treatment_(parameters.nnbar_treatment),
234  nucleon_has_interacted_(nucleon_has_interacted),
235  N_tot_(N_tot),
236  N_proj_(N_proj),
237  string_formation_time_(config.take(
238  {"Collision_Term", "String_Parameters", "Formation_Time"}, 1.)) {
241  throw std::invalid_argument(
242  "The stochastic collision criterion is only supported for elastic (and "
243  "isotropic)\n2-to-2 reactions of one particle species. Change you "
244  "config accordingly.");
245  }
247  const auto& log = logger<LogArea::FindScatter>();
248  log.info("Constant elastic isotropic cross-section mode:", " using ",
249  elastic_parameter_, " mb as maximal cross-section.");
250  }
251  if (strings_switch_) {
252  auto subconfig = config["Collision_Term"]["String_Parameters"];
253  string_process_interface_ = make_unique<StringProcess>(
254  subconfig.take({"String_Tension"}, 1.0), string_formation_time_,
255  subconfig.take({"Gluon_Beta"}, 0.5),
256  subconfig.take({"Gluon_Pmin"}, 0.001),
257  subconfig.take({"Quark_Alpha"}, 2.0),
258  subconfig.take({"Quark_Beta"}, 7.0),
259  subconfig.take({"Strange_Supp"}, 0.16),
260  subconfig.take({"Diquark_Supp"}, 0.036),
261  subconfig.take({"Sigma_Perp"}, 0.42),
262  subconfig.take({"StringZ_A_Leading"}, 0.2),
263  subconfig.take({"StringZ_B_Leading"}, 2.0),
264  subconfig.take({"StringZ_A"}, 2.0), subconfig.take({"StringZ_B"}, 0.55),
265  subconfig.take({"String_Sigma_T"}, 0.5),
266  subconfig.take({"Form_Time_Factor"}, 1.0),
267  subconfig.take({"Mass_Dependent_Formation_Times"}, false),
268  subconfig.take({"Prob_proton_to_d_uu"}, 1. / 3.),
269  subconfig.take({"Separate_Fragment_Baryon"}, true),
270  subconfig.take({"Popcorn_Rate"}, 0.15));
271  }
272 }
const int testparticles_
Number of test particles.
(Default) geometric criterion.
Stochastic Criteiron.
const ReactionsBitSet incl_set_
List of included 2<->2 reactions.
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_.
const bool two_to_one_
Enable 2->1 processes.
const double low_snn_cut_
Elastic collsions between two nucleons with sqrt_s below low_snn_cut_ are excluded.
const double string_formation_time_
Parameter for formation time.
const bool strings_with_probability_
Decide whether to implement string fragmentation based on a probability.
const std::vector< bool > & nucleon_has_interacted_
Parameter to record whether the nucleon has experienced a collision or not.
std::unique_ptr< StringProcess > string_process_interface_
Class that deals with strings, interfacing Pythia.
const bool strings_switch_
Switch to turn off string excitation.
const NNbarTreatment nnbar_treatment_
Switch for NNbar reactions.
const bool use_AQM_
Switch to control whether to use AQM or not.
const int N_proj_
Record the number of the nucleons in the projectile.
const bool isotropic_
Do all collisions isotropically.
const int N_tot_
Record the total number of the nucleons in the two colliding nuclei.
const double elastic_parameter_
Elastic cross section parameter (in mb).
const CollisionCriterion coll_crit_
Specifies which collision criterion is used.

Here is the call graph for this function:

Member Function Documentation

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 as in Xu:2004mz.

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.

UrQMD collision time in computational frame, see Bass:1998ca (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 78 of file scatteractionsfinder.h.

80  {
82  return dt * random::uniform(0., 1.);
83  } else {
84  /*
85  * For frozen Fermi motion:
86  * If particles have not yet interacted and are the initial nucleons,
87  * perform action finding with beam momentum instead of Fermi motion
88  * corrected momentum. That is because the particles are propagated with
89  * the beam momentum until they interact.
90  */
91  if (p1.id() < 0 || p2.id() < 0) {
92  throw std::runtime_error("Invalid particle ID for Fermi motion");
93  }
94  const bool p1_has_no_prior_interactions =
95  (static_cast<uint64_t>(p1.id()) < // particle from
96  static_cast<uint64_t>(beam_momentum.size())) && // initial nucleus
97  (p1.get_history().collisions_per_particle == 0);
98 
99  const bool p2_has_no_prior_interactions =
100  (static_cast<uint64_t>(p2.id()) < // particle from
101  static_cast<uint64_t>(beam_momentum.size())) && // initial nucleus
102  (p2.get_history().collisions_per_particle == 0);
103 
104  const FourVector p1_mom = (p1_has_no_prior_interactions)
105  ? beam_momentum[p1.id()]
106  : p1.momentum();
107  const FourVector p2_mom = (p2_has_no_prior_interactions)
108  ? beam_momentum[p2.id()]
109  : p2.momentum();
110 
120  const ThreeVector dv_times_e1e2 =
121  p1_mom.threevec() * p2_mom.x0() - p2_mom.threevec() * p1_mom.x0();
122  const double dv_times_e1e2_sqr = dv_times_e1e2.sqr();
123  if (dv_times_e1e2_sqr < really_small) {
124  return -1.0;
125  }
126  const ThreeVector dr =
127  p1.position().threevec() - p2.position().threevec();
128  return -(dr * dv_times_e1e2) *
129  (p1_mom.x0() * p2_mom.x0() / dv_times_e1e2_sqr);
130  }
131  }
constexpr double really_small
Numerical error tolerance.
Definition: constants.h:37
Stochastic Criteiron.
T uniform(T min, T max)
Definition: random.h:88
const CollisionCriterion coll_crit_
Specifies which collision criterion is used.

Here is the call graph for this function:

Here is the caller graph for this function:

ActionList smash::ScatterActionsFinder::find_actions_in_cell ( const ParticleList &  search_list,
double  dt,
const double  cell_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]cell_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 399 of file scatteractionsfinder.cc.

401  {
402  std::vector<ActionPtr> actions;
403  for (const ParticleData& p1 : search_list) {
404  for (const ParticleData& p2 : search_list) {
405  if (p1.id() < p2.id()) {
406  // Check if a collision is possible.
407  ActionPtr act = check_collision(p1, p2, dt, beam_momentum, cell_vol);
408  if (act) {
409  actions.push_back(std::move(act));
410  }
411  }
412  }
413  }
414  return actions;
415 }
ActionPtr check_collision(const ParticleData &data_a, const ParticleData &data_b, double dt, const std::vector< FourVector > &beam_momentum={}, const double cell_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...

Here is the call graph for this function:

Here is the caller graph for this function:

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 417 of file scatteractionsfinder.cc.

419  {
420  std::vector<ActionPtr> actions;
422  // Only search in cells
423  return actions;
424  }
425  for (const ParticleData& p1 : search_list) {
426  for (const ParticleData& p2 : neighbors_list) {
427  assert(p1.id() != p2.id());
428  // Check if a collision is possible.
429  ActionPtr act = check_collision(p1, p2, dt, beam_momentum);
430  if (act) {
431  actions.push_back(std::move(act));
432  }
433  }
434  }
435  return actions;
436 }
Stochastic Criteiron.
ActionPtr check_collision(const ParticleData &data_a, const ParticleData &data_b, double dt, const std::vector< FourVector > &beam_momentum={}, const double cell_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...
const CollisionCriterion coll_crit_
Specifies which collision criterion is used.

Here is the call graph for this function:

Here is the caller graph for this function:

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 438 of file scatteractionsfinder.cc.

440  {
441  std::vector<ActionPtr> actions;
443  // Only search in cells
444  return actions;
445  }
446  for (const ParticleData& p2 : surrounding_list) {
447  /* don't look for collisions if the particle from the surrounding list is
448  * also in the search list */
449  auto result = std::find_if(
450  search_list.begin(), search_list.end(),
451  [&p2](const ParticleData& p) { return p.id() == p2.id(); });
452  if (result != search_list.end()) {
453  continue;
454  }
455  for (const ParticleData& p1 : search_list) {
456  // Check if a collision is possible.
457  ActionPtr act = check_collision(p1, p2, dt, beam_momentum);
458  if (act) {
459  actions.push_back(std::move(act));
460  }
461  }
462  }
463  return actions;
464 }
Stochastic Criteiron.
ActionPtr check_collision(const ParticleData &data_a, const ParticleData &data_b, double dt, const std::vector< FourVector > &beam_momentum={}, const double cell_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...
constexpr int p
Proton.
const CollisionCriterion coll_crit_
Specifies which collision criterion is used.

Here is the call graph for this function:

Here is the caller graph for this function:

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 186 of file scatteractionsfinder.h.

187  {
188  return ActionList();
189  }
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 201 of file scatteractionsfinder.h.

201  {
202  return ParticleType::list_all().size() == 1 && !two_to_one_ && isotropic_ &&
203  elastic_parameter_ > 0.;
204  }
const bool two_to_one_
Enable 2->1 processes.
static const ParticleTypeList & list_all()
Definition: particletype.cc:55
const bool isotropic_
Do all collisions isotropically.
const double elastic_parameter_
Elastic cross section parameter (in mb).

Here is the call graph for this function:

Here is the caller graph for this function:

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

The maximal distance over which particles can interact, 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.

Definition at line 216 of file scatteractionsfinder.h.

216  {
219  testparticles * fm2_mb * M_1_PI;
220  }
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_.
constexpr double fm2_mb
mb <-> fm^2 conversion factor.
Definition: constants.h:28
constexpr double maximum_cross_section
The maximal cross section (in mb) for which it is guaranteed that all collisions with this cross sect...
Definition: constants.h:111
const double elastic_parameter_
Elastic cross section parameter (in mb).

Here is the call graph for this function:

Here is the caller graph for this function:

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 466 of file scatteractionsfinder.cc.

466  {
467  constexpr double time = 0.0;
468 
469  const size_t N_isotypes = IsoParticleType::list_all().size();
470  const size_t N_pairs = N_isotypes * (N_isotypes - 1) / 2;
471 
472  std::cout << N_isotypes << " iso-particle types." << std::endl;
473  std::cout << "They can make " << N_pairs << " pairs." << std::endl;
474  std::vector<double> momentum_scan_list = {0.1, 0.3, 0.5, 1.0,
475  2.0, 3.0, 5.0, 10.0};
476  for (const IsoParticleType& A_isotype : IsoParticleType::list_all()) {
477  for (const IsoParticleType& B_isotype : IsoParticleType::list_all()) {
478  if (&A_isotype > &B_isotype) {
479  continue;
480  }
481  bool any_nonzero_cs = false;
482  std::vector<std::string> r_list;
483  for (const ParticleTypePtr A_type : A_isotype.get_states()) {
484  for (const ParticleTypePtr B_type : B_isotype.get_states()) {
485  if (A_type > B_type) {
486  continue;
487  }
488  ParticleData A(*A_type), B(*B_type);
489  for (auto mom : momentum_scan_list) {
490  A.set_4momentum(A.pole_mass(), mom, 0.0, 0.0);
491  B.set_4momentum(B.pole_mass(), -mom, 0.0, 0.0);
492  ScatterActionPtr act = make_unique<ScatterAction>(
493  A, B, time, isotropic_, string_formation_time_);
494  if (strings_switch_) {
495  act->set_string_interface(string_process_interface_.get());
496  }
497  act->add_all_scatterings(elastic_parameter_, two_to_one_, incl_set_,
501  const double total_cs = act->cross_section();
502  if (total_cs <= 0.0) {
503  continue;
504  }
505  any_nonzero_cs = true;
506  for (const auto& channel : act->collision_channels()) {
507  const auto type = channel->get_type();
508  std::string r;
509  if (is_string_soft_process(type) ||
510  type == ProcessType::StringHard) {
511  r = A_type->name() + B_type->name() + std::string(" → strings");
512  } else {
513  std::string r_type =
514  (type == ProcessType::Elastic)
515  ? std::string(" (el)")
516  : (channel->get_type() == ProcessType::TwoToTwo)
517  ? std::string(" (inel)")
518  : std::string(" (?)");
519  r = A_type->name() + B_type->name() + std::string(" → ") +
520  channel->particle_types()[0]->name() +
521  channel->particle_types()[1]->name() + r_type;
522  }
523  isoclean(r);
524  r_list.push_back(r);
525  }
526  }
527  }
528  }
529  std::sort(r_list.begin(), r_list.end());
530  r_list.erase(std::unique(r_list.begin(), r_list.end()), r_list.end());
531  if (any_nonzero_cs) {
532  for (auto r : r_list) {
533  std::cout << r;
534  if (r_list.back() != r) {
535  std::cout << ", ";
536  }
537  }
538  std::cout << std::endl;
539  }
540  }
541  }
542 }
const ReactionsBitSet incl_set_
List of included 2<->2 reactions.
bool is_string_soft_process(ProcessType p)
Check if a given process type is a soft string excitation.
const bool two_to_one_
Enable 2->1 processes.
const double low_snn_cut_
Elastic collsions between two nucleons with sqrt_s below low_snn_cut_ are excluded.
const double string_formation_time_
Parameter for formation time.
void isoclean(std::string &s)
Remove ⁺, ⁻, ⁰ from string.
const bool strings_with_probability_
Decide whether to implement string fragmentation based on a probability.
2->2 inelastic scattering
std::unique_ptr< StringProcess > string_process_interface_
Class that deals with strings, interfacing Pythia.
const bool strings_switch_
Switch to turn off string excitation.
elastic scattering: particles remain the same, only momenta change
const NNbarTreatment nnbar_treatment_
Switch for NNbar reactions.
hard string process involving 2->2 QCD process by PYTHIA.
const bool use_AQM_
Switch to control whether to use AQM or not.
const bool isotropic_
Do all collisions isotropically.
const double elastic_parameter_
Elastic cross section parameter (in mb).
static const IsoParticleTypeList & list_all()
Returns a list of all IsoParticleTypes.

Here is the call graph for this function:

Here is the caller graph for this function:

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 852 of file scatteractionsfinder.cc.

854  {
855  typedef std::vector<std::pair<double, double>> xs_saver;
856  std::map<std::string, xs_saver> xs_dump;
857  std::map<std::string, double> outgoing_total_mass;
858 
859  ParticleData a_data(a), b_data(b);
860  int n_momentum_points = 200;
861  constexpr double momentum_step = 0.02;
862  /*
863  // Round to output precision.
864  for (auto& p : plab) {
865  p = std::floor((p * 100000) + 0.5) / 100000;
866  }
867  */
868  if (plab.size() > 0) {
869  n_momentum_points = plab.size();
870  // Remove duplicates.
871  std::sort(plab.begin(), plab.end());
872  plab.erase(std::unique(plab.begin(), plab.end()), plab.end());
873  }
874  for (int i = 0; i < n_momentum_points; i++) {
875  double momentum;
876  if (plab.size() > 0) {
877  momentum = pCM_from_s(s_from_plab(plab.at(i), m_a, m_b), m_a, m_b);
878  } else {
879  momentum = momentum_step * (i + 1);
880  }
881  a_data.set_4momentum(m_a, momentum, 0.0, 0.0);
882  b_data.set_4momentum(m_b, -momentum, 0.0, 0.0);
883  const double sqrts = (a_data.momentum() + b_data.momentum()).abs();
884  const ParticleList incoming = {a_data, b_data};
885  ScatterActionPtr act = make_unique<ScatterAction>(
886  a_data, b_data, 0., isotropic_, string_formation_time_);
887  if (strings_switch_) {
888  act->set_string_interface(string_process_interface_.get());
889  }
890  act->add_all_scatterings(elastic_parameter_, two_to_one_, incl_set_,
893  decaytree::Node tree(a.name() + b.name(), act->cross_section(), {&a, &b},
894  {&a, &b}, {&a, &b}, {});
895  const CollisionBranchList& processes = act->collision_channels();
896  for (const auto& process : processes) {
897  const double xs = process->weight();
898  if (xs <= 0.0) {
899  continue;
900  }
901  if (!final_state) {
902  std::stringstream process_description_stream;
903  process_description_stream << *process;
904  const std::string& description = process_description_stream.str();
905  double m_tot = 0.0;
906  for (const auto& ptype : process->particle_types()) {
907  m_tot += ptype->mass();
908  }
909  outgoing_total_mass[description] = m_tot;
910  if (!xs_dump[description].empty() &&
911  std::abs(xs_dump[description].back().first - sqrts) <
912  really_small) {
913  xs_dump[description].back().second += xs;
914  } else {
915  xs_dump[description].push_back(std::make_pair(sqrts, xs));
916  }
917  } else {
918  std::stringstream process_description_stream;
919  process_description_stream << *process;
920  const std::string& description = process_description_stream.str();
921  ParticleTypePtrList initial_particles = {&a, &b};
922  ParticleTypePtrList final_particles = process->particle_types();
923  auto& process_node =
924  tree.add_action(description, xs, std::move(initial_particles),
925  std::move(final_particles));
926  decaytree::add_decays(process_node, sqrts);
927  }
928  }
929  xs_dump["total"].push_back(std::make_pair(sqrts, act->cross_section()));
930  // Total cross-section should be the first in the list -> negative mass
931  outgoing_total_mass["total"] = -1.0;
932  if (final_state) {
933  // tree.print();
934  auto final_state_xs = tree.final_state_cross_sections();
935  deduplicate(final_state_xs);
936  for (const auto& p : final_state_xs) {
937  // Don't print empty columns.
938  //
939  // FIXME(steinberg): The better fix would be to not have them in the
940  // first place.
941  if (p.name_ == "") {
942  continue;
943  }
944  outgoing_total_mass[p.name_] = p.mass_;
945  xs_dump[p.name_].push_back(std::make_pair(sqrts, p.cross_section_));
946  }
947  }
948  }
949  // Get rid of cross sections that are zero.
950  // (This only happens if their is a resonance in the final state that cannot
951  // decay with our simplified assumptions.)
952  for (auto it = begin(xs_dump); it != end(xs_dump);) {
953  // Sum cross section over all energies.
954  const xs_saver& xs = (*it).second;
955  double sum = 0;
956  for (const auto& p : xs) {
957  sum += p.second;
958  }
959  if (sum == 0.) {
960  it = xs_dump.erase(it);
961  } else {
962  ++it;
963  }
964  }
965 
966  // Nice ordering of channels by summed pole mass of products
967  std::vector<std::string> all_channels;
968  for (const auto channel : xs_dump) {
969  all_channels.push_back(channel.first);
970  }
971  std::sort(all_channels.begin(), all_channels.end(),
972  [&](const std::string& str_a, const std::string& str_b) {
973  return outgoing_total_mass[str_a] < outgoing_total_mass[str_b];
974  });
975 
976  // Print header
977  std::cout << "# Dumping partial " << a.name() << b.name()
978  << " cross-sections in mb, energies in GeV" << std::endl;
979  std::cout << " sqrt_s";
980  // Align everything to 16 unicode characters.
981  // This should be enough for the longest channel name (7 final-state
982  // particles).
983  for (const auto channel : all_channels) {
984  std::cout << utf8::fill_left(channel, 16, ' ');
985  }
986  std::cout << std::endl;
987 
988  // Print out all partial cross-sections in mb
989  for (int i = 0; i < n_momentum_points; i++) {
990  double momentum;
991  if (plab.size() > 0) {
992  momentum = pCM_from_s(s_from_plab(plab.at(i), m_a, m_b), m_a, m_b);
993  } else {
994  momentum = momentum_step * (i + 1);
995  }
996  a_data.set_4momentum(m_a, momentum, 0.0, 0.0);
997  b_data.set_4momentum(m_b, -momentum, 0.0, 0.0);
998  const double sqrts = (a_data.momentum() + b_data.momentum()).abs();
999  std::printf("%9.6f", sqrts);
1000  for (const auto channel : all_channels) {
1001  const xs_saver energy_and_xs = xs_dump[channel];
1002  size_t j = 0;
1003  for (; j < energy_and_xs.size() && energy_and_xs[j].first < sqrts; j++) {
1004  }
1005  double xs = 0.0;
1006  if (j < energy_and_xs.size() &&
1007  std::abs(energy_and_xs[j].first - sqrts) < really_small) {
1008  xs = energy_and_xs[j].second;
1009  }
1010  std::printf("%16.6f", xs); // Same alignment as in the header.
1011  }
1012  std::printf("\n");
1013  }
1014 }
static void add_decays(Node &node, double sqrts)
Add nodes for all decays possible from the given node and all of its children.
static void deduplicate(std::vector< FinalStateCrossSection > &final_state_xs)
Deduplicate the final-state cross sections by summing.
constexpr double really_small
Numerical error tolerance.
Definition: constants.h:37
const ReactionsBitSet incl_set_
List of included 2<->2 reactions.
const bool two_to_one_
Enable 2->1 processes.
const double low_snn_cut_
Elastic collsions between two nucleons with sqrt_s below low_snn_cut_ are excluded.
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.
const double string_formation_time_
Parameter for formation time.
const bool strings_with_probability_
Decide whether to implement string fragmentation based on a probability.
T pCM_from_s(const T s, const T mass_a, const T mass_b) noexcept
Definition: kinematics.h:66
std::unique_ptr< StringProcess > string_process_interface_
Class that deals with strings, interfacing Pythia.
const bool strings_switch_
Switch to turn off 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:224
const NNbarTreatment nnbar_treatment_
Switch for NNbar reactions.
constexpr int p
Proton.
const bool use_AQM_
Switch to control whether to use AQM or not.
const bool isotropic_
Do all collisions isotropically.
const double elastic_parameter_
Elastic cross section parameter (in mb).

Here is the call graph for this function:

Here is the caller graph for this function:

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 249 of file scatteractionsfinder.h.

249  {
250  if (strings_switch_) {
251  return string_process_interface_.get();
252  } else {
253  return NULL;
254  }
255  }
std::unique_ptr< StringProcess > string_process_interface_
Class that deals with strings, interfacing Pythia.
const bool strings_switch_
Switch to turn off string excitation.

Here is the call graph for this function:

ActionPtr smash::ScatterActionsFinder::check_collision ( const ParticleData data_a,
const ParticleData data_b,
double  dt,
const std::vector< FourVector > &  beam_momentum = {},
const double  cell_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 (3.27). 2. A stochastic collision criterion e.g. employed by BAMPS Xu:2004mz (Sec.IIB). Note, the latter is currently only tested for a box with a fixed elastic cross section.

More details on the stochastic collision criterion can be found here:

  • P. Danielewicz and G. F. Bertsch, Nucl. Phys. A533, 712 (1991).
  • A. Lang, H. Babovsky, W. Cassing, U. Mosel, H. G. Reusch, and K. Weber, J. Comp. Phys. 106, 391 (1993).
  • W. Cassing, Nucl. Phys. A700, 618 (2002).
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]cell_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: cell_vol is optional, since only find_actions_in_cell has (and needs) this information for the stochastic collision criterion.

Definition at line 274 of file scatteractionsfinder.cc.

276  {
277  const auto& log = logger<LogArea::FindScatter>();
278 
279  /* If the two particles
280  * 1) belong to the two colliding nuclei
281  * 2) are within the same nucleus
282  * 3) both of them have never experienced any collisons,
283  * then the collision between them are banned. */
284  assert(data_a.id() >= 0);
285  assert(data_b.id() >= 0);
286  if (data_a.id() < N_tot_ && data_b.id() < N_tot_ &&
287  ((data_a.id() < N_proj_ && data_b.id() < N_proj_) ||
288  (data_a.id() >= N_proj_ && data_b.id() >= N_proj_)) &&
289  !(nucleon_has_interacted_[data_a.id()] ||
290  nucleon_has_interacted_[data_b.id()])) {
291  return nullptr;
292  }
293 
294  // Determine time of collision.
295  const double time_until_collision =
296  collision_time(data_a, data_b, dt, beam_momentum);
297 
298  // Check that collision happens in this timestep.
299  if (time_until_collision < 0. || time_until_collision >= dt) {
300  return nullptr;
301  }
302 
303  // Create ScatterAction object.
304  ScatterActionPtr act = make_unique<ScatterAction>(
305  data_a, data_b, time_until_collision, isotropic_, string_formation_time_);
306 
307  if (strings_switch_) {
308  act->set_string_interface(string_process_interface_.get());
309  }
310 
312  // No grid or search in cell
313  if (cell_vol < really_small) {
314  return nullptr;
315  }
316 
317  // Add various subprocesses.
318  act->add_all_scatterings(elastic_parameter_, two_to_one_, incl_set_,
321 
322  const double xs = act->cross_section() * fm2_mb;
323 
324  // Relative velocity calculation, see e.g. \iref{Seifert:2017oyb}, eq. (5)
325  const double m1 = act->incoming_particles()[0].effective_mass();
326  const double m1_sqr = m1 * m1;
327  const double m2 = act->incoming_particles()[1].effective_mass();
328  const double m2_sqr = m2 * m2;
329  const double e1 = act->incoming_particles()[0].momentum().x0();
330  const double e2 = act->incoming_particles()[1].momentum().x0();
331  const double m_s = act->mandelstam_s();
332  const double lambda = (m_s - m1_sqr - m2_sqr) * (m_s - m1_sqr - m2_sqr) -
333  4. * m1_sqr * m2_sqr;
334  const double v_rel = std::sqrt(lambda) / (2. * e1 * e2);
335 
336  // Collision probability, see e.g. \iref{Xu:2004mz}, eq. (11)
337  const double p_22 = xs * v_rel * dt / (cell_vol * testparticles_);
338 
339  log.debug("Stochastic collison criterion parameters:\np_22 = ", p_22,
340  ", xs = ", xs, ", v_rel = ", v_rel, ", dt = ", dt,
341  ", cell_vol = ", cell_vol, ", testparticles = ", testparticles_);
342 
343  if (p_22 > 1.) {
344  std::stringstream err;
345  err << "Probability larger than 1 for stochastic rates. ( P = " << p_22
346  << " )\nUse smaller timesteps.";
347  throw std::runtime_error(err.str());
348  }
349 
350  // probability criterion
351  double random_no = random::uniform(0., 1.);
352  if (random_no > p_22) {
353  return nullptr;
354  }
355 
357  // just collided with this particle
358  if (data_a.id_process() > 0 && data_a.id_process() == data_b.id_process()) {
359  log.debug("Skipping collided particles at time ", data_a.position().x0(),
360  " due to process ", data_a.id_process(), "\n ", data_a,
361  "\n<-> ", data_b);
362  return nullptr;
363  }
364 
365  const double distance_squared = act->transverse_distance_sqr();
366 
367  // Don't calculate cross section if the particles are very far apart.
368  if (distance_squared >= max_transverse_distance_sqr(testparticles_)) {
369  return nullptr;
370  }
371 
372  // Add various subprocesses.
373  act->add_all_scatterings(elastic_parameter_, two_to_one_, incl_set_,
376 
377  // Cross section for collision criterion
378  double cross_section_criterion = act->cross_section() * fm2_mb * M_1_PI /
379  static_cast<double>(testparticles_);
380 
381  // Take cross section scaling factors into account
382  cross_section_criterion *= data_a.xsec_scaling_factor(time_until_collision);
383  cross_section_criterion *= data_b.xsec_scaling_factor(time_until_collision);
384 
385  // distance criterion according to cross_section
386  if (distance_squared >= cross_section_criterion) {
387  return nullptr;
388  }
389 
390  log.debug("particle distance squared: ", distance_squared, "\n ", data_a,
391  "\n<-> ", data_b);
392  }
393 
394  // Using std::move here is redundant with newer compilers, but required for
395  // supporting GCC 4.8. Once we drop this support, std::move should be removed.
396  return std::move(act);
397 }
const int testparticles_
Number of test particles.
constexpr double really_small
Numerical error tolerance.
Definition: constants.h:37
(Default) geometric criterion.
Stochastic Criteiron.
const ReactionsBitSet incl_set_
List of included 2<->2 reactions.
const bool two_to_one_
Enable 2->1 processes.
const double low_snn_cut_
Elastic collsions between two nucleons with sqrt_s below low_snn_cut_ are excluded.
const double string_formation_time_
Parameter for formation time.
const bool strings_with_probability_
Decide whether to implement string fragmentation based on a probability.
double max_transverse_distance_sqr(int testparticles) const
The maximal distance over which particles can interact, related to the number of test particles and t...
constexpr double fm2_mb
mb <-> fm^2 conversion factor.
Definition: constants.h:28
const std::vector< bool > & nucleon_has_interacted_
Parameter to record whether the nucleon has experienced a collision or not.
std::unique_ptr< StringProcess > string_process_interface_
Class that deals with strings, interfacing Pythia.
const bool strings_switch_
Switch to turn off string excitation.
const NNbarTreatment nnbar_treatment_
Switch for NNbar reactions.
T uniform(T min, T max)
Definition: random.h:88
const bool use_AQM_
Switch to control whether to use AQM or not.
const int N_proj_
Record the number of the nucleons in the projectile.
const bool isotropic_
Do all collisions isotropically.
const int N_tot_
Record the total number of the nucleons in the two colliding nuclei.
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.
const double elastic_parameter_
Elastic cross section parameter (in mb).
const CollisionCriterion coll_crit_
Specifies which collision criterion is used.

Here is the call graph for this function:

Here is the caller graph for this function:

Member Data Documentation

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

Class that deals with strings, interfacing Pythia.

Definition at line 294 of file scatteractionsfinder.h.

const CollisionCriterion smash::ScatterActionsFinder::coll_crit_
private

Specifies which collision criterion is used.

Definition at line 296 of file scatteractionsfinder.h.

const double smash::ScatterActionsFinder::elastic_parameter_
private

Elastic cross section parameter (in mb).

Definition at line 298 of file scatteractionsfinder.h.

const int smash::ScatterActionsFinder::testparticles_
private

Number of test particles.

Definition at line 300 of file scatteractionsfinder.h.

const bool smash::ScatterActionsFinder::isotropic_
private

Do all collisions isotropically.

Definition at line 302 of file scatteractionsfinder.h.

const bool smash::ScatterActionsFinder::two_to_one_
private

Enable 2->1 processes.

Definition at line 304 of file scatteractionsfinder.h.

const ReactionsBitSet smash::ScatterActionsFinder::incl_set_
private

List of included 2<->2 reactions.

Definition at line 306 of file scatteractionsfinder.h.

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 311 of file scatteractionsfinder.h.

const bool smash::ScatterActionsFinder::strings_switch_
private

Switch to turn off string excitation.

Definition at line 313 of file scatteractionsfinder.h.

const bool smash::ScatterActionsFinder::use_AQM_
private

Switch to control whether to use AQM or not.

Definition at line 315 of file scatteractionsfinder.h.

const bool smash::ScatterActionsFinder::strings_with_probability_
private

Decide whether to implement string fragmentation based on a probability.

Definition at line 317 of file scatteractionsfinder.h.

const NNbarTreatment smash::ScatterActionsFinder::nnbar_treatment_
private

Switch for NNbar reactions.

Definition at line 319 of file scatteractionsfinder.h.

const std::vector<bool>& smash::ScatterActionsFinder::nucleon_has_interacted_
private

Parameter to record whether the nucleon has experienced a collision or not.

Definition at line 323 of file scatteractionsfinder.h.

const int smash::ScatterActionsFinder::N_tot_
private

Record the total number of the nucleons in the two colliding nuclei.

Definition at line 325 of file scatteractionsfinder.h.

const int smash::ScatterActionsFinder::N_proj_
private

Record the number of the nucleons in the projectile.

Definition at line 327 of file scatteractionsfinder.h.

const double smash::ScatterActionsFinder::string_formation_time_
private

Parameter for formation time.

Definition at line 329 of file scatteractionsfinder.h.


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