OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
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 
29 #include "Structure/DataSink.h"
30 
32 
33 #include "OPALconfig.h"
35 #include "Utilities/Options.h"
36 #include "Utilities/Util.h"
37 #include "Fields/Fieldmap.h"
40 #include "Utilities/Timer.h"
41 
42 #ifdef __linux__
43  #include "MemoryProfiler.h"
44 #else
45  #include "MemoryWriter.h"
46 #endif
47 
48 
49 #ifdef ENABLE_AMR
50  #include "Algorithms/AmrPartBunch.h"
51 #endif
52 
53 
54 
55 #include "LBalWriter.h"
56 
57 #ifdef ENABLE_AMR
58  #include "GridLBalWriter.h"
59 #endif
60 
61 #include <sstream>
62 
64  : isMultiBunch_m(false)
65 {
66  this->init();
67 }
68 
69 
70 DataSink::DataSink(H5PartWrapper *h5wrapper, bool restart, short numBunch)
71  : isMultiBunch_m(numBunch > 1)
72 {
73  if (restart && !Options::enableHDF5) {
74  throw OpalException("DataSink::DataSink()",
75  "Can not restart when HDF5 is disabled");
76  }
77 
78  this->init(restart, h5wrapper, numBunch);
79 
80  if ( restart )
81  rewindLines();
82 }
83 
84 
85 DataSink::DataSink(H5PartWrapper *h5wrapper, short numBunch)
86  : DataSink(h5wrapper, false, numBunch)
87 { }
88 
89 
91  if (!Options::enableHDF5) return;
92 
93  h5Writer_m->writePhaseSpace(beam, FDext);
94 }
95 
96 
97 int DataSink::dumpH5(PartBunchBase<double, 3> *beam, Vector_t FDext[], double meanEnergy,
98  double refPr, double refPt, double refPz,
99  double refR, double refTheta, double refZ,
100  double azimuth, double elevation, bool local) const
101 {
102  if (!Options::enableHDF5) return -1;
103 
104  return h5Writer_m->writePhaseSpace(beam, FDext, meanEnergy, refPr, refPt, refPz,
105  refR, refTheta, refZ, azimuth, elevation, local);
106 }
107 
108 
110  const double& azimuth) const
111 {
112  this->dumpSDDS(beam, FDext, losses_t(), azimuth);
113 }
114 
115 
117  const losses_t &losses, const double& azimuth) const
118 {
119  beam->calcBeamParameters();
120 
121  size_t npOutside = 0;
123  npOutside = beam->calcNumPartsOutside(Options::beamHaloBoundary*beam->get_rrms());
124 
126 
127  statWriter_m->write(beam, FDext, losses, azimuth, npOutside);
128 
130 
131  for (size_t i = 0; i < sddsWriter_m.size(); ++i)
132  sddsWriter_m[i]->write(beam);
133 
135 }
136 
137 
139  if (!Options::enableHDF5) return;
140 
141  h5Writer_m->storeCavityInformation();
142 }
143 
144 
146  if (!Options::enableHDF5) return;
147 
148  h5Writer_m->changeH5Wrapper(h5wrapper);
149 }
150 
151 
152 void DataSink::writeGeomToVtk(BoundaryGeometry &bg, std::string fn) {
153  if (Ippl::myNode() == 0 && Options::enableVTK) {
154  bg.writeGeomToVtk (fn);
155  }
156 }
157 
158 
159 void DataSink::writeImpactStatistics(const PartBunchBase<double, 3> *beam, long long &step, size_t &impact, double &sey_num,
160  size_t numberOfFieldEmittedParticles, bool nEmissionMode, std::string fn) {
161 
162  double charge = 0.0;
163  size_t Npart = 0;
164  double Npart_d = 0.0;
165  if(!nEmissionMode) {
166  charge = -1.0 * beam->getCharge();
167  //reduce(charge, charge, OpAddAssign());
168  Npart_d = -1.0 * charge / beam->getChargePerParticle();
169  } else {
170  Npart = beam->getTotalNum();
171  }
172  if(Ippl::myNode() == 0) {
173  std::string ffn = fn + std::string(".dat");
174 
175  std::unique_ptr<Inform> ofp(new Inform(NULL, ffn.c_str(), Inform::APPEND, 0));
176  Inform &fid = *ofp;
177  fid.precision(6);
178  fid << std::setiosflags(std::ios::scientific);
179  double t = beam->getT() * 1.0e9;
180  if(!nEmissionMode) {
181 
182  if(step == 0) {
183  fid << "#Time/ns" << std::setw(18) << "#Geometry impacts" << std::setw(18) << "tot_sey" << std::setw(18)
184  << "TotalCharge" << std::setw(18) << "PartNum" << " numberOfFieldEmittedParticles " << endl;
185  }
186  fid << t << std::setw(18) << impact << std::setw(18) << sey_num << std::setw(18) << charge
187  << std::setw(18) << Npart_d << std::setw(18) << numberOfFieldEmittedParticles << endl;
188  } else {
189 
190  if(step == 0) {
191  fid << "#Time/ns" << std::setw(18) << "#Geometry impacts" << std::setw(18) << "tot_sey" << std::setw(18)
192  << "ParticleNumber" << " numberOfFieldEmittedParticles " << endl;
193  }
194  fid << t << std::setw(18) << impact << std::setw(18) << sey_num
195  << std::setw(18) << double(Npart) << std::setw(18) << numberOfFieldEmittedParticles << endl;
196  }
197  }
198 }
199 
200 
202  MultiBunchHandler* mbhandler_p) {
205 
206  for (short b = 0; b < mbhandler_p->getNumBunch(); ++b) {
207  bool isOk = mbhandler_p->calcBunchBeamParameters(beam, b);
208  const MultiBunchHandler::beaminfo_t& binfo = mbhandler_p->getBunchInfo(b);
209  if (isOk) {
210  mbWriter_m[b]->write(beam, binfo);
211  }
212  }
213 
214  for (size_t i = 0; i < sddsWriter_m.size(); ++i)
215  sddsWriter_m[i]->write(beam);
216 
219 }
220 
221 
223  for (short b = 0; b < mbhandler_p->getNumBunch(); ++b) {
224  MultiBunchHandler::beaminfo_t& binfo = mbhandler_p->getBunchInfo(b);
225  if (mbWriter_m[b]->exists()) {
226  binfo.pathlength = mbWriter_m[b]->getLastValue("s");
227  } else if (statWriter_m->exists()) {
228  binfo.pathlength = statWriter_m->getLastValue("s");
229  } else {
230  binfo.pathlength = 0.0;
231  }
232  }
233 }
234 
235 
237  unsigned int linesToRewind = 0;
238 
239  double spos = h5Writer_m->getLastPosition();
240  if (isMultiBunch_m) {
241  /* first check if multi-bunch restart
242  *
243  * first element of vector belongs to first
244  * injected bunch in machine --> rewind lines
245  * according to that file --> thus rewind in
246  * reversed order
247  */
248  for (std::vector<mbWriter_t>::reverse_iterator rit = mbWriter_m.rbegin();
249  rit != mbWriter_m.rend(); ++rit)
250  {
251  if ((*rit)->exists()) {
252  linesToRewind = (*rit)->rewindToSpos(spos);
253  (*rit)->replaceVersionString();
254  }
255  }
256  } else if ( statWriter_m->exists() ) {
257  // use stat file to get position
258  linesToRewind = statWriter_m->rewindToSpos(spos);
259  statWriter_m->replaceVersionString();
260  }
261  h5Writer_m->close();
262 
263  // rewind all others
264  if ( linesToRewind > 0 ) {
265  for (size_t i = 0; i < sddsWriter_m.size(); ++i) {
266  sddsWriter_m[i]->rewindLines(linesToRewind);
267  sddsWriter_m[i]->replaceVersionString();
268  }
269  }
270 }
271 
272 
273 void DataSink::init(bool restart, H5PartWrapper* h5wrapper, short numBunch) {
274  std::string fn = OpalData::getInstance()->getInputBasename();
275 
276  lossWrCounter_m = 0;
278 
279  statWriter_m = statWriter_t(new StatWriter(fn + std::string(".stat"), restart));
280 
281  sddsWriter_m.push_back(
282  sddsWriter_t(new LBalWriter(fn + std::string(".lbal"), restart))
283  );
284 
285 #ifdef ENABLE_AMR
286  if ( Options::amr ) {
287  sddsWriter_m.push_back(
288  sddsWriter_t(new GridLBalWriter(fn + std::string(".grid"), restart))
289  );
290  }
291 #endif
292 
293  if ( Options::memoryDump ) {
294 #ifdef __linux__
295  sddsWriter_m.push_back(
296  sddsWriter_t(new MemoryProfiler(fn + std::string(".mem"), restart))
297  );
298 #else
299  sddsWriter_m.push_back(
300  sddsWriter_t(new MemoryWriter(fn + std::string(".mem"), restart))
301  );
302 #endif
303  }
304 
305  if ( isMultiBunch_m ) {
306  initMultiBunchDump(numBunch);
307  }
308 
309  if ( Options::enableHDF5 ) {
310  h5Writer_m = h5Writer_t(new H5Writer(h5wrapper, restart));
311  }
312 }
313 
314 
315 void DataSink::initMultiBunchDump(short numBunch) {
316  bool restart = OpalData::getInstance()->inRestartRun();
317  std::string fn = OpalData::getInstance()->getInputBasename();
318  short bunch = mbWriter_m.size();
319  while (bunch < numBunch) {
320  std::string fname = fn + std::string("-bunch-") +
321  convertToString(bunch, 4) + std::string(".smb");
322  mbWriter_m.push_back(
323  mbWriter_t(new MultiBunchDump(fname, restart))
324  );
325  ++bunch;
326  }
327 }
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
bool memoryDump
Definition: Options.cpp:105
bool enableVTK
If true VTK files are written.
Definition: Options.cpp:83
bool enableHDF5
If true HDF5 files are written.
Definition: Options.cpp:81
bool amr
Enable AMR if true.
Definition: Options.cpp:99
double beamHaloBoundary
Definition: Options.cpp:89
double getChargePerParticle() const
get the macro particle charge
size_t getTotalNum() const
size_t calcNumPartsOutside(Vector_t x)
returns the number of particles outside of a box defined by x
Vector_t get_rrms() const
void calcBeamParameters()
double getCharge() const
get the total charge per simulation particle
void gatherLoadBalanceStatistics()
double getT() const
std::string getInputBasename()
get input file name without extension
Definition: OpalData.cpp:658
static OpalData * getInstance()
Definition: OpalData.cpp:195
bool inRestartRun()
true if we do a restart run
Definition: OpalData.cpp:311
bool calcBunchBeamParameters(PartBunchBase< double, 3 > *beam, short bunchNr)
beaminfo_t & getBunchInfo(short bunchNr)
short getNumBunch() const
void writeGeomToVtk(std::string fn)
void setMultiBunchInitialPathLengh(MultiBunchHandler *mbhandler_p)
Definition: DataSink.cpp:222
std::unique_ptr< MultiBunchDump > mbWriter_t
Definition: DataSink.h:55
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:159
void rewindLines()
Definition: DataSink.cpp:236
std::vector< sddsWriter_t > sddsWriter_m
Definition: DataSink.h:137
void changeH5Wrapper(H5PartWrapper *h5wrapper)
Definition: DataSink.cpp:145
const bool isMultiBunch_m
Definition: DataSink.h:148
StatWriter::losses_t losses_t
Definition: DataSink.h:51
void initMultiBunchDump(short numBunch)
Definition: DataSink.cpp:315
void dumpSDDS(PartBunchBase< double, 3 > *beam, Vector_t FDext[], const double &azimuth=-1) const
Definition: DataSink.cpp:109
void init(bool restart=false, H5PartWrapper *h5wrapper=nullptr, short numBunch=1)
Definition: DataSink.cpp:273
void writeGeomToVtk(BoundaryGeometry &bg, std::string fn)
Definition: DataSink.cpp:152
std::unique_ptr< SDDSWriter > sddsWriter_t
Definition: DataSink.h:53
static std::string convertToString(int number, int setw=5)
Definition: DataSink.h:155
std::vector< mbWriter_t > mbWriter_m
Definition: DataSink.h:138
void storeCavityInformation()
Write cavity information from H5 file.
Definition: DataSink.cpp:138
void dumpH5(PartBunchBase< double, 3 > *beam, Vector_t FDext[]) const
Definition: DataSink.cpp:90
IpplTimings::TimerRef StatMarkerTimer_m
Timer to track statistics write time.
Definition: DataSink.h:146
std::unique_ptr< H5Writer > h5Writer_t
Definition: DataSink.h:54
unsigned int lossWrCounter_m
needed to create index for vtk file
Definition: DataSink.h:143
statWriter_t statWriter_m
Definition: DataSink.h:136
void writeMultiBunchStatistics(PartBunchBase< double, 3 > *beam, MultiBunchHandler *mbhandler)
Definition: DataSink.cpp:201
DataSink()
Default constructor.
Definition: DataSink.cpp:63
h5Writer_t h5Writer_m
Definition: DataSink.h:135
std::unique_ptr< StatWriter > statWriter_t
Definition: DataSink.h:52
The base class for all OPAL exceptions.
Definition: OpalException.h:28
Definition: Inform.h:42
@ APPEND
Definition: Inform.h:46
int precision() const
Definition: Inform.h:112
static int myNode()
Definition: IpplInfo.cpp:691
static TimerRef getTimer(const char *nm)
Definition: IpplTimings.h:182
static void stopTimer(TimerRef t)
Definition: IpplTimings.h:192
static void startTimer(TimerRef t)
Definition: IpplTimings.h:187