Version: SMASH-2.0
deformednucleus.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014-2020
3  * SMASH Team
4  *
5  * GNU General Public License (GPLv3 or later)
6  */
8 
9 #include <cmath>
10 #include <map>
11 #include <stdexcept>
12 
13 #include "smash/configuration.h"
14 #include "smash/constants.h"
15 #include "smash/fourvector.h"
16 #include "smash/random.h"
17 #include "smash/threevector.h"
18 
19 namespace smash {
20 
49 // For readability and layout issues parts of the customnucleus userguide
50 // needs to be located here. The example configuration can however be found in
51 // customnucleus.cc
52 
106 DeformedNucleus::DeformedNucleus(const std::map<PdgCode, int> &particle_list,
107  int nTest)
108  : Nucleus(particle_list, nTest) {}
109 
111  bool auto_deformation)
112  : Nucleus(config, nTest) {
113  if (auto_deformation) {
115  } else {
117  }
118 
119  if (config.has_value({"Deformed", "Orientation"})) {
120  Configuration subconfig = config["Deformed"]["Orientation"];
121  set_orientation_from_config(subconfig);
122  }
123 }
124 
126  double a_radius;
127  Angles a_direction;
128  // Set a sensible maximum bound for radial sampling.
129  double radius_max =
132 
133  // Sample the distribution.
134  do {
135  a_direction.distribute_isotropically();
136  // sample r**2 dr
137  a_radius = radius_max * std::cbrt(random::canonical());
138  } while (random::canonical() >
139  nucleon_density(a_radius, a_direction.costheta()) /
141 
142  // Update (x, y, z) positions.
143  return a_direction.threevec() * a_radius;
144 }
145 
147  // Set the deformation parameters
148  // reference for U, Pb, Au, Cu: \iref{Moller:1993ed}
149  // reference for Zr and Ru: \iref{Schenke:2019ruo}
150  bool listed = 0;
151  const std::map<int, std::string> A_map = {
152  {238, "Uranium"}, {208, "Lead"}, {197, "Gold"}, {63, "Copper"}};
153  const std::map<std::string, std::string> Z_map = {
154  {"Uranium", "92"}, {"Lead", "82"}, {"Gold", "79"}, {"Copper", "29"}};
156  int Z = Nucleus::number_of_protons();
157  switch (A) {
158  case 238: // Uranium
159  if (Z == 92) {
160  set_beta_2(0.28);
161  set_beta_4(0.093);
162  } else {
163  listed = true;
164  }
165  break;
166  case 208: // Lead
167  if (Z == 82) {
168  set_beta_2(0.0);
169  set_beta_4(0.0);
170  } else {
171  listed = true;
172  }
173  break;
174  case 197: // Gold
175  if (Z == 79) {
176  set_beta_2(-0.131);
177  set_beta_4(-0.031);
178  } else {
179  listed = true;
180  }
181  break;
182  case 63: // Copper
183  if (Z == 29) {
184  set_beta_2(0.162);
185  set_beta_4(-0.006);
186  } else {
187  listed = true;
188  }
189  break;
190  case 96:
191  if (Z == 40) { // Zirconium
192  set_beta_2(0.0);
193  set_beta_4(0.0);
194  } else if (Z == 44) { // Ruthenium
195  set_beta_2(0.158);
196  set_beta_4(0.0);
197  } else {
198  throw std::domain_error(
199  "Number of protons for nuclei with mass number A = 96 does not "
200  "match that of Zirconium or Ruthenium. The deformation parameters "
201  "for additional isobars are currently not implemented."
202  " Please specify at least \"Beta_2\" and \"Beta_4\" "
203  "manually and set \"Automatic: False.\" ");
204  }
205  break;
206  default:
207  throw std::domain_error(
208  "Mass number not listed for automatically setting deformation "
209  "parameters. Please specify at least \"Beta_2\" and \"Beta_4\" "
210  "manually and set \"Automatic: False.\" ");
211  }
212  if (listed) {
213  throw std::domain_error("Mass number is listed under " + A_map.at(A) +
214  " but the proton "
215  "number of " +
216  std::to_string(Z) +
217  " does not match "
218  "its " +
219  Z_map.at(A_map.at(A)) +
220  " protons."
221  "Please specify at least \"Beta_2\" and \"Beta_4\" "
222  "manually and set \"Automatic: False.\" ");
223  }
224 }
225 
227  Configuration &config) {
228  // Deformation parameters.
229  if (config.has_value({"Deformed", "Beta_2"})) {
230  set_beta_2(static_cast<double>(config.take({"Deformed", "Beta_2"})));
231  }
232  if (config.has_value({"Deformed", "Beta_4"})) {
233  set_beta_4(static_cast<double>(config.take({"Deformed", "Beta_4"})));
234  }
235 }
236 
238  Configuration &orientation_config) {
239  // Read in orientation if provided, otherwise, the defaults are
240  // theta = pi/2, phi = 0, as declared in the angles class
241 
242  if (orientation_config.has_value({"Theta"})) {
243  if (orientation_config.has_value({"Random_Rotation"}) &&
244  orientation_config.take({"Random_Rotation"})) {
245  throw std::domain_error(
246  "Random rotation of nuclei is activated although"
247  " theta is provided. Please specify only either of them. ");
248  } else {
249  set_polar_angle(static_cast<double>(orientation_config.take({"Theta"})));
250  }
251  }
252 
253  if (orientation_config.has_value({"Phi"})) {
254  if (orientation_config.has_value({"Random_Rotation"}) &&
255  orientation_config.take({"Random_Rotation"})) {
256  throw std::domain_error(
257  "Random rotation of nuclei is activated although"
258  " phi is provided. Please specify only either of them. ");
259  } else {
261  static_cast<double>(orientation_config.take({"Phi"})));
262  }
263  }
264 
265  if (orientation_config.take({"Random_Rotation"}, false)) {
266  random_rotation_ = true;
267  }
268 }
269 
271  if (random_rotation_) {
272  // Randomly generate euler angles for theta and phi. Psi needs not be
273  // assigned, as the nucleus objects are symmetric with respect to psi.
277  }
278  for (auto &particle : *this) {
279  /* Rotate every vector by the nuclear azimuth phi and polar angle
280  * theta (the Euler angles). This means applying the matrix for a
281  * rotation of phi about z, followed by the matrix for a rotation
282  * theta about the rotated x axis. The third angle psi is 0 by symmetry.*/
283  ThreeVector three_pos = particle.position().threevec();
285  0.);
286  particle.set_3position(three_pos);
287  }
288 }
289 
290 double y_l_0(int l, double cosx) {
291  if (l == 2) {
292  return (1. / 4) * std::sqrt(5 / M_PI) * (3. * (cosx * cosx) - 1);
293  } else if (l == 4) {
294  return (3. / 16) * std::sqrt(1 / M_PI) *
295  (35. * (cosx * cosx) * (cosx * cosx) - 30. * (cosx * cosx) + 3);
296  } else {
297  throw std::domain_error(
298  "Not a valid angular momentum quantum number in y_l_0.");
299  }
300 }
301 
302 double DeformedNucleus::nucleon_density(double r, double cosx) const {
304  (1 + std::exp((r - Nucleus::get_nuclear_radius() *
305  (1 + beta2_ * y_l_0(2, cosx) +
306  beta4_ * y_l_0(4, cosx))) /
308 }
309 
310 } // namespace smash
smash::Nucleus::random_euler_angles
void random_euler_angles()
Randomly generate Euler angles.
Definition: nucleus.cc:497
smash
Definition: action.h:24
smash::Nucleus
A nucleus is a collection of particles that are initialized, before the beginning of the simulation a...
Definition: nucleus.h:27
smash::DeformedNucleus::beta2_
double beta2_
Deformation parameter for angular momentum l=2.
Definition: deformednucleus.h:141
smash::DeformedNucleus::set_beta_4
void set_beta_4(double b4)
Set deformation coefficient for Y_4_0.
Definition: deformednucleus.h:115
smash::Angles::phi
double phi() const
Definition: angles.h:260
smash::Nucleus::number_of_protons
size_t number_of_protons() const
Number of physical protons in the nucleus:
Definition: nucleus.h:183
smash::Nucleus::get_diffusiveness
double get_diffusiveness() const
Definition: nucleus.h:295
smash::DeformedNucleus::nuclear_orientation_
Angles nuclear_orientation_
Nucleus orientation (initial profile in xz plane) in terms of a pair of angles (theta,...
Definition: deformednucleus.h:148
smash::DeformedNucleus::beta4_
double beta4_
Deformation parameter for angular momentum l=4.
Definition: deformednucleus.h:143
smash::ThreeVector::rotate
void rotate(double phi, double theta, double psi)
Rotate vector by the given Euler angles phi, theta, psi.
Definition: threevector.h:276
smash::DeformedNucleus::distribute_nucleon
ThreeVector distribute_nucleon() override
Deformed Woods-Saxon sampling routine.
Definition: deformednucleus.cc:125
smash::Nucleus::get_saturation_density
double get_saturation_density() const
Definition: nucleus.h:307
smash::DeformedNucleus::rotate
void rotate() override
Rotates the nucleus according to members nucleus_polar_angle_ and nucleus_azimuthal_angle_ and update...
Definition: deformednucleus.cc:270
smash::Angles::distribute_isotropically
void distribute_isotropically()
Populate the object with a new direction.
Definition: angles.h:188
smash::Nucleus::euler_theta_
double euler_theta_
Euler angel theta.
Definition: nucleus.h:267
smash::Configuration::has_value
bool has_value(std::initializer_list< const char * > keys) const
Returns whether there is a non-empty value behind the requested keys.
Definition: configuration.cc:181
fourvector.h
smash::Nucleus::number_of_particles
size_t number_of_particles() const
Number of physical particles in the nucleus:
Definition: nucleus.h:164
random.h
smash::Configuration
Interface to the SMASH configuration files.
Definition: configuration.h:464
smash::ThreeVector
Definition: threevector.h:31
deformednucleus.h
smash::DeformedNucleus::nucleon_density
double nucleon_density(double r, double cosx) const override
Return the deformed Woods-Saxon probability density for the given position.
Definition: deformednucleus.cc:302
threevector.h
smash::DeformedNucleus::set_beta_2
void set_beta_2(double b2)
Set deformation coefficient for Y_2_0.
Definition: deformednucleus.h:110
smash::y_l_0
double y_l_0(int l, double cosx)
Spherical harmonics Y_2_0 and Y_4_0.
Definition: deformednucleus.cc:290
smash::DeformedNucleus::set_orientation_from_config
void set_orientation_from_config(Configuration &orientation_config)
Set angles for orientation of nucleus from config file.
Definition: deformednucleus.cc:237
smash::Angles::threevec
ThreeVector threevec() const
Definition: angles.h:268
smash::DeformedNucleus::set_azimuthal_angle
void set_azimuthal_angle(double phi)
Set the nucleus azimuthal angle.
Definition: deformednucleus.h:127
constants.h
smash::Nucleus::euler_phi_
double euler_phi_
Euler angel phi.
Definition: nucleus.h:265
smash::DeformedNucleus::set_deformation_parameters_from_config
void set_deformation_parameters_from_config(Configuration &config)
Set parameters for spherical deformation of the nucleus from the values specified in the configuratio...
Definition: deformednucleus.cc:226
configuration.h
smash::Configuration::take
Value take(std::initializer_list< const char * > keys)
The default interface for SMASH to read configuration values.
Definition: configuration.cc:140
smash::Nucleus::get_nuclear_radius
double get_nuclear_radius() const
Definition: nucleus.h:335
smash::Angles
Angles provides a common interface for generating directions: i.e., two angles that should be interpr...
Definition: angles.h:59
smash::Angles::theta
double theta() const
Definition: angles.h:272
smash::DeformedNucleus::DeformedNucleus
DeformedNucleus(const std::map< PdgCode, int > &particle_list, int nTest)
Constructor for DeformedNucles which takes a particle list and the number of testparticles.
Definition: deformednucleus.cc:106
smash::DeformedNucleus::set_polar_angle
void set_polar_angle(double theta)
Set the nucleus polar angle.
Definition: deformednucleus.h:120
smash::random::canonical
T canonical()
Definition: random.h:113
smash::DeformedNucleus::random_rotation_
bool random_rotation_
Whether the nuclei should be rotated randomly.
Definition: deformednucleus.h:152
smash::Angles::costheta
double costheta() const
Definition: angles.h:259
smash::DeformedNucleus::set_deformation_parameters_automatic
void set_deformation_parameters_automatic()
Sets the deformation parameters of the radius according to the current mass number.
Definition: deformednucleus.cc:146