OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
PluginElement.cpp
Go to the documentation of this file.
2 
6 #include "Utilities/Options.h"
7 
8 extern Inform *gmsg;
9 
11 {}
12 
13 PluginElement::PluginElement(const std::string &name):
14  Component(name),
15  filename_m(""),
16  position_m(0.0) {
17  setDimensions(0.0, 0.0, 0.0, 0.0);
18 }
19 
21  Component(right),
22  filename_m(right.filename_m),
23  position_m(right.position_m) {
24  setDimensions(right.xstart_m, right.xend_m, right.ystart_m, right.yend_m);
25 }
26 
28  if (online_m)
29  goOffline();
30 }
31 
32 void PluginElement::initialise(PartBunchBase<double, 3> *bunch, double &, double &) {
33  initialise(bunch);
34 }
35 
37  RefPartBunch_m = bunch;
38  lossDs_m = std::unique_ptr<LossDataSink>(new LossDataSink(getOutputFN(), !Options::asciidump));
39  // virtual hook
40  doInitialise(bunch);
41  goOnline(-1e6);
42 }
43 
45  doFinalise();
46  if (online_m)
47  goOffline();
48 }
49 
51  if (online_m && lossDs_m)
52  lossDs_m->save();
53  lossDs_m.reset(nullptr);
54  doGoOffline();
55  online_m = false;
56 }
57 
58 bool PluginElement::bends() const {
59  return false;
60 }
61 
62 bool PluginElement::apply(const size_t &i, const double &, Vector_t &, Vector_t &) {
63  return false;
64 }
65 
66 bool PluginElement::applyToReferenceParticle(const Vector_t &, const Vector_t &, const double &, Vector_t &, Vector_t &) {
67  return false;
68 }
69 
70 void PluginElement::setOutputFN(std::string fn) {
71  filename_m = fn;
72 }
73 
74 std::string PluginElement::getOutputFN() const {
75  if (filename_m == std::string(""))
76  return getName();
77  else
78  return filename_m.substr(0, filename_m.rfind("."));
79 }
80 
81 void PluginElement::setDimensions(double xstart, double xend, double ystart, double yend) {
82  xstart_m = xstart;
83  ystart_m = ystart;
84  xend_m = xend;
85  yend_m = yend;
86  rstart_m = std::hypot(xstart, ystart);
87  rend_m = std::hypot(xend, yend);
88  // start position is the one with lowest radius
89  if (rstart_m > rend_m) {
90  std::swap(xstart_m, xend_m);
91  std::swap(ystart_m, yend_m);
92  std::swap(rstart_m, rend_m);
93  }
94  A_m = yend_m - ystart_m;
95  B_m = xstart_m - xend_m;
97  C_m = ystart_m*xend_m - xstart_m*yend_m;
98 
99  // element equation: A*X + B*Y + C = 0
100  // point closest to origin https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line
101  double x_close = 0.0;
102  if (R_m > 0.0)
103  x_close = - A_m * C_m / (R_m * R_m);
104 
105  if (x_close > std::min(xstart_m, xend_m) && x_close < std::max(xstart_m, xend_m) )
106  rmin_m = std::abs(C_m) / std::hypot(A_m,B_m);
107  else
108  rmin_m = rstart_m;
109 }
110 
111 void PluginElement::setGeom(const double dist) {
112 
113  double slope;
114  if (xend_m == xstart_m)
115  slope = 1.0e12;
116  else
117  slope = (yend_m - ystart_m) / (xend_m - xstart_m);
118 
119  double coeff2 = sqrt(1 + slope * slope);
120  double coeff1 = slope / coeff2;
121  double halfdist = dist / 2.0;
122  geom_m[0].x = xstart_m - halfdist * coeff1;
123  geom_m[0].y = ystart_m + halfdist / coeff2;
124 
125  geom_m[1].x = xstart_m + halfdist * coeff1;
126  geom_m[1].y = ystart_m - halfdist / coeff2;
127 
128  geom_m[2].x = xend_m + halfdist * coeff1;
129  geom_m[2].y = yend_m - halfdist / coeff2;
130 
131  geom_m[3].x = xend_m - halfdist * coeff1;
132  geom_m[3].y = yend_m + halfdist / coeff2;
133 
134  geom_m[4].x = geom_m[0].x;
135  geom_m[4].y = geom_m[0].y;
136 
137  doSetGeom();
138 }
139 
140 void PluginElement::changeWidth(PartBunchBase<double, 3> *bunch, int i, const double tstep, const double tangle) {
141 
142  constexpr double c_mmtns = Physics::c * 1.0e-6; // m/s --> mm/ns
143  double lstep = euclidean_norm(bunch->P[i]) / Util::getGamma(bunch->P[i]) * c_mmtns * tstep; // [mm]
144  double sWidth = lstep / sqrt( 1 + 1/tangle/tangle );
145  setGeom(sWidth);
146 }
147 
148 double PluginElement::calculateIncidentAngle(double xp, double yp) const {
149  double k1, k2, tangle = 0.0;
150  if ( B_m == 0.0 && xp == 0.0) {
151  // width is 0.0, keep non-zero
152  tangle = 0.1;
153  } else if ( B_m == 0.0 ){
154  k1 = yp / xp;
155  if (k1 == 0.0)
156  tangle = 1.0e12;
157  else
158  tangle = std::abs(1 / k1);
159  } else if ( xp == 0.0 ) {
160  k2 = - A_m/B_m;
161  if ( k2 == 0.0 )
162  tangle = 1.0e12;
163  else
164  tangle = std::abs(1 / k2);
165  } else {
166  k1 = yp / xp;
167  k2 = - A_m / B_m;
168  tangle = std::abs(( k1-k2 ) / (1 + k1*k2));
169  }
170  return tangle;
171 }
172 
173 double PluginElement::getXStart() const {
174  return xstart_m;
175 }
176 
177 double PluginElement::getXEnd() const {
178  return xend_m;
179 }
180 
181 double PluginElement::getYStart() const {
182  return ystart_m;
183 }
184 
185 double PluginElement::getYEnd() const {
186  return yend_m;
187 }
188 
189 bool PluginElement::check(PartBunchBase<double, 3> *bunch, const int turnnumber, const double t, const double tstep) {
190  bool flag = false;
191  // check if bunch close
192  bool bunchClose = preCheck(bunch);
193 
194  if (bunchClose == true) {
195  flag = doCheck(bunch, turnnumber, t, tstep); // virtual hook
196  }
197  // finalise, can have reduce
198  flag = finaliseCheck(bunch, flag);
199 
200  return flag;
201 }
202 
203 void PluginElement::getDimensions(double &zBegin, double &zEnd) const {
204  zBegin = position_m - 0.005;
205  zEnd = position_m + 0.005;
206 }
207 
208 int PluginElement::checkPoint(const double &x, const double &y) const {
209  int cn = 0;
210  for(int i = 0; i < 4; i++) {
211  if(( (geom_m[i].y <= y) && (geom_m[i+1].y > y))
212  || ((geom_m[i].y > y) && (geom_m[i+1].y <= y))) {
213 
214  float vt = (float)(y - geom_m[i].y) / (geom_m[i+1].y - geom_m[i].y);
215  if(x < geom_m[i].x + vt * (geom_m[i+1].x - geom_m[i].x))
216  ++cn;
217  }
218  }
219  return (cn & 1); // 0 if even (out), and 1 if odd (in)
220 }
221 
223  OpalData::OPENMODE openMode;
224  if (numPassages_m > 0) {
225  openMode = OpalData::OPENMODE::APPEND;
226  } else {
227  openMode = OpalData::getInstance()->getOpenMode();
228  }
229  lossDs_m->save(1, openMode);
230  numPassages_m++;
231 }
ParticleAttrib< Vector_t > P
bool preCheck(PartBunchBase< double, 3 > *bunch)
Check if bunch is close to element.
Definition: PluginElement.h:81
void save()
Save output.
double getXStart() const
Member variable access.
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
bool finaliseCheck(PartBunchBase< double, 3 > *bunch, bool flagNeedUpdate)
Finalise call after check.
Definition: PluginElement.h:83
double calculateIncidentAngle(double xp, double yp) const
Calculate angle of particle/bunch wrt to element.
virtual void doGoOffline()
Virtual hook for goOffline.
Definition: PluginElement.h:97
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:123
Point geom_m[5]
actual geometry positions with adaptive width such that each particle hits element once per turn ...
double x
Definition: Component.h:39
virtual void finalise() final
Inform * gmsg
Definition: Main.cpp:21
double C_m
Geometric lengths used in calculations.
bool online_m
Definition: Component.h:201
double getYEnd() const
std::unique_ptr< LossDataSink > lossDs_m
Pointer to Loss instance.
virtual const std::string & getName() const
Get element name.
Definition: ElementBase.cpp:95
virtual void goOffline() final
double rmin_m
radius closest to the origin
virtual bool apply(const size_t &i, const double &t, Vector_t &E, Vector_t &B) override
void changeWidth(PartBunchBase< double, 3 > *bunch, int i, const double tstep, const double tangle)
Change probe width depending on step size and angle of particle.
static OpalData * getInstance()
Definition: OpalData.cpp:209
double getYStart() const
double getGamma(Vector_t p)
Definition: Util.h:24
int numPassages_m
Number of turns (number of times save() method is called)
double xstart_m
input geometry positions
OPENMODE
Enum for writing to files.
Definition: OpalData.h:69
virtual bool bends() const override
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:52
std::string getOutputFN() const
Get output filename.
std::string filename_m
Definition: PluginElement.h:97
void setGeom(const double dist)
Sets geometry geom_m with element width dist.
double y
Definition: Component.h:40
PartBunchBase< double, 3 > * RefPartBunch_m
Definition: Component.h:200
OPENMODE getOpenMode() const
Definition: OpalData.cpp:381
virtual void doSetGeom()
Virtual hook for setGeom.
Definition: PluginElement.h:89
Tps< T > sqrt(const Tps< T > &x)
Square root.
Definition: TpsMath.h:91
virtual void doInitialise(PartBunchBase< double, 3 > *bunch)
Pure virtual hook for initialise.
Definition: PluginElement.h:85
double getXEnd() const
bool asciidump
Definition: Options.cpp:18
T euclidean_norm(const Vector< T > &)
Euclidean norm.
Definition: Vector.h:243
const std::string name
virtual void goOnline(const double &kineticEnergy)
Definition: Component.cpp:83
Interface for a single beam element.
Definition: Component.h:51
virtual void initialise(PartBunchBase< double, 3 > *bunch, double &startField, double &endField) override
Pure virtual implementation of Component.
void setOutputFN(std::string fn)
Set output filename.
virtual bool doCheck(PartBunchBase< double, 3 > *bunch, const int turnnumber, const double t, const double tstep)=0
Pure virtual hook for check.
Definition: Inform.h:41
int checkPoint(const double &x, const double &y) const
Checks if coordinate is within element.
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:95
bool check(PartBunchBase< double, 3 > *bunch, const int turnnumber, const double t, const double tstep)
constexpr double c_mmtns
virtual void getDimensions(double &zBegin, double &zEnd) const override
virtual bool applyToReferenceParticle(const Vector_t &R, const Vector_t &P, const double &t, Vector_t &E, Vector_t &B) override
virtual void doFinalise()
Virtual hook for finalise.
Definition: PluginElement.h:95
void setDimensions(double xstart, double xend, double ystart, double yend)
Set dimensions and consistency checks.
virtual ~PluginElement()