Version: SMASH-2.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:
[legend]
Collaboration diagram for smash::ScatterActionMulti:
[legend]

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...
 
- 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 void 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 void 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_3body_phasespace ()
 Sample the full 3-body phase-space (masses, momenta, angles) in the center-of-mass frame for the final state particles. More...
 
virtual void sample_5body_phasespace ()
 Sample the full 5-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 three_to_two ()
 Perform a 3->2 process. More...
 
void five_to_two ()
 Perform a 5->2 process. More...
 
double probability_three_to_one (const ParticleType &type_out, double dt, const double gcell_vol, const int degen_factor=1) const
 Calculate the probability for a 3m-to-1 reaction according to the stochastic collision criterion as given in Staudenmaier:2021lrg [49]. More...
 
double probability_three_to_two (const ParticleType &type_out1, const ParticleType &type_out2, double dt, const double gcell_vol, const double degen_factor=1.0) const
 Calculate the probability for a 3-to-2 reaction according to the stochastic collision criterion as given in Staudenmaier:2021lrg [49]. More...
 
double probability_five_to_two (const double m_out, double dt, const double gcell_vol, const double degen_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 [20]. More...
 
double parametrizaton_phi5_pions (const double man_s) const
 Calculate the parametrized 5-pion phase space. More...
 
double calculate_I3 (const double sqrts) const
 Calculate the integration necessary for the three-body 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 3->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...
 
- 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/c). 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 20 of file scatteractionmulti.cc.

22  : 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 278 of file scatteractionmulti.cc.

278  {
279  logg[LScatterActionMulti].debug("Incoming particles for ScatterActionMulti: ",
281 
282  /* Decide for a particular final state. */
283  const CollisionBranch* proc =
284  choose_channel<CollisionBranch>(reaction_channels_, total_probability_);
285  process_type_ = proc->get_type();
286  outgoing_particles_ = proc->particle_list();
287  partial_probability_ = proc->weight();
288 
289  logg[LScatterActionMulti].debug("Chosen channel: ", process_type_,
291 
292  switch (process_type_) {
294  /* n->1 annihilation */
295  annihilation();
296  break;
298  /* 3->2 scattering */
299  three_to_two();
300  break;
302  /* 5->2 scattering */
303  five_to_two();
304  break;
305  default:
306  throw InvalidScatterActionMulti(
307  "ScatterActionMulti::generate_final_state: Invalid process type " +
308  std::to_string(static_cast<int>(process_type_)) + " was requested.");
309  }
310 
311  /* The production point of the new particles. */
312  FourVector middle_point = get_interaction_point();
313 
314  for (ParticleData& new_particle : outgoing_particles_) {
315  // Boost to the computational frame
316  new_particle.boost_momentum(
318  /* Set positions of the outgoing particles */
319  new_particle.set_4position(middle_point);
320  }
321 }
FourVector total_momentum_of_outgoing_particles() const
Calculate the total kinetic momentum of the outgoing particles.
Definition: action.cc:152
ParticleList outgoing_particles_
Initially this stores only the PDG codes of final-state particles.
Definition: action.h:339
ParticleList incoming_particles_
List with data of incoming particles.
Definition: action.h:331
FourVector get_interaction_point() const
Get the interaction point.
Definition: action.cc:67
ProcessType process_type_
type of process
Definition: action.h:348
CollisionBranchList reaction_channels_
List of possible collisions.
void three_to_two()
Perform a 3->2 process.
void five_to_two()
Perform a 5->2 process.
double partial_probability_
Partial probability of the chosen outgoing channel.
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
@ MultiParticleThreeMesonsToOne
multi particle scattering
Here is the call graph for this function:

◆ 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 33 of file scatteractionmulti.cc.

33  {
34  double xsec_scaling = 1.0;
35  for (const ParticleData& in_part : incoming_particles_) {
36  xsec_scaling *= in_part.xsec_scaling_factor();
37  }
38  return total_probability_ * xsec_scaling;
39 }

◆ 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 41 of file scatteractionmulti.cc.

41  {
42  double xsec_scaling = 1.0;
43  for (const ParticleData& in_part : incoming_particles_) {
44  xsec_scaling *= in_part.xsec_scaling_factor();
45  }
46  return partial_probability_ * xsec_scaling;
47 }

◆ 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 49 of file scatteractionmulti.cc.

51  {
52  // 3 -> m
53  if (incoming_particles_.size() == 3) {
54  // 3 -> 1
55  if (incl_multi[IncludedMultiParticleReactions::Meson_3to1] == 1) {
57  incoming_particles_[2])) {
58  // 3pi -> omega
59  const ParticleTypePtr type_omega = ParticleType::try_find(0x223);
60  if (type_omega) {
61  add_reaction(make_unique<CollisionBranch>(
62  *type_omega,
63  probability_three_to_one(*type_omega, dt, gcell_vol,
64  type_omega->spin_degeneracy()),
66  }
67  // 3pi -> phi
68  const ParticleTypePtr type_phi = ParticleType::try_find(0x333);
69  if (type_phi) {
70  add_reaction(make_unique<CollisionBranch>(
71  *type_phi,
72  probability_three_to_one(*type_phi, dt, gcell_vol,
73  type_phi->spin_degeneracy()),
75  }
77  incoming_particles_[2])) {
78  // eta2pi -> eta-prime
79  const ParticleTypePtr type_eta_prime = ParticleType::try_find(0x331);
80 
81  int sym_factor_in = 1;
82  if (incoming_particles_[0].type() == incoming_particles_[1].type() ||
83  incoming_particles_[1].type() == incoming_particles_[2].type() ||
84  incoming_particles_[2].type() == incoming_particles_[0].type()) {
85  sym_factor_in = 2; // 2 factorial
86  }
87 
88  if (type_eta_prime) {
89  add_reaction(make_unique<CollisionBranch>(
90  *type_eta_prime,
92  *type_eta_prime, dt, gcell_vol,
93  sym_factor_in * type_eta_prime->spin_degeneracy()),
95  }
96  }
97  }
98  // 3 -> 2
99  if (incl_multi[IncludedMultiParticleReactions::Deuteron_3to2] == 1) {
100  const PdgCode pdg_a = incoming_particles_[0].pdgcode();
101  const PdgCode pdg_b = incoming_particles_[1].pdgcode();
102  const PdgCode pdg_c = incoming_particles_[2].pdgcode();
103  const ParticleTypePtr type_deuteron =
105  const ParticleTypePtr type_anti_deuteron =
107 
108  const int spin_factor_inc = pdg_a.spin_degeneracy() *
109  pdg_b.spin_degeneracy() *
110  pdg_c.spin_degeneracy();
111 
112  if (type_deuteron && type_anti_deuteron) {
113  // πpn → πd
114  if ((pdg_a.is_pion() && pdg_b == pdg::p && pdg_c == pdg::n) ||
115  (pdg_a.is_pion() && pdg_b == pdg::n && pdg_c == pdg::p) ||
116  (pdg_a == pdg::p && pdg_b.is_pion() && pdg_c == pdg::n) ||
117  (pdg_a == pdg::n && pdg_b.is_pion() && pdg_c == pdg::p) ||
118  (pdg_a == pdg::p && pdg_b == pdg::n && pdg_c.is_pion()) ||
119  (pdg_a == pdg::n && pdg_b == pdg::p && pdg_c.is_pion())) {
120  // Get type of incoming π
121  ParticleList::iterator it = std::find_if(
123  [](ParticleData x) { return x.is_pion(); });
124  const ParticleType& type_pi = it->type();
125 
126  const double spin_degn =
127  react_degen_factor(spin_factor_inc, type_pi.spin_degeneracy(),
128  type_deuteron->spin_degeneracy());
129 
130  add_reaction(make_unique<CollisionBranch>(
131  type_pi, *type_deuteron,
132  probability_three_to_two(type_pi, *type_deuteron, dt, gcell_vol,
133  spin_degn),
135  }
136 
137  // πp̅n̅ → πd̅
138  if ((pdg_a.is_pion() && pdg_b == -pdg::p && pdg_c == -pdg::n) ||
139  (pdg_a.is_pion() && pdg_b == -pdg::n && pdg_c == -pdg::p) ||
140  (pdg_a == -pdg::p && pdg_b.is_pion() && pdg_c == -pdg::n) ||
141  (pdg_a == -pdg::n && pdg_b.is_pion() && pdg_c == -pdg::p) ||
142  (pdg_a == -pdg::p && pdg_b == -pdg::n && pdg_c.is_pion()) ||
143  (pdg_a == -pdg::n && pdg_b == -pdg::p && pdg_c.is_pion())) {
144  // Get type of incoming π
145  ParticleList::iterator it = std::find_if(
147  [](ParticleData x) { return x.is_pion(); });
148  const ParticleType& type_pi = it->type();
149 
150  const double spin_degn =
151  react_degen_factor(spin_factor_inc, type_pi.spin_degeneracy(),
152  type_anti_deuteron->spin_degeneracy());
153 
154  add_reaction(make_unique<CollisionBranch>(
155  type_pi, *type_anti_deuteron,
156  probability_three_to_two(type_pi, *type_anti_deuteron, dt,
157  gcell_vol, spin_degn),
159  }
160 
161  // Nnp → Nd, N̅np → N̅d
162  if ((pdg_a.is_nucleon() && pdg_b == pdg::p && pdg_c == pdg::n) ||
163  (pdg_a.is_nucleon() && pdg_b == pdg::n && pdg_c == pdg::p) ||
164  (pdg_a == pdg::p && pdg_b.is_nucleon() && pdg_c == pdg::n) ||
165  (pdg_a == pdg::n && pdg_b.is_nucleon() && pdg_c == pdg::p) ||
166  (pdg_a == pdg::p && pdg_b == pdg::n && pdg_c.is_nucleon()) ||
167  (pdg_a == pdg::n && pdg_b == pdg::p && pdg_c.is_nucleon())) {
168  int symmetry_factor = 1; // already true for N̅np → N̅d case
169 
170  ParticleList::iterator it =
171  std::find_if(incoming_particles_.begin(),
172  incoming_particles_.end(), [](ParticleData x) {
173  return x.pdgcode().antiparticle_sign() == -1;
174  });
175  if (it == incoming_particles_.end()) {
176  /* Meaning no anti-N found by find_if,
177  * therefore not N̅np → N̅d, but Nnp → Nd. */
178  symmetry_factor = 2; // for Nnp → Nd (2 factorial)
179  // It is already clear here that we have a double of two N
180  if (pdg_a == pdg_b) {
181  it = incoming_particles_.begin();
182  } else {
183  // If a and b are not the double, then c has to be part of it
184  it = incoming_particles_.begin() + 2;
185  }
186  }
187  const ParticleType& type_N = it->type();
188 
189  const double spin_degn =
190  react_degen_factor(spin_factor_inc, type_N.spin_degeneracy(),
191  type_deuteron->spin_degeneracy());
192 
193  add_reaction(make_unique<CollisionBranch>(
194  type_N, *type_deuteron,
195  probability_three_to_two(type_N, *type_deuteron, dt, gcell_vol,
196  symmetry_factor * spin_degn),
198  }
199 
200  // Np̅n̅ → Nd̅, N̅p̅n̅ → N̅d̅
201  if ((pdg_a.is_nucleon() && pdg_b == -pdg::p && pdg_c == -pdg::n) ||
202  (pdg_a.is_nucleon() && pdg_b == -pdg::n && pdg_c == -pdg::p) ||
203  (pdg_a == -pdg::p && pdg_b.is_nucleon() && pdg_c == -pdg::n) ||
204  (pdg_a == -pdg::n && pdg_b.is_nucleon() && pdg_c == -pdg::p) ||
205  (pdg_a == -pdg::p && pdg_b == -pdg::n && pdg_c.is_nucleon()) ||
206  (pdg_a == -pdg::n && pdg_b == -pdg::p && pdg_c.is_nucleon())) {
207  int symmetry_factor = 1; // already true for Np̅n̅ → Nd̅ case
208 
209  ParticleList::iterator it =
210  std::find_if(incoming_particles_.begin(),
211  incoming_particles_.end(), [](ParticleData x) {
212  return x.pdgcode().antiparticle_sign() == 1;
213  });
214  if (it == incoming_particles_.end()) {
215  /* Meaning no N found by find_if,
216  * therefore not Np̅n̅ → Nd̅, but N̅p̅n̅ → N̅d̅. */
217  symmetry_factor = 2; // for N̅p̅n̅ → N̅d̅ (2 factorial)
218  // It is already clear here that we have a double of two N̅
219  if (pdg_a == pdg_b) {
220  it = incoming_particles_.begin();
221  } else {
222  // If a and b are not the double, then c has to be part of it
223  it = incoming_particles_.begin() + 2;
224  }
225  }
226  const ParticleType& type_N = it->type();
227 
228  const double spin_degn =
229  react_degen_factor(spin_factor_inc, type_N.spin_degeneracy(),
230  type_anti_deuteron->spin_degeneracy());
231 
232  add_reaction(make_unique<CollisionBranch>(
233  type_N, *type_anti_deuteron,
234  probability_three_to_two(type_N, *type_anti_deuteron, dt,
235  gcell_vol, symmetry_factor * spin_degn),
237  }
238  }
239  }
240  }
241  // 5 -> 2
242  if (incoming_particles_.size() == 5) {
243  if (incl_multi[IncludedMultiParticleReactions::NNbar_5to2] == 1) {
245  const int spin_factor_inc =
246  incoming_particles_[0].pdgcode().spin_degeneracy() *
247  incoming_particles_[1].pdgcode().spin_degeneracy() *
248  incoming_particles_[2].pdgcode().spin_degeneracy() *
249  incoming_particles_[3].pdgcode().spin_degeneracy() *
250  incoming_particles_[4].pdgcode().spin_degeneracy();
251  const double symmetry_factor = 4.0; // 2! * 2!
252 
253  const ParticleTypePtr type_p = ParticleType::try_find(pdg::p);
254  const ParticleTypePtr type_anti_p = ParticleType::try_find(-pdg::p);
255  const ParticleTypePtr type_n = ParticleType::try_find(pdg::n);
256  const ParticleTypePtr type_anti_n = ParticleType::try_find(-pdg::n);
257 
258  const double spin_degn =
259  react_degen_factor(spin_factor_inc, type_p->spin_degeneracy(),
260  type_anti_p->spin_degeneracy());
261 
262  if (type_p && type_n) {
263  const double prob = probability_five_to_two(
264  type_p->mass(), dt, gcell_vol,
265  symmetry_factor * spin_degn); // same for ppbar and nnbar
266  add_reaction(make_unique<CollisionBranch>(
267  *type_p, *type_anti_p, prob,
269  add_reaction(make_unique<CollisionBranch>(
270  *type_n, *type_anti_n, prob,
272  }
273  }
274  }
275  }
276 }
static const ParticleTypePtr try_find(PdgCode pdgcode)
Returns the ParticleTypePtr for the given pdgcode.
Definition: particletype.cc:89
static PdgCode from_decimal(const int pdgcode_decimal)
Construct PDG code from decimal number.
Definition: pdgcode.h:269
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.
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 3->2 reaction.
double probability_three_to_one(const ParticleType &type_out, double dt, const double gcell_vol, const int degen_factor=1) const
Calculate the probability for a 3m-to-1 reaction according to the stochastic collision criterion as g...
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.
double probability_three_to_two(const ParticleType &type_out1, const ParticleType &type_out2, double dt, const double gcell_vol, const double degen_factor=1.0) const
Calculate the probability for a 3-to-2 reaction according to the stochastic collision criterion as gi...
double probability_five_to_two(const double m_out, double dt, const double gcell_vol, const double degen_factor=1.0) const
Calculate the probability for a 5-to-2 reaction according to the stochastic collision criterion as gi...
void add_reaction(CollisionBranchPtr p)
Add a new reaction channel.
@ NNbar_5to2
@ Deuteron_3to2
@ Meson_3to1
constexpr int p
Proton.
constexpr int n
Neutron.
constexpr int decimal_antid
Anti-deuteron in decimal digits.
constexpr int decimal_d
Deuteron in decimal digits.
Here is the call graph for this function:

◆ 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_; }

◆ 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 510 of file scatteractionmulti.cc.

510  {
511  out << "MultiParticleScatter of " << incoming_particles_;
512  if (outgoing_particles_.empty()) {
513  out << " (not performed)";
514  } else {
515  out << " to " << outgoing_particles_;
516  }
517 }

◆ add_reaction()

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

Add a new reaction channel.

Parameters
[in]pChannel to be added.

Definition at line 24 of file scatteractionmulti.cc.

24  {
25  add_process<CollisionBranch>(p, reaction_channels_, total_probability_);
26 }
Here is the caller graph for this function:

◆ 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 28 of file scatteractionmulti.cc.

28  {
29  add_processes<CollisionBranch>(std::move(pv), reaction_channels_,
31 }

◆ annihilation()

void smash::ScatterActionMulti::annihilation ( )
private

Perform a n->1 annihilation process.

Exceptions
InvalidScatterActionMulti

Definition at line 427 of file scatteractionmulti.cc.

427  {
428  if (outgoing_particles_.size() != 1) {
429  std::string s =
430  "Annihilation: "
431  "Incorrect number of particles in final state: ";
432  s += std::to_string(outgoing_particles_.size()) + ".";
433  throw InvalidScatterActionMulti(s);
434  }
435  // Set the momentum of the formed particle in its rest frame.
436  outgoing_particles_[0].set_4momentum(
437  total_momentum_of_outgoing_particles().abs(), 0., 0., 0.);
438  // Make sure to assign formation times before boost to the computational frame
440 
441  logg[LScatterActionMulti].debug("Momentum of the new particle: ",
442  outgoing_particles_[0].momentum());
443 }
void assign_formation_time_to_outgoing_particles()
Assign the formation time to the outgoing particles.
Definition: action.cc:183
Here is the call graph for this function:
Here is the caller graph for this function:

◆ three_to_two()

void smash::ScatterActionMulti::three_to_two ( )
private

Perform a 3->2 process.

Definition at line 445 of file scatteractionmulti.cc.

445  {
447  // Make sure to assign formation times before boost to the computational frame
449  logg[LScatterActionMulti].debug("3->2 scattering:", incoming_particles_,
450  " -> ", outgoing_particles_);
451 }
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:297
Here is the call graph for this function:
Here is the caller graph for this function:

◆ five_to_two()

void smash::ScatterActionMulti::five_to_two ( )
private

Perform a 5->2 process.

Definition at line 453 of file scatteractionmulti.cc.

453  {
455  // Make sure to assign formation times before boost to the computational frame
457  logg[LScatterActionMulti].debug("5->2 scattering:", incoming_particles_,
458  " -> ", outgoing_particles_);
459 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ probability_three_to_one()

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

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

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_factordegeneracy factor for reaction (including symmetry factors)
Returns
probabilty for 3-to-1 reaction

Definition at line 350 of file scatteractionmulti.cc.

352  {
353  const double e1 = incoming_particles_[0].momentum().x0();
354  const double e2 = incoming_particles_[1].momentum().x0();
355  const double e3 = incoming_particles_[2].momentum().x0();
356  const double sqrts = sqrt_s();
357 
358  const double gamma_decay = type_out.get_partial_width(
359  sqrts, {&incoming_particles_[0].type(), &incoming_particles_[1].type(),
360  &incoming_particles_[2].type()});
361 
362  const double I_3 = calculate_I3(sqrts);
363  const double ph_sp_3 =
364  1. / (8 * M_PI * M_PI * M_PI) * 1. / (16 * sqrts * sqrts) * I_3;
365 
366  const double spec_f_val = type_out.spectral_function(sqrts);
367 
368  return dt / (gcell_vol * gcell_vol) * M_PI / (4. * e1 * e2 * e3) *
369  gamma_decay / ph_sp_3 * spec_f_val * std::pow(hbarc, 5.0) *
370  degen_factor;
371 }
double sqrt_s() const
Determine the total energy in the center-of-mass frame [GeV].
Definition: action.h:266
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
Here is the call graph for this function:
Here is the caller graph for this function:

◆ 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_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 [49].

\[ 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 1
[in]dttimestep size
[in]gcell_volgrid cell volume
[in]degen_factordegeneracy factor for reaction (including symmetry factors)
Returns
probabilty for 3-to-2 reaction

Definition at line 373 of file scatteractionmulti.cc.

375  {
376  const double e1 = incoming_particles_[0].momentum().x0();
377  const double e2 = incoming_particles_[1].momentum().x0();
378  const double e3 = incoming_particles_[2].momentum().x0();
379  const double m4 = type_out1.mass();
380  const double m5 = type_out2.mass();
381 
382  const double sqrts = sqrt_s();
383  const double xs =
384  CrossSections::two_to_three_xs(type_out1, type_out2, sqrts) / gev2_mb;
385  const double lamb = lambda_tilde(sqrts * sqrts, m4 * m4, m5 * m5);
386 
387  const double I_3 = calculate_I3(sqrts);
388  const double ph_sp_3 =
389  1. / (8 * M_PI * M_PI * M_PI) * 1. / (16 * sqrts * sqrts) * I_3;
390 
391  return dt / (gcell_vol * gcell_vol) * 1. / (4. * e1 * e2 * e3) * lamb /
392  (ph_sp_3 * 8 * M_PI * sqrts * sqrts) * xs * std::pow(hbarc, 5.0) *
393  degen_factor;
394 }
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:310
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
Here is the call graph for this function:
Here is the caller graph for this function:

◆ probability_five_to_two()

double smash::ScatterActionMulti::probability_five_to_two ( const double  m_out,
double  dt,
const double  gcell_vol,
const double  degen_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 [20].

\[ 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_factordegeneracy factor for reaction (including symmetry factors)
Returns
probabilty for 5-to-2 reaction

Definition at line 396 of file scatteractionmulti.cc.

398  {
399  const double e1 = incoming_particles_[0].momentum().x0();
400  const double e2 = incoming_particles_[1].momentum().x0();
401  const double e3 = incoming_particles_[2].momentum().x0();
402  const double e4 = incoming_particles_[3].momentum().x0();
403  const double e5 = incoming_particles_[4].momentum().x0();
404 
405  const double man_s = sqrt_s() * sqrt_s();
406  const double lamb = lambda_tilde(man_s, mout * mout, mout * mout);
407  const double ph_sp_5 = parametrizaton_phi5_pions(man_s);
408 
409  // Matching the NNbar anihilation cross section defintion for 2-to-5
410  const double xs =
411  std::max(0., ppbar_total(man_s) - ppbar_elastic(man_s)) / gev2_mb;
412 
413  return dt / std::pow(gcell_vol, 4.0) * 1. / (32. * e1 * e2 * e3 * e4 * e5) *
414  xs / (4. * M_PI * man_s) * lamb / ph_sp_5 * std::pow(hbarc, 11.0) *
415  degen_factor;
416 }
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
Here is the call graph for this function:
Here is the caller graph for this function:

◆ 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 418 of file scatteractionmulti.cc.

418  {
419  // see function documentation for parameter naming
420  const double s_zero = 25 * pion_mass * pion_mass;
421  const double fit_a = 2.1018e-10;
422  const double fit_alpha = 1.982;
423  return fit_a * std::pow(man_s - s_zero, 5.0) *
424  std::pow(1 + man_s / s_zero, -fit_alpha);
425 }
constexpr double pion_mass
Pion mass in GeV.
Definition: constants.h:65
Here is the caller graph for this function:

◆ calculate_I3()

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

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 323 of file scatteractionmulti.cc.

323  {
324  static Integrator integrate;
325  const double m1 = incoming_particles_[0].effective_mass();
326  const double m2 = incoming_particles_[1].effective_mass();
327  const double m3 = incoming_particles_[2].effective_mass();
328  const double lower_bound = (m1 + m2) * (m1 + m2);
329  const double upper_bound = (sqrts - m3) * (sqrts - m3);
330  const auto result = integrate(lower_bound, upper_bound, [&](double m12_sqr) {
331  const double m12 = std::sqrt(m12_sqr);
332  const double e2_star = (m12_sqr - m1 * m1 + m2 * m2) / (2 * m12);
333  const double e3_star = (sqrts * sqrts - m12_sqr - m3 * m3) / (2 * m12);
334  const double m23_sqr_min =
335  (e2_star + e3_star) * (e2_star + e3_star) -
336  std::pow(std::sqrt(e2_star * e2_star - m2 * m2) +
337  std::sqrt(e3_star * e3_star - m3 * m3),
338  2.0);
339  const double m23_sqr_max =
340  (e2_star + e3_star) * (e2_star + e3_star) -
341  std::pow(std::sqrt(e2_star * e2_star - m2 * m2) -
342  std::sqrt(e3_star * e3_star - m3 * m3),
343  2.0);
344  return m23_sqr_max - m23_sqr_min;
345  });
346 
347  return result;
348 }
static Integrator integrate
Definition: decaytype.cc:144
Here is the caller graph for this function:

◆ 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 3->2 reaction.

\[D_{spin} = \frac{(2J_{out1}+1)(2J_{out2}+1)} {(2J_{in1}+1)(2J_{in2}+1)(2J_{in3}+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 241 of file scatteractionmulti.h.

243  {
244  return static_cast<double>(spin_degen_out1 * spin_degen_out2) /
245  static_cast<double>(spin_factor_inc);
246  }
Here is the caller graph for this function:

◆ 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 461 of file scatteractionmulti.cc.

463  {
464  // We want a combination of pi+, pi- and pi0
465  const PdgCode pdg_a = data_a.pdgcode();
466  const PdgCode pdg_b = data_b.pdgcode();
467  const PdgCode pdg_c = data_c.pdgcode();
468 
469  return (pdg_a.is_pion() && pdg_b.is_pion() && pdg_c.is_pion()) &&
470  (pdg_a != pdg_b && pdg_b != pdg_c && pdg_c != pdg_a);
471 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ 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 473 of file scatteractionmulti.cc.

475  {
476  // We want a combination of pi0, pi0 and eta or pi+, pi- and eta
477  const PdgCode pdg_a = data_a.pdgcode();
478  const PdgCode pdg_b = data_b.pdgcode();
479  const PdgCode pdg_c = data_c.pdgcode();
480 
481  return (pdg_a == pdg::pi_z && pdg_b == pdg::pi_z && pdg_c == pdg::eta) ||
482  (pdg_a == pdg::pi_z && pdg_b == pdg::eta && pdg_c == pdg::pi_z) ||
483  (pdg_a == pdg::eta && pdg_b == pdg::pi_z && pdg_c == pdg::pi_z) ||
484 
485  (pdg_a == pdg::eta && pdg_b == pdg::pi_m && pdg_c == pdg::pi_p) ||
486  (pdg_a == pdg::eta && pdg_b == pdg::pi_p && pdg_c == pdg::pi_m) ||
487  (pdg_a == pdg::pi_m && pdg_b == pdg::pi_p && pdg_c == pdg::eta) ||
488  (pdg_a == pdg::pi_m && pdg_b == pdg::eta && pdg_c == pdg::pi_p) ||
489  (pdg_a == pdg::pi_p && pdg_b == pdg::pi_m && pdg_c == pdg::eta) ||
490  (pdg_a == pdg::pi_p && pdg_b == pdg::eta && pdg_c == pdg::pi_m);
491 }
constexpr int pi_p
π⁺.
constexpr int eta
η.
constexpr int pi_z
π⁰.
constexpr int pi_m
π⁻.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ 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 493 of file scatteractionmulti.cc.

494  {
495  const bool all_inc_pi =
497  [](const ParticleData& data) { return data.is_pion(); });
498  const int no_of_piz = std::count_if(
500  [](const ParticleData& data) { return data.pdgcode() == pdg::pi_z; });
501 
502  int total_state_charge = 0;
503  for (const ParticleData& part : incoming_particles_) {
504  total_state_charge += part.pdgcode().charge();
505  }
506 
507  return (all_inc_pi && total_state_charge == 0 && no_of_piz == 1);
508 }
bool all_of(Container &&c, UnaryPredicate &&p)
Convenience wrapper for std::all_of that operates on a complete container.
Definition: algorithms.h:80
Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ total_probability_

double smash::ScatterActionMulti::total_probability_
private

Total probability of reaction.

Definition at line 280 of file scatteractionmulti.h.

◆ partial_probability_

double smash::ScatterActionMulti::partial_probability_
private

Partial probability of the chosen outgoing channel.

Definition at line 283 of file scatteractionmulti.h.

◆ reaction_channels_

CollisionBranchList smash::ScatterActionMulti::reaction_channels_
private

List of possible collisions.

Definition at line 286 of file scatteractionmulti.h.


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