Version: SMASH-3.4
collidermodus.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012-2026
3  * SMASH Team
4  *
5  * GNU General Public License (GPLv3 or later)
6  */
7 
8 #include "smash/collidermodus.h"
9 
10 #include <algorithm>
11 #include <cmath>
12 #include <cstdlib>
13 #include <cstring>
14 #include <memory>
15 #include <stdexcept>
16 #include <string>
17 #include <tuple>
18 #include <utility>
19 #include <vector>
20 
21 #include "smash/configuration.h"
22 #include "smash/customnucleus.h"
25 #include "smash/fourvector.h"
26 #include "smash/icparameters.h"
27 #include "smash/input_keys.h"
28 #include "smash/logging.h"
29 #include "smash/nucleus.h"
30 #include "smash/random.h"
31 
32 namespace smash {
33 static constexpr int LCollider = LogArea::Collider::id;
34 static constexpr int LInitialConditions = LogArea::InitialConditions::id;
35 
37  const ExperimentParameters &params) {
38  Configuration modus_cfg = modus_config.extract_complete_sub_configuration(
40  // Get the reference frame for the collision calculation.
42 
45  Configuration targ_cfg =
47  /* Needed to check if projectile and target in customnucleus are read from
48  * the same input file.*/
49  bool same_file = false;
50  // Set up the projectile nucleus
52  projectile_ =
53  create_deformed_nucleus(proj_cfg, params.testparticles, "projectile");
54  } else if (proj_cfg.has_section(InputSections::m_c_p_custom)) {
55  same_file = same_inputfile(proj_cfg, targ_cfg);
56  projectile_ = std::make_unique<CustomNucleus>(
57  proj_cfg, params.testparticles, same_file);
58  } else if (proj_cfg.has_section(InputSections::m_c_p_alphaClustered)) {
59  logg[LCollider].info() << "Projectile is alpha-clustered with woods-saxon "
60  "parameters for the He-clusters listed below.";
62  "projectile");
63  } else {
64  projectile_ = std::make_unique<Nucleus>(proj_cfg, params.testparticles);
65  }
67 
68  // Set up the target nucleus
70  target_ = create_deformed_nucleus(targ_cfg, params.testparticles, "target");
71  } else if (targ_cfg.has_section(InputSections::m_c_t_custom)) {
72  target_ = std::make_unique<CustomNucleus>(targ_cfg, params.testparticles,
73  same_file);
74  } else if (targ_cfg.has_section(InputSections::m_c_t_alphaClustered)) {
75  logg[LCollider].info() << "Target is alpha-clustered with woods-saxon "
76  "parameters for the He-clusters listed below.";
77  target_ =
78  create_alphaclustered_nucleus(targ_cfg, params.testparticles, "target");
79  } else {
80  target_ = std::make_unique<Nucleus>(targ_cfg, params.testparticles);
81  }
82  target_->set_label(BelongsTo::Target);
83 
84  // Get the Fermi-Motion input (off, on, frozen)
87  logg[LCollider].info() << "Fermi motion is ON.";
88  } else if (fermi_motion_ == FermiMotion::Frozen) {
89  logg[LCollider].info() << "FROZEN Fermi motion is on.";
90  } else if (fermi_motion_ == FermiMotion::Off) {
91  logg[LCollider].info() << "Fermi motion is OFF.";
92  }
93 
94  // Get the total nucleus-nucleus collision energy. Since there is
95  // no meaningful choice for a default energy, we require the user to
96  // give one (and only one) energy input from the available options.
97  int energy_input = 0;
98  const double mass_projec = projectile_->mass();
99  const double mass_target = target_->mass();
100  // average mass of a particle in that nucleus
101  const double mass_a =
102  projectile_->mass() / projectile_->number_of_particles();
103  const double mass_b = target_->mass() / target_->number_of_particles();
104  // Option 1: Center of mass energy.
107  // Check that input satisfies the lower bound (everything at rest).
108  if (sqrt_s_NN_ <= mass_a + mass_b) {
110  "Input Error: sqrt(s_NN) is not larger than masses:\n" +
111  std::to_string(sqrt_s_NN_) + " GeV <= " + std::to_string(mass_a) +
112  " GeV + " + std::to_string(mass_b) + " GeV.");
113  }
114  // Set the total nucleus-nucleus collision energy.
115  total_s_ = (sqrt_s_NN_ * sqrt_s_NN_ - mass_a * mass_a - mass_b * mass_b) *
116  mass_projec * mass_target / (mass_a * mass_b) +
117  mass_projec * mass_projec + mass_target * mass_target;
118  energy_input++;
119  }
120  /* Option 2: Total energy per nucleon of the projectile nucleus
121  * (target at rest). */
122  if (modus_cfg.has_value(InputKeys::modi_collider_eTot)) {
123  const double e_tot = modus_cfg.take(InputKeys::modi_collider_eTot);
124  if (e_tot < 0) {
126  "Input Error: "
127  "E_Tot must be nonnegative.");
128  }
129  // Set the total nucleus-nucleus collision energy.
130  total_s_ = s_from_Etot(e_tot * projectile_->number_of_particles(),
131  mass_projec, mass_target);
132  sqrt_s_NN_ = std::sqrt(s_from_Etot(e_tot, mass_a, mass_b));
133  energy_input++;
134  }
135  /* Option 3: Kinetic energy per nucleon of the projectile nucleus
136  * (target at rest). */
137  if (modus_cfg.has_value(InputKeys::modi_collider_eKin)) {
138  const double e_kin = modus_cfg.take(InputKeys::modi_collider_eKin);
139  // Set the total nucleus-nucleus collision energy.
140  total_s_ = s_from_Ekin(e_kin * projectile_->number_of_particles(),
141  mass_projec, mass_target);
142  sqrt_s_NN_ = std::sqrt(s_from_Ekin(e_kin, mass_a, mass_b));
143  energy_input++;
144  }
145  // Option 4: Momentum of the projectile nucleus (target at rest).
146  if (modus_cfg.has_value(InputKeys::modi_collider_pLab)) {
147  const double p_lab = modus_cfg.take(InputKeys::modi_collider_pLab);
148  // Set the total nucleus-nucleus collision energy.
149  total_s_ = s_from_plab(p_lab * projectile_->number_of_particles(),
150  mass_projec, mass_target);
151  sqrt_s_NN_ = std::sqrt(s_from_plab(p_lab, mass_a, mass_b));
152  energy_input++;
153  }
154  // Option 5: Total energy per nucleon of _each_ beam
157  const double e_tot_p =
159  const double e_tot_t = targ_cfg.take(InputKeys::modi_collider_target_eTot);
160  total_s_ = s_from_Etot(e_tot_p * projectile_->number_of_particles(),
161  e_tot_t * target_->number_of_particles(),
162  mass_projec, mass_target);
163  sqrt_s_NN_ = std::sqrt(s_from_Ekin(e_tot_p, e_tot_t, mass_a, mass_b));
164  energy_input++;
165  }
166  // Option 6: Kinetic energy per nucleon of _each_ beam
169  const double e_kin_p =
171  const double e_kin_t = targ_cfg.take(InputKeys::modi_collider_target_eKin);
172  total_s_ = s_from_Ekin(e_kin_p * projectile_->number_of_particles(),
173  e_kin_t * target_->number_of_particles(),
174  mass_projec, mass_target);
175  sqrt_s_NN_ = std::sqrt(s_from_Ekin(e_kin_p, e_kin_t, mass_a, mass_b));
176  energy_input++;
177  }
178  // Option 7: Momentum per nucleon of _each_ beam
181  const double p_lab_p =
183  const double p_lab_t = targ_cfg.take(InputKeys::modi_collider_target_pLab);
184  total_s_ = s_from_plab(p_lab_p * projectile_->number_of_particles(),
185  p_lab_t * target_->number_of_particles(),
186  mass_projec, mass_target);
187  sqrt_s_NN_ = std::sqrt(s_from_plab(p_lab_p, p_lab_t, mass_a, mass_b));
188  energy_input++;
189  }
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.");
194  }
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.");
199  }
200 
201  /* Impact parameter setting: Either "Value", "Range", "Max" or "Sample".
202  * Unspecified means 0 impact parameter.*/
205  imp_min_ = impact_;
206  imp_max_ = impact_;
207  } else {
208  // If impact is not supplied by value, inspect sampling parameters:
211  if (sampling_ == Sampling::Custom) {
214  throw std::invalid_argument(
215  "Input Error: Need impact parameter spectrum for custom sampling."
216  " Please provide Values and Yields.");
217  }
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.");
226  }
227  impact_interpolation_ = std::make_unique<InterpolateDataLinear<double>>(
228  InterpolateDataLinear<double>(impacts, yields));
229 
230  const auto imp_minmax =
231  std::minmax_element(impacts.begin(), impacts.end());
232  imp_min_ = *imp_minmax.first;
233  imp_max_ = *imp_minmax.second;
234  yield_max_ = *std::max_element(yields.begin(), yields.end());
235  }
236  }
238  const std::array<double, 2> range =
240  imp_min_ = range[0];
241  imp_max_ = range[1];
242  }
244  imp_min_ = 0.0;
246  }
247  }
248  /// \todo include a check that only one method of specifying impact is used
249  // whether the direction of separation should be randomly sampled
252  // Look for user-defined initial separation between nuclei.
253  // The displacement is half the distance (both nuclei are shifted
254  // initial_z_displacement_ away from origin)
258  IC_for_hybrid_ = true;
259  IC_parameters_ = std::make_unique<InitialConditionParameters>();
260  IC_parameters_->type =
262 
265  if (modus_cfg.has_value(
267  IC_parameters_->proper_time = modus_cfg.take(
269  } else {
270  IC_parameters_->lower_bound = modus_cfg.take(
272  IC_parameters_->proper_time_scaling =
274  }
275  IC_parameters_->rapidity_cut = modus_cfg.take(
277  IC_parameters_->pT_cut =
280  } else if (IC_parameters_->type == FluidizationType::Dynamic) {
282  double threshold = modus_cfg.take(
284  double min_time =
286  double max_time =
288  int cells =
290  double form_time_fraction = modus_cfg.take(
292  if (max_time < min_time) {
293  logg[LInitialConditions].fatal()
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.");
298  }
299 
300  IC_parameters_->fluidizable_processes = modus_cfg.take(
302 
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};
307 
309  std::make_unique<RectangularLattice<EnergyMomentumTensor>>(
310  length, cell_array, origin, false, LatticeUpdate::EveryTimestep);
311  fluid_background_ = std::make_unique<std::map<int32_t, double>>();
312 
313  IC_parameters_->energy_density_threshold = threshold;
314  IC_parameters_->min_time = min_time;
315  IC_parameters_->max_time = max_time;
316  IC_parameters_->num_fluid_cells = cells;
317  logg[LInitialConditions].info()
318  << "Preparing dynamic Initial Conditions with threshold " << threshold
319  << " GeV/fm³ in energy density, between " << min_time << " and "
320  << max_time << " fm.";
321  IC_parameters_->formation_time_fraction = form_time_fraction;
322  IC_parameters_->smearing_kernel_at_0 =
323  std::pow(2 * M_PI * params.gaussian_sigma, -1.5);
324  IC_parameters_->delay_initial_elastic = modus_cfg.take(
326  }
327  }
328 }
329 
331  const double rapidity = IC_parameters_->rapidity_cut.value();
332  const double pT = IC_parameters_->pT_cut.value();
333  std::ostringstream message{"Extracting iso-tau initial conditions ",
334  std::ios_base::ate};
335  std::vector<std::string> cuts{};
336  if (rapidity > 0.0) {
337  cuts.emplace_back("|y| <= ");
338  cuts.back() += std::to_string(rapidity);
339  }
340  if (pT > 0.0) {
341  cuts.emplace_back("pT <= ");
342  cuts.back() += std::to_string(pT) + " GeV.";
343  }
344  if (cuts.size() > 0) {
345  message << "in kinematic range: " << join(cuts, "; ") << ".";
346  } else {
347  message << "without kinematic cuts.";
348  }
349  logg[LInitialConditions].info() << message.str();
350 }
351 
352 std::ostream &operator<<(std::ostream &out, const ColliderModus &m) {
353  return out << "-- Collider Modus:\n"
354  << "sqrt(S) (nucleus-nucleus) = "
355  << format(std::sqrt(m.total_s_), "GeV\n")
356  << "sqrt(S) (nucleon-nucleon) = " << format(m.sqrt_s_NN_, "GeV\n")
357  << "Projectile:\n"
358  << *m.projectile_ << "\nTarget:\n"
359  << *m.target_;
360 }
361 
362 std::unique_ptr<DeformedNucleus> ColliderModus::create_deformed_nucleus(
363  Configuration &nucleus_cfg, int ntest, const std::string &nucleus_type) {
364  assert(has_projectile_or_target(nucleus_cfg));
365  const bool is_projectile = is_about_projectile(nucleus_cfg);
366  const auto &[automatic_key, beta2_key, beta3_key, beta4_key,
367  gamma_key] = [&is_projectile]() {
368  return is_projectile
369  ? std::make_tuple(
375  : std::make_tuple(
381  }();
382 
383  bool automatic_deformation = nucleus_cfg.take(automatic_key);
384  bool was_any_beta_given = nucleus_cfg.has_value(beta2_key) ||
385  nucleus_cfg.has_value(beta3_key) ||
386  nucleus_cfg.has_value(beta4_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 =
390  nucleus_cfg.has_value(gamma_key) && !nucleus_cfg.has_value(beta2_key);
391 
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.");
408  } else {
409  return std::make_unique<DeformedNucleus>(nucleus_cfg, ntest,
410  automatic_deformation);
411  }
412 }
413 
414 std::unique_ptr<AlphaClusteredNucleus>
416  int ntest,
417  const std::string &nucleus_type) {
418  const bool is_projectile = is_about_projectile(nucleus_cfg);
419  const auto &[automatic_key, side_length_key] = [&is_projectile]() {
420  return is_projectile
421  ? std::make_tuple(
422  InputKeys::
423  modi_collider_projectile_alphaClustered_automatic,
424  InputKeys::
425  modi_collider_projectile_alphaClustered_sideLength)
426  : std::make_tuple(
429  }();
430 
431  bool automatic_alphaclustering = nucleus_cfg.take(automatic_key);
432  bool was_sidelength_given = nucleus_cfg.has_value(side_length_key);
433 
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 "
439  "file.");
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.");
445  } else {
446  return std::make_unique<AlphaClusteredNucleus>(nucleus_cfg, ntest,
447  automatic_alphaclustering);
448  }
449 }
450 
452  const ExperimentParameters &) {
453  // Populate the nuclei with appropriately distributed nucleons.
454  // If deformed, this includes rotating the nucleus.
455  projectile_->arrange_nucleons();
456  target_->arrange_nucleons();
457 
458  // Use the total mandelstam variable to get the frame-dependent velocity for
459  // each nucleus. Position a is projectile, position b is target.
460  double v_a, v_b;
461  std::tie(v_a, v_b) =
462  get_velocities(total_s_, projectile_->mass(), target_->mass());
463 
464  // If velocities are larger or equal to 1, throw an exception.
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.");
470  }
471 
472  // Calculate the beam velocity of the projectile and the target, which will
473  // be used to calculate the beam momenta in experiment.cc
475  velocity_projectile_ = v_a;
476  velocity_target_ = v_b;
477  }
478 
479  // Generate Fermi momenta if necessary
482  // Frozen: Fermi momenta will be ignored during the propagation to
483  // avoid that the nuclei will fly apart.
484  projectile_->generate_fermi_momenta();
485  target_->generate_fermi_momenta();
486  } else if (fermi_motion_ == FermiMotion::Off) {
487  } else {
488  throw std::invalid_argument("Invalid Fermi_Motion input.");
489  }
490 
491  // Boost the nuclei to the appropriate velocity.
492  projectile_->boost(v_a);
493  target_->boost(v_b);
494 
495  // Shift the nuclei into starting positions. Contracted spheres with
496  // nuclear radii should touch exactly at t=0. Modus starts at negative
497  // time corresponding to additional initial displacement.
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();
502  const double dz = initial_z_displacement_;
503 
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);
508  // rotation angle in the transverse plane
509  const double phi =
510  random_reaction_plane_ ? random::uniform(0.0, 2.0 * M_PI) : 0.0;
511 
512  projectile_->shift(proj_z, +impact_ / 2.0, simulation_time);
513  target_->shift(targ_z, -impact_ / 2.0, simulation_time);
514 
515  // Put the particles in the nuclei into code particles.
516  projectile_->copy_particles(particles);
517  target_->copy_particles(particles);
518  rotate_reaction_plane(phi, particles);
519  return simulation_time;
520 }
521 
522 void ColliderModus::rotate_reaction_plane(double phi, Particles *particles) {
523  for (ParticleData &p : *particles) {
524  ThreeVector pos = p.position().threevec();
525  ThreeVector mom = p.momentum().threevec();
526  pos.rotate_around_z(phi);
527  mom.rotate_around_z(phi);
528  p.set_3position(pos);
529  p.set_3momentum(mom);
530  }
531 }
532 
534  switch (sampling_) {
535  case Sampling::Quadratic: {
536  // quadratic sampling: Note that for bmin > bmax, this still yields
537  // the correct distribution (however canonical() = 0 is then the
538  // upper end, not the lower).
539  impact_ = std::sqrt(imp_min_ * imp_min_ +
542  } break;
543  case Sampling::Custom: {
544  // rejection sampling based on given distribution
545  assert(impact_interpolation_ != nullptr);
546  double probability_random = 1;
547  double probability = 0;
548  double b;
549  while (probability_random > probability) {
551  probability = (*impact_interpolation_)(b) / yield_max_;
552  assert(probability < 1.);
553  probability_random = random::uniform(0., 1.);
554  }
555  impact_ = b;
556  } break;
557  case Sampling::Uniform: {
558  // linear sampling. Still, min > max works fine.
560  }
561  }
562 }
563 
564 std::pair<double, double> ColliderModus::get_velocities(double s, double m_a,
565  double m_b) {
566  double v_a = 0.0;
567  double v_b = 0.0;
568  // Frame dependent calculations of velocities. Assume v_a >= 0, v_b <= 0.
569  switch (frame_) {
571  v_a = center_of_velocity_v(s, m_a, m_b);
572  v_b = -v_a;
573  break;
575  // Compute center of mass momentum.
576  double pCM = pCM_from_s(s, m_a, m_b);
577  v_a = pCM / std::sqrt(m_a * m_a + pCM * pCM);
578  v_b = -pCM / std::sqrt(m_b * m_b + pCM * pCM);
579  } break;
581  v_a = fixed_target_projectile_v(s, m_a, m_b);
582  break;
583  default:
584  throw std::invalid_argument(
585  "Invalid reference frame in "
586  "ColliderModus::get_velocities.");
587  }
588  return std::make_pair(v_a, v_b);
589 }
590 
591 std::string ColliderModus::custom_file_path(const std::string &file_directory,
592  const std::string &file_name) {
593  // make sure that path is correct even if the / at the end is missing
594  if (file_directory.back() == '/') {
595  return file_directory + file_name;
596  } else {
597  return file_directory + '/' + file_name;
598  }
599 }
600 
602  Configuration &targ_config) {
603  /* Check if both nuclei are custom
604  * Only check target as function is called after if statement for
605  * projectile.
606  */
607  if (!targ_config.has_section(InputSections::m_c_t_custom)) {
608  return false;
609  }
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 =
618  // Check if files are the same for projectile and target
619  std::string proj_path =
620  custom_file_path(projectile_file_directory, projectile_file_name);
621  std::string targ_path =
622  custom_file_path(target_file_directory, target_file_name);
623  if (proj_path == targ_path) {
624  return true;
625  } else {
626  return false;
627  }
628 }
629 
631  const double t, const std::vector<Particles> &ensembles,
632  const DensityParameters &dens_par) {
633  if (fluid_lattice_ == nullptr) {
634  throw std::logic_error(
635  "Trying to build fluidization lattice with unset pointer in "
636  "ColliderModus.");
637  }
638  if (t < IC_parameters_->min_time.value() ||
639  t > IC_parameters_->max_time.value()) {
640  return;
641  }
642  const double resizing_rate = 5;
643  double side = fluid_lattice_->lattice_sizes()[0] / 2.;
644  if (t > side) {
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";
651  }
652 
655  dens_par, ensembles, false);
656 }
657 
658 } // namespace smash
ColliderModus: Provides a modus for colliding nuclei.
Definition: collidermodus.h:48
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 &parameters)
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 &parameters)
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.
Definition: density.h:92
static bool remove_particle_
Whether fluidization actions remove the particle from the evolution.
Represent a piecewise linear interpolation.
Definition: interpolation.h:67
double length() const
Definition: modusdefault.h:93
ParticleData contains the dynamic information of a certain particle.
Definition: particledata.h:59
The Particles class abstracts the storage and manipulation of particles.
Definition: particles.h:33
The ThreeVector class represents a physical three-vector with the components .
Definition: threevector.h:31
void rotate_around_z(double theta)
Rotate the vector around the z axis by the given angle theta.
Definition: threevector.h:324
@ 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.
Definition: action.h:546
std::array< einhard::Logger<>, std::tuple_size< LogArea::AreaTuple >::value > & logg
An array that stores all pre-configured Logger objects.
Definition: logging.h:245
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...
Definition: logging.h:217
constexpr Section m_c_p_deformed
Subsection for the deformed projectile in collider modus.
Definition: input_keys.h:177
constexpr Section m_collider
Subsection for the collider modus.
Definition: input_keys.h:161
constexpr Section m_c_t_deformed
Subsection for the deformed target in collider modus.
Definition: input_keys.h:190
constexpr Section m_c_target
Subsection for the target in collider modus.
Definition: input_keys.h:183
constexpr Section m_c_t_alphaClustered
Subsection for the alpha-clustered target in collider modus.
Definition: input_keys.h:185
constexpr Section m_c_p_custom
Subsection for the custom projectile in collider modus.
Definition: input_keys.h:174
constexpr Section m_c_p_alphaClustered
Subsection for the alpha-clustered projectile in collider modus.
Definition: input_keys.h:171
constexpr Section m_c_initialConditions
Subsection for the initial conditions in collider modus.
Definition: input_keys.h:165
constexpr Section m_c_projectile
Subsection for the projectile in collider modus.
Definition: input_keys.h:168
constexpr Section m_c_t_custom
Subsection for the custom target in collider modus.
Definition: input_keys.h:188
constexpr int p
Proton.
T uniform(T min, T max)
Definition: random.h:91
T canonical()
Definition: random.h:122
Definition: action.h:24
T pCM(const T sqrts, const T mass_a, const T mass_b) noexcept
Definition: kinematics.h:79
static constexpr int LInitialConditions
Definition: experiment.h:95
double fixed_target_projectile_v(double s, double ma, double mb)
Definition: kinematics.h:39
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...
Definition: kinematics.h:254
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.
Definition: density.h:654
std::string to_string(ThermodynamicQuantity quantity)
Convert a ThermodynamicQuantity enum value to its corresponding string.
Definition: stringify.cc:26
double center_of_velocity_v(double s, double ma, double mb)
Definition: kinematics.h:26
bool has_projectile_or_target(const Configuration &config)
Find out whether a configuration has a projectile or a target sub-section.
Definition: nucleus.cc:588
bool is_about_projectile(const Configuration &config)
Find out whether a configuration is about projectile or target.
Definition: nucleus.cc:594
T pCM_from_s(const T s, const T mass_a, const T mass_b) noexcept
Definition: kinematics.h:66
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...
Definition: kinematics.h:226
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...
Definition: kinematics.h:280
Helper structure for Experiment.
int testparticles
Number of test-particles.
double gaussian_sigma
Width of gaussian Wigner density of particles.
A container to keep track of all ever existed input keys.
Definition: input_keys.h:1255
static const Key< double > modi_collider_projectile_eKin
See user guide description for more information.
Definition: input_keys.h:4320
static const Key< double > modi_collider_target_pLab
See user guide description for more information.
Definition: input_keys.h:4383
static const Key< double > modi_collider_target_eTot
See user guide description for more information.
Definition: input_keys.h:4351
static const Key< double > modi_collider_initialDistance
See user guide description for more information.
Definition: input_keys.h:4166
static const Key< bool > modi_collider_projectile_deformed_automatic
See user guide description for more information.
Definition: input_keys.h:4492
static const Key< double > modi_collider_projectile_deformed_beta3
See user guide description for more information.
Definition: input_keys.h:4542
static const Key< std::string > modi_collider_projectile_custom_fileDirectory
See user guide description for more information.
Definition: input_keys.h:4407
static const Key< double > modi_collider_eKin
See user guide description for more information.
Definition: input_keys.h:4029
static const Key< double > modi_collider_pLab
See user guide description for more information.
Definition: input_keys.h:4066
static const Key< bool > modi_collider_initialConditions_delayInitialElastic
See user guide description for more information.
Definition: input_keys.h:5178
static const Key< FluidizationType > modi_collider_initialConditions_type
See user guide description for more information.
Definition: input_keys.h:4954
static const Key< double > modi_collider_sqrtSNN
See user guide description for more information.
Definition: input_keys.h:4083
static const Key< int > modi_collider_initialConditions_fluidCells
See user guide description for more information.
Definition: input_keys.h:5129
static const Key< std::vector< double > > modi_collider_impact_values
See user guide description for more information.
Definition: input_keys.h:4904
static const Key< double > modi_collider_impact_value
See user guide description for more information.
Definition: input_keys.h:4882
static const Key< double > modi_collider_projectile_deformed_beta4
See user guide description for more information.
Definition: input_keys.h:4568
static const Key< bool > modi_collider_impact_randomReactionPlane
See user guide description for more information.
Definition: input_keys.h:4817
static const Key< double > modi_collider_initialConditions_scaling
See user guide description for more information.
Definition: input_keys.h:5015
static const Key< std::array< double, 2 > > modi_collider_impact_range
See user guide description for more information.
Definition: input_keys.h:4834
static const Key< double > modi_collider_initialConditions_maxTime
See user guide description for more information.
Definition: input_keys.h:5112
static const Key< double > modi_collider_initialConditions_minTime
See user guide description for more information.
Definition: input_keys.h:5095
static const Key< FluidizableProcessesBitSet > modi_collider_initialConditions_fluidProcesses
See user guide description for more information.
Definition: input_keys.h:5159
static const Key< bool > modi_collider_target_deformed_automatic
See user guide description for more information.
Definition: input_keys.h:4499
static const Key< double > modi_collider_initialConditions_eDenThreshold
See user guide description for more information.
Definition: input_keys.h:5077
static const Key< double > modi_collider_target_eKin
See user guide description for more information.
Definition: input_keys.h:4327
static const Key< CalculationFrame > modi_collider_calculationFrame
See user guide description for more information.
Definition: input_keys.h:4109
static const Key< double > modi_collider_impact_max
See user guide description for more information.
Definition: input_keys.h:4800
static const Key< std::vector< double > > modi_collider_impact_yields
See user guide description for more information.
Definition: input_keys.h:4928
static const Key< double > modi_collider_initialConditions_formTimeFraction
See user guide description for more information.
Definition: input_keys.h:5198
static const Key< double > modi_collider_target_deformed_beta2
See user guide description for more information.
Definition: input_keys.h:4524
static const Key< double > modi_collider_target_alphaClustered_sideLength
See user guide description for more information.
Definition: input_keys.h:4670
static const Key< double > modi_collider_target_deformed_beta4
See user guide description for more information.
Definition: input_keys.h:4576
static const Key< double > modi_collider_initialConditions_lowerBound
See user guide description for more information.
Definition: input_keys.h:4972
static const Key< double > modi_collider_eTot
See user guide description for more information.
Definition: input_keys.h:4047
static const Key< std::string > modi_collider_target_custom_fileName
See user guide description for more information.
Definition: input_keys.h:4447
static const Key< double > modi_collider_projectile_deformed_beta2
See user guide description for more information.
Definition: input_keys.h:4516
static const Key< std::string > modi_collider_projectile_custom_fileName
See user guide description for more information.
Definition: input_keys.h:4434
static const Key< double > modi_collider_projectile_deformed_gamma
See user guide description for more information.
Definition: input_keys.h:4593
static const Key< double > modi_collider_projectile_pLab
See user guide description for more information.
Definition: input_keys.h:4376
static const Key< double > modi_collider_target_deformed_gamma
See user guide description for more information.
Definition: input_keys.h:4601
static const Key< Sampling > modi_collider_impact_sample
See user guide description for more information.
Definition: input_keys.h:4866
static const Key< double > modi_collider_initialConditions_rapidityCut
See user guide description for more information.
Definition: input_keys.h:5057
static const Key< double > modi_collider_projectile_eTot
See user guide description for more information.
Definition: input_keys.h:4344
static const Key< std::string > modi_collider_target_custom_fileDirectory
See user guide description for more information.
Definition: input_keys.h:4417
static const Key< FermiMotion > modi_collider_fermiMotion
See user guide description for more information.
Definition: input_keys.h:4146
static const Key< double > modi_collider_initialConditions_properTime
See user guide description for more information.
Definition: input_keys.h:4995
static const Key< double > modi_collider_initialConditions_pTCut
See user guide description for more information.
Definition: input_keys.h:5036
static const Key< bool > modi_collider_target_alphaClustered_automatic
See user guide description for more information.
Definition: input_keys.h:4643
static const Key< double > modi_collider_target_deformed_beta3
See user guide description for more information.
Definition: input_keys.h:4550
Thrown when the requested energy is smaller than the masses of two particles.
Definition: modusdefault.h:203