Version: SMASH-2.0
density.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2013-2020
4  * SMASH Team
5  *
6  * GNU General Public License (GPLv3 or later)
7  *
8  */
9 
10 #include "smash/density.h"
11 #include "smash/constants.h"
12 #include "smash/logging.h"
13 
14 namespace smash {
15 
16 double density_factor(const ParticleType &type, DensityType dens_type) {
17  switch (dens_type) {
19  return type.is_hadron() ? 1. : 0.;
21  return static_cast<double>(type.baryon_number());
23  return type.is_baryon() || type.is_nucleus() ? type.isospin3_rel() : 0.;
24  case DensityType::Pion:
25  return type.pdgcode().is_pion() ? 1. : 0.;
27  return type.is_hadron() ? type.isospin3() : 0.;
29  return static_cast<double>(type.charge());
31  return static_cast<double>(type.strangeness());
32  default:
33  return 0.;
34  }
35 }
36 
37 std::pair<double, ThreeVector> unnormalized_smearing_factor(
38  const ThreeVector &r, const FourVector &p, const double m_inv,
39  const DensityParameters &dens_par, const bool compute_gradient) {
40  const double r_sqr = r.sqr();
41  // Distance from particle to point of interest > r_cut
42  if (r_sqr > dens_par.r_cut_sqr()) {
43  return std::make_pair(0.0, ThreeVector(0.0, 0.0, 0.0));
44  }
45 
46  const FourVector u = p * m_inv;
47  const double u_r_scalar = r * u.threevec();
48  const double r_rest_sqr = r_sqr + u_r_scalar * u_r_scalar;
49 
50  // Lorentz contracted distance from particle to point of interest > r_cut
51  if (r_rest_sqr > dens_par.r_cut_sqr()) {
52  return std::make_pair(0.0, ThreeVector(0.0, 0.0, 0.0));
53  }
54  const double sf = std::exp(-r_rest_sqr * dens_par.two_sig_sqr_inv()) * u.x0();
55  const ThreeVector sf_grad = compute_gradient
56  ? sf * (r + u.threevec() * u_r_scalar) *
57  dens_par.two_sig_sqr_inv() * 2.0
58  : ThreeVector(0.0, 0.0, 0.0);
59 
60  return std::make_pair(sf, sf_grad);
61 }
62 
64 template <typename /*ParticlesContainer*/ T>
65 std::tuple<double, FourVector, ThreeVector, ThreeVector, ThreeVector>
66 current_eckart_impl(const ThreeVector &r, const T &plist,
67  const DensityParameters &par, DensityType dens_type,
68  bool compute_gradient, bool smearing) {
69  /* The current density of the positively and negatively charged particles.
70  * Division into positive and negative charges is necessary to avoid
71  * problems with the Eckart frame definition. Example of problem:
72  * get Eckart frame for two identical oppositely flying bunches of
73  * electrons and positrons. For this case jmu = (0, 0, 0, non-zero),
74  * so jmu.abs does not exist and Eckart frame is not defined.
75  * If one takes rho = jmu_pos.abs - jmu_neg.abs, it is still Lorentz-
76  * invariant and gives the right limit in non-relativistic case, but
77  * it gives no such problem. */
78  FourVector jmu_pos, jmu_neg;
79  /* The array of the derivatives of the current density.
80  * The zeroth component is the time derivative,
81  * while the next 3 ones are spacial derivatives. */
82  std::array<FourVector, 4> djmu_dx;
83 
84  for (const auto &p : plist) {
85  const double dens_factor = density_factor(p.type(), dens_type);
86  if (std::fabs(dens_factor) < really_small) {
87  continue;
88  }
89  const FourVector mom = p.momentum();
90  const double m = mom.abs();
91  if (m < really_small) {
92  continue;
93  }
94  const double m_inv = 1.0 / m;
95  const auto sf_and_grad = unnormalized_smearing_factor(
96  p.position().threevec() - r, mom, m_inv, par, compute_gradient);
97  if (smearing && sf_and_grad.first < really_small) {
98  continue;
99  }
100  const FourVector tmp = mom * (dens_factor / mom.x0());
101  if (smearing) {
102  if (dens_factor > 0.) {
103  jmu_pos += tmp * sf_and_grad.first;
104  } else {
105  jmu_neg += tmp * sf_and_grad.first;
106  }
107  } else {
108  if (dens_factor > 0.) {
109  jmu_pos += tmp;
110  } else {
111  jmu_neg += tmp;
112  }
113  }
114  if (compute_gradient) {
115  for (int k = 1; k <= 3; k++) {
116  djmu_dx[k] += tmp * sf_and_grad.second[k - 1];
117  djmu_dx[0] -= tmp * sf_and_grad.second[k - 1] * tmp.threevec()[k - 1] /
118  dens_factor;
119  }
120  }
121  }
122 
123  // Eckart density
124  const double rho_eck = (jmu_pos.abs() - jmu_neg.abs()) * par.norm_factor_sf();
125 
126  // $\partial_t \vec j$
127  const ThreeVector dj_dt = compute_gradient
128  ? djmu_dx[0].threevec() * par.norm_factor_sf()
129  : ThreeVector(0.0, 0.0, 0.0);
130 
131  // Gradient of density
132  ThreeVector rho_grad;
133  // Curl of current density
134  ThreeVector j_rot;
135  if (compute_gradient) {
136  j_rot.set_x1(djmu_dx[2].x3() - djmu_dx[3].x2());
137  j_rot.set_x2(djmu_dx[3].x1() - djmu_dx[1].x3());
138  j_rot.set_x3(djmu_dx[1].x2() - djmu_dx[2].x1());
139  j_rot *= par.norm_factor_sf();
140  for (int i = 1; i < 4; i++) {
141  rho_grad[i - 1] += djmu_dx[i].x0() * par.norm_factor_sf();
142  }
143  }
144  return std::make_tuple(rho_eck, jmu_pos + jmu_neg, rho_grad, dj_dt, j_rot);
145 }
146 
147 std::tuple<double, FourVector, ThreeVector, ThreeVector, ThreeVector>
148 current_eckart(const ThreeVector &r, const ParticleList &plist,
149  const DensityParameters &par, DensityType dens_type,
150  bool compute_gradient, bool smearing) {
151  return current_eckart_impl(r, plist, par, dens_type, compute_gradient,
152  smearing);
153 }
154 std::tuple<double, FourVector, ThreeVector, ThreeVector, ThreeVector>
155 current_eckart(const ThreeVector &r, const Particles &plist,
156  const DensityParameters &par, DensityType dens_type,
157  bool compute_gradient, bool smearing) {
158  return current_eckart_impl(r, plist, par, dens_type, compute_gradient,
159  smearing);
160 }
161 
162 std::ostream &operator<<(std::ostream &os, DensityType dens_type) {
163  switch (dens_type) {
164  case DensityType::Hadron:
165  os << "hadron density";
166  break;
167  case DensityType::Baryon:
168  os << "baryon density";
169  break;
171  os << "baryonic isospin density";
172  break;
173  case DensityType::Pion:
174  os << "pion density";
175  break;
177  os << "total isospin3 density";
178  break;
179  case DensityType::None:
180  os << "none";
181  break;
182  default:
183  os.setstate(std::ios_base::failbit);
184  }
185  return os;
186 }
187 
188 } // namespace smash
smash::DensityType::Strangeness
smash
Definition: action.h:24
smash::ThreeVector::set_x2
void set_x2(double y)
set second component
Definition: threevector.h:171
smash::DensityParameters::two_sig_sqr_inv
double two_sig_sqr_inv() const
Definition: density.h:137
smash::DensityParameters
A class to pre-calculate and store parameters relevant for density calculation.
Definition: density.h:108
smash::DensityType::BaryonicIsospin
smash::ThreeVector::set_x3
void set_x3(double z)
set third component
Definition: threevector.h:175
smash::PdgCode::is_pion
bool is_pion() const
Definition: pdgcode.h:381
smash::operator<<
std::ostream & operator<<(std::ostream &out, const ActionPtr &action)
Definition: action.h:518
smash::ThreeVector::sqr
double sqr() const
Definition: threevector.h:259
smash::ParticleType::pdgcode
PdgCode pdgcode() const
Definition: particletype.h:156
smash::unnormalized_smearing_factor
std::pair< double, ThreeVector > unnormalized_smearing_factor(const ThreeVector &r, const FourVector &p, const double m_inv, const DensityParameters &dens_par, const bool compute_gradient=false)
Implements gaussian smearing for any quantity.
Definition: density.cc:37
smash::ParticleType::is_baryon
bool is_baryon() const
Definition: particletype.h:203
smash::really_small
constexpr double really_small
Numerical error tolerance.
Definition: constants.h:37
smash::density_factor
double density_factor(const ParticleType &type, DensityType dens_type)
Get the factor that determines how much a particle contributes to the density type that is computed.
Definition: density.cc:16
smash::ThreeVector
Definition: threevector.h:31
smash::DensityType::Charge
smash::current_eckart_impl
std::tuple< double, FourVector, ThreeVector, ThreeVector, ThreeVector > current_eckart_impl(const ThreeVector &r, const T &plist, const DensityParameters &par, DensityType dens_type, bool compute_gradient, bool smearing)
Calculates Eckart rest frame density and 4-current of a given density type and optionally the gradien...
Definition: density.cc:66
smash::FourVector::x0
double x0() const
Definition: fourvector.h:303
smash::ParticleType::is_nucleus
bool is_nucleus() const
Definition: particletype.h:242
smash::ParticleType::is_hadron
bool is_hadron() const
Definition: particletype.h:197
smash::ParticleType::isospin3_rel
double isospin3_rel() const
Definition: particletype.h:179
smash::ParticleType
Definition: particletype.h:97
smash::DensityParameters::r_cut_sqr
double r_cut_sqr() const
Definition: density.h:135
density.h
smash::DensityType::Pion
smash::current_eckart
std::tuple< double, FourVector, ThreeVector, ThreeVector, ThreeVector > current_eckart(const ThreeVector &r, const ParticleList &plist, const DensityParameters &par, DensityType dens_type, bool compute_gradient, bool smearing)
Calculates Eckart rest frame density and 4-current of a given density type and optionally the gradien...
Definition: density.cc:148
smash::ThreeVector::set_x1
void set_x1(double x)
set first component
Definition: threevector.h:167
smash::FourVector::abs
double abs() const
calculate the lorentz invariant absolute value
Definition: fourvector.h:454
smash::ParticleType::isospin3
int isospin3() const
Definition: particletype.h:176
smash::Particles
Definition: particles.h:33
smash::DensityType
DensityType
Allows to choose which kind of density to calculate.
Definition: density.h:36
constants.h
smash::DensityParameters::norm_factor_sf
double norm_factor_sf() const
Definition: density.h:143
logging.h
smash::ParticleType::strangeness
int strangeness() const
Definition: particletype.h:212
smash::DensityType::None
smash::FourVector
Definition: fourvector.h:33
smash::DensityType::Isospin3_tot
smash::pdg::p
constexpr int p
Proton.
Definition: pdgcode_constants.h:28
smash::DensityType::Hadron
smash::DensityType::Baryon
smash::FourVector::threevec
ThreeVector threevec() const
Definition: fourvector.h:319
smash::ParticleType::charge
int32_t charge() const
The charge of the particle.
Definition: particletype.h:188
smash::ParticleType::baryon_number
int baryon_number() const
Definition: particletype.h:209