26 static constexpr
int LNucleus = LogArea::Nucleus::id;
43 const auto &[particles_key, diffusiveness_key, radius_key,
44 saturation_key] = [&is_projectile]() {
58 std::map<PdgCode, int> part = config.
take(particles_key);
64 const bool is_diffusiveness_given = config.
has_value(diffusiveness_key),
65 is_radius_given = config.
has_value(radius_key),
66 is_saturation_given = config.
has_value(saturation_key);
67 if (is_diffusiveness_given && is_radius_given && is_saturation_given) {
71 }
else if (!is_diffusiveness_given && !is_radius_given &&
72 !is_saturation_given) {
76 throw std::invalid_argument(
77 "Diffusiveness, Radius and Saturation_Density required to manually "
78 "configure the Woods-Saxon distribution. Only one or two were provided."
79 "\nProviding none of the above mentioned parameters automatically "
80 "configures the distribution based on the atomic number.");
85 double total_mass = 0.;
87 total_mass += i->momentum().abs();
251 double prob_range1 = 1.0;
252 double prob_range2 = 3. / radius_scaled;
253 double prob_range3 = 2. * prob_range2 / radius_scaled;
254 double prob_range4 = 1. * prob_range3 / radius_scaled;
255 double ranges234 = prob_range2 + prob_range3 + prob_range4;
260 if (which_range < 0.0) {
264 if (which_range >= prob_range2) {
266 if (which_range >= prob_range2 + prob_range3) {
280 double position_scaled = t + radius_scaled;
290 for (
auto i =
begin(); i !=
end(); i++) {
292 i->set_4momentum(i->pole_mass(), 0.0, 0.0, 0.0);
317 }
else if ((A == 238) && (Z == 92)) {
321 }
else if ((A == 208) && (Z == 82)) {
325 }
else if ((A == 197) && (Z == 79)) {
329 }
else if ((A == 129) && (Z == 54)) {
333 }
else if ((A == 63) && (Z == 29)) {
337 }
else if (A == 96) {
342 }
else if (Z == 44) {
350 0.86 * std::pow(A, -1.0 / 3.0));
365 const bool is_projectile =
367 const auto &[rotation_key, theta_key, phi_key, psi_key] = [&is_projectile]() {
380 const bool was_any_angle_provided = config.
has_value(theta_key) ||
385 throw std::domain_error(
386 "The random rotation of nuclei has been requested, but some specific "
387 "rotation angle is provided, too. Please specify only either of them.");
402 for (
auto &particle : *
this) {
408 ThreeVector three_pos = particle.position().threevec();
410 particle.set_3position(three_pos);
423 const int A = N_n + N_p;
424 constexpr
double pi2_3 = 3.0 * M_PI * M_PI;
425 logg[
LNucleus].debug() << N_n <<
" neutrons, " << N_p <<
" protons.";
428 for (
auto i =
begin(); i !=
end(); i++) {
432 logg[
LNucleus].warn() <<
"No rule to calculate Fermi momentum "
433 <<
"for particle " << i->
pdgcode();
437 const double r = (i->
position() - nucleus_center).abs3();
453 ptot += ith_3momentum;
455 logg[
LNucleus].debug() <<
"Particle: " << *i <<
", pF[GeV]: "
456 <<
hbarc * std::pow(pi2_3 * rho, 1.0 / 3.0)
462 assert(ptot.
x1() == 0.0 && ptot.
x2() == 0.0 && ptot.
x3() == 0.0);
467 for (
auto i =
begin(); i !=
end(); i++) {
477 double beta_squared = beta_scalar * beta_scalar;
478 double one_over_gamma = std::sqrt(1.0 - beta_squared);
479 double gamma = 1.0 / one_over_gamma;
487 for (
auto i =
begin(); i !=
end(); i++) {
493 this_position.
set_x3(this_position.
x3() * one_over_gamma);
494 i->set_4position(this_position);
501 i->set_4momentum(i->pole_mass(), mom_i.
x1(), mom_i.
x2(),
502 gamma * (beta_scalar * mom_i.
x0() + mom_i.
x3()));
509 for (
auto n = particle_list.cbegin();
n != particle_list.cend(); ++
n) {
511 double current_mass = current_type.
mass();
515 particles_.back().set_4momentum(current_mass, 0.0, 0.0, 0.0);
522 for (
auto i =
begin(); i !=
end(); i++) {
524 this_position.
set_x3(this_position.
x3() + z_offset);
525 this_position.
set_x1(this_position.
x1() + x_offset);
526 this_position.
set_x0(simulation_time);
527 i->set_4position(this_position);
528 i->set_formation_time(simulation_time);
534 external_particles->
insert(*
p);
541 centerpoint +=
p->position();
543 centerpoint /=
size();
570 const auto result =
integrate(0.01, 1, -1, 1, [&](
double t,
double cosx) {
571 const double r = (1 - t) / t;
572 return twopi * std::pow(r, 2.0) *
580 return out <<
" #particles #testparticles mass [GeV] "
581 "radius [fm] diffusiveness [fm]\n"
582 <<
format(
n.number_of_particles(),
nullptr, 12)
584 <<
format(
n.get_nuclear_radius(),
nullptr, 14)
585 <<
format(
n.get_diffusiveness(),
nullptr, 20);
591 return is_projectile || is_target;
597 if (is_projectile == is_target) {
598 throw std::logic_error(
599 "Error parsing configuration of EITHER projectile OR target.\n"
600 "Configuration tested for it contains the following:\n------------\n" +
601 config.
to_string() +
"\n------------\n");
603 return is_projectile;
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.
std::string to_string() const
Return a string of the current YAML tree.
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...
bool has_section(const KeyLabels &labels) const
Return whether there is a (possibly empty) section with the given labels.
T take(const Key< T > &key)
The default interface for SMASH to read configuration values.
The FourVector class holds relevant values in Minkowski spacetime with (+, −, −, −) metric signature.
ThreeVector threevec() const
A C++ interface for numerical integration in two dimensions with the Cuba Cuhre integration function.
A nucleus is a collection of particles that are initialized, before the beginning of the simulation a...
Nucleus()=default
default constructor
double euler_theta_
Euler angle theta.
std::vector< ParticleData >::const_iterator cbegin() const
For const iterators over the particle list:
virtual double nucleon_density_unnormalized(double r, double, double) const
Return the unnormalized Woods-Saxon distribution for the given position without deformation.
void shift(double z_offset, double x_offset, double simulation_time)
Shifts the nucleus to correct impact parameter and z displacement.
double get_saturation_density() const
double woods_saxon(double x)
Woods-Saxon distribution.
void random_euler_angles()
Randomly generate Euler angles.
virtual void arrange_nucleons()
Sets the positions of the nucleons inside a nucleus.
virtual double calculate_saturation_density() const
double default_nuclear_radius()
Default nuclear radius calculated as:
double diffusiveness_
Diffusiveness of Woods-Saxon distribution of this nucleus in fm (for diffusiveness_ == 0,...
double saturation_density_
Saturation density of this nucleus.
FourVector center() const
Calculate geometrical center of the nucleus.
virtual void generate_fermi_momenta()
Generates momenta according to Fermi motion for the nucleons.
virtual void set_parameters_automatic()
Sets the deformation parameters of the Woods-Saxon distribution according to the current mass number.
std::vector< ParticleData >::const_iterator cend() const
For const iterators over the particle list:
size_t size() const
Number of numerical (=test-)particles in the nucleus:
size_t testparticles_
Number of testparticles per physical particle.
virtual double nucleon_density(double r, double, double) const
Return the Woods-Saxon probability density for the given position.
double euler_phi_
The Euler angle phi of the three Euler angles used to apply rotations to the nucleus.
double nuclear_radius_
Nuclear radius of this nucleus.
void fill_from_list(const std::map< PdgCode, int > &particle_list, int testparticles)
Adds particles from a map PDG code => Number_of_particles_with_that_PDG_code to the nucleus.
std::vector< ParticleData > particles_
Particles associated with this nucleus.
double euler_psi_
Euler angle psi.
void make_nucleus_unpolarized()
Set unpolarized spin vectors for all particles in the nucleus.
void align_center()
Shifts the nucleus so that its center is at (0,0,0)
void copy_particles(Particles *particles)
Copies the particles from this nucleus into the particle list.
virtual void set_saturation_density(double density)
Sets the saturation density of the nucleus.
void set_nuclear_radius(double rad)
Sets the nuclear radius.
bool random_rotation_
Whether the nucleus should be rotated randomly.
void set_diffusiveness(double diffuse)
Sets the diffusiveness of the nucleus.
virtual void rotate()
Rotates the nucleus using the three euler angles phi, theta and psi.
std::vector< ParticleData >::iterator begin()
For iterators over the particle list:
size_t number_of_protons() const
Number of physical protons in the nucleus:
void boost(double beta_scalar)
Boosts the nuclei into the computational frame, such that the nucleons have the appropriate momentum ...
virtual ThreeVector distribute_nucleon()
The distribution of return values from this function is according to a spherically symmetric Woods-Sa...
size_t number_of_particles() const
Number of physical particles in the nucleus:
void set_orientation_from_config(Configuration &orientation_config)
Set angles for rotation of the nucleus from config file.
std::vector< ParticleData >::iterator end()
For iterators over the particle list:
ParticleData contains the dynamic information of a certain particle.
PdgCode pdgcode() const
Get the pdgcode of the particle.
void set_4momentum(const FourVector &momentum_vector)
Set the particle's 4-momentum directly.
const FourVector & momentum() const
Get the particle's 4-momentum.
double pole_mass() const
Get the particle's pole mass ("on-shell").
void set_3momentum(const ThreeVector &mom)
Set the momentum of the particle without modifying the energy.
const FourVector & position() const
Get the particle's position in Minkowski space.
Particle type contains the static properties of a particle species.
static const ParticleType & find(PdgCode pdgcode)
Returns the ParticleType object for the given pdgcode.
The Particles class abstracts the storage and manipulation of particles.
const ParticleData & insert(const ParticleData &p)
Inserts the particle into the list of particles.
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.
SpinInteractionType
Possible spin interaction types.
@ Off
No spin interactions.
std::ostream & operator<<(std::ostream &out, const ActionPtr &action)
Convenience: dereferences the ActionPtr to Action.
std::array< einhard::Logger<>, std::tuple_size< LogArea::AreaTuple >::value > logg
An array that stores all pre-configured Logger objects.
FormattingHelper< T > format(const T &value, const char *unit, int width=-1, int precision=-1)
Acts as a stream modifier for std::ostream to output an object with an optional suffix string and wit...
bool almost_equal(const N x, const N y)
Checks whether two floating-point numbers are almost equal.
static Integrator integrate
bool has_projectile_or_target(const Configuration &config)
Find out whether a configuration has a projectile or a target sub-section.
constexpr double hbarc
GeV <-> fm conversion factor.
bool is_about_projectile(const Configuration &config)
Find out whether a configuration is about projectile or target.
static constexpr int LNucleus
Generic numerical functions.