83 bool backBeam,
bool backTrack):
84 Tracker(beamline, nullptr, reference, backBeam, backTrack)
91 bool backBeam,
bool backTrack):
93 itsBeamline_m(beamline),
130 double lByPz = length /
std::sqrt(2 * P[2] * P[2] -
dot(P, P));
131 part.
setX(part.
getX() + P[0] * lByPz);
132 part.
setY(part.
getY() + P[1] * lByPz);
133 part.
setZ(part.
getZ() + P[2] * (refTime /
std::sqrt(P[2] * P[2] + kin * kin) - lByPz));
142 int order = field.
order();
145 for(
unsigned int i = 0; i < itsBunch_m->getLocalNum(); i++) {
148 double x = part.
getX();
149 double y = part.
getY();
150 double kx = + field.
normal(order);
151 double ky = - field.
skew(order);
155 double kxt = x * kx - y * ky;
156 double kyt = x * ky + y * kx;
157 kx = kxt + field.
normal(ord);
158 ky = kyt - field.
skew(ord);
163 itsBunch_m->setParticle(part, i);
171 Series2 As = buildSBendVectorPotential2D(field, h) * scale;
177 for(
unsigned int i = 0; i < itsBunch_m->getLocalNum(); i++) {
184 itsBunch_m->setParticle(part, i);
196 double px = part.
getPx();
197 double py = part.
getPy();
198 double pt = part.
getPz() + 1.0;
199 double pz =
std::sqrt(pt * pt - px * px - py * py);
201 part.
setPx(euclid.
M(0, 0) * px + euclid.
M(1, 0) * py + euclid.
M(2, 0) * pz);
202 part.
setPy(euclid.
M(0, 1) * px + euclid.
M(1, 1) * py + euclid.
M(2, 1) * pz);
203 pz = euclid.
M(0, 2) * px + euclid.
M(1, 2) * py + euclid.
M(2, 2) * pz;
205 double x = part.
getX() - euclid.
getX();
206 double y = part.
getY() - euclid.
getY();
208 euclid.
M(0, 0) * x + euclid.
M(1, 0) * y - euclid.
M(2, 0) * euclid.
getZ();
210 euclid.
M(0, 1) * x + euclid.
M(1, 1) * y - euclid.
M(2, 1) * euclid.
getZ();
212 euclid.
M(0, 2) * x + euclid.
M(1, 2) * y - euclid.
M(2, 2) * euclid.
getZ();
213 double sByPz = s2 / pz;
215 double E =
std::sqrt(pt * pt + kin * kin);
218 part.
setZ(part.
getZ() + pt * (refTime / E + sByPz));
227 int order = field.
order();
239 kx = kxt + field.
normal(order) / double(order);
240 ky = kyt - field.
skew(order) / double(order);
254 int order = field.
order();
260 Series ky = - field.
skew(order) / double(order);
263 Series kxt = x * kx - y * ky;
264 Series kyt = x * ky + y * kx;
266 kx = kxt + field.
normal(order) / double(order);
267 ky = kyt - field.
skew(order) / double(order);
270 Series As = x * kx - y * ky;
281 int order = field.
order();
292 for(
int i = order; --i >= 1;) {
293 Ae = Ae * x + field.
normal(i);
294 Ao = Ao * x - field.
skew(i);
300 Ae = + (Ae * hx1).integral(
X);
314 if(++k > order)
break;
318 Ao = Ao.derivative(0);
321 if(++k > order)
break;
333 int order = field.
order();
344 for(
int i = order; --i >= 1;) {
345 Ae = Ae * x + field.
normal(i);
346 Ao = Ao * x - field.
skew(i);
352 Ae = + (Ae * hx1).integral(
X);
366 if(++k > order)
break;
370 Ao = Ao.derivative(
X);
373 if(++k > order)
break;
A templated representation for vectors.
double normal(int) const
Get component.
Tps< T > sqrt(const Tps< T > &x)
Square root.
T evaluate(const FVector< T, N > &) const
Evaluate FTps at point.
double getPx() const
Get horizontal momentum (no dimension).
void push_back(OpalParticle const &p)
void setPy(double)
Set the vertical momentum.
double getX() const
Get displacement.
void setTruncOrder(int order)
Set truncation order.
int order() const
Return order.
void applyDrift(double length)
Apply a drift length.
FTps< double, 2 > buildSBendVectorPotential2D(const BMultipoleField &, double h)
Construct vector potential for a SBend.
Truncated power series in N variables of type T.
FTps< double, 2 > Series2
double getZ() const
Get displacement.
void addToBunch(const OpalParticle &)
Add particle to bunch.
bool isIdentity() const
Test for identity.
double skew(int) const
Get component.
double getY() const
Get displacement.
An abstract sequence of beam line components.
FTps< double, 6 > buildMultipoleVectorPotential(const BMultipoleField &)
Construct vector potential for a Multipole.
double getPy() const
Get vertical momentum (no dimension).
double getBeta() const
The relativistic beta per particle.
const PartBunchBase< double, 3 > * getBunch() const
Return the current bunch.
void setY(double)
Set the vertical displacement in m.
double M(int row, int col) const
Get component.
double getM() const
The constant mass per particle.
FTps< double, 2 > buildMultipoleVectorPotential2D(const BMultipoleField &)
Construct vector potential for a Multipole.
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
void setParticle(FVector< double, 6 > z, int ii)
void setX(double)
Set the horizontal position in m.
size_t getLocalNum() const
double getPz() const
Get relative momentum error (no dimension).
double getZ() const
Get longitudinal displacement c*t in m.
const PartData itsReference
The reference information.
void applyThinMultipole(const BMultipoleField &field, double factor)
void setPx(double)
Set the horizontal momentum.
void setZ(double)
Set longitudinal position in m.
Track particles or bunches.
FTps< double, 6 > buildSBendVectorPotential(const BMultipoleField &, double h)
Construct vector potential for a SBend.
const Vector_t & getP() const
Get momentum.
void applyThinSBend(const BMultipoleField &field, double scale, double h)
FTps derivative(int var) const
Partial derivative.
double getY() const
Get vertical displacement in m.
PartBunchBase< double, 3 > * itsBunch_m
The bunch of particles to be tracked.
Displacement and rotation in space.
int getMaxOrder() const
Get maximum order.
OpalParticle getParticle(int ii)
double getP() const
The constant reference momentum per particle.
Interface for a single beam element.
virtual void visitComponent(const Component &)
Store the bunch.
void applyTransform(const Euclid3D &, double refLength=0.0)
Apply a geometric transformation.
static FTps makeVariable(int var)
Make variable.
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
double getX() const
Get horizontal position in m.
The magnetic field of a multipole.
virtual void trackBunch(PartBunchBase< double, 3 > *bunch, const PartData &, bool revBeam, bool revTrack) const
Track particle bunch.