Version: SMASH-2.1
density.h
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2013-2021
4  * SMASH Team
5  *
6  * GNU General Public License (GPLv3 or later)
7  *
8  */
9 #ifndef SRC_INCLUDE_SMASH_DENSITY_H_
10 #define SRC_INCLUDE_SMASH_DENSITY_H_
11 
12 #include <iostream>
13 #include <tuple>
14 #include <typeinfo>
15 #include <utility>
16 #include <vector>
17 
18 #include "energymomentumtensor.h"
19 #include "experimentparameters.h"
20 #include "forwarddeclarations.h"
21 #include "fourvector.h"
22 #include "lattice.h"
23 #include "particledata.h"
24 #include "particles.h"
25 #include "pdgcode.h"
26 #include "threevector.h"
27 
28 namespace smash {
29 static constexpr int LDensity = LogArea::Density::id;
30 
36 enum class DensityType {
37  None = 0,
38  Hadron = 1,
39  Baryon = 2,
40  BaryonicIsospin = 3,
41  Pion = 4,
42  Isospin3_tot = 5,
43  Charge = 6,
44  Strangeness = 7,
45 };
46 
54 std::ostream &operator<<(std::ostream &os, DensityType dt);
55 
68 double density_factor(const ParticleType &type, DensityType dens_type);
69 
77 inline double smearing_factor_norm(const double two_sigma_sqr) {
78  const double tmp = two_sigma_sqr * M_PI;
79  return tmp * std::sqrt(tmp);
80 }
81 
99 inline double smearing_factor_rcut_correction(const double rcut_in_sigma) {
100  const double x = rcut_in_sigma / std::sqrt(2.0);
101  return -2.0 / std::sqrt(M_PI) * x * std::exp(-x * x) + std::erf(x);
102 }
103 
109  public:
122  : sig_(par.gaussian_sigma),
123  r_cut_(par.gauss_cutoff_in_sigma * par.gaussian_sigma),
124  ntest_(par.testparticles),
125  nensembles_(par.n_ensembles),
126  derivatives_(par.derivatives_mode),
127  rho_derivatives_(par.rho_derivatives_mode),
128  smearing_(par.smearing_mode),
129  central_weight_(par.discrete_weight),
133  const double two_sig_sqr = 2 * sig_ * sig_;
134  two_sig_sqr_inv_ = 1. / two_sig_sqr;
135  const double norm = smearing_factor_norm(two_sig_sqr);
136  const double corr_factor =
138  norm_factor_sf_ = 1. / (norm * ntest_ * nensembles_ * corr_factor);
139  }
141  int ntest() const { return ntest_; }
143  int nensembles() const { return nensembles_; }
148  return rho_derivatives_;
149  }
151  SmearingMode smearing() const { return smearing_; }
153  double central_weight() const { return central_weight_; }
155  double triangular_range() const { return triangular_range_; }
157  double r_cut() const { return r_cut_; }
159  double r_cut_sqr() const { return r_cut_sqr_; }
161  double two_sig_sqr_inv() const { return two_sig_sqr_inv_; }
167  double norm_factor_sf() const { return norm_factor_sf_; }
169  bool only_participants() const { return only_participants_; }
170 
171  private:
173  const double sig_;
175  const double r_cut_;
177  double r_cut_sqr_;
183  const int ntest_;
185  const int nensembles_;
193  const double central_weight_;
195  const double triangular_range_;
198 };
199 
217 std::pair<double, ThreeVector> unnormalized_smearing_factor(
218  const ThreeVector &r, const FourVector &p, const double m_inv,
219  const DensityParameters &dens_par, const bool compute_gradient = false);
220 
273 current_eckart(const ThreeVector &r, const ParticleList &plist,
274  const DensityParameters &par, DensityType dens_type,
275  bool compute_gradient, bool smearing);
279 current_eckart(const ThreeVector &r, const Particles &plist,
280  const DensityParameters &par, DensityType dens_type,
281  bool compute_gradient, bool smearing);
282 
311  public:
314  : jmu_pos_(FourVector()),
315  jmu_neg_(FourVector()),
317  drho_dxnu_(FourVector()) {}
318 
331  void add_particle(const ParticleData &part, double FactorTimesSf) {
332  const FourVector part_four_velocity = FourVector(1.0, part.velocity());
333  if (FactorTimesSf > 0.0) {
334  jmu_pos_ += part_four_velocity * FactorTimesSf;
335  } else {
336  jmu_neg_ += part_four_velocity * FactorTimesSf;
337  }
338  }
339 
352  void add_particle_for_derivatives(const ParticleData &part, double factor,
353  ThreeVector sf_grad) {
354  const FourVector PartFourVelocity = FourVector(1.0, part.velocity());
355  for (int k = 1; k <= 3; k++) {
356  djmu_dxnu_[k] += factor * PartFourVelocity * sf_grad[k - 1];
357  djmu_dxnu_[0] -=
358  factor * PartFourVelocity * sf_grad[k - 1] * part.velocity()[k - 1];
359  }
360  }
361 
379  double rho(const double norm_factor = 1.0) {
380  return (jmu_pos_.abs() - jmu_neg_.abs()) * norm_factor;
381  }
382 
389  ThreeVector curl_vecj(const double norm_factor = 1.0) {
390  ThreeVector curl_vec_j = ThreeVector();
391  curl_vec_j.set_x1(djmu_dxnu_[2].x3() - djmu_dxnu_[3].x2());
392  curl_vec_j.set_x2(djmu_dxnu_[3].x1() - djmu_dxnu_[1].x3());
393  curl_vec_j.set_x3(djmu_dxnu_[1].x2() - djmu_dxnu_[2].x1());
394  curl_vec_j *= norm_factor;
395  return curl_vec_j;
396  }
397 
405  ThreeVector grad_j0(const double norm_factor = 1.0) {
406  ThreeVector j0_grad = ThreeVector();
407  for (int i = 1; i < 4; i++) {
408  j0_grad[i - 1] = djmu_dxnu_[i].x0() * norm_factor;
409  }
410  return j0_grad;
411  }
412 
419  ThreeVector dvecj_dt(const double norm_factor = 1.0) {
420  return djmu_dxnu_[0].threevec() * norm_factor;
421  }
422 
429  FourVector jmu_net() const { return jmu_pos_ + jmu_neg_; }
430 
435  void add_to_jmu_pos(FourVector additional_jmu_B) {
436  jmu_pos_ += additional_jmu_B;
437  }
438 
443  void add_to_jmu_neg(FourVector additional_jmu_B) {
444  jmu_neg_ += additional_jmu_B;
445  }
446 
453  FourVector drho_dxnu() const { return drho_dxnu_; }
454 
460  std::array<FourVector, 4> djmu_dxnu() const { return djmu_dxnu_; }
461 
467  const ThreeVector grad_rho = drho_dxnu_.threevec();
468  const ThreeVector vecj = jmu_net().threevec();
469  const ThreeVector Drho_cross_vecj = grad_rho.cross_product(vecj);
470 
471  return Drho_cross_vecj;
472  }
473 
478  djmu_dxnu_[0] = FourVector(0.0, 0.0, 0.0, 0.0);
479  }
480 
485 
490  void overwrite_drho_dxnu(FourVector computed_drho_dxnu) {
491  drho_dxnu_ = computed_drho_dxnu;
492  }
493 
502  FourVector djmu_dy, FourVector djmu_dz) {
503  djmu_dxnu_[0] = djmu_dt;
504  djmu_dxnu_[1] = djmu_dx;
505  djmu_dxnu_[2] = djmu_dy;
506  djmu_dxnu_[3] = djmu_dz;
507  }
508 
509  private:
515  std::array<FourVector, 4> djmu_dxnu_;
518 };
519 
522 
535 template <typename T>
537  const DensityType dens_type, const DensityParameters &par,
538  const std::vector<Particles> &ensembles,
539  const bool compute_gradient) {
540  // Do not proceed if lattice does not exists/update not required
541  if (lat == nullptr || lat->when_update() != update) {
542  return;
543  }
544 
545  lat->reset();
546  // get the normalization factor for the covariant Gaussian smearing
547  const double norm_factor_gaus = par.norm_factor_sf();
548  // get the volume of the cell and weights for discrete smearing
549  const double V_cell =
550  (lat->cell_sizes())[0] * (lat->cell_sizes())[1] * (lat->cell_sizes())[2];
551  // weights for coarse smearing
552  const double big = par.central_weight();
553  const double small = (1.0 - big) / 6.0;
554  // get the radii for triangular smearing
555  const std::array<double, 3> triangular_radius = {
556  par.triangular_range() * (lat->cell_sizes())[0],
557  par.triangular_range() * (lat->cell_sizes())[1],
558  par.triangular_range() * (lat->cell_sizes())[2]};
559  const double prefactor_triangular =
560  1.0 /
561  (par.ntest() * par.nensembles() * triangular_radius[0] *
562  triangular_radius[0] * triangular_radius[1] * triangular_radius[1] *
563  triangular_radius[2] * triangular_radius[2]);
564 
565  for (const Particles &particles : ensembles) {
566  for (const ParticleData &part : particles) {
567  if (par.only_participants()) {
568  // if this conditions holds, the hadron is a spectator
569  if (part.get_history().collisions_per_particle == 0) {
570  continue;
571  }
572  }
573  const double dens_factor = density_factor(part.type(), dens_type);
574  if (std::abs(dens_factor) < really_small) {
575  continue;
576  }
577  const FourVector p_mu = part.momentum();
578  const ThreeVector pos = part.position().threevec();
579 
580  // act accordingly to which smearing is used
582  const double m = p_mu.abs();
583  if (unlikely(m < really_small)) {
584  logg[LDensity].warn("Gaussian smearing is undefined for momentum ",
585  p_mu);
586  continue;
587  }
588  const double m_inv = 1.0 / m;
589 
590  // unweighted contribution to density
591  const double common_weight = dens_factor * norm_factor_gaus;
592  lat->iterate_in_cube(
593  pos, par.r_cut(), [&](T &node, int ix, int iy, int iz) {
594  // find the weight for smearing
595  const ThreeVector r = lat->cell_center(ix, iy, iz);
596  const auto sf = unnormalized_smearing_factor(
597  pos - r, p_mu, m_inv, par, compute_gradient);
598  node.add_particle(part, sf.first * common_weight);
599  if (par.derivatives() == DerivativesMode::CovariantGaussian) {
600  node.add_particle_for_derivatives(part, dens_factor,
601  sf.second * norm_factor_gaus);
602  }
603  });
604  } else if (par.smearing() == SmearingMode::Discrete) {
605  // unweighted contribution to density
606  const double common_weight =
607  dens_factor / (par.ntest() * par.nensembles() * V_cell);
609  pos, [&](T &node, int iterated_index, int center_index) {
610  node.add_particle(
611  part, common_weight *
612  // the contribution to density is weighted depending
613  // on what node it is added to
614  (iterated_index == center_index ? big : small));
615  });
616  } else if (par.smearing() == SmearingMode::Triangular) {
617  // unweighted contribution to density
618  const double common_weight = dens_factor * prefactor_triangular;
620  pos, triangular_radius, [&](T &node, int ix, int iy, int iz) {
621  // compute the position of the node
622  const ThreeVector cell_center = lat->cell_center(ix, iy, iz);
623  // compute smearing weight
624  const double weight_x =
625  triangular_radius[0] - std::abs(cell_center[0] - pos[0]);
626  const double weight_y =
627  triangular_radius[1] - std::abs(cell_center[1] - pos[1]);
628  const double weight_z =
629  triangular_radius[2] - std::abs(cell_center[2] - pos[2]);
630  // add the contribution to the node
631  node.add_particle(part,
632  common_weight * weight_x * weight_y * weight_z);
633  });
634  }
635  } // end of for (const ParticleData &part : particles)
636  } // end of for (const Particles &particles : ensembles)
637 }
638 
658 void update_lattice(
659  RectangularLattice<DensityOnLattice> *lat,
660  RectangularLattice<FourVector> *old_jmu,
661  RectangularLattice<FourVector> *new_jmu,
662  RectangularLattice<std::array<FourVector, 4>> *four_grad_lattice,
663  const LatticeUpdate update, const DensityType dens_type,
664  const DensityParameters &par, const std::vector<Particles> &ensembles,
665  const double time_step, const bool compute_gradient);
666 } // namespace smash
667 
668 #endif // SRC_INCLUDE_SMASH_DENSITY_H_
A class for time-efficient (time-memory trade-off) calculation of density on the lattice.
Definition: density.h:310
std::array< FourVector, 4 > djmu_dxnu() const
Return the FourGradient of the net baryon current .
Definition: density.h:460
std::array< FourVector, 4 > djmu_dxnu_
Four-gradient of the four-current density, .
Definition: density.h:515
double rho(const double norm_factor=1.0)
Compute the net Eckart density on the local lattice.
Definition: density.h:379
ThreeVector grad_j0(const double norm_factor=1.0)
Compute gradient of the the zeroth component of the four-current j^mu (that is of the computational f...
Definition: density.h:405
void overwrite_djmu_dxnu(FourVector djmu_dt, FourVector djmu_dx, FourVector djmu_dy, FourVector djmu_dz)
Overwrite all density current derivatives to provided values.
Definition: density.h:501
ThreeVector grad_rho_cross_vecj() const
Compute the cross product of and .
Definition: density.h:466
void add_particle(const ParticleData &part, double FactorTimesSf)
Adds particle to 4-current: .
Definition: density.h:331
ThreeVector dvecj_dt(const double norm_factor=1.0)
Compute time derivative of the current density on the local lattice.
Definition: density.h:419
void add_to_jmu_pos(FourVector additional_jmu_B)
Add to the positive density current.
Definition: density.h:435
FourVector drho_dxnu_
Four-gradient of the rest frame density, .
Definition: density.h:517
void add_to_jmu_neg(FourVector additional_jmu_B)
Add to the negative density current.
Definition: density.h:443
void overwrite_drho_dxnu(FourVector computed_drho_dxnu)
Overwrite the rest frame density derivatives to provided values.
Definition: density.h:490
void overwrite_djmu_dt_to_zero()
Overwrite the time derivative of the current to zero.
Definition: density.h:477
FourVector jmu_pos_
Four-current density of the positively charged particle.
Definition: density.h:511
void overwrite_drho_dt_to_zero()
Overwrite the time derivative of the rest frame density to zero.
Definition: density.h:484
DensityOnLattice()
Default constructor.
Definition: density.h:313
ThreeVector curl_vecj(const double norm_factor=1.0)
Compute curl of the current on the local lattice.
Definition: density.h:389
FourVector jmu_net() const
Definition: density.h:429
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:352
FourVector drho_dxnu() const
Return the FourGradient of the rest frame density .
Definition: density.h:453
FourVector jmu_neg_
Four-current density of the negatively charged particle.
Definition: density.h:513
A class to pre-calculate and store parameters relevant for density calculation.
Definition: density.h:108
double r_cut_sqr_
Squared cut-off radius [fm ].
Definition: density.h:177
const double central_weight_
Weight of the central cell in the discrete smearing.
Definition: density.h:193
const double triangular_range_
Range of the triangular smearing.
Definition: density.h:195
const SmearingMode smearing_
Mode of smearing.
Definition: density.h:191
const int nensembles_
Number of ensembles.
Definition: density.h:185
double triangular_range() const
Definition: density.h:155
double r_cut() const
Definition: density.h:157
RestFrameDensityDerivativesMode rho_derivatives() const
Definition: density.h:147
SmearingMode smearing() const
Definition: density.h:151
const DerivativesMode derivatives_
Mode of calculating the gradients.
Definition: density.h:187
bool only_participants_
Flag to take into account only participants.
Definition: density.h:197
bool only_participants() const
Definition: density.h:169
const double sig_
Gaussian smearing width [fm].
Definition: density.h:173
DerivativesMode derivatives() const
Definition: density.h:145
double two_sig_sqr_inv() const
Definition: density.h:161
double central_weight() const
Definition: density.h:153
const RestFrameDensityDerivativesMode rho_derivatives_
Whether to calculate the rest frame density derivatives.
Definition: density.h:189
const int ntest_
Testparticle number.
Definition: density.h:183
double norm_factor_sf() const
Definition: density.h:167
int nensembles() const
Definition: density.h:143
double r_cut_sqr() const
Definition: density.h:159
const double r_cut_
Cut-off radius [fm].
Definition: density.h:175
double norm_factor_sf_
Normalization for Gaussian smearing factor.
Definition: density.h:181
DensityParameters(const ExperimentParameters &par)
Constructor of DensityParameters.
Definition: density.h:121
double two_sig_sqr_inv_
[fm ]
Definition: density.h:179
The FourVector class holds relevant values in Minkowski spacetime with (+, −, −, −) metric signature.
Definition: fourvector.h:33
double abs() const
calculate the lorentz invariant absolute value
Definition: fourvector.h:459
ThreeVector threevec() const
Definition: fourvector.h:324
ParticleData contains the dynamic information of a certain particle.
Definition: particledata.h:58
ThreeVector velocity() const
Get the velocity 3-vector.
Definition: particledata.h:301
The Particles class abstracts the storage and manipulation of particles.
Definition: particles.h:33
A container class to hold all the arrays on the lattice and access them.
Definition: lattice.h:47
void reset()
Sets all values on lattice to zeros.
Definition: lattice.h:104
LatticeUpdate when_update() const
Definition: lattice.h:169
ThreeVector cell_center(int ix, int iy, int iz) const
Find the coordinates of a given cell.
Definition: lattice.h:131
void iterate_in_cube(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 give...
Definition: lattice.h:617
void iterate_nearest_neighbors(const ThreeVector &point, F &&func)
Iterates only over nodes corresponding to the center cell (the cell containing the given point) and i...
Definition: lattice.h:727
void iterate_in_rectangle(const ThreeVector &point, const std::array< double, 3 > &rectangle, F &&func)
Iterates only nodes whose cell centers lie not further than d_x in x-, d_y in y-, and d_z in z-direct...
Definition: lattice.h:683
const std::array< double, 3 > & cell_sizes() const
Definition: lattice.h:160
The ThreeVector class represents a physical three-vector with the components .
Definition: threevector.h:31
void set_x1(double x)
set first component
Definition: threevector.h:167
void set_x3(double z)
set third component
Definition: threevector.h:175
void set_x2(double y)
set second component
Definition: threevector.h:171
ThreeVector cross_product(const ThreeVector &b) const
Definition: threevector.h:239
SmearingMode
Modes of smearing.
RestFrameDensityDerivativesMode
Modes of calculating the gradients: whether to calculate the rest frame density derivatives.
DerivativesMode
Modes of calculating the gradients.
std::ostream & operator<<(std::ostream &out, const ActionPtr &action)
Convenience: dereferences the ActionPtr to Action.
Definition: action.h:529
std::array< einhard::Logger<>, std::tuple_size< LogArea::AreaTuple >::value > logg
An array that stores all pre-configured Logger objects.
Definition: logging.cc:39
#define unlikely(x)
Tell the branch predictor that this expression is likely false.
Definition: macros.h:16
constexpr int p
Proton.
Definition: action.h:24
double smearing_factor_norm(const double two_sigma_sqr)
Norm of the Gaussian smearing function.
Definition: density.h:77
void update_lattice(RectangularLattice< T > *lat, const LatticeUpdate update, const DensityType dens_type, const DensityParameters &par, const std::vector< Particles > &ensembles, const bool compute_gradient)
Updates the contents on the lattice.
Definition: density.h:536
std::tuple< double, FourVector, ThreeVector, ThreeVector, FourVector, FourVector, FourVector, FourVector > current_eckart(const ThreeVector &r, const ParticleList &plist, const DensityParameters &par, DensityType dens_type, bool compute_gradient, bool smearing)
Definition: density.cc:167
void update_lattice(RectangularLattice< DensityOnLattice > *lat, RectangularLattice< FourVector > *old_jmu, RectangularLattice< FourVector > *new_jmu, RectangularLattice< std::array< FourVector, 4 >> *four_grad_lattice, const LatticeUpdate update, const DensityType dens_type, const DensityParameters &par, const std::vector< Particles > &ensembles, const double time_step, const bool compute_gradient)
Updates the contents on the lattice of DensityOnLattice type.
Definition: density.cc:182
LatticeUpdate
Enumerator option for lattice updates.
Definition: lattice.h:36
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:99
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
RectangularLattice< DensityOnLattice > DensityLattice
Conveniency typedef for lattice of density.
Definition: density.h:521
constexpr double really_small
Numerical error tolerance.
Definition: constants.h:37
DensityType
Allows to choose which kind of density to calculate.
Definition: density.h:36
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
static constexpr int LDensity
Definition: density.h:29
Helper structure for Experiment.
double gauss_cutoff_in_sigma
Distance at which gaussian is cut, i.e. set to zero, IN SIGMA (not fm)