OPAL (Object Oriented Parallel Accelerator Library) 2024.2
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"
27#include "Utilities/Options.h"
28#include "Utilities/Util.h"
29
30#include <fstream>
31#include <memory>
32
33
34std::map<double, SetStatistics> Monitor::statFileEntries_sm;
35const double Monitor::halfLength_s = 0.005;
36
40
41
43 Component(right),
45 plane_m(right.plane_m),
46 type_m(right.type_m),
48{}
49
50
51Monitor::Monitor(const std::string &name):
53 filename_m(""),
54 plane_m(OFF),
57{}
58
59
62
63
64void Monitor::accept(BeamlineVisitor &visitor) const {
65 visitor.visitMonitor(*this);
66}
67
68bool 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),
123 csTrafoGlobal2Local_m.rotateFrom(P),
124 time,
125 RefPartBunch_m->get_sPos() + ds,
126 RefPartBunch_m->getGlobalTrackStep());
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) {
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
149void 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
184void 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
199bool Monitor::bends() const {
200 return false;
201}
202
203void Monitor::getDimensions(double &zBegin, double &zEnd) const {
204 zBegin = -halfLength_s;
205 zEnd = halfLength_s;
206}
207
208
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}
ElementType
Definition ElementBase.h:88
Quaternion getQuaternion(Vector_t u, Vector_t ref)
CollectionType
T euclidean_norm(const Vector< T > &)
Euclidean norm.
Definition Vector.h:243
const std::string name
constexpr double c
The velocity of light in m/s.
Definition Physics.h:45
bool asciidump
Definition Options.cpp:85
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
Vector_t getBeta(Vector_t p)
Definition Util.h:51
size_t getTotalNum() const
double get_sPos() const
std::string getInputBasename()
get input file name without extension
Definition OpalData.cpp:674
OpenMode getOpenMode() const
Definition OpalData.cpp:353
static OpalData * getInstance()
Definition OpalData.cpp:196
OpenMode
Enum for writing to files.
Definition OpalData.h:64
virtual void visitMonitor(const Monitor &)=0
Apply the algorithm to a beam position monitor.
bool online_m
Definition Component.h:192
Component(const std::string &name)
Constructor with given name.
Definition Component.cpp:53
PartBunchBase< double, 3 > * RefPartBunch_m
Definition Component.h:191
bool update(const AttributeSet &)
Update element.
CoordinateSystemTrafo getCSTrafoGlobal2Local() const
std::string getOutputFN() const
Get output filename.
CoordinateSystemTrafo csTrafoGlobal2Local_m
CollectionType type_m
Definition Monitor.h:104
static void writeStatistics()
Definition Monitor.cpp:213
virtual void accept(BeamlineVisitor &) const override
Apply visitor to Monitor.
Definition Monitor.cpp:64
std::string filename_m
Definition Monitor.h:102
virtual void goOnline(const double &kineticEnergy) override
Definition Monitor.cpp:184
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
@ OFF
Monitor is off (inactive).
Definition Monitor.h:39
virtual ElementType getType() const override
Get element type std::string.
Definition Monitor.cpp:209
virtual void initialise(PartBunchBase< double, 3 > *bunch, double &startField, double &endField) override
Definition Monitor.cpp:149
virtual void goOffline() override
Definition Monitor.cpp:188
std::unique_ptr< LossDataSink > lossDs_m
Definition Monitor.h:107
virtual void getDimensions(double &zBegin, double &zEnd) const override
Definition Monitor.cpp:203
Monitor(const std::string &name)
Constructor with given name.
Definition Monitor.cpp:51
Monitor()
Definition Monitor.cpp:37
virtual ~Monitor()
Definition Monitor.cpp:60
Plane plane_m
Definition Monitor.h:103
static std::map< double, SetStatistics > statFileEntries_sm
Definition Monitor.h:109
virtual void finalise() override
Definition Monitor.cpp:180
unsigned int numPassages_m
Definition Monitor.h:105
static const double halfLength_s
Definition Monitor.h:110
virtual bool bends() const override
Definition Monitor.cpp:199
virtual bool apply(const size_t &i, const double &t, Vector_t &E, Vector_t &B) override
Definition Monitor.cpp:68
void driftToCorrectPositionAndSave(const Vector_t &R, const Vector_t &P)
Definition Monitor.cpp:91
Vector_t transformTo(const Vector_t &r) const
Vector_t rotateTo(const Vector_t &r) const
void addRow(const SetStatistics &set)
static int myNode()
Definition IpplInfo.cpp:691
static Communicate * Comm
Definition IpplInfo.h:84
Vektor< double, 3 > Vector_t