Version: SMASH-1.5
density.h
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2013-2018
4  * SMASH Team
5  *
6  * GNU General Public License (GPLv3 or later)
7  *
8  */
9 #ifndef SRC_INCLUDE_DENSITY_H_
10 #define SRC_INCLUDE_DENSITY_H_
11 
12 #include <iostream>
13 #include <typeinfo>
14 #include <utility>
15 #include <vector>
16 
17 #include "energymomentumtensor.h"
18 #include "experimentparameters.h"
19 #include "forwarddeclarations.h"
20 #include "fourvector.h"
21 #include "lattice.h"
22 #include "particledata.h"
23 #include "particles.h"
24 #include "pdgcode.h"
25 #include "threevector.h"
26 
27 namespace smash {
28 
34 enum class DensityType {
35  None = 0,
36  Hadron = 1,
37  Baryon = 2,
38  BaryonicIsospin = 3,
39  Pion = 4,
40 };
41 
49 std::ostream &operator<<(std::ostream &os, DensityType dt);
50 
63 double density_factor(const ParticleType &type, DensityType dens_type);
64 
72 inline double smearing_factor_norm(const double two_sigma_sqr) {
73  const double tmp = two_sigma_sqr * M_PI;
74  return tmp * std::sqrt(tmp);
75 }
76 
94 inline double smearing_factor_rcut_correction(const double rcut_in_sigma) {
95  const double x = rcut_in_sigma / std::sqrt(2.0);
96  return -2.0 / std::sqrt(M_PI) * x * std::exp(-x * x) + std::erf(x);
97 }
98 
104  public:
114  : sig_(par.gaussian_sigma),
115  r_cut_(par.gauss_cutoff_in_sigma * par.gaussian_sigma),
116  ntest_(par.testparticles) {
118  const double two_sig_sqr = 2 * sig_ * sig_;
119  two_sig_sqr_inv_ = 1. / two_sig_sqr;
120  const double norm = smearing_factor_norm(two_sig_sqr);
121  const double corr_factor =
123  norm_factor_sf_ = 1. / (norm * ntest_ * corr_factor);
124  }
126  int ntest() const { return ntest_; }
128  double r_cut() const { return r_cut_; }
130  double r_cut_sqr() const { return r_cut_sqr_; }
132  double two_sig_sqr_inv() const { return two_sig_sqr_inv_; }
138  double norm_factor_sf() const { return norm_factor_sf_; }
139 
140  private:
142  const double sig_;
144  const double r_cut_;
146  double r_cut_sqr_;
152  const int ntest_;
153 };
154 
172 std::pair<double, ThreeVector> unnormalized_smearing_factor(
173  const ThreeVector &r, const FourVector &p, const double m_inv,
174  const DensityParameters &dens_par, const bool compute_gradient = false);
175 
213 std::tuple<double, ThreeVector, ThreeVector, ThreeVector> rho_eckart(
214  const ThreeVector &r, const ParticleList &plist,
215  const DensityParameters &par, DensityType dens_type, bool compute_gradient);
217 std::tuple<double, ThreeVector, ThreeVector, ThreeVector> rho_eckart(
218  const ThreeVector &r, const Particles &plist, const DensityParameters &par,
219  DensityType dens_type, bool compute_gradient);
220 
243  public:
246  : jmu_pos_(FourVector()),
247  jmu_neg_(FourVector()),
249 
262  void add_particle(const ParticleData &part, double FactorTimesSf) {
263  const FourVector PartFourVelocity = FourVector(1.0, part.velocity());
264  if (FactorTimesSf > 0.0) {
265  jmu_pos_ += PartFourVelocity * FactorTimesSf;
266  } else {
267  jmu_neg_ += PartFourVelocity * FactorTimesSf;
268  }
269  }
270 
283  void add_particle_for_derivatives(const ParticleData &part, double factor,
284  ThreeVector sf_grad) {
285  const FourVector PartFourVelocity = FourVector(1.0, part.velocity());
286  for (int k = 1; k <= 3; k++) {
287  djmu_dx_[k] += factor * PartFourVelocity * sf_grad[k - 1];
288  djmu_dx_[0] -=
289  factor * PartFourVelocity * sf_grad[k - 1] * part.velocity()[k - 1];
290  }
291  }
292 
310  double density(const double norm_factor = 1.0) {
311  return (jmu_pos_.abs() - jmu_neg_.abs()) * norm_factor;
312  }
313 
320  ThreeVector rot_j(const double norm_factor = 1.0) {
321  ThreeVector j_rot = ThreeVector();
322  j_rot.set_x1(djmu_dx_[2].x3() - djmu_dx_[3].x2());
323  j_rot.set_x2(djmu_dx_[3].x1() - djmu_dx_[1].x3());
324  j_rot.set_x3(djmu_dx_[1].x2() - djmu_dx_[2].x1());
325  j_rot *= norm_factor;
326  return j_rot;
327  }
328 
335  ThreeVector grad_rho(const double norm_factor = 1.0) {
336  ThreeVector rho_grad = ThreeVector();
337  for (int i = 1; i < 4; i++) {
338  rho_grad[i - 1] = djmu_dx_[i].x0() * norm_factor;
339  }
340  return rho_grad;
341  }
342 
349  ThreeVector dj_dt(const double norm_factor = 1.0) {
350  return djmu_dx_[0].threevec() * norm_factor;
351  }
352 
359  FourVector jmu_net() const { return jmu_pos_ + jmu_neg_; }
360 
361  private:
367  std::array<FourVector, 4> djmu_dx_;
368 };
369 
372 
385 template <typename T>
387  const DensityType dens_type, const DensityParameters &par,
388  const Particles &particles,
389  const bool compute_gradient = false) {
390  // Do not proceed if lattice does not exists/update not required
391  if (lat == nullptr || lat->when_update() != update) {
392  return;
393  }
394  lat->reset();
395  const double norm_factor = par.norm_factor_sf();
396  for (const auto &part : particles) {
397  const double dens_factor = density_factor(part.type(), dens_type);
398  if (std::abs(dens_factor) < really_small) {
399  continue;
400  }
401  const FourVector p = part.momentum();
402  const double m = p.abs();
403  if (unlikely(m < really_small)) {
404  const auto &log = logger<LogArea::Density>();
405  log.warn("Gaussian smearing is undefined for momentum ", p);
406  continue;
407  }
408  const double m_inv = 1.0 / m;
409 
410  const ThreeVector pos = part.position().threevec();
411  lat->iterate_in_radius(
412  pos, par.r_cut(), [&](T &node, int ix, int iy, int iz) {
413  const ThreeVector r = lat->cell_center(ix, iy, iz);
414  const auto sf = unnormalized_smearing_factor(pos - r, p, m_inv, par,
415  compute_gradient);
416  if (sf.first * norm_factor > really_small) {
417  node.add_particle(part, sf.first * norm_factor * dens_factor);
418  }
419  if (compute_gradient) {
420  node.add_particle_for_derivatives(part, dens_factor,
421  sf.second * norm_factor);
422  }
423  });
424  }
425 }
426 
427 } // namespace smash
428 
429 #endif // SRC_INCLUDE_DENSITY_H_
A class to pre-calculate and store parameters relevant for density calculation.
Definition: density.h:103
std::array< FourVector, 4 > djmu_dx_
Definition: density.h:367
A class for time-efficient (time-memory trade-off) calculation of density on the lattice.
Definition: density.h:242
The ThreeVector class represents a physical three-vector with the components .
Definition: threevector.h:30
DensityParameters(const ExperimentParameters &par)
Constructor of DensityParameters.
Definition: density.h:113
constexpr double really_small
Numerical error tolerance.
Definition: constants.h:34
double norm_factor_sf() const
Definition: density.h:138
FourVector jmu_neg_
Four-current density of the negatively charged particle.
Definition: density.h:365
const int ntest_
Testparticle number.
Definition: density.h:152
void add_particle(const ParticleData &part, double FactorTimesSf)
Adds particle to 4-current: .
Definition: density.h:262
const double sig_
Gaussian smearing width [fm].
Definition: density.h:142
void update_lattice(RectangularLattice< T > *lat, const LatticeUpdate update, const DensityType dens_type, const DensityParameters &par, const Particles &particles, const bool compute_gradient=false)
Updates the contents on the lattice.
Definition: density.h:386
std::tuple< double, ThreeVector, ThreeVector, ThreeVector > rho_eckart(const ThreeVector &r, const ParticleList &plist, const DensityParameters &par, DensityType dens_type, bool compute_gradient)
Calculates Eckart rest frame density and optionally the gradient of the density in an arbitary frame...
Definition: density.cc:133
FourVector jmu_net() const
Definition: density.h:359
LatticeUpdate
Enumerator option for lattice updates.
Definition: lattice.h:35
double two_sig_sqr_inv() const
Definition: density.h:132
void iterate_in_radius(const ThreeVector &point, const double r_cut, F &&func)
Iterates only nodes, whose cell centers lie not further than r_cut in x, y, z directions from the giv...
Definition: lattice.h:279
LatticeUpdate when_update() const
Definition: lattice.h:157
void set_x1(double x)
set first component
Definition: threevector.h:157
double two_sig_sqr_inv_
[fm ]
Definition: density.h:148
A container class to hold all the arrays on the lattice and access them.
Definition: lattice.h:46
void reset()
Sets all values on lattice to zeros.
Definition: lattice.h:92
DensityOnLattice()
Default constructor.
Definition: density.h:245
double gauss_cutoff_in_sigma
Distance at which gaussian is cut, i.e. set to zero, IN SIGMA (not fm)
ThreeVector rot_j(const double norm_factor=1.0)
Compute curl of the current on the local lattice.
Definition: density.h:320
double norm_factor_sf_
Normalization for smearing factor.
Definition: density.h:150
double smearing_factor_rcut_correction(const double rcut_in_sigma)
Gaussians used for smearing are cut at radius for calculation speed-up.
Definition: density.h:94
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:17
ThreeVector dj_dt(const double norm_factor=1.0)
Compute time derivative of the current density on the local lattice.
Definition: density.h:349
void set_x3(double z)
set third component
Definition: threevector.h:165
ThreeVector cell_center(int ix, int iy, int iz) const
Find the coordinates of a given cell.
Definition: lattice.h:119
double r_cut() const
Definition: density.h:128
double smearing_factor_norm(const double two_sigma_sqr)
Norm of the Gaussian smearing function.
Definition: density.h:72
constexpr int p
Proton.
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:32
const double r_cut_
Cut-off radius [fm].
Definition: density.h:144
ThreeVector velocity() const
Get the velocity 3-vector.
Definition: particledata.h:282
#define unlikely(x)
Tell the branch predictor that this expression is likely false.
Definition: macros.h:16
FourVector jmu_pos_
Four-current density of the positively charged particle.
Definition: density.h:363
The Particles class abstracts the storage and manipulation of particles.
Definition: particles.h:33
DensityType
Allows to choose which kind of density to calculate.
Definition: density.h:34
std::ostream & operator<<(std::ostream &out, const ActionPtr &action)
Convenience: dereferences the ActionPtr to Action.
Definition: action.h:457
ThreeVector grad_rho(const double norm_factor=1.0)
Compute gradient of the density on the local lattice.
Definition: density.h:335
The FourVector class holds relevant values in Minkowski spacetime with (+, −, −, −) metric signature.
Definition: fourvector.h:32
double density(const double norm_factor=1.0)
Compute the net Eckart density on the local lattice.
Definition: density.h:310
double abs() const
calculate the lorentz invariant absolute value
Definition: fourvector.h:441
RectangularLattice< DensityOnLattice > DensityLattice
Conveniency typedef for lattice of density.
Definition: density.h:371
Helper structure for Experiment.
double r_cut_sqr() const
Definition: density.h:130
ParticleData contains the dynamic information of a certain particle.
Definition: particledata.h:52
void set_x2(double y)
set second component
Definition: threevector.h:161
double r_cut_sqr_
Squared cut-off radius [fm ].
Definition: density.h:146
Definition: action.h:24
void add_particle_for_derivatives(const ParticleData &part, double factor, ThreeVector sf_grad)
Adds particle to the time and spatial derivatives of the 4-current.
Definition: density.h:283