Version: SMASH-3.1
smash::ScatterActionMulti Class Reference

#include <scatteractionmulti.h>

ScatterActionMulti is a special action which takes any number of incoming particles and performs a scattering with the use of the stochastic criterion, producing one or more final-state particles.

Definition at line 23 of file scatteractionmulti.h.

Inheritance diagram for smash::ScatterActionMulti:
smash::Action

Classes

class  InvalidScatterActionMulti
 Thrown when ScatterActionMulti is called to perform with unknown combination of incoming and outgoing number of particles or unknown process type. More...
 

Public Member Functions

 ScatterActionMulti (const ParticleList &in_plist, double time)
 Construct a ScatterActionMulti object. More...
 
void generate_final_state () override
 Generate the final-state of the multi-particle scattering process. More...
 
double get_total_weight () const override
 Get the total probability for the reaction (scaled with the cross section scaling factors of the incoming particles). More...
 
double get_partial_weight () const override
 Get the partial probability for the chosen channel (scaled with the cross section scaling factors of the incoming particles). More...
 
void add_possible_reactions (double dt, const double gcell_vol, const MultiParticleReactionsBitSet incl_multi)
 Add all possible multi-particle reactions for the given incoming particles. More...
 
const CollisionBranchList & reaction_channels ()
 Get list of possible reaction channels. More...
 
double calculate_I3 (const double sqrts) const
 Calculate the integration necessary for the three-body phase space. More...
 
double parametrizaton_phi4 (const double man_s) const
 Calculate the parametrized 4-body relativistic phase space integral. More...
 
- Public Member Functions inherited from smash::Action
 Action (const ParticleList &in_part, double time)
 Construct an action object with incoming particles and relative time. More...
 
 Action (const ParticleData &in_part, const ParticleData &out_part, double time, ProcessType type)
 Construct an action object with the incoming particles, relative time, and the already known outgoing particles and type of the process. More...
 
 Action (const ParticleList &in_part, const ParticleList &out_part, double absolute_execution_time, ProcessType type)
 Construct an action object with the incoming particles, absolute time, and the already known outgoing particles and type of the process. More...
 
 Action (const Action &)=delete
 Copying is disabled. Use pointers or create a new Action. More...
 
virtual ~Action ()
 Virtual Destructor. More...
 
bool operator< (const Action &rhs) const
 Determine whether one action takes place before another in time. More...
 
virtual ProcessType get_type () const
 Get the process type. More...
 
template<typename Branch >
void add_process (ProcessBranchPtr< Branch > &p, ProcessBranchList< Branch > &subprocesses, double &total_weight)
 Add a new subprocess. More...
 
template<typename Branch >
void add_processes (ProcessBranchList< Branch > pv, ProcessBranchList< Branch > &subprocesses, double &total_weight)
 Add several new subprocesses at once. More...
 
virtual double perform (Particles *particles, uint32_t id_process)
 Actually perform the action, e.g. More...
 
bool is_valid (const Particles &particles) const
 Check whether the action still applies. More...
 
bool is_pauli_blocked (const std::vector< Particles > &ensembles, const PauliBlocker &p_bl) const
 Check if the action is Pauli-blocked. More...
 
const ParticleList & incoming_particles () const
 Get the list of particles that go into the action. More...
 
void update_incoming (const Particles &particles)
 Update the incoming particles that are stored in this action to the state they have in the global particle list. More...
 
const ParticleList & outgoing_particles () const
 Get the list of particles that resulted from the action. More...
 
double time_of_execution () const
 Get the time at which the action is supposed to be performed. More...
 
virtual double check_conservation (const uint32_t id_process) const
 Check various conservation laws. More...
 
double sqrt_s () const
 Determine the total energy in the center-of-mass frame [GeV]. More...
 
FourVector total_momentum_of_outgoing_particles () const
 Calculate the total kinetic momentum of the outgoing particles. More...
 
FourVector get_interaction_point () const
 Get the interaction point. More...
 
std::pair< FourVector, FourVectorget_potential_at_interaction_point () const
 Get the skyrme and asymmetry potential at the interaction point. More...
 
void set_stochastic_pos_idx ()
 Setter function that stores a random incoming particle index latter used to determine the interaction point. More...
 

Protected Member Functions

void format_debug_output (std::ostream &out) const override
 Writes information about this action to the out stream. More...
 
- Protected Member Functions inherited from smash::Action
FourVector total_momentum () const
 Sum of 4-momenta of incoming particles. More...
 
template<typename Branch >
const Branch * choose_channel (const ProcessBranchList< Branch > &subprocesses, double total_weight)
 Decide for a particular final-state channel via Monte-Carlo and return it as a ProcessBranch. More...
 
virtual std::pair< double, double > sample_masses (double kinetic_energy_cm) const
 Sample final-state masses in general X->2 processes (thus also fixing the absolute c.o.m. More...
 
virtual void sample_angles (std::pair< double, double > masses, double kinetic_energy_cm)
 Sample final-state momenta in general X->2 processes (here: using an isotropical angular distribution). More...
 
void sample_2body_phasespace ()
 Sample the full 2-body phase-space (masses, momenta, angles) in the center-of-mass frame for the final state particles. More...
 
virtual void sample_manybody_phasespace ()
 Sample the full n-body phase-space (masses, momenta, angles) in the center-of-mass frame for the final state particles. More...
 
void assign_formation_time_to_outgoing_particles ()
 Assign the formation time to the outgoing particles. More...
 

Private Member Functions

void add_reaction (CollisionBranchPtr p)
 Add a new reaction channel. More...
 
void add_reactions (CollisionBranchList pv)
 Add several new reaction channels at once. More...
 
void annihilation ()
 Perform a n->1 annihilation process. More...
 
void n_to_two ()
 Perform a n->2 process. More...
 
double probability_three_to_one (const ParticleType &type_out, double dt, const double gcell_vol, const int degen_sym_factor=1) const
 Calculate the probability for a 3m-to-1 reaction according to the stochastic collision criterion as given in Staudenmaier:2021lrg [56]. More...
 
double probability_three_to_two (const ParticleType &type_out1, const ParticleType &type_out2, double dt, const double gcell_vol, const double degen_sym_factor=1.0) const
 Calculate the probability for a 3-to-2 reaction according to the stochastic collision criterion as given in Staudenmaier:2021lrg [56]. More...
 
double probability_four_to_two (const ParticleType &type_out1, const ParticleType &type_out2, double dt, const double gcell_vol, const double degen_sym_factor=1.0) const
 Calculate the probability for a 4-to-2 reaction according to the stochastic collision criterion as given in Staudenmaier:2021lrg [56]. More...
 
double probability_five_to_two (const double m_out, double dt, const double gcell_vol, const double degen_sym_factor=1.0) const
 Calculate the probability for a 5-to-2 reaction according to the stochastic collision criterion as given in Garcia-Montero:2021haa [23]. More...
 
double parametrizaton_phi5_pions (const double man_s) const
 Calculate the parametrized 5-pion phase space. More...
 
double react_degen_factor (const int spin_factor_inc, const int spin_degen_out1, const int spin_degen_out2) const
 Determine the spin degeneracy factor ( \(D_{spin}\)) for the N->2 reaction. More...
 
bool three_different_pions (const ParticleData &data_a, const ParticleData &data_b, const ParticleData &data_c) const
 Check wether the three incoming particles are π⁺,π⁻,π⁰ in any order. More...
 
bool two_pions_eta (const ParticleData &data_a, const ParticleData &data_b, const ParticleData &data_c) const
 Check wether the three incoming particles are π⁺,π⁻,η or π⁰,π⁰,η in any order. More...
 
bool all_incoming_particles_are_pions_have_zero_charge_only_one_piz () const
 Check if 5 incoming particles match intial pion state for 5-to-2, which is pi+ pi- pi+ pi- pi0 in order to match the NNbar resonance treatment. More...
 

Private Attributes

double total_probability_
 Total probability of reaction. More...
 
double partial_probability_
 Partial probability of the chosen outgoing channel. More...
 
CollisionBranchList reaction_channels_
 List of possible collisions. More...
 

Additional Inherited Members

- Static Public Member Functions inherited from smash::Action
static double lambda_tilde (double a, double b, double c)
 Little helper function that calculates the lambda function (sometimes written with a tilde to better distinguish it) that appears e.g. More...
 
static void sample_manybody_phasespace_impl (double sqrts, const std::vector< double > &m, std::vector< FourVector > &sampled_momenta)
 Implementation of the full n-body phase-space sampling (masses, momenta, angles) in the center-of-mass frame for the final state particles. More...
 
- Protected Attributes inherited from smash::Action
ParticleList incoming_particles_
 List with data of incoming particles. More...
 
ParticleList outgoing_particles_
 Initially this stores only the PDG codes of final-state particles. More...
 
const double time_of_execution_
 Time at which the action is supposed to be performed (absolute time in the lab frame in fm). More...
 
ProcessType process_type_
 type of process More...
 
double box_length_ = -1.0
 Box length: needed to determine coordinates of collision correctly in case of collision through the wall. More...
 
int stochastic_position_idx_ = -1
 This stores a randomly-chosen index to an incoming particle. More...
 

Constructor & Destructor Documentation

◆ ScatterActionMulti()

smash::ScatterActionMulti::ScatterActionMulti ( const ParticleList &  in_plist,
double  time 
)

Construct a ScatterActionMulti object.

Parameters
[in]in_plistList of reaction partners
[in]timeTime at which the action is supposed to take place

Definition at line 25 of file scatteractionmulti.cc.

27  : Action(in_plist, time), total_probability_(0.) {}
Action(const ParticleList &in_part, double time)
Construct an action object with incoming particles and relative time.
Definition: action.h:44
double total_probability_
Total probability of reaction.

Member Function Documentation

◆ generate_final_state()

void smash::ScatterActionMulti::generate_final_state ( )
overridevirtual

Generate the final-state of the multi-particle scattering process.

Assign position and momenta to outgoing particles.

Exceptions
InvalidScatterActionMulti

Implements smash::Action.

Definition at line 369 of file scatteractionmulti.cc.

369  {
370  logg[LScatterActionMulti].debug("Incoming particles for ScatterActionMulti: ",
372 
373  /* Decide for a particular final state. */
374  const CollisionBranch* proc =
375  choose_channel<CollisionBranch>(reaction_channels_, total_probability_);
376  process_type_ = proc->get_type();
377  outgoing_particles_ = proc->particle_list();
378  partial_probability_ = proc->weight();
379 
380  logg[LScatterActionMulti].debug("Chosen channel: ", process_type_,
382 
383  switch (process_type_) {
385  /* n->1 annihilation */
386  annihilation();
387  break;
391  /* n->2 scattering */
392  n_to_two();
393  break;
394  default:
395  throw InvalidScatterActionMulti(
396  "ScatterActionMulti::generate_final_state: Invalid process type " +
397  std::to_string(static_cast<int>(process_type_)) + " was requested.");
398  }
399 
400  /* The production point of the new particles. */
401  FourVector middle_point = get_interaction_point();
402 
403  for (ParticleData& new_particle : outgoing_particles_) {
404  // Boost to the computational frame
405  new_particle.boost_momentum(
407  /* Set positions of the outgoing particles */
408  new_particle.set_4position(middle_point);
409  }
410 }
FourVector total_momentum_of_outgoing_particles() const
Calculate the total kinetic momentum of the outgoing particles.
Definition: action.cc:157
ParticleList outgoing_particles_
Initially this stores only the PDG codes of final-state particles.
Definition: action.h:363
ParticleList incoming_particles_
List with data of incoming particles.
Definition: action.h:355
FourVector get_interaction_point() const
Get the interaction point.
Definition: action.cc:68
ProcessType process_type_
type of process
Definition: action.h:372
CollisionBranchList reaction_channels_
List of possible collisions.
double partial_probability_
Partial probability of the chosen outgoing channel.
void n_to_two()
Perform a n->2 process.
void annihilation()
Perform a n->1 annihilation process.
std::array< einhard::Logger<>, std::tuple_size< LogArea::AreaTuple >::value > logg
An array that stores all pre-configured Logger objects.
Definition: logging.cc:39
static constexpr int LScatterActionMulti
@ MultiParticleThreeToTwo
See here for a short description.
@ MultiParticleThreeMesonsToOne
See here for a short description.
@ MultiParticleFourToTwo
See here for a short description.
@ MultiParticleFiveToTwo
See here for a short description.

◆ get_total_weight()

double smash::ScatterActionMulti::get_total_weight ( ) const
overridevirtual

Get the total probability for the reaction (scaled with the cross section scaling factors of the incoming particles).

Returns
total probability.

Implements smash::Action.

Definition at line 38 of file scatteractionmulti.cc.

38  {
39  double xsec_scaling = 1.0;
40  for (const ParticleData& in_part : incoming_particles_) {
41  xsec_scaling *= in_part.xsec_scaling_factor();
42  }
43  return total_probability_ * xsec_scaling;
44 }

◆ get_partial_weight()

double smash::ScatterActionMulti::get_partial_weight ( ) const
overridevirtual

Get the partial probability for the chosen channel (scaled with the cross section scaling factors of the incoming particles).

Returns
partial probability.

Implements smash::Action.

Definition at line 46 of file scatteractionmulti.cc.

46  {
47  double xsec_scaling = 1.0;
48  for (const ParticleData& in_part : incoming_particles_) {
49  xsec_scaling *= in_part.xsec_scaling_factor();
50  }
51  return partial_probability_ * xsec_scaling;
52 }

◆ add_possible_reactions()

void smash::ScatterActionMulti::add_possible_reactions ( double  dt,
const double  gcell_vol,
const MultiParticleReactionsBitSet  incl_multi 
)

Add all possible multi-particle reactions for the given incoming particles.

Parameters
[in]dttimestep size
[in]gcell_volgcell_vol grid cell volume
[in]incl_multiWhich multi-particle reactions are enabled?

Definition at line 54 of file scatteractionmulti.cc.

56  {
57  // 3 -> m
58  if (incoming_particles_.size() == 3) {
59  // 3 -> 1
60  if (incl_multi[IncludedMultiParticleReactions::Meson_3to1] == 1) {
62  incoming_particles_[2])) {
63  // 3pi -> omega
64  const ParticleTypePtr type_omega = ParticleType::try_find(0x223);
65  if (type_omega) {
66  add_reaction(std::make_unique<CollisionBranch>(
67  *type_omega,
68  probability_three_to_one(*type_omega, dt, gcell_vol,
69  type_omega->spin_degeneracy()),
71  }
72  // 3pi -> phi
73  const ParticleTypePtr type_phi = ParticleType::try_find(0x333);
74  if (type_phi) {
75  add_reaction(std::make_unique<CollisionBranch>(
76  *type_phi,
77  probability_three_to_one(*type_phi, dt, gcell_vol,
78  type_phi->spin_degeneracy()),
80  }
82  incoming_particles_[2])) {
83  // eta2pi -> eta-prime
84  const ParticleTypePtr type_eta_prime = ParticleType::try_find(0x331);
85 
86  int sym_factor_in = 1;
87  if (incoming_particles_[0].type() == incoming_particles_[1].type() ||
88  incoming_particles_[1].type() == incoming_particles_[2].type() ||
89  incoming_particles_[2].type() == incoming_particles_[0].type()) {
90  sym_factor_in = 2; // 2 factorial
91  }
92 
93  if (type_eta_prime) {
94  add_reaction(std::make_unique<CollisionBranch>(
95  *type_eta_prime,
97  *type_eta_prime, dt, gcell_vol,
98  sym_factor_in * type_eta_prime->spin_degeneracy()),
100  }
101  }
102  }
103  // 3 -> 2
104  if (incl_multi[IncludedMultiParticleReactions::Deuteron_3to2] == 1) {
105  const PdgCode pdg_a = incoming_particles_[0].pdgcode();
106  const PdgCode pdg_b = incoming_particles_[1].pdgcode();
107  const PdgCode pdg_c = incoming_particles_[2].pdgcode();
108  const ParticleTypePtr type_deuteron =
110  const ParticleTypePtr type_anti_deuteron =
112 
113  const int spin_factor_inc = pdg_a.spin_degeneracy() *
114  pdg_b.spin_degeneracy() *
115  pdg_c.spin_degeneracy();
116 
117  if (type_deuteron && type_anti_deuteron) {
118  // πpn → πd
119  if ((pdg_a.is_pion() && pdg_b == pdg::p && pdg_c == pdg::n) ||
120  (pdg_a.is_pion() && pdg_b == pdg::n && pdg_c == pdg::p) ||
121  (pdg_a == pdg::p && pdg_b.is_pion() && pdg_c == pdg::n) ||
122  (pdg_a == pdg::n && pdg_b.is_pion() && pdg_c == pdg::p) ||
123  (pdg_a == pdg::p && pdg_b == pdg::n && pdg_c.is_pion()) ||
124  (pdg_a == pdg::n && pdg_b == pdg::p && pdg_c.is_pion())) {
125  // Get type of incoming π
126  ParticleList::iterator it = std::find_if(
128  [](ParticleData x) { return x.is_pion(); });
129  const ParticleType& type_pi = it->type();
130 
131  const double spin_degn =
132  react_degen_factor(spin_factor_inc, type_pi.spin_degeneracy(),
133  type_deuteron->spin_degeneracy());
134 
135  add_reaction(std::make_unique<CollisionBranch>(
136  type_pi, *type_deuteron,
137  probability_three_to_two(type_pi, *type_deuteron, dt, gcell_vol,
138  spin_degn),
140  }
141 
142  // πp̅n̅ → πd̅
143  if ((pdg_a.is_pion() && pdg_b == -pdg::p && pdg_c == -pdg::n) ||
144  (pdg_a.is_pion() && pdg_b == -pdg::n && pdg_c == -pdg::p) ||
145  (pdg_a == -pdg::p && pdg_b.is_pion() && pdg_c == -pdg::n) ||
146  (pdg_a == -pdg::n && pdg_b.is_pion() && pdg_c == -pdg::p) ||
147  (pdg_a == -pdg::p && pdg_b == -pdg::n && pdg_c.is_pion()) ||
148  (pdg_a == -pdg::n && pdg_b == -pdg::p && pdg_c.is_pion())) {
149  // Get type of incoming π
150  ParticleList::iterator it = std::find_if(
152  [](ParticleData x) { return x.is_pion(); });
153  const ParticleType& type_pi = it->type();
154 
155  const double spin_degn =
156  react_degen_factor(spin_factor_inc, type_pi.spin_degeneracy(),
157  type_anti_deuteron->spin_degeneracy());
158 
159  add_reaction(std::make_unique<CollisionBranch>(
160  type_pi, *type_anti_deuteron,
161  probability_three_to_two(type_pi, *type_anti_deuteron, dt,
162  gcell_vol, spin_degn),
164  }
165 
166  // Nnp → Nd, N̅np → N̅d
167  if ((pdg_a.is_nucleon() && pdg_b == pdg::p && pdg_c == pdg::n) ||
168  (pdg_a.is_nucleon() && pdg_b == pdg::n && pdg_c == pdg::p) ||
169  (pdg_a == pdg::p && pdg_b.is_nucleon() && pdg_c == pdg::n) ||
170  (pdg_a == pdg::n && pdg_b.is_nucleon() && pdg_c == pdg::p) ||
171  (pdg_a == pdg::p && pdg_b == pdg::n && pdg_c.is_nucleon()) ||
172  (pdg_a == pdg::n && pdg_b == pdg::p && pdg_c.is_nucleon())) {
173  int symmetry_factor = 1; // already true for N̅np → N̅d case
174 
175  ParticleList::iterator it =
176  std::find_if(incoming_particles_.begin(),
177  incoming_particles_.end(), [](ParticleData x) {
178  return x.pdgcode().antiparticle_sign() == -1;
179  });
180  if (it == incoming_particles_.end()) {
181  /* Meaning no anti-N found by find_if,
182  * therefore not N̅np → N̅d, but Nnp → Nd. */
183  symmetry_factor = 2; // for Nnp → Nd (2 factorial)
184  // It is already clear here that we have a double of two N
185  if (pdg_a == pdg_b) {
186  it = incoming_particles_.begin();
187  } else {
188  // If a and b are not the double, then c has to be part of it
189  it = incoming_particles_.begin() + 2;
190  }
191  }
192  const ParticleType& type_N = it->type();
193 
194  const double spin_degn =
195  react_degen_factor(spin_factor_inc, type_N.spin_degeneracy(),
196  type_deuteron->spin_degeneracy());
197 
198  add_reaction(std::make_unique<CollisionBranch>(
199  type_N, *type_deuteron,
200  probability_three_to_two(type_N, *type_deuteron, dt, gcell_vol,
201  symmetry_factor * spin_degn),
203  }
204 
205  // Np̅n̅ → Nd̅, N̅p̅n̅ → N̅d̅
206  if ((pdg_a.is_nucleon() && pdg_b == -pdg::p && pdg_c == -pdg::n) ||
207  (pdg_a.is_nucleon() && pdg_b == -pdg::n && pdg_c == -pdg::p) ||
208  (pdg_a == -pdg::p && pdg_b.is_nucleon() && pdg_c == -pdg::n) ||
209  (pdg_a == -pdg::n && pdg_b.is_nucleon() && pdg_c == -pdg::p) ||
210  (pdg_a == -pdg::p && pdg_b == -pdg::n && pdg_c.is_nucleon()) ||
211  (pdg_a == -pdg::n && pdg_b == -pdg::p && pdg_c.is_nucleon())) {
212  int symmetry_factor = 1; // already true for Np̅n̅ → Nd̅ case
213 
214  ParticleList::iterator it =
215  std::find_if(incoming_particles_.begin(),
216  incoming_particles_.end(), [](ParticleData x) {
217  return x.pdgcode().antiparticle_sign() == 1;
218  });
219  if (it == incoming_particles_.end()) {
220  /* Meaning no N found by find_if,
221  * therefore not Np̅n̅ → Nd̅, but N̅p̅n̅ → N̅d̅. */
222  symmetry_factor = 2; // for N̅p̅n̅ → N̅d̅ (2 factorial)
223  // It is already clear here that we have a double of two N̅
224  if (pdg_a == pdg_b) {
225  it = incoming_particles_.begin();
226  } else {
227  // If a and b are not the double, then c has to be part of it
228  it = incoming_particles_.begin() + 2;
229  }
230  }
231  const ParticleType& type_N = it->type();
232 
233  const double spin_degn =
234  react_degen_factor(spin_factor_inc, type_N.spin_degeneracy(),
235  type_anti_deuteron->spin_degeneracy());
236 
237  add_reaction(std::make_unique<CollisionBranch>(
238  type_N, *type_anti_deuteron,
239  probability_three_to_two(type_N, *type_anti_deuteron, dt,
240  gcell_vol, symmetry_factor * spin_degn),
242  }
243  }
244  }
245  }
246  // 4 -> 2
247  if (incoming_particles_.size() == 4 &&
249  std::map<PdgCode, int> c; // counts incoming PdgCodes
250  int spin_factor_inc = 1;
251  for (const ParticleData& data : incoming_particles_) {
252  c[data.pdgcode()]++;
253  spin_factor_inc *= data.pdgcode().spin_degeneracy();
254  }
255  // Nucleons, antinucleons, and pions can catalyze
256  const int n_possible_catalysts_incoming =
257  c[pdg::n] + c[pdg::p] + c[-pdg::p] + c[-pdg::n] + c[pdg::pi_p] +
258  c[pdg::pi_z] + c[pdg::pi_m];
259 
260  for (PdgCode pdg_nucleus :
263  const ParticleTypePtr type_nucleus = ParticleType::try_find(pdg_nucleus);
264  // Nucleus can be formed if and only if:
265  // 1) Incoming particles contain enough components (like p, n, Lambda)
266  // 2) In (incoming particles - components) there is still a catalyst
267  // This is including the situation like nnpp. Can be that t(nnp) is formed
268  // and p is catalyst, can be that he-3(ppn) is formed and n is catalyst.
269  // Both reactions should be added.
270  const int n_nucleus_components_that_can_be_catalysts =
271  pdg_nucleus.nucleus_p() + pdg_nucleus.nucleus_ap() +
272  pdg_nucleus.nucleus_n() + pdg_nucleus.nucleus_an();
273  const bool incoming_contain_nucleus_components =
274  c[pdg::p] >= pdg_nucleus.nucleus_p() &&
275  c[-pdg::p] >= pdg_nucleus.nucleus_ap() &&
276  c[pdg::n] >= pdg_nucleus.nucleus_n() &&
277  c[-pdg::n] >= pdg_nucleus.nucleus_an() &&
278  c[pdg::Lambda] >= pdg_nucleus.nucleus_La() &&
279  c[-pdg::Lambda] >= pdg_nucleus.nucleus_aLa();
280  const bool can_form_nucleus =
281  type_nucleus && incoming_contain_nucleus_components &&
282  n_possible_catalysts_incoming -
283  n_nucleus_components_that_can_be_catalysts ==
284  1;
285 
286  if (!can_form_nucleus) {
287  continue;
288  }
289  // Find the catalyst
290  std::map<PdgCode, int> catalyst_count = c;
291  catalyst_count[pdg::p] -= pdg_nucleus.nucleus_p();
292  catalyst_count[-pdg::p] -= pdg_nucleus.nucleus_ap();
293  catalyst_count[pdg::n] -= pdg_nucleus.nucleus_n();
294  catalyst_count[-pdg::n] -= pdg_nucleus.nucleus_an();
295  catalyst_count[pdg::Lambda] -= pdg_nucleus.nucleus_La();
296  catalyst_count[-pdg::Lambda] -= pdg_nucleus.nucleus_aLa();
297  PdgCode pdg_catalyst = PdgCode::invalid();
298  for (const auto i : catalyst_count) {
299  if (i.second == 1) {
300  pdg_catalyst = i.first;
301  break;
302  }
303  }
304  if (pdg_catalyst == PdgCode::invalid()) {
305  logg[LScatterActionMulti].error("Something went wrong while forming",
306  pdg_nucleus, " from ",
308  }
309  const ParticleTypePtr type_catalyst =
310  ParticleType::try_find(pdg_catalyst);
311  const double spin_degn =
312  react_degen_factor(spin_factor_inc, type_catalyst->spin_degeneracy(),
313  type_nucleus->spin_degeneracy());
314  double symmetry_factor = 1.0;
315  for (const auto i : c) {
316  symmetry_factor *= (i.second == 3) ? 6.0 // 3!
317  : (i.second == 2) ? 2.0 // 2!
318  : 1.0;
319  if (i.second > 3 || i.second < 0) {
320  logg[LScatterActionMulti].error("4<->2 error, incoming particles ",
322  }
323  }
324 
325  add_reaction(std::make_unique<CollisionBranch>(
326  *type_catalyst, *type_nucleus,
327  probability_four_to_two(*type_catalyst, *type_nucleus, dt, gcell_vol,
328  symmetry_factor * spin_degn),
330  }
331  }
332  // 5 -> 2
333  if (incoming_particles_.size() == 5) {
334  if (incl_multi[IncludedMultiParticleReactions::NNbar_5to2] == 1) {
336  const int spin_factor_inc =
337  incoming_particles_[0].pdgcode().spin_degeneracy() *
338  incoming_particles_[1].pdgcode().spin_degeneracy() *
339  incoming_particles_[2].pdgcode().spin_degeneracy() *
340  incoming_particles_[3].pdgcode().spin_degeneracy() *
341  incoming_particles_[4].pdgcode().spin_degeneracy();
342  const double symmetry_factor = 4.0; // 2! * 2!
343 
344  const ParticleTypePtr type_p = ParticleType::try_find(pdg::p);
345  const ParticleTypePtr type_anti_p = ParticleType::try_find(-pdg::p);
346  const ParticleTypePtr type_n = ParticleType::try_find(pdg::n);
347  const ParticleTypePtr type_anti_n = ParticleType::try_find(-pdg::n);
348 
349  const double spin_degn =
350  react_degen_factor(spin_factor_inc, type_p->spin_degeneracy(),
351  type_anti_p->spin_degeneracy());
352 
353  if (type_p && type_n) {
354  const double prob = probability_five_to_two(
355  type_p->mass(), dt, gcell_vol,
356  symmetry_factor * spin_degn); // same for ppbar and nnbar
357  add_reaction(std::make_unique<CollisionBranch>(
358  *type_p, *type_anti_p, prob,
360  add_reaction(std::make_unique<CollisionBranch>(
361  *type_n, *type_anti_n, prob,
363  }
364  }
365  }
366  }
367 }
static const ParticleTypePtr try_find(PdgCode pdgcode)
Returns the ParticleTypePtr for the given pdgcode.
Definition: particletype.cc:89
static PdgCode invalid()
PdgCode 0x0 is guaranteed not to be valid by the PDG standard, but it passes all tests here,...
Definition: pdgcode.h:758
double probability_four_to_two(const ParticleType &type_out1, const ParticleType &type_out2, double dt, const double gcell_vol, const double degen_sym_factor=1.0) const
Calculate the probability for a 4-to-2 reaction according to the stochastic collision criterion as gi...
bool two_pions_eta(const ParticleData &data_a, const ParticleData &data_b, const ParticleData &data_c) const
Check wether the three incoming particles are π⁺,π⁻,η or π⁰,π⁰,η in any order.
double probability_three_to_one(const ParticleType &type_out, double dt, const double gcell_vol, const int degen_sym_factor=1) const
Calculate the probability for a 3m-to-1 reaction according to the stochastic collision criterion as g...
bool all_incoming_particles_are_pions_have_zero_charge_only_one_piz() const
Check if 5 incoming particles match intial pion state for 5-to-2, which is pi+ pi- pi+ pi- pi0 in ord...
double react_degen_factor(const int spin_factor_inc, const int spin_degen_out1, const int spin_degen_out2) const
Determine the spin degeneracy factor ( ) for the N->2 reaction.
double probability_five_to_two(const double m_out, double dt, const double gcell_vol, const double degen_sym_factor=1.0) const
Calculate the probability for a 5-to-2 reaction according to the stochastic collision criterion as gi...
double probability_three_to_two(const ParticleType &type_out1, const ParticleType &type_out2, double dt, const double gcell_vol, const double degen_sym_factor=1.0) const
Calculate the probability for a 3-to-2 reaction according to the stochastic collision criterion as gi...
bool three_different_pions(const ParticleData &data_a, const ParticleData &data_b, const ParticleData &data_c) const
Check wether the three incoming particles are π⁺,π⁻,π⁰ in any order.
void add_reaction(CollisionBranchPtr p)
Add a new reaction channel.
@ NNbar_5to2
@ A3_Nuclei_4to2
@ Deuteron_3to2
@ Meson_3to1
constexpr int pi_p
π⁺.
constexpr int64_t antideuteron
Anti-deuteron in decimal digits.
constexpr int64_t triton
Triton.
constexpr int64_t antihe3
Anti-He-3.
constexpr int p
Proton.
constexpr int64_t hypertriton
Hypertriton.
constexpr int64_t antihypertriton
Anti-Hypertriton.
constexpr int64_t antitriton
Anti-triton.
constexpr int pi_z
π⁰.
constexpr int n
Neutron.
constexpr int64_t deuteron
Deuteron.
constexpr int Lambda
Λ.
constexpr int pi_m
π⁻.
constexpr int64_t he3
He-3.

◆ reaction_channels()

const CollisionBranchList& smash::ScatterActionMulti::reaction_channels ( )
inline

Get list of possible reaction channels.

Returns
list of possible reaction channels.

Definition at line 72 of file scatteractionmulti.h.

72 { return reaction_channels_; }

◆ calculate_I3()

double smash::ScatterActionMulti::calculate_I3 ( const double  sqrts) const

Calculate the integration necessary for the three-body phase space.

The defintion for the integral is given by

\[I_3 = \int dm^2_{23}dm^2_{12} = \int^{(M-m_3)^2}_{(m_1+m_2)^2}[m^2_{23, max}- m^2_{23, min}]dm^2_{12}\]

see PDG book (chapter Kinematics) for defintions of variables. The numbered masses reference the incoming particles and \(M\) the mass of the outgoing particles in this case, since we are looking at the backreaction to the 1-to-3 decay.

Parameters
[in]sqrtscenter of mass energy of incoming particles (= mass of outgoing particle)
Returns
result of integral

Definition at line 412 of file scatteractionmulti.cc.

412  {
413  const double m1 = incoming_particles_[0].type().mass();
414  const double m2 = incoming_particles_[1].type().mass();
415  const double m3 = incoming_particles_[2].type().mass();
416 
417  if (sqrts < m1 + m2 + m3) {
418  return 0.0;
419  }
420  const double x1 = (m1 - m2) * (m1 - m2), x2 = (m1 + m2) * (m1 + m2),
421  x3 = (sqrts - m3) * (sqrts - m3),
422  x4 = (sqrts + m3) * (sqrts + m3);
423  const double qmm = x3 - x1, qmp = x3 - x2, qpm = x4 - x1, qpp = x4 - x2;
424  const double kappa = std::sqrt(qpm * qmp / (qpp * qmm));
425  const double tmp = std::sqrt(qmm * qpp);
426  const double c1 =
427  4.0 * m1 * m2 * std::sqrt(qmm / qpp) * (x4 - m3 * sqrts + m1 * m2);
428  const double c2 = 0.5 * (m1 * m1 + m2 * m2 + m3 * m3 + sqrts * sqrts) * tmp;
429  const double c3 = 8 * m1 * m2 / tmp *
430  ((m1 * m1 + m2 * m2) * (m3 * m3 + sqrts * sqrts) -
431  2 * m1 * m1 * m2 * m2 - 2 * m3 * m3 * sqrts * sqrts);
432  const double c4 =
433  -8 * m1 * m2 / tmp * smash::pow_int(sqrts * sqrts - m3 * m3, 2);
434  const double precision = 1.e-6;
435  const double res =
436  c1 * gsl_sf_ellint_Kcomp(kappa, precision) +
437  c2 * gsl_sf_ellint_Ecomp(kappa, precision) +
438  c3 * gsl_sf_ellint_Pcomp(kappa, -qmp / qmm, precision) +
439  c4 * gsl_sf_ellint_Pcomp(kappa, -x1 * qmp / (x2 * qmm), precision);
440  return res;
441 }
constexpr T pow_int(const T base, unsigned const exponent)
Efficient template for calculating integer powers using squaring.
Definition: pow.h:23

◆ parametrizaton_phi4()

double smash::ScatterActionMulti::parametrizaton_phi4 ( const double  man_s) const

Calculate the parametrized 4-body relativistic phase space integral.

The 4-body phase space is a n = 4 case of general integral over

\[d\Phi_n = (2\pi)^4 \prod_{i=1}^n \frac{d^3p_i}{2E_i (2\pi)^3} \times \delta(E_{tot} - \sum E_i) \delta^{(3)}(p_{tot} - \sum p_i)\]

. This is a Lorentz-invariant quantity, so the result of the integration depends only on

\[ s = E_{tot}^2 - p_{tot}^2\]

and masses of the particles

\[ m_i^2 = E_i^2 - p_i^2 \]

. The dimension in general case is

\[\mathrm{GeV}^{2n-4}\]

. The

\[\hbar = c = 1 \]

convention is used here, so when this integral is used in the acceptance probability for collision, one has to restore

\[\hbar\]

to obtain correct dimensionless probability. More on phase space integrals can be found, for example, in CERN-68-15 report. For developers, I (oliiny) have compiled a document with properties and parametrizations of many-body phase space integrals here: github.com/smash-transport/smash-devel/files/7791360/n_body_relativistic_phase_space.pdf

Parameters
[in]man_smandelstam s of reaction
Returns
phase space integral value for 4 bodies [GeV^4]

Definition at line 510 of file scatteractionmulti.cc.

510  {
511  int n_nucleons = 0, n_pions = 0, n_lambdas = 0;
512  double sum_m = 0.0, prod_m = 1.0;
513  for (const ParticleData& data : incoming_particles_) {
514  const PdgCode pdg = data.type().pdgcode();
515  n_nucleons += pdg.is_nucleon(); // including anti-nucleons
516  n_pions += pdg.is_pion();
517  n_lambdas += pdg.is_Lambda(); // including anti-Lambda
518  sum_m += data.type().mass();
519  prod_m *= data.type().mass();
520  }
521  const double x = 1.0 - sum_m / std::sqrt(man_s);
522  const double x2 = x * x;
523  const double x3 = x2 * x;
524  double g = -1.0;
525 
526  if (n_nucleons == 3 && n_pions == 1) { // NNNpi
527  g = (1.0 + 0.862432 * x - 3.4853 * x2 + 1.70259 * x3) /
528  (1.0 + 0.387376 * x - 1.34128 * x2 + 0.154489 * x3);
529  } else if (n_nucleons == 4) { // NNNN
530  g = (1.0 - 1.72285 * x + 0.728331 * x2) /
531  (1.0 - 0.967146 * x - 0.0103633 * x2);
532  } else if (n_nucleons == 2 && n_lambdas == 1 && n_pions == 1) { // LaNNpi
533  g = (1.0 + 0.937064 * x - 3.56864 * x2 + 1.721 * x3) /
534  (1.0 + 0.365202 * x - 1.2854 * x2 + 0.138444 * x3);
535  } else if (n_nucleons == 3 && n_lambdas == 1) { // LaNNN
536  g = (1.0 + 0.882401 * x - 3.4074 * x2 + 1.62454 * x3) /
537  (1.0 + 1.61741 * x - 2.12543 * x2 - 0.0902067 * x3);
538  }
539 
540  if (g > 0.0) {
541  return (std::sqrt(prod_m) * sum_m * sum_m * std::pow(x, 3.5) * g) /
542  (840. * std::sqrt(2) * std::pow(M_PI, 4.0) * std::pow(1 - x, 4.0));
543  } else {
544  logg[LScatterActionMulti].error("parametrizaton_phi4: no parametrization ",
545  "available for ", incoming_particles_);
546  return 0.0;
547  }
548 }

◆ format_debug_output()

void smash::ScatterActionMulti::format_debug_output ( std::ostream &  out) const
overrideprotectedvirtual

Writes information about this action to the out stream.

Parameters
[out]outout stream to be written to

Implements smash::Action.

Definition at line 657 of file scatteractionmulti.cc.

657  {
658  out << "MultiParticleScatter of " << incoming_particles_;
659  if (outgoing_particles_.empty()) {
660  out << " (not performed)";
661  } else {
662  out << " to " << outgoing_particles_;
663  }
664 }

◆ add_reaction()

void smash::ScatterActionMulti::add_reaction ( CollisionBranchPtr  p)
private

Add a new reaction channel.

Parameters
[in]pChannel to be added.

Definition at line 29 of file scatteractionmulti.cc.

29  {
30  add_process<CollisionBranch>(p, reaction_channels_, total_probability_);
31 }

◆ add_reactions()

void smash::ScatterActionMulti::add_reactions ( CollisionBranchList  pv)
private

Add several new reaction channels at once.

Parameters
[in]pvlist of channels to be added.

Definition at line 33 of file scatteractionmulti.cc.

33  {
34  add_processes<CollisionBranch>(std::move(pv), reaction_channels_,
36 }

◆ annihilation()

void smash::ScatterActionMulti::annihilation ( )
private

Perform a n->1 annihilation process.

Exceptions
InvalidScatterActionMulti

Definition at line 581 of file scatteractionmulti.cc.

581  {
582  if (outgoing_particles_.size() != 1) {
583  std::string s =
584  "Annihilation: "
585  "Incorrect number of particles in final state: ";
586  s += std::to_string(outgoing_particles_.size()) + ".";
587  throw InvalidScatterActionMulti(s);
588  }
589  // Set the momentum of the formed particle in its rest frame.
590  outgoing_particles_[0].set_4momentum(
591  total_momentum_of_outgoing_particles().abs(), 0., 0., 0.);
592  // Make sure to assign formation times before boost to the computational frame
594 
595  logg[LScatterActionMulti].debug("Momentum of the new particle: ",
596  outgoing_particles_[0].momentum());
597 }
void assign_formation_time_to_outgoing_particles()
Assign the formation time to the outgoing particles.
Definition: action.cc:188

◆ n_to_two()

void smash::ScatterActionMulti::n_to_two ( )
private

Perform a n->2 process.

Definition at line 599 of file scatteractionmulti.cc.

599  {
601  // Make sure to assign formation times before boost to the computational frame
604  "->2 scattering:", incoming_particles_,
605  " -> ", outgoing_particles_);
606 }
void sample_2body_phasespace()
Sample the full 2-body phase-space (masses, momenta, angles) in the center-of-mass frame for the fina...
Definition: action.cc:302

◆ probability_three_to_one()

double smash::ScatterActionMulti::probability_three_to_one ( const ParticleType type_out,
double  dt,
const double  gcell_vol,
const int  degen_sym_factor = 1 
) const
private

Calculate the probability for a 3m-to-1 reaction according to the stochastic collision criterion as given in Staudenmaier:2021lrg [56].

The formula for the probablilty is not taken from a reference, but derived following the same idea as specified e.g. in the paper above.

\[ P_{3\rightarrow 1} = \frac{\Delta t}{(\Delta^3x)^2} \frac{\pi}{4E_1E_2E_3}\frac{\Gamma_{1\rightarrow3}}{\Phi_3} \mathcal{A}(\sqrt{s}),\]

where \(\Phi_3\) represents the 3-body phase space:

\[\Phi_3 = \frac{1}{(2\pi)^3)}\frac{1}{16M^2}I_3.\]

The defintion for the integral \(I_3\) is given in the documentation of calculate_I3(). Degeneracy and symmetry factors are neglected in the formula, since they are treated as input for the function.

Parameters
[in]type_outtype of outgoing particle
[in]dttimestep size
[in]gcell_volgrid cell volume
[in]degen_sym_factordegeneracy factor for reaction (including symmetry factors)
Returns
probabilty for 3-to-1 reaction

Definition at line 443 of file scatteractionmulti.cc.

445  {
446  const double e1 = incoming_particles_[0].momentum().x0();
447  const double e2 = incoming_particles_[1].momentum().x0();
448  const double e3 = incoming_particles_[2].momentum().x0();
449  const double sqrts = sqrt_s();
450 
451  const double gamma_decay = type_out.get_partial_width(
452  sqrts, {&incoming_particles_[0].type(), &incoming_particles_[1].type(),
453  &incoming_particles_[2].type()});
454 
455  const double I_3 = calculate_I3(sqrts);
456  const double ph_sp_3 =
457  1. / (8 * M_PI * M_PI * M_PI) * 1. / (16 * sqrts * sqrts) * I_3;
458 
459  const double spec_f_val = type_out.spectral_function(sqrts);
460 
461  return dt / (gcell_vol * gcell_vol) * M_PI / (4. * e1 * e2 * e3) *
462  gamma_decay / ph_sp_3 * spec_f_val * std::pow(hbarc, 5.0) *
463  degen_sym_factor;
464 }
double sqrt_s() const
Determine the total energy in the center-of-mass frame [GeV].
Definition: action.h:271
double calculate_I3(const double sqrts) const
Calculate the integration necessary for the three-body phase space.
constexpr double hbarc
GeV <-> fm conversion factor.
Definition: constants.h:25

◆ probability_three_to_two()

double smash::ScatterActionMulti::probability_three_to_two ( const ParticleType type_out1,
const ParticleType type_out2,
double  dt,
const double  gcell_vol,
const double  degen_sym_factor = 1.0 
) const
private

Calculate the probability for a 3-to-2 reaction according to the stochastic collision criterion as given in Staudenmaier:2021lrg [56].

\[ P_{3 \rightarrow 2} = \frac{1}{4E_1E_2E_3} \frac{\Delta t}{(\Delta^3 x)^2} \frac{\tilde{\lambda}}{\Phi_38\pi s}\sigma_{2 \rightarrow 3},\]

where \(\Phi_3\) represents the 3-body phase space:

\[\Phi_3 = \frac{1}{(2\pi)^3)}\frac{1}{16M^2}I_3.\]

The defintion for the integral \(I_3\) is given in the documentation of calculate_I3(). Degeneracy and symmetry factors are neglected in the formula, since they are treated as input for the function.

Parameters
[in]type_out1type of outgoing particle 1
[in]type_out2type of outgoing particle 2
[in]dttimestep size
[in]gcell_volgrid cell volume
[in]degen_sym_factordegeneracy factor for reaction (including symmetry factors)
Returns
probabilty for 3-to-2 reaction

Definition at line 466 of file scatteractionmulti.cc.

468  {
469  const double e1 = incoming_particles_[0].momentum().x0();
470  const double e2 = incoming_particles_[1].momentum().x0();
471  const double e3 = incoming_particles_[2].momentum().x0();
472  const double m4 = type_out1.mass();
473  const double m5 = type_out2.mass();
474 
475  const double sqrts = sqrt_s();
476  const double xs =
477  CrossSections::two_to_three_xs(type_out1, type_out2, sqrts) / gev2_mb;
478  const double lamb = lambda_tilde(sqrts * sqrts, m4 * m4, m5 * m5);
479 
480  const double I_3 = calculate_I3(sqrts);
481  const double ph_sp_3 =
482  1. / (8 * M_PI * M_PI * M_PI) * 1. / (16 * sqrts * sqrts) * I_3;
483 
484  return dt / (gcell_vol * gcell_vol) * 1. / (4. * e1 * e2 * e3) * lamb /
485  (ph_sp_3 * 8 * M_PI * sqrts * sqrts) * xs * std::pow(hbarc, 5.0) *
486  degen_sym_factor;
487 }
static double lambda_tilde(double a, double b, double c)
Little helper function that calculates the lambda function (sometimes written with a tilde to better ...
Definition: action.h:315
static double two_to_three_xs(const ParticleType &type_in1, const ParticleType &type_in2, double sqrts)
Determine 2->3 cross section for the scattering of the given particle types.
constexpr double gev2_mb
GeV^-2 <-> mb conversion factor.
Definition: constants.h:31

◆ probability_four_to_two()

double smash::ScatterActionMulti::probability_four_to_two ( const ParticleType type_out1,
const ParticleType type_out2,
double  dt,
const double  gcell_vol,
const double  degen_sym_factor = 1.0 
) const
private

Calculate the probability for a 4-to-2 reaction according to the stochastic collision criterion as given in Staudenmaier:2021lrg [56].

\[ P_{4 \rightarrow 2} = \frac{1}{16E_1E_2E_3E_4} \frac{\Delta t}{(\Delta^3 x)^3} \frac{\tilde{\lambda}}{\Phi_44\pi s} \sigma_{2 \rightarrow 4},\]

where \(\Phi_4\) represents the 4-body phase space. Degeneracy and symmetry factors are neglected in the formula, since they are treated as input for the function.

Parameters
[in]type_out1type of outgoing particle 1
[in]type_out2type of outgoing particle 2
[in]dttimestep size
[in]gcell_volgrid cell volume
[in]degen_sym_factordegeneracy factor for reaction (including symmetry factors)
Returns
probabilty for 4-to-2 reaction

Definition at line 489 of file scatteractionmulti.cc.

491  {
492  const double e1 = incoming_particles_[0].momentum().x0();
493  const double e2 = incoming_particles_[1].momentum().x0();
494  const double e3 = incoming_particles_[2].momentum().x0();
495  const double e4 = incoming_particles_[3].momentum().x0();
496  const double m5 = type_out1.mass();
497  const double m6 = type_out2.mass();
498 
499  const double man_s = sqrt_s() * sqrt_s();
500  const double xs =
501  CrossSections::two_to_four_xs(type_out1, type_out2, sqrt_s()) / gev2_mb;
502  const double lamb = lambda_tilde(man_s, m5 * m5, m6 * m6);
503  const double ph_sp_4 = parametrizaton_phi4(man_s);
504 
505  return dt / std::pow(gcell_vol, 3.0) * 1. / (16. * e1 * e2 * e3 * e4) * xs /
506  (4. * M_PI * man_s) * lamb / ph_sp_4 * std::pow(hbarc, 8.0) *
507  degen_sym_factor;
508 }
static double two_to_four_xs(const ParticleType &type_in1, const ParticleType &type_in2, double sqrts)
Determine 2->4 cross section for the scattering of the given particle types.
double parametrizaton_phi4(const double man_s) const
Calculate the parametrized 4-body relativistic phase space integral.

◆ probability_five_to_two()

double smash::ScatterActionMulti::probability_five_to_two ( const double  m_out,
double  dt,
const double  gcell_vol,
const double  degen_sym_factor = 1.0 
) const
private

Calculate the probability for a 5-to-2 reaction according to the stochastic collision criterion as given in Garcia-Montero:2021haa [23].

\[ P_{5 \rightarrow 2} = \frac{1}{32E_1E_2E_3E_4E_5} \frac{\Delta t}{(\Delta^3 x)^4} \frac{\tilde{\lambda}}{\Phi_54\pi s}\sigma_{2 \rightarrow 5},\]

where the defintion is given without the necessary symmetry and spin degeneracy factors, which are input to the function and \(\Phi_5\) represents the 5-body phase space, which is paramaterized for the relevent 5 pion state here, see documentation of parametrizaton_phi5_pions().

Parameters
[in]m_outmass of outgoing particle types (assumes equal masses)
[in]dttimestep size
[in]gcell_volgrid cell volume
[in]degen_sym_factordegeneracy factor for reaction (including symmetry factors)
Returns
probabilty for 5-to-2 reaction

Definition at line 550 of file scatteractionmulti.cc.

552  {
553  const double e1 = incoming_particles_[0].momentum().x0();
554  const double e2 = incoming_particles_[1].momentum().x0();
555  const double e3 = incoming_particles_[2].momentum().x0();
556  const double e4 = incoming_particles_[3].momentum().x0();
557  const double e5 = incoming_particles_[4].momentum().x0();
558 
559  const double man_s = sqrt_s() * sqrt_s();
560  const double lamb = lambda_tilde(man_s, mout * mout, mout * mout);
561  const double ph_sp_5 = parametrizaton_phi5_pions(man_s);
562 
563  // Matching the NNbar anihilation cross section defintion for 2-to-5
564  const double xs =
565  std::max(0., ppbar_total(man_s) - ppbar_elastic(man_s)) / gev2_mb;
566 
567  return dt / std::pow(gcell_vol, 4.0) * 1. / (32. * e1 * e2 * e3 * e4 * e5) *
568  xs / (4. * M_PI * man_s) * lamb / ph_sp_5 * std::pow(hbarc, 11.0) *
569  degen_sym_factor;
570 }
double parametrizaton_phi5_pions(const double man_s) const
Calculate the parametrized 5-pion phase space.
double ppbar_total(double mandelstam_s)
ppbar total cross section parametrization Source: Bass:1998ca
double ppbar_elastic(double mandelstam_s)
ppbar elastic cross section parametrization Source: Bass:1998ca

◆ parametrizaton_phi5_pions()

double smash::ScatterActionMulti::parametrizaton_phi5_pions ( const double  man_s) const
private

Calculate the parametrized 5-pion phase space.

The defintion for the paramterization is given by

\[\Phi_5^{param.} = A(s-s_0)^5(1+\frac{s}{s_0})^{-\alpha}\]

with \(s_0 = 25 m_{\pi}^2\). \(A\) and \(\alpha\) are fitted to reproduce the phase space distribution.

Parameters
[in]man_smandelstam s of reaction
Returns
phase space value for 5 pions

Definition at line 572 of file scatteractionmulti.cc.

572  {
573  // see function documentation for parameter naming
574  const double s_zero = 25 * pion_mass * pion_mass;
575  const double fit_a = 2.1018e-10;
576  const double fit_alpha = 1.982;
577  return fit_a * std::pow(man_s - s_zero, 5.0) *
578  std::pow(1 + man_s / s_zero, -fit_alpha);
579 }
constexpr double pion_mass
Pion mass in GeV.
Definition: constants.h:65

◆ react_degen_factor()

double smash::ScatterActionMulti::react_degen_factor ( const int  spin_factor_inc,
const int  spin_degen_out1,
const int  spin_degen_out2 
) const
inlineprivate

Determine the spin degeneracy factor ( \(D_{spin}\)) for the N->2 reaction.

\[D_{spin} = \frac{(2J_{out1}+1)(2J_{out2}+1)} {(2J_{in1}+1)(2J_{in2}+1)(2J_{in3}+1)...(2J_{inN}+1)}\]

Parameters
[in]spin_factor_incproduct of incoming spin degeneracy (denominator in above expression)
[in]spin_degen_out1degeneracy factor of outgoing particle 1
[in]spin_degen_out2degeneracy factor of outgoing particle 2
Returns
spin degeneracy factor

Definition at line 283 of file scatteractionmulti.h.

285  {
286  return static_cast<double>(spin_degen_out1 * spin_degen_out2) /
287  static_cast<double>(spin_factor_inc);
288  }

◆ three_different_pions()

bool smash::ScatterActionMulti::three_different_pions ( const ParticleData data_a,
const ParticleData data_b,
const ParticleData data_c 
) const
private

Check wether the three incoming particles are π⁺,π⁻,π⁰ in any order.

Wrapper for unwieldy if statment.

Parameters
[in]data_adata for first incoming particle
[in]data_bdata for second incoming particle
[in]data_cdata for third incoming particle
Returns
true if combination of π⁺,π⁻,π⁰

Definition at line 608 of file scatteractionmulti.cc.

610  {
611  // We want a combination of pi+, pi- and pi0
612  const PdgCode pdg_a = data_a.pdgcode();
613  const PdgCode pdg_b = data_b.pdgcode();
614  const PdgCode pdg_c = data_c.pdgcode();
615 
616  return (pdg_a.is_pion() && pdg_b.is_pion() && pdg_c.is_pion()) &&
617  (pdg_a != pdg_b && pdg_b != pdg_c && pdg_c != pdg_a);
618 }

◆ two_pions_eta()

bool smash::ScatterActionMulti::two_pions_eta ( const ParticleData data_a,
const ParticleData data_b,
const ParticleData data_c 
) const
private

Check wether the three incoming particles are π⁺,π⁻,η or π⁰,π⁰,η in any order.

Wrapper for unwieldy if statment.

Parameters
[in]data_adata for first incoming particle
[in]data_bdata for second incoming particle
[in]data_cdata for third incoming particle
Returns
true if combination of π⁺,π⁻,η or π⁰,π⁰,η

Definition at line 620 of file scatteractionmulti.cc.

622  {
623  // We want a combination of pi0, pi0 and eta or pi+, pi- and eta
624  const PdgCode pdg_a = data_a.pdgcode();
625  const PdgCode pdg_b = data_b.pdgcode();
626  const PdgCode pdg_c = data_c.pdgcode();
627 
628  return (pdg_a == pdg::pi_z && pdg_b == pdg::pi_z && pdg_c == pdg::eta) ||
629  (pdg_a == pdg::pi_z && pdg_b == pdg::eta && pdg_c == pdg::pi_z) ||
630  (pdg_a == pdg::eta && pdg_b == pdg::pi_z && pdg_c == pdg::pi_z) ||
631 
632  (pdg_a == pdg::eta && pdg_b == pdg::pi_m && pdg_c == pdg::pi_p) ||
633  (pdg_a == pdg::eta && pdg_b == pdg::pi_p && pdg_c == pdg::pi_m) ||
634  (pdg_a == pdg::pi_m && pdg_b == pdg::pi_p && pdg_c == pdg::eta) ||
635  (pdg_a == pdg::pi_m && pdg_b == pdg::eta && pdg_c == pdg::pi_p) ||
636  (pdg_a == pdg::pi_p && pdg_b == pdg::pi_m && pdg_c == pdg::eta) ||
637  (pdg_a == pdg::pi_p && pdg_b == pdg::eta && pdg_c == pdg::pi_m);
638 }
constexpr int eta
η.

◆ all_incoming_particles_are_pions_have_zero_charge_only_one_piz()

bool smash::ScatterActionMulti::all_incoming_particles_are_pions_have_zero_charge_only_one_piz ( ) const
private

Check if 5 incoming particles match intial pion state for 5-to-2, which is pi+ pi- pi+ pi- pi0 in order to match the NNbar resonance treatment.

Definition at line 640 of file scatteractionmulti.cc.

641  {
642  const bool all_inc_pi =
644  [](const ParticleData& data) { return data.is_pion(); });
645  const int no_of_piz = std::count_if(
647  [](const ParticleData& data) { return data.pdgcode() == pdg::pi_z; });
648 
649  int total_state_charge = 0;
650  for (const ParticleData& part : incoming_particles_) {
651  total_state_charge += part.pdgcode().charge();
652  }
653 
654  return (all_inc_pi && total_state_charge == 0 && no_of_piz == 1);
655 }
bool all_of(Container &&c, UnaryPredicate &&p)
Convenience wrapper for std::all_of that operates on a complete container.
Definition: algorithms.h:80

Member Data Documentation

◆ total_probability_

double smash::ScatterActionMulti::total_probability_
private

Total probability of reaction.

Definition at line 322 of file scatteractionmulti.h.

◆ partial_probability_

double smash::ScatterActionMulti::partial_probability_
private

Partial probability of the chosen outgoing channel.

Definition at line 325 of file scatteractionmulti.h.

◆ reaction_channels_

CollisionBranchList smash::ScatterActionMulti::reaction_channels_
private

List of possible collisions.

Definition at line 328 of file scatteractionmulti.h.


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