Version: SMASH-1.8
deformednucleus.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014-2019
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/angles.h"
14 #include "smash/configuration.h"
15 #include "smash/constants.h"
16 #include "smash/fourvector.h"
17 #include "smash/particledata.h"
18 #include "smash/random.h"
19 #include "smash/threevector.h"
20 
21 namespace smash {
22 
51 // For readability and layout issues parts of the customnucleus userguide
52 // needs to be located here. The example configuration can however be found in
53 // customnucleus.cc
54 
108 DeformedNucleus::DeformedNucleus(const std::map<PdgCode, int> &particle_list,
109  int nTest)
110  : Nucleus(particle_list, nTest) {}
111 
113  bool auto_deformation)
114  : Nucleus(config, nTest) {
115  if (auto_deformation) {
117  } else {
119  }
120 
121  if (config.has_value({"Deformed", "Orientation"})) {
122  Configuration subconfig = config["Deformed"]["Orientation"];
123  set_orientation_from_config(subconfig);
124  }
125 }
126 
128  double a_radius;
129  Angles a_direction;
130  // Set a sensible maximum bound for radial sampling.
131  double radius_max =
134 
135  // Sample the distribution.
136  do {
137  a_direction.distribute_isotropically();
138  // sample r**2 dr
139  a_radius = radius_max * std::cbrt(random::canonical());
140  } while (random::canonical() >
141  nucleon_density(a_radius, a_direction.costheta()) /
143 
144  // Update (x, y, z) positions.
145  return a_direction.threevec() * a_radius;
146 }
147 
149  // Set the deformation parameters
150  // reference for U, Pb, Au, Cu: \iref{Moller:1993ed}
151  // reference for Zr and Ru: \iref{Schenke:2019ruo}
152  bool listed = 0;
153  const std::map<int, std::string> A_map = {
154  {238, "Uranium"}, {208, "Lead"}, {197, "Gold"}, {63, "Copper"}};
155  const std::map<std::string, std::string> Z_map = {
156  {"Uranium", "92"}, {"Lead", "82"}, {"Gold", "79"}, {"Copper", "29"}};
158  int Z = Nucleus::number_of_protons();
159  switch (A) {
160  case 238: // Uranium
161  if (Z == 92) {
162  set_beta_2(0.28);
163  set_beta_4(0.093);
164  } else {
165  listed = true;
166  }
167  break;
168  case 208: // Lead
169  if (Z == 82) {
170  set_beta_2(0.0);
171  set_beta_4(0.0);
172  } else {
173  listed = true;
174  }
175  break;
176  case 197: // Gold
177  if (Z == 79) {
178  set_beta_2(-0.131);
179  set_beta_4(-0.031);
180  } else {
181  listed = true;
182  }
183  break;
184  case 63: // Copper
185  if (Z == 29) {
186  set_beta_2(0.162);
187  set_beta_4(-0.006);
188  } else {
189  listed = true;
190  }
191  break;
192  case 96:
193  if (Z == 40) { // Zirconium
194  set_beta_2(0.0);
195  set_beta_4(0.0);
196  } else if (Z == 44) { // Ruthenium
197  set_beta_2(0.158);
198  set_beta_4(0.0);
199  } else {
200  throw std::domain_error(
201  "Number of protons for nuclei with mass number A = 96 does not "
202  "match that of Zirconium or Ruthenium. The deformation parameters "
203  "for additional isobars are currently not implemented."
204  " Please specify at least \"Beta_2\" and \"Beta_4\" "
205  "manually and set \"Automatic: False.\" ");
206  }
207  break;
208  default:
209  throw std::domain_error(
210  "Mass number not listed for automatically setting deformation "
211  "parameters. Please specify at least \"Beta_2\" and \"Beta_4\" "
212  "manually and set \"Automatic: False.\" ");
213  }
214  if (listed) {
215  throw std::domain_error("Mass number is listed under " + A_map.at(A) +
216  " but the proton "
217  "number of " +
218  std::to_string(Z) +
219  " does not match "
220  "its " +
221  Z_map.at(A_map.at(A)) +
222  " protons."
223  "Please specify at least \"Beta_2\" and \"Beta_4\" "
224  "manually and set \"Automatic: False.\" ");
225  }
226 }
227 
229  Configuration &config) {
230  // Deformation parameters.
231  if (config.has_value({"Deformed", "Beta_2"})) {
232  set_beta_2(static_cast<double>(config.take({"Deformed", "Beta_2"})));
233  }
234  if (config.has_value({"Deformed", "Beta_4"})) {
235  set_beta_4(static_cast<double>(config.take({"Deformed", "Beta_4"})));
236  }
237 }
238 
240  Configuration &orientation_config) {
241  // Read in orientation if provided, otherwise, the defaults are
242  // theta = pi/2, phi = 0, as declared in the angles class
243 
244  if (orientation_config.has_value({"Theta"})) {
245  if (orientation_config.has_value({"Random_Rotation"}) &&
246  orientation_config.take({"Random_Rotation"})) {
247  throw std::domain_error(
248  "Random rotation of nuclei is activated although"
249  " theta is provided. Please specify only either of them. ");
250  } else {
251  set_polar_angle(static_cast<double>(orientation_config.take({"Theta"})));
252  }
253  }
254 
255  if (orientation_config.has_value({"Phi"})) {
256  if (orientation_config.has_value({"Random_Rotation"}) &&
257  orientation_config.take({"Random_Rotation"})) {
258  throw std::domain_error(
259  "Random rotation of nuclei is activated although"
260  " phi is provided. Please specify only either of them. ");
261  } else {
263  static_cast<double>(orientation_config.take({"Phi"})));
264  }
265  }
266 
267  if (orientation_config.take({"Random_Rotation"}, false)) {
268  random_rotation_ = true;
269  }
270 }
271 
273  if (random_rotation_) {
274  // Randomly generate euler angles for theta and phi. Psi needs not be
275  // assigned, as the nucleus objects are symmetric with respect to psi.
279  }
280  for (auto &particle : *this) {
281  /* Rotate every vector by the nuclear azimuth phi and polar angle
282  * theta (the Euler angles). This means applying the matrix for a
283  * rotation of phi about z, followed by the matrix for a rotation
284  * theta about the rotated x axis. The third angle psi is 0 by symmetry.*/
285  ThreeVector three_pos = particle.position().threevec();
287  0.);
288  particle.set_3position(three_pos);
289  }
290 }
291 
292 double y_l_0(int l, double cosx) {
293  if (l == 2) {
294  return (1. / 4) * std::sqrt(5 / M_PI) * (3. * (cosx * cosx) - 1);
295  } else if (l == 4) {
296  return (3. / 16) * std::sqrt(1 / M_PI) *
297  (35. * (cosx * cosx) * (cosx * cosx) - 30. * (cosx * cosx) + 3);
298  } else {
299  throw std::domain_error(
300  "Not a valid angular momentum quantum number in y_l_0.");
301  }
302 }
303 
304 double DeformedNucleus::nucleon_density(double r, double cosx) {
306  (1 + std::exp((r - Nucleus::get_nuclear_radius() *
307  (1 + beta2_ * y_l_0(2, cosx) +
308  beta4_ * y_l_0(4, cosx))) /
310 }
311 
312 } // namespace smash
smash::Nucleus::random_euler_angles
void random_euler_angles()
Randomly generate Euler angles.
Definition: nucleus.cc:501
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
particledata.h
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:127
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:272
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
angles.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) override
Return the deformed Woods-Saxon probability density for the given position.
Definition: deformednucleus.cc:304
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:292
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:239
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:228
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:108
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:148