Version: SMASH-3.4
decayaction.h
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2015-2020,2025
4  * SMASH Team
5  *
6  * GNU General Public License (GPLv3 or later)
7  *
8  */
9 
10 #ifndef SRC_INCLUDE_SMASH_DECAYACTION_H_
11 #define SRC_INCLUDE_SMASH_DECAYACTION_H_
12 
13 #include <optional>
14 #include <utility>
15 
16 #include "action.h"
17 
18 namespace smash {
19 
20 /**
21  * \ingroup action
22  * DecayAction is a special action which takes one single particle in the
23  * initial state and makes it decay into a number of daughter particles
24  * (currently two or three).
25  */
26 class DecayAction : public Action {
27  public:
28  /**
29  * Construct a DecayAction from a particle \p p.
30  *
31  * It does not initialize the list of possible decay processes. You need to
32  * call add_processes after construction.
33  *
34  * \param[in] p The particle that should decay if the action is performed.
35  * \param[in] time Time at which the action is supposed to take place
36  * \param[in] spin_interaction_type Which type of spin interaction to use
37  */
39  const ParticleData& p, double time,
40  SpinInteractionType spin_interaction_type = SpinInteractionType::Off);
41 
42  /**
43  * Add several new decays at once.
44  * \param[in] pv List of decays to be added.
45  */
46  void add_decays(DecayBranchList pv);
47 
48  /**
49  * Add one new decay.
50  * \param[in] p Decay to be added.
51  */
52  void add_decay(DecayBranchPtr p);
53 
54  /**
55  * Generate the final state of the decay process.
56  * Performs a decay of one particle to two or three particles.
57  *
58  * \throws InvalidDecay
59  */
60  void generate_final_state() override;
61 
62  /**
63  * Sample the masses of the final particles
64  * \returns Pair of sampled masses of particle 1 and 2
65  */
66  std::pair<double, double> sample_masses(
67  double kinetic_energy_cm) const override;
68 
69  /**
70  * Sample the full 2-body phase space (masses, momenta, angles)
71  * in the center-of-mass frame for the final-state particles.
72  *
73  * \see Action::sample_2body_phasespace for the base behaviour.
74  *
75  * This overrides the base implementation to integrate with DecayAction’s
76  * channel selection and potential-aware kinematics. If sample_masses()
77  * returns NaNs (i.e., the previously chosen channel is kinematically
78  * forbidden once potentials are considered), this method sets
79  * was_2body_phase_space_sampled_with_potentials_as_valid_ to 'false' so the
80  * caller can fall back to another channel instead of throwing. Otherwise it
81  * sets it to 'true' and proceeds with momentum/angle sampling (which may use
82  * L_).
83  */
84  void sample_2body_phasespace() override;
85 
86  /// Return the total width of the decay process.
87  double get_total_weight() const override { return total_width_; }
88 
89  /**
90  * Get partial width of chosen channel
91  * \return Partial width of chosen channel
92  */
93  double get_partial_weight() const override { return partial_width_; }
94 
95  /**
96  * Get total decay width
97  * \return Total width of decay
98  */
99  double total_width() const { return total_width_; }
100 
101  /**
102  * \ingroup exception
103  * Thrown when DecayAction is called to perform with 0 or more than 2
104  * entries in outgoing_particles.
105  */
106  class InvalidDecay : public std::invalid_argument {
107  using std::invalid_argument::invalid_argument;
108  };
109 
110  private:
111  /**
112  * Optional success flag for sampling outgoing particles.
113  *
114  * Set to `true` if 2-body phase-space sampling succeeded, `false` if
115  * `sample_masses()` signaled failure via NaNs (e.g., because the
116  * chosen channel turned out to be kinematically forbidden after
117  * considering potentials), or `std::nullopt` if not sampled yet.
118  *
119  * This is a **temporary workaround**: the decay channel is currently
120  * chosen without knowledge of the potentials, and kinematic failure
121  * is handled a posteriori. In the future, this should be replaced by
122  * a proper channel selection that already accounts for potential
123  * effects during the decision, avoiding the need for this flag.
124  */
126  std::nullopt;
127 
128  /**
129  * Check for the decay Σ*→Λπ. In this case it sets the output indices.
130  *
131  * \param[in] parent Particle decaying
132  * \param[in] daughter0 First decay product
133  * \param[in] daughter1 Second decay product
134  * \param[out] lambda_idx Possible index for Λ in the decay channel
135  * \param[out] pion_idx Possible index for π in the decay channel
136  * \return true if parent is Σ* and daughters are {Λ, π}
137  */
139  const ParticleData& parent, const ParticleData& daughter0,
140  const ParticleData& daughter1, int& lambda_idx, int& pion_idx) {
141  // Fast rejections first
142  if (!parent.is_sigmastar())
143  return false;
144 
145  const bool lambda0 = daughter0.pdgcode().is_Lambda();
146  const bool lambda1 = daughter1.pdgcode().is_Lambda();
147  const bool pion0 = daughter0.pdgcode().is_pion();
148  const bool pion1 = daughter1.pdgcode().is_pion();
149 
150  // Check if one daughter is a lambda and the other a pion
151  if (lambda0 && pion1 && !lambda1 && !pion0) {
152  lambda_idx = 0;
153  pion_idx = 1;
154  return true;
155  } else if (lambda1 && pion0 && !lambda0 && !pion1) {
156  lambda_idx = 1;
157  pion_idx = 0;
158  return true;
159  } else {
160  return false;
161  }
162  }
163 
164  protected:
165  /**
166  * \ingroup logging
167  * Writes information about this decay action to the \p out stream.
168  */
169  void format_debug_output(std::ostream& out) const override;
170 
171  /**
172  * Sample outgoing particle types, masses and angles
173  * return success of sampling
174  */
176 
177  /// List of possible decays
178  DecayBranchList decay_channels_;
179 
180  /// total decay width
181  double total_width_;
182 
183  /// partial decay width to the chosen outgoing channel
185 
186  /// Angular momentum of the decay
187  int L_ = 0;
188 
189  private:
190  /// Spin interaction type
192 };
193 
194 } // namespace smash
195 
196 #endif // SRC_INCLUDE_SMASH_DECAYACTION_H_
Action is the base class for a generic process that takes a number of incoming particles and transfor...
Definition: action.h:35
Thrown when DecayAction is called to perform with 0 or more than 2 entries in outgoing_particles.
Definition: decayaction.h:106
DecayAction is a special action which takes one single particle in the initial state and makes it dec...
Definition: decayaction.h:26
double partial_width_
partial decay width to the chosen outgoing channel
Definition: decayaction.h:184
double total_width_
total decay width
Definition: decayaction.h:181
double get_total_weight() const override
Return the total width of the decay process.
Definition: decayaction.h:87
bool sample_outgoing_particles()
Sample outgoing particle types, masses and angles return success of sampling.
Definition: decayaction.cc:35
SpinInteractionType spin_interaction_type_
Spin interaction type.
Definition: decayaction.h:191
void add_decays(DecayBranchList pv)
Add several new decays at once.
Definition: decayaction.cc:27
DecayAction(const ParticleData &p, double time, SpinInteractionType spin_interaction_type=SpinInteractionType::Off)
Construct a DecayAction from a particle p.
Definition: decayaction.cc:21
std::optional< bool > was_2body_phase_space_sampled_with_potentials_as_valid_
Optional success flag for sampling outgoing particles.
Definition: decayaction.h:125
double total_width() const
Get total decay width.
Definition: decayaction.h:99
void generate_final_state() override
Generate the final state of the decay process.
Definition: decayaction.cc:82
double get_partial_weight() const override
Get partial width of chosen channel.
Definition: decayaction.h:93
void add_decay(DecayBranchPtr p)
Add one new decay.
Definition: decayaction.cc:31
DecayBranchList decay_channels_
List of possible decays.
Definition: decayaction.h:178
int L_
Angular momentum of the decay.
Definition: decayaction.h:187
void sample_2body_phasespace() override
Sample the full 2-body phase space (masses, momenta, angles) in the center-of-mass frame for the fina...
Definition: decayaction.cc:145
static bool is_sigmastar_to_lambda_pion_decay(const ParticleData &parent, const ParticleData &daughter0, const ParticleData &daughter1, int &lambda_idx, int &pion_idx)
Check for the decay Σ*→Λπ.
Definition: decayaction.h:138
std::pair< double, double > sample_masses(double kinetic_energy_cm) const override
Sample the masses of the final particles.
Definition: decayaction.cc:162
ParticleData contains the dynamic information of a certain particle.
Definition: particledata.h:59
PdgCode pdgcode() const
Get the pdgcode of the particle.
Definition: particledata.h:88
bool is_sigmastar() const
Definition: particledata.h:113
bool is_pion() const
Definition: pdgcode.h:471
bool is_Lambda() const
Definition: pdgcode.h:448
SpinInteractionType
Possible spin interaction types.
@ Off
No spin interactions.
void format_debug_output(std::ostream &out) const override
Writes information about this decay action to the out stream.
Definition: decayaction.cc:202
constexpr int p
Proton.
Definition: action.h:24