OPAL (Object Oriented Parallel Accelerator Library) 2024.2
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__
45#else
47#endif
48
49#ifdef ENABLE_AMR
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
67DataSink::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 )
79}
80
81
82DataSink::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
94int 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
150void DataSink::writeGeomToVtk(BoundaryGeometry& bg, const std::string& fn) {
151 if (Ippl::myNode() == 0 && Options::enableVTK) {
152 bg.writeGeomToVtk(fn);
153 }
154}
155
156
157void 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
271void 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
313void 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}
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
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:674
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:220
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:157
void rewindLines()
Definition DataSink.cpp:234
std::vector< sddsWriter_t > sddsWriter_m
Definition DataSink.h:134
void writeGeomToVtk(BoundaryGeometry &bg, const std::string &fn)
Definition DataSink.cpp:150
void changeH5Wrapper(H5PartWrapper *h5wrapper)
Definition DataSink.cpp:143
const bool isMultiBunch_m
Definition DataSink.h:145
StatWriter::losses_t losses_t
Definition DataSink.h:50
void initMultiBunchDump(short numBunch)
Definition DataSink.cpp:313
void dumpSDDS(PartBunchBase< double, 3 > *beam, Vector_t FDext[], const double &azimuth=-1) const
Definition DataSink.cpp:106
void init(bool restart=false, H5PartWrapper *h5wrapper=nullptr, short numBunch=1)
Definition DataSink.cpp:271
std::unique_ptr< SDDSWriter > sddsWriter_t
Definition DataSink.h:52
static std::string convertToString(int number, int setw=5)
Definition DataSink.h:152
std::vector< mbWriter_t > mbWriter_m
Definition DataSink.h:135
void storeCavityInformation()
Write cavity information from H5 file.
Definition DataSink.cpp:136
void dumpH5(PartBunchBase< double, 3 > *beam, Vector_t FDext[]) const
Definition DataSink.cpp:87
IpplTimings::TimerRef StatMarkerTimer_m
Timer to track statistics write time.
Definition DataSink.h:143
std::unique_ptr< H5Writer > h5Writer_t
Definition DataSink.h:53
unsigned int lossWrCounter_m
needed to create index for vtk file
Definition DataSink.h:140
statWriter_t statWriter_m
Definition DataSink.h:133
void writeMultiBunchStatistics(PartBunchBase< double, 3 > *beam, MultiBunchHandler *mbhandler)
Definition DataSink.cpp:199
DataSink()
Default constructor.
Definition DataSink.cpp:60
h5Writer_t h5Writer_m
Definition DataSink.h:132
std::unique_ptr< StatWriter > statWriter_t
Definition DataSink.h:51
The base class for all OPAL exceptions.
@ 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)
static void stopTimer(TimerRef t)
static void startTimer(TimerRef t)
Vektor< double, 3 > Vector_t