OPALX (Object Oriented Parallel Accelerator Library for Exascal) MINIorX
OPALX
PluginElement.cpp
Go to the documentation of this file.
1//
2// Class PluginElement
3// Abstract Interface for (Cyclotron) Plugin Elements (CCollimator, Probe, Stripper, Septum)
4// Implementation via Non-Virtual Interface Template Method
5//
6// Copyright (c) 2018-2020, Paul Scherrer Institut, Villigen PSI, Switzerland
7// All rights reserved
8//
9// This file is part of OPAL.
10//
11// OPAL is free software: you can redistribute it and/or modify
12// it under the terms of the GNU General Public License as published by
13// the Free Software Foundation, either version 3 of the License, or
14// (at your option) any later version.
15//
16// You should have received a copy of the GNU General Public License
17// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
18//
20
22#include "PartBunch/PartBunch.h"
23#include "Physics/Physics.h"
24#include "Physics/Units.h"
26#include "Utilities/Options.h"
27#include "Utilities/Util.h"
28
31
32PluginElement::PluginElement(const std::string& name) : Component(name) {
33 setDimensions(0.0, 0.0, 0.0, 0.0);
34}
35
37 setDimensions(right.xstart_m, right.xend_m, right.ystart_m, right.yend_m);
38}
39
44
45void PluginElement::initialise(PartBunch_t* bunch, double&, double&) {
46 initialise(bunch);
47}
48
50 RefPartBunch_m = bunch;
51 lossDs_m = std::unique_ptr<LossDataSink>(new LossDataSink(getOutputFN(), !Options::asciidump));
52 // virtual hook
53 doInitialise(bunch);
54 goOnline(-1e6);
55}
56
58 doFinalise();
59 if (online_m)
60 goOffline();
61}
62
64 if (online_m && lossDs_m)
65 lossDs_m->save();
66 lossDs_m.reset(nullptr);
68 online_m = false;
69}
70
72 return false;
73}
74
76 const size_t& /*i*/, const double&, Vector_t<double, 3>&, Vector_t<double, 3>&) {
77 return false;
78}
79
81 const Vector_t<double, 3>& R, const Vector_t<double, 3>& P, const double& t,
83 return false;
84}
85
86
87
93
94void PluginElement::setDimensions(double xstart, double xend, double ystart, double yend) {
95 xstart_m = xstart;
96 ystart_m = ystart;
97 xend_m = xend;
98 yend_m = yend;
99 rstart_m = std::hypot(xstart, ystart);
100 rend_m = std::hypot(xend, yend);
101 // start position is the one with lowest radius
102 if (rstart_m > rend_m) {
103 std::swap(xstart_m, xend_m);
104 std::swap(ystart_m, yend_m);
105 std::swap(rstart_m, rend_m);
106 }
107 A_m = yend_m - ystart_m;
108 B_m = xstart_m - xend_m;
109 R_m = std::sqrt(A_m * A_m + B_m * B_m);
111
112 // element equation: A*X + B*Y + C = 0
113 // point closest to origin https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line
114 double x_close = 0.0;
115 if (R_m > 0.0)
116 x_close = -A_m * C_m / (R_m * R_m);
117
118 if (x_close > std::min(xstart_m, xend_m) && x_close < std::max(xstart_m, xend_m))
119 rmin_m = std::abs(C_m) / std::hypot(A_m, B_m);
120 else
122}
123
124void PluginElement::setGeom(const double dist) {
125 double slope;
126 if (xend_m == xstart_m)
127 slope = 1.0e12;
128 else
129 slope = (yend_m - ystart_m) / (xend_m - xstart_m);
130
131 double coeff2 = std::sqrt(1 + slope * slope);
132 double coeff1 = slope / coeff2;
133 double halfdist = dist / 2.0;
134 geom_m[0].x = xstart_m - halfdist * coeff1;
135 geom_m[0].y = ystart_m + halfdist / coeff2;
136
137 geom_m[1].x = xstart_m + halfdist * coeff1;
138 geom_m[1].y = ystart_m - halfdist / coeff2;
139
140 geom_m[2].x = xend_m + halfdist * coeff1;
141 geom_m[2].y = yend_m - halfdist / coeff2;
142
143 geom_m[3].x = xend_m - halfdist * coeff1;
144 geom_m[3].y = yend_m + halfdist / coeff2;
145
146 geom_m[4].x = geom_m[0].x;
147 geom_m[4].y = geom_m[0].y;
148
149 doSetGeom();
150}
151
153 PartBunch_t* bunch, int i, const double tstep, const double tangle) {
154 constexpr double c_mtns = Physics::c / Units::s2ns; // m/s --> m/ns
155
156 const double tmp = std::sqrt(dot(bunch->P(i), bunch->P(i)));
157 double lstep = tmp / Util::getGamma(bunch->P(i)) * c_mtns * tstep; // [m]
158 double sWidth = lstep / std::sqrt(1 + 1 / tangle / tangle);
159 setGeom(sWidth);
160}
161
162double PluginElement::calculateIncidentAngle(double xp, double yp) const {
163 double k1, k2, tangle = 0.0;
164 if (B_m == 0.0 && xp == 0.0) {
165 // width is 0.0, keep non-zero
166 tangle = 0.1;
167 } else if (B_m == 0.0) {
168 k1 = yp / xp;
169 if (k1 == 0.0)
170 tangle = 1.0e12;
171 else
172 tangle = std::abs(1 / k1);
173 } else if (xp == 0.0) {
174 k2 = -A_m / B_m;
175 if (k2 == 0.0)
176 tangle = 1.0e12;
177 else
178 tangle = std::abs(1 / k2);
179 } else {
180 k1 = yp / xp;
181 k2 = -A_m / B_m;
182 tangle = std::abs((k1 - k2) / (1 + k1 * k2));
183 }
184 return tangle;
185}
186
188 return xstart_m;
189}
190
192 return xend_m;
193}
194
196 return ystart_m;
197}
198
200 return yend_m;
201}
202
204 PartBunch_t* bunch, const int turnnumber, const double t, const double tstep) {
205 bool flag = false;
206 // check if bunch close
207 bool bunchClose = preCheck(bunch);
208
209 if (bunchClose == true) {
210 flag = doCheck(bunch, turnnumber, t, tstep); // virtual hook
211 }
212 // finalise, can have reduce
213 flag = finaliseCheck(bunch, flag);
214
215 return flag;
216}
217
218void PluginElement::getDimensions(double& zBegin, double& zEnd) const {
219 zBegin = -0.005;
220 zEnd = 0.005;
221}
222
223int PluginElement::checkPoint(const double& x, const double& y) const {
224 int cn = 0;
225 for (int i = 0; i < 4; i++) {
226 if (((geom_m[i].y <= y) && (geom_m[i + 1].y > y))
227 || ((geom_m[i].y > y) && (geom_m[i + 1].y <= y))) {
228 float vt = (float)(y - geom_m[i].y) / (geom_m[i + 1].y - geom_m[i].y);
229 if (x < geom_m[i].x + vt * (geom_m[i + 1].x - geom_m[i].x))
230 ++cn;
231 }
232 }
233 return (cn & 1); // 0 if even (out), and 1 if odd (in)
234}
235
237 OpalData::OpenMode openMode;
238 if (numPassages_m > 0) {
240 } else {
241 openMode = OpalData::getInstance()->getOpenMode();
242 }
243 lossDs_m->save(1, openMode);
245}
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
Definition Vector3D.cpp:118
PartBunch< PLayout_t< double, 3 >, double, 3 > PartBunch_t
ippl::Vector< T, Dim > Vector_t
constexpr double c
The velocity of light in m/s.
Definition Physics.h:45
constexpr double s2ns
Definition Units.h:44
bool asciidump
Definition Options.cpp:85
double getGamma(ippl::Vector< double, 3 > p)
Definition Util.h:44
bool online_m
Definition Component.h:186
virtual void goOnline(const double &kineticEnergy)
Definition Component.cpp:64
Component(const std::string &name)
Constructor with given name.
Definition Component.cpp:44
PartBunch_t * RefPartBunch_m
Definition Component.h:185
std::string getOutputFN() const
Get output filename.
int checkPoint(const double &x, const double &y) const
Checks if coordinate is within element.
void setGeom(const double dist)
Sets geometry geom_m with element width dist.
virtual void getDimensions(double &zBegin, double &zEnd) const override
virtual bool bends() const override
double C_m
Geometric lengths used in calculations.
double getYStart() const
void changeWidth(PartBunch_t *bunch, int i, const double tstep, const double tangle)
Change probe width depending on step size and angle of particle.
virtual void finalise() final
virtual void doSetGeom()
Virtual hook for setGeom.
virtual void doGoOffline()
Virtual hook for goOffline.
int numPassages_m
Number of turns (number of times save() method is called).
virtual bool apply(const size_t &i, const double &t, Vector_t< double, 3 > &E, Vector_t< double, 3 > &B) override
Virtual implementation of Component.
virtual bool doCheck(PartBunch_t *bunch, const int turnnumber, const double t, const double tstep)=0
Pure virtual hook for check.
virtual void doInitialise(PartBunch_t *)
Pure virtual hook for initialise.
bool finaliseCheck(PartBunch_t *bunch, bool flagNeedUpdate)
Finalise call after check.
virtual void doFinalise()
Virtual hook for finalise.
virtual void goOffline() final
double getXEnd() const
bool preCheck(PartBunch_t *bunch)
Check if bunch is close to element.
double calculateIncidentAngle(double xp, double yp) const
Calculate angle of particle/bunch wrt to element.
double xstart_m
input geometry positions
virtual void initialise(PartBunch_t *bunch, double &startField, double &endField) override
Pure virtual implementation of Component.
void setDimensions(double xstart, double xend, double ystart, double yend)
Set dimensions and consistency checks.
std::unique_ptr< LossDataSink > lossDs_m
Pointer to Loss instance.
double getXStart() const
Member variable access.
bool check(PartBunch_t *bunch, const int turnnumber, const double t, const double tstep)
double getYEnd() const
double rmin_m
radius closest to the origin
PluginElement(const std::string &name)
Constructor with given name.
virtual ~PluginElement()
virtual bool applyToReferenceParticle(const Vector_t< double, 3 > &R, const Vector_t< double, 3 > &P, const double &t, Vector_t< double, 3 > &E, Vector_t< double, 3 > &B) override
void save()
Save output.
OpenMode getOpenMode() const
Definition OpalData.cpp:352
static OpalData * getInstance()
Definition OpalData.cpp:195
OpenMode
Enum for writing to files.
Definition OpalData.h:58
ParticleAttrib< Vector_t< T, Dim > > P