Version: SMASH-3.4
potentials.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2014-2015,2017-2024,2026
4  * SMASH Team
5  *
6  * GNU General Public License (GPLv3 or later)
7  *
8  */
9 
10 #include "smash/potentials.h"
11 
12 #include <algorithm>
13 
14 #include "smash/constants.h"
15 #include "smash/density.h"
16 #include "smash/input_keys.h"
17 
18 namespace smash {
19 
21  : param_(param),
22  use_skyrme_(conf.has_section(InputSections::p_skyrme)),
23  use_symmetry_(conf.has_section(InputSections::p_symmetry)),
24  use_coulomb_(conf.has_section(InputSections::p_coulomb)),
25  use_vdf_(conf.has_section(InputSections::p_vdf)),
26  use_momentum_dependence_(
27  conf.has_section(InputSections::p_momentumDependence)),
28  use_potentials_outside_lattice_(
29  conf.take(InputKeys::potentials_use_potentials_outside_lattice)) {
30  if (use_skyrme_) {
34  }
39  }
40 
41  if (use_symmetry_) {
46  }
47  }
48  if (use_coulomb_) {
50  }
51  if (use_vdf_) {
55  if (coeffs_.size() != powers_.size()) {
56  throw std::invalid_argument(
57  "The number of coefficients should equal the number of powers.");
58  }
59  // coefficients are provided in MeV, but the code uses GeV
60  std::transform(coeffs_.cbegin(), coeffs_.cend(), coeffs_.begin(),
61  [](double c) { return c * mev_to_gev; });
62  }
63 }
64 
66 
67 double Potentials::skyrme_pot(const double baryon_density, const double A,
68  const double B, const double tau) {
69  const double tmp = baryon_density / nuclear_density;
70  /* U = U(|rho|) * sgn , because the sign of the potential changes
71  * under a charge reversal transformation. */
72  const int sgn = tmp > 0 ? 1 : -1;
73  // Return in GeV
74  return mev_to_gev * sgn *
75  (A * std::abs(tmp) + B * std::pow(std::abs(tmp), tau));
76 }
77 
78 double Potentials::symmetry_S(const double baryon_density) const {
80  return 12.3 * std::pow(baryon_density / nuclear_density, 2. / 3.) +
81  20.0 * std::pow(baryon_density / nuclear_density, symmetry_gamma_);
82  } else {
83  return 0.;
84  }
85 }
86 double Potentials::symmetry_pot(const double baryon_isospin_density,
87  const double baryon_density) const {
88  double pot = mev_to_gev * 2. * symmetry_S_Pot_ * baryon_isospin_density /
91  pot += mev_to_gev * symmetry_S(baryon_density) * baryon_isospin_density *
92  baryon_isospin_density / (baryon_density * baryon_density);
93  }
94  return pot;
95 }
96 
97 FourVector Potentials::vdf_pot(double rhoB, const FourVector jmuB_net) const {
98  // this needs to be used in order to prevent trying to calculate something
99  // like
100  // (-rho_B)^{3.4}
101  const int sgn = rhoB > 0 ? 1 : -1;
102  double abs_rhoB = std::abs(rhoB);
103  // to prevent NAN expressions
104  if (abs_rhoB < very_small_double) {
105  abs_rhoB = very_small_double;
106  }
107  // F_2 is a multiplicative factor in front of the baryon current
108  // in the VDF potential
109  double F_2 = 0.0;
110  for (int i = 0; i < number_of_terms(); i++) {
111  F_2 += coeffs_[i] * std::pow(abs_rhoB, powers_[i] - 2.0) /
112  std::pow(saturation_density_, powers_[i] - 1.0);
113  }
114  F_2 = F_2 * sgn;
115  // Return in GeV
116  return F_2 * jmuB_net;
117 }
118 
119 double Potentials::potential(const ThreeVector &r, const ParticleList &plist,
120  const ParticleType &acts_on) const {
121  double total_potential = 0.0;
122  const bool compute_gradient = false;
123  const bool smearing = true;
124  const auto scale = force_scale(acts_on);
125 
126  if (!(acts_on.is_baryon() || acts_on.is_nucleus())) {
127  return total_potential;
128  }
129  const auto baryon_density_and_gradient = current_eckart(
130  r, plist, param_, DensityType::Baryon, compute_gradient, smearing);
131  const double rhoB = std::get<0>(baryon_density_and_gradient);
132  if (use_skyrme_) {
133  total_potential += scale.first * skyrme_pot(rhoB);
134  }
135  if (use_symmetry_) {
136  const double rho_iso = std::get<0>(
138  compute_gradient, smearing));
139  const double sym_pot = symmetry_pot(rho_iso, rhoB) * acts_on.isospin3_rel();
140  total_potential += scale.second * sym_pot;
141  }
142 
143  if (use_vdf_) {
144  const FourVector jmuB = std::get<1>(baryon_density_and_gradient);
145  const FourVector VDF_potential = vdf_pot(rhoB, jmuB);
146  total_potential += scale.first * VDF_potential.x0();
147  }
148 
149  return total_potential;
150 }
151 
152 std::pair<double, int> Potentials::force_scale(const ParticleType &data) {
153  const auto &pdg = data.pdgcode();
154  const double skyrme_or_VDF_scale =
155  (3 - std::abs(pdg.strangeness())) / 3. * pdg.baryon_number();
156  const int symmetry_scale = pdg.baryon_number();
157  return std::make_pair(skyrme_or_VDF_scale, symmetry_scale);
158 }
159 
160 std::pair<ThreeVector, ThreeVector> Potentials::skyrme_force(
161  const double rhoB, const ThreeVector grad_j0B, const ThreeVector dvecjB_dt,
162  const ThreeVector curl_vecjB) const {
163  ThreeVector E_component(0.0, 0.0, 0.0), B_component(0.0, 0.0, 0.0);
164  if (use_skyrme_) {
165  const int sgn = rhoB > 0 ? 1 : -1;
166  const double abs_rhoB = std::abs(rhoB);
167  const double dV_drho = sgn *
169  std::pow(abs_rhoB / nuclear_density,
170  skyrme_tau_ - 1)) *
172  E_component -= dV_drho * (grad_j0B + dvecjB_dt);
173  B_component += dV_drho * curl_vecjB;
174  }
175  return std::make_pair(E_component, B_component);
176 }
177 
178 std::pair<ThreeVector, ThreeVector> Potentials::symmetry_force(
179  const double rhoI3, const ThreeVector grad_j0I3,
180  const ThreeVector dvecjI3_dt, const ThreeVector curl_vecjI3,
181  const double rhoB, const ThreeVector grad_j0B, const ThreeVector dvecjB_dt,
182  const ThreeVector curl_vecjB) const {
183  ThreeVector E_component(0.0, 0.0, 0.0), B_component(0.0, 0.0, 0.0);
184  if (use_symmetry_) {
185  E_component -= dVsym_drhoI3(rhoB, rhoI3) * (grad_j0I3 + dvecjI3_dt) +
186  dVsym_drhoB(rhoB, rhoI3) * (grad_j0B + dvecjB_dt);
187  B_component += dVsym_drhoI3(rhoB, rhoI3) * curl_vecjI3 +
188  dVsym_drhoB(rhoB, rhoI3) * curl_vecjB;
189  }
190  return std::make_pair(E_component, B_component);
191 }
192 
193 std::pair<ThreeVector, ThreeVector> Potentials::vdf_force(
194  double rhoB, const double drhoB_dt, const ThreeVector grad_rhoB,
195  const ThreeVector gradrhoB_cross_vecjB, const double j0B,
196  const ThreeVector grad_j0B, const ThreeVector vecjB,
197  const ThreeVector dvecjB_dt, const ThreeVector curl_vecjB) const {
198  // this needs to be used to prevent trying to calculate something like
199  // (-rhoB)^{3.4}
200  const int sgn = rhoB > 0 ? 1 : -1;
201  ThreeVector E_component(0.0, 0.0, 0.0), B_component(0.0, 0.0, 0.0);
202  // to prevent NAN expressions
203  double abs_rhoB = std::abs(rhoB);
204  if (abs_rhoB < very_small_double) {
205  abs_rhoB = very_small_double;
206  }
207  if (use_vdf_) {
208  // F_1 and F_2 are multiplicative factors in front of the baryon current
209  // in the VDF potential
210  double F_1 = 0.0;
211  for (int i = 0; i < number_of_terms(); i++) {
212  F_1 += coeffs_[i] * (powers_[i] - 2.0) *
213  std::pow(abs_rhoB, powers_[i] - 3.0) /
214  std::pow(saturation_density_, powers_[i] - 1.0);
215  }
216  F_1 = F_1 * sgn;
217 
218  double F_2 = 0.0;
219  for (int i = 0; i < number_of_terms(); i++) {
220  F_2 += coeffs_[i] * std::pow(abs_rhoB, powers_[i] - 2.0) /
221  std::pow(saturation_density_, powers_[i] - 1.0);
222  }
223  F_2 = F_2 * sgn;
224 
225  E_component -= (F_1 * (grad_rhoB * j0B + drhoB_dt * vecjB) +
226  F_2 * (grad_j0B + dvecjB_dt));
227  B_component += F_1 * gradrhoB_cross_vecjB + F_2 * curl_vecjB;
228  }
229  return std::make_pair(E_component, B_component);
230 }
231 
232 // overload of the above
233 std::pair<ThreeVector, ThreeVector> Potentials::vdf_force(
234  const ThreeVector grad_A_0, const ThreeVector dA_dt,
235  const ThreeVector curl_A) const {
236  ThreeVector E_component(0.0, 0.0, 0.0), B_component(0.0, 0.0, 0.0);
237  if (use_vdf_) {
238  E_component -= (grad_A_0 + dA_dt);
239  B_component += curl_A;
240  }
241  return std::make_pair(E_component, B_component);
242 }
243 
244 double Potentials::dVsym_drhoI3(const double rhoB, const double rhoI3) const {
245  double term1 = 2. * symmetry_S_Pot_ / nuclear_density;
247  double term2 = 2. * rhoI3 * symmetry_S(rhoB) / (rhoB * rhoB);
248  return mev_to_gev * (term1 + term2);
249  } else {
250  return mev_to_gev * term1;
251  }
252 }
253 
254 double Potentials::dVsym_drhoB(const double rhoB, const double rhoI3) const {
256  double rhoB_over_rho0 = rhoB / nuclear_density;
257  double term1 = 8.2 * std::pow(rhoB_over_rho0, -1. / 3.) / nuclear_density +
258  20. * symmetry_gamma_ *
259  std::pow(rhoB_over_rho0, symmetry_gamma_) / rhoB;
260  double term2 = -2. * symmetry_S(rhoB) / rhoB;
261  return mev_to_gev * (term1 + term2) * rhoI3 * rhoI3 / (rhoB * rhoB);
262  } else {
263  return 0.;
264  }
265 }
266 
267 std::tuple<ThreeVector, ThreeVector, ThreeVector, ThreeVector>
268 Potentials::all_forces(const ThreeVector &r, const ParticleList &plist) const {
269  const bool compute_gradient = true;
270  const bool smearing = true;
271  auto F_skyrme_or_VDF =
272  std::make_pair(ThreeVector(0., 0., 0.), ThreeVector(0., 0., 0.));
273  auto F_symmetry =
274  std::make_pair(ThreeVector(0., 0., 0.), ThreeVector(0., 0., 0.));
275 
276  const auto baryon_density_and_gradient = current_eckart(
277  r, plist, param_, DensityType::Baryon, compute_gradient, smearing);
278  double rhoB = std::get<0>(baryon_density_and_gradient);
279  const ThreeVector grad_j0B = std::get<2>(baryon_density_and_gradient);
280  const ThreeVector curl_vecjB = std::get<3>(baryon_density_and_gradient);
281  const FourVector djmuB_dt = std::get<4>(baryon_density_and_gradient);
282  if (use_skyrme_) {
283  F_skyrme_or_VDF =
284  skyrme_force(rhoB, grad_j0B, djmuB_dt.threevec(), curl_vecjB);
285  }
286 
287  if (use_symmetry_) {
288  const auto density_and_gradient =
290  compute_gradient, smearing);
291  const double rhoI3 = std::get<0>(density_and_gradient);
292  const ThreeVector grad_j0I3 = std::get<2>(density_and_gradient);
293  const ThreeVector curl_vecjI3 = std::get<3>(density_and_gradient);
294  const FourVector dvecjI3_dt = std::get<4>(density_and_gradient);
295  F_symmetry =
296  symmetry_force(rhoI3, grad_j0I3, dvecjI3_dt.threevec(), curl_vecjI3,
297  rhoB, grad_j0B, djmuB_dt.threevec(), curl_vecjB);
298  }
299 
300  if (use_vdf_) {
301  const FourVector jmuB = std::get<1>(baryon_density_and_gradient);
302  const FourVector djmuB_dx = std::get<5>(baryon_density_and_gradient);
303  const FourVector djmuB_dy = std::get<6>(baryon_density_and_gradient);
304  const FourVector djmuB_dz = std::get<7>(baryon_density_and_gradient);
305 
306  // safety check to not divide by zero
307  const int sgn = rhoB > 0 ? 1 : -1;
308  if (std::abs(rhoB) < very_small_double) {
309  rhoB = sgn * very_small_double;
310  }
311 
312  const double drhoB_dt =
313  (1 / rhoB) * (jmuB.x0() * djmuB_dt.x0() - jmuB.x1() * djmuB_dt.x1() -
314  jmuB.x2() * djmuB_dt.x2() - jmuB.x3() * djmuB_dt.x3());
315 
316  const double drhoB_dx =
317  (1 / rhoB) * (jmuB.x0() * djmuB_dx.x0() - jmuB.x1() * djmuB_dx.x1() -
318  jmuB.x2() * djmuB_dx.x2() - jmuB.x3() * djmuB_dx.x3());
319 
320  const double drhoB_dy =
321  (1 / rhoB) * (jmuB.x0() * djmuB_dy.x0() - jmuB.x1() * djmuB_dy.x1() -
322  jmuB.x2() * djmuB_dy.x2() - jmuB.x3() * djmuB_dy.x3());
323 
324  const double drhoB_dz =
325  (1 / rhoB) * (jmuB.x0() * djmuB_dz.x0() - jmuB.x1() * djmuB_dz.x1() -
326  jmuB.x2() * djmuB_dz.x2() - jmuB.x3() * djmuB_dz.x3());
327 
328  const FourVector drhoB_dxnu = {drhoB_dt, drhoB_dx, drhoB_dy, drhoB_dz};
329 
330  const ThreeVector grad_rhoB = drhoB_dxnu.threevec();
331  const ThreeVector vecjB = jmuB.threevec();
332  const ThreeVector Drho_cross_vecj = grad_rhoB.cross_product(vecjB);
333 
334  F_skyrme_or_VDF = vdf_force(
335  rhoB, drhoB_dt, drhoB_dxnu.threevec(), Drho_cross_vecj, jmuB.x0(),
336  grad_j0B, jmuB.threevec(), djmuB_dt.threevec(), curl_vecjB);
337  }
338 
339  return std::make_tuple(F_skyrme_or_VDF.first, F_skyrme_or_VDF.second,
340  F_symmetry.first, F_symmetry.second);
341 }
342 
343 } // namespace smash
Interface to the SMASH configuration files.
bool has_value(const Key< T > &key) const
Return whether there is a non-empty value behind the requested key (which is supposed not to refer to...
T take(const Key< T > &key)
The default interface for SMASH to read configuration values.
A class to pre-calculate and store parameters relevant for density calculation.
Definition: density.h:92
The FourVector class holds relevant values in Minkowski spacetime with (+, −, −, −) metric signature.
Definition: fourvector.h:33
double x3() const
Definition: fourvector.h:325
double x2() const
Definition: fourvector.h:321
ThreeVector threevec() const
Definition: fourvector.h:329
double x0() const
Definition: fourvector.h:313
double x1() const
Definition: fourvector.h:317
Particle type contains the static properties of a particle species.
Definition: particletype.h:100
bool is_baryon() const
Definition: particletype.h:206
bool is_nucleus() const
Definition: particletype.h:254
PdgCode pdgcode() const
Definition: particletype.h:159
double isospin3_rel() const
Definition: particletype.h:182
int baryon_number() const
Definition: pdgcode.h:388
bool use_skyrme_
Skyrme potential on/off.
Definition: potentials.h:528
bool use_symmetry_
Symmetry potential on/off.
Definition: potentials.h:531
double skyrme_pot(const double baryon_density) const
Evaluates Skyrme potential given a baryon density.
Definition: potentials.h:202
double symmetry_pot(const double baryon_isospin_density, const double baryon_density) const
Evaluates symmetry potential given baryon isospin density.
Definition: potentials.cc:86
double mom_dependence_C_
Parameter C of the momentum-dependent part of the potentials given in MeV.
Definition: potentials.h:570
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:178
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:119
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:97
std::vector< double > powers_
Parameters of the VDF potential: exponents .
Definition: potentials.h:602
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:254
double symmetry_S(const double baryon_density) const
Calculate the factor in the symmetry potential.
Definition: potentials.cc:78
double symmetry_S_Pot_
Parameter S_Pot in the symmetry potential in MeV.
Definition: potentials.h:573
double skyrme_a_
Parameter of skyrme potentials: the coefficient in front of in GeV.
Definition: potentials.h:546
std::vector< double > coeffs_
Parameters of the VDF potential: coefficients , in GeV.
Definition: potentials.h:600
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:193
double mom_dependence_Lambda_
Parameter Lambda of the momentum-dependent part of the potentials given in 1/fm.
Definition: potentials.h:564
bool use_momentum_dependence_
Momentum-dependent part on/off.
Definition: potentials.h:540
double skyrme_tau_
Parameters of skyrme potentials: the power index.
Definition: potentials.h:558
Potentials(Configuration conf, const DensityParameters &parameters)
Potentials constructor.
Definition: potentials.cc:20
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:244
int number_of_terms() const
Definition: potentials.h:506
static std::pair< double, int > force_scale(const ParticleType &data)
Evaluates the scaling factor of the forces acting on the particles.
Definition: potentials.cc:152
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:160
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:268
bool use_coulomb_
Coulomb potential on/Off.
Definition: potentials.h:534
double symmetry_gamma_
Power in formula for :
Definition: potentials.h:586
bool symmetry_is_rhoB_dependent_
Whether the baryon density dependence of the symmetry potential is included.
Definition: potentials.h:579
double coulomb_r_cut_
Cutoff in integration for coulomb potential.
Definition: potentials.h:589
const DensityParameters param_
Struct that contains the gaussian smearing width , the distance cutoff and the testparticle number n...
Definition: potentials.h:525
bool use_vdf_
VDF potential on/off.
Definition: potentials.h:537
double saturation_density_
Saturation density of nuclear matter used in the VDF potential; it may vary between different paramet...
Definition: potentials.h:598
virtual ~Potentials()
Standard destructor.
Definition: potentials.cc:65
double skyrme_b_
Parameters of skyrme potentials: the coefficient in front of in GeV.
Definition: potentials.h:552
The ThreeVector class represents a physical three-vector with the components .
Definition: threevector.h:31
ThreeVector cross_product(const ThreeVector &b) const
Definition: threevector.h:255
Collection of useful constants that are known at compile time.
constexpr Section p_skyrme
Subsection for the Skyrme potentials information.
Definition: input_keys.h:235
constexpr Section p_vdf
Subsection for the VDF potentials information.
Definition: input_keys.h:239
constexpr Section p_coulomb
Subsection for the Coulomb potentials information.
Definition: input_keys.h:230
constexpr Section p_symmetry
Subsection for the symmetry potentials information.
Definition: input_keys.h:237
constexpr Section p_momentumDependence
Subsection for the momentum-dependent potentials information.
Definition: input_keys.h:232
int sgn(T val)
Signum function.
Definition: random.h:207
Definition: action.h:24
constexpr double mev_to_gev
MeV to GeV conversion factor.
Definition: constants.h:38
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:176
constexpr double very_small_double
A very small double, used to avoid division by zero.
Definition: constants.h:44
constexpr double nuclear_density
Ground state density of symmetric nuclear matter [fm^-3].
Definition: constants.h:52
A container to keep track of all ever existed input keys.
Definition: input_keys.h:1255
static const Key< double > potentials_momentum_dependence_C
See user guide description for more information.
Definition: input_keys.h:7520
static const Key< std::vector< double > > potentials_vdf_powers
See user guide description for more information.
Definition: input_keys.h:7471
static const Key< double > potentials_coulomb_rCut
See user guide description for more information.
Definition: input_keys.h:7505
static const Key< double > potentials_skyrme_skyrmeB
See user guide description for more information.
Definition: input_keys.h:7389
static const Key< double > potentials_momentum_dependence_Lambda
See user guide description for more information.
Definition: input_keys.h:7536
static const Key< double > potentials_skyrme_skyrmeA
See user guide description for more information.
Definition: input_keys.h:7375
static const Key< double > potentials_symmetry_gamma
See user guide description for more information.
Definition: input_keys.h:7422
static const Key< double > potentials_skyrme_skyrmeTau
See user guide description for more information.
Definition: input_keys.h:7404
static const Key< double > potentials_symmetry_sPot
See user guide description for more information.
Definition: input_keys.h:7438
static const Key< double > potentials_vdf_satRhoB
See user guide description for more information.
Definition: input_keys.h:7489
static const Key< std::vector< double > > potentials_vdf_coeffs
See user guide description for more information.
Definition: input_keys.h:7452