Version: SMASH-2.0
potentials.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2014-2020
4  * SMASH Team
5  *
6  * GNU General Public License (GPLv3 or later)
7  *
8  */
9 
10 #include "smash/potentials.h"
11 
12 #include "smash/constants.h"
13 #include "smash/density.h"
14 
15 namespace smash {
16 
17 Potentials::Potentials(Configuration conf, const DensityParameters &param)
18  : param_(param),
19  use_skyrme_(conf.has_value({"Skyrme"})),
20  use_symmetry_(conf.has_value({"Symmetry"})) {
71  if (use_skyrme_) {
72  skyrme_a_ = conf.take({"Skyrme", "Skyrme_A"});
73  skyrme_b_ = conf.take({"Skyrme", "Skyrme_B"});
74  skyrme_tau_ = conf.take({"Skyrme", "Skyrme_Tau"});
75  }
76 
98  if (use_symmetry_) {
99  symmetry_S_Pot_ = conf.take({"Symmetry", "S_Pot"});
100  if (conf.has_value({"Symmetry", "gamma"})) {
101  symmetry_gamma_ = conf.take({"Symmetry", "gamma"});
102  symmetry_is_rhoB_dependent_ = true;
103  }
104  }
105 }
106 
107 Potentials::~Potentials() {}
108 
109 double Potentials::skyrme_pot(const double baryon_density) const {
110  const double tmp = baryon_density / nuclear_density;
111  /* U = U(|rho|) * sgn , because the sign of the potential changes
112  * under a charge reversal transformation. */
113  const int sgn = tmp > 0 ? 1 : -1;
114  // Return in GeV
115  return 1.0e-3 * sgn *
116  (skyrme_a_ * std::abs(tmp) +
117  skyrme_b_ * std::pow(std::abs(tmp), skyrme_tau_));
118 }
119 double Potentials::symmetry_S(const double baryon_density) const {
120  if (symmetry_is_rhoB_dependent_) {
121  return 12.3 * std::pow(baryon_density / nuclear_density, 2. / 3.) +
122  20.0 * std::pow(baryon_density / nuclear_density, symmetry_gamma_);
123  } else {
124  return 0.;
125  }
126 }
127 double Potentials::symmetry_pot(const double baryon_isospin_density,
128  const double baryon_density) const {
129  double pot =
130  1.0e-3 * 2. * symmetry_S_Pot_ * baryon_isospin_density / nuclear_density;
131  if (symmetry_is_rhoB_dependent_) {
132  pot += 1.0e-3 * symmetry_S(baryon_density) * baryon_isospin_density *
133  baryon_isospin_density / (baryon_density * baryon_density);
134  }
135  return pot;
136 }
137 
138 double Potentials::potential(const ThreeVector &r, const ParticleList &plist,
139  const ParticleType &acts_on) const {
140  double total_potential = 0.0;
141  const bool compute_gradient = false;
142  const bool smearing = true;
143  const auto scale = force_scale(acts_on);
144 
145  if (!(acts_on.is_baryon() || acts_on.is_nucleus())) {
146  return total_potential;
147  }
148  const double rho_B = std::get<0>(current_eckart(
149  r, plist, param_, DensityType::Baryon, compute_gradient, smearing));
150  if (use_skyrme_) {
151  total_potential += scale.first * skyrme_pot(rho_B);
152  }
153  if (use_symmetry_) {
154  const double rho_iso = std::get<0>(
155  current_eckart(r, plist, param_, DensityType::BaryonicIsospin,
156  compute_gradient, smearing));
157  const double sym_pot =
158  symmetry_pot(rho_iso, rho_B) * acts_on.isospin3_rel();
159  total_potential += scale.second * sym_pot;
160  }
161  return total_potential;
162 }
163 
164 std::pair<double, int> Potentials::force_scale(const ParticleType &data) {
165  const auto &pdg = data.pdgcode();
166  const double skyrme_scale =
167  (3 - std::abs(pdg.strangeness())) / 3. * pdg.baryon_number();
168  const int symmetry_scale = pdg.baryon_number();
169  return std::make_pair(skyrme_scale, symmetry_scale);
170 }
171 
172 std::pair<ThreeVector, ThreeVector> Potentials::skyrme_force(
173  const double density, const ThreeVector grad_rho, const ThreeVector dj_dt,
174  const ThreeVector rot_j) const {
175  ThreeVector E_component(0.0, 0.0, 0.0), B_component(0.0, 0.0, 0.0);
176  if (use_skyrme_) {
177  const int sgn = density > 0 ? 1 : -1;
178  const double abs_density = std::abs(density);
179  const double dV_drho =
180  sgn *
181  (skyrme_a_ +
182  skyrme_b_ * skyrme_tau_ *
183  std::pow(abs_density / nuclear_density, skyrme_tau_ - 1)) *
185  E_component -= dV_drho * (grad_rho + dj_dt);
186  B_component += dV_drho * rot_j;
187  }
188  return std::make_pair(E_component, B_component);
189 }
190 
191 std::pair<ThreeVector, ThreeVector> Potentials::symmetry_force(
192  const double rhoI3, const ThreeVector grad_rhoI3, const ThreeVector djI3_dt,
193  const ThreeVector rot_jI3, const double rhoB, const ThreeVector grad_rhoB,
194  const ThreeVector djB_dt, const ThreeVector rot_jB) const {
195  ThreeVector E_component(0.0, 0.0, 0.0), B_component(0.0, 0.0, 0.0);
196  if (use_symmetry_) {
197  E_component -= dVsym_drhoI3(rhoB, rhoI3) * (grad_rhoI3 + djI3_dt) +
198  dVsym_drhoB(rhoB, rhoI3) * (grad_rhoB + djB_dt);
199  B_component +=
200  dVsym_drhoI3(rhoB, rhoI3) * rot_jI3 + dVsym_drhoB(rhoB, rhoI3) * rot_jB;
201  }
202  return std::make_pair(E_component, B_component);
203 }
204 
205 double Potentials::dVsym_drhoI3(const double rhoB, const double rhoI3) const {
206  double term1 = 2. * symmetry_S_Pot_ / nuclear_density;
207  if (symmetry_is_rhoB_dependent_) {
208  double term2 = 2. * rhoI3 * symmetry_S(rhoB) / (rhoB * rhoB);
209  return mev_to_gev * (term1 + term2);
210  } else {
211  return mev_to_gev * term1;
212  }
213 }
214 
215 double Potentials::dVsym_drhoB(const double rhoB, const double rhoI3) const {
216  if (symmetry_is_rhoB_dependent_) {
217  double rhoB_over_rho0 = rhoB / nuclear_density;
218  double term1 = 8.2 * std::pow(rhoB_over_rho0, -1. / 3.) / nuclear_density +
219  20. * symmetry_gamma_ *
220  std::pow(rhoB_over_rho0, symmetry_gamma_) / rhoB;
221  double term2 = -2. * symmetry_S(rhoB) / rhoB;
222  return mev_to_gev * (term1 + term2) * rhoI3 * rhoI3 / (rhoB * rhoB);
223  } else {
224  return 0.;
225  }
226 }
227 
228 std::tuple<ThreeVector, ThreeVector, ThreeVector, ThreeVector>
229 Potentials::all_forces(const ThreeVector &r, const ParticleList &plist) const {
230  const bool compute_gradient = true;
231  const bool smearing = true;
232  auto F_skyrme =
233  std::make_pair(ThreeVector(0., 0., 0.), ThreeVector(0., 0., 0.));
234  auto F_symmetry =
235  std::make_pair(ThreeVector(0., 0., 0.), ThreeVector(0., 0., 0.));
236 
237  const auto baryon_density_and_gradient = current_eckart(
238  r, plist, param_, DensityType::Baryon, compute_gradient, smearing);
239  const double rhoB = std::get<0>(baryon_density_and_gradient);
240  const ThreeVector grad_rhoB = std::get<2>(baryon_density_and_gradient);
241  const ThreeVector djB_dt = std::get<3>(baryon_density_and_gradient);
242  const ThreeVector rot_jB = std::get<4>(baryon_density_and_gradient);
243  if (use_skyrme_) {
244  F_skyrme = skyrme_force(rhoB, grad_rhoB, djB_dt, rot_jB);
245  }
246 
247  if (use_symmetry_) {
248  const auto density_and_gradient =
249  current_eckart(r, plist, param_, DensityType::BaryonicIsospin,
250  compute_gradient, smearing);
251  const double rhoI3 = std::get<0>(density_and_gradient);
252  const ThreeVector grad_rhoI3 = std::get<2>(density_and_gradient);
253  const ThreeVector djI3_dt = std::get<3>(density_and_gradient);
254  const ThreeVector rot_jI3 = std::get<4>(density_and_gradient);
255  F_symmetry = symmetry_force(rhoI3, grad_rhoI3, djI3_dt, rot_jI3, rhoB,
256  grad_rhoB, djB_dt, rot_jB);
257  }
258 
259  return std::make_tuple(F_skyrme.first, F_skyrme.second, F_symmetry.first,
260  F_symmetry.second);
261 }
262 
263 } // namespace smash
smash
Definition: action.h:24
smash::mev_to_gev
constexpr double mev_to_gev
MeV to GeV conversion factor.
Definition: constants.h:34
smash::PdgCode::baryon_number
int baryon_number() const
Definition: pdgcode.h:305
smash::nuclear_density
constexpr double nuclear_density
Ground state density of symmetric nuclear matter [fm^-3].
Definition: constants.h:45
smash::Potentials::Potentials
Potentials(Configuration conf, const DensityParameters &parameters)
Potentials constructor.
smash::ParticleType::pdgcode
PdgCode pdgcode() const
Definition: particletype.h:156
smash::ParticleType::is_baryon
bool is_baryon() const
Definition: particletype.h:203
smash::ThreeVector
Definition: threevector.h:31
smash::ParticleType::is_nucleus
bool is_nucleus() const
Definition: particletype.h:242
smash::ParticleType::isospin3_rel
double isospin3_rel() const
Definition: particletype.h:179
smash::ParticleType
Definition: particletype.h:97
density.h
smash::current_eckart
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:148
constants.h
smash::random::sgn
int sgn(T val)
Signum function.
Definition: random.h:190
potentials.h