23 :
Nucleus(particle_list, nTest) {}
26 bool auto_deformation)
28 if (auto_deformation) {
34 if (config.
has_value({
"Deformed",
"Orientation"})) {
60 return a_direction.
threevec() * a_radius;
69 const std::map<int, std::string> A_map = {{238,
"Uranium"},
74 const std::map<std::string, std::string> Z_map = {{
"Uranium",
"92"},
126 }
else if (Z == 44) {
130 throw std::domain_error(
131 "Number of protons for nuclei with mass number A = 96 does not "
132 "match that of Zirconium or Ruthenium. The deformation parameters "
133 "for additional isobars are currently not implemented."
134 " Please specify at least \"Beta_2\" and \"Beta_4\" "
135 "manually and set \"Automatic: False.\" ");
139 throw std::domain_error(
140 "Mass number not listed for automatically setting deformation "
141 "parameters. Please specify at least \"Beta_2\" and \"Beta_4\" "
142 "manually and set \"Automatic: False.\" ");
145 throw std::domain_error(
"Mass number is listed under " + A_map.at(A) +
151 Z_map.at(A_map.at(A)) +
153 "Please specify at least \"Beta_2\" and \"Beta_4\" "
154 "manually and set \"Automatic: False.\" ");
161 if (config.
has_value({
"Deformed",
"Beta_2"})) {
162 set_beta_2(
static_cast<double>(config.
take({
"Deformed",
"Beta_2"})));
164 if (config.
has_value({
"Deformed",
"Gamma"})) {
165 set_gamma(
static_cast<double>(config.
take({
"Deformed",
"Gamma"})));
167 if (config.
has_value({
"Deformed",
"Beta_3"})) {
168 set_beta_3(
static_cast<double>(config.
take({
"Deformed",
"Beta_3"})));
170 if (config.
has_value({
"Deformed",
"Beta_4"})) {
171 set_beta_4(
static_cast<double>(config.
take({
"Deformed",
"Beta_4"})));
180 if (orientation_config.
has_value({
"Theta"})) {
181 if (orientation_config.
has_value({
"Random_Rotation"}) &&
182 orientation_config.
take({
"Random_Rotation"})) {
183 throw std::domain_error(
184 "Random rotation of nuclei is activated although"
185 " theta is provided. Please specify only either of them. ");
191 if (orientation_config.
has_value({
"Phi"})) {
192 if (orientation_config.
has_value({
"Random_Rotation"}) &&
193 orientation_config.
take({
"Random_Rotation"})) {
194 throw std::domain_error(
195 "Random rotation of nuclei is activated although"
196 " phi is provided. Please specify only either of them. ");
199 static_cast<double>(orientation_config.
take({
"Phi"})));
203 if (orientation_config.
has_value({
"Psi"})) {
204 if (orientation_config.
has_value({
"Random_Rotation"}) &&
205 orientation_config.
take({
"Random_Rotation"})) {
206 throw std::domain_error(
207 "Random rotation of nuclei is activated although"
208 " psi is provided. Please specify only either of them. ");
214 if (orientation_config.
take({
"Random_Rotation"},
false)) {
228 for (
auto &particle : *
this) {
235 ThreeVector three_pos = particle.position().threevec();
238 particle.set_3position(three_pos);
242 double y_l_m(
int l,
int m,
double cosx,
double phi) {
243 if (l == 2 && m == 0) {
244 return (1. / 4) * std::sqrt(5 / M_PI) * (3. * (cosx * cosx) - 1);
245 }
else if (l == 2 && m == 2) {
246 double sinx2 = 1. - cosx * cosx;
247 return (1. / 4) * std::sqrt(15 / (2. * M_PI)) * sinx2 * std::cos(2. * phi);
248 }
else if (l == 3 && m == 0) {
249 return (1. / 4) * std::sqrt(7 / M_PI) *
250 (5. * cosx * (cosx * cosx) - 3. * cosx);
251 }
else if (l == 4 && m == 0) {
252 return (3. / 16) * std::sqrt(1 / M_PI) *
253 (35. * (cosx * cosx) * (cosx * cosx) - 30. * (cosx * cosx) + 3);
255 throw std::domain_error(
256 "Not a valid angular momentum quantum number in y_l_m.");
266 y_l_m(2, 0, cosx, phi) +
267 std::sqrt(2) * std::sin(
gamma_) *
268 y_l_m(2, 2, cosx, phi)) +
280 y_l_m(2, 0, cosx, phi) +
281 std::sqrt(2) * std::sin(
gamma_) *
282 y_l_m(2, 2, cosx, phi)) +
296 const auto result =
integrate(0.0, 2.0 * M_PI, [&](
double phi) {
299 return result.value();
310 const auto result =
integrate(0.01, 1, -1, 1, [&](
double t,
double cosx) {
311 const double r = (1 - t) / t;
312 return twopi * std::pow(r, 2.0) *
318 const auto result =
integrate(0.01, 1, -1, 1, [&](
double t,
double cosx) {
319 const double r = (1 - t) / t;
Angles provides a common interface for generating directions: i.e., two angles that should be interpr...
ThreeVector threevec() const
void distribute_isotropically()
Populate the object with a new direction.
Interface to the SMASH configuration files.
bool has_value(std::initializer_list< const char * > keys) const
Return whether there is a non-empty value behind the requested keys.
Configuration extract_sub_configuration(std::initializer_list< const char * > keys, Configuration::GetEmpty empty_if_not_existing=Configuration::GetEmpty::No)
Create a new configuration from a then-removed section of the present object.
Value take(std::initializer_list< const char * > keys)
The default interface for SMASH to read configuration values.
A C++ interface for numerical integration in two dimensions with the Cuba Cuhre integration function.
A C++ interface for numerical integration in one dimension with the GSL CQUAD integration functions.
A nucleus is a collection of particles that are initialized, before the beginning of the simulation a...
double get_diffusiveness() const
double euler_theta_
Euler angel theta.
double get_saturation_density() const
void random_euler_angles()
Randomly generate Euler angles.
double get_nuclear_radius() const
double euler_phi_
Euler angel phi.
double euler_psi_
Euler angel psi.
virtual void set_saturation_density(double density)
Sets the saturation density of the nucleus.
size_t number_of_protons() const
Number of physical protons in the nucleus:
size_t number_of_particles() const
Number of physical particles in the nucleus:
The ThreeVector class represents a physical three-vector with the components .
void rotate(double phi, double theta, double psi)
Rotate vector by the given Euler angles phi, theta, psi.
Collection of useful constants that are known at compile time.
static Integrator integrate
double y_l_m(int l, int m, double cosx, double phi)
Spherical harmonics Y_2_0, Y_2_2, Y_3_0 and Y_4_0.