OPAL (Object Oriented Parallel Accelerator Library) 2022.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"
27#include "Utilities/Options.h"
28#include "Utilities/Util.h"
29
30#include <boost/filesystem.hpp>
31
32#include <fstream>
33#include <memory>
34
35
36std::map<double, SetStatistics> Monitor::statFileEntries_sm;
37const double Monitor::halfLength_s = 0.005;
38
40 Monitor("")
41{}
42
43
45 Component(right),
46 filename_m(right.filename_m),
47 plane_m(right.plane_m),
48 type_m(right.type_m),
49 numPassages_m(0)
50{}
51
52
53Monitor::Monitor(const std::string &name):
55 filename_m(""),
56 plane_m(OFF),
57 type_m(CollectionType::SPATIAL),
58 numPassages_m(0)
59{}
60
61
63{}
64
65
66void Monitor::accept(BeamlineVisitor &visitor) const {
67 visitor.visitMonitor(*this);
68}
69
70bool Monitor::apply(const size_t &i, const double &t, Vector_t &/*E*/, Vector_t &/*B*/) {
71 const Vector_t &R = RefPartBunch_m->R[i];
72 const Vector_t &P = RefPartBunch_m->P[i];
73 const double &dt = RefPartBunch_m->dt[i];
74 const Vector_t singleStep = Physics::c * dt * Util::getBeta(P);
76 if (dt * R(2) < 0.0 &&
77 dt * (R(2) + singleStep(2)) > 0.0) {
78 // if R(2) is negative then frac should be positive and vice versa
79 double frac = -R(2) / singleStep(2);
80
81 lossDs_m->addParticle(OpalParticle(RefPartBunch_m->ID[i],
82 R + frac * singleStep,
83 P,
84 t + frac * dt,
85 RefPartBunch_m->Q[i],
86 RefPartBunch_m->M[i]));
87 }
88 }
89
90 return false;
91}
92
94 const double cdt = Physics::c * RefPartBunch_m->getdT();
95 const Vector_t driftPerTimeStep = cdt * Util::getBeta(refP);
96 const double tau = -refR(2) / driftPerTimeStep(2);
97 const CoordinateSystemTrafo update(refR + tau * driftPerTimeStep, getQuaternion(refP, Vector_t(0, 0, 1)));
99
100 for (OpalParticle particle : *RefPartBunch_m) {
101 Vector_t beta = refToLocalCSTrafo.rotateTo(Util::getBeta(particle.getP()));
102 Vector_t dS = (tau - 0.5) * cdt * beta; // the particles are half a step ahead relative to the reference particle
103 particle.setR(refToLocalCSTrafo.transformTo(particle.getR()) + dS);
104 lossDs_m->addParticle(particle);
105 }
106}
107
109 const Vector_t &P,
110 const double &t,
111 Vector_t &,
112 Vector_t &) {
113 if (!OpalData::getInstance()->isInPrepState()) {
114 const double dt = RefPartBunch_m->getdT();
115 const double cdt = Physics::c * dt;
116 const Vector_t singleStep = cdt * Util::getBeta(P);
117
118 if (dt * R(2) < 0.0 &&
119 dt * (R(2) + singleStep(2)) > 0.0) {
120 double frac = -R(2) / singleStep(2);
121 double time = t + frac * dt;
122 Vector_t dR = frac * singleStep;
123 double ds = euclidean_norm(dR + 0.5 * singleStep);
124 lossDs_m->addReferenceParticle(csTrafoGlobal2Local_m.transformFrom(R + dR),
126 time,
127 RefPartBunch_m->get_sPos() + ds,
129
132 auto stats = lossDs_m->computeStatistics(1);
133 if (!stats.empty()) {
134 statFileEntries_sm.insert(std::make_pair(stats.begin()->spos_m, *stats.begin()));
135 OpalData::OpenMode openMode;
136 if (numPassages_m > 0) {
138 } else {
139 openMode = OpalData::getInstance()->getOpenMode();
140 }
141 lossDs_m->save(1, openMode);
142 }
143 }
144
145 ++ numPassages_m;
146 }
147 }
148 return false;
149}
150
151void Monitor::initialise(PartBunchBase<double, 3> *bunch, double &startField, double &endField) {
152 RefPartBunch_m = bunch;
153 endField = startField + halfLength_s;
154 startField -= halfLength_s;
155
156 const size_t totalNum = bunch->getTotalNum();
157 double currentPosition = endField;
158 if (totalNum > 0) {
159 currentPosition = bunch->get_sPos();
160 }
161
163
164 if (OpalData::getInstance()->getOpenMode() == OpalData::OpenMode::WRITE ||
165 currentPosition < startField) {
166
167 namespace fs = boost::filesystem;
168
169 fs::path lossFileName = fs::path(filename_m + ".h5");
170 if (fs::exists(lossFileName)) {
172 if (Ippl::myNode() == 0) {
173 fs::remove(lossFileName);
174 }
176 }
177 }
178
179 lossDs_m = std::unique_ptr<LossDataSink>(new LossDataSink(filename_m, !Options::asciidump, type_m));
180}
181
183
184}
185
186void Monitor::goOnline(const double &) {
187 online_m = true;
188}
189
191 auto stats = lossDs_m->computeStatistics(numPassages_m);
192 for (auto &stat: stats) {
193 statFileEntries_sm.insert(std::make_pair(stat.spos_m, stat));
194 }
195
197 lossDs_m->save(numPassages_m);
198 }
199}
200
201bool Monitor::bends() const {
202 return false;
203}
204
205void Monitor::getDimensions(double &zBegin, double &zEnd) const {
206 zBegin = -halfLength_s;
207 zEnd = halfLength_s;
208}
209
210
213}
214
216 if (statFileEntries_sm.size() == 0) return;
217
218 std::string fileName = OpalData::getInstance()->getInputBasename() + std::string("_Monitors.stat");
219 auto instance = OpalData::getInstance();
220 bool hasPriorTrack = instance->hasPriorTrack();
221 bool inRestartRun = instance->inRestartRun();
222
223 auto it = statFileEntries_sm.begin();
224 double spos = it->first;
225 Util::rewindLinesSDDS(fileName, spos, false);
226
227 MonitorStatisticsWriter writer(fileName, hasPriorTrack || inRestartRun);
228
229 for (const auto &entry: statFileEntries_sm) {
230 writer.addRow(entry.second);
231 }
232
233 statFileEntries_sm.clear();
234}
ElementType
Definition: ElementBase.h:88
Quaternion getQuaternion(Vector_t u, Vector_t ref)
Definition: Quaternion.cpp:34
CollectionType
Definition: LossDataSink.h:72
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:220
Vector_t getBeta(Vector_t p)
Definition: Util.h:50
FRONT * fs
Definition: hypervolume.cpp:59
ParticlePos_t & R
ParticleAttrib< double > M
size_t getTotalNum() const
ParticleAttrib< Vector_t > P
double getdT() const
ParticleAttrib< double > Q
CoordinateSystemTrafo toLabTrafo_m
ParticleAttrib< double > dt
long long getGlobalTrackStep() const
ParticleIndex_t & ID
double get_sPos() const
std::string getInputBasename()
get input file name without extension
Definition: OpalData.cpp:669
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.
Interface for a single beam element.
Definition: Component.h:50
bool online_m
Definition: Component.h:192
PartBunchBase< double, 3 > * RefPartBunch_m
Definition: Component.h:191
bool update(const AttributeSet &)
Update element.
CoordinateSystemTrafo getCSTrafoGlobal2Local() const
Definition: ElementBase.h:497
std::string getOutputFN() const
Get output filename.
CoordinateSystemTrafo csTrafoGlobal2Local_m
Definition: ElementBase.h:365
CollectionType type_m
Definition: Monitor.h:104
static void writeStatistics()
Definition: Monitor.cpp:215
virtual void accept(BeamlineVisitor &) const override
Apply visitor to Monitor.
Definition: Monitor.cpp:66
std::string filename_m
Definition: Monitor.h:102
virtual void goOnline(const double &kineticEnergy) override
Definition: Monitor.cpp:186
virtual bool applyToReferenceParticle(const Vector_t &R, const Vector_t &P, const double &t, Vector_t &E, Vector_t &B) override
Definition: Monitor.cpp:108
virtual ElementType getType() const override
Get element type std::string.
Definition: Monitor.cpp:211
virtual void initialise(PartBunchBase< double, 3 > *bunch, double &startField, double &endField) override
Definition: Monitor.cpp:151
virtual void goOffline() override
Definition: Monitor.cpp:190
std::unique_ptr< LossDataSink > lossDs_m
Definition: Monitor.h:107
virtual void getDimensions(double &zBegin, double &zEnd) const override
Definition: Monitor.cpp:205
Monitor()
Definition: Monitor.cpp:39
virtual ~Monitor()
Definition: Monitor.cpp:62
static std::map< double, SetStatistics > statFileEntries_sm
Definition: Monitor.h:109
virtual void finalise() override
Definition: Monitor.cpp:182
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:201
virtual bool apply(const size_t &i, const double &t, Vector_t &E, Vector_t &B) override
Definition: Monitor.cpp:70
void driftToCorrectPositionAndSave(const Vector_t &R, const Vector_t &P)
Definition: Monitor.cpp:93
Vector_t rotateFrom(const Vector_t &r) const
Vector_t transformFrom(const Vector_t &r) const
Vector_t transformTo(const Vector_t &r) const
Vector_t rotateTo(const Vector_t &r) const
void addRow(const SetStatistics &set)
void barrier(void)
static int myNode()
Definition: IpplInfo.cpp:691
static Communicate * Comm
Definition: IpplInfo.h:84
Vektor< double, 3 > Vector_t
Definition: Vektor.h:6