Version: SMASH-1.5
vtkoutput.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2014-2018
4  * SMASH Team
5  *
6  * GNU General Public License (GPLv3 or later)
7  *
8  */
9 
10 #include <fstream>
11 #include <memory>
12 
13 #include "smash/clock.h"
14 #include "smash/config.h"
15 #include "smash/file.h"
17 #include "smash/particles.h"
18 #include "smash/vtkoutput.h"
19 
20 namespace smash {
21 
22 VtkOutput::VtkOutput(const bf::path &path, const std::string &name,
23  const OutputParameters &out_par)
24  : OutputInterface(name),
25  base_path_(std::move(path)),
26  is_thermodynamics_output_(name == "Thermodynamics") {
27  const auto &log = logger<LogArea::Output>();
28  if (out_par.part_extended) {
29  log.warn() << "Creating VTK output: There is no extended VTK format.";
30  }
31 }
32 
34 
59 void VtkOutput::at_eventstart(const Particles &particles,
60  const int event_number) {
67 
68  current_event_ = event_number;
70  write(particles);
72  }
73 }
74 
75 void VtkOutput::at_eventend(const Particles & /*particles*/,
76  const int /*event_number*/,
77  double /*impact_parameter*/) {}
78 
79 void VtkOutput::at_intermediate_time(const Particles &particles, const Clock &,
80  const DensityParameters &) {
82  write(particles);
84  }
85 }
86 
87 void VtkOutput::write(const Particles &particles) {
88  char filename[32];
89  snprintf(filename, sizeof(filename), "pos_ev%05i_tstep%05i.vtk",
91  FilePtr file_{std::fopen((base_path_ / filename).native().c_str(), "w")};
92 
93  /* Legacy VTK file format */
94  std::fprintf(file_.get(), "# vtk DataFile Version 2.0\n");
95  std::fprintf(file_.get(), "Generated from molecular-offset data %s\n",
96  VERSION_MAJOR);
97  std::fprintf(file_.get(), "ASCII\n");
98 
99  /* Unstructured data sets are composed of points, lines, polygons, .. */
100  std::fprintf(file_.get(), "DATASET UNSTRUCTURED_GRID\n");
101  std::fprintf(file_.get(), "POINTS %zu double\n", particles.size());
102  for (const auto &p : particles) {
103  std::fprintf(file_.get(), "%g %g %g\n", p.position().x1(),
104  p.position().x2(), p.position().x3());
105  }
106  std::fprintf(file_.get(), "CELLS %zu %zu\n", particles.size(),
107  particles.size() * 2);
108  for (size_t point_index = 0; point_index < particles.size(); point_index++) {
109  std::fprintf(file_.get(), "1 %zu\n", point_index);
110  }
111  std::fprintf(file_.get(), "CELL_TYPES %zu\n", particles.size());
112  for (size_t point_index = 0; point_index < particles.size(); point_index++) {
113  std::fprintf(file_.get(), "1\n");
114  }
115  std::fprintf(file_.get(), "POINT_DATA %zu\n", particles.size());
116  std::fprintf(file_.get(), "SCALARS pdg_codes int 1\n");
117  std::fprintf(file_.get(), "LOOKUP_TABLE default\n");
118  for (const auto &p : particles) {
119  std::fprintf(file_.get(), "%s\n", p.pdgcode().string().c_str());
120  }
121  std::fprintf(file_.get(), "SCALARS is_formed int 1\n");
122  std::fprintf(file_.get(), "LOOKUP_TABLE default\n");
123  double current_time = particles.time();
124  for (const auto &p : particles) {
125  std::fprintf(file_.get(), "%s\n",
126  (p.formation_time() > current_time) ? "0" : "1");
127  }
128  std::fprintf(file_.get(), "SCALARS cross_section_scaling_factor double 1\n");
129  std::fprintf(file_.get(), "LOOKUP_TABLE default\n");
130  for (const auto &p : particles) {
131  std::fprintf(file_.get(), "%g\n", p.xsec_scaling_factor());
132  }
133  std::fprintf(file_.get(), "SCALARS mass double 1\n");
134  std::fprintf(file_.get(), "LOOKUP_TABLE default\n");
135  for (const auto &p : particles) {
136  std::fprintf(file_.get(), "%g\n", p.effective_mass());
137  }
138 
139  std::fprintf(file_.get(), "VECTORS momentum double\n");
140  for (const auto &p : particles) {
141  std::fprintf(file_.get(), "%g %g %g\n", p.momentum().x1(),
142  p.momentum().x2(), p.momentum().x3());
143  }
144 }
145 
155 template <typename T>
156 void VtkOutput::write_vtk_header(std::ofstream &file,
157  RectangularLattice<T> &lattice,
158  const std::string &description) {
159  const auto dim = lattice.dimensions();
160  const auto cs = lattice.cell_sizes();
161  const auto orig = lattice.origin();
162  file << "# vtk DataFile Version 2.0\n"
163  << description << "\n"
164  << "ASCII\n"
165  << "DATASET STRUCTURED_POINTS\n"
166  << "DIMENSIONS " << dim[0] << " " << dim[1] << " " << dim[2] << "\n"
167  << "SPACING " << cs[0] << " " << cs[1] << " " << cs[2] << "\n"
168  << "ORIGIN " << orig[0] << " " << orig[1] << " " << orig[2] << "\n"
169  << "POINT_DATA " << lattice.size() << "\n";
170 }
171 
172 template <typename T, typename F>
173 void VtkOutput::write_vtk_scalar(std::ofstream &file,
174  RectangularLattice<T> &lattice,
175  const std::string &varname, F &&get_quantity) {
176  file << "SCALARS " << varname << " double 1\n"
177  << "LOOKUP_TABLE default\n";
178  file << std::setprecision(3);
179  file << std::fixed;
180  const auto dim = lattice.dimensions();
181  lattice.iterate_sublattice({0, 0, 0}, dim, [&](T &node, int ix, int, int) {
182  const double f_from_node = get_quantity(node);
183  file << f_from_node << " ";
184  if (ix == dim[0] - 1) {
185  file << "\n";
186  }
187  });
188 }
189 
190 template <typename T, typename F>
191 void VtkOutput::write_vtk_vector(std::ofstream &file,
192  RectangularLattice<T> &lattice,
193  const std::string &varname, F &&get_quantity) {
194  file << "VECTORS " << varname << " double\n";
195  file << std::setprecision(3);
196  file << std::fixed;
197  const auto dim = lattice.dimensions();
198  lattice.iterate_sublattice({0, 0, 0}, dim, [&](T &node, int, int, int) {
199  const ThreeVector v = get_quantity(node);
200  file << v.x1() << " " << v.x2() << " " << v.x3() << "\n";
201  });
202 }
203 
204 std::string VtkOutput::make_filename(const std::string &descr, int counter) {
205  char suffix[22];
206  snprintf(suffix, sizeof(suffix), "_%05i_tstep%05i.vtk", current_event_,
207  counter);
208  return base_path_.string() + std::string("/") + descr + std::string(suffix);
209 }
210 
212  const DensityType dens_type) {
213  return std::string(to_string(dens_type)) + std::string("_") +
214  std::string(to_string(tq));
215 }
216 
218  const ThermodynamicQuantity tq, const DensityType dens_type,
221  return;
222  }
223  std::ofstream file;
224  const std::string varname = make_varname(tq, dens_type);
225  file.open(make_filename(varname, vtk_density_output_counter_), std::ios::out);
226  write_vtk_header(file, lattice, varname);
227  write_vtk_scalar(file, lattice, varname,
228  [&](DensityOnLattice &node) { return node.density(); });
230 }
231 
249  const ThermodynamicQuantity tq, const DensityType dens_type,
252  return;
253  }
254  std::ofstream file;
255  const std::string varname = make_varname(tq, dens_type);
256 
257  if (tq == ThermodynamicQuantity::Tmn) {
258  file.open(make_filename(varname, vtk_tmn_output_counter_++), std::ios::out);
259  write_vtk_header(file, Tmn_lattice, varname);
260  for (int i = 0; i < 4; i++) {
261  for (int j = i; j < 4; j++) {
262  write_vtk_scalar(file, Tmn_lattice,
263  varname + std::to_string(i) + std::to_string(j),
264  [&](EnergyMomentumTensor &node) {
265  return node[EnergyMomentumTensor::tmn_index(i, j)];
266  });
267  }
268  }
269  } else if (tq == ThermodynamicQuantity::TmnLandau) {
270  file.open(make_filename(varname, vtk_tmn_landau_output_counter_++),
271  std::ios::out);
272  write_vtk_header(file, Tmn_lattice, varname);
273  for (int i = 0; i < 4; i++) {
274  for (int j = i; j < 4; j++) {
275  write_vtk_scalar(file, Tmn_lattice,
276  varname + std::to_string(i) + std::to_string(j),
277  [&](EnergyMomentumTensor &node) {
278  const FourVector u = node.landau_frame_4velocity();
279  const EnergyMomentumTensor Tmn_L = node.boosted(u);
280  return Tmn_L[EnergyMomentumTensor::tmn_index(i, j)];
281  });
282  }
283  }
284  } else {
285  file.open(make_filename(varname, vtk_v_landau_output_counter_++),
286  std::ios::out);
287  write_vtk_header(file, Tmn_lattice, varname);
288  write_vtk_vector(file, Tmn_lattice, varname,
289  [&](EnergyMomentumTensor &node) {
290  const FourVector u = node.landau_frame_4velocity();
291  return -u.threevec();
292  });
293  }
294 }
295 
298  return;
299  }
300  std::ofstream file;
301  file.open(make_filename("fluidization_td", vtk_fluidization_counter_++),
302  std::ios::out);
303  write_vtk_header(file, gct.lattice(), "fluidization_td");
304  write_vtk_scalar(file, gct.lattice(), "e",
305  [&](ThermLatticeNode &node) { return node.e(); });
306  write_vtk_scalar(file, gct.lattice(), "p",
307  [&](ThermLatticeNode &node) { return node.p(); });
308  write_vtk_vector(file, gct.lattice(), "v",
309  [&](ThermLatticeNode &node) { return node.v(); });
310  write_vtk_scalar(file, gct.lattice(), "T",
311  [&](ThermLatticeNode &node) { return node.T(); });
312  write_vtk_scalar(file, gct.lattice(), "mub",
313  [&](ThermLatticeNode &node) { return node.mub(); });
314  write_vtk_scalar(file, gct.lattice(), "mus",
315  [&](ThermLatticeNode &node) { return node.mus(); });
316 }
317 
318 } // namespace smash
FilePtr fopen(const bf::path &filename, const std::string &mode)
Open a file with given mode.
Definition: file.cc:14
A class to pre-calculate and store parameters relevant for density calculation.
Definition: density.h:103
A class for time-efficient (time-memory trade-off) calculation of density on the lattice.
Definition: density.h:242
The ThreeVector class represents a physical three-vector with the components .
Definition: threevector.h:30
void at_eventstart(const Particles &particles, const int event_number) override
Writes the initial particle information list of an event to the VTK output.
Definition: vtkoutput.cc:59
double x3() const
Definition: threevector.h:163
void write_vtk_vector(std::ofstream &file, RectangularLattice< T > &lat, const std::string &varname, F &&function)
Write a VTK vector.
Definition: vtkoutput.cc:191
void write_vtk_header(std::ofstream &file, RectangularLattice< T > &lat, const std::string &description)
Write the VTK header.
Definition: vtkoutput.cc:156
static std::int8_t tmn_index(std::int8_t mu, std::int8_t nu)
Access the index of component .
void at_eventend(const Particles &particles, const int event_number, double impact_parameter) override
Writes the final particle information list of an event to the VTK output.
Definition: vtkoutput.cc:75
void thermodynamics_output(const ThermodynamicQuantity tq, const DensityType dt, RectangularLattice< DensityOnLattice > &lattice) override
Prints the density lattice in VTK format on a grid.
Definition: vtkoutput.cc:217
bool part_extended
Extended format for particles output.
int vtk_tmn_output_counter_
Number of energy-momentum tensor lattice vtk output in current event.
Definition: vtkoutput.h:176
const std::array< int, 3 > & dimensions() const
Definition: lattice.h:145
double x1() const
Definition: threevector.h:155
STL namespace.
EnergyMomentumTensor boosted(const FourVector &u) const
Boost to a given 4-velocity.
int vtk_v_landau_output_counter_
Number of Landau rest frame velocity vtk output in current event.
Definition: vtkoutput.h:180
const bf::path base_path_
filesystem path for output
Definition: vtkoutput.h:166
A container class to hold all the arrays on the lattice and access them.
Definition: lattice.h:46
size_t size() const
Definition: particles.h:87
ThreeVector threevec() const
Definition: fourvector.h:306
int current_event_
Event number.
Definition: vtkoutput.h:169
std::string make_filename(const std::string &description, int counter)
Make a file name given a description and a counter.
Definition: vtkoutput.cc:204
ThermodynamicQuantity
Represents thermodynamic quantities that can be printed out.
int vtk_tmn_landau_output_counter_
Number of Landau frame energy-momentum tensor vtk output in current event.
Definition: vtkoutput.h:178
void at_intermediate_time(const Particles &particles, const Clock &clock, const DensityParameters &dens_param) override
Writes out all current particles.
Definition: vtkoutput.cc:79
std::unique_ptr< std::FILE, FileDeleter > FilePtr
A RAII type to replace std::FILE *.
Definition: file.h:63
const std::array< double, 3 > & origin() const
Definition: lattice.h:151
const std::array< double, 3 > & cell_sizes() const
Definition: lattice.h:148
int vtk_output_counter_
Number of vtk output in current event.
Definition: vtkoutput.h:171
void write_vtk_scalar(std::ofstream &file, RectangularLattice< T > &lat, const std::string &varname, F &&function)
Write a VTK scalar.
Definition: vtkoutput.cc:173
FourVector landau_frame_4velocity() const
Find the Landau frame 4-velocity from energy-momentum tensor.
Helper structure for Experiment to hold output options and parameters.
The GrandCanThermalizer class implements the following functionality:
The EnergyMomentumTensor class represents a symmetric positive semi-definite energy-momentum tensor ...
Clock tracks the time in the simulation.
Definition: clock.h:75
int vtk_fluidization_counter_
Number of fluidization output.
Definition: vtkoutput.h:182
bool is_thermodynamics_output_
Is the VTK output a thermodynamics output.
Definition: vtkoutput.h:184
int vtk_density_output_counter_
Number of density lattice vtk output in current event.
Definition: vtkoutput.h:174
constexpr int p
Proton.
RectangularLattice< ThermLatticeNode > & lattice() const
Getter function for the lattice.
The ThermLatticeNode class is intended to compute thermodynamical quantities in a cell given a set of...
const char * to_string(const ThermodynamicQuantity tq)
Convert thermodynamic quantities to strings.
void write(const Particles &particles)
Write the given particles to the output.
Definition: vtkoutput.cc:87
The Particles class abstracts the storage and manipulation of particles.
Definition: particles.h:33
DensityType
Allows to choose which kind of density to calculate.
Definition: density.h:34
The FourVector class holds relevant values in Minkowski spacetime with (+, −, −, −) metric signature.
Definition: fourvector.h:32
VtkOutput(const bf::path &path, const std::string &name, const OutputParameters &out_par)
Create a new VTK output.
Definition: vtkoutput.cc:22
std::string make_varname(const ThermodynamicQuantity tq, const DensityType dens_type)
Make a variable name given quantity and density type.
Definition: vtkoutput.cc:211
double density(const double norm_factor=1.0)
Compute the net Eckart density on the local lattice.
Definition: density.h:310
void iterate_sublattice(const std::array< int, 3 > &lower_bounds, const std::array< int, 3 > &upper_bounds, F &&func)
A sub-lattice iterator, which iterates in a 3D-structured manner and calls a function on every cell...
Definition: lattice.h:233
Abstraction of generic output.
std::size_t size() const
Definition: lattice.h:176
double x2() const
Definition: threevector.h:159
Definition: action.h:24