Version: SMASH-1.6
density.h
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2013-2019
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  Isospin3_tot = 5,
41  Charge = 6,
42  Strangeness = 7,
43 };
44 
52 std::ostream &operator<<(std::ostream &os, DensityType dt);
53 
66 double density_factor(const ParticleType &type, DensityType dens_type);
67 
75 inline double smearing_factor_norm(const double two_sigma_sqr) {
76  const double tmp = two_sigma_sqr * M_PI;
77  return tmp * std::sqrt(tmp);
78 }
79 
97 inline double smearing_factor_rcut_correction(const double rcut_in_sigma) {
98  const double x = rcut_in_sigma / std::sqrt(2.0);
99  return -2.0 / std::sqrt(M_PI) * x * std::exp(-x * x) + std::erf(x);
100 }
101 
107  public:
117  : sig_(par.gaussian_sigma),
118  r_cut_(par.gauss_cutoff_in_sigma * par.gaussian_sigma),
119  ntest_(par.testparticles) {
120  r_cut_sqr_ = r_cut_ * r_cut_;
121  const double two_sig_sqr = 2 * sig_ * sig_;
122  two_sig_sqr_inv_ = 1. / two_sig_sqr;
123  const double norm = smearing_factor_norm(two_sig_sqr);
124  const double corr_factor =
126  norm_factor_sf_ = 1. / (norm * ntest_ * corr_factor);
127  }
129  int ntest() const { return ntest_; }
131  double r_cut() const { return r_cut_; }
133  double r_cut_sqr() const { return r_cut_sqr_; }
135  double two_sig_sqr_inv() const { return two_sig_sqr_inv_; }
141  double norm_factor_sf() const { return norm_factor_sf_; }
142 
143  private:
145  const double sig_;
147  const double r_cut_;
149  double r_cut_sqr_;
155  const int ntest_;
156 };
157 
175 std::pair<double, ThreeVector> unnormalized_smearing_factor(
176  const ThreeVector &r, const FourVector &p, const double m_inv,
177  const DensityParameters &dens_par, const bool compute_gradient = false);
178 
225 std::tuple<double, FourVector, ThreeVector, ThreeVector, ThreeVector>
226 current_eckart(const ThreeVector &r, const ParticleList &plist,
227  const DensityParameters &par, DensityType dens_type,
228  bool compute_gradient, bool smearing);
230 std::tuple<double, FourVector, ThreeVector, ThreeVector, ThreeVector>
231 current_eckart(const ThreeVector &r, const Particles &plist,
232  const DensityParameters &par, DensityType dens_type,
233  bool compute_gradient, bool smearing);
234 
257  public:
260  : jmu_pos_(FourVector()),
261  jmu_neg_(FourVector()),
262  djmu_dx_({FourVector(), FourVector(), FourVector(), FourVector()}) {}
263 
276  void add_particle(const ParticleData &part, double FactorTimesSf) {
277  const FourVector PartFourVelocity = FourVector(1.0, part.velocity());
278  if (FactorTimesSf > 0.0) {
279  jmu_pos_ += PartFourVelocity * FactorTimesSf;
280  } else {
281  jmu_neg_ += PartFourVelocity * FactorTimesSf;
282  }
283  }
284 
297  void add_particle_for_derivatives(const ParticleData &part, double factor,
298  ThreeVector sf_grad) {
299  const FourVector PartFourVelocity = FourVector(1.0, part.velocity());
300  for (int k = 1; k <= 3; k++) {
301  djmu_dx_[k] += factor * PartFourVelocity * sf_grad[k - 1];
302  djmu_dx_[0] -=
303  factor * PartFourVelocity * sf_grad[k - 1] * part.velocity()[k - 1];
304  }
305  }
306 
324  double density(const double norm_factor = 1.0) {
325  return (jmu_pos_.abs() - jmu_neg_.abs()) * norm_factor;
326  }
327 
334  ThreeVector rot_j(const double norm_factor = 1.0) {
335  ThreeVector j_rot = ThreeVector();
336  j_rot.set_x1(djmu_dx_[2].x3() - djmu_dx_[3].x2());
337  j_rot.set_x2(djmu_dx_[3].x1() - djmu_dx_[1].x3());
338  j_rot.set_x3(djmu_dx_[1].x2() - djmu_dx_[2].x1());
339  j_rot *= norm_factor;
340  return j_rot;
341  }
342 
349  ThreeVector grad_rho(const double norm_factor = 1.0) {
350  ThreeVector rho_grad = ThreeVector();
351  for (int i = 1; i < 4; i++) {
352  rho_grad[i - 1] = djmu_dx_[i].x0() * norm_factor;
353  }
354  return rho_grad;
355  }
356 
363  ThreeVector dj_dt(const double norm_factor = 1.0) {
364  return djmu_dx_[0].threevec() * norm_factor;
365  }
366 
373  FourVector jmu_net() const { return jmu_pos_ + jmu_neg_; }
374 
375  private:
381  std::array<FourVector, 4> djmu_dx_;
382 };
383 
386 
399 template <typename T>
401  const DensityType dens_type, const DensityParameters &par,
402  const Particles &particles,
403  const bool compute_gradient = false) {
404  // Do not proceed if lattice does not exists/update not required
405  if (lat == nullptr || lat->when_update() != update) {
406  return;
407  }
408  lat->reset();
409  const double norm_factor = par.norm_factor_sf();
410  for (const auto &part : particles) {
411  const double dens_factor = density_factor(part.type(), dens_type);
412  if (std::abs(dens_factor) < really_small) {
413  continue;
414  }
415  const FourVector p = part.momentum();
416  const double m = p.abs();
417  if (unlikely(m < really_small)) {
418  const auto &log = logger<LogArea::Density>();
419  log.warn("Gaussian smearing is undefined for momentum ", p);
420  continue;
421  }
422  const double m_inv = 1.0 / m;
423 
424  const ThreeVector pos = part.position().threevec();
425  lat->iterate_in_radius(
426  pos, par.r_cut(), [&](T &node, int ix, int iy, int iz) {
427  const ThreeVector r = lat->cell_center(ix, iy, iz);
428  const auto sf = unnormalized_smearing_factor(pos - r, p, m_inv, par,
429  compute_gradient);
430  if (sf.first * norm_factor > really_small) {
431  node.add_particle(part, sf.first * norm_factor * dens_factor);
432  }
433  if (compute_gradient) {
434  node.add_particle_for_derivatives(part, dens_factor,
435  sf.second * norm_factor);
436  }
437  });
438  }
439 }
440 
441 } // namespace smash
442 
443 #endif // SRC_INCLUDE_DENSITY_H_
A class to pre-calculate and store parameters relevant for density calculation.
Definition: density.h:106
std::array< FourVector, 4 > djmu_dx_
Definition: density.h:381
A class for time-efficient (time-memory trade-off) calculation of density on the lattice.
Definition: density.h:256
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:116
constexpr double really_small
Numerical error tolerance.
Definition: constants.h:34
FourVector jmu_neg_
Four-current density of the negatively charged particle.
Definition: density.h:379
const int ntest_
Testparticle number.
Definition: density.h:155
void add_particle(const ParticleData &part, double FactorTimesSf)
Adds particle to 4-current: .
Definition: density.h:276
const double sig_
Gaussian smearing width [fm].
Definition: density.h:145
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:400
double abs() const
calculate the lorentz invariant absolute value
Definition: fourvector.h:441
LatticeUpdate
Enumerator option for lattice updates.
Definition: lattice.h:35
ThreeVector velocity() const
Get the velocity 3-vector.
Definition: particledata.h:282
FourVector jmu_net() const
Definition: density.h:373
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
void set_x1(double x)
set first component
Definition: threevector.h:157
double two_sig_sqr_inv_
[fm ]
Definition: density.h:151
A container class to hold all the arrays on the lattice and access them.
Definition: lattice.h:46
LatticeUpdate when_update() const
Definition: lattice.h:157
double r_cut_sqr() const
Definition: density.h:133
void reset()
Sets all values on lattice to zeros.
Definition: lattice.h:92
ThreeVector cell_center(int ix, int iy, int iz) const
Find the coordinates of a given cell.
Definition: lattice.h:119
DensityOnLattice()
Default constructor.
Definition: density.h:259
double gauss_cutoff_in_sigma
Distance at which gaussian is cut, i.e. set to zero, IN SIGMA (not fm)
Particle type contains the static properties of a particle species.
Definition: particletype.h:97
ThreeVector rot_j(const double norm_factor=1.0)
Compute curl of the current on the local lattice.
Definition: density.h:334
int ntest() const
Definition: density.h:129
double norm_factor_sf_
Normalization for smearing factor.
Definition: density.h:153
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:97
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:363
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:149
void set_x3(double z)
set third component
Definition: threevector.h:165
double smearing_factor_norm(const double two_sigma_sqr)
Norm of the Gaussian smearing function.
Definition: density.h:75
double r_cut() const
Definition: density.h:131
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:38
const double r_cut_
Cut-off radius [fm].
Definition: density.h:147
double two_sig_sqr_inv() const
Definition: density.h:135
#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:377
double norm_factor_sf() const
Definition: density.h:141
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:463
ThreeVector grad_rho(const double norm_factor=1.0)
Compute gradient of the density on the local lattice.
Definition: density.h:349
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:324
RectangularLattice< DensityOnLattice > DensityLattice
Conveniency typedef for lattice of density.
Definition: density.h:385
Helper structure for Experiment.
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:149
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:297