Version: SMASH-3.1
potentials.h
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2014-2015,2017-2024
4  * SMASH Team
5  *
6  * GNU General Public License (GPLv3 or later)
7  *
8  */
9 
10 #ifndef SRC_INCLUDE_SMASH_POTENTIALS_H_
11 #define SRC_INCLUDE_SMASH_POTENTIALS_H_
12 
13 #include <tuple>
14 #include <utility>
15 #include <vector>
16 
17 #include "gsl/gsl_multiroots.h"
18 #include "gsl/gsl_vector.h"
19 
20 #include "configuration.h"
21 #include "density.h"
22 #include "forwarddeclarations.h"
23 #include "particledata.h"
24 #include "rootsolver.h"
25 #include "threevector.h"
26 
27 namespace smash {
28 static constexpr int LPotentials = LogArea::Potentials::id;
36 class Potentials {
37  public:
49  Potentials(Configuration conf, const DensityParameters &parameters);
51  virtual ~Potentials();
52 
66  const ThreeVector &position,
67  const ThreeVector &momentum,
68  double mass,
69  ParticleList &plist) const {
70  const std::array<double, 3> dr = (jB_lattice)
71  ? jB_lattice->cell_sizes()
72  : std::array<double, 3>{0.1, 0.1, 0.1};
73  ThreeVector result, position_left, position_right;
74  DensityOnLattice jmu_left, jmu_right;
75  FourVector net_4current_left, net_4current_right;
76  for (int i = 0; i < 3; i++) {
77  position_left = position;
78  position_left[i] -= dr[i];
79  position_right = position;
80  position_right[i] += dr[i];
81 
82  if (jB_lattice && jB_lattice->value_at(position_left, jmu_left)) {
83  net_4current_left = jmu_left.jmu_net();
85  auto current = current_eckart(position_left, plist, param_,
86  DensityType::Baryon, false, true);
87  net_4current_left = std::get<1>(current);
88  } else {
89  return {0., 0., 0.};
90  }
91 
92  if (jB_lattice && jB_lattice->value_at(position_right, jmu_right)) {
93  net_4current_right = jmu_right.jmu_net();
95  auto current = current_eckart(position_right, plist, param_,
96  DensityType::Baryon, false, true);
97  net_4current_right = std::get<1>(current);
98  } else {
99  return {0., 0., 0.};
100  }
101  result[i] =
102  (calculation_frame_energy(momentum, net_4current_right, mass) -
103  calculation_frame_energy(momentum, net_4current_left, mass)) /
104  (2 * dr[i]);
105  }
106  return result;
107  }
108 
118  double calculation_frame_energy(const ThreeVector &momentum,
119  const FourVector &jmu_B, double mass) const {
120  std::function<double(double)> root_equation = [momentum, jmu_B, mass,
121  this](double energy) {
122  return root_eq_potentials(energy, momentum, jmu_B, mass, skyrme_a_,
125  };
126  RootSolver1D root_solver{root_equation};
127  const std::array<double, 4> starting_interval_width = {0.1, 1.0, 10.0,
128  100.0};
129  for (double width : starting_interval_width) {
130  const double initial_guess = std::sqrt(mass * mass + momentum * momentum);
131  auto calc_frame_energy = root_solver.try_find_root(
132  initial_guess - width / 2, initial_guess + width / 2, 100000);
133  if (calc_frame_energy) {
134  return *calc_frame_energy;
135  } else {
136  logg[LPotentials].debug()
137  << "Did not find a root for potentials in the interval ["
138  << initial_guess - width / 2 << " GeV ,"
139  << initial_guess + width / 2 << " GeV]. Trying a wider interval";
140  }
141  }
142  logg[LPotentials].debug(
143  "Root for potentials was not found in any of the intervals "
144  "tried.");
145  throw std::runtime_error(
146  "Failed to find root for momentum-dependent potentials");
147  }
148 
157  double skyrme_pot(const double baryon_density) const {
158  return skyrme_pot(baryon_density, skyrme_a_, skyrme_b_, skyrme_tau_);
159  }
160 
174  double symmetry_pot(const double baryon_isospin_density,
175  const double baryon_density) const;
176 
183  double symmetry_S(const double baryon_density) const;
184 
196  FourVector vdf_pot(double rhoB, const FourVector jmuB_net) const;
197 
218  double potential(const ThreeVector &r, const ParticleList &plist,
219  const ParticleType &acts_on) const;
220 
237  static std::pair<double, int> force_scale(const ParticleType &data);
238 
261  std::pair<ThreeVector, ThreeVector> skyrme_force(
262  const double rhoB, const ThreeVector grad_j0B,
263  const ThreeVector dvecjB_dt, const ThreeVector curl_vecjB) const;
264 
300  std::pair<ThreeVector, ThreeVector> symmetry_force(
301  const double rhoI3, const ThreeVector grad_j0I3,
302  const ThreeVector dvecjI3_dt, const ThreeVector curl_vecjI3,
303  const double rhoB, const ThreeVector grad_j0B,
304  const ThreeVector dvecjB_dt, const ThreeVector curl_vecjB) const;
305 
321  DensityOnLattice &charge_density,
322  ThreeVector point) {
323  ThreeVector dr = point - pos;
324  if (dr.abs() < really_small) {
325  return {0., 0., 0.};
326  }
327  return elementary_charge * charge_density.rho() * dr /
328  std::pow(dr.abs(), 3);
329  }
330 
339  DensityOnLattice &charge_density,
340  ThreeVector point) {
341  ThreeVector dr = point - pos;
342  if (dr.abs() < really_small) {
343  return {0., 0., 0.};
344  }
345  return elementary_charge *
346  charge_density.jmu_net().threevec().cross_product(dr) /
347  std::pow(dr.abs(), 3);
348  }
387  std::pair<ThreeVector, ThreeVector> vdf_force(
388  double rhoB, const double drhoB_dt, const ThreeVector grad_rhoB,
389  const ThreeVector gradrhoB_cross_vecjB, const double j0B,
390  const ThreeVector grad_j0B, const ThreeVector vecjB,
391  const ThreeVector dvecjB_dt, const ThreeVector curl_vecjB) const;
392 
410  std::pair<ThreeVector, ThreeVector> vdf_force(
411  const ThreeVector grad_A_0, const ThreeVector dA_dt,
412  const ThreeVector curl_vecA) const;
413 
429  virtual std::tuple<ThreeVector, ThreeVector, ThreeVector, ThreeVector>
430  all_forces(const ThreeVector &r, const ParticleList &plist) const;
431 
433  virtual bool use_skyrme() const { return use_skyrme_; }
435  virtual bool use_symmetry() const { return use_symmetry_; }
437  virtual bool use_coulomb() const { return use_coulomb_; }
439  virtual bool use_momentum_dependence() const {
441  }
442 
444  double skyrme_a() const { return skyrme_a_; }
446  double skyrme_b() const { return skyrme_b_; }
448  double skyrme_tau() const { return skyrme_tau_; }
450  double symmetry_S_pot() const { return symmetry_S_Pot_; }
451 
453  virtual bool use_vdf() const { return use_vdf_; }
455  double saturation_density() const { return saturation_density_; }
457  const std::vector<double> &coeffs() const { return coeffs_; }
459  const std::vector<double> &powers() const { return powers_; }
461  int number_of_terms() const { return powers_.size(); }
462 
464  double coulomb_r_cut() const { return coulomb_r_cut_; }
465 
472  }
473 
474  private:
481 
484 
487 
490 
492  bool use_vdf_;
493 
496 
501  double skyrme_a_;
502 
507  double skyrme_b_;
508 
513  double skyrme_tau_;
514 
520 
526 
529 
542 
545 
548 
555  std::vector<double> coeffs_;
557  std::vector<double> powers_;
558 
574  double dVsym_drhoI3(const double rhoB, const double rhoI3) const;
575 
594  double dVsym_drhoB(const double rhoB, const double rhoI3) const;
595 
605  static double skyrme_pot(const double baryon_density, const double A,
606  const double B, const double tau);
607 
634  static double root_eq_potentials(double energy_calc,
635  const ThreeVector &momentum_calc,
636  const FourVector &jmu, double m, double A,
637  double B, double tau, double C,
638  double Lambda) {
639  // get velocity for boost to the local rest frame
640  double rho_LRF = jmu.abs();
641  ThreeVector beta_LRF = jmu.x0() > really_small ? jmu.threevec() / jmu.x0()
642  : ThreeVector(0, 0, 0);
643  // get momentum in the local rest frame
644  FourVector pmu_calc = FourVector(energy_calc, momentum_calc);
645  FourVector pmu_LRF = beta_LRF.abs() > really_small
646  ? pmu_calc.lorentz_boost(beta_LRF)
647  : pmu_calc;
648  double p_LRF = pmu_LRF.threevec().abs();
649  double energy_LRF = std::sqrt(m * m + p_LRF * p_LRF) +
650  skyrme_pot(rho_LRF, A, B, tau) +
651  momentum_dependent_part(p_LRF, rho_LRF, C, Lambda);
652  const double result = energy_calc * energy_calc - momentum_calc.sqr() -
653  (energy_LRF * energy_LRF - p_LRF * p_LRF);
654  logg[LPotentials].debug()
655  << "root equation for potentials called with E_calc=" << energy_calc
656  << " p_calc=" << momentum_calc << " jmu=" << jmu << " m=" << m
657  << " tau=" << tau << " A=" << A << " B=" << B << " C=" << C
658  << " Lambda=" << Lambda << " and the root equation is " << result;
659  return result;
660  }
661 
676  static double momentum_dependent_part(double momentum, double rho, double C,
677  double Lambda) {
678  /* We assume here that the distribution function is the one of cold
679  * nuclear matter, which consists only of protons and neutrons.
680  * That is, the degeneracy factor simply equals nucleon spin degeneracy
681  * times nucleon isospin degeneracy, even though all baryons contribute
682  * to the density and the potential is applied to all baryons. */
683  int g = 4;
684  const double fermi_momentum =
685  std::cbrt(6. * M_PI * M_PI * rho / g); // in 1/fm
686  momentum = momentum / hbarc; // convert to 1/fm
687  if (unlikely(momentum < really_small)) {
688  return mev_to_gev * g * C / (M_PI * M_PI * nuclear_density) *
689  (Lambda * Lambda * fermi_momentum -
690  std::pow(Lambda, 3) * std::atan(fermi_momentum / Lambda));
691  }
692  const std::array<double, 7> temp = {
693  2 * g * C * M_PI * std::pow(Lambda, 3) /
694  (std::pow(2 * M_PI, 3) * nuclear_density),
695  (fermi_momentum * fermi_momentum + Lambda * Lambda -
696  momentum * momentum) /
697  (2 * momentum * Lambda),
698  std::pow(momentum + fermi_momentum, 2) + Lambda * Lambda,
699  std::pow(momentum - fermi_momentum, 2) + Lambda * Lambda,
700  2 * fermi_momentum / Lambda,
701  (momentum + fermi_momentum) / Lambda,
702  (momentum - fermi_momentum) / Lambda};
703  const double result =
704  temp[0] * (temp[1] * std::log(temp[2] / temp[3]) + temp[4] -
705  2 * (std::atan(temp[5]) - std::atan(temp[6])));
706  return mev_to_gev * result;
707  }
708 };
709 
710 } // namespace smash
711 
712 #endif // SRC_INCLUDE_SMASH_POTENTIALS_H_
Interface to the SMASH configuration files.
A class for time-efficient (time-memory trade-off) calculation of density on the lattice.
Definition: density.h:315
double rho(const double norm_factor=1.0)
Compute the net Eckart density on the local lattice.
Definition: density.h:384
FourVector jmu_net() const
Definition: density.h:434
A class to pre-calculate and store parameters relevant for density calculation.
Definition: density.h:108
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
FourVector lorentz_boost(const ThreeVector &v) const
Returns the FourVector boosted with velocity v.
Definition: fourvector.cc:17
ThreeVector threevec() const
Definition: fourvector.h:329
double x0() const
Definition: fourvector.h:313
Particle type contains the static properties of a particle species.
Definition: particletype.h:98
A class that stores parameters of potentials, calculates potentials and their gradients.
Definition: potentials.h:36
const std::vector< double > & powers() const
Definition: potentials.h:459
static double momentum_dependent_part(double momentum, double rho, double C, double Lambda)
Momentum dependent term of the potential.
Definition: potentials.h:676
bool use_skyrme_
Skyrme potential on/off.
Definition: potentials.h:483
bool use_symmetry_
Symmetry potential on/off.
Definition: potentials.h:486
double skyrme_pot(const double baryon_density) const
Evaluates Skyrme potential given a baryon density.
Definition: potentials.h:157
static double root_eq_potentials(double energy_calc, const ThreeVector &momentum_calc, const FourVector &jmu, double m, double A, double B, double tau, double C, double Lambda)
Root equation used to determine the energy in the calculation frame.
Definition: potentials.h:634
virtual bool use_symmetry() const
Definition: potentials.h:435
double symmetry_pot(const double baryon_isospin_density, const double baryon_density) const
Evaluates symmetry potential given baryon isospin density.
Definition: potentials.cc:90
double mom_dependence_C_
Parameter C of the momentum-dependent part of the potentials given in MeV.
Definition: potentials.h:525
ThreeVector single_particle_energy_gradient(DensityLattice *jB_lattice, const ThreeVector &position, const ThreeVector &momentum, double mass, ParticleList &plist) const
Calculates the gradient of the single-particle energy (including potentials) in the calculation frame...
Definition: potentials.h:65
const std::vector< double > & coeffs() const
Definition: potentials.h:457
static ThreeVector B_field_integrand(ThreeVector pos, DensityOnLattice &charge_density, ThreeVector point)
Integrand for calculating the magnetic field using the Biot-Savart formula.
Definition: potentials.h:338
static ThreeVector E_field_integrand(ThreeVector pos, DensityOnLattice &charge_density, ThreeVector point)
Integrand for calculating the electric field.
Definition: potentials.h:320
std::pair< ThreeVector, ThreeVector > symmetry_force(const double rhoI3, const ThreeVector grad_j0I3, const ThreeVector dvecjI3_dt, const ThreeVector curl_vecjI3, const double rhoB, const ThreeVector grad_j0B, const ThreeVector dvecjB_dt, const ThreeVector curl_vecjB) const
Evaluates the electric and magnetic components of the symmetry force.
Definition: potentials.cc:182
double calculation_frame_energy(const ThreeVector &momentum, const FourVector &jmu_B, double mass) const
Evaluates the single-particle energy (including the potential) of a particle at a given position and ...
Definition: potentials.h:118
virtual bool use_skyrme() const
Definition: potentials.h:433
double potential(const ThreeVector &r, const ParticleList &plist, const ParticleType &acts_on) const
Evaluates potential (Skyrme with optional Symmetry or VDF) at point r.
Definition: potentials.cc:123
FourVector vdf_pot(double rhoB, const FourVector jmuB_net) const
Evaluates the FourVector potential in the VDF model given the rest frame density and the computationa...
Definition: potentials.cc:101
bool use_potentials_outside_lattice() const
Definition: potentials.h:470
std::vector< double > powers_
Parameters of the VDF potential: exponents .
Definition: potentials.h:557
bool use_potentials_outside_lattice_
Wether potentials should be included outside of the lattice.
Definition: potentials.h:547
double dVsym_drhoB(const double rhoB, const double rhoI3) const
Calculate the derivative of the symmetry potential with respect to the net baryon density in GeV * fm...
Definition: potentials.cc:258
virtual bool use_coulomb() const
Definition: potentials.h:437
double skyrme_a() const
Definition: potentials.h:444
double symmetry_S(const double baryon_density) const
Calculate the factor in the symmetry potential.
Definition: potentials.cc:82
double symmetry_S_Pot_
Parameter S_Pot in the symmetry potential in MeV.
Definition: potentials.h:528
double skyrme_a_
Parameter of skyrme potentials: the coefficient in front of in GeV.
Definition: potentials.h:501
std::vector< double > coeffs_
Parameters of the VDF potential: coefficients , in GeV.
Definition: potentials.h:555
std::pair< ThreeVector, ThreeVector > vdf_force(double rhoB, const double drhoB_dt, const ThreeVector grad_rhoB, const ThreeVector gradrhoB_cross_vecjB, const double j0B, const ThreeVector grad_j0B, const ThreeVector vecjB, const ThreeVector dvecjB_dt, const ThreeVector curl_vecjB) const
Evaluates the electric and magnetic components of force in the VDF model given the derivatives of the...
Definition: potentials.cc:197
double skyrme_tau() const
Definition: potentials.h:448
double mom_dependence_Lambda_
Parameter Lambda of the momentum-dependent part of the potentials given in 1/fm.
Definition: potentials.h:519
bool use_momentum_dependence_
Momentum-dependent part on/off.
Definition: potentials.h:495
double coulomb_r_cut() const
Definition: potentials.h:464
double skyrme_tau_
Parameters of skyrme potentials: the power index.
Definition: potentials.h:513
double symmetry_S_pot() const
Definition: potentials.h:450
Potentials(Configuration conf, const DensityParameters &parameters)
Potentials constructor.
Definition: potentials.cc:18
double dVsym_drhoI3(const double rhoB, const double rhoI3) const
Calculate the derivative of the symmetry potential with respect to the isospin density in GeV * fm^3.
Definition: potentials.cc:248
int number_of_terms() const
Definition: potentials.h:461
static std::pair< double, int > force_scale(const ParticleType &data)
Evaluates the scaling factor of the forces acting on the particles.
Definition: potentials.cc:156
std::pair< ThreeVector, ThreeVector > skyrme_force(const double rhoB, const ThreeVector grad_j0B, const ThreeVector dvecjB_dt, const ThreeVector curl_vecjB) const
Evaluates the electric and magnetic components of the skyrme force.
Definition: potentials.cc:164
virtual std::tuple< ThreeVector, ThreeVector, ThreeVector, ThreeVector > all_forces(const ThreeVector &r, const ParticleList &plist) const
Evaluates the electric and magnetic components of the forces at point r.
Definition: potentials.cc:272
double skyrme_b() const
Definition: potentials.h:446
bool use_coulomb_
Coulomb potential on/Off.
Definition: potentials.h:489
double symmetry_gamma_
Power in formula for :
Definition: potentials.h:541
bool symmetry_is_rhoB_dependent_
Whether the baryon density dependence of the symmetry potential is included.
Definition: potentials.h:534
double coulomb_r_cut_
Cutoff in integration for coulomb potential.
Definition: potentials.h:544
virtual bool use_vdf() const
Definition: potentials.h:453
const DensityParameters param_
Struct that contains the gaussian smearing width , the distance cutoff and the testparticle number n...
Definition: potentials.h:480
double saturation_density() const
Definition: potentials.h:455
bool use_vdf_
VDF potential on/off.
Definition: potentials.h:492
double saturation_density_
Saturation density of nuclear matter used in the VDF potential; it may vary between different paramet...
Definition: potentials.h:553
virtual bool use_momentum_dependence() const
Definition: potentials.h:439
virtual ~Potentials()
Standard destructor.
Definition: potentials.cc:69
double skyrme_b_
Parameters of skyrme potentials: the coefficient in front of in GeV.
Definition: potentials.h:507
A container class to hold all the arrays on the lattice and access them.
Definition: lattice.h:47
bool value_at(const ThreeVector &r, T &value)
Interpolates lattice quantity to coordinate r.
Definition: lattice.h:547
const std::array< double, 3 > & cell_sizes() const
Definition: lattice.h:160
A class used for calculating the root of a one-dimensional equation.
Definition: rootsolver.h:30
The ThreeVector class represents a physical three-vector with the components .
Definition: threevector.h:31
double abs() const
Definition: threevector.h:268
double sqr() const
Definition: threevector.h:266
ThreeVector cross_product(const ThreeVector &b) const
Definition: threevector.h:246
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 Lambda
Λ.
Definition: action.h:24
constexpr double mev_to_gev
MeV to GeV conversion factor.
Definition: constants.h:34
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
static constexpr int LPotentials
Definition: potentials.h:28
constexpr double nuclear_density
Ground state density of symmetric nuclear matter [fm^-3].
Definition: constants.h:48
constexpr double hbarc
GeV <-> fm conversion factor.
Definition: constants.h:25
constexpr double really_small
Numerical error tolerance.
Definition: constants.h:37
const double elementary_charge
Elementary electric charge in natural units, approximately 0.3.
Definition: constants.h:98