Version: SMASH-3.4
kinematics.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015-2018,2020-2021,2026
3  * SMASH Team
4  *
5  * GNU General Public License (GPLv3 or later)
6  */
7 
8 #ifndef SRC_INCLUDE_SMASH_KINEMATICS_H_
9 #define SRC_INCLUDE_SMASH_KINEMATICS_H_
10 
11 #include <array>
12 #include <cassert>
13 #include <sstream>
14 
15 #include "constants.h"
16 
17 namespace smash {
18 
19 /**
20  * \return Velocity in the center of velocities frame of two particles given
21  * their Mandelstam s and masses
22  * \param[in] s Mandelstam s of the collision [GeV^2]
23  * \param[in] ma Mass of the first particle [GeV]
24  * \param[in] mb Mass of the second particle [GeV]
25  */
26 inline double center_of_velocity_v(double s, double ma, double mb) {
27  const double m_sum = ma + mb;
28  const double m_dif = ma - mb;
29  return std::sqrt((s - m_sum * m_sum) / (s - m_dif * m_dif));
30 }
31 
32 /**
33  * \return Velocity of projectile in the fixed target frame given
34  * the Mandelstam s of projectile and target and their masses
35  * \param[in] s Mandelstam s of the collision [GeV^2]
36  * \param[in] ma Mass of the projectile [GeV]
37  * \param[in] mb Mass of the target [GeV]
38  */
39 inline double fixed_target_projectile_v(double s, double ma, double mb) {
40  const double inv_gamma = 2 * ma * mb / (s - ma * ma - mb * mb);
41  return std::sqrt(1.0 - inv_gamma * inv_gamma);
42 }
43 
44 /**
45  * \return The squared center-of-mass momentum of two particles,
46  * given s and their masses. [GeV^2]
47  * \param[in] s Mandelstam s of the process [GeV^2].
48  * \param[in] mass_a Mass of first particle [GeV].
49  * \param[in] mass_b Mass of second particle [GeV].
50  */
51 template <typename T>
52 T pCM_sqr_from_s(const T s, const T mass_a, const T mass_b) noexcept {
53  const auto mass_a_sqr = mass_a * mass_a;
54  const auto x = s + mass_a_sqr - mass_b * mass_b;
55  return x * x * (T(0.25) / s) - mass_a_sqr;
56 }
57 
58 /**
59  * \return The center-of-mass momentum of two particles,
60  * given s and their masses. [GeV]
61  * \param[in] s Mandelstam s of the process [GeV^2].
62  * \param[in] mass_a Mass of first particle [GeV].
63  * \param[in] mass_b Mass of second particle [GeV].
64  */
65 template <typename T>
66 T pCM_from_s(const T s, const T mass_a, const T mass_b) noexcept {
67  const auto psqr = pCM_sqr_from_s(s, mass_a, mass_b);
68  return psqr > T(0.) ? std::sqrt(psqr) : T(0.);
69 }
70 
71 /**
72  * \return The center-of-mass momentum of two particles,
73  * given sqrt(s) and their masses. [GeV]
74  * \param[in] sqrts sqrt(s) of the process [GeV].
75  * \param[in] mass_a Mass of first particle [GeV].
76  * \param[in] mass_b Mass of second particle [GeV].
77  */
78 template <typename T>
79 T pCM(const T sqrts, const T mass_a, const T mass_b) noexcept {
80  return pCM_from_s(sqrts * sqrts, mass_a, mass_b);
81 }
82 
83 /**
84  * \return The squared center-of-mass momentum of two particles,
85  * given sqrt(s) and their masses.
86  * \param[in] sqrts sqrt(s) of the process [GeV].
87  * \param[in] mass_a Mass of first particle [GeV].
88  * \param[in] mass_b Mass of second particle [GeV].
89  */
90 template <typename T>
91 T pCM_sqr(const T sqrts, const T mass_a, const T mass_b) noexcept {
92  return pCM_sqr_from_s(sqrts * sqrts, mass_a, mass_b);
93 }
94 
95 /**
96  * Get the range of Mandelstam-t values allowed in a particular 2->2 process,
97  * see PDG 2014 booklet, eq. (46.34).
98  * \param[in] sqrts sqrt(s) of the process [GeV].
99  * \param[in] m1 Mass of first incoming particle [GeV].
100  * \param[in] m2 Mass of second incoming particle [GeV].
101  * \param[in] m3 Mass of first outgoing particle [GeV].
102  * \param[in] m4 Mass of second outgoing particle [GeV].
103  * \return array consisting of {t_min, t_max}
104  *
105  * Note that both t_min and t_max are negative,
106  * with |t_min| < |t_max|, i.e. t_min > t_max.
107  */
108 template <typename T>
109 std::array<T, 2> get_t_range(const T sqrts, const T m1, const T m2, const T m3,
110  const T m4) {
111  const T p_i = pCM(sqrts, m1, m2); // initial-state CM momentum
112  const T p_f = pCM(sqrts, m3, m4); // final-state CM momentum
113  const T sqrt_t0 = (m1 * m1 - m2 * m2 - m3 * m3 + m4 * m4) / (2. * sqrts);
114  const T t0 = sqrt_t0 * sqrt_t0;
115  const T t_min = t0 - (p_i - p_f) * (p_i - p_f);
116  const T t_max = t0 - (p_i + p_f) * (p_i + p_f);
117  assert(t_min >= t_max);
118  return {t_min, t_max};
119 }
120 
121 /**
122  * Helper function for plab_from_s.
123  * \param[in] mandelstam_s The Mandelstam variable s [GeV^2]
124  * \param[in] m_sum Sum of masses of target and projectile [GeV]
125  * \f$ m_1 + m_2 \f$
126  */
127 static inline void check_energy(double mandelstam_s, double m_sum) {
128  if (mandelstam_s < m_sum * m_sum) {
129  std::stringstream err;
130  err << "plab_from_s: s too small: " << mandelstam_s << " < "
131  << m_sum * m_sum;
132  throw std::runtime_error(err.str());
133  }
134 }
135 
136 /**
137  * Helper function for plab_from_s.
138  * \param[in] mandelstam_s The Mandelstam variable s [GeV^2]
139  * \param[in] radicand \f$ (s - (m_1 + m_2)^2) * (s - (m_1 - m_2)^2) \f$
140  * where \f$ m_1 \f$ and \f$ m_2 \f$ are masses of incoming particles [GeV^4]
141  */
142 static inline void check_radicand(double mandelstam_s, double radicand) {
143  if (radicand < 0) {
144  std::stringstream err;
145  err << "plab_from_s: negative radicand: " << mandelstam_s;
146  throw std::runtime_error(err.str());
147  }
148 }
149 
150 /**
151  * Convert Mandelstam-s to p_lab in a fixed-target collision.
152  * This assumes both particles have the given mass.
153  * \param[in] mandelstam_s The Mandelstam variable s [GeV^2]
154  * \param[in] mass Mass of projectile and target [GeV]
155  * \return Momentum of the projectile in the lab frame [GeV]
156  */
157 inline double plab_from_s(double mandelstam_s, double mass) {
158  const double radicand = mandelstam_s * (mandelstam_s - 4 * mass * mass);
159 #ifndef NDEBUG
160  const double m_sum = 2 * mass;
161  check_energy(mandelstam_s, m_sum);
162  check_radicand(mandelstam_s, radicand);
163 #endif
164  return std::sqrt(radicand) / (2 * mass);
165 }
166 
167 /**
168  * Convert Mandelstam-s to p_lab in a fixed-target collision.
169  * This assumes both particles have the mass of a nucleon.
170  * \param[in] mandelstam_s The Mandelstam variable s [GeV^2]
171  * \return Momentum of the projectile in the lab frame [GeV]
172  */
173 inline double plab_from_s(double mandelstam_s) {
174  return plab_from_s(mandelstam_s, nucleon_mass);
175 }
176 
177 /**
178  * Convert Mandelstam-s to p_lab in a fixed-target collision.
179  * The mass of the projectile and the mass of the target have to be given.
180  * \param[in] mandelstam_s the Mandelstam variable s [GeV^2]
181  * \param[in] m_projectile mass of the projectile [GeV]
182  * \param[in] m_target mass of the target [GeV]
183  * \return momentum of the projectile in the lab frame [GeV]
184  */
185 inline double plab_from_s(double mandelstam_s, double m_projectile,
186  double m_target) {
187  const double m_sum = m_projectile + m_target;
188  const double m_diff = m_projectile - m_target;
189  const double radicand =
190  (mandelstam_s - m_sum * m_sum) * (mandelstam_s - m_diff * m_diff);
191 /* This is equivalent to:
192  * const double radicand
193  * = (mandelstam_s - m_a_sq - m_b_sq) * (mandelstam_s - m_a_sq - m_b_sq)
194  * - 4 * m_a_sq * m_b_sq; */
195 #ifndef NDEBUG
196  check_energy(mandelstam_s, m_sum);
197  check_radicand(mandelstam_s, radicand);
198 #endif
199  return std::sqrt(radicand) / (2 * m_target);
200 }
201 
202 /**
203  * Convert Mandelstam-s to p_lab in a fixed-target collision.
204  * The mass of the two colliding particles have to be given and the heavier
205  * particle is assumed to be the target, i.e. at rest.
206  * \param[in] mandelstam_s the Mandelstam variable s [GeV^2]
207  * \param[in] m1 mass of first particle [GeV]
208  * \param[in] m2 mass of second particle [GeV]
209  * \return momentum of the projectile in the lab frame [GeV]
210  */
211 inline double plab_from_s_heavier_particle_at_rest(double mandelstam_s,
212  double m1, double m2) {
213  return (m1 > m2) ? plab_from_s(mandelstam_s, m2, m1)
214  : plab_from_s(mandelstam_s, m1, m2);
215 }
216 
217 /**
218  * Convert E_tot to Mandelstam-s for a fixed-target setup,
219  * with a projectile of mass m_P and a total energy e_tot
220  * and a target of mass m_T at rest.
221  * \param[in] e_tot energy of the projectile in the lab frame [GeV]
222  * \param[in] m_P mass of the projectile [GeV]
223  * \param[in] m_T mass of the target [GeV]
224  * \return The Mandelstam variable s [GeV^2]
225  */
226 inline double s_from_Etot(double e_tot, double m_P, double m_T) {
227  return m_P * m_P + m_T * m_T + 2 * m_T * e_tot;
228 }
229 /**
230  * Convert E_tot to Mandelstam-s for two beams with total energies and
231  * masses (E,m)
232  *
233  * \param[in] e_tot_p Total energy of projectile [GeV]
234  * \param[in] e_tot_t Total energy of target [GeV]
235  * \param[in] m_p Mass of projectile [GeV]
236  * \param[in] m_t Mass of target [GeV]
237  * \return Mandelstam-s [GeV^2]
238  */
239 inline double s_from_Etot(double e_tot_p, double e_tot_t, double m_p,
240  double m_t) {
241  double pz_p = std::sqrt(e_tot_p * e_tot_p - m_p * m_p);
242  double pz_t = std::sqrt(e_tot_t * e_tot_t - m_t * m_t);
243  return std::pow(e_tot_p + e_tot_t, 2) - std::pow(pz_p - pz_t, 2);
244 }
245 /**
246  * Convert E_kin to Mandelstam-s for a fixed-target setup,
247  * with a projectile of mass m_P and a kinetic energy e_kin
248  * and a target of mass m_T at rest.
249  * \param[in] e_kin kinetic energy of the projectile in the lab frame [GeV]
250  * \param[in] m_P mass of the projectile [GeV]
251  * \param[in] m_T mass of the target [GeV]
252  * \return The Mandelstam variable s [GeV^2]
253  */
254 inline double s_from_Ekin(double e_kin, double m_P, double m_T) {
255  return s_from_Etot(e_kin + m_P, m_P, m_T);
256 }
257 /**
258  * Convert E_kin=(E_tot-m) to Mandelstam-s for two beams with total
259  * energies and masses (E,m)
260  *
261  * \param[in] e_kin_p Kinetic energy of projectile [GeV]
262  * \param[in] e_kin_t Kinetic energy of target [GeV]
263  * \param[in] m_p Mass of projectile [GeV]
264  * \param[in] m_t Mass of target [GeV]
265  * \return Mandelstam-s [GeV^2]
266  */
267 inline double s_from_Ekin(double e_kin_p, double e_kin_t, double m_p,
268  double m_t) {
269  return s_from_Etot(e_kin_p + m_t, e_kin_t + m_t, m_p, m_t);
270 }
271 /**
272  * Convert p_lab to Mandelstam-s for a fixed-target setup,
273  * with a projectile of mass m_P and momentum plab
274  * and a target of mass m_T at rest.
275  * \param[in] plab Momentum of the projectile in the lab frame [GeV]
276  * \param[in] m_P Mass of the projectile [GeV]
277  * \param[in] m_T Mass of the target [GeV]
278  * \return The Mandelstam variable s [GeV^2]
279  */
280 inline double s_from_plab(double plab, double m_P, double m_T) {
281  return m_P * m_P + m_T * m_T + 2 * m_T * std::sqrt(m_P * m_P + plab * plab);
282 }
283 /**
284  * Convert P_lab to Mandelstam-s for two beams with total momenta and masses
285  * (P,m) (P_lab gives per nucleon, P=P_lab*A)
286  *
287  * \param[in] plab_p Kinetic energy of projectile [GeV]
288  * \param[in] plab_t Kinetic energy of target [GeV]
289  * \param[in] m_p Mass of projectile [GeV]
290  * \param[in] m_t Mass of target [GeV]
291  * \return Mandelstam-s [GeV^2]
292  */
293 inline double s_from_plab(double plab_p, double plab_t, double m_p,
294  double m_t) {
295  return s_from_Etot(std::sqrt(m_p * m_p + plab_p * plab_p),
296  std::sqrt(m_t * m_t + plab_t * plab_t), plab_p, plab_t);
297 }
298 
299 } // namespace smash
300 
301 #endif // SRC_INCLUDE_SMASH_KINEMATICS_H_
Collection of useful constants that are known at compile time.
Definition: action.h:24
double plab_from_s(double mandelstam_s, double mass)
Convert Mandelstam-s to p_lab in a fixed-target collision.
Definition: kinematics.h:157
T pCM(const T sqrts, const T mass_a, const T mass_b) noexcept
Definition: kinematics.h:79
T pCM_sqr(const T sqrts, const T mass_a, const T mass_b) noexcept
Definition: kinematics.h:91
double fixed_target_projectile_v(double s, double ma, double mb)
Definition: kinematics.h:39
double s_from_Ekin(double e_kin, double m_P, double m_T)
Convert E_kin to Mandelstam-s for a fixed-target setup, with a projectile of mass m_P and a kinetic e...
Definition: kinematics.h:254
T pCM_sqr_from_s(const T s, const T mass_a, const T mass_b) noexcept
Definition: kinematics.h:52
static void check_radicand(double mandelstam_s, double radicand)
Helper function for plab_from_s.
Definition: kinematics.h:142
std::array< T, 2 > get_t_range(const T sqrts, const T m1, const T m2, const T m3, const T m4)
Get the range of Mandelstam-t values allowed in a particular 2->2 process, see PDG 2014 booklet,...
Definition: kinematics.h:109
static void check_energy(double mandelstam_s, double m_sum)
Helper function for plab_from_s.
Definition: kinematics.h:127
constexpr double nucleon_mass
Nucleon mass in GeV.
Definition: constants.h:69
double center_of_velocity_v(double s, double ma, double mb)
Definition: kinematics.h:26
double plab_from_s_heavier_particle_at_rest(double mandelstam_s, double m1, double m2)
Convert Mandelstam-s to p_lab in a fixed-target collision.
Definition: kinematics.h:211
T pCM_from_s(const T s, const T mass_a, const T mass_b) noexcept
Definition: kinematics.h:66
double s_from_Etot(double e_tot, double m_P, double m_T)
Convert E_tot to Mandelstam-s for a fixed-target setup, with a projectile of mass m_P and a total ene...
Definition: kinematics.h:226
double s_from_plab(double plab, double m_P, double m_T)
Convert p_lab to Mandelstam-s for a fixed-target setup, with a projectile of mass m_P and momentum pl...
Definition: kinematics.h:280