Version: SMASH-3.1
clebschgordan.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013-2020,2022-2023
3  * SMASH Team
4  *
5  * GNU General Public License (GPLv3 or later)
6  */
7 
8 #include "smash/clebschgordan.h"
9 
10 #include <numeric>
11 
12 #include "gsl/gsl_sf_coupling.h"
13 
15 #include "smash/constants.h"
16 #include "smash/logging.h"
17 
18 namespace smash {
19 
30 static double isospin_clebsch_gordan_2to1(const ParticleType &p_a,
31  const ParticleType &p_b,
32  const int I_tot, const int I_z) {
33  return ClebschGordan::coefficient(p_a.isospin(), p_b.isospin(), I_tot,
34  p_a.isospin3(), p_b.isospin3(), I_z);
35 }
36 
38  const ParticleType &p_b,
39  const ParticleType &p_c,
40  const ParticleType &Res) {
41  // Calculate allowed isospin range for 3->1 reaction I_ab
42  const auto min_I_ab = std::abs(p_a.isospin() - p_b.isospin());
43  const auto max_I_ab = p_a.isospin() + p_b.isospin();
44  std::vector<int> possible_I_ab(max_I_ab - min_I_ab + 1);
45  std::iota(possible_I_ab.begin(), possible_I_ab.end(), min_I_ab);
46  std::vector<int> allowed_I_ab;
47  allowed_I_ab.reserve(possible_I_ab.size());
48  for (const auto Iab : possible_I_ab) {
49  const auto min_I = std::abs(Iab - p_c.isospin());
50  const auto max_I = Iab + p_c.isospin();
51  if (min_I <= Res.isospin() && Res.isospin() <= max_I) {
52  allowed_I_ab.push_back(Iab);
53  }
54  }
55  if (allowed_I_ab.size() != 1) {
56  throw std::runtime_error(
57  "The coupled 3-body isospin state is not uniquely defined for " +
58  Res.name() + " -> " + p_a.name() + " " + p_b.name() + " " + p_c.name());
59  }
60  const auto I_ab = allowed_I_ab[0];
61 
62  const int I_abz = p_a.isospin3() + p_b.isospin3();
63  const double cg =
64  ClebschGordan::coefficient(I_ab, p_c.isospin(), Res.isospin(), I_abz,
65  p_c.isospin3(), Res.isospin3()) *
66  ClebschGordan::coefficient(p_a.isospin(), p_b.isospin(), I_ab,
67  p_a.isospin3(), p_b.isospin3(), I_abz);
68  return cg * cg;
69 }
70 
72  const ParticleType &p_b,
73  const ParticleType &p_c,
74  const ParticleType &p_d, const int I) {
75  const int I_z = p_a.isospin3() + p_b.isospin3();
76 
77  /* Loop over total isospin in allowed range. */
78  double isospin_factor = 0.;
79  for (const int I_tot : I_tot_range(p_a, p_b, p_c, p_d)) {
80  if (I < 0 || I_tot == I) {
81  const double cg_in = isospin_clebsch_gordan_2to1(p_a, p_b, I_tot, I_z);
82  const double cg_out = isospin_clebsch_gordan_2to1(p_c, p_d, I_tot, I_z);
83  isospin_factor = isospin_factor + cg_in * cg_in * cg_out * cg_out;
84  }
85  }
86  return isospin_factor;
87 }
88 
89 } // namespace smash
static double coefficient(const int j_a, const int j_b, const int j_c, const int m_a, const int m_b, const int m_c)
Check in the Clebsch-Gordan lookup table if the requested coefficient is available.
Range of total isospin for reaction of particle a with particle b.
Definition: clebschgordan.h:68
Particle type contains the static properties of a particle species.
Definition: particletype.h:98
int isospin3() const
Definition: particletype.h:177
const std::string & name() const
Definition: particletype.h:142
int isospin() const
Returns twice the isospin vector length .
Collection of useful constants that are known at compile time.
Definition: action.h:24
double isospin_clebsch_gordan_sqr_3to1(const ParticleType &p_a, const ParticleType &p_b, const ParticleType &p_c, const ParticleType &Res)
Calculate the squared isospin Clebsch-Gordan coefficient for three particles p_a, p_b and p_c couplin...
double isospin_clebsch_gordan_sqr_2to2(const ParticleType &p_a, const ParticleType &p_b, const ParticleType &p_c, const ParticleType &p_d, const int I=-1)
Calculate the squared isospin Clebsch-Gordan coefficient for a 2-to-2 reaction A + B -> C + D.
static double isospin_clebsch_gordan_2to1(const ParticleType &p_a, const ParticleType &p_b, const int I_tot, const int I_z)
Calculate isospin Clebsch-Gordan coefficient for two particles p_a and p_b coupling to a total isospi...