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