Version: SMASH-3.1
density.h
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2014-2022
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 
277 current_eckart(const ThreeVector &r, const ParticleList &plist,
278  const DensityParameters &par, DensityType dens_type,
279  bool compute_gradient, bool smearing);
283 current_eckart(const ThreeVector &r, const Particles &plist,
284  const DensityParameters &par, DensityType dens_type,
285  bool compute_gradient, bool smearing);
286 
316  public:
319  : jmu_pos_(FourVector()),
320  jmu_neg_(FourVector()),
322  drho_dxnu_(FourVector()) {}
323 
336  void add_particle(const ParticleData &part, double FactorTimesSf) {
337  const FourVector part_four_velocity = FourVector(1.0, part.velocity());
338  if (FactorTimesSf > 0.0) {
339  jmu_pos_ += part_four_velocity * FactorTimesSf;
340  } else {
341  jmu_neg_ += part_four_velocity * FactorTimesSf;
342  }
343  }
344 
357  void add_particle_for_derivatives(const ParticleData &part, double factor,
358  ThreeVector sf_grad) {
359  const FourVector PartFourVelocity = FourVector(1.0, part.velocity());
360  for (int k = 1; k <= 3; k++) {
361  djmu_dxnu_[k] += factor * PartFourVelocity * sf_grad[k - 1];
362  djmu_dxnu_[0] -=
363  factor * PartFourVelocity * sf_grad[k - 1] * part.velocity()[k - 1];
364  }
365  }
366 
384  double rho(const double norm_factor = 1.0) {
385  return (jmu_pos_.abs() - jmu_neg_.abs()) * norm_factor;
386  }
387 
394  ThreeVector curl_vecj(const double norm_factor = 1.0) {
395  ThreeVector curl_vec_j = ThreeVector();
396  curl_vec_j.set_x1(djmu_dxnu_[2].x3() - djmu_dxnu_[3].x2());
397  curl_vec_j.set_x2(djmu_dxnu_[3].x1() - djmu_dxnu_[1].x3());
398  curl_vec_j.set_x3(djmu_dxnu_[1].x2() - djmu_dxnu_[2].x1());
399  curl_vec_j *= norm_factor;
400  return curl_vec_j;
401  }
402 
410  ThreeVector grad_j0(const double norm_factor = 1.0) {
411  ThreeVector j0_grad = ThreeVector();
412  for (int i = 1; i < 4; i++) {
413  j0_grad[i - 1] = djmu_dxnu_[i].x0() * norm_factor;
414  }
415  return j0_grad;
416  }
417 
424  ThreeVector dvecj_dt(const double norm_factor = 1.0) {
425  return djmu_dxnu_[0].threevec() * norm_factor;
426  }
427 
434  FourVector jmu_net() const { return jmu_pos_ + jmu_neg_; }
435 
440  void add_to_jmu_pos(FourVector additional_jmu_B) {
441  jmu_pos_ += additional_jmu_B;
442  }
443 
448  void add_to_jmu_neg(FourVector additional_jmu_B) {
449  jmu_neg_ += additional_jmu_B;
450  }
451 
458  FourVector drho_dxnu() const { return drho_dxnu_; }
459 
465  std::array<FourVector, 4> djmu_dxnu() const { return djmu_dxnu_; }
466 
473  const ThreeVector grad_rho = drho_dxnu_.threevec();
474  const ThreeVector vecj = jmu_net().threevec();
475  const ThreeVector Drho_cross_vecj = grad_rho.cross_product(vecj);
476 
477  return Drho_cross_vecj;
478  }
479 
484  djmu_dxnu_[0] = FourVector(0.0, 0.0, 0.0, 0.0);
485  }
486 
491 
496  void overwrite_drho_dxnu(FourVector computed_drho_dxnu) {
497  drho_dxnu_ = computed_drho_dxnu;
498  }
499 
508  FourVector djmu_dy, FourVector djmu_dz) {
509  djmu_dxnu_[0] = djmu_dt;
510  djmu_dxnu_[1] = djmu_dx;
511  djmu_dxnu_[2] = djmu_dy;
512  djmu_dxnu_[3] = djmu_dz;
513  }
514 
515  private:
521  std::array<FourVector, 4> djmu_dxnu_;
524 };
525 
528 
541 template <typename T>
543  const DensityType dens_type, const DensityParameters &par,
544  const std::vector<Particles> &ensembles,
545  const bool compute_gradient) {
546  // Do not proceed if lattice does not exists/update not required
547  if (lat == nullptr || lat->when_update() != update) {
548  return;
549  }
550 
551  lat->reset();
552  // get the normalization factor for the covariant Gaussian smearing
553  const double norm_factor_gaus = par.norm_factor_sf();
554  // get the volume of the cell and weights for discrete smearing
555  const double V_cell =
556  (lat->cell_sizes())[0] * (lat->cell_sizes())[1] * (lat->cell_sizes())[2];
557  // weights for coarse smearing
558  const double big = par.central_weight();
559  const double small = (1.0 - big) / 6.0;
560  // get the radii for triangular smearing
561  const std::array<double, 3> triangular_radius = {
562  par.triangular_range() * (lat->cell_sizes())[0],
563  par.triangular_range() * (lat->cell_sizes())[1],
564  par.triangular_range() * (lat->cell_sizes())[2]};
565  const double prefactor_triangular =
566  1.0 /
567  (par.ntest() * par.nensembles() * triangular_radius[0] *
568  triangular_radius[0] * triangular_radius[1] * triangular_radius[1] *
569  triangular_radius[2] * triangular_radius[2]);
570 
571  for (const Particles &particles : ensembles) {
572  for (const ParticleData &part : particles) {
573  if (par.only_participants()) {
574  // if this conditions holds, the hadron is a spectator
575  if (part.get_history().collisions_per_particle == 0) {
576  continue;
577  }
578  }
579  const double dens_factor = density_factor(part.type(), dens_type);
580  if (std::abs(dens_factor) < really_small) {
581  continue;
582  }
583  const FourVector p_mu = part.momentum();
584  const ThreeVector pos = part.position().threevec();
585 
586  // act accordingly to which smearing is used
588  const double m = p_mu.abs();
589  if (unlikely(m < really_small)) {
590  logg[LDensity].warn("Gaussian smearing is undefined for momentum ",
591  p_mu);
592  continue;
593  }
594  const double m_inv = 1.0 / m;
595 
596  // unweighted contribution to density
597  const double common_weight = dens_factor * norm_factor_gaus;
598  lat->iterate_in_cube(
599  pos, par.r_cut(), [&](T &node, int ix, int iy, int iz) {
600  // find the weight for smearing
601  const ThreeVector r = lat->cell_center(ix, iy, iz);
602  const auto sf = unnormalized_smearing_factor(
603  pos - r, p_mu, m_inv, par, compute_gradient);
604  node.add_particle(part, sf.first * common_weight);
605  if (par.derivatives() == DerivativesMode::CovariantGaussian) {
606  node.add_particle_for_derivatives(part, dens_factor,
607  sf.second * norm_factor_gaus);
608  }
609  });
610  } else if (par.smearing() == SmearingMode::Discrete) {
611  // unweighted contribution to density
612  const double common_weight =
613  dens_factor / (par.ntest() * par.nensembles() * V_cell);
615  pos, [&](T &node, int iterated_index, int center_index) {
616  node.add_particle(
617  part, common_weight *
618  // the contribution to density is weighted depending
619  // on what node it is added to
620  (iterated_index == center_index ? big : small));
621  });
622  } else if (par.smearing() == SmearingMode::Triangular) {
623  // unweighted contribution to density
624  const double common_weight = dens_factor * prefactor_triangular;
626  pos, triangular_radius, [&](T &node, int ix, int iy, int iz) {
627  // compute the position of the node
628  const ThreeVector cell_center = lat->cell_center(ix, iy, iz);
629  // compute smearing weight
630  const double weight_x =
631  triangular_radius[0] - std::abs(cell_center[0] - pos[0]);
632  const double weight_y =
633  triangular_radius[1] - std::abs(cell_center[1] - pos[1]);
634  const double weight_z =
635  triangular_radius[2] - std::abs(cell_center[2] - pos[2]);
636  // add the contribution to the node
637  node.add_particle(part,
638  common_weight * weight_x * weight_y * weight_z);
639  });
640  }
641  } // end of for (const ParticleData &part : particles)
642  } // end of for (const Particles &particles : ensembles)
643 }
644 
664 void update_lattice(
665  RectangularLattice<DensityOnLattice> *lat,
666  RectangularLattice<FourVector> *old_jmu,
667  RectangularLattice<FourVector> *new_jmu,
668  RectangularLattice<std::array<FourVector, 4>> *four_grad_lattice,
669  const LatticeUpdate update, const DensityType dens_type,
670  const DensityParameters &par, const std::vector<Particles> &ensembles,
671  const double time_step, const bool compute_gradient);
672 } // namespace smash
673 
674 #endif // SRC_INCLUDE_SMASH_DENSITY_H_
A class for time-efficient (time-memory trade-off) calculation of density on the lattice.
Definition: density.h:315
std::array< FourVector, 4 > djmu_dxnu() const
Return the FourGradient of the net baryon current .
Definition: density.h:465
std::array< FourVector, 4 > djmu_dxnu_
Four-gradient of the four-current density, .
Definition: density.h:521
double rho(const double norm_factor=1.0)
Compute the net Eckart density on the local lattice.
Definition: density.h:384
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:410
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:507
ThreeVector grad_rho_cross_vecj() const
Compute the cross product of and .
Definition: density.h:472
void add_particle(const ParticleData &part, double FactorTimesSf)
Adds particle to 4-current: .
Definition: density.h:336
ThreeVector dvecj_dt(const double norm_factor=1.0)
Compute time derivative of the current density on the local lattice.
Definition: density.h:424
void add_to_jmu_pos(FourVector additional_jmu_B)
Add to the positive density current.
Definition: density.h:440
FourVector drho_dxnu_
Four-gradient of the rest frame density, .
Definition: density.h:523
void add_to_jmu_neg(FourVector additional_jmu_B)
Add to the negative density current.
Definition: density.h:448
void overwrite_drho_dxnu(FourVector computed_drho_dxnu)
Overwrite the rest frame density derivatives to provided values.
Definition: density.h:496
void overwrite_djmu_dt_to_zero()
Overwrite the time derivative of the current to zero.
Definition: density.h:483
FourVector jmu_pos_
Four-current density of the positively charged particle.
Definition: density.h:517
void overwrite_drho_dt_to_zero()
Overwrite the time derivative of the rest frame density to zero.
Definition: density.h:490
DensityOnLattice()
Default constructor.
Definition: density.h:318
ThreeVector curl_vecj(const double norm_factor=1.0)
Compute curl of the current on the local lattice.
Definition: density.h:394
FourVector jmu_net() const
Definition: density.h:434
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:357
FourVector drho_dxnu() const
Return the FourGradient of the rest frame density .
Definition: density.h:458
FourVector jmu_neg_
Four-current density of the negatively charged particle.
Definition: density.h:519
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:464
ThreeVector threevec() const
Definition: fourvector.h:329
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:179
void set_x3(double z)
set third component
Definition: threevector.h:187
void set_x2(double y)
set second component
Definition: threevector.h:183
ThreeVector cross_product(const ThreeVector &b) const
Definition: threevector.h:246
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:547
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:542
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)
Calculates Eckart rest frame density and 4-current of a given density type and optionally the gradien...
Definition: density.cc:171
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:186
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:38
RectangularLattice< DensityOnLattice > DensityLattice
Conveniency typedef for lattice of density.
Definition: density.h:527
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:17
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)