OPALX (Object Oriented Parallel Accelerator Library for Exascal) master (dc2a29eed580)
OPALX
Loading...
Searching...
No Matches
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
30
31PluginElement::PluginElement(const std::string& name) : Component(name) {
32 setDimensions(0.0, 0.0, 0.0, 0.0);
33}
34
36 setDimensions(right.xstart_m, right.xend_m, right.ystart_m, right.yend_m);
37}
38
42
43void PluginElement::initialise(PartBunch_t* bunch, double&, double&) { initialise(bunch); }
44
46 RefPartBunch_m = bunch;
47 lossDs_m = std::unique_ptr<LossDataSink>(new LossDataSink(getOutputFN(), !Options::asciidump));
48 // virtual hook
49 doInitialise(bunch);
50 goOnline(-1e6);
51}
52
57
59 if (online_m && lossDs_m) lossDs_m->save();
60 lossDs_m.reset(nullptr);
62 online_m = false;
63}
64
65bool PluginElement::bends() const { return false; }
66
67bool PluginElement::apply(const std::shared_ptr<ParticleContainer_t>& /*pc*/) { return false; }
68
70 const size_t& /*i*/, const double&, Vector_t<double, 3>&, Vector_t<double, 3>&) {
71 return false;
72}
73
75 const Vector_t<double, 3>& /*R*/, const Vector_t<double, 3>& /*P*/, const double& /*t*/,
77 *gmsg << "passed R, P, t, E, B arguments not used in PluginElement::apply" << endl;
78 return false;
79}
80
86
87void PluginElement::setDimensions(double xstart, double xend, double ystart, double yend) {
88 xstart_m = xstart;
89 ystart_m = ystart;
90 xend_m = xend;
91 yend_m = yend;
92 rstart_m = std::hypot(xstart, ystart);
93 rend_m = std::hypot(xend, yend);
94 // start position is the one with lowest radius
95 if (rstart_m > rend_m) {
96 std::swap(xstart_m, xend_m);
97 std::swap(ystart_m, yend_m);
98 std::swap(rstart_m, rend_m);
99 }
100 A_m = yend_m - ystart_m;
101 B_m = xstart_m - xend_m;
102 R_m = std::sqrt(A_m * A_m + B_m * B_m);
104
105 // element equation: A*X + B*Y + C = 0
106 // point closest to origin https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line
107 double x_close = 0.0;
108 if (R_m > 0.0) x_close = -A_m * C_m / (R_m * R_m);
109
110 if (x_close > std::min(xstart_m, xend_m) && x_close < std::max(xstart_m, xend_m))
111 rmin_m = std::abs(C_m) / std::hypot(A_m, B_m);
112 else
114}
115
116void PluginElement::setGeom(const double dist) {
117 double slope;
118 if (xend_m == xstart_m)
119 slope = 1.0e12;
120 else
121 slope = (yend_m - ystart_m) / (xend_m - xstart_m);
122
123 double coeff2 = std::sqrt(1 + slope * slope);
124 double coeff1 = slope / coeff2;
125 double halfdist = dist / 2.0;
126 geom_m[0].x = xstart_m - halfdist * coeff1;
127 geom_m[0].y = ystart_m + halfdist / coeff2;
128
129 geom_m[1].x = xstart_m + halfdist * coeff1;
130 geom_m[1].y = ystart_m - halfdist / coeff2;
131
132 geom_m[2].x = xend_m + halfdist * coeff1;
133 geom_m[2].y = yend_m - halfdist / coeff2;
134
135 geom_m[3].x = xend_m - halfdist * coeff1;
136 geom_m[3].y = yend_m + halfdist / coeff2;
137
138 geom_m[4].x = geom_m[0].x;
139 geom_m[4].y = geom_m[0].y;
140
141 doSetGeom();
142}
143
145 PartBunch_t* bunch, int i, const double tstep, const double tangle) {
146 constexpr double c_mtns = Physics::c / Units::s2ns; // m/s --> m/ns
147
148 const double tmp = std::sqrt(dot(bunch->P(i), bunch->P(i)));
149 double lstep = tmp / Util::getGamma(bunch->P(i)) * c_mtns * tstep; // [m]
150 double sWidth = lstep / std::sqrt(1 + 1 / tangle / tangle);
151 setGeom(sWidth);
152}
153
154double PluginElement::calculateIncidentAngle(double xp, double yp) const {
155 double k1, k2, tangle = 0.0;
156 if (B_m == 0.0 && xp == 0.0) {
157 // width is 0.0, keep non-zero
158 tangle = 0.1;
159 } else if (B_m == 0.0) {
160 k1 = yp / xp;
161 if (k1 == 0.0)
162 tangle = 1.0e12;
163 else
164 tangle = std::abs(1 / k1);
165 } else if (xp == 0.0) {
166 k2 = -A_m / B_m;
167 if (k2 == 0.0)
168 tangle = 1.0e12;
169 else
170 tangle = std::abs(1 / k2);
171 } else {
172 k1 = yp / xp;
173 k2 = -A_m / B_m;
174 tangle = std::abs((k1 - k2) / (1 + k1 * k2));
175 }
176 return tangle;
177}
178
179double PluginElement::getXStart() const { return xstart_m; }
180
181double PluginElement::getXEnd() const { return xend_m; }
182
183double PluginElement::getYStart() const { return ystart_m; }
184
185double PluginElement::getYEnd() const { return yend_m; }
186
188 PartBunch_t* bunch, const int turnnumber, const double t, const double tstep) {
189 bool flag = false;
190 // check if bunch close
191 bool bunchClose = preCheck(bunch);
192
193 if (bunchClose == true) {
194 flag = doCheck(bunch, turnnumber, t, tstep); // virtual hook
195 }
196 // finalise, can have reduce
197 flag = finaliseCheck(bunch, flag);
198
199 return flag;
200}
201
202void PluginElement::getFieldExtend(double& zBegin, double& zEnd) const {
203 zBegin = -0.005;
204 zEnd = 0.005;
205}
206
207int PluginElement::checkPoint(const double& x, const double& y) const {
208 int cn = 0;
209 for (int i = 0; i < 4; i++) {
210 if (((geom_m[i].y <= y) && (geom_m[i + 1].y > y))
211 || ((geom_m[i].y > y) && (geom_m[i + 1].y <= y))) {
212 float vt = (float)(y - geom_m[i].y) / (geom_m[i + 1].y - geom_m[i].y);
213 if (x < geom_m[i].x + vt * (geom_m[i + 1].x - geom_m[i].x)) ++cn;
214 }
215 }
216 return (cn & 1); // 0 if even (out), and 1 if odd (in)
217}
218
220 OpalData::OpenMode openMode;
221 if (numPassages_m > 0) {
223 } else {
224 openMode = OpalData::getInstance()->getOpenMode();
225 }
226 lossDs_m->save(1, openMode);
228}
Inform * gmsg
Definition changes.cpp:7
double x
Definition Component.h:29
double y
Definition Component.h:30
ippl::Vector< T, Dim > Vector_t
Template PIC bunch: IPPL PicManager, shared field mesh/solver, and multiple particle containers.
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
Definition Vector3D.cpp:95
bool online_m
Definition Component.h:226
virtual void goOnline(const double &kineticEnergy)
Definition Component.cpp:43
PartBunch_t * RefPartBunch_m
Definition Component.h:225
std::string getOutputFN() const
Get output filename.
OpenMode getOpenMode() const
Definition OpalData.cpp:300
static OpalData * getInstance()
Definition OpalData.cpp:193
OpenMode
Enum for writing to files.
Definition OpalData.h:58
Vector_t< double, Dim > P(size_t)
Do not use; throws (access momenta via ParticleContainer::P).
Definition PartBunch.h:620
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 getFieldExtend(double &zBegin, double &zEnd) const override
Return the field-support extent of the component.
virtual bool bends() const override
double C_m
Geometric lengths used in calculations.
virtual bool apply(const std::shared_ptr< ParticleContainer_t > &pc) override
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 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
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
Apply to reference particle with position R and momemtum P.
void save()
Save output.
bool asciidump
Definition Options.cpp:87
constexpr double c
The velocity of light in m/s.
Definition Physics.h:60
constexpr double s2ns
Definition Units.h:44
double getGamma(ippl::Vector< double, 3 > p)
Definition Util.h:44