OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
DataSink.cpp
Go to the documentation of this file.
1 //
2 // Copyright & License: See Copyright.readme in src directory
3 //
4 
5 #include "Structure/DataSink.h"
6 
7 #include "OPALconfig.h"
9 #include "Utilities/Options.h"
10 #include "Utilities/Util.h"
11 #include "Fields/Fieldmap.h"
15 #include "Utilities/Timer.h"
16 
17 #ifdef __linux__
18  #include "MemoryProfiler.h"
19 #endif
20 
21 
22 #ifdef ENABLE_AMR
23  #include "Algorithms/AmrPartBunch.h"
24 #endif
25 
26 
27 
28 #include "LBalWriter.h"
29 #include "MemoryWriter.h"
30 
31 #ifdef ENABLE_AMR
32  #include "GridLBalWriter.h"
33 #endif
34 
35 
36 #include <boost/filesystem.hpp>
37 #include <boost/regex.hpp>
38 
39 #include <queue>
40 #include <sstream>
41 
43  : isMultiBunch_m(false)
44 {
45  this->init();
46 }
47 
48 
49 DataSink::DataSink(H5PartWrapper *h5wrapper, bool restart, short numBunch)
50  : isMultiBunch_m(numBunch > 1)
51 {
52  if (restart && !Options::enableHDF5) {
53  throw OpalException("DataSink::DataSink()",
54  "Can not restart when HDF5 is disabled");
55  }
56 
57  this->init(restart, h5wrapper, numBunch);
58 
59  if ( restart )
60  rewindLines();
61 }
62 
63 
64 DataSink::DataSink(H5PartWrapper *h5wrapper, short numBunch)
65  : DataSink(h5wrapper, false, numBunch)
66 { }
67 
68 
70  if (!Options::enableHDF5) return;
71 
72  h5Writer_m->writePhaseSpace(beam, FDext);
73 }
74 
75 
76 int DataSink::dumpH5(PartBunchBase<double, 3> *beam, Vector_t FDext[], double meanEnergy,
77  double refPr, double refPt, double refPz,
78  double refR, double refTheta, double refZ,
79  double azimuth, double elevation, bool local) const
80 {
81  if (!Options::enableHDF5) return -1;
82 
83  return h5Writer_m->writePhaseSpace(beam, FDext, meanEnergy, refPr, refPt, refPz,
84  refR, refTheta, refZ, azimuth, elevation, local);
85 }
86 
87 
89  double sposHead, double sposRef,
90  double sposTail) const
91 {
92  //FIXME https://gitlab.psi.ch/OPAL/src/issues/245
93  if (!Options::enableHDF5) return;
94 
95  h5Writer_m->writePhaseSpace(beam, FDext, sposHead, sposRef, sposTail);
96 }
97 
98 
100  const double& azimuth) const
101 {
102  this->dumpSDDS(beam, FDext, losses_t(), azimuth);
103 }
104 
105 
107  const losses_t &losses, const double& azimuth) const
108 {
110 
111  statWriter_m->write(beam, FDext, losses, azimuth);
112 
113  for (size_t i = 0; i < sddsWriter_m.size(); ++i)
114  sddsWriter_m[i]->write(beam);
115 
117 }
118 
119 
121  double sposHead, double sposRef, double sposTail) const
122 {
124 
125  statWriter_m->write(beam, FDext, sposHead, sposRef, sposTail);
126 
128 }
129 
130 
132  if (!Options::enableHDF5) return;
133 
134  h5Writer_m->storeCavityInformation();
135 }
136 
137 
139  if (!Options::enableHDF5) return;
140 
141  h5Writer_m->changeH5Wrapper(h5wrapper);
142 }
143 
144 
146 
147  size_t temp = lossWrCounter_m ;
148 
149  std::string ffn = fn + convertToString(temp) + std::string("Z.dat");
150  std::unique_ptr<Inform> ofp(new Inform(NULL, ffn.c_str(), Inform::OVERWRITE, 0));
151  Inform &fid = *ofp;
152  setInform(fid);
153  fid.precision(6);
154 
155  std::string ftrn = fn + std::string("triangle") + convertToString(temp) + std::string(".dat");
156  std::unique_ptr<Inform> oftr(new Inform(NULL, ftrn.c_str(), Inform::OVERWRITE, 0));
157  Inform &fidtr = *oftr;
158  setInform(fidtr);
159  fidtr.precision(6);
160 
161  Vector_t Geo_nr = bg.getnr();
162  Vector_t Geo_hr = bg.gethr();
163  Vector_t Geo_mincoords = bg.getmincoords();
164  double t = beam->getT();
165  double t_step = t * 1.0e9;
166  double* prPartLossZ = new double[bg.getnr() (2)];
167  double* sePartLossZ = new double[bg.getnr() (2)];
168  double* fePartLossZ = new double[bg.getnr() (2)];
169  fidtr << "# Time/ns" << std::setw(18) << "Triangle_ID" << std::setw(18)
170  << "Xcoordinates (m)" << std::setw(18)
171  << "Ycoordinates (m)" << std::setw(18)
172  << "Zcoordinates (m)" << std::setw(18)
173  << "Primary part. charge (C)" << std::setw(40)
174  << "Field emit. part. charge (C)" << std::setw(40)
175  << "Secondary emit. part. charge (C)" << std::setw(40) << endl;
176  for(int i = 0; i < Geo_nr(2) ; i++) {
177  prPartLossZ[i] = 0;
178  sePartLossZ[i] = 0;
179  fePartLossZ[i] = 0;
180  for(size_t j = 0; j < bg.getNumBFaces(); j++) {
181  if(((Geo_mincoords[2] + Geo_hr(2)*i) < bg.TriBarycenters_m[j](2))
182  && (bg.TriBarycenters_m[j](2) < (Geo_hr(2)*i + Geo_hr(2) + Geo_mincoords[2]))) {
183  prPartLossZ[i] += bg.TriPrPartloss_m[j];
184  sePartLossZ[i] += bg.TriSePartloss_m[j];
185  fePartLossZ[i] += bg.TriFEPartloss_m[j];
186  }
187 
188  }
189  }
190  for(size_t j = 0; j < bg.getNumBFaces(); j++) {
191  // fixme: maybe gether particle loss data, i.e., do a reduce() for
192  // each triangle in each node befor write to file.
193  fidtr << t_step << std::setw(18) << j << std::setw(18)
194  << bg.TriBarycenters_m[j](0) << std::setw(18)
195  << bg.TriBarycenters_m[j](1) << std::setw(18)
196  << bg.TriBarycenters_m[j](2) << std::setw(40)
197  << -bg.TriPrPartloss_m[j] << std::setw(40)
198  << -bg.TriFEPartloss_m[j] << std::setw(40)
199  << -bg.TriSePartloss_m[j] << endl;
200  }
201  fid << "# Delta_Z/m" << std::setw(18)
202  << "Zcoordinates (m)" << std::setw(18)
203  << "Primary part. charge (C)" << std::setw(40)
204  << "Field emit. part. charge (C)" << std::setw(40)
205  << "Secondary emit. part. charge (C)" << std::setw(40) << "t" << endl;
206 
207 
208  for(int i = 0; i < Geo_nr(2) ; i++) {
209  double primaryPLoss = -prPartLossZ[i];
210  double secondaryPLoss = -sePartLossZ[i];
211  double fieldemissionPLoss = -fePartLossZ[i];
212  reduce(primaryPLoss, primaryPLoss, OpAddAssign());
213  reduce(secondaryPLoss, secondaryPLoss, OpAddAssign());
214  reduce(fieldemissionPLoss, fieldemissionPLoss, OpAddAssign());
215  fid << Geo_hr(2) << std::setw(18)
216  << Geo_mincoords[2] + Geo_hr(2)*i << std::setw(18)
217  << primaryPLoss << std::setw(40)
218  << fieldemissionPLoss << std::setw(40)
219  << secondaryPLoss << std::setw(40) << t << endl;
220  }
221  lossWrCounter_m++;
222  delete[] prPartLossZ;
223  delete[] sePartLossZ;
224  delete[] fePartLossZ;
225 }
226 
227 
228 void DataSink::writeGeomToVtk(BoundaryGeometry &bg, std::string fn) {
229  if(Ippl::myNode() == 0) {
230  bg.writeGeomToVtk (fn);
231  }
232 }
233 
234 
235 void DataSink::writeImpactStatistics(PartBunchBase<double, 3> *beam, long long &step, size_t &impact, double &sey_num,
236  size_t numberOfFieldEmittedParticles, bool nEmissionMode, std::string fn) {
237 
238  double charge = 0.0;
239  size_t Npart = 0;
240  double Npart_d = 0.0;
241  if(!nEmissionMode) {
242  charge = -1.0 * beam->getCharge();
243  //reduce(charge, charge, OpAddAssign());
244  Npart_d = -1.0 * charge / beam->getChargePerParticle();
245  } else {
246  Npart = beam->getTotalNum();
247  }
248  if(Ippl::myNode() == 0) {
249  std::string ffn = fn + std::string(".dat");
250 
251  std::unique_ptr<Inform> ofp(new Inform(NULL, ffn.c_str(), Inform::APPEND, 0));
252  Inform &fid = *ofp;
253  setInform(fid);
254 
255  fid.precision(6);
256  fid << std::setiosflags(std::ios::scientific);
257  double t = beam->getT() * 1.0e9;
258  if(!nEmissionMode) {
259 
260  if(step == 0) {
261  fid << "#Time/ns" << std::setw(18) << "#Geometry impacts" << std::setw(18) << "tot_sey" << std::setw(18)
262  << "TotalCharge" << std::setw(18) << "PartNum" << " numberOfFieldEmittedParticles " << endl;
263  }
264  fid << t << std::setw(18) << impact << std::setw(18) << sey_num << std::setw(18) << charge
265  << std::setw(18) << Npart_d << std::setw(18) << numberOfFieldEmittedParticles << endl;
266  } else {
267 
268  if(step == 0) {
269  fid << "#Time/ns" << std::setw(18) << "#Geometry impacts" << std::setw(18) << "tot_sey" << std::setw(18)
270  << "ParticleNumber" << " numberOfFieldEmittedParticles " << endl;
271  }
272  fid << t << std::setw(18) << impact << std::setw(18) << sey_num
273  << std::setw(18) << double(Npart) << std::setw(18) << numberOfFieldEmittedParticles << endl;
274  }
275  }
276 }
277 
278 
280  MultiBunchHandler* mbhandler_p) {
283 
284  for (short b = 0; b < mbhandler_p->getNumBunch(); ++b) {
285  bool isOk = mbhandler_p->calcBunchBeamParameters(beam, b);
286  const MultiBunchHandler::beaminfo_t& binfo = mbhandler_p->getBunchInfo(b);
287  if (isOk) {
288  mbWriter_m[b]->write(beam, binfo);
289  }
290  }
291 
292  for (size_t i = 0; i < sddsWriter_m.size(); ++i)
293  sddsWriter_m[i]->write(beam);
294 
297 }
298 
299 
301  for (short b = 0; b < mbhandler_p->getNumBunch(); ++b) {
302  MultiBunchHandler::beaminfo_t& binfo = mbhandler_p->getBunchInfo(b);
303  binfo.pathlength = mbWriter_m[b]->getLastValue("s");
304  }
305 }
306 
307 
309  unsigned int linesToRewind = 0;
310 
311  double spos = h5Writer_m->getLastPosition();
312  if (isMultiBunch_m) {
313  /* first check if multi-bunch restart
314  *
315  * first element of vector belongs to first
316  * injected bunch in machine --> rewind lines
317  * according to that file --> thus rewind in
318  * reversed order
319  */
320  for (std::vector<mbWriter_t>::reverse_iterator rit = mbWriter_m.rbegin();
321  rit != mbWriter_m.rend(); ++rit)
322  {
323  if ((*rit)->exists()) {
324  linesToRewind = (*rit)->rewindToSpos(spos);
325  (*rit)->replaceVersionString();
326  }
327  }
328  } else if ( statWriter_m->exists() ) {
329  // use stat file to get position
330  linesToRewind = statWriter_m->rewindToSpos(spos);
331  statWriter_m->replaceVersionString();
332  }
333  h5Writer_m->close();
334 
335  // rewind all others
336  if ( linesToRewind > 0 ) {
337  for (size_t i = 0; i < sddsWriter_m.size(); ++i) {
338  sddsWriter_m[i]->rewindLines(linesToRewind);
339  sddsWriter_m[i]->replaceVersionString();
340  }
341  }
342 }
343 
344 
345 void DataSink::init(bool restart, H5PartWrapper* h5wrapper, short numBunch) {
346  std::string fn = OpalData::getInstance()->getInputBasename();
347 
348  lossWrCounter_m = 0;
350 
351  statWriter_m = statWriter_t(new StatWriter(fn + std::string(".stat"), restart));
352 
353  sddsWriter_m.push_back(
354  sddsWriter_t(new LBalWriter(fn + std::string(".lbal"), restart))
355  );
356 
357 #ifdef ENABLE_AMR
358  if ( Options::amr ) {
359  sddsWriter_m.push_back(
360  sddsWriter_t(new GridLBalWriter(fn + std::string(".grid"), restart))
361  );
362  }
363 #endif
364 
365  if ( Options::memoryDump ) {
366 #ifdef __linux__
367  sddsWriter_m.push_back(
368  sddsWriter_t(new MemoryProfiler(fn + std::string(".mem"), restart))
369  );
370 #else
371  sddsWriter_m.push_back(
372  sddsWriter_t(new MemoryWriter(fn + std::string(".mem"), restart))
373  );
374 #endif
375  }
376 
377  if ( isMultiBunch_m ) {
378  initMultiBunchDump(numBunch);
379  }
380 
381  if ( Options::enableHDF5 ) {
382  h5Writer_m = h5Writer_t(new H5Writer(h5wrapper, restart));
383  }
384 }
385 
386 
387 void DataSink::initMultiBunchDump(short numBunch) {
388  bool restart = OpalData::getInstance()->inRestartRun();
389  std::string fn = OpalData::getInstance()->getInputBasename();
390  short bunch = mbWriter_m.size();
391  while (bunch < numBunch) {
392  std::string fname = fn + std::string("-bunch-") +
393  convertToString(bunch, 4) + std::string(".smb");
394  mbWriter_m.push_back(
395  mbWriter_t(new MultiBunchDump(fname, restart))
396  );
397  ++bunch;
398  }
399 }
400 
401 // vi: set et ts=4 sw=4 sts=4:
402 // Local Variables:
403 // mode:c++
404 // c-basic-offset: 4
405 // indent-tabs-mode:nil
406 // End:
std::vector< double > TriFEPartloss_m
double getT() const
h5Writer_t h5Writer_m
Definition: DataSink.h:139
static std::string convertToString(int number, int setw=5)
Definition: DataSink.h:159
core of the envelope tracker based on Rene Bakkers BET implementation
Definition: EnvelopeBunch.h:60
std::unique_ptr< H5Writer > h5Writer_t
Definition: DataSink.h:40
void writeMultiBunchStatistics(PartBunchBase< double, 3 > *beam, MultiBunchHandler *mbhandler)
Definition: DataSink.cpp:279
void writeGeomToVtk(std::string fn)
void setInform(Inform &inform)
The base class for all OPAL exceptions.
Definition: OpalException.h:28
bool inRestartRun()
true if we do a restart run
Definition: OpalData.cpp:336
void changeH5Wrapper(H5PartWrapper *h5wrapper)
Definition: DataSink.cpp:138
static int myNode()
Definition: IpplInfo.cpp:794
bool memoryDump
Definition: Options.cpp:108
bool calcBunchBeamParameters(PartBunchBase< double, 3 > *beam, short bunchNr)
IpplTimings::TimerRef StatMarkerTimer_m
Timer to track statistics write time.
Definition: DataSink.h:150
size_t getTotalNum() const
void writeGeomToVtk(BoundaryGeometry &bg, std::string fn)
Definition: DataSink.cpp:228
bool reduce(Communicate &, InputIterator, InputIterator, OutputIterator, const ReduceOp &, bool *IncludeVal=0)
Definition: GlobalComm.hpp:55
static OpalData * getInstance()
Definition: OpalData.cpp:209
DataSink()
Default constructor.
Definition: DataSink.cpp:42
void writeImpactStatistics(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:235
std::unique_ptr< SDDSWriter > sddsWriter_t
Definition: DataSink.h:39
Vector_t getmincoords()
static void startTimer(TimerRef t)
Definition: IpplTimings.h:187
double getChargePerParticle() const
get the macro particle charge
std::vector< double > TriSePartloss_m
bool enableHDF5
If true HDF5 files are written.
Definition: Options.cpp:35
std::vector< double > TriPrPartloss_m
void dumpH5(PartBunchBase< double, 3 > *beam, Vector_t FDext[]) const
Definition: DataSink.cpp:69
std::vector< mbWriter_t > mbWriter_m
Definition: DataSink.h:142
std::vector< sddsWriter_t > sddsWriter_m
Definition: DataSink.h:141
int precision() const
Definition: Inform.h:115
bool amr
Definition: Options.cpp:100
double getCharge() const
get the total charge per simulation particle
unsigned int lossWrCounter_m
needed to create index for vtk file
Definition: DataSink.h:147
const bool isMultiBunch_m
Definition: DataSink.h:152
std::unique_ptr< MultiBunchDump > mbWriter_t
Definition: DataSink.h:41
beaminfo_t & getBunchInfo(short bunchNr)
void writePartlossZASCII(PartBunchBase< double, 3 > *beam, BoundaryGeometry &bg, std::string fn)
Definition: DataSink.cpp:145
void init(bool restart=false, H5PartWrapper *h5wrapper=nullptr, short numBunch=1)
Definition: DataSink.cpp:345
void setMultiBunchInitialPathLengh(MultiBunchHandler *mbhandler_p)
Definition: DataSink.cpp:300
void dumpSDDS(PartBunchBase< double, 3 > *beam, Vector_t FDext[], const double &azimuth=-1) const
Definition: DataSink.cpp:99
short getNumBunch() const
void initMultiBunchDump(short numBunch)
Definition: DataSink.cpp:387
void rewindLines()
Definition: DataSink.cpp:308
std::vector< Vector_t > TriBarycenters_m
static TimerRef getTimer(const char *nm)
Definition: IpplTimings.h:182
static void stopTimer(TimerRef t)
Definition: IpplTimings.h:192
std::string getInputBasename()
get input file name without extension
Definition: OpalData.cpp:717
StatWriter::losses_t losses_t
Definition: DataSink.h:37
Definition: Inform.h:41
statWriter_t statWriter_m
Definition: DataSink.h:140
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
void storeCavityInformation()
Write cavity information from H5 file.
Definition: DataSink.cpp:131
Vektor< int, 3 > getnr()
std::unique_ptr< StatWriter > statWriter_t
Definition: DataSink.h:38