7 #ifndef SRC_INCLUDE_EXPERIMENT_H_ 8 #define SRC_INCLUDE_EXPERIMENT_H_ 55 template <
typename T,
typename Ratio>
57 const chrono::duration<T, Ratio> &seconds) {
58 using Seconds = chrono::duration<double>;
59 using Minutes = chrono::duration<double, std::ratio<60>>;
60 using Hours = chrono::duration<double, std::ratio<60 * 60>>;
61 constexpr Minutes threshold_for_minutes{10};
62 constexpr Hours threshold_for_hours{3};
63 if (seconds < threshold_for_minutes) {
64 return out << Seconds(seconds).count() <<
" [s]";
66 if (seconds < threshold_for_hours) {
67 return out << Minutes(seconds).count() <<
" [min]";
69 return out << Hours(seconds).count() <<
" [h]";
112 const bf::path &output_path);
120 virtual void run() = 0;
128 using std::invalid_argument::invalid_argument;
132 template <
typename Modus>
134 template <
typename Modus>
135 std::ostream &operator<<(std::ostream &out, const Experiment<Modus> &e);
161 template <
typename Modus>
238 template <
typename Container>
240 const Container &particles_before_actions);
388 std::unique_ptr<RectangularLattice<FourVector>>
UB_lat_ =
nullptr;
394 std::unique_ptr<RectangularLattice<FourVector>>
UI3_lat_ =
nullptr;
397 std::unique_ptr<RectangularLattice<std::pair<ThreeVector, ThreeVector>>>
401 std::unique_ptr<RectangularLattice<std::pair<ThreeVector, ThreeVector>>>
405 std::unique_ptr<RectangularLattice<EnergyMomentumTensor>>
Tmn_;
531 friend std::ostream &operator<<<>(std::ostream &out,
const Experiment &e);
535 template <
typename Modus>
536 std::ostream &operator<<(std::ostream &out, const Experiment<Modus> &e) {
537 out <<
"End time: " << e.end_time_ <<
" fm/c\n";
542 template <
typename Modus>
544 const std::string &content,
545 const bf::path &output_path,
547 const auto &log = logger<LogArea::Experiment>();
548 log.info() <<
"Adding output " << content <<
" of format " <<
format 551 if (
format ==
"VTK" && content ==
"Particles") {
552 outputs_.emplace_back(
553 make_unique<VtkOutput>(output_path, content, out_par));
554 }
else if (
format ==
"Root") {
555 #ifdef SMASH_USE_ROOT 556 outputs_.emplace_back(
557 make_unique<RootOutput>(output_path, content, out_par));
559 log.error(
"Root output requested, but Root support not compiled in");
561 }
else if (
format ==
"Binary") {
562 if (content ==
"Collisions" || content ==
"Dileptons" ||
563 content ==
"Photons") {
564 outputs_.emplace_back(
565 make_unique<BinaryOutputCollisions>(output_path, content, out_par));
566 }
else if (content ==
"Particles") {
567 outputs_.emplace_back(
568 make_unique<BinaryOutputParticles>(output_path, content, out_par));
570 }
else if (
format ==
"Oscar1999" ||
format ==
"Oscar2013") {
571 outputs_.emplace_back(
573 }
else if (content ==
"Thermodynamics" &&
format ==
"ASCII") {
574 outputs_.emplace_back(
575 make_unique<ThermodynamicOutput>(output_path, content, out_par));
576 }
else if (content ==
"Thermodynamics" &&
format ==
"VTK") {
577 printout_lattice_td_ =
true;
578 outputs_.emplace_back(
579 make_unique<VtkOutput>(output_path, content, out_par));
581 log.error() <<
"Unknown combination of format (" <<
format 582 <<
") and content (" << content <<
"). Fix the config.";
708 template <
typename Modus>
712 modus_(config[
"Modi"], parameters_),
714 nevents_(config.take({
"General",
"Nevents"})),
715 end_time_(config.take({
"General",
"End_Time"})),
716 delta_time_startup_(parameters_.labclock.timestep_duration()),
718 config.take({
"Collision_Term",
"Force_Decays_At_End"},
true)),
719 use_grid_(config.take({
"General",
"Use_Grid"},
true)),
722 config.take({
"General",
"Expansion_Rate"}, 0.1)),
723 dileptons_switch_(config.has_value({
"Output",
"Dileptons"})),
724 photons_switch_(config.has_value({
"Output",
"Photons"})),
727 const auto &log = logger<LogArea::Experiment>();
731 if (dileptons_switch_) {
732 dilepton_finder_ = make_unique<DecayActionsFinderDilepton>();
734 if (parameters_.photons_switch) {
735 n_fractional_photons_ = config.take({
"Output",
"Photons",
"Fractions"});
737 if (parameters_.two_to_one) {
738 action_finders_.emplace_back(make_unique<DecayActionsFinder>());
740 bool no_coll = config.take({
"Collision_Term",
"No_Collisions"},
false);
741 if ((parameters_.two_to_one || parameters_.included_2to2.any() ||
742 parameters_.strings_switch) &&
744 auto scat_finder = make_unique<ScatterActionsFinder>(
745 config, parameters_, nucleon_has_interacted_, modus_.total_N_number(),
746 modus_.proj_N_number());
747 max_transverse_distance_sqr_ =
748 scat_finder->max_transverse_distance_sqr(parameters_.testparticles);
749 process_string_ptr_ = scat_finder->get_process_string_ptr();
750 action_finders_.emplace_back(std::move(scat_finder));
753 process_string_ptr_ = NULL;
755 const double modus_l = modus_.length();
757 action_finders_.emplace_back(make_unique<WallCrossActionsFinder>(modus_l));
760 if (config.has_value({
"Collision_Term",
"Pauli_Blocking"})) {
761 log.info() <<
"Pauli blocking is ON.";
762 pauli_blocker_ = make_unique<PauliBlocker>(
763 config[
"Collision_Term"][
"Pauli_Blocking"], parameters_);
766 config.take({
"Collision_Term",
"Power_Particle_Formation"}, -1.);
804 auto output_conf = config[
"Output"];
1024 log.debug() <<
"Density type printed to headers: " << dens_type_;
1026 const OutputParameters output_parameters(std::move(output_conf));
1028 std::vector<std::string> output_contents = output_conf.list_upmost_nodes();
1029 for (
const auto &content : output_contents) {
1030 auto this_output_conf = output_conf[content.c_str()];
1031 std::vector<std::string> formats = this_output_conf.take({
"Format"});
1032 for (
const auto &
format : formats) {
1033 create_output(
format, content, output_path, output_parameters);
1044 if (config.has_value({
"Potentials"})) {
1046 log.error() <<
"Potentials only work with time steps!";
1047 throw std::invalid_argument(
"Can't use potentials without time steps!");
1050 log.error() <<
"Potentials don't work with frozen Fermi momenta! " 1051 "Use normal Fermi motion instead.";
1052 throw std::invalid_argument(
1053 "Can't use potentials " 1054 "with frozen Fermi momenta!");
1056 log.info() <<
"Potentials are ON. Timestep is " 1057 << parameters_.labclock.timestep_duration();
1059 potentials_ = make_unique<Potentials>(config[
"Potentials"], parameters_);
1117 if (config.has_value({
"Lattice"})) {
1119 const std::array<double, 3> l = config.take({
"Lattice",
"Sizes"});
1120 const std::array<int, 3>
n = config.take({
"Lattice",
"Cell_Number"});
1121 const std::array<double, 3> origin = config.take({
"Lattice",
"Origin"});
1122 const bool periodic = config.take({
"Lattice",
"Periodic"});
1124 if (printout_lattice_td_) {
1125 dens_type_lattice_printout_ = output_parameters.td_dens_type;
1126 printout_tmn_ = output_parameters.td_tmn;
1127 printout_tmn_landau_ = output_parameters.td_tmn_landau;
1128 printout_v_landau_ = output_parameters.td_v_landau;
1130 if (printout_tmn_ || printout_tmn_landau_ || printout_v_landau_) {
1131 Tmn_ = make_unique<RectangularLattice<EnergyMomentumTensor>>(
1138 if (potentials_->use_skyrme()) {
1139 jmu_B_lat_ = make_unique<DensityLattice>(l,
n, origin, periodic,
1141 UB_lat_ = make_unique<RectangularLattice<FourVector>>(
1144 RectangularLattice<std::pair<ThreeVector, ThreeVector>>>(
1147 if (potentials_->use_symmetry()) {
1148 jmu_I3_lat_ = make_unique<DensityLattice>(l,
n, origin, periodic,
1150 UI3_lat_ = make_unique<RectangularLattice<FourVector>>(
1153 RectangularLattice<std::pair<ThreeVector, ThreeVector>>>(
1158 jmu_B_lat_ = make_unique<DensityLattice>(l,
n, origin, periodic,
1162 jmu_I3_lat_ = make_unique<DensityLattice>(l,
n, origin, periodic,
1169 jmu_custom_lat_ = make_unique<DensityLattice>(l,
n, origin, periodic,
1172 }
else if (printout_lattice_td_) {
1174 "If you want Thermodynamic VTK output, configure a lattice for it.");
1178 if (parameters_.potential_affect_threshold) {
1185 if (config.has_value({
"Forced_Thermalization"})) {
1186 Configuration &&th_conf = config[
"Forced_Thermalization"];
1187 thermalizer_ = modus_.create_grandcan_thermalizer(th_conf);
1192 seed_ = config.take({
"General",
"Randomseed"});
1196 const std::string
hline(67,
'-');
1198 template <
typename Modus>
1200 const auto &log = logger<LogArea::Experiment>();
1203 log.info() <<
"random number seed: " << seed_;
1210 while (r == INT64_MIN) {
1213 seed_ = std::abs(r);
1218 if (process_string_ptr_ != NULL) {
1219 process_string_ptr_->init_pythia_hadron_rndm();
1225 double start_time = modus_.initial_conditions(&particles_, parameters_);
1229 modus_.impose_boundary_conditions(&particles_, outputs_);
1231 double timestep = delta_time_startup_;
1233 switch (time_step_mode_) {
1237 timestep = end_time_ - start_time;
1239 const double max_dt = modus_.max_timestep(max_transverse_distance_sqr_);
1240 if (max_dt > 0. && max_dt < timestep) {
1245 Clock clock_for_this_event(start_time, timestep);
1246 parameters_.labclock = std::move(clock_for_this_event);
1249 const double dt_output = parameters_.outputclock.timestep_duration();
1250 const double zeroth_output_time =
1251 std::floor(start_time / dt_output) * dt_output;
1252 Clock output_clock(zeroth_output_time, dt_output);
1253 parameters_.outputclock = std::move(output_clock);
1255 log.debug(
"Lab clock: t_start = ", parameters_.labclock.current_time(),
1256 ", dt = ", parameters_.labclock.timestep_duration());
1257 log.debug(
"Output clock: t_start = ", parameters_.outputclock.current_time(),
1258 ", dt = ", parameters_.outputclock.timestep_duration());
1263 wall_actions_total_ = 0;
1264 previous_wall_actions_total_ = 0;
1265 interactions_total_ = 0;
1266 previous_interactions_total_ = 0;
1267 total_pauli_blocked_ = 0;
1269 log.info() <<
hline;
1270 log.info() <<
"Time [fm] Ediff [GeV] Scatt.|Decays " 1271 "Particles Timing ";
1272 log.info() <<
hline;
1275 template <
typename Modus>
1276 template <
typename Container>
1278 Action &action,
const Container &particles_before_actions) {
1279 const auto &log = logger<LogArea::Experiment>();
1281 if (!action.
is_valid(particles_)) {
1282 log.debug(~
einhard::DRed(),
"✘ ", action,
" (discarded: invalid)");
1286 log.debug(
"Process Type is: ", action.
get_type());
1287 if (pauli_blocker_ && action.
is_pauli_blocked(particles_, *pauli_blocker_)) {
1288 total_pauli_blocked_++;
1291 if (modus_.is_collider()) {
1295 assert(incoming.id() >= 0);
1296 if (incoming.id() < modus_.total_N_number()) {
1297 nucleon_has_interacted_[incoming.id()] =
true;
1303 const auto id_process =
static_cast<uint32_t
>(interactions_total_ + 1);
1304 action.
perform(&particles_, id_process);
1305 interactions_total_++;
1307 wall_actions_total_++;
1313 constexpr
bool compute_grad =
false;
1314 rho = std::get<0>(
rho_eckart(r_interaction.threevec(),
1315 particles_before_actions, density_param_,
1316 dens_type_, compute_grad));
1333 for (
const auto &output : outputs_) {
1334 if (!output->is_dilepton_output() && !output->is_photon_output()) {
1335 output->at_interaction(action, rho);
1344 if (photons_switch_ &&
1350 constexpr
double action_time = 0.;
1352 n_fractional_photons_,
1368 photon_act.add_single_process();
1370 photon_act.perform_photons(outputs_);
1397 uint64_t scatterings_this_interval,
1398 const QuantumNumbers &conserved_initial,
1401 template <
typename Modus>
1405 const auto &log = logger<LogArea::Experiment>();
1409 parameters_.labclock.current_time());
1411 while (parameters_.labclock.current_time() < end_time_) {
1412 const double t = parameters_.labclock.current_time();
1414 std::min(parameters_.labclock.timestep_duration(), end_time_ - t);
1415 log.debug(
"Timestepless propagation for next ", dt,
" fm/c.");
1419 thermalizer_->is_time_to_thermalize(parameters_.labclock)) {
1420 const bool ignore_cells_under_treshold =
true;
1421 thermalizer_->update_thermalizer_lattice(particles_, density_param_,
1422 ignore_cells_under_treshold);
1423 const double current_t = parameters_.labclock.current_time();
1424 thermalizer_->thermalize(particles_, current_t,
1425 parameters_.testparticles);
1428 perform_action(th_act, particles_);
1433 double min_cell_length = compute_min_cell_length(dt);
1434 log.debug(
"Creating grid with minimal cell length ", min_cell_length);
1435 const auto &grid = use_grid_
1436 ? modus_.create_grid(particles_, min_cell_length)
1437 : modus_.create_grid(particles_, min_cell_length,
1442 [&](
const ParticleList &search_list) {
1443 for (
const auto &finder : action_finders_) {
1444 actions.
insert(finder->find_actions_in_cell(search_list, dt));
1447 [&](
const ParticleList &search_list,
1448 const ParticleList &neighbors_list) {
1449 for (
const auto &finder : action_finders_) {
1450 actions.
insert(finder->find_actions_with_neighbors(
1451 search_list, neighbors_list, dt));
1458 run_time_evolution_timestepless(actions);
1463 update_potentials();
1464 update_momenta(&particles_, parameters_.labclock.timestep_duration(),
1465 *potentials_, FB_lat_.get(), FI3_lat_.get());
1474 ++parameters_.labclock;
1482 if (!potentials_ && !parameters_.strings_switch &&
1484 std::string err_msg = conserved_initial_.report_deviations(particles_);
1485 if (!err_msg.empty()) {
1486 log.error() << err_msg;
1487 throw std::runtime_error(
"Violation of conserved quantities!");
1492 if (pauli_blocker_) {
1493 log.info(
"Interactions: Pauli-blocked/performed = ", total_pauli_blocked_,
1494 "/", interactions_total_ - wall_actions_total_);
1498 template <
typename Modus>
1502 if (dilepton_finder_ !=
nullptr) {
1503 for (
const auto &output : outputs_) {
1504 dilepton_finder_->shine(particles_, output.get(), dt);
1517 constexpr uint64_t max_uint32 = std::numeric_limits<uint32_t>::max();
1518 if (interactions_total >= max_uint32) {
1519 throw std::runtime_error(
"Integer overflow in total interaction number!");
1523 template <
typename Modus>
1525 const auto &log = logger<LogArea::Experiment>();
1527 const double start_time = parameters_.labclock.current_time();
1528 const double end_time = std::min(parameters_.labclock.next_time(), end_time_);
1529 double time_left = end_time - start_time;
1530 log.debug(
"Timestepless propagation: ",
"Actions size = ", actions.
size(),
1531 ", start time = ", start_time,
", end time = ", end_time);
1536 ActionPtr act = actions.
pop();
1537 if (!act->is_valid(particles_)) {
1538 log.debug(~
einhard::DRed(),
"✘ ", act,
" (discarded: invalid)");
1541 if (act->time_of_execution() > end_time) {
1542 log.error(act,
" scheduled later than end time: t_action[fm/c] = ",
1543 act->time_of_execution(),
", t_end[fm/c] = ", end_time);
1547 while (next_output_time() <= act->time_of_execution()) {
1548 log.debug(
"Propagating until output time: ", next_output_time());
1549 propagate_and_shine(next_output_time());
1550 ++parameters_.outputclock;
1551 intermediate_output();
1555 log.debug(
"Propagating until next action ", act,
1556 ", action time = ", act->time_of_execution());
1557 propagate_and_shine(act->time_of_execution());
1564 act->update_incoming(particles_);
1566 const bool performed = perform_action(*act, particles_);
1576 time_left = end_time - act->time_of_execution();
1577 const ParticleList &outgoing_particles = act->outgoing_particles();
1578 for (
const auto &finder : action_finders_) {
1581 finder->find_actions_in_cell(outgoing_particles, time_left));
1583 actions.
insert(finder->find_actions_with_surrounding_particles(
1584 outgoing_particles, particles_, time_left));
1590 while (next_output_time() <= end_time) {
1591 log.debug(
"Propagating until output time: ", next_output_time());
1592 propagate_and_shine(next_output_time());
1593 ++parameters_.outputclock;
1595 if (parameters_.outputclock.current_time() < end_time_) {
1596 intermediate_output();
1600 log.debug(
"Propagating to time ", end_time);
1601 propagate_and_shine(end_time);
1604 template <
typename Modus>
1606 const auto &log = logger<LogArea::Experiment>();
1607 const uint64_t wall_actions_this_interval =
1608 wall_actions_total_ - previous_wall_actions_total_;
1609 previous_wall_actions_total_ = wall_actions_total_;
1610 const uint64_t interactions_this_interval = interactions_total_ -
1611 previous_interactions_total_ -
1612 wall_actions_this_interval;
1613 previous_interactions_total_ = interactions_total_;
1615 conserved_initial_, time_start_,
1616 parameters_.outputclock.current_time());
1619 for (
const auto &output : outputs_) {
1620 if (output->is_dilepton_output() || output->is_photon_output()) {
1623 output->at_intermediate_time(particles_, parameters_.outputclock,
1627 switch (dens_type_lattice_printout_) {
1630 density_param_, particles_,
false);
1636 density_param_, particles_,
false);
1645 dens_type_lattice_printout_, density_param_, particles_,
1648 dens_type_lattice_printout_,
1651 if (printout_tmn_ || printout_tmn_landau_ || printout_v_landau_) {
1653 density_param_, particles_);
1654 if (printout_tmn_) {
1656 dens_type_lattice_printout_, *Tmn_);
1658 if (printout_tmn_landau_) {
1660 dens_type_lattice_printout_, *Tmn_);
1662 if (printout_v_landau_) {
1664 dens_type_lattice_printout_, *Tmn_);
1669 output->thermodynamics_output(*thermalizer_);
1674 template <
typename Modus>
1677 if (potentials_->use_skyrme() && jmu_B_lat_ !=
nullptr) {
1680 const size_t UBlattice_size = UB_lat_->size();
1681 for (
size_t i = 0; i < UBlattice_size; i++) {
1682 auto jB = (*jmu_B_lat_)[i];
1684 ? jB.jmu_net() / jB.density()
1687 flow_four_velocity * potentials_->skyrme_pot(jB.density());
1688 (*FB_lat_)[i] = potentials_->skyrme_force(jB.density(), jB.grad_rho(),
1689 jB.dj_dt(), jB.rot_j());
1692 if (potentials_->use_symmetry() && jmu_I3_lat_ !=
nullptr) {
1696 const size_t UI3lattice_size = UI3_lat_->size();
1697 for (
size_t i = 0; i < UI3lattice_size; i++) {
1698 auto jI3 = (*jmu_I3_lat_)[i];
1700 abs(jI3.density()) >
really_small ? jI3.jmu_net() / jI3.density()
1703 flow_four_velocity * potentials_->symmetry_pot(jI3.density());
1704 (*FI3_lat_)[i] = potentials_->symmetry_force(jI3.grad_rho(),
1705 jI3.dj_dt(), jI3.rot_j());
1711 template <
typename Modus>
1715 uint64_t interactions_old;
1716 const auto particles_before_actions = particles_.copy_to_vector();
1720 interactions_old = interactions_total_;
1723 if (dilepton_finder_ !=
nullptr) {
1724 for (
const auto &output : outputs_) {
1725 dilepton_finder_->shine_final(particles_, output.get(),
true);
1729 for (
const auto &finder : action_finders_) {
1730 actions.
insert(finder->find_final_actions(particles_));
1734 perform_action(*actions.
pop(), particles_before_actions);
1737 }
while (interactions_total_ > interactions_old);
1740 if (dilepton_finder_ !=
nullptr) {
1741 for (
const auto &output : outputs_) {
1742 dilepton_finder_->shine_final(particles_, output.get(),
false);
1747 template <
typename Modus>
1749 const auto &log = logger<LogArea::Experiment>();
1753 if (
likely(parameters_.labclock > 0)) {
1754 const uint64_t wall_actions_this_interval =
1755 wall_actions_total_ - previous_wall_actions_total_;
1756 const uint64_t interactions_this_interval = interactions_total_ -
1757 previous_interactions_total_ -
1758 wall_actions_this_interval;
1760 conserved_initial_, time_start_,
1761 parameters_.outputclock.current_time());
1762 log.info() <<
hline;
1763 log.info() <<
"Time real: " << SystemClock::now() - time_start_;
1764 log.info() <<
"Final interaction number: " 1765 << interactions_total_ - wall_actions_total_;
1767 int unformed_particles_count = 0;
1768 for (
const auto &particle : particles_) {
1769 if (particle.formation_time() > end_time_) {
1770 unformed_particles_count++;
1773 if (unformed_particles_count > 0) {
1774 log.warn(
"End time might be too small. ", unformed_particles_count,
1775 " unformed particles were found at the end of the evolution.");
1779 for (
const auto &output : outputs_) {
1780 output->at_eventend(particles_, evt_num, modus_.impact_parameter());
1784 template <
typename Modus>
1786 const auto &mainlog = logger<LogArea::Main>();
1787 for (
int j = 0; j < nevents_; j++) {
1788 mainlog.info() <<
"Event " << j;
1791 initialize_new_event();
1799 if (modus_.is_collider()) {
1800 if (!modus_.cll_in_nucleus()) {
1801 nucleon_has_interacted_.assign(modus_.total_N_number(),
false);
1803 nucleon_has_interacted_.assign(modus_.total_N_number(),
true);
1809 for (
int i = 0; i < modus_.total_N_number(); i++) {
1810 const auto mass_beam = particles_.copy_to_vector()[i].effective_mass();
1811 const auto v_beam = i < modus_.proj_N_number()
1812 ? modus_.velocity_projectile()
1813 : modus_.velocity_target();
1814 const auto gamma = 1.0 / std::sqrt(1.0 - v_beam * v_beam);
1815 beam_momentum_.emplace_back(
FourVector(gamma * mass_beam, 0.0, 0.0,
1816 gamma * v_beam * mass_beam));
1821 for (
const auto &output : outputs_) {
1822 output->at_eventstart(particles_, j);
1825 run_time_evolution();
1827 if (force_decays_) {
1838 #endif // SRC_INCLUDE_EXPERIMENT_H_ 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...
The main class, where the simulation of an experiment is executed.
Experiment(Configuration config, const bf::path &output_path)
Create a new Experiment.
A class to pre-calculate and store parameters relevant for density calculation.
OutputPtr photon_output_
The Photon output.
Potentials * pot_pointer
Pointer to a Potential class.
FermiMotion
Option to use Fermi Motion.
void check_interactions_total(uint64_t interactions_total)
Make sure interactions_total can be represented as a 32-bit integer.
virtual void run()=0
Runs the experiment.
static std::unique_ptr< ExperimentBase > create(Configuration config, const bf::path &output_path)
Factory method that creates and initializes a new Experiment<Modus>.
virtual void generate_final_state()=0
Generate the final state for this action.
int64_t seed_
random seed for the next event.
std::unique_ptr< RectangularLattice< EnergyMomentumTensor > > Tmn_
Lattices of energy-momentum tensors for printout.
double next_output_time() const
Shortcut for next output time.
FourVector get_interaction_point() const
Get the interaction point.
constexpr double really_small
Numerical error tolerance.
double propagate_straight_line(Particles *particles, double to_time, const std::vector< FourVector > &beam_momentum)
Propagates the positions of all particles on a straight line to a given moment.
void run_time_evolution()
Runs the time evolution of an event with fixed-sized time steps or without timesteps, from action to actions.
The Actions class abstracts the storage and manipulation of actions.
std::unique_ptr< DensityLattice > jmu_custom_lat_
Custom density on the lattices.
String excitation processes used in SMASH.
std::unique_ptr< RectangularLattice< std::pair< ThreeVector, ThreeVector > > > FB_lat_
Lattices for the electric and magnetic components of the Skyrme force.
uint64_t total_pauli_blocked_
Total number of Pauli-blockings for current timestep.
RectangularLattice< FourVector > * UI3_lat_pointer
Pointer to the symmmetry potential on the lattice.
void final_output(const int evt_num)
Output at the end of an event.
#define likely(x)
Tell the branch predictor that this expression is likely true.
std::unique_ptr< RectangularLattice< FourVector > > UB_lat_
Lattices for Skyrme potentials (evaluated in the local rest frame) times the baryon flow 4-velocity...
void update_momenta(Particles *particles, double dt, const Potentials &pot, RectangularLattice< std::pair< ThreeVector, ThreeVector >> *FB_lat, RectangularLattice< std::pair< ThreeVector, ThreeVector >> *FI3_lat)
Updates the momenta of all particles at the current time step according to the equations of motion: ...
void insert(ActionList &&new_acts)
Insert a list of actions into this object.
std::unique_ptr< DecayActionsFinderDilepton > dilepton_finder_
The Dilepton Action Finder.
void update_lattice(RectangularLattice< T > *lat, const LatticeUpdate update, const DensityType dens_type, const DensityParameters &par, const Particles &particles, const bool compute_gradient=false)
Updates the contents on the lattice.
std::tuple< double, ThreeVector, ThreeVector, ThreeVector > rho_eckart(const ThreeVector &r, const ParticleList &plist, const DensityParameters &par, DensityType dens_type, bool compute_gradient)
Calculates Eckart rest frame density and optionally the gradient of the density in an arbitary frame...
bool is_valid(const Particles &particles) const
Check whether the action still applies.
const TimeStepMode time_step_mode_
This indicates whether to use time steps.
constexpr double fm2_mb
mb <-> fm^2 conversion factor.
void set_seed(T &&seed)
Sets the seed of the random number engine.
LatticeUpdate
Enumerator option for lattice updates.
uint64_t wall_actions_total_
Total number of wall-crossings for current timestep.
double compute_min_cell_length(double dt) const
Calculate the minimal size for the grid cells such that the ScatterActionsFinder will find all collis...
Interface to the SMASH configuration files.
void do_final_decays()
Performs the final decays of an event.
constexpr double maximum_cross_section
The maximal cross section (in mb) for which it is guaranteed that all collisions with this cross sect...
Non-template interface to Experiment<Modus>.
ExperimentParameters create_experiment_parameters(Configuration config)
Gathers all general Experiment parameters.
std::unique_ptr< GrandCanThermalizer > thermalizer_
Instance of class used for forced thermalization.
const bool force_decays_
This indicates whether we force all resonances to decay in the last timestep.
StringProcess * process_string_ptr_
Pointer to the string process class object, which is used to set the random seed for PYTHIA objects i...
int n_fractional_photons_
Number of fractional photons produced per single reaction.
QuantumNumbers conserved_initial_
The conserved quantities of the system.
void propagate_and_shine(double to_time)
Propagate all particles until time to_time without any interactions and shine dileptons.
ThermalizationAction implements forced thermalization as an Action class.
ExperimentParameters parameters_
Struct of several member variables.
void update_potentials()
Recompute potentials on lattices if necessary.
const bool use_grid_
This indicates whether to use the grid.
bool printout_tmn_landau_
Whether to print the energy-momentum tensor in Landau frame.
Particles particles_
Complete particle list.
const std::string hline(67, '-')
String representing a horizontal line.
static bool is_kinematically_possible(const double s_sqrt, const ParticleList &in)
Check if CM-energy is sufficient to produce hadron in final state.
bool printout_lattice_td_
Whether to print the thermodynamics quantities evaluated on the lattices.
RectangularLattice< FourVector > * UB_lat_pointer
Pointer to the skyrme potential on the lattice.
std::unique_ptr< DensityLattice > jmu_I3_lat_
Isospin projection density on the lattices.
DensityType dens_type_
Type of density to be written to collision headers.
bool perform_action(Action &action, const Container &particles_before_actions)
Perform the given action.
void initialize_new_event()
This is called in the beginning of each event.
OutputPtr dilepton_output_
The Dilepton output.
Collection of useful type aliases to measure and output the (real) runtime.
std::unique_ptr< OutputInterface > create_oscar_output(const std::string &format, const std::string &content, const bf::path &path, const OutputParameters &out_par)
const double end_time_
simulation time at which the evolution is stopped.
std::unique_ptr< RectangularLattice< FourVector > > UI3_lat_
Lattices for symmetry potentials (evaluated in the local rest frame) times the isospin flow 4-velocit...
uint64_t previous_wall_actions_total_
Total number of wall-crossings for previous timestep.
double max_transverse_distance_sqr_
Maximal distance at which particles can interact, squared.
std::vector< bool > nucleon_has_interacted_
nucleon_has_interacted_ labels whether the particles in the nuclei have experienced any collisions or...
uint64_t interactions_total_
Total number of interactions for current timestep.
TimeStepMode
The time step mode.
std::unique_ptr< RectangularLattice< std::pair< ThreeVector, ThreeVector > > > FI3_lat_
Lattices for the electric and magnetic component of the symmetry force.
Engine::result_type advance()
Advance the engine's state and return the generated value.
std::string format_measurements(const Particles &particles, uint64_t scatterings_this_interval, const QuantumNumbers &conserved_initial, SystemTimePoint time_start, double time)
Generate the tabulated string which will be printed to the screen when SMASH is running.
#define source_location
Hackery that is required to output the location in the source code where the log statement occurs...
const ExpansionProperties metric_
This struct contains information on the metric to be used.
Exception class that is thrown if an invalid modus is requested from the Experiment factory...
SystemTimePoint time_start_
system starting time of the simulation
virtual ~ExperimentBase()=default
The virtual destructor avoids undefined behavior when destroying derived objects. ...
const ParticleList & incoming_particles() const
Get the list of particles that go into the action.
const double delta_time_startup_
The clock's timestep size at start up.
Clock outputclock
Output clock to keep track of the next output time.
A container for storing conserved values.
void run() override
Runs the experiment.
uint64_t previous_interactions_total_
Total number of interactions for previous timestep.
Don't use fermi motion.
ActionPtr pop()
Return the first action in the list and removes it from the list.
Helper structure for Experiment to hold output options and parameters.
void run_time_evolution_timestepless(Actions &actions)
Performs all the propagations and actions during a certain time interval neglecting the influence of ...
static double formation_power_
Power with which the cross section scaling factor grows in time.
const bool dileptons_switch_
This indicates whether dileptons are switched on.
virtual ProcessType get_type() const
Get the process type.
std::unique_ptr< ActionFinderInterface > photon_finder_
The (Scatter) Actions Finder for Direct Photons.
std::unique_ptr< Potentials > potentials_
An instance of potentials class, that stores parameters of potentials, calculates them and their grad...
bool any_particles_thermalized() const
This method checks, if there are particles in the region to be thermalized.
Clock tracks the time in the simulation.
Action is the base class for a generic process that takes a number of incoming particles and transfor...
virtual double get_total_weight() const =0
Return the total weight value, which is mainly used for the weight output entry.
const bool photons_switch_
This indicates whether photons are switched on.
std::ostream & operator<<(std::ostream &out, const Experiment< Modus > &e)
Creates a verbose textual description of the setup of the Experiment.
std::unique_ptr< T > make_unique(Args &&... args)
Definition for make_unique Is in C++14's standard library; necessary for older compilers.
Use fermi motion without potentials.
void intermediate_output()
Intermediate output during an event.
std::chrono::time_point< std::chrono::system_clock > SystemTimePoint
Type (alias) that is used to store the current time.
OutputsList outputs_
A list of output formaters.
Modus modus_
Instance of the Modus template parameter.
void create_output(const std::string &format, const std::string &content, const bf::path &output_path, const OutputParameters &par)
Create a list of output files.
void expand_space_time(Particles *particles, const ExperimentParameters ¶meters, const ExpansionProperties &metric)
Modifies positions and momentum of all particles to account for space-time deformation.
Particles * particles()
Provides external access to SMASH particles.
std::vector< std::unique_ptr< ActionFinderInterface > > action_finders_
The Action finder objects.
bool printout_v_landau_
Whether to print the 4-velocity in Landau fram.
DensityParameters density_param_
Structure to precalculate and hold parameters for density computations.
A stream modifier that allows to colorize the log output.
Modus * modus()
Provides external access to SMASH calculation modus.
The Particles class abstracts the storage and manipulation of particles.
DensityType dens_type_lattice_printout_
Type of density for lattice printout.
DensityType
Allows to choose which kind of density to calculate.
const int nevents_
Number of events.
bool is_pauli_blocked(const Particles &particles, const PauliBlocker &p_bl) const
Check if the action is Pauli-blocked.
static bool is_photon_reaction(const ParticleList &in)
Check if particles can undergo an implemented photon process.
Make cells as large as possible.
The FourVector class holds relevant values in Minkowski spacetime with (+, −, −, −) metric signature.
std::unique_ptr< PauliBlocker > pauli_blocker_
An instance of PauliBlocker class that stores parameters needed for Pauli blocking calculations and c...
ActionList::size_type size() const
Struct containing the type of the metric and the expansion parameter of the metric.
std::unique_ptr< DensityLattice > jmu_B_lat_
Baryon density on the lattices.
Helper structure for Experiment.
bool printout_tmn_
Whether to print the energy-momentum tensor.
std::vector< FourVector > beam_momentum_
The initial nucleons in the ColliderModus propagate with beam_momentum_, if Fermi motion is frozen...
virtual void perform(Particles *particles, uint32_t id_process)
Actually perform the action, e.g.
double sqrt_s() const
Determine the total energy in the center-of-mass frame [GeV].