33 static constexpr
int LCollider = LogArea::Collider::id;
49 bool same_file =
false;
59 logg[
LCollider].info() <<
"Projectile is alpha-clustered with woods-saxon "
60 "parameters for the He-clusters listed below.";
75 logg[
LCollider].info() <<
"Target is alpha-clustered with woods-saxon "
76 "parameters for the He-clusters listed below.";
99 const double mass_target =
target_->mass();
101 const double mass_a =
103 const double mass_b =
target_->mass() /
target_->number_of_particles();
110 "Input Error: sqrt(s_NN) is not larger than masses:\n" +
116 mass_projec * mass_target / (mass_a * mass_b) +
117 mass_projec * mass_projec + mass_target * mass_target;
127 "E_Tot must be nonnegative.");
131 mass_projec, mass_target);
141 mass_projec, mass_target);
150 mass_projec, mass_target);
157 const double e_tot_p =
161 e_tot_t *
target_->number_of_particles(),
162 mass_projec, mass_target);
169 const double e_kin_p =
173 e_kin_t *
target_->number_of_particles(),
174 mass_projec, mass_target);
181 const double p_lab_p =
185 p_lab_t *
target_->number_of_particles(),
186 mass_projec, mass_target);
190 if (energy_input == 0) {
191 throw std::domain_error(
192 "Input Error: Non-existent collision energy. "
193 "Please provide one of Sqrtsnn/E_Kin/P_Lab.");
195 if (energy_input > 1) {
196 throw std::invalid_argument(
197 "Input Error: Redundant collision energy. "
198 "Please provide only one of Sqrtsnn/E_Kin/P_Lab.");
214 throw std::invalid_argument(
215 "Input Error: Need impact parameter spectrum for custom sampling."
216 " Please provide Values and Yields.");
218 const std::vector<double> impacts =
220 const std::vector<double> yields =
222 if (impacts.size() != yields.size()) {
223 throw std::invalid_argument(
224 "Input Error: Need as many impact parameter values as yields. "
225 "Please make sure that Values and Yields have the same length.");
230 const auto imp_minmax =
231 std::minmax_element(impacts.begin(), impacts.end());
234 yield_max_ = *std::max_element(yields.begin(), yields.end());
238 const std::array<double, 2> range =
282 double threshold = modus_cfg.
take(
290 double form_time_fraction = modus_cfg.
take(
292 if (max_time < min_time) {
294 <<
"Bad parameters chosen for dynamic initial conditions:\n"
295 <<
" Maximum_Time = " << max_time <<
" > " << min_time
296 <<
" = Minimum_Time";
297 throw std::invalid_argument(
"Please adjust the configuration file.");
303 double min_size = std::max(min_time, 40.);
304 std::array<double, 3>
length{2 * min_size, 2 * min_size, 2 * min_size};
305 std::array<double, 3> origin{-min_size, -min_size, -min_size};
306 std::array<int, 3> cell_array{cells, cells, cells};
309 std::make_unique<RectangularLattice<EnergyMomentumTensor>>(
318 <<
"Preparing dynamic Initial Conditions with threshold " << threshold
319 <<
" GeV/fm³ in energy density, between " << min_time <<
" and "
320 << max_time <<
" fm.";
333 std::ostringstream message{
"Extracting iso-tau initial conditions ",
335 std::vector<std::string> cuts{};
336 if (rapidity > 0.0) {
337 cuts.emplace_back(
"|y| <= ");
341 cuts.emplace_back(
"pT <= ");
344 if (cuts.size() > 0) {
345 message <<
"in kinematic range: " <<
join(cuts,
"; ") <<
".";
347 message <<
"without kinematic cuts.";
353 return out <<
"-- Collider Modus:\n"
354 <<
"sqrt(S) (nucleus-nucleus) = "
363 Configuration &nucleus_cfg,
int ntest,
const std::string &nucleus_type) {
366 const auto &[automatic_key, beta2_key, beta3_key, beta4_key,
367 gamma_key] = [&is_projectile]() {
383 bool automatic_deformation = nucleus_cfg.
take(automatic_key);
384 bool was_any_beta_given = nucleus_cfg.
has_value(beta2_key) ||
387 bool was_any_deformation_parameter_given =
388 was_any_beta_given || nucleus_cfg.
has_value(gamma_key);
389 bool was_gamma_given_without_beta_2 =
392 if (automatic_deformation && was_any_deformation_parameter_given) {
393 throw std::invalid_argument(
394 "Automatic deformation of " + nucleus_type +
395 " nucleus requested, but deformation parameter(s) were provided as"
396 " well. Please, check the 'Deformed' section in your input file.");
397 }
else if (!automatic_deformation && !was_any_beta_given) {
398 throw std::invalid_argument(
399 "Manual deformation of " + nucleus_type +
400 " nucleus requested, but no deformation beta parameter was provided."
401 " Please, check the 'Deformed' section in your input file.");
402 }
else if (!automatic_deformation && was_gamma_given_without_beta_2) {
403 throw std::invalid_argument(
404 "Manual deformation of " + nucleus_type +
405 " nucleus requested, but 'Gamma' parameter was provided without "
406 "providing a value of 'Beta_2' having hence no deformation effect. "
407 "Please, check the 'Deformed' section in your input file.");
409 return std::make_unique<DeformedNucleus>(nucleus_cfg, ntest,
410 automatic_deformation);
414 std::unique_ptr<AlphaClusteredNucleus>
417 const std::string &nucleus_type) {
419 const auto &[automatic_key, side_length_key] = [&is_projectile]() {
423 modi_collider_projectile_alphaClustered_automatic,
425 modi_collider_projectile_alphaClustered_sideLength)
431 bool automatic_alphaclustering = nucleus_cfg.
take(automatic_key);
432 bool was_sidelength_given = nucleus_cfg.
has_value(side_length_key);
434 if (automatic_alphaclustering && was_sidelength_given) {
435 throw std::invalid_argument(
436 "Automatic alpha-clustering of " + nucleus_type +
437 " nucleus requested, but a sidelength was provided as"
438 " well. Please, check the 'Alpha_Clustered' section in your input "
440 }
else if (!automatic_alphaclustering && !was_sidelength_given) {
441 throw std::invalid_argument(
442 "Manual alpha-clustering of " + nucleus_type +
443 " nucleus requested, but no sidelength was provided."
444 " Please, check the 'Alpha_Clustered' section in your input file.");
446 return std::make_unique<AlphaClusteredNucleus>(nucleus_cfg, ntest,
447 automatic_alphaclustering);
465 if (v_a >= 1.0 || v_b >= 1.0) {
466 throw std::domain_error(
467 "Found velocity equal to or larger than 1 in "
468 "ColliderModus::initial_conditions.\nConsider using "
469 "the center of velocity reference frame.");
485 target_->generate_fermi_momenta();
488 throw std::invalid_argument(
"Invalid Fermi_Motion input.");
498 const double d_a = std::max(0.,
projectile_->get_diffusiveness());
499 const double d_b = std::max(0.,
target_->get_diffusiveness());
500 const double r_a =
projectile_->get_nuclear_radius();
501 const double r_b =
target_->get_nuclear_radius();
504 const double simulation_time = -dz / std::abs(v_a);
505 const double proj_z = -dz - std::sqrt(1.0 - v_a * v_a) * (r_a + d_a);
506 const double targ_z =
507 +dz * std::abs(v_b / v_a) + std::sqrt(1.0 - v_b * v_b) * (r_b + d_b);
517 target_->copy_particles(particles);
519 return simulation_time;
528 p.set_3position(pos);
529 p.set_3momentum(mom);
546 double probability_random = 1;
547 double probability = 0;
549 while (probability_random > probability) {
551 probability = (*impact_interpolation_)(b) /
yield_max_;
552 assert(probability < 1.);
577 v_a =
pCM / std::sqrt(m_a * m_a +
pCM *
pCM);
578 v_b = -
pCM / std::sqrt(m_b * m_b +
pCM *
pCM);
584 throw std::invalid_argument(
585 "Invalid reference frame in "
586 "ColliderModus::get_velocities.");
588 return std::make_pair(v_a, v_b);
592 const std::string &file_name) {
594 if (file_directory.back() ==
'/') {
595 return file_directory + file_name;
597 return file_directory +
'/' + file_name;
610 std::string projectile_file_directory = proj_config.
read(
612 std::string target_file_directory =
614 std::string projectile_file_name =
616 std::string target_file_name =
619 std::string proj_path =
621 std::string targ_path =
623 if (proj_path == targ_path) {
631 const double t,
const std::vector<Particles> &ensembles,
634 throw std::logic_error(
635 "Trying to build fluidization lattice with unset pointer in "
638 if (t < IC_parameters_->min_time.value() ||
642 const double resizing_rate = 5;
645 side += resizing_rate;
646 std::array<double, 3> new_length{2 * side, 2 * side, 2 * side};
647 std::array<double, 3> new_origin{-side, -side, -side};
648 fluid_lattice_->reset_and_resize(new_length, new_origin, std::nullopt);
649 logg[
LCollider].debug() <<
"Fluidization lattice resizing at " << t
650 <<
" fm to " << 2 * side <<
" fm";
655 dens_par, ensembles,
false);
ColliderModus: Provides a modus for colliding nuclei.
CalculationFrame frame_
Reference frame for the system, as specified from config.
double imp_min_
Minimum value of impact parameter.
double initial_z_displacement_
Initial z-displacement of nuclei.
bool IC_for_hybrid_
Whether the particles will serve as initial conditions for hydrodynamics.
double yield_max_
Maximum value of yield. Needed for custom impact parameter sampling.
void log_IC_kinematic_range() noexcept
Print information about the input kinematic range for the Initial Conditions output.
bool random_reaction_plane_
Whether the reaction plane should be randomized.
void rotate_reaction_plane(double phi, Particles *particles)
Rotate the reaction plane about the angle phi.
std::pair< double, double > get_velocities(double mandelstam_s, double m_a, double m_b)
Get the frame dependent velocity for each nucleus, using the current reference frame.
void sample_impact()
Sample impact parameter.
std::unique_ptr< Nucleus > projectile_
Projectile.
std::unique_ptr< InterpolateDataLinear< double > > impact_interpolation_
Pointer to the impact parameter interpolation.
FermiMotion fermi_motion_
An option to include Fermi motion ("off", "on", "frozen")
static std::unique_ptr< AlphaClusteredNucleus > create_alphaclustered_nucleus(Configuration &nucleus_cfg, const int ntest, const std::string &nucleus_type)
Configure Alpha-Clustered Nucleus.
double velocity_projectile_
Beam velocity of the projectile.
Sampling sampling_
Method used for sampling of impact parameter.
std::unique_ptr< RectangularLattice< EnergyMomentumTensor > > fluid_lattice_
Energy-momentum tensor lattice for dynamic fluidization.
std::string custom_file_path(const std::string &file_directory, const std::string &file_name)
Creates full path string consisting of file_directory and file_name Needed to initialize a customnucl...
double total_s_
Center-of-mass energy squared of the nucleus-nucleus collision.
std::unique_ptr< Nucleus > target_
Target.
ColliderModus(Configuration modus_config, const ExperimentParameters ¶meters)
Constructor.
double impact_
Impact parameter.
double sqrt_s_NN_
Center-of-mass energy of a nucleon-nucleon collision.
double initial_conditions(Particles *particles, const ExperimentParameters ¶meters)
Generates initial state of the particles in the system.
void build_fluidization_lattice(double t, const std::vector< Particles > &ensembles, const DensityParameters &dens_par)
Build lattice of energy momentum tensor.
bool same_inputfile(Configuration &proj_config, Configuration &targ_config)
Checks if target and projectile are read from the same external file if they are both initialized as ...
std::unique_ptr< std::map< int32_t, double > > fluid_background_
Energy density background from hydrodynamic evolution, with particle indices as keys.
static std::unique_ptr< DeformedNucleus > create_deformed_nucleus(Configuration &nucleus_cfg, const int ntest, const std::string &nucleus_type)
Configure Deformed Nucleus.
double velocity_target_
Beam velocity of the target.
std::unique_ptr< InitialConditionParameters > IC_parameters_
Plain Old Data type to hold parameters for initial conditions.
double imp_max_
Maximum value of impact parameter.
Interface to the SMASH configuration files.
T read(const Key< T > &key) const
Additional interface for SMASH to read configuration values without removing them.
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.
Configuration extract_complete_sub_configuration(KeyLabels section, Configuration::GetEmpty empty_if_not_existing=Configuration::GetEmpty::No)
Alternative method to extract a sub-configuration, which retains the labels from the top-level in the...
T take(const Key< T > &key)
The default interface for SMASH to read configuration values.
A class to pre-calculate and store parameters relevant for density calculation.
static bool remove_particle_
Whether fluidization actions remove the particle from the evolution.
Represent a piecewise linear interpolation.
ParticleData contains the dynamic information of a certain particle.
The Particles class abstracts the storage and manipulation of particles.
The ThreeVector class represents a physical three-vector with the components .
void rotate_around_z(double theta)
Rotate the vector around the z axis by the given angle theta.
@ On
Use fermi motion in combination with potentials.
@ Frozen
Use fermi motion without potentials.
@ Off
Don't use fermi motion.
@ ConstantTau
Hypersurface crossed at a fixed proper time.
@ Dynamic
Dynamic fluidization based on local densities.
@ Quadratic
Sample from areal / quadratic distribution.
@ Custom
Sample from custom, user-defined distribution.
@ Uniform
Sample from uniform distribution.
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...
T pCM(const T sqrts, const T mass_a, const T mass_b) noexcept
static constexpr int LInitialConditions
double fixed_target_projectile_v(double s, double ma, double mb)
double s_from_Ekin(double e_kin, double m_P, double m_T)
Convert E_kin to Mandelstam-s for a fixed-target setup, with a projectile of mass m_P and a kinetic e...
void update_lattice_accumulating_ensembles(RectangularLattice< T > *lat, const LatticeUpdate update, const DensityType dens_type, const DensityParameters &par, const std::vector< Particles > &ensembles, const bool compute_gradient)
Updates the contents on the lattice when ensembles are used.
std::string to_string(ThermodynamicQuantity quantity)
Convert a ThermodynamicQuantity enum value to its corresponding string.
double center_of_velocity_v(double s, double ma, double mb)
bool has_projectile_or_target(const Configuration &config)
Find out whether a configuration has a projectile or a target sub-section.
bool is_about_projectile(const Configuration &config)
Find out whether a configuration is about projectile or target.
T pCM_from_s(const T s, const T mass_a, const T mass_b) noexcept
static constexpr int LCollider
std::string join(const std::vector< std::string > &v, std::string_view delim)
Join strings using delimiter.
double s_from_Etot(double e_tot, double m_P, double m_T)
Convert E_tot to Mandelstam-s for a fixed-target setup, with a projectile of mass m_P and a total ene...
double s_from_plab(double plab, double m_P, double m_T)
Convert p_lab to Mandelstam-s for a fixed-target setup, with a projectile of mass m_P and momentum pl...
Helper structure for Experiment.
int testparticles
Number of test-particles.
double gaussian_sigma
Width of gaussian Wigner density of particles.
Thrown when the requested energy is smaller than the masses of two particles.