Version: SMASH-3.4
icoutput.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2019-2020,2022-2025
4  * SMASH Team
5  *
6  * GNU General Public License (GPLv3 or later)
7  *
8  */
9 
10 #include "smash/icoutput.h"
11 
12 #include <filesystem>
13 #include <fstream>
14 
15 #include "smash/action.h"
16 
17 namespace smash {
18 
19 /*!\Userguide
20  * \page doxypage_output_initial_conditions
21  *
22  * <h3> Output for vHLLE </h3>
23  * The "For_vHLLE" initial conditions output **SMASH_IC_For_vHLLE.dat** contains
24  * a list of particles on a hypersurface of constant proper time. This output is
25  * formatted such that it is directly compatible with the vHLLE hydrodynamics
26  * code \iref{Karpenko:2013wva}. As a consequence, **spectators are not written
27  * to the IC output** as they would need to be excluded anyways in order to
28  * initialize the hydrodynamics evolution. Note though that for all other output
29  * formats the full particle list is printed to the IC output, including
30  * spectators. The particle data is provided in the computational frame. For
31  * further details, see \ref doxypage_input_conf_modi_C_initial_conditions. \n
32  *
33  * The "For_vHLLE" initial conditions output is formatted as follows:
34  *
35  * **Header**
36  * \code
37  * # **smash_version** initial conditions: hypersurface of constant proper time
38  * # tau x y eta mt px py Rap pdg charge baryon_number strangeness
39  * # fm fm fm none GeV GeV GeV none none e none none
40  * \endcode
41  * The header consists of 3 lines starting with a '#', containing the following
42  * information:
43  * -# SMASH-version and the information, that 'initial conditions' are provided
44  * -# The header with all column names
45  * -# The units of all column quantities
46  *
47  * **Output block header**
48  *
49  * The initial conditions output for vHLLE is, similar to the OSCAR output,
50  * based on a block structure, where each block consists of 1 event (multiple
51  * ensembles, if used, are separated as well). The header for a new event is
52  * structured as follows:
53  * \code
54  * # event ev_num ensemble ens_num start
55  * \endcode
56  * where
57  * \li \key ev_num: The number of the current event
58  * \li \key ens_num: The number of the current ensemble
59  *
60  * Note that 'event', 'ensemble' and 'start' are not variables, but words that
61  * are printed in the header.
62  *
63  * **Particle line**
64  *
65  * The particle lines are formatted as follows:
66  * \code
67  * tau x y eta mt px py Rap pdg charge baryon_number strangeness
68  * \endcode
69  * where
70  * \li \key tau: Proper time of the particle
71  * \li \key x, \key y: Cartesian x and y coordinates of the particle
72  * \li \key eta: Space-time rapidity of the particle
73  * \li \key mt: Transverse mass of the particle
74  * \li \key px, \key py: x and y components of the particle's momentum
75  * \li \key Rap: Momentum space rapidity of the particle
76  * \li \key pdg: PDG code of the particle (see http://pdg.lbl.gov/).
77  * It contains all quantum numbers and uniquely identifies its type.
78  * every particle in the event.
79  * \li \key charge: electric charge of the particle
80  * \li \key baryon_number: baryon number of the particle
81  * \li \key strangeness: strangeness of the particle
82  *
83  * **Event end line**
84  *
85  * The end of an event is indicated by the following line:
86  * \code
87  * # event ev_num ensemble ens_num end
88  * \endcode
89  * where
90  * \li \key ev_num: The number of the current event
91  * \li \key ens_num: The number of the current ensemble
92  *
93  * Note that 'event', 'ensemble' and 'start' are not variables, but words that
94  * are printed in the header.
95  *
96  * \note
97  * If SMASH is run with test particles (necessary e.g. for potentials), the
98  * output will contain Ntest * Npart particle entries. Remember to weigh
99  * each of those particles with 1/Ntest.
100  */
101 
102 ICOutput::ICOutput(const std::filesystem::path &path, const std::string &name,
103  const OutputParameters &out_par)
104  : OutputInterface(name),
105  file_{path / "SMASH_IC_For_vHLLE.dat", "w"},
106  out_par_(out_par),
107  formatter_{OutputDefaultQuantities::ic_For_vHLLE} {
108  std::fprintf(
109  file_.get(),
110  "# %s initial conditions: hypersurface of constant proper time\n",
111  SMASH_VERSION);
112  std::fprintf(file_.get(), "# %s", formatter_.quantities_line().c_str());
113  std::fprintf(file_.get(), "# %s", formatter_.unit_line().c_str());
114 }
115 
117 
118 void ICOutput::at_eventstart(const Particles &, const EventLabel &event_label,
119  const EventInfo &event) {
120  if (event.n_ensembles != 1) {
121  throw std::logic_error(
122  "ICOutput shouldn't be used with multiple parallel ensembles.");
123  }
124  std::fprintf(file_.get(), "# event %i ensemble %i start\n",
125  event_label.event_number, event_label.ensemble_number);
126 }
127 
128 void ICOutput::at_eventend([[maybe_unused]] const Particles &particles,
129  const EventLabel &event_label,
130  const EventInfo &event) {
131  if (event.n_ensembles != 1) {
132  throw std::logic_error(
133  "ICOutput shouldn't be used with multiple parallel ensembles.");
134  }
135  std::fprintf(file_.get(), "# event %i ensemble %i end\n",
136  event_label.event_number, event_label.ensemble_number);
137 }
138 
140  const std::unique_ptr<Clock> &,
141  const DensityParameters &,
142  const EventLabel &, const EventInfo &) {
143  // Dummy, but virtual function needs to be declared.
144 }
145 
146 void ICOutput::at_interaction(const Action &action, const double) {
147  assert(action.get_type() == ProcessType::Fluidization ||
149  assert(action.incoming_particles().size() == 1);
150 
151  const ParticleData &particle = action.incoming_particles()[0];
152 
153  // Determine if particle is spectator:
154  // Fulfilled if particle is initial nucleon, aka has no prior interactions
155  bool is_spectator = particle.get_history().collisions_per_particle == 0;
156 
157  // write particle data excluding spectators
158  if (!is_spectator) {
159  std::fprintf(file_.get(), "%s",
160  formatter_.single_particle_data(particle).c_str());
161  }
162 
163  if (IC_proper_time_ < 0.0) {
164  // First particle that is removed, overwrite negative default
165  IC_proper_time_ = particle.hyperbolic_time();
166  } else {
167  // Verify that all other particles have the same proper time
168  const double next_proper_time = particle.hyperbolic_time();
169  if (!((next_proper_time - IC_proper_time_) < really_small))
170  throw std::runtime_error(
171  "Hypersurface proper time changed during evolution.");
172  }
173 }
174 
175 } // namespace smash
Action is the base class for a generic process that takes a number of incoming particles and transfor...
Definition: action.h:35
virtual ProcessType get_type() const
Get the process type.
Definition: action.h:131
const ParticleList & incoming_particles() const
Get the list of particles that go into the action.
Definition: action.cc:61
A class to pre-calculate and store parameters relevant for density calculation.
Definition: density.h:92
void at_eventstart(const Particles &, const EventLabel &event_label, const EventInfo &event) override
Write event start line.
Definition: icoutput.cc:118
void at_intermediate_time(const Particles &, const std::unique_ptr< Clock > &, const DensityParameters &, const EventLabel &, const EventInfo &) override
Unused, but needed since virtually declared in mother class.
Definition: icoutput.cc:139
RenamingFilePtr file_
Pointer to output file.
Definition: icoutput.h:76
ICOutput(const std::filesystem::path &path, const std::string &name, const OutputParameters &out_par)
Create a new IC output.
Definition: icoutput.cc:102
double IC_proper_time_
Proper time of the particles removed when extracting initial conditions.
Definition: icoutput.h:89
void at_interaction(const Action &action, const double) override
Write particle data at the hypersurface crossing point to the IC output.
Definition: icoutput.cc:146
void at_eventend(const Particles &particles, const EventLabel &event_label, const EventInfo &event) override
Write event end line.
Definition: icoutput.cc:128
OutputFormatter< ToASCII > formatter_
Formatter of the output.
Definition: icoutput.h:92
Abstraction of generic output.
ParticleData contains the dynamic information of a certain particle.
Definition: particledata.h:59
double hyperbolic_time() const
Particle (hyperbolic time)
Definition: particledata.h:404
HistoryData get_history() const
Get history information.
Definition: particledata.h:143
The Particles class abstracts the storage and manipulation of particles.
Definition: particles.h:33
FILE * get()
Get the underlying FILE* pointer.
Definition: file.cc:27
Definition: action.h:24
@ FluidizationNoRemoval
See here for a short description.
@ Fluidization
See here for a short description.
constexpr double really_small
Numerical error tolerance.
Definition: constants.h:41
Structure to contain custom data for output.
int n_ensembles
Number of ensembles.
Structure to contain information about the event and ensemble numbers.
int32_t ensemble_number
The number of the ensemble.
int32_t event_number
The number of the event.
int32_t collisions_per_particle
Collision counter per particle, zero only for initially present particles.
Definition: particledata.h:33
Struct that holds quantities required by default output standards.
Helper structure for Experiment to hold output options and parameters.