OPAL (Object Oriented Parallel Accelerator Library)  2024.1
OPAL
DataSink.cpp
Go to the documentation of this file.
1 //
2 // Class DataSink
3 // This class acts as an observer during the calculation. It generates diagnostic
4 // output of the accelerated beam such as statistical beam descriptors of particle
5 // positions, momenta, beam phase space (emittance) etc. These are written to file
6 // at periodic time steps during the calculation.
7 //
8 // This class also writes the full beam phase space to an H5 file at periodic time
9 // steps in the calculation (this period is different from that of the statistical
10 // numbers).
11 
12 // Class also writes processor load balancing data to file to track parallel
13 // calculation efficiency.
14 //
15 // Copyright (c) 2008 - 2020, Paul Scherrer Institut, Villigen PSI, Switzerland
16 // All rights reserved
17 //
18 // This file is part of OPAL.
19 //
20 // OPAL is free software: you can redistribute it and/or modify
21 // it under the terms of the GNU General Public License as published by
22 // the Free Software Foundation, either version 3 of the License, or
23 // (at your option) any later version.
24 //
25 // You should have received a copy of the GNU General Public License
26 // along with OPAL. If not, see <https://www.gnu.org/licenses/>.
27 //
28 #include "Structure/DataSink.h"
29 
30 #include "OPALconfig.h"
31 
33 #include "Fields/Fieldmap.h"
34 #include "Physics/Units.h"
37 #include "Structure/LBalWriter.h"
38 #include "Utilities/Options.h"
39 #include "Utilities/Timer.h"
40 #include "Utilities/Util.h"
42 
43 #ifdef __linux__
45 #else
46  #include "Structure/MemoryWriter.h"
47 #endif
48 
49 #ifdef ENABLE_AMR
50  #include "Algorithms/AmrPartBunch.h"
51 #endif
52 
53 #ifdef ENABLE_AMR
55 #endif
56 
57 #include <sstream>
58 
59 
61  : isMultiBunch_m(false)
62 {
63  this->init();
64 }
65 
66 
67 DataSink::DataSink(H5PartWrapper* h5wrapper, bool restart, short numBunch)
68  : isMultiBunch_m(numBunch > 1)
69 {
70  if (restart && !Options::enableHDF5) {
71  throw OpalException("DataSink::DataSink()",
72  "Can not restart when HDF5 is disabled");
73  }
74 
75  this->init(restart, h5wrapper, numBunch);
76 
77  if ( restart )
78  rewindLines();
79 }
80 
81 
82 DataSink::DataSink(H5PartWrapper* h5wrapper, short numBunch)
83  : DataSink(h5wrapper, false, numBunch)
84 { }
85 
86 
88  if (!Options::enableHDF5) return;
89 
90  h5Writer_m->writePhaseSpace(beam, FDext);
91 }
92 
93 
94 int DataSink::dumpH5(PartBunchBase<double, 3>* beam, Vector_t FDext[], double meanEnergy,
95  double refPr, double refPt, double refPz,
96  double refR, double refTheta, double refZ,
97  double azimuth, double elevation, bool local) const
98 {
99  if (!Options::enableHDF5) return -1;
100 
101  return h5Writer_m->writePhaseSpace(beam, FDext, meanEnergy, refPr, refPt, refPz,
102  refR, refTheta, refZ, azimuth, elevation, local);
103 }
104 
105 
107  const double& azimuth) const
108 {
109  this->dumpSDDS(beam, FDext, losses_t(), azimuth);
110 }
111 
112 
114  const losses_t& losses, const double& azimuth) const
115 {
116  beam->calcBeamParameters();
117 
118  size_t npOutside = 0;
120  npOutside = beam->calcNumPartsOutside(Options::beamHaloBoundary*beam->get_rrms());
121 
123 
124  statWriter_m->write(beam, FDext, losses, azimuth, npOutside);
125 
127 
128  for (size_t i = 0; i < sddsWriter_m.size(); ++i) {
129  sddsWriter_m[i]->write(beam);
130  }
131 
133 }
134 
135 
137  if (!Options::enableHDF5) return;
138 
139  h5Writer_m->storeCavityInformation();
140 }
141 
142 
144  if (!Options::enableHDF5) return;
145 
146  h5Writer_m->changeH5Wrapper(h5wrapper);
147 }
148 
149 
150 void DataSink::writeGeomToVtk(BoundaryGeometry& bg, const std::string& fn) {
151  if (Ippl::myNode() == 0 && Options::enableVTK) {
152  bg.writeGeomToVtk(fn);
153  }
154 }
155 
156 
157 void DataSink::writeImpactStatistics(const PartBunchBase<double, 3>* beam, long long& step, size_t& impact, double& sey_num,
158  size_t numberOfFieldEmittedParticles, bool nEmissionMode, std::string fn) {
159 
160  double charge = 0.0;
161  size_t Npart = 0;
162  double Npart_d = 0.0;
163  if (!nEmissionMode) {
164  charge = -1.0 * beam->getCharge();
165  //reduce(charge, charge, OpAddAssign());
166  Npart_d = -1.0 * charge / beam->getChargePerParticle();
167  } else {
168  Npart = beam->getTotalNum();
169  }
170  if (Ippl::myNode() == 0) {
171  std::string ffn = fn + std::string(".dat");
172 
173  std::unique_ptr<Inform> ofp(new Inform(nullptr, ffn.c_str(), Inform::APPEND, 0));
174  Inform &fid = *ofp;
175  fid.precision(6);
176  fid << std::setiosflags(std::ios::scientific);
177  double t = beam->getT() * Units::s2ns;
178  if (!nEmissionMode) {
179 
180  if (step == 0) {
181  fid << "#Time/ns" << std::setw(18) << "#Geometry impacts" << std::setw(18) << "tot_sey" << std::setw(18)
182  << "TotalCharge" << std::setw(18) << "PartNum" << " numberOfFieldEmittedParticles " << endl;
183  }
184  fid << t << std::setw(18) << impact << std::setw(18) << sey_num << std::setw(18) << charge
185  << std::setw(18) << Npart_d << std::setw(18) << numberOfFieldEmittedParticles << endl;
186  } else {
187 
188  if (step == 0) {
189  fid << "#Time/ns" << std::setw(18) << "#Geometry impacts" << std::setw(18) << "tot_sey" << std::setw(18)
190  << "ParticleNumber" << " numberOfFieldEmittedParticles " << endl;
191  }
192  fid << t << std::setw(18) << impact << std::setw(18) << sey_num
193  << std::setw(18) << double(Npart) << std::setw(18) << numberOfFieldEmittedParticles << endl;
194  }
195  }
196 }
197 
198 
200  MultiBunchHandler* mbhandler_p) {
203 
204  for (short b = 0; b < mbhandler_p->getNumBunch(); ++b) {
205  bool isOk = mbhandler_p->calcBunchBeamParameters(beam, b);
206  const MultiBunchHandler::beaminfo_t& binfo = mbhandler_p->getBunchInfo(b);
207  if (isOk) {
208  mbWriter_m[b]->write(beam, binfo);
209  }
210  }
211 
212  for (size_t i = 0; i < sddsWriter_m.size(); ++i)
213  sddsWriter_m[i]->write(beam);
214 
217 }
218 
219 
221  for (short b = 0; b < mbhandler_p->getNumBunch(); ++b) {
222  MultiBunchHandler::beaminfo_t& binfo = mbhandler_p->getBunchInfo(b);
223  if (mbWriter_m[b]->exists()) {
224  binfo.pathlength = mbWriter_m[b]->getLastValue("s");
225  } else if (statWriter_m->exists()) {
226  binfo.pathlength = statWriter_m->getLastValue("s");
227  } else {
228  binfo.pathlength = 0.0;
229  }
230  }
231 }
232 
233 
235  unsigned int linesToRewind = 0;
236 
237  double spos = h5Writer_m->getLastPosition();
238  if (isMultiBunch_m) {
239  /* first check if multi-bunch restart
240  *
241  * first element of vector belongs to first
242  * injected bunch in machine --> rewind lines
243  * according to that file --> thus rewind in
244  * reversed order
245  */
246  for (std::vector<mbWriter_t>::reverse_iterator rit = mbWriter_m.rbegin();
247  rit != mbWriter_m.rend(); ++rit)
248  {
249  if ((*rit)->exists()) {
250  linesToRewind = (*rit)->rewindToSpos(spos);
251  (*rit)->replaceVersionString();
252  }
253  }
254  } else if ( statWriter_m->exists() ) {
255  // use stat file to get position
256  linesToRewind = statWriter_m->rewindToSpos(spos);
257  statWriter_m->replaceVersionString();
258  }
259  h5Writer_m->close();
260 
261  // rewind all others
262  if ( linesToRewind > 0 ) {
263  for (size_t i = 0; i < sddsWriter_m.size(); ++i) {
264  sddsWriter_m[i]->rewindLines(linesToRewind);
265  sddsWriter_m[i]->replaceVersionString();
266  }
267  }
268 }
269 
270 
271 void DataSink::init(bool restart, H5PartWrapper* h5wrapper, short numBunch) {
272  std::string fn = OpalData::getInstance()->getInputBasename();
273 
274  lossWrCounter_m = 0;
276 
277  statWriter_m = statWriter_t(new StatWriter(fn + std::string(".stat"), restart));
278 
279  sddsWriter_m.push_back(
280  sddsWriter_t(new LBalWriter(fn + std::string(".lbal"), restart))
281  );
282 
283 #ifdef ENABLE_AMR
284  if ( Options::amr ) {
285  sddsWriter_m.push_back(
286  sddsWriter_t(new GridLBalWriter(fn + std::string(".grid"), restart))
287  );
288  }
289 #endif
290 
291  if ( Options::memoryDump ) {
292 #ifdef __linux__
293  sddsWriter_m.push_back(
294  sddsWriter_t(new MemoryProfiler(fn + std::string(".mem"), restart))
295  );
296 #else
297  sddsWriter_m.push_back(
298  sddsWriter_t(new MemoryWriter(fn + std::string(".mem"), restart))
299  );
300 #endif
301  }
302 
303  if ( isMultiBunch_m ) {
304  initMultiBunchDump(numBunch);
305  }
306 
307  if ( Options::enableHDF5 ) {
308  h5Writer_m = h5Writer_t(new H5Writer(h5wrapper, restart));
309  }
310 }
311 
312 
313 void DataSink::initMultiBunchDump(short numBunch) {
314  bool restart = OpalData::getInstance()->inRestartRun();
315  std::string fn = OpalData::getInstance()->getInputBasename();
316  short bunch = mbWriter_m.size();
317  while (bunch < numBunch) {
318  std::string fname = fn + std::string("-bunch-") +
319  convertToString(bunch, 4) + std::string(".smb");
320  mbWriter_m.push_back(
321  mbWriter_t(new MultiBunchDump(fname, restart))
322  );
323  ++bunch;
324  }
325 }
static OpalData * getInstance()
Definition: OpalData.cpp:196
void initMultiBunchDump(short numBunch)
Definition: DataSink.cpp:313
std::unique_ptr< SDDSWriter > sddsWriter_t
Definition: DataSink.h:52
bool enableHDF5
If true HDF5 files are written.
Definition: Options.cpp:81
static int myNode()
Definition: IpplInfo.cpp:691
statWriter_t statWriter_m
Definition: DataSink.h:133
void rewindLines()
Definition: DataSink.cpp:234
bool memoryDump
Definition: Options.cpp:105
DataSink()
Default constructor.
Definition: DataSink.cpp:60
short getNumBunch() const
bool inRestartRun()
true if we do a restart run
Definition: OpalData.cpp:312
void calcBeamParameters()
Vector_t get_rrms() const
int precision() const
Definition: Inform.h:112
bool enableVTK
If true VTK files are written.
Definition: Options.cpp:83
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
IpplTimings::TimerRef StatMarkerTimer_m
Timer to track statistics write time.
Definition: DataSink.h:143
void storeCavityInformation()
Write cavity information from H5 file.
Definition: DataSink.cpp:136
void setMultiBunchInitialPathLengh(MultiBunchHandler *mbhandler_p)
Definition: DataSink.cpp:220
h5Writer_t h5Writer_m
Definition: DataSink.h:132
static void startTimer(TimerRef t)
Definition: IpplTimings.h:187
void writeImpactStatistics(const PartBunchBase< double, 3 > *beam, long long int &step, size_t &impact, double &sey_num, size_t numberOfFieldEmittedParticles, bool nEmissionMode, std::string fn)
Definition: DataSink.cpp:157
double getT() const
void writeMultiBunchStatistics(PartBunchBase< double, 3 > *beam, MultiBunchHandler *mbhandler)
Definition: DataSink.cpp:199
unsigned int lossWrCounter_m
needed to create index for vtk file
Definition: DataSink.h:140
std::vector< mbWriter_t > mbWriter_m
Definition: DataSink.h:135
size_t getTotalNum() const
The base class for all OPAL exceptions.
Definition: OpalException.h:28
std::vector< sddsWriter_t > sddsWriter_m
Definition: DataSink.h:134
bool calcBunchBeamParameters(PartBunchBase< double, 3 > *beam, short bunchNr)
static std::string convertToString(int number, int setw=5)
Definition: DataSink.h:152
Definition: Inform.h:42
void dumpH5(PartBunchBase< double, 3 > *beam, Vector_t FDext[]) const
Definition: DataSink.cpp:87
std::unique_ptr< H5Writer > h5Writer_t
Definition: DataSink.h:53
void writeGeomToVtk(BoundaryGeometry &bg, const std::string &fn)
Definition: DataSink.cpp:150
constexpr double s2ns
Definition: Units.h:44
void init(bool restart=false, H5PartWrapper *h5wrapper=nullptr, short numBunch=1)
Definition: DataSink.cpp:271
beaminfo_t & getBunchInfo(short bunchNr)
double getChargePerParticle() const
get the macro particle charge
void dumpSDDS(PartBunchBase< double, 3 > *beam, Vector_t FDext[], const double &azimuth=-1) const
Definition: DataSink.cpp:106
bool amr
Enable AMR if true.
Definition: Options.cpp:99
void gatherLoadBalanceStatistics()
std::unique_ptr< MultiBunchDump > mbWriter_t
Definition: DataSink.h:54
std::string getInputBasename()
get input file name without extension
Definition: OpalData.cpp:674
void changeH5Wrapper(H5PartWrapper *h5wrapper)
Definition: DataSink.cpp:143
static TimerRef getTimer(const char *nm)
Definition: IpplTimings.h:182
double getCharge() const
get the total charge per simulation particle
StatWriter::losses_t losses_t
Definition: DataSink.h:50
const bool isMultiBunch_m
Definition: DataSink.h:145
size_t calcNumPartsOutside(Vector_t x)
returns the number of particles outside of a box defined by x
static void stopTimer(TimerRef t)
Definition: IpplTimings.h:192
double beamHaloBoundary
Definition: Options.cpp:89
void writeGeomToVtk(std::string fn)
std::unique_ptr< StatWriter > statWriter_t
Definition: DataSink.h:51