OPAL (Object Oriented Parallel Accelerator Library)  2024.1
OPAL
Monitor.cpp
Go to the documentation of this file.
1 //
2 // Class Monitor
3 // Defines the abstract interface for a beam position monitor.
4 //
5 // Copyright (c) 2000 - 2021, Paul Scherrer Institut, Villigen PSI, Switzerland
6 // All rights reserved.
7 //
8 // This file is part of OPAL.
9 //
10 // OPAL is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with OPAL. If not, see <https://www.gnu.org/licenses/>.
17 //
18 #include "AbsBeamline/Monitor.h"
19 
23 #include "Fields/Fieldmap.h"
24 #include "Physics/Physics.h"
25 #include "Structure/LossDataSink.h"
27 #include "Utilities/Options.h"
28 #include "Utilities/Util.h"
29 
30 #include <fstream>
31 #include <memory>
32 
33 
34 std::map<double, SetStatistics> Monitor::statFileEntries_sm;
35 const double Monitor::halfLength_s = 0.005;
36 
38  Monitor("")
39 {}
40 
41 
42 Monitor::Monitor(const Monitor &right):
43  Component(right),
44  filename_m(right.filename_m),
45  plane_m(right.plane_m),
46  type_m(right.type_m),
47  numPassages_m(0)
48 {}
49 
50 
51 Monitor::Monitor(const std::string &name):
52  Component(name),
53  filename_m(""),
54  plane_m(OFF),
55  type_m(CollectionType::SPATIAL),
56  numPassages_m(0)
57 {}
58 
59 
61 {}
62 
63 
64 void Monitor::accept(BeamlineVisitor &visitor) const {
65  visitor.visitMonitor(*this);
66 }
67 
68 bool Monitor::apply(const size_t &i, const double &t, Vector_t &/*E*/, Vector_t &/*B*/) {
69  const Vector_t &R = RefPartBunch_m->R[i];
70  const Vector_t &P = RefPartBunch_m->P[i];
71  const double &dt = RefPartBunch_m->dt[i];
72  const Vector_t singleStep = Physics::c * dt * Util::getBeta(P);
74  if (dt * R(2) < 0.0 &&
75  dt * (R(2) + singleStep(2)) > 0.0) {
76  // if R(2) is negative then frac should be positive and vice versa
77  double frac = -R(2) / singleStep(2);
78 
79  lossDs_m->addParticle(OpalParticle(RefPartBunch_m->ID[i],
80  R + frac * singleStep,
81  P,
82  t + frac * dt,
83  RefPartBunch_m->Q[i],
84  RefPartBunch_m->M[i]));
85  }
86  }
87 
88  return false;
89 }
90 
92  const double cdt = Physics::c * RefPartBunch_m->getdT();
93  const Vector_t driftPerTimeStep = cdt * Util::getBeta(refP);
94  const double tau = -refR(2) / driftPerTimeStep(2);
95  const CoordinateSystemTrafo update(refR + tau * driftPerTimeStep, getQuaternion(refP, Vector_t(0, 0, 1)));
96  const CoordinateSystemTrafo refToLocalCSTrafo = update * (getCSTrafoGlobal2Local() * RefPartBunch_m->toLabTrafo_m);
97 
98  for (OpalParticle particle : *RefPartBunch_m) {
99  Vector_t beta = refToLocalCSTrafo.rotateTo(Util::getBeta(particle.getP()));
100  Vector_t dS = (tau - 0.5) * cdt * beta; // the particles are half a step ahead relative to the reference particle
101  particle.setR(refToLocalCSTrafo.transformTo(particle.getR()) + dS);
102  lossDs_m->addParticle(particle);
103  }
104 }
105 
107  const Vector_t &P,
108  const double &t,
109  Vector_t &,
110  Vector_t &) {
111  if (!OpalData::getInstance()->isInPrepState()) {
112  const double dt = RefPartBunch_m->getdT();
113  const double cdt = Physics::c * dt;
114  const Vector_t singleStep = cdt * Util::getBeta(P);
115 
116  if (dt * R(2) < 0.0 &&
117  dt * (R(2) + singleStep(2)) > 0.0) {
118  double frac = -R(2) / singleStep(2);
119  double time = t + frac * dt;
120  Vector_t dR = frac * singleStep;
121  double ds = euclidean_norm(dR + 0.5 * singleStep);
122  lossDs_m->addReferenceParticle(csTrafoGlobal2Local_m.transformFrom(R + dR),
124  time,
125  RefPartBunch_m->get_sPos() + ds,
127 
130  auto stats = lossDs_m->computeStatistics(1);
131  if (!stats.empty()) {
132  statFileEntries_sm.insert(std::make_pair(stats.begin()->spos_m, *stats.begin()));
133  OpalData::OpenMode openMode;
134  if (numPassages_m > 0) {
135  openMode = OpalData::OpenMode::APPEND;
136  } else {
137  openMode = OpalData::getInstance()->getOpenMode();
138  }
139  lossDs_m->save(1, openMode);
140  }
141  }
142 
143  ++ numPassages_m;
144  }
145  }
146  return false;
147 }
148 
149 void Monitor::initialise(PartBunchBase<double, 3> *bunch, double &startField, double &endField) {
150  RefPartBunch_m = bunch;
151  endField = startField + halfLength_s;
152  startField -= halfLength_s;
153 
154  const size_t totalNum = bunch->getTotalNum();
155  double currentPosition = endField;
156  if (totalNum > 0) {
157  currentPosition = bunch->get_sPos();
158  }
159 
161 
162  if (OpalData::getInstance()->getOpenMode() == OpalData::OpenMode::WRITE ||
163  currentPosition < startField) {
164 
165  namespace fs = std::filesystem;
166 
167  fs::path lossFileName = fs::path(filename_m + ".h5");
168  if (fs::exists(lossFileName)) {
169  Ippl::Comm->barrier();
170  if (Ippl::myNode() == 0) {
171  fs::remove(lossFileName);
172  }
173  Ippl::Comm->barrier();
174  }
175  }
176 
177  lossDs_m = std::unique_ptr<LossDataSink>(new LossDataSink(filename_m, !Options::asciidump, type_m));
178 }
179 
181 
182 }
183 
184 void Monitor::goOnline(const double &) {
185  online_m = true;
186 }
187 
189  auto stats = lossDs_m->computeStatistics(numPassages_m);
190  for (auto &stat: stats) {
191  statFileEntries_sm.insert(std::make_pair(stat.spos_m, stat));
192  }
193 
195  lossDs_m->save(numPassages_m);
196  }
197 }
198 
199 bool Monitor::bends() const {
200  return false;
201 }
202 
203 void Monitor::getDimensions(double &zBegin, double &zEnd) const {
204  zBegin = -halfLength_s;
205  zEnd = halfLength_s;
206 }
207 
208 
210  return ElementType::MONITOR;
211 }
212 
214  if (statFileEntries_sm.size() == 0) return;
215 
216  std::string fileName = OpalData::getInstance()->getInputBasename() + std::string("_Monitors.stat");
217  auto instance = OpalData::getInstance();
218  bool hasPriorTrack = instance->hasPriorTrack();
219  bool inRestartRun = instance->inRestartRun();
220 
221  auto it = statFileEntries_sm.begin();
222  double spos = it->first;
223  Util::rewindLinesSDDS(fileName, spos, false);
224 
225  MonitorStatisticsWriter writer(fileName, hasPriorTrack || inRestartRun);
226 
227  for (const auto &entry: statFileEntries_sm) {
228  writer.addRow(entry.second);
229  }
230 
231  statFileEntries_sm.clear();
232 }
static OpalData * getInstance()
Definition: OpalData.cpp:196
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:45
static void writeStatistics()
Definition: Monitor.cpp:213
CollectionType type_m
Definition: Monitor.h:104
and that you know you can do these things To protect your we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights These restrictions translate to certain responsibilities for you if you distribute copies of the or if you modify it For if you distribute copies of such a whether gratis or for a you must give the recipients all the rights that you have You must make sure that receive or can get the source code And you must show them these terms so they know their rights We protect your rights with two distribute and or modify the software for each author s protection and we want to make certain that everyone understands that there is no warranty for this free software If the software is modified by someone else and passed we want its recipients to know that what they have is not the so that any problems introduced by others will not reflect on the original authors reputations any free program is threatened constantly by software patents We wish to avoid the danger that redistributors of a free program will individually obtain patent in effect making the program proprietary To prevent we have made it clear that any patent must be licensed for everyone s free use or not licensed at all The precise terms and conditions for distribution and modification follow GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR DISTRIBUTION AND MODIFICATION This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License The refers to any such program or and a work based on the Program means either the Program or any derivative work under copyright a work containing the Program or a portion of it
Definition: LICENSE:43
void barrier(void)
virtual void getDimensions(double &zBegin, double &zEnd) const override
Definition: Monitor.cpp:203
void driftToCorrectPositionAndSave(const Vector_t &R, const Vector_t &P)
Definition: Monitor.cpp:91
CollectionType
Definition: LossDataSink.h:71
CoordinateSystemTrafo getCSTrafoGlobal2Local() const
Definition: ElementBase.h:498
static std::map< double, SetStatistics > statFileEntries_sm
Definition: Monitor.h:109
ParticleAttrib< Vector_t > P
static int myNode()
Definition: IpplInfo.cpp:691
Vektor< double, 3 > Vector_t
Definition: Vektor.h:6
bool asciidump
Definition: Options.cpp:85
ParticleAttrib< double > M
unsigned int rewindLinesSDDS(const std::string &fileName, double maxSPos, bool checkForTime)
rewind the SDDS file such that the spos of the last step is less or equal to maxSPos ...
Definition: Util.cpp:240
PartBunchBase< double, 3 > * RefPartBunch_m
Definition: Component.h:191
double get_sPos() const
virtual void visitMonitor(const Monitor &)=0
Apply the algorithm to a beam position monitor.
Vector_t transformFrom(const Vector_t &r) const
double getdT() const
CoordinateSystemTrafo toLabTrafo_m
Vector_t rotateFrom(const Vector_t &r) const
T euclidean_norm(const Vector< T > &)
Euclidean norm.
Definition: Vector.h:243
virtual void goOffline() override
Definition: Monitor.cpp:188
size_t getTotalNum() const
FRONT * fs
Definition: hypervolume.cpp:59
static Communicate * Comm
Definition: IpplInfo.h:84
CoordinateSystemTrafo csTrafoGlobal2Local_m
Definition: ElementBase.h:366
Vector_t rotateTo(const Vector_t &r) const
bool online_m
Definition: Component.h:192
virtual ~Monitor()
Definition: Monitor.cpp:60
virtual void finalise() override
Definition: Monitor.cpp:180
Vector_t getBeta(Vector_t p)
Definition: Util.h:51
ElementType
Definition: ElementBase.h:88
long long getGlobalTrackStep() const
virtual bool apply(const size_t &i, const double &t, Vector_t &E, Vector_t &B) override
Definition: Monitor.cpp:68
ParticleAttrib< double > Q
OpenMode
Enum for writing to files.
Definition: OpalData.h:64
Vector_t transformTo(const Vector_t &r) const
std::string filename_m
Definition: Monitor.h:102
ParticleAttrib< double > dt
OpenMode getOpenMode() const
Definition: OpalData.cpp:353
std::unique_ptr< LossDataSink > lossDs_m
Definition: Monitor.h:107
unsigned int numPassages_m
Definition: Monitor.h:105
virtual bool applyToReferenceParticle(const Vector_t &R, const Vector_t &P, const double &t, Vector_t &E, Vector_t &B) override
Definition: Monitor.cpp:106
const std::string name
ParticlePos_t & R
ParticleIndex_t & ID
Quaternion getQuaternion(Vector_t u, Vector_t ref)
Definition: Quaternion.cpp:34
static const double halfLength_s
Definition: Monitor.h:110
void addRow(const SetStatistics &set)
std::string getInputBasename()
get input file name without extension
Definition: OpalData.cpp:674
virtual bool bends() const override
Definition: Monitor.cpp:199
bool update(const AttributeSet &)
Update element.
Interface for a single beam element.
Definition: Component.h:50
Monitor()
Definition: Monitor.cpp:37
std::string getOutputFN() const
Get output filename.
virtual void goOnline(const double &kineticEnergy) override
Definition: Monitor.cpp:184
virtual void accept(BeamlineVisitor &) const override
Apply visitor to Monitor.
Definition: Monitor.cpp:64
virtual void initialise(PartBunchBase< double, 3 > *bunch, double &startField, double &endField) override
Definition: Monitor.cpp:149
virtual ElementType getType() const override
Get element type std::string.
Definition: Monitor.cpp:209