Version: SMASH-1.8
smash::CrossSections Class Reference

#include <crosssections.h>

The cross section class assembels everything that is needed to calculate the cross section and returns a list of all possible reactions for the incoming particles at the given energy with the calculated cross sections.

Definition at line 62 of file crosssections.h.

Collaboration diagram for smash::CrossSections:
[legend]

Public Member Functions

 CrossSections (const ParticleList &incoming_particles, const double sqrt_s, const std::pair< FourVector, FourVector > potentials)
 Construct CrossSections instance. More...
 
CollisionBranchList generate_collision_list (double elastic_parameter, bool two_to_one_switch, ReactionsBitSet included_2to2, double low_snn_cut, bool strings_switch, bool use_AQM, bool strings_with_probability, NNbarTreatment nnbar_treatment, StringProcess *string_process) const
 Generate a list of all possible collisions between the incoming particles with the given c.m. More...
 
CollisionBranchPtr elastic (double elast_par, bool use_AQM) const
 Determine the elastic cross section for this collision. More...
 
CollisionBranchList two_to_one () const
 Find all resonances that can be produced in a 2->1 collision of the two input particles and the production cross sections of these resonances. More...
 
double formation (const ParticleType &type_resonance, double cm_momentum_sqr) const
 Return the 2-to-1 resonance production cross section for a given resonance. More...
 
CollisionBranchList rare_two_to_two () const
 Find all 2->2 processes which are suppressed at high energies when strings are turned on with probabilites, but important for the production of rare species such as strange particles. More...
 
CollisionBranchList two_to_two (ReactionsBitSet included_2to2) const
 Find all inelastic 2->2 processes for the given scattering. More...
 
CollisionBranchList string_excitation (double total_string_xs, StringProcess *string_process, bool use_AQM) const
 Determine the cross section for string excitations, which is given by the difference between the parametrized total cross section and all the explicitly implemented channels at low energy (elastic, resonance excitation, etc). More...
 
CollisionBranchPtr NNbar_annihilation (const double current_xs) const
 Determine the cross section for NNbar annihilation, which is given by the difference between the parametrized total cross section and all the explicitly implemented channels at low energy (in this case only elastic). More...
 
CollisionBranchList NNbar_creation () const
 Determine the cross section for NNbar creation, which is given by detailed balance from the reverse reaction. More...
 
double high_energy () const
 Determine the parametrized total cross section at high energies for the given collision, which is non-zero for Baryon-Baryon and Nucleon-Pion scatterings currently. More...
 
double string_probability (bool strings_switch, bool use_transition_probability, bool use_AQM, bool treat_nnbar_with_strings) const
 
double probability_transit_high (const double region_lower, const double region_upper) const
 

Private Member Functions

double elastic_parametrization (bool use_AQM) const
 Choose the appropriate parametrizations for given incoming particles and return the (parametrized) elastic cross section. More...
 
double nn_el () const
 Determine the (parametrized) elastic cross section for a nucleon-nucleon (NN) collision. More...
 
double npi_el () const
 Determine the elastic cross section for a nucleon-pion (Npi) collision. More...
 
double nk_el () const
 Determine the elastic cross section for a nucleon-kaon (NK) collision. More...
 
CollisionBranchList npi_yk () const
 Find all processes for Nucleon-Pion to Hyperon-Kaon Scattering. More...
 
CollisionBranchList bb_xx_except_nn (ReactionsBitSet included_2to2) const
 Find all inelastic 2->2 processes for Baryon-Baryon (BB) Scattering except the more specific Nucleon-Nucleon Scattering. More...
 
CollisionBranchList nn_xx (ReactionsBitSet included_2to2) const
 Find all inelastic 2->2 processes for Nucelon-Nucelon Scattering. More...
 
CollisionBranchList nk_xx (ReactionsBitSet included_2to2) const
 Find all inelastic 2->2 background processes for Nucleon-Kaon (NK) Scattering. More...
 
CollisionBranchList deltak_xx (ReactionsBitSet included_2to2) const
 Find all inelastic 2->2 processes for Delta-Kaon (DeltaK) Scattering. More...
 
CollisionBranchList ypi_xx (ReactionsBitSet included_2to2) const
 Find all inelastic 2->2 processes for Hyperon-Pion (Ypi) Scattering. More...
 
CollisionBranchList dpi_xx (ReactionsBitSet included_2to2) const
 Find all inelastic 2->2 processes involving Pion and (anti-) Deuteron (dpi), specifically dπ→ NN, d̅π→ N̅N̅; πd→ πd' (mockup for πd→ πnp), πd̅→ πd̅' and reverse. More...
 
CollisionBranchList dn_xx (ReactionsBitSet included_2to2) const
 Find all inelastic 2->2 processes involving Nucleon and (anti-) Deuteron (dN), specifically Nd → Nd', N̅d → N̅d', N̅d̅→ N̅d̅', Nd̅→ Nd̅' and reverse (e.g. More...
 
double string_hard_cross_section () const
 Determine the (parametrized) hard non-diffractive string cross section for this collision. More...
 
CollisionBranchList bar_bar_to_nuc_nuc (const bool is_anti_particles) const
 Calculate cross sections for resonance absorption (i.e. More...
 
template<class IntegrationMethod >
CollisionBranchList find_nn_xsection_from_type (const ParticleTypePtrList &type_res_1, const ParticleTypePtrList &type_res_2, const IntegrationMethod integrator) const
 Utility function to avoid code replication in nn_xx(). More...
 
double cm_momentum () const
 Determine the momenta of the incoming particles in the center-of-mass system. More...
 
template<typename F >
void add_channel (CollisionBranchList &process_list, F &&get_xsection, double sqrts, const ParticleType &type_a, const ParticleType &type_b) const
 Helper function: Add a 2-to-2 channel to a collision branch list given a cross section. More...
 

Static Private Member Functions

static double nn_to_resonance_matrix_element (double sqrts, const ParticleType &type_a, const ParticleType &type_b, const int twoI)
 Scattering matrix amplitude squared (divided by 16π) for resonance production processes like NN → NR and NN → ΔR, where R is a baryon resonance (Δ, N*, Δ*). More...
 

Private Attributes

const ParticleList incoming_particles_
 List with data of scattering particles. More...
 
const double sqrt_s_
 Total energy in the center-of-mass frame. More...
 
const std::pair< FourVector, FourVectorpotentials_
 Potentials at the interacting point. More...
 
const bool is_BBbar_pair_
 Whether incoming particles are a baryon-antibaryon pair. More...
 

Constructor & Destructor Documentation

◆ CrossSections()

smash::CrossSections::CrossSections ( const ParticleList &  incoming_particles,
const double  sqrt_s,
const std::pair< FourVector, FourVector potentials 
)

Construct CrossSections instance.

Parameters
[in]incoming_particlesParticles that are reacting.
[in]sqrt_sCenter-of-mass energy of the reaction.
[in]potentialsPotentials at the interacting point. they are used to calculate the corrections on the thresholds.

Definition at line 114 of file crosssections.cc.

117  : incoming_particles_(incoming_particles),
118  sqrt_s_(sqrt_s),
119  potentials_(potentials),
120  is_BBbar_pair_(incoming_particles_[0].type().is_baryon() &&
121  incoming_particles_[1].type().is_baryon() &&
122  incoming_particles_[0].type().antiparticle_sign() ==
123  -incoming_particles_[1].type().antiparticle_sign()) {}

Member Function Documentation

◆ generate_collision_list()

CollisionBranchList smash::CrossSections::generate_collision_list ( double  elastic_parameter,
bool  two_to_one_switch,
ReactionsBitSet  included_2to2,
double  low_snn_cut,
bool  strings_switch,
bool  use_AQM,
bool  strings_with_probability,
NNbarTreatment  nnbar_treatment,
StringProcess string_process 
) const

Generate a list of all possible collisions between the incoming particles with the given c.m.

energy and the calculated cross sections. The string processes are not added at this step if it's not triggerd according to the probability. It will then be added in add_all_scatterings in scatteraction.cc

Parameters
[in]elastic_parameterValue of the constant global elastic cross section, if it is non-zero. The parametrized elastic cross section is used otherwise.
[in]two_to_one_switch2->1 reactions enabled?
[in]included_2to2Which 2->2 ractions are enabled?
[in]low_snn_cutElastic collisions with CME below are forbidden.
[in]strings_switchAre string processes enabled?
[in]use_AQMIs the Additive Quark Model enabled?
[in]strings_with_probabilityAre string processes triggered according to a probability?
[in]nnbar_treatmentNNbar treatment through resonance, strings or none
[in]string_processa pointer to the StringProcess object, which is used for string excitation and fragmentation.
Returns
List of all possible collisions.

Definition at line 125 of file crosssections.cc.

129  {
130  CollisionBranchList process_list;
131  const ParticleType& t1 = incoming_particles_[0].type();
132  const ParticleType& t2 = incoming_particles_[1].type();
133 
134  double p_pythia = 0.;
135  if (strings_with_probability) {
136  p_pythia =
137  string_probability(strings_switch, strings_with_probability, use_AQM,
138  nnbar_treatment == NNbarTreatment::Strings);
139  }
140 
141  /* Elastic collisions between two nucleons with sqrt_s below
142  * low_snn_cut can not happen. */
143  const bool reject_by_nucleon_elastic_cutoff =
144  t1.is_nucleon() && t2.is_nucleon() &&
145  t1.antiparticle_sign() == t2.antiparticle_sign() && sqrt_s_ < low_snn_cut;
146  bool incl_elastic = included_2to2[IncludedReactions::Elastic];
147  if (incl_elastic && !reject_by_nucleon_elastic_cutoff) {
148  process_list.emplace_back(elastic(elastic_parameter, use_AQM));
149  }
150  if (p_pythia > 0.) {
151  /* String-excitation cross section =
152  * Parametrized total cross - the contributions
153  * from all other present channels. */
154  const double sig_current = sum_xs_of(process_list);
155  const double sig_string = std::max(0., high_energy() - sig_current);
156  append_list(process_list,
157  string_excitation(sig_string, string_process, use_AQM),
158  p_pythia);
159  append_list(process_list, rare_two_to_two(), p_pythia);
160  }
161  if (p_pythia < 1.) {
162  if (two_to_one_switch) {
163  // resonance formation (2->1)
164  append_list(process_list, two_to_one(), 1. - p_pythia);
165  }
166  if (included_2to2.any()) {
167  // 2->2 (inelastic)
168  append_list(process_list, two_to_two(included_2to2), 1. - p_pythia);
169  }
170  }
171  /* NNbar annihilation thru NNbar → ρh₁(1170); combined with the decays
172  * ρ → ππ and h₁(1170) → πρ, this gives a final state of 5 pions.
173  * Only use in cases when detailed balance MUST happen, i.e. in a box! */
174  if (nnbar_treatment == NNbarTreatment::Resonances) {
175  if (included_2to2[IncludedReactions::NNbar] != 1) {
176  throw std::runtime_error(
177  "'NNbar' has to be in the list of allowed 2 to 2 processes "
178  "to enable annihilation to go through resonances");
179  }
180  if (t1.is_nucleon() && t2.pdgcode() == t1.get_antiparticle()->pdgcode()) {
181  /* Has to be called after the other processes are already determined,
182  * so that the sum of the cross sections includes all other processes. */
183  process_list.emplace_back(NNbar_annihilation(sum_xs_of(process_list)));
184  }
185  if ((t1.pdgcode() == pdg::rho_z && t2.pdgcode() == pdg::h1) ||
186  (t1.pdgcode() == pdg::h1 && t2.pdgcode() == pdg::rho_z)) {
187  append_list(process_list, NNbar_creation());
188  }
189  }
190  return process_list;
191 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ elastic()

CollisionBranchPtr smash::CrossSections::elastic ( double  elast_par,
bool  use_AQM 
) const

Determine the elastic cross section for this collision.

If elastic_par is given (and positive), we just use a constant cross section of that size, otherwise a parametrization of the elastic cross section is used (if available).

Parameters
[in]elast_parElastic cross section parameter from the input file.
[in]use_AQMWhether to extend elastic cross-sections with AQM.
Returns
A ProcessBranch object containing the cross section and final-state IDs.

Definition at line 193 of file crosssections.cc.

194  {
195  double elastic_xs = 0.;
196  if (elast_par >= 0.) {
197  // use constant elastic cross section from config file
198  elastic_xs = elast_par;
199  } else {
200  // use parametrization
201  elastic_xs = elastic_parametrization(use_AQM);
202  }
203  return make_unique<CollisionBranch>(incoming_particles_[0].type(),
204  incoming_particles_[1].type(), elastic_xs,
206 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ two_to_one()

CollisionBranchList smash::CrossSections::two_to_one ( ) const

Find all resonances that can be produced in a 2->1 collision of the two input particles and the production cross sections of these resonances.

Given the data and type information of two colliding particles, create a list of possible resonance production processes and their cross sections.

Returns
A list of processes with resonance in the final state. Each element in the list contains the type of the final-state particle and the cross section for that particular process.

Definition at line 705 of file crosssections.cc.

705  {
706  CollisionBranchList resonance_process_list;
707  const ParticleType& type_particle_a = incoming_particles_[0].type();
708  const ParticleType& type_particle_b = incoming_particles_[1].type();
709 
710  const double m1 = incoming_particles_[0].effective_mass();
711  const double m2 = incoming_particles_[1].effective_mass();
712  const double p_cm_sqr = pCM_sqr(sqrt_s_, m1, m2);
713 
714  // Find all the possible resonances
715  for (const ParticleType& type_resonance : ParticleType::list_all()) {
716  /* Not a resonance, go to next type of particle */
717  if (type_resonance.is_stable()) {
718  continue;
719  }
720 
721  // Same resonance as in the beginning, ignore
722  if ((!type_particle_a.is_stable() &&
723  type_resonance.pdgcode() == type_particle_a.pdgcode()) ||
724  (!type_particle_b.is_stable() &&
725  type_resonance.pdgcode() == type_particle_b.pdgcode())) {
726  continue;
727  }
728 
729  double resonance_xsection = formation(type_resonance, p_cm_sqr);
730 
731  // If cross section is non-negligible, add resonance to the list
732  if (resonance_xsection > really_small) {
733  resonance_process_list.push_back(make_unique<CollisionBranch>(
734  type_resonance, resonance_xsection, ProcessType::TwoToOne));
735  logg[LCrossSections].debug("Found resonance: ", type_resonance);
736  logg[LCrossSections].debug(type_particle_a.name(), type_particle_b.name(),
737  "->", type_resonance.name(),
738  " at sqrt(s)[GeV] = ", sqrt_s_,
739  " with xs[mb] = ", resonance_xsection);
740  }
741  }
742  return resonance_process_list;
743 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ formation()

double smash::CrossSections::formation ( const ParticleType type_resonance,
double  cm_momentum_sqr 
) const

Return the 2-to-1 resonance production cross section for a given resonance.

Parameters
[in]type_resonanceType information for the resonance to be produced.
[in]cm_momentum_sqrSquare of the center-of-mass momentum of the two initial particles.
Returns
The cross section for the process [initial particle a] + [initial particle b] -> resonance.

Calculate resonance production cross section using the Breit-Wigner distribution as probability amplitude. See Eq. (176) in Buss:2011mx [10].

Definition at line 745 of file crosssections.cc.

746  {
747  const ParticleType& type_particle_a = incoming_particles_[0].type();
748  const ParticleType& type_particle_b = incoming_particles_[1].type();
749  // Check for charge conservation.
750  if (type_resonance.charge() !=
751  type_particle_a.charge() + type_particle_b.charge()) {
752  return 0.;
753  }
754 
755  // Check for baryon-number conservation.
756  if (type_resonance.baryon_number() !=
757  type_particle_a.baryon_number() + type_particle_b.baryon_number()) {
758  return 0.;
759  }
760 
761  // Calculate partial in-width.
762  const double partial_width = type_resonance.get_partial_in_width(
764  if (partial_width <= 0.) {
765  return 0.;
766  }
767 
768  // Calculate spin factor
769  const double spinfactor =
770  static_cast<double>(type_resonance.spin() + 1) /
771  ((type_particle_a.spin() + 1) * (type_particle_b.spin() + 1));
772  const int sym_factor =
773  (type_particle_a.pdgcode() == type_particle_b.pdgcode()) ? 2 : 1;
777  return spinfactor * sym_factor * 2. * M_PI * M_PI / cm_momentum_sqr *
778  type_resonance.spectral_function(sqrt_s_) * partial_width * hbarc *
779  hbarc / fm2_mb;
780 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rare_two_to_two()

CollisionBranchList smash::CrossSections::rare_two_to_two ( ) const

Find all 2->2 processes which are suppressed at high energies when strings are turned on with probabilites, but important for the production of rare species such as strange particles.

This function should call the different, more specific functions for the different scatterings. But so far, only Nucleon-Pion to Hyperon- Kaon scattering is implemented.

Returns
List of all possibe rare 2->2 processes.

Definition at line 208 of file crosssections.cc.

208  {
209  CollisionBranchList process_list;
210  const ParticleData& data_a = incoming_particles_[0];
211  const ParticleData& data_b = incoming_particles_[1];
212  const auto& pdg_a = data_a.pdgcode();
213  const auto& pdg_b = data_b.pdgcode();
214  if ((pdg_a.is_nucleon() && pdg_b.is_pion()) ||
215  (pdg_b.is_nucleon() && pdg_a.is_pion())) {
216  process_list = npi_yk();
217  }
218  return process_list;
219 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ two_to_two()

CollisionBranchList smash::CrossSections::two_to_two ( ReactionsBitSet  included_2to2) const

Find all inelastic 2->2 processes for the given scattering.

This function calls the different, more specific functions for the different scatterings.

Parameters
[in]included_2to2Which 2->2 reactions are enabled?
Returns
List of all possibe inelastic 2->2 processes.

Definition at line 782 of file crosssections.cc.

783  {
784  CollisionBranchList process_list;
785  const ParticleData& data_a = incoming_particles_[0];
786  const ParticleData& data_b = incoming_particles_[1];
787  const ParticleType& type_a = data_a.type();
788  const ParticleType& type_b = data_b.type();
789  const auto& pdg_a = data_a.pdgcode();
790  const auto& pdg_b = data_b.pdgcode();
791  if (data_a.is_baryon() && data_b.is_baryon()) {
792  if (pdg_a.is_nucleon() && pdg_b.is_nucleon() &&
793  pdg_a.antiparticle_sign() == pdg_b.antiparticle_sign()) {
794  // Nucleon Nucleon Scattering
795  process_list = nn_xx(included_2to2);
796  } else {
797  // Baryon Baryon Scattering
798  process_list = bb_xx_except_nn(included_2to2);
799  }
800  } else if ((type_a.is_baryon() && type_b.is_meson()) ||
801  (type_a.is_meson() && type_b.is_baryon())) {
802  // Baryon Meson Scattering
803  if ((pdg_a.is_nucleon() && pdg_b.is_kaon()) ||
804  (pdg_b.is_nucleon() && pdg_a.is_kaon())) {
805  // Nucleon Kaon Scattering
806  process_list = nk_xx(included_2to2);
807  } else if ((pdg_a.is_hyperon() && pdg_b.is_pion()) ||
808  (pdg_b.is_hyperon() && pdg_a.is_pion())) {
809  // Hyperon Pion Scattering
810  process_list = ypi_xx(included_2to2);
811  } else if ((pdg_a.is_Delta() && pdg_b.is_kaon()) ||
812  (pdg_b.is_Delta() && pdg_a.is_kaon())) {
813  // Delta Kaon Scattering
814  process_list = deltak_xx(included_2to2);
815  }
816  } else if (type_a.is_nucleus() || type_b.is_nucleus()) {
817  if ((type_a.is_nucleon() && type_b.is_nucleus()) ||
818  (type_b.is_nucleon() && type_a.is_nucleus())) {
819  // Nucleon Deuteron and Nucleon d' Scattering
820  process_list = dn_xx(included_2to2);
821  } else if (((type_a.is_deuteron() || type_a.is_dprime()) &&
822  pdg_b.is_pion()) ||
823  ((type_b.is_deuteron() || type_b.is_dprime()) &&
824  pdg_a.is_pion())) {
825  // Pion Deuteron and Pion d' Scattering
826  process_list = dpi_xx(included_2to2);
827  }
828  }
829  return process_list;
830 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ string_excitation()

CollisionBranchList smash::CrossSections::string_excitation ( double  total_string_xs,
StringProcess string_process,
bool  use_AQM 
) const

Determine the cross section for string excitations, which is given by the difference between the parametrized total cross section and all the explicitly implemented channels at low energy (elastic, resonance excitation, etc).

Parameters
[in]total_string_xsTotal cross section for the string process [mb].
[in]string_processa pointer to the StringProcess object, which is used for string excitation and fragmentation.
[in]use_AQMwhether to extend string cross-sections with AQM
Returns
List of subprocesses (single-diffractive, double-diffractive and non-diffractive) with their cross sections.
Exceptions
std::runtime_errorif string_process is a null pointer.

This method has to be called after all other processes have been determined.

Todo:
Same assumption made by NNbar_annihilation. Resolve.

Definition at line 2093 of file crosssections.cc.

2094  {
2095  if (!string_process) {
2096  throw std::runtime_error("string_process should be initialized.");
2097  }
2098 
2099  CollisionBranchList channel_list;
2100  if (total_string_xs <= 0.) {
2101  return channel_list;
2102  }
2103 
2104  /* Get mapped PDG id for evaluation of the parametrized cross sections
2105  * for diffractive processes.
2106  * This must be rescaled according to additive quark model
2107  * in the case of exotic hadrons.
2108  * Also calculate the multiplicative factor for AQM
2109  * based on the quark contents. */
2110  std::array<int, 2> pdgid;
2111  double AQM_factor = 1.;
2112  for (int i = 0; i < 2; i++) {
2113  PdgCode pdg = incoming_particles_[i].type().pdgcode();
2114  pdgid[i] = StringProcess::pdg_map_for_pythia(pdg);
2115  AQM_factor *= (1. - 0.4 * pdg.frac_strange());
2116  }
2117 
2118  /* Determine if the initial state is a baryon-antibaryon pair,
2119  * which can annihilate. */
2120  bool can_annihilate = false;
2121  if (is_BBbar_pair_) {
2122  int n_q_types = 5; // u, d, s, c, b
2123  for (int iq = 1; iq <= n_q_types; iq++) {
2124  std::array<int, 2> nquark;
2125  for (int i = 0; i < 2; i++) {
2126  nquark[i] =
2127  incoming_particles_[i].type().pdgcode().net_quark_number(iq);
2128  }
2129  if (nquark[0] != 0 && nquark[1] != 0) {
2130  can_annihilate = true;
2131  break;
2132  }
2133  }
2134  }
2135 
2136  /* Total parametrized cross-section (I) and pythia-produced total
2137  * cross-section (II) do not necessarily coincide. If I > II then
2138  * non-diffractive cross-section is reinforced to get I == II.
2139  * If I < II then partial cross-sections are drained one-by-one
2140  * to reduce II until I == II:
2141  * first non-diffractive, then double-diffractive, then
2142  * single-diffractive AB->AX and AB->XB in equal proportion.
2143  * The way it is done here is not unique. I (ryu) think that at high energy
2144  * collision this is not an issue, but at sqrt_s < 10 GeV it may
2145  * matter. */
2146  std::array<double, 3> xs =
2147  string_process->cross_sections_diffractive(pdgid[0], pdgid[1], sqrt_s_);
2148  if (use_AQM) {
2149  for (int ip = 0; ip < 3; ip++) {
2150  xs[ip] *= AQM_factor;
2151  }
2152  }
2153  double single_diffr_AX = xs[0], single_diffr_XB = xs[1], double_diffr = xs[2];
2154  double single_diffr = single_diffr_AX + single_diffr_XB;
2155  double diffractive = single_diffr + double_diffr;
2156 
2157  /* The case for baryon/anti-baryon annihilation is treated separately,
2158  * as in this case we use only one way to break up the particles, namely
2159  * into 2 mesonic strings of equal mass after annihilating one quark-
2160  * anti-quark pair. See StringProcess::next_BBbarAnn() */
2161  double sig_annihilation = 0.0;
2162  if (can_annihilate) {
2163  /* In the case of baryon-antibaryon pair,
2164  * the parametrized cross section for annihilation will be added.
2165  * See xs_ppbar_annihilation(). */
2166  double xs_param = xs_ppbar_annihilation(sqrt_s_ * sqrt_s_);
2167  if (use_AQM) {
2168  xs_param *= AQM_factor;
2169  }
2170  sig_annihilation = std::min(total_string_xs, xs_param);
2171  }
2172 
2173  const double nondiffractive_all =
2174  std::max(0., total_string_xs - sig_annihilation - diffractive);
2175  diffractive = total_string_xs - sig_annihilation - nondiffractive_all;
2176  double_diffr = std::max(0., diffractive - single_diffr);
2177  const double a = (diffractive - double_diffr) / single_diffr;
2178  single_diffr_AX *= a;
2179  single_diffr_XB *= a;
2180  assert(std::abs(single_diffr_AX + single_diffr_XB + double_diffr +
2181  sig_annihilation + nondiffractive_all - total_string_xs) <
2182  1.e-6);
2183 
2184  double nondiffractive_soft = 0.;
2185  double nondiffractive_hard = 0.;
2186  if (nondiffractive_all > 0.) {
2187  /* Hard string process is added by hard cross section
2188  * in conjunction with multipartion interaction picture
2189  * \iref{Sjostrand:1987su}. */
2190  const double hard_xsec = AQM_factor * string_hard_cross_section();
2191  nondiffractive_soft =
2192  nondiffractive_all * std::exp(-hard_xsec / nondiffractive_all);
2193  nondiffractive_hard = nondiffractive_all - nondiffractive_soft;
2194  }
2195  logg[LCrossSections].debug("String cross sections [mb] are");
2196  logg[LCrossSections].debug("Single-diffractive AB->AX: ", single_diffr_AX);
2197  logg[LCrossSections].debug("Single-diffractive AB->XB: ", single_diffr_XB);
2198  logg[LCrossSections].debug("Double-diffractive AB->XX: ", double_diffr);
2199  logg[LCrossSections].debug("Soft non-diffractive: ", nondiffractive_soft);
2200  logg[LCrossSections].debug("Hard non-diffractive: ", nondiffractive_hard);
2201  logg[LCrossSections].debug("B-Bbar annihilation: ", sig_annihilation);
2202 
2203  /* cross section of soft string excitation including annihilation */
2204  const double sig_string_soft = total_string_xs - nondiffractive_hard;
2205 
2206  /* fill the list of process channels */
2207  if (sig_string_soft > 0.) {
2208  channel_list.push_back(make_unique<CollisionBranch>(
2209  single_diffr_AX, ProcessType::StringSoftSingleDiffractiveAX));
2210  channel_list.push_back(make_unique<CollisionBranch>(
2211  single_diffr_XB, ProcessType::StringSoftSingleDiffractiveXB));
2212  channel_list.push_back(make_unique<CollisionBranch>(
2214  channel_list.push_back(make_unique<CollisionBranch>(
2215  nondiffractive_soft, ProcessType::StringSoftNonDiffractive));
2216  if (can_annihilate) {
2217  channel_list.push_back(make_unique<CollisionBranch>(
2218  sig_annihilation, ProcessType::StringSoftAnnihilation));
2219  }
2220  }
2221  if (nondiffractive_hard > 0.) {
2222  channel_list.push_back(make_unique<CollisionBranch>(
2223  nondiffractive_hard, ProcessType::StringHard));
2224  }
2225  return channel_list;
2226 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ NNbar_annihilation()

CollisionBranchPtr smash::CrossSections::NNbar_annihilation ( const double  current_xs) const

Determine the cross section for NNbar annihilation, which is given by the difference between the parametrized total cross section and all the explicitly implemented channels at low energy (in this case only elastic).

Parameters
[in]current_xsSum of all cross sections of already determined processes
Returns
Collision Branch with NNbar annihilation process and its cross section

This method has to be called after all other processes have been determined.

Todo:
Same assumption made by string_excitation. Resolve.

Definition at line 2315 of file crosssections.cc.

2316  {
2317  /* Calculate NNbar cross section:
2318  * Parametrized total minus all other present channels.*/
2319  const double s = sqrt_s_ * sqrt_s_;
2320  double nnbar_xsec = std::max(0., ppbar_total(s) - current_xs);
2321  logg[LCrossSections].debug("NNbar cross section is: ", nnbar_xsec);
2322  // Make collision channel NNbar -> ρh₁(1170); eventually decays into 5π
2323  return make_unique<CollisionBranch>(ParticleType::find(pdg::h1),
2325  nnbar_xsec, ProcessType::TwoToTwo);
2326 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ NNbar_creation()

CollisionBranchList smash::CrossSections::NNbar_creation ( ) const

Determine the cross section for NNbar creation, which is given by detailed balance from the reverse reaction.

See NNbar_annihilation.

Returns
Collision Branch with NNbar creation process and its cross section

Definition at line 2328 of file crosssections.cc.

2328  {
2329  CollisionBranchList channel_list;
2330  /* Calculate NNbar reverse cross section:
2331  * from reverse reaction (see NNbar_annihilation_cross_section).*/
2332  const double s = sqrt_s_ * sqrt_s_;
2333  const double pcm = cm_momentum();
2334 
2335  const auto& type_N = ParticleType::find(pdg::p);
2336  const auto& type_Nbar = ParticleType::find(-pdg::p);
2337 
2338  // Check available energy
2339  if (sqrt_s_ - 2 * type_N.mass() < 0) {
2340  return channel_list;
2341  }
2342 
2343  double xsection = detailed_balance_factor_RR(
2344  sqrt_s_, pcm, incoming_particles_[0].type(),
2345  incoming_particles_[1].type(), type_N, type_Nbar) *
2346  std::max(0., ppbar_total(s) - ppbar_elastic(s));
2347  logg[LCrossSections].debug("NNbar reverse cross section is: ", xsection);
2348  channel_list.push_back(make_unique<CollisionBranch>(
2349  type_N, type_Nbar, xsection, ProcessType::TwoToTwo));
2350  channel_list.push_back(make_unique<CollisionBranch>(
2353  return channel_list;
2354 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ high_energy()

double smash::CrossSections::high_energy ( ) const

Determine the parametrized total cross section at high energies for the given collision, which is non-zero for Baryon-Baryon and Nucleon-Pion scatterings currently.

This is rescaled by AQM factors.

Definition at line 2228 of file crosssections.cc.

2228  {
2229  const PdgCode& pdg_a = incoming_particles_[0].type().pdgcode();
2230  const PdgCode& pdg_b = incoming_particles_[1].type().pdgcode();
2231 
2232  const double s = sqrt_s_ * sqrt_s_;
2233  double xs = 0.;
2234 
2235  // Currently all BB collisions use the nucleon-nucleon parametrizations.
2236  if (pdg_a.is_baryon() && pdg_b.is_baryon()) {
2237  if (pdg_a == pdg_b) {
2238  xs = pp_high_energy(s); // pp, nn
2239  } else if (pdg_a.antiparticle_sign() * pdg_b.antiparticle_sign() == 1) {
2240  xs = np_high_energy(s); // np, nbarpbar
2241  } else if (pdg_a.antiparticle_sign() * pdg_b.antiparticle_sign() == -1) {
2242  /* In the case of baryon-antibaryon interactions,
2243  * the low-energy cross section must be involved
2244  * due to annihilation processes (via strings). */
2245  double xs_l = ppbar_total(s);
2246  double xs_h = 0.;
2247  if (pdg_a.is_antiparticle_of(pdg_b)) {
2248  xs_h = ppbar_high_energy(s); // ppbar, nnbar
2249  } else {
2250  xs_h = npbar_high_energy(s); // npbar, nbarp
2251  }
2252  /* Transition between low and high energy is set to be consistent with
2253  * that defined in string_probability(). */
2254  double region_lower = transit_high_energy::sqrts_range_NN[0];
2255  double region_upper = transit_high_energy::sqrts_range_NN[1];
2256  double prob_high = probability_transit_high(region_lower, region_upper);
2257  xs = xs_l * (1. - prob_high) + xs_h * prob_high;
2258  }
2259  }
2260 
2261  // Pion nucleon interaction / baryon-meson
2262  if ((pdg_a == pdg::pi_p && pdg_b == pdg::p) ||
2263  (pdg_b == pdg::pi_p && pdg_a == pdg::p) ||
2264  (pdg_a == pdg::pi_m && pdg_b == pdg::n) ||
2265  (pdg_b == pdg::pi_m && pdg_a == pdg::n)) {
2266  xs = piplusp_high_energy(s); // pi+ p, pi- n
2267  } else if ((pdg_a == pdg::pi_m && pdg_b == pdg::p) ||
2268  (pdg_b == pdg::pi_m && pdg_a == pdg::p) ||
2269  (pdg_a == pdg::pi_p && pdg_b == pdg::n) ||
2270  (pdg_b == pdg::pi_p && pdg_a == pdg::n)) {
2271  xs = piminusp_high_energy(s); // pi- p, pi+ n
2272  } else if ((pdg_a.is_meson() && pdg_b.is_baryon()) ||
2273  (pdg_b.is_meson() && pdg_a.is_baryon())) {
2274  xs = piminusp_high_energy(s); // default for baryon-meson
2275  }
2276 
2277  /* Meson-meson interaction goes through AQM from pi+p,
2278  * see user guide "Use_AQM"*/
2279  if (pdg_a.is_meson() && pdg_b.is_meson()) {
2280  /* 2/3 factor since difference of 1 meson between meson-meson
2281  * and baryon-meson */
2282  xs = 2. / 3. * piplusp_high_energy(s);
2283  }
2284 
2285  // AQM scaling for cross-sections
2286  xs *= (1. - 0.4 * pdg_a.frac_strange()) * (1. - 0.4 * pdg_b.frac_strange());
2287 
2288  return xs;
2289 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ string_probability()

double smash::CrossSections::string_probability ( bool  strings_switch,
bool  use_transition_probability,
bool  use_AQM,
bool  treat_nnbar_with_strings 
) const
Returns
the probability whether the scattering between the incoming particles is via string fragmentation or not.

If use_transition_probability is true: The string fragmentation is implemented in the same way in GiBUU (Physics Reports 512(2012), 1-124, pg. 33). If the center of mass energy is low, two particles scatter through the resonance channels. If high, the outgoing particles are generated by string fragmentation. If in between, the out- going particles are generated either through the resonance channels or string fragmentation by chance. In detail, the low energy region is from the threshold to (mix_scatter_type_energy - mix_scatter_type_window_width), while the high energy region is from (mix_scatter_type_energy + mix_scatter_type_window_width) to infinity. In between, the probability for string fragmentation increases smoothly from 0 to 1 as the c.m. energy.

If use_transition_probability is false: The string fragmentation is implemented similarly to what is in UrQMD (Bass:1998ca [4]). If sqrts is lower than some cutoff value, there are no strings. If higher, strings are allowed, with the cross-section being the difference between some parametrized total cross-section and the sum of all other channels, if this parametrization is larger than the sum of the channels. If not, strings are not allowed (this cross-section check is performed directly after the function is called, for technical reasons).

Both of these methods are initially implemented for NN and Npi cross- sections, and extended using the AQM to all BB, BM and MM interactions.

Baryon-antibaryon annihilation also uses this function to decide whether to produce strings or not. Since there are no other contributions for this process, there are no cutoffs or gradual increase in the probability of this process happening or not, it just requires the proper combination of incoming particles and config parameters.

Parameters
[in]strings_switchIs string fragmentation enabled?
[in]use_transition_probabilitywhich algorithm to use for string treatment (see Switch_on_String_with_Probability)
[in]use_AQMwhether AQM is activated
[in]treat_nnbar_with_stringsuse strings for nnbar treatment?

Definition at line 2584 of file crosssections.cc.

2587  {
2588  /* string fragmentation is enabled when strings_switch is on and the process
2589  * is included in pythia. */
2590  if (!strings_switch) {
2591  return 0.;
2592  }
2593 
2594  const ParticleType& t1 = incoming_particles_[0].type();
2595  const ParticleType& t2 = incoming_particles_[1].type();
2596 
2597  const bool is_NN_scattering =
2598  t1.is_nucleon() && t2.is_nucleon() &&
2599  t1.antiparticle_sign() == t2.antiparticle_sign();
2600  const bool is_BBbar_scattering =
2601  (treat_BBbar_with_strings && is_BBbar_pair_ && use_AQM) ||
2602  (t1.is_nucleon() && t2.is_nucleon() &&
2603  t1.antiparticle_sign() != t2.antiparticle_sign());
2604  const bool is_Npi_scattering = (t1.pdgcode().is_pion() && t2.is_nucleon()) ||
2605  (t1.is_nucleon() && t2.pdgcode().is_pion());
2606  /* True for baryon-baryon, anti-baryon-anti-baryon, baryon-meson,
2607  * anti-baryon-meson and meson-meson*/
2608  const bool is_AQM_scattering =
2609  use_AQM && ((t1.is_baryon() && t2.is_baryon() &&
2610  t1.antiparticle_sign() == t2.antiparticle_sign()) ||
2611  ((t1.is_baryon() && t2.is_meson()) ||
2612  (t2.is_baryon() && t1.is_meson())) ||
2613  (t1.is_meson() && t2.is_meson()));
2614  const double mass_sum =
2615  incoming_particles_[0].pole_mass() + incoming_particles_[1].pole_mass();
2616 
2617  if (!is_NN_scattering && !is_BBbar_scattering && !is_Npi_scattering &&
2618  !is_AQM_scattering) {
2619  return 0.;
2620  } else if (is_BBbar_scattering) {
2621  // BBbar only goes through strings, so there are no "window" considerations
2622  return 1.;
2623  } else {
2624  /* true for K+ p and K0 p (+ antiparticles), which have special treatment
2625  * to fit data */
2626  const PdgCode pdg1 = t1.pdgcode(), pdg2 = t2.pdgcode();
2627  const bool is_KplusP =
2628  ((pdg1 == pdg::K_p || pdg1 == pdg::K_z) && (pdg2 == pdg::p)) ||
2629  ((pdg2 == pdg::K_p || pdg2 == pdg::K_z) && (pdg1 == pdg::p)) ||
2630  ((pdg1 == -pdg::K_p || pdg1 == -pdg::K_z) && (pdg2 == -pdg::p)) ||
2631  ((pdg2 == -pdg::K_p || pdg2 == -pdg::K_z) && (pdg1 == -pdg::p));
2632  // where to start the AQM strings above mass sum
2633  double aqm_offset = transit_high_energy::sqrts_add_lower;
2634  if (is_KplusP) {
2635  /* for this specific case we have data. This corresponds to the point
2636  * where the AQM parametrization is smaller than the current 2to2
2637  * parametrization, which starts growing and diverges from exp. data */
2638  aqm_offset = transit_high_energy::KN_offset;
2639  } else if (pdg1.is_pion() && pdg2.is_pion()) {
2640  aqm_offset = transit_high_energy::pipi_offset;
2641  }
2642  /* if we do not use the probability transition algorithm, this is always a
2643  * string contribution if the energy is large enough */
2644  if (!use_transition_probability) {
2645  return static_cast<double>(sqrt_s_ > mass_sum + aqm_offset);
2646  }
2647  /* No strings at low energy, only strings at high energy and
2648  * a transition region in the middle. Determine transition region: */
2649  double region_lower, region_upper;
2650  if (is_Npi_scattering) {
2651  region_lower = transit_high_energy::sqrts_range_Npi[0];
2652  region_upper = transit_high_energy::sqrts_range_Npi[1];
2653  } else if (is_NN_scattering) {
2654  region_lower = transit_high_energy::sqrts_range_NN[0];
2655  region_upper = transit_high_energy::sqrts_range_NN[1];
2656  } else { // AQM - Additive Quark Model
2657  /* Transition region around 0.9 larger than the sum of pole masses;
2658  * highly arbitrary, feel free to improve */
2659  region_lower = mass_sum + aqm_offset;
2660  region_upper = mass_sum + aqm_offset + transit_high_energy::sqrts_range;
2661  }
2662 
2663  if (sqrt_s_ > region_upper) {
2664  return 1.;
2665  } else if (sqrt_s_ < region_lower) {
2666  return 0.;
2667  } else {
2668  // Rescale transition region to [-1, 1]
2669  return probability_transit_high(region_lower, region_upper);
2670  }
2671  }
2672 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ probability_transit_high()

double smash::CrossSections::probability_transit_high ( const double  region_lower,
const double  region_upper 
) const
Parameters
[in]region_lowerthe lowest sqrts in the transition region [GeV]
[in]region_upperthe highest sqrts in the transition region [GeV]
Returns
probability to have the high energy interaction (via string)

Definition at line 2674 of file crosssections.cc.

2675  {
2676  if (sqrt_s_ < region_lower) {
2677  return 0.;
2678  }
2679 
2680  if (sqrt_s_ > region_upper) {
2681  return 1.;
2682  }
2683 
2684  double x = (sqrt_s_ - 0.5 * (region_lower + region_upper)) /
2685  (region_upper - region_lower);
2686  assert(x >= -0.5 && x <= 0.5);
2687  double prob = 0.5 * (std::sin(M_PI * x) + 1.0);
2688  assert(prob >= 0. && prob <= 1.);
2689 
2690  return prob;
2691 }
Here is the caller graph for this function:

◆ elastic_parametrization()

double smash::CrossSections::elastic_parametrization ( bool  use_AQM) const
private

Choose the appropriate parametrizations for given incoming particles and return the (parametrized) elastic cross section.

Parameters
[in]use_AQMwhether AQM is activated
Returns
Elastic cross section

Definition at line 221 of file crosssections.cc.

221  {
222  const PdgCode& pdg_a = incoming_particles_[0].type().pdgcode();
223  const PdgCode& pdg_b = incoming_particles_[1].type().pdgcode();
224  double elastic_xs = 0.0;
225  if ((pdg_a.is_nucleon() && pdg_b.is_pion()) ||
226  (pdg_b.is_nucleon() && pdg_a.is_pion())) {
227  // Elastic Nucleon Pion Scattering
228  elastic_xs = npi_el();
229  } else if ((pdg_a.is_nucleon() && pdg_b.is_kaon()) ||
230  (pdg_b.is_nucleon() && pdg_a.is_kaon())) {
231  // Elastic Nucleon Kaon Scattering
232  elastic_xs = nk_el();
233  } else if (pdg_a.is_nucleon() && pdg_b.is_nucleon() &&
234  pdg_a.antiparticle_sign() == pdg_b.antiparticle_sign()) {
235  // Elastic Nucleon Nucleon Scattering
236  elastic_xs = nn_el();
237  } else if (pdg_a.is_nucleon() && pdg_b.is_nucleon() &&
238  pdg_a.antiparticle_sign() == -pdg_b.antiparticle_sign()) {
239  // Elastic Nucleon anti-Nucleon Scattering
240  elastic_xs = ppbar_elastic(sqrt_s_ * sqrt_s_);
241  } else if (pdg_a.is_nucleus() || pdg_b.is_nucleus()) {
242  const PdgCode& pdg_nucleus = pdg_a.is_nucleus() ? pdg_a : pdg_b;
243  const PdgCode& pdg_other = pdg_a.is_nucleus() ? pdg_b : pdg_a;
244  const bool is_deuteron =
245  std::abs(pdg_nucleus.get_decimal()) == pdg::decimal_d;
246  if (is_deuteron && pdg_other.is_pion()) {
247  // Elastic (Anti-)deuteron Pion Scattering
248  elastic_xs = deuteron_pion_elastic(sqrt_s_ * sqrt_s_);
249  } else if (is_deuteron && pdg_other.is_nucleon()) {
250  // Elastic (Anti-)deuteron (Anti-)Nucleon Scattering
251  elastic_xs = deuteron_nucleon_elastic(sqrt_s_ * sqrt_s_);
252  }
253  } else if (use_AQM) {
254  const double m1 = incoming_particles_[0].effective_mass();
255  const double m2 = incoming_particles_[1].effective_mass();
256  const double s = sqrt_s_ * sqrt_s_;
257  if (pdg_a.is_baryon() && pdg_b.is_baryon()) {
258  elastic_xs = nn_el(); // valid also for annihilation
259  } else if ((pdg_a.is_meson() && pdg_b.is_baryon()) ||
260  (pdg_b.is_meson() && pdg_a.is_baryon())) {
261  elastic_xs = piplusp_elastic_high_energy(s, m1, m2);
262  } else if (pdg_a.is_meson() && pdg_b.is_meson()) {
263  /* Special case: the pi+pi- elastic cross-section goes through resonances
264  * at low sqrt_s, so we turn it off for this region so as not to destroy
265  * the agreement with experimental data; this does not
266  * apply to other pi pi cross-sections, which do not have any data */
267  if (((pdg_a == pdg::pi_p && pdg_b == pdg::pi_m) ||
268  (pdg_a == pdg::pi_m && pdg_b == pdg::pi_p)) &&
270  elastic_xs = 0.0;
271  } else {
272  // meson-meson goes through scaling from π+p parametrization
273  elastic_xs = 2. / 3. * piplusp_elastic_AQM(s, m1, m2);
274  }
275  }
276  elastic_xs *=
277  (1. - 0.4 * pdg_a.frac_strange()) * (1. - 0.4 * pdg_b.frac_strange());
278  }
279  return elastic_xs;
280 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nn_el()

double smash::CrossSections::nn_el ( ) const
private

Determine the (parametrized) elastic cross section for a nucleon-nucleon (NN) collision.

Returns
Elastic cross section for NN
Exceptions
std::runtime_errorif positive cross section cannot be specified.

Definition at line 282 of file crosssections.cc.

282  {
283  const PdgCode& pdg_a = incoming_particles_[0].type().pdgcode();
284  const PdgCode& pdg_b = incoming_particles_[1].type().pdgcode();
285 
286  const double s = sqrt_s_ * sqrt_s_;
287 
288  // Use parametrized cross sections.
289  double sig_el = -1.;
290  if (pdg_a.antiparticle_sign() == -pdg_b.antiparticle_sign()) {
291  sig_el = ppbar_elastic(s);
292  } else if (pdg_a.is_nucleon() && pdg_b.is_nucleon()) {
293  sig_el = (pdg_a == pdg_b) ? pp_elastic(s) : np_elastic(s);
294  } else {
295  // AQM - Additive Quark Model
296  const double m1 = incoming_particles_[0].effective_mass();
297  const double m2 = incoming_particles_[1].effective_mass();
298  sig_el = pp_elastic_high_energy(s, m1, m2);
299  }
300  if (sig_el > 0.) {
301  return sig_el;
302  } else {
303  std::stringstream ss;
304  const auto name_a = incoming_particles_[0].type().name();
305  const auto name_b = incoming_particles_[1].type().name();
306  ss << "problem in CrossSections::elastic: a=" << name_a << " b=" << name_b
307  << " j_a=" << pdg_a.spin() << " j_b=" << pdg_b.spin()
308  << " sigma=" << sig_el << " s=" << s;
309  throw std::runtime_error(ss.str());
310  }
311 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ npi_el()

double smash::CrossSections::npi_el ( ) const
private

Determine the elastic cross section for a nucleon-pion (Npi) collision.

It is given by a parametrization of experimental data.

Returns
Elastic cross section for Npi
Exceptions
std::runtime_errorif incoming particles are not nucleon+pion.
std::runtime_errorif positive cross section cannot be specified.

Definition at line 313 of file crosssections.cc.

313  {
314  const PdgCode& pdg_a = incoming_particles_[0].type().pdgcode();
315  const PdgCode& pdg_b = incoming_particles_[1].type().pdgcode();
316 
317  const PdgCode& nucleon = pdg_a.is_nucleon() ? pdg_a : pdg_b;
318  const PdgCode& pion = pdg_a.is_nucleon() ? pdg_b : pdg_a;
319  assert(pion != nucleon);
320 
321  const double s = sqrt_s_ * sqrt_s_;
322 
323  double sig_el = 0.;
324  switch (nucleon.code()) {
325  case pdg::p:
326  switch (pion.code()) {
327  case pdg::pi_p:
328  sig_el = piplusp_elastic(s);
329  break;
330  case pdg::pi_m:
331  sig_el = piminusp_elastic(s);
332  break;
333  case pdg::pi_z:
334  sig_el = 0.5 * (piplusp_elastic(s) + piminusp_elastic(s));
335  break;
336  }
337  break;
338  case pdg::n:
339  switch (pion.code()) {
340  case pdg::pi_p:
341  sig_el = piminusp_elastic(s);
342  break;
343  case pdg::pi_m:
344  sig_el = piplusp_elastic(s);
345  break;
346  case pdg::pi_z:
347  sig_el = 0.5 * (piplusp_elastic(s) + piminusp_elastic(s));
348  break;
349  }
350  break;
351  case -pdg::p:
352  switch (pion.code()) {
353  case pdg::pi_p:
354  sig_el = piminusp_elastic(s);
355  break;
356  case pdg::pi_m:
357  sig_el = piplusp_elastic(s);
358  break;
359  case pdg::pi_z:
360  sig_el = 0.5 * (piplusp_elastic(s) + piminusp_elastic(s));
361  break;
362  }
363  break;
364  case -pdg::n:
365  switch (pion.code()) {
366  case pdg::pi_p:
367  sig_el = piplusp_elastic(s);
368  break;
369  case pdg::pi_m:
370  sig_el = piminusp_elastic(s);
371  break;
372  case pdg::pi_z:
373  sig_el = 0.5 * (piplusp_elastic(s) + piminusp_elastic(s));
374  break;
375  }
376  break;
377  default:
378  throw std::runtime_error(
379  "only the elastic cross section for proton-pion "
380  "is implemented");
381  }
382 
383  if (sig_el > 0) {
384  return sig_el;
385  } else {
386  std::stringstream ss;
387  const auto name_a = incoming_particles_[0].type().name();
388  const auto name_b = incoming_particles_[1].type().name();
389  ss << "problem in CrossSections::elastic: a=" << name_a << " b=" << name_b
390  << " j_a=" << pdg_a.spin() << " j_b=" << pdg_b.spin()
391  << " sigma=" << sig_el << " s=" << s;
392  throw std::runtime_error(ss.str());
393  }
394 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nk_el()

double smash::CrossSections::nk_el ( ) const
private

Determine the elastic cross section for a nucleon-kaon (NK) collision.

It is given by a parametrization of experimental data.

Returns
Elastic cross section for NK
Exceptions
std::runtime_errorif incoming particles are not nucleon+kaon.
std::runtime_errorif positive cross section cannot be specified.

Definition at line 610 of file crosssections.cc.

610  {
611  const PdgCode& pdg_a = incoming_particles_[0].type().pdgcode();
612  const PdgCode& pdg_b = incoming_particles_[1].type().pdgcode();
613 
614  const PdgCode& nucleon = pdg_a.is_nucleon() ? pdg_a : pdg_b;
615  const PdgCode& kaon = pdg_a.is_nucleon() ? pdg_b : pdg_a;
616  assert(kaon != nucleon);
617 
618  const double s = sqrt_s_ * sqrt_s_;
619 
620  double sig_el = 0.;
621  switch (nucleon.code()) {
622  case pdg::p:
623  switch (kaon.code()) {
624  case pdg::K_p:
625  sig_el = kplusp_elastic_background(s);
626  break;
627  case pdg::K_m:
628  sig_el = kminusp_elastic_background(s);
629  break;
630  case pdg::K_z:
631  sig_el = k0p_elastic_background(s);
632  break;
633  case pdg::Kbar_z:
634  sig_el = kbar0p_elastic_background(s);
635  break;
636  }
637  break;
638  case pdg::n:
639  switch (kaon.code()) {
640  case pdg::K_p:
641  sig_el = kplusn_elastic_background(s);
642  break;
643  case pdg::K_m:
644  sig_el = kminusn_elastic_background(s);
645  break;
646  case pdg::K_z:
647  sig_el = k0n_elastic_background(s);
648  break;
649  case pdg::Kbar_z:
650  sig_el = kbar0n_elastic_background(s);
651  break;
652  }
653  break;
654  case -pdg::p:
655  switch (kaon.code()) {
656  case pdg::K_p:
657  sig_el = kminusp_elastic_background(s);
658  break;
659  case pdg::K_m:
660  sig_el = kplusp_elastic_background(s);
661  break;
662  case pdg::K_z:
663  sig_el = kbar0p_elastic_background(s);
664  break;
665  case pdg::Kbar_z:
666  sig_el = k0p_elastic_background(s);
667  break;
668  }
669  break;
670  case -pdg::n:
671  switch (kaon.code()) {
672  case pdg::K_p:
673  sig_el = kminusn_elastic_background(s);
674  break;
675  case pdg::K_m:
676  sig_el = kplusn_elastic_background(s);
677  break;
678  case pdg::K_z:
679  sig_el = kbar0n_elastic_background(s);
680  break;
681  case pdg::Kbar_z:
682  sig_el = k0n_elastic_background(s);
683  break;
684  }
685  break;
686  default:
687  throw std::runtime_error(
688  "elastic cross section for antinucleon-kaon "
689  "not implemented");
690  }
691 
692  if (sig_el > 0) {
693  return sig_el;
694  } else {
695  std::stringstream ss;
696  const auto name_a = incoming_particles_[0].type().name();
697  const auto name_b = incoming_particles_[1].type().name();
698  ss << "problem in CrossSections::elastic: a=" << name_a << " b=" << name_b
699  << " j_a=" << pdg_a.spin() << " j_b=" << pdg_b.spin()
700  << " sigma=" << sig_el << " s=" << s;
701  throw std::runtime_error(ss.str());
702  }
703 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ npi_yk()

CollisionBranchList smash::CrossSections::npi_yk ( ) const
private

Find all processes for Nucleon-Pion to Hyperon-Kaon Scattering.

These scatterings are suppressed at high energies when strings are turned on with probabilities, so they need to be added back manually.

Returns
List of all possible Npi -> YK reactions with their cross sections

Definition at line 396 of file crosssections.cc.

396  {
397  const ParticleType& a = incoming_particles_[0].type();
398  const ParticleType& b = incoming_particles_[1].type();
399  const ParticleType& type_nucleon = a.pdgcode().is_nucleon() ? a : b;
400  const ParticleType& type_pion = a.pdgcode().is_nucleon() ? b : a;
401 
402  const auto pdg_nucleon = type_nucleon.pdgcode().code();
403  const auto pdg_pion = type_pion.pdgcode().code();
404 
405  const double s = sqrt_s_ * sqrt_s_;
406 
407  /* The cross sections are paramectrized for four isospin channels. The
408  * cross sections of the rest isospin channels are obtained using
409  * Clebsch-Gordan coefficients */
410 
411  CollisionBranchList process_list;
412  switch (pdg_nucleon) {
413  case pdg::p: {
414  switch (pdg_pion) {
415  case pdg::pi_p: {
416  const auto& type_Sigma_p = ParticleType::find(pdg::Sigma_p);
417  const auto& type_K_p = ParticleType::find(pdg::K_p);
418  add_channel(process_list,
419  [&] { return piplusp_sigmapluskplus_pdg(s); }, sqrt_s_,
420  type_K_p, type_Sigma_p);
421  break;
422  }
423  case pdg::pi_m: {
424  const auto& type_Sigma_m = ParticleType::find(pdg::Sigma_m);
425  const auto& type_Sigma_z = ParticleType::find(pdg::Sigma_z);
426  const auto& type_Lambda = ParticleType::find(pdg::Lambda);
427  const auto& type_K_p = ParticleType::find(pdg::K_p);
428  const auto& type_K_z = ParticleType::find(pdg::K_z);
429  add_channel(process_list,
430  [&] { return piminusp_sigmaminuskplus_pdg(s); }, sqrt_s_,
431  type_K_p, type_Sigma_m);
432  add_channel(process_list, [&] { return piminusp_sigma0k0_res(s); },
433  sqrt_s_, type_K_z, type_Sigma_z);
434  add_channel(process_list, [&] { return piminusp_lambdak0_pdg(s); },
435  sqrt_s_, type_K_z, type_Lambda);
436  break;
437  }
438  case pdg::pi_z: {
439  const auto& type_Sigma_p = ParticleType::find(pdg::Sigma_p);
440  const auto& type_Sigma_z = ParticleType::find(pdg::Sigma_z);
441  const auto& type_Lambda = ParticleType::find(pdg::Lambda);
442  const auto& type_K_p = ParticleType::find(pdg::K_p);
443  const auto& type_K_z = ParticleType::find(pdg::K_z);
444  add_channel(process_list,
445  [&] {
446  return 0.5 * (piplusp_sigmapluskplus_pdg(s) -
449  },
450  sqrt_s_, type_K_p, type_Sigma_z);
451  add_channel(process_list, [&] { return piminusp_sigma0k0_res(s); },
452  sqrt_s_, type_K_z, type_Sigma_p);
453  add_channel(process_list,
454  [&] { return 0.5 * piminusp_lambdak0_pdg(s); }, sqrt_s_,
455  type_K_p, type_Lambda);
456  break;
457  }
458  }
459  break;
460  }
461  case pdg::n: {
462  switch (pdg_pion) {
463  case pdg::pi_p: {
464  const auto& type_Sigma_p = ParticleType::find(pdg::Sigma_p);
465  const auto& type_Sigma_z = ParticleType::find(pdg::Sigma_z);
466  const auto& type_Lambda = ParticleType::find(pdg::Lambda);
467  const auto& type_K_p = ParticleType::find(pdg::K_p);
468  const auto& type_K_z = ParticleType::find(pdg::K_z);
469  add_channel(process_list,
470  [&] { return piminusp_sigmaminuskplus_pdg(s); }, sqrt_s_,
471  type_K_z, type_Sigma_p);
472  add_channel(process_list, [&] { return piminusp_sigma0k0_res(s); },
473  sqrt_s_, type_K_p, type_Sigma_z);
474  add_channel(process_list, [&] { return piminusp_lambdak0_pdg(s); },
475  sqrt_s_, type_K_p, type_Lambda);
476  break;
477  }
478  case pdg::pi_m: {
479  const auto& type_Sigma_m = ParticleType::find(pdg::Sigma_m);
480  const auto& type_K_z = ParticleType::find(pdg::K_z);
481  add_channel(process_list,
482  [&] { return piplusp_sigmapluskplus_pdg(s); }, sqrt_s_,
483  type_K_z, type_Sigma_m);
484  break;
485  }
486  case pdg::pi_z: {
487  const auto& type_Sigma_m = ParticleType::find(pdg::Sigma_m);
488  const auto& type_Sigma_z = ParticleType::find(pdg::Sigma_z);
489  const auto& type_Lambda = ParticleType::find(pdg::Lambda);
490  const auto& type_K_p = ParticleType::find(pdg::K_p);
491  const auto& type_K_z = ParticleType::find(pdg::K_z);
492  add_channel(process_list,
493  [&] {
494  return 0.5 * (piplusp_sigmapluskplus_pdg(s) -
497  },
498  sqrt_s_, type_K_z, type_Sigma_z);
499  add_channel(process_list, [&] { return piminusp_sigma0k0_res(s); },
500  sqrt_s_, type_K_p, type_Sigma_m);
501  add_channel(process_list,
502  [&] { return 0.5 * piminusp_lambdak0_pdg(s); }, sqrt_s_,
503  type_K_z, type_Lambda);
504  break;
505  }
506  }
507  break;
508  }
509  case -pdg::p: {
510  switch (pdg_pion) {
511  case pdg::pi_p: {
512  const auto& type_Sigma_m_bar = ParticleType::find(-pdg::Sigma_m);
513  const auto& type_Sigma_z_bar = ParticleType::find(-pdg::Sigma_z);
514  const auto& type_Lambda_bar = ParticleType::find(-pdg::Lambda);
515  const auto& type_K_m = ParticleType::find(-pdg::K_p);
516  const auto& type_Kbar_z = ParticleType::find(-pdg::K_z);
517  add_channel(process_list,
518  [&] { return piminusp_sigmaminuskplus_pdg(s); }, sqrt_s_,
519  type_K_m, type_Sigma_m_bar);
520  add_channel(process_list, [&] { return piminusp_sigma0k0_res(s); },
521  sqrt_s_, type_Kbar_z, type_Sigma_z_bar);
522  add_channel(process_list, [&] { return piminusp_lambdak0_pdg(s); },
523  sqrt_s_, type_Kbar_z, type_Lambda_bar);
524  break;
525  }
526  case pdg::pi_m: {
527  const auto& type_Sigma_p_bar = ParticleType::find(-pdg::Sigma_p);
528  const auto& type_K_m = ParticleType::find(-pdg::K_p);
529  add_channel(process_list,
530  [&] { return piplusp_sigmapluskplus_pdg(s); }, sqrt_s_,
531  type_K_m, type_Sigma_p_bar);
532  break;
533  }
534  case pdg::pi_z: {
535  const auto& type_Sigma_p_bar = ParticleType::find(-pdg::Sigma_p);
536  const auto& type_Sigma_z_bar = ParticleType::find(-pdg::Sigma_z);
537  const auto& type_Lambda_bar = ParticleType::find(-pdg::Lambda);
538  const auto& type_K_m = ParticleType::find(-pdg::K_p);
539  const auto& type_Kbar_z = ParticleType::find(-pdg::K_z);
540  add_channel(process_list,
541  [&] {
542  return 0.5 * (piplusp_sigmapluskplus_pdg(s) -
545  },
546  sqrt_s_, type_K_m, type_Sigma_z_bar);
547  add_channel(process_list, [&] { return piminusp_sigma0k0_res(s); },
548  sqrt_s_, type_Kbar_z, type_Sigma_p_bar);
549  add_channel(process_list,
550  [&] { return 0.5 * piminusp_lambdak0_pdg(s); }, sqrt_s_,
551  type_K_m, type_Lambda_bar);
552  break;
553  }
554  }
555  break;
556  }
557  case -pdg::n: {
558  switch (pdg_pion) {
559  case pdg::pi_p: {
560  const auto& type_Sigma_m_bar = ParticleType::find(-pdg::Sigma_m);
561  const auto& type_Kbar_z = ParticleType::find(-pdg::K_z);
562  add_channel(process_list,
563  [&] { return piplusp_sigmapluskplus_pdg(s); }, sqrt_s_,
564  type_Kbar_z, type_Sigma_m_bar);
565  break;
566  }
567  case pdg::pi_m: {
568  const auto& type_Sigma_p_bar = ParticleType::find(-pdg::Sigma_p);
569  const auto& type_Sigma_z_bar = ParticleType::find(-pdg::Sigma_z);
570  const auto& type_Lambda_bar = ParticleType::find(-pdg::Lambda);
571  const auto& type_K_m = ParticleType::find(-pdg::K_p);
572  const auto& type_Kbar_z = ParticleType::find(-pdg::K_z);
573  add_channel(process_list,
574  [&] { return piminusp_sigmaminuskplus_pdg(s); }, sqrt_s_,
575  type_Kbar_z, type_Sigma_p_bar);
576  add_channel(process_list, [&] { return piminusp_sigma0k0_res(s); },
577  sqrt_s_, type_K_m, type_Sigma_z_bar);
578  add_channel(process_list, [&] { return piminusp_lambdak0_pdg(s); },
579  sqrt_s_, type_K_m, type_Lambda_bar);
580  break;
581  }
582  case pdg::pi_z: {
583  const auto& type_Sigma_m_bar = ParticleType::find(-pdg::Sigma_m);
584  const auto& type_Sigma_z_bar = ParticleType::find(-pdg::Sigma_z);
585  const auto& type_Lambda_bar = ParticleType::find(-pdg::Lambda);
586  const auto& type_K_m = ParticleType::find(-pdg::K_p);
587  const auto& type_Kbar_z = ParticleType::find(-pdg::K_z);
588  add_channel(process_list,
589  [&] {
590  return 0.5 * (piplusp_sigmapluskplus_pdg(s) -
593  },
594  sqrt_s_, type_Kbar_z, type_Sigma_z_bar);
595  add_channel(process_list, [&] { return piminusp_sigma0k0_res(s); },
596  sqrt_s_, type_K_m, type_Sigma_m_bar);
597  add_channel(process_list,
598  [&] { return 0.5 * piminusp_lambdak0_pdg(s); }, sqrt_s_,
599  type_Kbar_z, type_Lambda_bar);
600  break;
601  }
602  }
603  break;
604  }
605  }
606 
607  return process_list;
608 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ bb_xx_except_nn()

CollisionBranchList smash::CrossSections::bb_xx_except_nn ( ReactionsBitSet  included_2to2) const
private

Find all inelastic 2->2 processes for Baryon-Baryon (BB) Scattering except the more specific Nucleon-Nucleon Scattering.

Parameters
[in]included_2to2Which 2->2 reactions are enabled?
Returns
List of all possible BB reactions with their cross sections

Definition at line 832 of file crosssections.cc.

833  {
834  CollisionBranchList process_list;
835  const ParticleType& type_a = incoming_particles_[0].type();
836  const ParticleType& type_b = incoming_particles_[1].type();
837 
838  bool same_sign = type_a.antiparticle_sign() == type_b.antiparticle_sign();
839  bool any_nucleus = type_a.is_nucleus() || type_b.is_nucleus();
840  if (!same_sign && !any_nucleus) {
841  return process_list;
842  }
843  bool anti_particles = type_a.antiparticle_sign() == -1;
844  if (type_a.is_nucleon() || type_b.is_nucleon()) {
845  // N R → N N, N̅ R → N̅ N̅
846  if (included_2to2[IncludedReactions::NN_to_NR] == 1) {
847  process_list = bar_bar_to_nuc_nuc(anti_particles);
848  }
849  } else if (type_a.is_Delta() || type_b.is_Delta()) {
850  // Δ R → N N, Δ̅ R → N̅ N̅
851  if (included_2to2[IncludedReactions::NN_to_DR] == 1) {
852  process_list = bar_bar_to_nuc_nuc(anti_particles);
853  }
854  }
855 
856  return process_list;
857 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nn_xx()

CollisionBranchList smash::CrossSections::nn_xx ( ReactionsBitSet  included_2to2) const
private

Find all inelastic 2->2 processes for Nucelon-Nucelon Scattering.

Calculate cross sections for resonance production from nucleon-nucleon collisions (i.e. N N -> N R, N N -> Delta R).

Checks are processed in the following order:

  1. Charge conservation
  2. Isospin factors (Clebsch-Gordan)
  3. Enough energy for all decay channels to be available for the resonance
Parameters
[in]included_2to2Which 2->2 reactions are enabled?
Returns
List of resonance production processes possible in the collision of the two nucleons. Each element in the list contains the type(s) of the final state particle(s) and the cross section for that particular process.

Definition at line 859 of file crosssections.cc.

859  {
860  CollisionBranchList process_list, channel_list;
861 
862  const double sqrts = sqrt_s_;
863 
864  /* Find whether colliding particles are nucleons or anti-nucleons;
865  * adjust lists of produced particles. */
866  bool both_antinucleons =
867  (incoming_particles_[0].type().antiparticle_sign() == -1) &&
868  (incoming_particles_[1].type().antiparticle_sign() == -1);
869  const ParticleTypePtrList& nuc_or_anti_nuc =
870  both_antinucleons ? ParticleType::list_anti_nucleons()
871  : ParticleType::list_nucleons();
872  const ParticleTypePtrList& delta_or_anti_delta =
873  both_antinucleons ? ParticleType::list_anti_Deltas()
874  : ParticleType::list_Deltas();
875  // Find N N → N R channels.
876  if (included_2to2[IncludedReactions::NN_to_NR] == 1) {
877  channel_list = find_nn_xsection_from_type(
878  ParticleType::list_baryon_resonances(), nuc_or_anti_nuc,
879  [&sqrts](const ParticleType& type_res_1, const ParticleType&) {
880  return type_res_1.iso_multiplet()->get_integral_NR(sqrts);
881  });
882  process_list.reserve(process_list.size() + channel_list.size());
883  std::move(channel_list.begin(), channel_list.end(),
884  std::inserter(process_list, process_list.end()));
885  channel_list.clear();
886  }
887 
888  // Find N N → Δ R channels.
889  if (included_2to2[IncludedReactions::NN_to_DR] == 1) {
890  channel_list = find_nn_xsection_from_type(
891  ParticleType::list_baryon_resonances(), delta_or_anti_delta,
892  [&sqrts](const ParticleType& type_res_1,
893  const ParticleType& type_res_2) {
894  return type_res_1.iso_multiplet()->get_integral_RR(
895  type_res_2.iso_multiplet(), sqrts);
896  });
897  process_list.reserve(process_list.size() + channel_list.size());
898  std::move(channel_list.begin(), channel_list.end(),
899  std::inserter(process_list, process_list.end()));
900  channel_list.clear();
901  }
902 
903  // Find N N → dπ and N̅ N̅→ d̅π channels.
904  ParticleTypePtr deutron =
906  ParticleTypePtr antideutron =
908  ParticleTypePtr pim = ParticleType::try_find(pdg::pi_m);
909  ParticleTypePtr pi0 = ParticleType::try_find(pdg::pi_z);
910  ParticleTypePtr pip = ParticleType::try_find(pdg::pi_p);
911  // Make sure all the necessary particle types are found
912  if (deutron && antideutron && pim && pi0 && pip &&
913  included_2to2[IncludedReactions::PiDeuteron_to_NN] == 1) {
914  const ParticleTypePtrList deutron_list = {deutron};
915  const ParticleTypePtrList antideutron_list = {antideutron};
916  const ParticleTypePtrList pion_list = {pim, pi0, pip};
917  channel_list = find_nn_xsection_from_type(
918  (both_antinucleons ? antideutron_list : deutron_list), pion_list,
919  [&sqrts](const ParticleType& type_res_1,
920  const ParticleType& type_res_2) {
921  return pCM(sqrts, type_res_1.mass(), type_res_2.mass());
922  });
923  process_list.reserve(process_list.size() + channel_list.size());
924  std::move(channel_list.begin(), channel_list.end(),
925  std::inserter(process_list, process_list.end()));
926  channel_list.clear();
927  }
928 
929  return process_list;
930 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nk_xx()

CollisionBranchList smash::CrossSections::nk_xx ( ReactionsBitSet  included_2to2) const
private

Find all inelastic 2->2 background processes for Nucleon-Kaon (NK) Scattering.

Parameters
[in]included_2to2Which 2->2 reactions are enabled?
Returns
List of all possible NK reactions with their cross sections

Definition at line 932 of file crosssections.cc.

932  {
933  const ParticleType& a = incoming_particles_[0].type();
934  const ParticleType& b = incoming_particles_[1].type();
935  const ParticleType& type_nucleon = a.pdgcode().is_nucleon() ? a : b;
936  const ParticleType& type_kaon = a.pdgcode().is_nucleon() ? b : a;
937 
938  const auto pdg_nucleon = type_nucleon.pdgcode().code();
939  const auto pdg_kaon = type_kaon.pdgcode().code();
940 
941  const double s = sqrt_s_ * sqrt_s_;
942 
943  // Some variable declarations for frequently used quantities
944  const auto sigma_kplusp = kplusp_inelastic_background(s);
945  const auto sigma_kplusn = kplusn_inelastic_background(s);
946 
947  /* At high energy, the parametrization we use diverges from experimental
948  * data. This cutoff represents the point where the AQM cross section
949  * becomes smaller than this parametrization, so we cut it here, and fully
950  * switch to AQM beyond this point. */
951  const double KN_to_KDelta_cutoff = transit_high_energy::KN_offset +
952  incoming_particles_[0].pole_mass() +
953  incoming_particles_[1].pole_mass();
954 
955  bool incl_KN_to_KN = included_2to2[IncludedReactions::KN_to_KN] == 1;
956  bool incl_KN_to_KDelta =
957  included_2to2[IncludedReactions::KN_to_KDelta] == 1 &&
958  sqrt_s_ < KN_to_KDelta_cutoff;
959  bool incl_Strangeness_exchange =
960  included_2to2[IncludedReactions::Strangeness_exchange] == 1;
961 
962  CollisionBranchList process_list;
963  switch (pdg_kaon) {
964  case pdg::K_m: {
965  /* All inelastic K- N channels here are strangeness exchange, plus one
966  * charge exchange. */
967  switch (pdg_nucleon) {
968  case pdg::p: {
969  if (incl_Strangeness_exchange) {
970  const auto& type_pi_z = ParticleType::find(pdg::pi_z);
971  const auto& type_pi_m = ParticleType::find(pdg::pi_m);
972  const auto& type_pi_p = ParticleType::find(pdg::pi_p);
973  const auto& type_Sigma_p = ParticleType::find(pdg::Sigma_p);
974  const auto& type_Sigma_m = ParticleType::find(pdg::Sigma_m);
975  const auto& type_Sigma_z = ParticleType::find(pdg::Sigma_z);
976  const auto& type_Lambda = ParticleType::find(pdg::Lambda);
977  add_channel(process_list,
978  [&] { return kminusp_piminussigmaplus(sqrt_s_); },
979  sqrt_s_, type_pi_m, type_Sigma_p);
980  add_channel(process_list,
981  [&] { return kminusp_piplussigmaminus(sqrt_s_); },
982  sqrt_s_, type_pi_p, type_Sigma_m);
983  add_channel(process_list,
984  [&] { return kminusp_pi0sigma0(sqrt_s_); }, sqrt_s_,
985  type_pi_z, type_Sigma_z);
986  add_channel(process_list,
987  [&] { return kminusp_pi0lambda(sqrt_s_); }, sqrt_s_,
988  type_pi_z, type_Lambda);
989  }
990  if (incl_KN_to_KN) {
991  const auto& type_n = ParticleType::find(pdg::n);
992  const auto& type_Kbar_z = ParticleType::find(pdg::Kbar_z);
993  add_channel(process_list, [&] { return kminusp_kbar0n(s); },
994  sqrt_s_, type_Kbar_z, type_n);
995  }
996  break;
997  }
998  case pdg::n: {
999  if (incl_Strangeness_exchange) {
1000  const auto& type_pi_z = ParticleType::find(pdg::pi_z);
1001  const auto& type_pi_m = ParticleType::find(pdg::pi_m);
1002  const auto& type_Sigma_m = ParticleType::find(pdg::Sigma_m);
1003  const auto& type_Sigma_z = ParticleType::find(pdg::Sigma_z);
1004  const auto& type_Lambda = ParticleType::find(pdg::Lambda);
1005  add_channel(process_list,
1006  [&] { return kminusn_piminussigma0(sqrt_s_); }, sqrt_s_,
1007  type_pi_m, type_Sigma_z);
1008  add_channel(process_list,
1009  [&] { return kminusn_piminussigma0(sqrt_s_); }, sqrt_s_,
1010  type_pi_z, type_Sigma_m);
1011  add_channel(process_list,
1012  [&] { return kminusn_piminuslambda(sqrt_s_); }, sqrt_s_,
1013  type_pi_m, type_Lambda);
1014  }
1015  break;
1016  }
1017  case -pdg::p: {
1018  if (incl_KN_to_KDelta) {
1019  const auto& type_K_m = ParticleType::find(pdg::K_m);
1020  const auto& type_Kbar_z = ParticleType::find(pdg::Kbar_z);
1021  const auto& type_Delta_pp_bar = ParticleType::find(-pdg::Delta_pp);
1022  const auto& type_Delta_p_bar = ParticleType::find(-pdg::Delta_p);
1023  add_channel(process_list,
1024  [&] {
1025  return sigma_kplusp * kaon_nucleon_ratios.get_ratio(
1026  type_nucleon, type_kaon,
1027  type_Kbar_z,
1028  type_Delta_pp_bar);
1029  },
1030  sqrt_s_, type_Kbar_z, type_Delta_pp_bar);
1031  add_channel(process_list,
1032  [&] {
1033  return sigma_kplusp * kaon_nucleon_ratios.get_ratio(
1034  type_nucleon, type_kaon,
1035  type_K_m, type_Delta_p_bar);
1036  },
1037  sqrt_s_, type_K_m, type_Delta_p_bar);
1038  }
1039  break;
1040  }
1041  case -pdg::n: {
1042  if (incl_KN_to_KDelta) {
1043  const auto& type_K_m = ParticleType::find(pdg::K_m);
1044  const auto& type_Kbar_z = ParticleType::find(pdg::Kbar_z);
1045  const auto& type_Delta_p_bar = ParticleType::find(-pdg::Delta_p);
1046  const auto& type_Delta_z_bar = ParticleType::find(-pdg::Delta_z);
1047  add_channel(process_list,
1048  [&] {
1049  return sigma_kplusn * kaon_nucleon_ratios.get_ratio(
1050  type_nucleon, type_kaon,
1051  type_Kbar_z,
1052  type_Delta_p_bar);
1053  },
1054  sqrt_s_, type_Kbar_z, type_Delta_p_bar);
1055  add_channel(process_list,
1056  [&] {
1057  return sigma_kplusn * kaon_nucleon_ratios.get_ratio(
1058  type_nucleon, type_kaon,
1059  type_K_m, type_Delta_z_bar);
1060  },
1061  sqrt_s_, type_K_m, type_Delta_z_bar);
1062  }
1063  if (incl_KN_to_KN) {
1064  const auto& type_Kbar_z = ParticleType::find(pdg::Kbar_z);
1065  const auto& type_p_bar = ParticleType::find(-pdg::p);
1066  add_channel(process_list, [&] { return kplusn_k0p(s); }, sqrt_s_,
1067  type_Kbar_z, type_p_bar);
1068  }
1069  break;
1070  }
1071  }
1072  break;
1073  }
1074  case pdg::K_p: {
1075  /* All inelastic channels are K+ N -> K Delta -> K pi N, with identical
1076  * cross section, weighted by the isospin factor. */
1077  switch (pdg_nucleon) {
1078  case pdg::p: {
1079  if (incl_KN_to_KDelta) {
1080  const auto& type_K_p = ParticleType::find(pdg::K_p);
1081  const auto& type_K_z = ParticleType::find(pdg::K_z);
1082  const auto& type_Delta_pp = ParticleType::find(pdg::Delta_pp);
1083  const auto& type_Delta_p = ParticleType::find(pdg::Delta_p);
1084  add_channel(process_list,
1085  [&] {
1086  return sigma_kplusp * kaon_nucleon_ratios.get_ratio(
1087  type_nucleon, type_kaon,
1088  type_K_z, type_Delta_pp);
1089  },
1090  sqrt_s_, type_K_z, type_Delta_pp);
1091  add_channel(process_list,
1092  [&] {
1093  return sigma_kplusp * kaon_nucleon_ratios.get_ratio(
1094  type_nucleon, type_kaon,
1095  type_K_p, type_Delta_p);
1096  },
1097  sqrt_s_, type_K_p, type_Delta_p);
1098  }
1099  break;
1100  }
1101  case pdg::n: {
1102  if (incl_KN_to_KDelta) {
1103  const auto& type_K_p = ParticleType::find(pdg::K_p);
1104  const auto& type_K_z = ParticleType::find(pdg::K_z);
1105  const auto& type_Delta_p = ParticleType::find(pdg::Delta_p);
1106  const auto& type_Delta_z = ParticleType::find(pdg::Delta_z);
1107  add_channel(process_list,
1108  [&] {
1109  return sigma_kplusn * kaon_nucleon_ratios.get_ratio(
1110  type_nucleon, type_kaon,
1111  type_K_z, type_Delta_p);
1112  },
1113  sqrt_s_, type_K_z, type_Delta_p);
1114  add_channel(process_list,
1115  [&] {
1116  return sigma_kplusn * kaon_nucleon_ratios.get_ratio(
1117  type_nucleon, type_kaon,
1118  type_K_p, type_Delta_z);
1119  },
1120  sqrt_s_, type_K_p, type_Delta_z);
1121  }
1122  if (incl_KN_to_KN) {
1123  const auto& type_K_z = ParticleType::find(pdg::K_z);
1124  const auto& type_p = ParticleType::find(pdg::p);
1125  add_channel(process_list, [&] { return kplusn_k0p(s); }, sqrt_s_,
1126  type_K_z, type_p);
1127  }
1128  break;
1129  }
1130  case -pdg::p: {
1131  if (incl_Strangeness_exchange) {
1132  const auto& type_pi_z = ParticleType::find(pdg::pi_z);
1133  const auto& type_pi_m = ParticleType::find(pdg::pi_m);
1134  const auto& type_pi_p = ParticleType::find(pdg::pi_p);
1135  const auto& type_Sigma_p_bar = ParticleType::find(-pdg::Sigma_p);
1136  const auto& type_Sigma_m_bar = ParticleType::find(-pdg::Sigma_m);
1137  const auto& type_Sigma_z_bar = ParticleType::find(-pdg::Sigma_z);
1138  const auto& type_Lambda_bar = ParticleType::find(-pdg::Lambda);
1139  add_channel(process_list,
1140  [&] { return kminusp_piminussigmaplus(sqrt_s_); },
1141  sqrt_s_, type_pi_p, type_Sigma_p_bar);
1142  add_channel(process_list,
1143  [&] { return kminusp_piplussigmaminus(sqrt_s_); },
1144  sqrt_s_, type_pi_m, type_Sigma_m_bar);
1145  add_channel(process_list,
1146  [&] { return kminusp_pi0sigma0(sqrt_s_); }, sqrt_s_,
1147  type_pi_z, type_Sigma_z_bar);
1148  add_channel(process_list,
1149  [&] { return kminusp_pi0lambda(sqrt_s_); }, sqrt_s_,
1150  type_pi_z, type_Lambda_bar);
1151  }
1152  if (incl_KN_to_KN) {
1153  const auto& type_n_bar = ParticleType::find(-pdg::n);
1154  const auto& type_K_z = ParticleType::find(pdg::K_z);
1155  add_channel(process_list, [&] { return kminusp_kbar0n(s); },
1156  sqrt_s_, type_K_z, type_n_bar);
1157  }
1158  break;
1159  }
1160  case -pdg::n: {
1161  if (incl_Strangeness_exchange) {
1162  const auto& type_pi_z = ParticleType::find(pdg::pi_z);
1163  const auto& type_pi_p = ParticleType::find(pdg::pi_p);
1164  const auto& type_Sigma_m_bar = ParticleType::find(-pdg::Sigma_m);
1165  const auto& type_Sigma_z_bar = ParticleType::find(-pdg::Sigma_z);
1166  const auto& type_Lambda_bar = ParticleType::find(-pdg::Lambda);
1167  add_channel(process_list,
1168  [&] { return kminusn_piminussigma0(sqrt_s_); }, sqrt_s_,
1169  type_pi_p, type_Sigma_z_bar);
1170  add_channel(process_list,
1171  [&] { return kminusn_piminussigma0(sqrt_s_); }, sqrt_s_,
1172  type_pi_z, type_Sigma_m_bar);
1173  add_channel(process_list,
1174  [&] { return kminusn_piminuslambda(sqrt_s_); }, sqrt_s_,
1175  type_pi_p, type_Lambda_bar);
1176  }
1177  break;
1178  }
1179  }
1180  break;
1181  }
1182  case pdg::K_z: {
1183  // K+ and K0 have the same mass and spin, so their cross sections are
1184  // assumed to only differ in isospin factors. For the initial state, we
1185  // assume that K0 p is equivalent to K+ n and K0 n equivalent to K+ p,
1186  // like for the elastic background.
1187 
1188  switch (pdg_nucleon) {
1189  case pdg::p: {
1190  if (incl_KN_to_KDelta) {
1191  const auto& type_K_p = ParticleType::find(pdg::K_p);
1192  const auto& type_K_z = ParticleType::find(pdg::K_z);
1193  const auto& type_Delta_p = ParticleType::find(pdg::Delta_p);
1194  const auto& type_Delta_z = ParticleType::find(pdg::Delta_z);
1195  add_channel(process_list,
1196  [&] {
1197  return sigma_kplusn * kaon_nucleon_ratios.get_ratio(
1198  type_nucleon, type_kaon,
1199  type_K_z, type_Delta_p);
1200  },
1201  sqrt_s_, type_K_z, type_Delta_p);
1202  add_channel(process_list,
1203  [&] {
1204  return sigma_kplusn * kaon_nucleon_ratios.get_ratio(
1205  type_nucleon, type_kaon,
1206  type_K_p, type_Delta_z);
1207  },
1208  sqrt_s_, type_K_p, type_Delta_z);
1209  }
1210  if (incl_KN_to_KN) {
1211  const auto& type_K_p = ParticleType::find(pdg::K_p);
1212  const auto& type_n = ParticleType::find(pdg::n);
1213  add_channel(process_list,
1214  [&] {
1215  // The isospin factor is 1, see the parametrizations
1216  // tests.
1217  return kplusn_k0p(s);
1218  },
1219  sqrt_s_, type_K_p, type_n);
1220  }
1221  break;
1222  }
1223  case pdg::n: {
1224  if (incl_KN_to_KDelta) {
1225  const auto& type_K_p = ParticleType::find(pdg::K_p);
1226  const auto& type_K_z = ParticleType::find(pdg::K_z);
1227  const auto& type_Delta_z = ParticleType::find(pdg::Delta_z);
1228  const auto& type_Delta_m = ParticleType::find(pdg::Delta_m);
1229  add_channel(process_list,
1230  [&] {
1231  return sigma_kplusp * kaon_nucleon_ratios.get_ratio(
1232  type_nucleon, type_kaon,
1233  type_K_z, type_Delta_z);
1234  },
1235  sqrt_s_, type_K_z, type_Delta_z);
1236  add_channel(process_list,
1237  [&] {
1238  return sigma_kplusp * kaon_nucleon_ratios.get_ratio(
1239  type_nucleon, type_kaon,
1240  type_K_p, type_Delta_m);
1241  },
1242  sqrt_s_, type_K_p, type_Delta_m);
1243  }
1244  break;
1245  }
1246  case -pdg::p: {
1247  if (incl_Strangeness_exchange) {
1248  const auto& type_pi_z = ParticleType::find(pdg::pi_z);
1249  const auto& type_pi_m = ParticleType::find(pdg::pi_m);
1250  const auto& type_Sigma_p_bar = ParticleType::find(-pdg::Sigma_p);
1251  const auto& type_Sigma_z_bar = ParticleType::find(-pdg::Sigma_z);
1252  const auto& type_Lambda_bar = ParticleType::find(-pdg::Lambda);
1253  add_channel(process_list,
1254  [&] { return kminusn_piminussigma0(sqrt_s_); }, sqrt_s_,
1255  type_pi_m, type_Sigma_z_bar);
1256  add_channel(process_list,
1257  [&] { return kminusn_piminussigma0(sqrt_s_); }, sqrt_s_,
1258  type_pi_z, type_Sigma_p_bar);
1259  add_channel(process_list,
1260  [&] { return kminusn_piminuslambda(sqrt_s_); }, sqrt_s_,
1261  type_pi_m, type_Lambda_bar);
1262  }
1263  break;
1264  }
1265  case -pdg::n: {
1266  if (incl_Strangeness_exchange) {
1267  const auto& type_pi_z = ParticleType::find(pdg::pi_z);
1268  const auto& type_pi_m = ParticleType::find(pdg::pi_m);
1269  const auto& type_pi_p = ParticleType::find(pdg::pi_p);
1270  const auto& type_Sigma_p_bar = ParticleType::find(-pdg::Sigma_p);
1271  const auto& type_Sigma_m_bar = ParticleType::find(-pdg::Sigma_m);
1272  const auto& type_Sigma_z_bar = ParticleType::find(-pdg::Sigma_z);
1273  const auto& type_Lambda_bar = ParticleType::find(-pdg::Lambda);
1274  add_channel(process_list,
1275  [&] { return kminusp_piminussigmaplus(sqrt_s_); },
1276  sqrt_s_, type_pi_m, type_Sigma_m_bar);
1277  add_channel(process_list,
1278  [&] { return kminusp_piplussigmaminus(sqrt_s_); },
1279  sqrt_s_, type_pi_p, type_Sigma_p_bar);
1280  add_channel(process_list,
1281  [&] { return kminusp_pi0sigma0(sqrt_s_); }, sqrt_s_,
1282  type_pi_z, type_Sigma_z_bar);
1283  add_channel(process_list,
1284  [&] { return kminusp_pi0lambda(sqrt_s_); }, sqrt_s_,
1285  type_pi_z, type_Lambda_bar);
1286  }
1287  if (incl_KN_to_KN) {
1288  const auto& type_K_p = ParticleType::find(pdg::K_p);
1289  const auto& type_p_bar = ParticleType::find(-pdg::p);
1290  add_channel(process_list, [&] { return kminusp_kbar0n(s); },
1291  sqrt_s_, type_K_p, type_p_bar);
1292  }
1293  break;
1294  }
1295  }
1296  break;
1297  }
1298  case pdg::Kbar_z:
1299  switch (pdg_nucleon) {
1300  case pdg::p: {
1301  if (incl_Strangeness_exchange) {
1302  const auto& type_pi_z = ParticleType::find(pdg::pi_z);
1303  const auto& type_pi_p = ParticleType::find(pdg::pi_p);
1304  const auto& type_Sigma_p = ParticleType::find(pdg::Sigma_p);
1305  const auto& type_Sigma_z = ParticleType::find(pdg::Sigma_z);
1306  const auto& type_Lambda = ParticleType::find(pdg::Lambda);
1307  add_channel(process_list,
1308  [&] { return kminusn_piminussigma0(sqrt_s_); }, sqrt_s_,
1309  type_pi_z, type_Sigma_p);
1310  add_channel(process_list,
1311  [&] { return kminusn_piminussigma0(sqrt_s_); }, sqrt_s_,
1312  type_pi_p, type_Sigma_z);
1313  add_channel(process_list,
1314  [&] { return kminusn_piminuslambda(sqrt_s_); }, sqrt_s_,
1315  type_pi_p, type_Lambda);
1316  }
1317  break;
1318  }
1319  case pdg::n: {
1320  if (incl_Strangeness_exchange) {
1321  const auto& type_pi_z = ParticleType::find(pdg::pi_z);
1322  const auto& type_pi_m = ParticleType::find(pdg::pi_m);
1323  const auto& type_pi_p = ParticleType::find(pdg::pi_p);
1324  const auto& type_Sigma_p = ParticleType::find(pdg::Sigma_p);
1325  const auto& type_Sigma_m = ParticleType::find(pdg::Sigma_m);
1326  const auto& type_Sigma_z = ParticleType::find(pdg::Sigma_z);
1327  const auto& type_Lambda = ParticleType::find(pdg::Lambda);
1328  add_channel(process_list,
1329  [&] { return kminusp_piminussigmaplus(sqrt_s_); },
1330  sqrt_s_, type_pi_p, type_Sigma_m);
1331  add_channel(process_list,
1332  [&] { return kminusp_piplussigmaminus(sqrt_s_); },
1333  sqrt_s_, type_pi_m, type_Sigma_p);
1334  add_channel(process_list,
1335  [&] { return kminusp_pi0sigma0(sqrt_s_); }, sqrt_s_,
1336  type_pi_z, type_Sigma_z);
1337  add_channel(process_list,
1338  [&] { return kminusp_pi0lambda(sqrt_s_); }, sqrt_s_,
1339  type_pi_z, type_Lambda);
1340  }
1341  if (incl_KN_to_KN) {
1342  const auto& type_p = ParticleType::find(pdg::p);
1343  const auto& type_K_m = ParticleType::find(pdg::K_m);
1344  add_channel(process_list, [&] { return kminusp_kbar0n(s); },
1345  sqrt_s_, type_K_m, type_p);
1346  }
1347  break;
1348  }
1349  case -pdg::p: {
1350  if (incl_KN_to_KDelta) {
1351  const auto& type_K_m = ParticleType::find(pdg::K_m);
1352  const auto& type_Kbar_z = type_kaon;
1353  const auto& type_Delta_bar_m = ParticleType::find(-pdg::Delta_p);
1354  const auto& type_Delta_bar_z = ParticleType::find(-pdg::Delta_z);
1355  add_channel(process_list,
1356  [&] {
1357  return sigma_kplusn * kaon_nucleon_ratios.get_ratio(
1358  type_nucleon, type_kaon,
1359  type_Kbar_z,
1360  type_Delta_bar_m);
1361  },
1362  sqrt_s_, type_Kbar_z, type_Delta_bar_m);
1363  add_channel(process_list,
1364  [&] {
1365  return sigma_kplusn * kaon_nucleon_ratios.get_ratio(
1366  type_nucleon, type_kaon,
1367  type_K_m, type_Delta_bar_z);
1368  },
1369  sqrt_s_, type_K_m, type_Delta_bar_z);
1370  }
1371  if (incl_KN_to_KN) {
1372  const auto& type_K_m = ParticleType::find(pdg::K_m);
1373  const auto& type_n_bar = ParticleType::find(-pdg::n);
1374  add_channel(process_list,
1375  [&] {
1376  // The isospin factor is 1, see the parametrizations
1377  // tests.
1378  return kplusn_k0p(s);
1379  },
1380  sqrt_s_, type_K_m, type_n_bar);
1381  }
1382  break;
1383  }
1384  case -pdg::n: {
1385  if (incl_KN_to_KDelta) {
1386  const auto& type_K_m = ParticleType::find(pdg::K_m);
1387  const auto& type_Kbar_z = ParticleType::find(pdg::Kbar_z);
1388  const auto& type_Delta_z_bar = ParticleType::find(-pdg::Delta_z);
1389  const auto& type_Delta_m_bar = ParticleType::find(-pdg::Delta_m);
1390  add_channel(process_list,
1391  [&] {
1392  return sigma_kplusp * kaon_nucleon_ratios.get_ratio(
1393  type_nucleon, type_kaon,
1394  type_Kbar_z,
1395  type_Delta_z_bar);
1396  },
1397  sqrt_s_, type_Kbar_z, type_Delta_z_bar);
1398  add_channel(process_list,
1399  [&] {
1400  return sigma_kplusp * kaon_nucleon_ratios.get_ratio(
1401  type_nucleon, type_kaon,
1402  type_K_m, type_Delta_m_bar);
1403  },
1404  sqrt_s_, type_K_m, type_Delta_m_bar);
1405  }
1406  break;
1407  }
1408  }
1409  break;
1410  }
1411 
1412  return process_list;
1413 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ deltak_xx()

CollisionBranchList smash::CrossSections::deltak_xx ( ReactionsBitSet  included_2to2) const
private

Find all inelastic 2->2 processes for Delta-Kaon (DeltaK) Scattering.

Parameters
[in]included_2to2Which 2->2 reactions are enabled?
Returns
List of all possible DeltaK reactions with their cross sections

Definition at line 1415 of file crosssections.cc.

1416  {
1417  CollisionBranchList process_list;
1418  if (included_2to2[IncludedReactions::KN_to_KDelta] == 0) {
1419  return process_list;
1420  }
1421  const ParticleType& a = incoming_particles_[0].type();
1422  const ParticleType& b = incoming_particles_[1].type();
1423  const ParticleType& type_delta = a.pdgcode().is_Delta() ? a : b;
1424  const ParticleType& type_kaon = a.pdgcode().is_Delta() ? b : a;
1425 
1426  const auto pdg_delta = type_delta.pdgcode().code();
1427  const auto pdg_kaon = type_kaon.pdgcode().code();
1428 
1429  const double s = sqrt_s_ * sqrt_s_;
1430  const double pcm = cm_momentum();
1431  /* The cross sections are determined from the backward reactions via
1432  * detailed balance. The same isospin factors as for the backward reaction
1433  * are used. */
1434  switch (pack(pdg_delta, pdg_kaon)) {
1435  case pack(pdg::Delta_pp, pdg::K_z):
1436  case pack(pdg::Delta_p, pdg::K_p): {
1437  const auto& type_p = ParticleType::find(pdg::p);
1438  const auto& type_K_p = ParticleType::find(pdg::K_p);
1439  add_channel(process_list,
1440  [&] {
1441  return detailed_balance_factor_RK(sqrt_s_, pcm, type_delta,
1442  type_kaon, type_p,
1443  type_K_p) *
1445  type_p, type_K_p, type_kaon, type_delta) *
1447  },
1448  sqrt_s_, type_p, type_K_p);
1449  break;
1450  }
1451  case pack(-pdg::Delta_pp, pdg::Kbar_z):
1452  case pack(-pdg::Delta_p, pdg::K_m): {
1453  const auto& type_p_bar = ParticleType::find(-pdg::p);
1454  const auto& type_K_m = ParticleType::find(pdg::K_m);
1455  add_channel(process_list,
1456  [&] {
1457  return detailed_balance_factor_RK(sqrt_s_, pcm, type_delta,
1458  type_kaon, type_p_bar,
1459  type_K_m) *
1461  type_p_bar, type_K_m, type_kaon, type_delta) *
1463  },
1464  sqrt_s_, type_p_bar, type_K_m);
1465  break;
1466  }
1467  case pack(pdg::Delta_p, pdg::K_z):
1468  case pack(pdg::Delta_z, pdg::K_p): {
1469  const auto& type_n = ParticleType::find(pdg::n);
1470  const auto& type_p = ParticleType::find(pdg::p);
1471  const auto& type_K_p = ParticleType::find(pdg::K_p);
1472  const auto& type_K_z = ParticleType::find(pdg::K_z);
1473  add_channel(process_list,
1474  [&] {
1475  return detailed_balance_factor_RK(sqrt_s_, pcm, type_delta,
1476  type_kaon, type_n,
1477  type_K_p) *
1479  type_n, type_K_p, type_kaon, type_delta) *
1481  },
1482  sqrt_s_, type_n, type_K_p);
1483 
1484  add_channel(process_list,
1485  [&] {
1486  return detailed_balance_factor_RK(sqrt_s_, pcm, type_delta,
1487  type_kaon, type_p,
1488  type_K_z) *
1490  type_p, type_K_z, type_kaon, type_delta) *
1492  },
1493  sqrt_s_, type_p, type_K_z);
1494  break;
1495  }
1496  case pack(-pdg::Delta_p, pdg::Kbar_z):
1497  case pack(-pdg::Delta_z, pdg::K_m): {
1498  const auto& type_n_bar = ParticleType::find(-pdg::n);
1499  const auto& type_p_bar = ParticleType::find(-pdg::p);
1500  const auto& type_K_m = ParticleType::find(pdg::K_m);
1501  const auto& type_Kbar_z = ParticleType::find(pdg::Kbar_z);
1502  add_channel(process_list,
1503  [&] {
1504  return detailed_balance_factor_RK(sqrt_s_, pcm, type_delta,
1505  type_kaon, type_n_bar,
1506  type_K_m) *
1508  type_n_bar, type_K_m, type_kaon, type_delta) *
1510  },
1511  sqrt_s_, type_n_bar, type_K_m);
1512 
1513  add_channel(process_list,
1514  [&] {
1515  return detailed_balance_factor_RK(sqrt_s_, pcm, type_delta,
1516  type_kaon, type_p_bar,
1517  type_Kbar_z) *
1519  type_p_bar, type_Kbar_z, type_kaon, type_delta) *
1521  },
1522  sqrt_s_, type_p_bar, type_Kbar_z);
1523  break;
1524  }
1525  case pack(pdg::Delta_z, pdg::K_z):
1526  case pack(pdg::Delta_m, pdg::K_p): {
1527  const auto& type_n = ParticleType::find(pdg::n);
1528  const auto& type_K_z = ParticleType::find(pdg::K_z);
1529  add_channel(process_list,
1530  [&] {
1531  return detailed_balance_factor_RK(sqrt_s_, pcm, type_delta,
1532  type_kaon, type_n,
1533  type_K_z) *
1535  type_n, type_K_z, type_kaon, type_delta) *
1537  },
1538  sqrt_s_, type_n, type_K_z);
1539  break;
1540  }
1541  case pack(-pdg::Delta_z, pdg::Kbar_z):
1542  case pack(-pdg::Delta_m, pdg::K_m): {
1543  const auto& type_n_bar = ParticleType::find(-pdg::n);
1544  const auto& type_Kbar_z = ParticleType::find(pdg::Kbar_z);
1545  add_channel(process_list,
1546  [&] {
1547  return detailed_balance_factor_RK(sqrt_s_, pcm, type_delta,
1548  type_kaon, type_n_bar,
1549  type_Kbar_z) *
1551  type_n_bar, type_Kbar_z, type_kaon, type_delta) *
1553  },
1554  sqrt_s_, type_n_bar, type_Kbar_z);
1555  break;
1556  }
1557  default:
1558  break;
1559  }
1560 
1561  return process_list;
1562 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ypi_xx()

CollisionBranchList smash::CrossSections::ypi_xx ( ReactionsBitSet  included_2to2) const
private

Find all inelastic 2->2 processes for Hyperon-Pion (Ypi) Scattering.

Parameters
[in]included_2to2Which 2->2 reactions are enabled?
Returns
List of all possible Ypi reactions with their cross sections

Definition at line 1564 of file crosssections.cc.

1564  {
1565  CollisionBranchList process_list;
1566  if (included_2to2[IncludedReactions::Strangeness_exchange] == 0) {
1567  return process_list;
1568  }
1569  const ParticleType& a = incoming_particles_[0].type();
1570  const ParticleType& b = incoming_particles_[1].type();
1571  const ParticleType& type_hyperon = a.pdgcode().is_hyperon() ? a : b;
1572  const ParticleType& type_pion = a.pdgcode().is_hyperon() ? b : a;
1573 
1574  const auto pdg_hyperon = type_hyperon.pdgcode().code();
1575  const auto pdg_pion = type_pion.pdgcode().code();
1576 
1577  const double s = sqrt_s_ * sqrt_s_;
1578 
1579  switch (pack(pdg_hyperon, pdg_pion)) {
1580  case pack(pdg::Sigma_z, pdg::pi_m): {
1581  const auto& type_n = ParticleType::find(pdg::n);
1582  const auto& type_K_m = ParticleType::find(pdg::K_m);
1583  add_channel(process_list,
1584  [&] {
1586  s, type_hyperon, type_pion, type_n, type_K_m) *
1588  },
1589  sqrt_s_, type_n, type_K_m);
1590  break;
1591  }
1592  case pack(pdg::Sigma_z, pdg::pi_p): {
1593  const auto& type_p = ParticleType::find(pdg::p);
1594  const auto& type_Kbar_z = ParticleType::find(pdg::Kbar_z);
1595  add_channel(process_list,
1596  [&] {
1597  return detailed_balance_factor_stable(s, type_hyperon,
1598  type_pion, type_p,
1599  type_Kbar_z) *
1601  },
1602  sqrt_s_, type_p, type_Kbar_z);
1603  break;
1604  }
1605  case pack(-pdg::Sigma_z, pdg::pi_p): {
1606  const auto& type_n_bar = ParticleType::find(-pdg::n);
1607  const auto& type_K_p = ParticleType::find(pdg::K_p);
1608  add_channel(process_list,
1609  [&] {
1610  return detailed_balance_factor_stable(s, type_hyperon,
1611  type_pion, type_n_bar,
1612  type_K_p) *
1614  },
1615  sqrt_s_, type_n_bar, type_K_p);
1616  break;
1617  }
1618  case pack(-pdg::Sigma_z, pdg::pi_m): {
1619  const auto& type_p_bar = ParticleType::find(-pdg::p);
1620  const auto& type_K_z = ParticleType::find(pdg::K_z);
1621  add_channel(process_list,
1622  [&] {
1623  return detailed_balance_factor_stable(s, type_hyperon,
1624  type_pion, type_p_bar,
1625  type_K_z) *
1627  },
1628  sqrt_s_, type_p_bar, type_K_z);
1629  break;
1630  }
1631  case pack(pdg::Sigma_m, pdg::pi_z): {
1632  const auto& type_n = ParticleType::find(pdg::n);
1633  const auto& type_K_m = ParticleType::find(pdg::K_m);
1634  add_channel(process_list,
1635  [&] {
1637  s, type_hyperon, type_pion, type_n, type_K_m) *
1639  },
1640  sqrt_s_, type_n, type_K_m);
1641  break;
1642  }
1643  case pack(pdg::Sigma_p, pdg::pi_z): {
1644  const auto& type_p = ParticleType::find(pdg::p);
1645  const auto& type_Kbar_z = ParticleType::find(pdg::Kbar_z);
1646  add_channel(process_list,
1647  [&] {
1648  return detailed_balance_factor_stable(s, type_hyperon,
1649  type_pion, type_p,
1650  type_Kbar_z) *
1652  },
1653  sqrt_s_, type_p, type_Kbar_z);
1654  break;
1655  }
1656  case pack(-pdg::Sigma_m, pdg::pi_z): {
1657  const auto& type_n_bar = ParticleType::find(-pdg::n);
1658  const auto& type_K_p = ParticleType::find(pdg::K_p);
1659  add_channel(process_list,
1660  [&] {
1661  return detailed_balance_factor_stable(s, type_hyperon,
1662  type_pion, type_n_bar,
1663  type_K_p) *
1665  },
1666  sqrt_s_, type_n_bar, type_K_p);
1667  break;
1668  }
1669  case pack(-pdg::Sigma_p, pdg::pi_z): {
1670  const auto& type_p_bar = ParticleType::find(-pdg::p);
1671  const auto& type_K_z = ParticleType::find(pdg::K_z);
1672  add_channel(process_list,
1673  [&] {
1674  return detailed_balance_factor_stable(s, type_hyperon,
1675  type_pion, type_p_bar,
1676  type_K_z) *
1678  },
1679  sqrt_s_, type_p_bar, type_K_z);
1680  break;
1681  }
1682  case pack(pdg::Lambda, pdg::pi_m): {
1683  const auto& type_n = ParticleType::find(pdg::n);
1684  const auto& type_K_m = ParticleType::find(pdg::K_m);
1685  add_channel(process_list,
1686  [&] {
1688  s, type_hyperon, type_pion, type_n, type_K_m) *
1690  },
1691  sqrt_s_, type_n, type_K_m);
1692  break;
1693  }
1694  case pack(pdg::Lambda, pdg::pi_p): {
1695  const auto& type_p = ParticleType::find(pdg::p);
1696  const auto& type_Kbar_z = ParticleType::find(pdg::Kbar_z);
1697  add_channel(process_list,
1698  [&] {
1699  return detailed_balance_factor_stable(s, type_hyperon,
1700  type_pion, type_p,
1701  type_Kbar_z) *
1703  },
1704  sqrt_s_, type_p, type_Kbar_z);
1705  break;
1706  }
1707  case pack(-pdg::Lambda, pdg::pi_p): {
1708  const auto& type_n_bar = ParticleType::find(-pdg::n);
1709  const auto& type_K_p = ParticleType::find(pdg::K_p);
1710  add_channel(process_list,
1711  [&] {
1712  return detailed_balance_factor_stable(s, type_hyperon,
1713  type_pion, type_n_bar,
1714  type_K_p) *
1716  },
1717  sqrt_s_, type_n_bar, type_K_p);
1718  break;
1719  }
1720  case pack(-pdg::Lambda, pdg::pi_m): {
1721  const auto& type_p_bar = ParticleType::find(-pdg::p);
1722  const auto& type_K_z = ParticleType::find(pdg::K_z);
1723  add_channel(process_list,
1724  [&] {
1725  return detailed_balance_factor_stable(s, type_hyperon,
1726  type_pion, type_p_bar,
1727  type_K_z) *
1729  },
1730  sqrt_s_, type_p_bar, type_K_z);
1731  break;
1732  }
1733  case pack(pdg::Sigma_z, pdg::pi_z): {
1734  const auto& type_p = ParticleType::find(pdg::p);
1735  const auto& type_n = ParticleType::find(pdg::n);
1736  const auto& type_Kbar_z = ParticleType::find(pdg::Kbar_z);
1737  const auto& type_K_m = ParticleType::find(pdg::K_m);
1738  add_channel(process_list,
1739  [&] {
1741  s, type_hyperon, type_pion, type_p, type_K_m) *
1743  },
1744  sqrt_s_, type_p, type_K_m);
1745  add_channel(process_list,
1746  [&] {
1747  return detailed_balance_factor_stable(s, type_hyperon,
1748  type_pion, type_n,
1749  type_Kbar_z) *
1751  },
1752  sqrt_s_, type_n, type_Kbar_z);
1753  break;
1754  }
1755  case pack(-pdg::Sigma_z, pdg::pi_z): {
1756  const auto& type_p_bar = ParticleType::find(-pdg::p);
1757  const auto& type_n_bar = ParticleType::find(-pdg::n);
1758  const auto& type_K_z = ParticleType::find(pdg::K_z);
1759  const auto& type_K_p = ParticleType::find(pdg::K_p);
1760  add_channel(process_list,
1761  [&] {
1762  return detailed_balance_factor_stable(s, type_hyperon,
1763  type_pion, type_p_bar,
1764  type_K_p) *
1766  },
1767  sqrt_s_, type_p_bar, type_K_p);
1768  add_channel(process_list,
1769  [&] {
1770  return detailed_balance_factor_stable(s, type_hyperon,
1771  type_pion, type_n_bar,
1772  type_K_z) *
1774  },
1775  sqrt_s_, type_n_bar, type_K_z);
1776  break;
1777  }
1778  case pack(pdg::Sigma_m, pdg::pi_p): {
1779  const auto& type_p = ParticleType::find(pdg::p);
1780  const auto& type_n = ParticleType::find(pdg::n);
1781  const auto& type_Kbar_z = ParticleType::find(pdg::Kbar_z);
1782  const auto& type_K_m = ParticleType::find(pdg::K_m);
1783  add_channel(process_list,
1784  [&] {
1786  s, type_hyperon, type_pion, type_p, type_K_m) *
1788  },
1789  sqrt_s_, type_p, type_K_m);
1790  add_channel(process_list,
1791  [&] {
1792  return detailed_balance_factor_stable(s, type_hyperon,
1793  type_pion, type_n,
1794  type_Kbar_z) *
1796  },
1797  sqrt_s_, type_n, type_Kbar_z);
1798  break;
1799  }
1800  case pack(-pdg::Sigma_m, pdg::pi_m): {
1801  const auto& type_p_bar = ParticleType::find(-pdg::p);
1802  const auto& type_n_bar = ParticleType::find(-pdg::n);
1803  const auto& type_K_z = ParticleType::find(pdg::K_z);
1804  const auto& type_K_p = ParticleType::find(pdg::K_p);
1805  add_channel(process_list,
1806  [&] {
1807  return detailed_balance_factor_stable(s, type_hyperon,
1808  type_pion, type_p_bar,
1809  type_K_p) *
1811  },
1812  sqrt_s_, type_p_bar, type_K_p);
1813  add_channel(process_list,
1814  [&] {
1815  return detailed_balance_factor_stable(s, type_hyperon,
1816  type_pion, type_n_bar,
1817  type_K_z) *
1819  },
1820  sqrt_s_, type_n_bar, type_K_z);
1821  break;
1822  }
1823  case pack(pdg::Lambda, pdg::pi_z): {
1824  const auto& type_p = ParticleType::find(pdg::p);
1825  const auto& type_n = ParticleType::find(pdg::n);
1826  const auto& type_Kbar_z = ParticleType::find(pdg::Kbar_z);
1827  const auto& type_K_m = ParticleType::find(pdg::K_m);
1828  add_channel(process_list,
1829  [&] {
1831  s, type_hyperon, type_pion, type_p, type_K_m) *
1833  },
1834  sqrt_s_, type_p, type_K_m);
1835  add_channel(process_list,
1836  [&] {
1837  return detailed_balance_factor_stable(s, type_hyperon,
1838  type_pion, type_n,
1839  type_Kbar_z) *
1841  },
1842  sqrt_s_, type_n, type_Kbar_z);
1843  break;
1844  }
1845  case pack(-pdg::Lambda, pdg::pi_z): {
1846  const auto& type_p_bar = ParticleType::find(-pdg::p);
1847  const auto& type_n_bar = ParticleType::find(-pdg::n);
1848  const auto& type_K_z = ParticleType::find(pdg::K_z);
1849  const auto& type_K_p = ParticleType::find(pdg::K_p);
1850  add_channel(process_list,
1851  [&] {
1852  return detailed_balance_factor_stable(s, type_hyperon,
1853  type_pion, type_p_bar,
1854  type_K_p) *
1856  },
1857  sqrt_s_, type_p_bar, type_K_p);
1858  add_channel(process_list,
1859  [&] {
1860  return detailed_balance_factor_stable(s, type_hyperon,
1861  type_pion, type_n_bar,
1862  type_K_z) *
1864  },
1865  sqrt_s_, type_n_bar, type_K_z);
1866  break;
1867  }
1868  case pack(pdg::Sigma_p, pdg::pi_m): {
1869  const auto& type_p = ParticleType::find(pdg::p);
1870  const auto& type_n = ParticleType::find(pdg::n);
1871  const auto& type_K_m = ParticleType::find(pdg::K_m);
1872  const auto& type_Kbar_z = ParticleType::find(pdg::Kbar_z);
1873  add_channel(process_list,
1874  [&] {
1876  s, type_hyperon, type_pion, type_p, type_K_m) *
1878  },
1879  sqrt_s_, type_p, type_K_m);
1880  add_channel(process_list,
1881  [&] {
1882  return detailed_balance_factor_stable(s, type_hyperon,
1883  type_pion, type_n,
1884  type_Kbar_z) *
1886  },
1887  sqrt_s_, type_n, type_Kbar_z);
1888  break;
1889  }
1890  case pack(-pdg::Sigma_p, pdg::pi_p): {
1891  const auto& type_p_bar = ParticleType::find(-pdg::p);
1892  const auto& type_n_bar = ParticleType::find(-pdg::n);
1893  const auto& type_K_p = ParticleType::find(pdg::K_p);
1894  const auto& type_K_z = ParticleType::find(pdg::K_z);
1895  add_channel(process_list,
1896  [&] {
1897  return detailed_balance_factor_stable(s, type_hyperon,
1898  type_pion, type_p_bar,
1899  type_K_p) *
1901  },
1902  sqrt_s_, type_p_bar, type_K_p);
1903  add_channel(process_list,
1904  [&] {
1905  return detailed_balance_factor_stable(s, type_hyperon,
1906  type_pion, type_n_bar,
1907  type_K_z) *
1909  },
1910  sqrt_s_, type_n_bar, type_K_z);
1911  break;
1912  }
1913  default:
1914  break;
1915  }
1916 
1917  return process_list;
1918 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ dpi_xx()

CollisionBranchList smash::CrossSections::dpi_xx ( ReactionsBitSet  included_2to2) const
private

Find all inelastic 2->2 processes involving Pion and (anti-) Deuteron (dpi), specifically dπ→ NN, d̅π→ N̅N̅; πd→ πd' (mockup for πd→ πnp), πd̅→ πd̅' and reverse.

Parameters
[in]included_2to2Which 2->2 reactions are enabled?
Returns
List of all possible dpi reactions with their cross sections

Definition at line 1920 of file crosssections.cc.

1920  {
1921  CollisionBranchList process_list;
1922  const double sqrts = sqrt_s_;
1923  const ParticleType& type_a = incoming_particles_[0].type();
1924  const ParticleType& type_b = incoming_particles_[1].type();
1925 
1926  // pi d -> N N
1927  bool is_pid = (type_a.is_deuteron() && type_b.pdgcode().is_pion()) ||
1928  (type_b.is_deuteron() && type_a.pdgcode().is_pion());
1929  if (is_pid && included_2to2[IncludedReactions::PiDeuteron_to_NN] == 1) {
1930  const int baryon_number = type_a.baryon_number() + type_b.baryon_number();
1931  ParticleTypePtrList nuc = (baryon_number > 0)
1934  const double s = sqrt_s_ * sqrt_s_;
1935  for (ParticleTypePtr nuc_a : nuc) {
1936  for (ParticleTypePtr nuc_b : nuc) {
1937  if (type_a.charge() + type_b.charge() !=
1938  nuc_a->charge() + nuc_b->charge()) {
1939  continue;
1940  }
1941  // loop over total isospin
1942  for (const int twoI : I_tot_range(*nuc_a, *nuc_b)) {
1943  const double isospin_factor = isospin_clebsch_gordan_sqr_2to2(
1944  type_a, type_b, *nuc_a, *nuc_b, twoI);
1945  // If Clebsch-Gordan coefficient = 0, don't bother with the rest.
1946  if (std::abs(isospin_factor) < really_small) {
1947  continue;
1948  }
1949 
1950  // Calculate matrix element for inverse process.
1951  const double matrix_element =
1952  nn_to_resonance_matrix_element(sqrts, type_a, type_b, twoI);
1953  if (matrix_element <= 0.) {
1954  continue;
1955  }
1956 
1957  const double spin_factor = (nuc_a->spin() + 1) * (nuc_b->spin() + 1);
1958  const int sym_fac_in =
1959  (type_a.iso_multiplet() == type_b.iso_multiplet()) ? 2 : 1;
1960  const int sym_fac_out =
1961  (nuc_a->iso_multiplet() == nuc_b->iso_multiplet()) ? 2 : 1;
1962  double p_cm_final = pCM_from_s(s, nuc_a->mass(), nuc_b->mass());
1963  const double xsection = isospin_factor * spin_factor * sym_fac_in /
1964  sym_fac_out * p_cm_final * matrix_element /
1965  (s * cm_momentum());
1966 
1967  if (xsection > really_small) {
1968  process_list.push_back(make_unique<CollisionBranch>(
1969  *nuc_a, *nuc_b, xsection, ProcessType::TwoToTwo));
1970  logg[LScatterAction].debug(type_a.name(), type_b.name(), "->",
1971  nuc_a->name(), nuc_b->name(),
1972  " at sqrts [GeV] = ", sqrts,
1973  " with cs[mb] = ", xsection);
1974  }
1975  }
1976  }
1977  }
1978  }
1979 
1980  // pi d -> pi d' (effectively pi d -> pi p n) AND reverse, pi d' -> pi d
1981  bool is_pid_or_pidprime = ((type_a.is_deuteron() || type_a.is_dprime()) &&
1982  type_b.pdgcode().is_pion()) ||
1983  ((type_b.is_deuteron() || type_b.is_dprime()) &&
1984  type_a.pdgcode().is_pion());
1985  if (is_pid_or_pidprime &&
1986  included_2to2[IncludedReactions::PiDeuteron_to_pidprime] == 1) {
1987  const ParticleType& type_pi = type_a.pdgcode().is_pion() ? type_a : type_b;
1988  const ParticleType& type_nucleus = type_a.is_nucleus() ? type_a : type_b;
1989  ParticleTypePtrList nuclei = ParticleType::list_light_nuclei();
1990  const double s = sqrt_s_ * sqrt_s_;
1991  for (ParticleTypePtr produced_nucleus : nuclei) {
1992  // Elastic collisions are treated in a different function
1993  if (produced_nucleus == &type_nucleus ||
1994  produced_nucleus->charge() != type_nucleus.charge() ||
1995  produced_nucleus->baryon_number() != type_nucleus.baryon_number()) {
1996  continue;
1997  }
1998  // same matrix element for πd and πd̅
1999  const double tmp = sqrts - pion_mass - deuteron_mass;
2000  // Matrix element is fit to match the inelastic pi+ d -> pi+ n p
2001  // cross-section from the Fig. 5 of [\iref{Arndt:1994bs}].
2002  const double matrix_element =
2003  295.5 + 2.862 / (0.00283735 + pow_int(sqrts - 2.181, 2)) +
2004  0.0672 / pow_int(tmp, 2) - 6.61753 / tmp;
2005  const double spin_factor =
2006  (produced_nucleus->spin() + 1) * (type_pi.spin() + 1);
2007  /* Isospin factor is always the same, so it is included into the
2008  * matrix element.
2009  * Symmetry factor is always 1 here.
2010  * The (hbarc)^2/16 pi factor is absorbed into matrix element. */
2011  double xsection = matrix_element * spin_factor / (s * cm_momentum());
2012  if (produced_nucleus->is_stable()) {
2013  assert(!type_nucleus.is_stable());
2014  xsection *= pCM_from_s(s, type_pi.mass(), produced_nucleus->mass());
2015  } else {
2016  assert(type_nucleus.is_stable());
2017  const double resonance_integral =
2018  produced_nucleus->iso_multiplet()->get_integral_piR(sqrts);
2019  xsection *= resonance_integral;
2020  logg[LScatterAction].debug("Resonance integral ", resonance_integral,
2021  ", matrix element: ", matrix_element,
2022  ", cm_momentum: ", cm_momentum());
2023  }
2024  process_list.push_back(make_unique<CollisionBranch>(
2025  type_pi, *produced_nucleus, xsection, ProcessType::TwoToTwo));
2026  logg[LScatterAction].debug(type_pi.name(), type_nucleus.name(), "→ ",
2027  type_pi.name(), produced_nucleus->name(),
2028  " at ", sqrts, " GeV, xs[mb] = ", xsection);
2029  }
2030  }
2031  return process_list;
2032 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ dn_xx()

CollisionBranchList smash::CrossSections::dn_xx ( ReactionsBitSet  included_2to2) const
private

Find all inelastic 2->2 processes involving Nucleon and (anti-) Deuteron (dN), specifically Nd → Nd', N̅d → N̅d', N̅d̅→ N̅d̅', Nd̅→ Nd̅' and reverse (e.g.

Nd'→ Nd).

Parameters
[in]included_2to2Which 2->2 reactions are enabled?
Returns
List of all possible dN reactions with their cross sections

Nd → Nd', N̅d̅→ N̅d̅' and reverse: Fit to match experimental cross-section Nd -> Nnp from [13].

N̅d → N̅d', Nd̅→ Nd̅' and reverse: Fit to roughly match experimental cross-section N̅d -> N̅ np from Bizzarri:1973sp [7].

Definition at line 2034 of file crosssections.cc.

2034  {
2035  const ParticleType& type_a = incoming_particles_[0].type();
2036  const ParticleType& type_b = incoming_particles_[1].type();
2037  const ParticleType& type_N = type_a.is_nucleon() ? type_a : type_b;
2038  const ParticleType& type_nucleus = type_a.is_nucleus() ? type_a : type_b;
2039  CollisionBranchList process_list;
2040  if (included_2to2[IncludedReactions::NDeuteron_to_Ndprime] == 0) {
2041  return process_list;
2042  }
2043  ParticleTypePtrList nuclei = ParticleType::list_light_nuclei();
2044  const double s = sqrt_s_ * sqrt_s_;
2045  const double sqrts = sqrt_s_;
2046 
2047  for (ParticleTypePtr produced_nucleus : nuclei) {
2048  // No elastic collisions for now, respect conservation laws
2049  if (produced_nucleus == &type_nucleus ||
2050  produced_nucleus->charge() != type_nucleus.charge() ||
2051  produced_nucleus->baryon_number() != type_nucleus.baryon_number()) {
2052  continue;
2053  }
2054  double matrix_element = 0.0;
2055  double tmp = sqrts - nucleon_mass - deuteron_mass;
2056  assert(tmp >= 0.0);
2057  if (std::signbit(type_N.baryon_number()) ==
2058  std::signbit(type_nucleus.baryon_number())) {
2062  matrix_element = 79.0474 / std::pow(tmp, 0.7897) + 654.596 * tmp;
2063  } else {
2067  matrix_element = 342.572 / std::pow(tmp, 0.6);
2068  }
2069  const double spin_factor =
2070  (produced_nucleus->spin() + 1) * (type_N.spin() + 1);
2071  /* Isospin factor is always the same, so it is included into matrix element
2072  * Symmetry factor is always 1 here
2073  * Absorb (hbarc)^2/16 pi factor into matrix element */
2074  double xsection = matrix_element * spin_factor / (s * cm_momentum());
2075  if (produced_nucleus->is_stable()) {
2076  assert(!type_nucleus.is_stable());
2077  xsection *= pCM_from_s(s, type_N.mass(), produced_nucleus->mass());
2078  } else {
2079  assert(type_nucleus.is_stable());
2080  const double resonance_integral =
2081  produced_nucleus->iso_multiplet()->get_integral_NR(sqrts);
2082  xsection *= resonance_integral;
2083  }
2084  process_list.push_back(make_unique<CollisionBranch>(
2085  type_N, *produced_nucleus, xsection, ProcessType::TwoToTwo));
2086  logg[LScatterAction].debug(type_N.name(), type_nucleus.name(), "→ ",
2087  type_N.name(), produced_nucleus->name(), " at ",
2088  sqrts, " GeV, xs[mb] = ", xsection);
2089  }
2090  return process_list;
2091 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ string_hard_cross_section()

double smash::CrossSections::string_hard_cross_section ( ) const
private

Determine the (parametrized) hard non-diffractive string cross section for this collision.

Returns
Parametrized cross section (without AQM scaling).

Definition at line 2291 of file crosssections.cc.

2291  {
2292  double cross_sec = 0.;
2293  /* Hard strings can only be excited if the lower cutoff by
2294  * Pythia is fulfilled */
2296  return cross_sec;
2297  }
2298  const ParticleData& data_a = incoming_particles_[0];
2299  const ParticleData& data_b = incoming_particles_[1];
2300 
2301  if (data_a.is_baryon() && data_b.is_baryon()) {
2302  // Nucleon-nucleon cross section is used for all baryon-baryon cases.
2303  cross_sec = NN_string_hard(sqrt_s_ * sqrt_s_);
2304  } else if (data_a.is_baryon() || data_b.is_baryon()) {
2305  // Nucleon-pion cross section is used for all baryon-meson cases.
2306  cross_sec = Npi_string_hard(sqrt_s_ * sqrt_s_);
2307  } else {
2308  // Pion-pion cross section is used for all meson-meson cases.
2309  cross_sec = pipi_string_hard(sqrt_s_ * sqrt_s_);
2310  }
2311 
2312  return cross_sec;
2313 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ bar_bar_to_nuc_nuc()

CollisionBranchList smash::CrossSections::bar_bar_to_nuc_nuc ( const bool  is_anti_particles) const
private

Calculate cross sections for resonance absorption (i.e.

NR->NN and ΔR->NN).

Parameters
[in]is_anti_particlesWhether the colliding particles are antiparticles
Returns
List of possible resonance absorption processes. Each element of the list contains the types of the final-state particles and the cross section for that particular process.

Cross section for 2->2 resonance absorption, obtained via detailed balance from the inverse reaction. See eqs. (B.6), (B.9) and (181) in Buss:2011mx [10]. There are factors for spin, isospin and symmetry involved.

Definition at line 2356 of file crosssections.cc.

2357  {
2358  const ParticleType& type_a = incoming_particles_[0].type();
2359  const ParticleType& type_b = incoming_particles_[1].type();
2360  CollisionBranchList process_list;
2361 
2362  const double s = sqrt_s_ * sqrt_s_;
2363  // CM momentum in final state
2364  double p_cm_final = std::sqrt(s - 4. * nucleon_mass * nucleon_mass) / 2.;
2365 
2366  ParticleTypePtrList nuc_or_anti_nuc;
2367  if (is_anti_particles) {
2368  nuc_or_anti_nuc = ParticleType::list_anti_nucleons();
2369  } else {
2370  nuc_or_anti_nuc = ParticleType::list_nucleons();
2371  }
2372 
2373  // Loop over all nucleon or anti-nucleon charge states.
2374  for (ParticleTypePtr nuc_a : nuc_or_anti_nuc) {
2375  for (ParticleTypePtr nuc_b : nuc_or_anti_nuc) {
2376  /* Check for charge conservation. */
2377  if (type_a.charge() + type_b.charge() !=
2378  nuc_a->charge() + nuc_b->charge()) {
2379  continue;
2380  }
2381  // loop over total isospin
2382  for (const int twoI : I_tot_range(*nuc_a, *nuc_b)) {
2383  const double isospin_factor = isospin_clebsch_gordan_sqr_2to2(
2384  type_a, type_b, *nuc_a, *nuc_b, twoI);
2385  // If Clebsch-Gordan coefficient is zero, don't bother with the rest
2386  if (std::abs(isospin_factor) < really_small) {
2387  continue;
2388  }
2389 
2390  // Calculate matrix element for inverse process.
2391  const double matrix_element =
2392  nn_to_resonance_matrix_element(sqrt_s_, type_a, type_b, twoI);
2393  if (matrix_element <= 0.) {
2394  continue;
2395  }
2396 
2401  const double spin_factor = (nuc_a->spin() + 1) * (nuc_b->spin() + 1);
2402  const int sym_fac_in =
2403  (type_a.iso_multiplet() == type_b.iso_multiplet()) ? 2 : 1;
2404  const int sym_fac_out =
2405  (nuc_a->iso_multiplet() == nuc_b->iso_multiplet()) ? 2 : 1;
2406  const double xsection = isospin_factor * spin_factor * sym_fac_in /
2407  sym_fac_out * p_cm_final * matrix_element /
2408  (s * cm_momentum());
2409 
2410  if (xsection > really_small) {
2411  process_list.push_back(make_unique<CollisionBranch>(
2412  *nuc_a, *nuc_b, xsection, ProcessType::TwoToTwo));
2413  logg[LCrossSections].debug(
2414  "2->2 absorption with original particles: ", type_a, type_b);
2415  }
2416  }
2417  }
2418  }
2419  return process_list;
2420 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nn_to_resonance_matrix_element()

double smash::CrossSections::nn_to_resonance_matrix_element ( double  sqrts,
const ParticleType type_a,
const ParticleType type_b,
const int  twoI 
)
staticprivate

Scattering matrix amplitude squared (divided by 16π) for resonance production processes like NN → NR and NN → ΔR, where R is a baryon resonance (Δ, N*, Δ*).

Includes no spin or isospin factors.

Parameters
[in]sqrtssqrt(Mandelstam-s), i.e. collision CMS energy.
[in]type_aType information for the first final-state particle.
[in]type_bType information for the second final-state particle.
[in]twoITwice the total isospin of the involved state.
Returns
Matrix amplitude squared \( |\mathcal{M}(\sqrt{s})|^2/16\pi \).

NN → NΔ: fit sqrt(s)-dependence to OBE model [Dmitriev:1986st [16]]

All other processes use a constant matrix element, similar to Bass:1998ca [4], equ. (3.35).

pn → pnη cross section is known to be larger than the corresponding pp → ppη cross section by a factor of 6.5 [Calen:1998vh [11]]. Since the eta is mainly produced by an intermediate N*(1535) we introduce an explicit isospin asymmetry for the production of N*(1535) produced in pn vs. pp similar to [Teis:1996kx [43]], eq. 29.

Definition at line 2422 of file crosssections.cc.

2425  {
2426  const double m_a = type_a.mass();
2427  const double m_b = type_b.mass();
2428  const double msqr = 2. * (m_a * m_a + m_b * m_b);
2429  /* If the c.m. energy is larger than the sum of the pole masses of the
2430  * outgoing particles plus three times of the sum of the widths plus 3 GeV,
2431  * the collision will be neglected.
2432  *
2433  * This can be problematic for some final-state cross sections, but at
2434  * energies that high strings are used anyway.
2435  */
2436  const double w_a = type_a.width_at_pole();
2437  const double w_b = type_b.width_at_pole();
2438  const double uplmt = m_a + m_b + 3.0 * (w_a + w_b) + 3.0;
2439  if (sqrts > uplmt) {
2440  return 0.;
2441  }
2443  if (((type_a.is_Delta() && type_b.is_nucleon()) ||
2444  (type_b.is_Delta() && type_a.is_nucleon())) &&
2445  (type_a.antiparticle_sign() == type_b.antiparticle_sign())) {
2446  return 68. / std::pow(sqrts - 1.104, 1.951);
2449  } else if (((type_a.is_Nstar() && type_b.is_nucleon()) ||
2450  (type_b.is_Nstar() && type_a.is_nucleon())) &&
2451  type_a.antiparticle_sign() == type_b.antiparticle_sign()) {
2452  // NN → NN*
2453  if (twoI == 2) {
2454  return 4.5 / msqr;
2455  } else if (twoI == 0) {
2456  const double parametrization = 14. / msqr;
2462  if (type_a.is_Nstar1535() || type_b.is_Nstar1535()) {
2463  return 6.5 * parametrization;
2464  } else {
2465  return parametrization;
2466  }
2467  }
2468  } else if (((type_a.is_Deltastar() && type_b.is_nucleon()) ||
2469  (type_b.is_Deltastar() && type_a.is_nucleon())) &&
2470  type_a.antiparticle_sign() == type_b.antiparticle_sign()) {
2471  // NN → NΔ*
2472  return 15. / msqr;
2473  } else if ((type_a.is_Delta() && type_b.is_Delta()) &&
2474  (type_a.antiparticle_sign() == type_b.antiparticle_sign())) {
2475  // NN → ΔΔ
2476  if (twoI == 2) {
2477  return 45. / msqr;
2478  } else if (twoI == 0) {
2479  return 120. / msqr;
2480  }
2481  } else if (((type_a.is_Nstar() && type_b.is_Delta()) ||
2482  (type_b.is_Nstar() && type_a.is_Delta())) &&
2483  type_a.antiparticle_sign() == type_b.antiparticle_sign()) {
2484  // NN → ΔN*
2485  return 7. / msqr;
2486  } else if (((type_a.is_Deltastar() && type_b.is_Delta()) ||
2487  (type_b.is_Deltastar() && type_a.is_Delta())) &&
2488  type_a.antiparticle_sign() == type_b.antiparticle_sign()) {
2489  // NN → ΔΔ*
2490  if (twoI == 2) {
2491  return 15. / msqr;
2492  } else if (twoI == 0) {
2493  return 25. / msqr;
2494  }
2495  } else if ((type_a.is_deuteron() && type_b.pdgcode().is_pion()) ||
2496  (type_b.is_deuteron() && type_a.pdgcode().is_pion())) {
2497  /* This parametrization is the result of fitting d+pi->NN cross-section.
2498  * Already Breit-Wigner-like part provides a good fit, exponential fixes
2499  * behaviour around the treshold. The d+pi experimental cross-section
2500  * was taken from Fig. 2 of [\iref{Tanabe:1987vg}]. */
2501  return 0.055 / (pow_int(sqrts - 2.145, 2) + pow_int(0.065, 2)) *
2502  (1.0 - std::exp(-(sqrts - 2.0) * 20.0));
2503  }
2504 
2505  // all cases not listed: zero!
2506  return 0.;
2507 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ find_nn_xsection_from_type()

template<class IntegrationMethod >
CollisionBranchList smash::CrossSections::find_nn_xsection_from_type ( const ParticleTypePtrList &  type_res_1,
const ParticleTypePtrList &  type_res_2,
const IntegrationMethod  integrator 
) const
private

Utility function to avoid code replication in nn_xx().

Parameters
[in]type_res_1List of possible first final resonance types
[in]type_res_2List of possible second final resonance types
[in]integratorUsed to integrate over the kinematically allowed mass range of the Breit-Wigner distribution
Returns
List of all possible NN reactions with their cross sections with different final states

Cross section for 2->2 process with 1/2 resonance(s) in final state. Based on Eq. (46) in Weil:2013mya [46] and Eq. (3.29) in Bass:1998ca [4]

Definition at line 2510 of file crosssections.cc.

2513  {
2514  const ParticleType& type_particle_a = incoming_particles_[0].type();
2515  const ParticleType& type_particle_b = incoming_particles_[1].type();
2516 
2517  CollisionBranchList channel_list;
2518  const double s = sqrt_s_ * sqrt_s_;
2519 
2520  // Loop over specified first resonance list
2521  for (ParticleTypePtr type_res_1 : list_res_1) {
2522  // Loop over specified second resonance list
2523  for (ParticleTypePtr type_res_2 : list_res_2) {
2524  // Check for charge conservation.
2525  if (type_res_1->charge() + type_res_2->charge() !=
2526  type_particle_a.charge() + type_particle_b.charge()) {
2527  continue;
2528  }
2529 
2530  // loop over total isospin
2531  for (const int twoI : I_tot_range(type_particle_a, type_particle_b)) {
2532  const double isospin_factor = isospin_clebsch_gordan_sqr_2to2(
2533  type_particle_a, type_particle_b, *type_res_1, *type_res_2, twoI);
2534  // If Clebsch-Gordan coefficient is zero, don't bother with the rest.
2535  if (std::abs(isospin_factor) < really_small) {
2536  continue;
2537  }
2538 
2539  // Integration limits.
2540  const double lower_limit = type_res_1->min_mass_kinematic();
2541  const double upper_limit = sqrt_s_ - type_res_2->mass();
2542  /* Check the available energy (requiring it to be a little above the
2543  * threshold, because the integration will not work if it's too close).
2544  */
2545  if (upper_limit - lower_limit < 1E-3) {
2546  continue;
2547  }
2548 
2549  // Calculate matrix element.
2550  const double matrix_element = nn_to_resonance_matrix_element(
2551  sqrt_s_, *type_res_1, *type_res_2, twoI);
2552  if (matrix_element <= 0.) {
2553  continue;
2554  }
2555 
2556  /* Calculate resonance production cross section
2557  * using the Breit-Wigner distribution as probability amplitude.
2558  * Integrate over the allowed resonance mass range. */
2559  const double resonance_integral = integrator(*type_res_1, *type_res_2);
2560 
2564  const double spin_factor =
2565  (type_res_1->spin() + 1) * (type_res_2->spin() + 1);
2566  const double xsection = isospin_factor * spin_factor * matrix_element *
2567  resonance_integral / (s * cm_momentum());
2568 
2569  if (xsection > really_small) {
2570  channel_list.push_back(make_unique<CollisionBranch>(
2571  *type_res_1, *type_res_2, xsection, ProcessType::TwoToTwo));
2572  logg[LCrossSections].debug(
2573  "Found 2->2 creation process for resonance ", type_res_1, ", ",
2574  type_res_2);
2575  logg[LCrossSections].debug("2->2 with original particles: ",
2576  type_particle_a, type_particle_b);
2577  }
2578  }
2579  }
2580  }
2581  return channel_list;
2582 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ cm_momentum()

double smash::CrossSections::cm_momentum ( ) const
inlineprivate

Determine the momenta of the incoming particles in the center-of-mass system.

Returns
Center-of-mass momentum

Definition at line 458 of file crosssections.h.

458  {
459  const double m1 = incoming_particles_[0].effective_mass();
460  const double m2 = incoming_particles_[1].effective_mass();
461  return pCM(sqrt_s_, m1, m2);
462  }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ add_channel()

template<typename F >
void smash::CrossSections::add_channel ( CollisionBranchList &  process_list,
F &&  get_xsection,
double  sqrts,
const ParticleType type_a,
const ParticleType type_b 
) const
inlineprivate

Helper function: Add a 2-to-2 channel to a collision branch list given a cross section.

The cross section is only calculated if there is enough energy for the process. If the cross section is small, the branch is not added.

Definition at line 487 of file crosssections.h.

489  {
490  const double sqrt_s_min =
491  type_a.min_mass_spectral() + type_b.min_mass_spectral();
492  /* Determine wether the process is below the threshold. */
493  double scale_B = 0.0;
494  double scale_I3 = 0.0;
495  bool is_below_threshold;
496  FourVector incoming_momentum = FourVector();
497  if (pot_pointer != nullptr) {
498  for (const auto p : incoming_particles_) {
499  incoming_momentum += p.momentum();
500  scale_B += pot_pointer->force_scale(p.type()).first;
501  scale_I3 +=
502  pot_pointer->force_scale(p.type()).second * p.type().isospin3_rel();
503  }
504  scale_B -= pot_pointer->force_scale(type_a).first;
505  scale_I3 -=
506  pot_pointer->force_scale(type_a).second * type_a.isospin3_rel();
507  scale_B -= pot_pointer->force_scale(type_b).first;
508  scale_I3 -=
509  pot_pointer->force_scale(type_b).second * type_b.isospin3_rel();
510  is_below_threshold = (incoming_momentum + potentials_.first * scale_B +
511  potentials_.second * scale_I3)
512  .abs() <= sqrt_s_min;
513  } else {
514  is_below_threshold = (sqrts <= sqrt_s_min);
515  }
516  if (is_below_threshold) {
517  return;
518  }
519  const auto xsection = get_xsection();
520  if (xsection > really_small) {
521  process_list.push_back(make_unique<CollisionBranch>(
522  type_a, type_b, xsection, ProcessType::TwoToTwo));
523  }
524  }
Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ incoming_particles_

const ParticleList smash::CrossSections::incoming_particles_
private

List with data of scattering particles.

Definition at line 465 of file crosssections.h.

◆ sqrt_s_

const double smash::CrossSections::sqrt_s_
private

Total energy in the center-of-mass frame.

Definition at line 468 of file crosssections.h.

◆ potentials_

const std::pair<FourVector, FourVector> smash::CrossSections::potentials_
private

Potentials at the interacting point.

They are used to calculate the corrections on the threshold energies.

Definition at line 474 of file crosssections.h.

◆ is_BBbar_pair_

const bool smash::CrossSections::is_BBbar_pair_
private

Whether incoming particles are a baryon-antibaryon pair.

Definition at line 477 of file crosssections.h.


The documentation for this class was generated from the following files:
NN_to_DR
Definition: forwarddeclarations.h:215
smash::ParticleType::list_nucleons
static ParticleTypePtrList & list_nucleons()
Definition: particletype.cc:75
smash::ppbar_high_energy
double ppbar_high_energy(double mandelstam_s)
ppbar total cross section at high energies
Definition: parametrizations.cc:48
smash::CrossSections::bar_bar_to_nuc_nuc
CollisionBranchList bar_bar_to_nuc_nuc(const bool is_anti_particles) const
Calculate cross sections for resonance absorption (i.e.
Definition: crosssections.cc:2356
smash::k0p_elastic_background
double k0p_elastic_background(double mandelstam_s)
K0 p elastic background cross section parametrization Source: Buss:2011mx , B.3.9.
Definition: parametrizations.cc:512
smash::ParticleType::list_anti_nucleons
static ParticleTypePtrList & list_anti_nucleons()
Definition: particletype.cc:77
smash::ProcessType::StringHard
hard string process involving 2->2 QCD process by PYTHIA.
smash::kplusn_inelastic_background
double kplusn_inelastic_background(double mandelstam_s)
K+ n inelastic background cross section parametrization Source: Buss:2011mx , B.3....
Definition: parametrizations.cc:548
smash::kplusn_k0p
double kplusn_k0p(double mandelstam_s)
K+ n charge exchange cross section parametrization.
Definition: parametrizations.cc:442
smash::pdg::Lambda
constexpr int Lambda
Λ.
Definition: pdgcode_constants.h:47
smash::deuteron_nucleon_elastic
double deuteron_nucleon_elastic(double mandelstam_s)
Deuteron nucleon elastic cross-section [mb] parametrized by Oh:2009gx .
Definition: parametrizations.cc:419
smash::CrossSections::incoming_particles_
const ParticleList incoming_particles_
List with data of scattering particles.
Definition: crosssections.h:465
smash::ppbar_elastic
double ppbar_elastic(double mandelstam_s)
ppbar elastic cross section parametrization Source: Bass:1998ca
Definition: parametrizations.cc:388
smash::kminusn_piminuslambda
double kminusn_piminuslambda(double sqrts)
K- n <-> pi- Lambda cross section parametrization Follow from the parametrization with the same stran...
Definition: parametrizations.cc:704
smash::kminusp_piplussigmaminus
double kminusp_piplussigmaminus(double sqrts)
K- p <-> pi+ Sigma- cross section parametrization Taken from UrQMD (Graef:2014mra ).
Definition: parametrizations.cc:687
smash::Potentials::force_scale
static std::pair< double, int > force_scale(const ParticleType &data)
Evaluates the scaling factor of the forces acting on the particles.
Definition: potentials.cc:164
smash::ParticleType::list_light_nuclei
static ParticleTypePtrList & list_light_nuclei()
Definition: particletype.cc:91
NNbar
Definition: forwarddeclarations.h:219
smash::PdgCode::from_decimal
static PdgCode from_decimal(const int pdgcode_decimal)
Construct PDG code from decimal number.
Definition: pdgcode.h:267
smash::kbar0p_elastic_background
double kbar0p_elastic_background(double mandelstam_s)
Kbar0 p elastic background cross section parametrization Source: Buss:2011mx , B.3....
Definition: parametrizations.cc:522
PiDeuteron_to_NN
Definition: forwarddeclarations.h:220
smash::kminusp_pi0sigma0
double kminusp_pi0sigma0(double sqrts)
K- p <-> pi0 Sigma0 cross section parametrization Fit to Landolt-Börnstein instead of UrQMD values.
Definition: parametrizations.cc:691
smash::ProcessType::StringSoftDoubleDiffractive
double diffractive. Two strings are formed, one from A and one from B.
smash::pdg::Sigma_p
constexpr int Sigma_p
Σ⁺.
Definition: pdgcode_constants.h:49
NNbarTreatment::Strings
Use string fragmentation.
smash::piplusp_high_energy
double piplusp_high_energy(double mandelstam_s)
pi+p total cross section at high energies
Definition: parametrizations.cc:60
smash::pipi_string_hard
double pipi_string_hard(double mandelstam_s)
pion-pion hard scattering cross section (with partonic scattering)
Definition: parametrizations.cc:99
smash::ProcessType::StringSoftNonDiffractive
non-diffractive. Two strings are formed both have ends in A and B.
smash::pp_elastic
double pp_elastic(double mandelstam_s)
pp elastic cross section parametrization Source: Weil:2013mya , eq.
Definition: parametrizations.cc:310
smash::pdg::Delta_m
constexpr int Delta_m
Δ⁻.
Definition: pdgcode_constants.h:44
smash::k0n_elastic_background
double k0n_elastic_background(double mandelstam_s)
K0 n elastic background cross section parametrization Source: Buss:2011mx , B.3.9.
Definition: parametrizations.cc:517
smash::pdg::Delta_p
constexpr int Delta_p
Δ⁺.
Definition: pdgcode_constants.h:40
smash::pdg::rho_z
constexpr int rho_z
ρ⁰.
Definition: pdgcode_constants.h:85
smash::pdg::K_m
constexpr int K_m
K̄⁻.
Definition: pdgcode_constants.h:75
smash::transit_high_energy::sqrts_range_Npi
const std::array< double, 2 > sqrts_range_Npi
transition range in N-pi collisions
Definition: crosssections.h:24
smash::CrossSections::formation
double formation(const ParticleType &type_resonance, double cm_momentum_sqr) const
Return the 2-to-1 resonance production cross section for a given resonance.
Definition: crosssections.cc:745
smash::xs_ppbar_annihilation
double xs_ppbar_annihilation(double mandelstam_s)
parametrized cross-section for proton-antiproton annihilation used in the UrQMD model
Definition: parametrizations.cc:68
smash::CrossSections::npi_el
double npi_el() const
Determine the elastic cross section for a nucleon-pion (Npi) collision.
Definition: crosssections.cc:313
Strangeness_exchange
Definition: forwarddeclarations.h:218
smash::pdg::Delta_z
constexpr int Delta_z
Δ⁰.
Definition: pdgcode_constants.h:42
smash::nucleon_mass
constexpr double nucleon_mass
Nucleon mass in GeV.
Definition: constants.h:55
smash::isospin_clebsch_gordan_sqr_2to2
double isospin_clebsch_gordan_sqr_2to2(const ParticleType &p_a, const ParticleType &p_b, const ParticleType &p_c, const ParticleType &p_d, const int I=-1)
Calculate the squared isospin Clebsch-Gordan coefficient for a 2-to-2 reaction A + B -> C + D.
Definition: clebschgordan.cc:84
smash::ProcessType::TwoToTwo
2->2 inelastic scattering
smash::detailed_balance_factor_RK
static double detailed_balance_factor_RK(double sqrts, double pcm, const ParticleType &a, const ParticleType &b, const ParticleType &c, const ParticleType &d)
Helper function: Calculate the detailed balance factor R such that.
Definition: crosssections.cc:49
smash::hbarc
constexpr double hbarc
GeV <-> fm conversion factor.
Definition: constants.h:25
smash::ProcessType::StringSoftSingleDiffractiveXB
single diffractive AB->XB.
smash::pdg::Sigma_z
constexpr int Sigma_z
Σ⁰.
Definition: pdgcode_constants.h:51
smash::ppbar_total
double ppbar_total(double mandelstam_s)
ppbar total cross section parametrization Source: Bass:1998ca
Definition: parametrizations.cc:401
smash::kminusp_elastic_background
double kminusp_elastic_background(double mandelstam_s)
K- p elastic background cross section parametrization Source: Buss:2011mx , B.3.9.
Definition: parametrizations.cc:466
smash::pdg::pi_z
constexpr int pi_z
π⁰.
Definition: pdgcode_constants.h:64
smash::logg
std::array< einhard::Logger<>, std::tuple_size< LogArea::AreaTuple >::value > logg
An array that stores all pre-configured Logger objects.
Definition: logging.cc:39
smash::ParticleType::list_anti_Deltas
static ParticleTypePtrList & list_anti_Deltas()
Definition: particletype.cc:83
smash::CrossSections::elastic_parametrization
double elastic_parametrization(bool use_AQM) const
Choose the appropriate parametrizations for given incoming particles and return the (parametrized) el...
Definition: crosssections.cc:221
smash::detailed_balance_factor_RR
static double detailed_balance_factor_RR(double sqrts, double pcm, const ParticleType &a, const ParticleType &b, const ParticleType &c, const ParticleType &d)
Helper function: Calculate the detailed balance factor R such that.
Definition: crosssections.cc:72
smash::pCM
T pCM(const T sqrts, const T mass_a, const T mass_b) noexcept
Definition: kinematics.h:79
smash::really_small
constexpr double really_small
Numerical error tolerance.
Definition: constants.h:37
smash::ParticleType::find
static const ParticleType & find(PdgCode pdgcode)
Returns the ParticleType object for the given pdgcode.
Definition: particletype.cc:105
smash::CrossSections::nn_to_resonance_matrix_element
static double nn_to_resonance_matrix_element(double sqrts, const ParticleType &type_a, const ParticleType &type_b, const int twoI)
Scattering matrix amplitude squared (divided by 16π) for resonance production processes like NN → NR ...
Definition: crosssections.cc:2422
smash::NN_string_hard
double NN_string_hard(double mandelstam_s)
nucleon-nucleon hard scattering cross section (with partonic scattering)
Definition: parametrizations.cc:91
smash::kplusn_elastic_background
double kplusn_elastic_background(double mandelstam_s)
K+ n elastic background cross section parametrization sigma(K+n->K+n) = sigma(K+n->K0p) = 0....
Definition: parametrizations.cc:438
smash::piminusp_sigmaminuskplus_pdg
double piminusp_sigmaminuskplus_pdg(double mandelstam_s)
pi- p -> Sigma- K+ cross section parametrization, PDG data.
Definition: parametrizations.cc:275
smash::detailed_balance_factor_stable
static double detailed_balance_factor_stable(double s, const ParticleType &a, const ParticleType &b, const ParticleType &c, const ParticleType &d)
Helper function: Calculate the detailed balance factor R such that.
Definition: crosssections.cc:30
smash::transit_high_energy::pipi_offset
const double pipi_offset
Constant offset as to where to turn on the strings and elastic processes for pi pi reactions (this is...
Definition: crosssections.h:47
smash::piplusp_elastic_AQM
double piplusp_elastic_AQM(double mandelstam_s, double m1, double m2)
An overload of piplusp_elastic_high_energy in which the very low part is replaced by a flat 5 mb cros...
Definition: parametrizations.cc:130
smash::CrossSections::NNbar_annihilation
CollisionBranchPtr NNbar_annihilation(const double current_xs) const
Determine the cross section for NNbar annihilation, which is given by the difference between the para...
Definition: crosssections.cc:2315
smash::kminusn_elastic_background
double kminusn_elastic_background(double mandelstam_s)
K- n elastic background cross section parametrization Source: Buss:2011mx , B.3.9.
Definition: parametrizations.cc:510
smash::pp_high_energy
double pp_high_energy(double mandelstam_s)
pp total cross section at high energies
Definition: parametrizations.cc:44
smash::CrossSections::nk_xx
CollisionBranchList nk_xx(ReactionsBitSet included_2to2) const
Find all inelastic 2->2 background processes for Nucleon-Kaon (NK) Scattering.
Definition: crosssections.cc:932
smash::CrossSections::npi_yk
CollisionBranchList npi_yk() const
Find all processes for Nucleon-Pion to Hyperon-Kaon Scattering.
Definition: crosssections.cc:396
smash::np_high_energy
double np_high_energy(double mandelstam_s)
np total cross section at high energies
Definition: parametrizations.cc:52
smash::CrossSections::string_probability
double string_probability(bool strings_switch, bool use_transition_probability, bool use_AQM, bool treat_nnbar_with_strings) const
Definition: crosssections.cc:2584
smash::CrossSections::sqrt_s_
const double sqrt_s_
Total energy in the center-of-mass frame.
Definition: crosssections.h:468
smash::CrossSections::find_nn_xsection_from_type
CollisionBranchList find_nn_xsection_from_type(const ParticleTypePtrList &type_res_1, const ParticleTypePtrList &type_res_2, const IntegrationMethod integrator) const
Utility function to avoid code replication in nn_xx().
Definition: crosssections.cc:2510
smash::pdg::decimal_antid
constexpr int decimal_antid
Anti-deuteron in decimal digits.
Definition: pdgcode_constants.h:95
smash::minimum_sqrts_pythia_can_handle
constexpr double minimum_sqrts_pythia_can_handle
Energy in GeV, below which hard reactions via pythia are impossible.
Definition: constants.h:124
smash::pp_elastic_high_energy
double pp_elastic_high_energy(double mandelstam_s, double m1, double m2)
pp elastic cross section parametrization, with only the high energy part generalized to all energy re...
Definition: parametrizations.cc:329
smash::kminusp_pi0lambda
double kminusp_pi0lambda(double sqrts)
K- p <-> pi0 Lambda cross section parametrization Fit to Landolt-Börnstein instead of UrQMD values.
Definition: parametrizations.cc:695
smash::transit_high_energy::sqrts_add_lower
const double sqrts_add_lower
constant for the lower end of transition region in the case of AQM this is added to the sum of masses
Definition: crosssections.h:35
smash::piplusp_elastic_high_energy
double piplusp_elastic_high_energy(double mandelstam_s, double m1, double m2)
pi+p elactic cross section parametrization.
Definition: parametrizations.cc:123
smash::LScatterAction
static constexpr int LScatterAction
Definition: bremsstrahlungaction.cc:17
smash::pdg::decimal_d
constexpr int decimal_d
Deuteron in decimal digits.
Definition: pdgcode_constants.h:93
smash::StringProcess::pdg_map_for_pythia
static int pdg_map_for_pythia(PdgCode &pdg)
Take pdg code and map onto particle specie which can be handled by PYTHIA.
Definition: processstring.cc:3239
smash::deuteron_pion_elastic
double deuteron_pion_elastic(double mandelstam_s)
Deuteron pion elastic cross-section [mb] parametrized to fit pi-d elastic scattering data (the data c...
Definition: parametrizations.cc:414
smash::CrossSections::bb_xx_except_nn
CollisionBranchList bb_xx_except_nn(ReactionsBitSet included_2to2) const
Find all inelastic 2->2 processes for Baryon-Baryon (BB) Scattering except the more specific Nucleon-...
Definition: crosssections.cc:832
smash::CrossSections::cm_momentum
double cm_momentum() const
Determine the momenta of the incoming particles in the center-of-mass system.
Definition: crosssections.h:458
smash::transit_high_energy::sqrts_range
const double sqrts_range
constant for the range of transition region in the case of AQM this is added to the sum of masses + s...
Definition: crosssections.h:40
smash::CrossSections::high_energy
double high_energy() const
Determine the parametrized total cross section at high energies for the given collision,...
Definition: crosssections.cc:2228
smash::CrossSections::deltak_xx
CollisionBranchList deltak_xx(ReactionsBitSet included_2to2) const
Find all inelastic 2->2 processes for Delta-Kaon (DeltaK) Scattering.
Definition: crosssections.cc:1415
smash::CrossSections::dn_xx
CollisionBranchList dn_xx(ReactionsBitSet included_2to2) const
Find all inelastic 2->2 processes involving Nucleon and (anti-) Deuteron (dN), specifically Nd → Nd',...
Definition: crosssections.cc:2034
smash::kplusp_elastic_background
double kplusp_elastic_background(double mandelstam_s)
K+ p elastic background cross section parametrization.
Definition: parametrizations.cc:425
smash::CrossSections::is_BBbar_pair_
const bool is_BBbar_pair_
Whether incoming particles are a baryon-antibaryon pair.
Definition: crosssections.h:477
smash::CrossSections::rare_two_to_two
CollisionBranchList rare_two_to_two() const
Find all 2->2 processes which are suppressed at high energies when strings are turned on with probabi...
Definition: crosssections.cc:208
smash::kaon_nucleon_ratios
KaonNucleonRatios kaon_nucleon_ratios
Definition: parametrizations.cc:668
NDeuteron_to_Ndprime
Definition: forwarddeclarations.h:222
smash::pdg::K_z
constexpr int K_z
K⁰.
Definition: pdgcode_constants.h:71
smash::piminusp_sigma0k0_res
double piminusp_sigma0k0_res(double mandelstam_s)
pi- p -> Sigma0 K0 cross section parametrization, resonance contribution.
Definition: parametrizations.cc:295
smash::kbar0n_elastic_background
double kbar0n_elastic_background(double mandelstam_s)
Kbar0 n elastic background cross section parametrization Source: Buss:2011mx , B.3....
Definition: parametrizations.cc:527
smash::ParticleType::try_find
static const ParticleTypePtr try_find(PdgCode pdgcode)
Returns the ParticleTypePtr for the given pdgcode.
Definition: particletype.cc:95
smash::piminusp_high_energy
double piminusp_high_energy(double mandelstam_s)
pi-p total cross section at high energies
Definition: parametrizations.cc:64
smash::np_elastic
double np_elastic(double mandelstam_s)
np elastic cross section parametrization Source: Weil:2013mya , eq.
Definition: parametrizations.cc:353
smash::append_list
static void append_list(CollisionBranchList &main_list, CollisionBranchList in_list, double weight=1.)
Helper function: Append a list of processes to another (main) list of processes.
Definition: crosssections.cc:93
smash::piminusp_lambdak0_pdg
double piminusp_lambdak0_pdg(double mandelstam_s)
pi- p -> Lambda K0 cross section parametrization, PDG data.
Definition: parametrizations.cc:255
KN_to_KN
Definition: forwarddeclarations.h:216
smash::pdg::Kbar_z
constexpr int Kbar_z
K̄⁰.
Definition: pdgcode_constants.h:73
smash::CrossSections::two_to_two
CollisionBranchList two_to_two(ReactionsBitSet included_2to2) const
Find all inelastic 2->2 processes for the given scattering.
Definition: crosssections.cc:782
KN_to_KDelta
Definition: forwarddeclarations.h:217
smash::pdg::h1
constexpr int h1
h₁(1170).
Definition: pdgcode_constants.h:90
smash::kminusn_piminussigma0
double kminusn_piminussigma0(double sqrts)
K- n <-> pi- Sigma0 cross section parametrization Follow from the parametrization with the same stran...
Definition: parametrizations.cc:699
NNbarTreatment::Resonances
Use intermediate Resonances.
smash::ProcessType::StringSoftSingleDiffractiveAX
(41-45) soft string excitations.
smash::kplusp_inelastic_background
double kplusp_inelastic_background(double mandelstam_s)
K+ p inelastic background cross section parametrization Source: Buss:2011mx , B.3....
Definition: parametrizations.cc:532
smash::CrossSections::NNbar_creation
CollisionBranchList NNbar_creation() const
Determine the cross section for NNbar creation, which is given by detailed balance from the reverse r...
Definition: crosssections.cc:2328
smash::pdg::Delta_pp
constexpr int Delta_pp
Δ⁺⁺.
Definition: pdgcode_constants.h:38
smash::pow_int
constexpr T pow_int(const T base, unsigned const exponent)
Efficient template for calculating integer powers using squaring.
Definition: pow.h:23
smash::CrossSections::ypi_xx
CollisionBranchList ypi_xx(ReactionsBitSet included_2to2) const
Find all inelastic 2->2 processes for Hyperon-Pion (Ypi) Scattering.
Definition: crosssections.cc:1564
smash::transit_high_energy::KN_offset
const double KN_offset
Constant offset as to where to shift from 2to2 to string processes (in GeV) in the case of KN reactio...
Definition: crosssections.h:53
smash::piplusp_elastic
double piplusp_elastic(double mandelstam_s)
pi+p elastic cross section parametrization, PDG data.
Definition: parametrizations.cc:140
smash::ProcessType::StringSoftAnnihilation
a special case of baryon-antibaryon annihilation.
smash::CrossSections::two_to_one
CollisionBranchList two_to_one() const
Find all resonances that can be produced in a 2->1 collision of the two input particles and the produ...
Definition: crosssections.cc:705
smash::LCrossSections
static constexpr int LCrossSections
Definition: crosssections.cc:21
smash::KaonNucleonRatios::get_ratio
double get_ratio(const ParticleType &a, const ParticleType &b, const ParticleType &c, const ParticleType &d) const
Return the isospin ratio of the given K N -> K Delta cross section.
Definition: parametrizations.cc:642
smash::fm2_mb
constexpr double fm2_mb
mb <-> fm^2 conversion factor.
Definition: constants.h:28
smash::piplusp_sigmapluskplus_pdg
double piplusp_sigmapluskplus_pdg(double mandelstam_s)
pi+ p to Sigma+ K+ cross section parametrization, PDG data.
Definition: parametrizations.cc:174
smash::piminusp_elastic
double piminusp_elastic(double mandelstam_s)
pi-p elastic cross section parametrization Source: GiBUU:parametrizationBarMes_HighEnergy....
Definition: parametrizations.cc:209
smash::npbar_high_energy
double npbar_high_energy(double mandelstam_s)
npbar total cross section at high energies
Definition: parametrizations.cc:56
smash::sum_xs_of
static double sum_xs_of(CollisionBranchList &list)
Helper function: Sum all cross sections of the given process list.
Definition: crosssections.cc:106
smash::ProcessType::Elastic
elastic scattering: particles remain the same, only momenta change
smash::CrossSections::nk_el
double nk_el() const
Determine the elastic cross section for a nucleon-kaon (NK) collision.
Definition: crosssections.cc:610
smash::Npi_string_hard
double Npi_string_hard(double mandelstam_s)
nucleon-pion hard scattering cross section (with partonic scattering)
Definition: parametrizations.cc:95
NN_to_NR
Definition: forwarddeclarations.h:214
smash::pdg::p
constexpr int p
Proton.
Definition: pdgcode_constants.h:28
smash::CrossSections::dpi_xx
CollisionBranchList dpi_xx(ReactionsBitSet included_2to2) const
Find all inelastic 2->2 processes involving Pion and (anti-) Deuteron (dpi), specifically dπ→ NN,...
Definition: crosssections.cc:1920
smash::CrossSections::nn_el
double nn_el() const
Determine the (parametrized) elastic cross section for a nucleon-nucleon (NN) collision.
Definition: crosssections.cc:282
smash::pdg::n
constexpr int n
Neutron.
Definition: pdgcode_constants.h:30
smash::ParticleType::list_baryon_resonances
static ParticleTypePtrList & list_baryon_resonances()
Definition: particletype.cc:87
smash::CrossSections::elastic
CollisionBranchPtr elastic(double elast_par, bool use_AQM) const
Determine the elastic cross section for this collision.
Definition: crosssections.cc:193
smash::CrossSections::string_excitation
CollisionBranchList string_excitation(double total_string_xs, StringProcess *string_process, bool use_AQM) const
Determine the cross section for string excitations, which is given by the difference between the para...
Definition: crosssections.cc:2093
smash::pot_pointer
Potentials * pot_pointer
Pointer to a Potential class.
Definition: potential_globals.cc:17
PiDeuteron_to_pidprime
Definition: forwarddeclarations.h:221
smash::CrossSections::nn_xx
CollisionBranchList nn_xx(ReactionsBitSet included_2to2) const
Find all inelastic 2->2 processes for Nucelon-Nucelon Scattering.
Definition: crosssections.cc:859
smash::transit_high_energy::sqrts_range_NN
const std::array< double, 2 > sqrts_range_NN
transition range in N-N collisions: Tuned to reproduce experimental exclusive cross section data,...
Definition: crosssections.h:30
smash::kminusp_piminussigmaplus
double kminusp_piminussigmaplus(double sqrts)
K- p <-> pi- Sigma+ cross section parametrization Taken from UrQMD (Graef:2014mra ).
Definition: parametrizations.cc:683
smash::deuteron_mass
constexpr double deuteron_mass
Deuteron mass in GeV.
Definition: constants.h:95
smash::pdg::pi_m
constexpr int pi_m
π⁻.
Definition: pdgcode_constants.h:66
smash::kminusp_kbar0n
double kminusp_kbar0n(double mandelstam_s)
K- p <-> Kbar0 n cross section parametrization.
Definition: parametrizations.cc:670
smash::CrossSections::potentials_
const std::pair< FourVector, FourVector > potentials_
Potentials at the interacting point.
Definition: crosssections.h:474
smash::CrossSections::string_hard_cross_section
double string_hard_cross_section() const
Determine the (parametrized) hard non-diffractive string cross section for this collision.
Definition: crosssections.cc:2291
smash::ProcessType::TwoToOne
resonance formation (2->1)
smash::pion_mass
constexpr double pion_mass
Pion mass in GeV.
Definition: constants.h:62
smash::CrossSections::probability_transit_high
double probability_transit_high(const double region_lower, const double region_upper) const
Definition: crosssections.cc:2674
smash::pdg::pi_p
constexpr int pi_p
π⁺.
Definition: pdgcode_constants.h:62
smash::pdg::Sigma_m
constexpr int Sigma_m
Σ⁻.
Definition: pdgcode_constants.h:53
smash::ParticleType::list_all
static const ParticleTypeList & list_all()
Definition: particletype.cc:57
smash::pack
constexpr uint64_t pack(int32_t x, int32_t y)
Pack two int32_t into an uint64_t.
Definition: pdgcode_constants.h:107
smash::CrossSections::add_channel
void add_channel(CollisionBranchList &process_list, F &&get_xsection, double sqrts, const ParticleType &type_a, const ParticleType &type_b) const
Helper function: Add a 2-to-2 channel to a collision branch list given a cross section.
Definition: crosssections.h:487
smash::pCM_sqr
T pCM_sqr(const T sqrts, const T mass_a, const T mass_b) noexcept
Definition: kinematics.h:91
smash::pCM_from_s
T pCM_from_s(const T s, const T mass_a, const T mass_b) noexcept
Definition: kinematics.h:66
smash::pdg::K_p
constexpr int K_p
K⁺.
Definition: pdgcode_constants.h:69