Version: SMASH-3.1
decayactionsfinder.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2014-2020,2022-2023
4  * SMASH Team
5  *
6  * GNU General Public License (GPLv3 or later)
7  *
8  */
9 
11 
12 #include "smash/constants.h"
13 #include "smash/decayaction.h"
14 #include "smash/decaymodes.h"
15 #include "smash/fourvector.h"
16 #include "smash/random.h"
17 
18 namespace smash {
19 
21  const ParticleList &search_list, double dt, const double,
22  const std::vector<FourVector> &) const {
23  ActionList actions;
24  /* for short time steps this seems reasonable to expect
25  * less than 10 decays in most time steps */
26  actions.reserve(10);
27 
28  for (const auto &p : search_list) {
29  if (p.type().is_stable()) {
30  continue; // particle doesn't decay
31  }
32 
34  p.get_history().collisions_per_particle == 0) {
35  continue;
36  }
37 
38  DecayBranchList processes = p.type().get_partial_widths(
39  p.momentum(), p.position().threevec(), WhichDecaymodes::Hadronic);
40  // total decay width (mass-dependent)
41  const double width = total_weight<DecayBranch>(processes);
42 
43  // check if there are any (hadronic) decays
44  if (!(width > 0.0)) {
45  continue;
46  }
47 
48  constexpr double one_over_hbarc = 1. / hbarc;
49 
50  /* The decay_time is sampled from an exponential distribution.
51  * Even though it may seem suspicious that it is sampled every
52  * timestep, it can be proven that this still overall obeys
53  * the exponential decay law.
54  */
55  double decay_time =
56  res_lifetime_factor_ * random::exponential<double>(
57  /* The clock goes slower in the rest
58  * frame of the resonance */
59  one_over_hbarc * p.inverse_gamma() * width);
60  /* If the particle is not yet formed, shift the decay time by the time it
61  * takes the particle to form */
62  if (p.xsec_scaling_factor() < 1.0) {
63  decay_time += p.formation_time() - p.position().x0();
64  }
65  if (decay_time < dt) {
66  /* => decay_time ∈ [0, dt[
67  * => the particle decays in this timestep. */
68  auto act = std::make_unique<DecayAction>(p, decay_time);
69  act->add_decays(std::move(processes));
70  actions.emplace_back(std::move(act));
71  }
72  }
73  return actions;
74 }
75 
76 ActionList DecayActionsFinder::find_final_actions(const Particles &search_list,
77  bool /*only_res*/) const {
78  ActionList actions;
79 
80  for (const auto &p : search_list) {
81  if (!do_final_weak_decays_ && p.type().is_stable()) {
82  continue; // particle is stable with respect to strong interaction
83  }
84 
85  if (p.type().decay_modes().is_empty()) {
86  continue; // particle cannot decay (not even e.m. or weakly)
87  }
88 
89  auto act = std::make_unique<DecayAction>(p, 0.);
90  act->add_decays(p.type().get_partial_widths(
91  p.momentum(), p.position().threevec(), WhichDecaymodes::All));
92  actions.emplace_back(std::move(act));
93  }
94  return actions;
95 }
96 
97 } // namespace smash
const bool decay_initial_particles_
Whether to initial state particles can decay.
const double res_lifetime_factor_
Multiplicative factor to be applied to resonance lifetimes.
const bool do_final_weak_decays_
Do weak decays at the end? Weak here means all non-strong decays, so electro-magnetic decays are done...
ActionList find_final_actions(const Particles &search_list, bool only_res=false) const override
Force all resonances to decay at the end of the simulation.
ActionList find_actions_in_cell(const ParticleList &search_list, double dt, const double, const std::vector< FourVector > &) const override
Check the whole particle list for decays.
The Particles class abstracts the storage and manipulation of particles.
Definition: particles.h:33
Collection of useful constants that are known at compile time.
constexpr int p
Proton.
Definition: action.h:24
constexpr double hbarc
GeV <-> fm conversion factor.
Definition: constants.h:25
@ Hadronic
Ignore dilepton decay modes widths.
@ All
All decay mode widths.