46 bool backBeam,
bool backTrack):
48 itsBeamline_m(beamline),
63 bool backBeam,
bool backTrack):
65 itsBeamline_m(beamline),
140 double px = part.
px();
141 double py = part.
py();
142 double pt = part.
pt() + 1.0;
143 double lByPz = length /
sqrt(pt * pt - px * px - py * py);
144 part.
x() += px * lByPz;
145 part.
y() += py * lByPz;
146 part.
t() += pt * (refTime /
sqrt(pt * pt + kin * kin) - lByPz);
155 int order = field.
order();
158 for(
unsigned int i = 0; i < itsBunch_m->getLocalNum(); i++) {
163 double kx = + field.
normal(order);
164 double ky = - field.
skew(order);
168 double kxt = x * kx - y * ky;
169 double kyt = x * ky + y * kx;
170 kx = kxt + field.
normal(ord);
171 ky = kyt - field.
skew(ord);
173 part.
px() -= kx * scale;
174 part.
py() += ky * scale;
176 itsBunch_m->set_part(part, i);
184 Series2 As = buildSBendVectorPotential2D(field, h) * scale;
190 for(
unsigned int i = 0; i < itsBunch_m->getLocalNum(); i++) {
197 itsBunch_m->set_part(part, i);
209 double px = part.
px();
210 double py = part.
py();
211 double pt = part.
pt() + 1.0;
212 double pz =
sqrt(pt * pt - px * px - py * py);
214 part.
px() = euclid.
M(0, 0) * px + euclid.
M(1, 0) * py + euclid.
M(2, 0) * pz;
215 part.
py() = euclid.
M(0, 1) * px + euclid.
M(1, 1) * py + euclid.
M(2, 1) * pz;
216 pz = euclid.
M(0, 2) * px + euclid.
M(1, 2) * py + euclid.
M(2, 2) * pz;
218 double x = part.
x() - euclid.
getX();
219 double y = part.
y() - euclid.
getY();
221 euclid.
M(0, 0) * x + euclid.
M(1, 0) * y - euclid.
M(2, 0) * euclid.
getZ();
223 euclid.
M(0, 1) * x + euclid.
M(1, 1) * y - euclid.
M(2, 1) * euclid.
getZ();
225 euclid.
M(0, 2) * x + euclid.
M(1, 2) * y - euclid.
M(2, 2) * euclid.
getZ();
226 double sByPz = s2 / pz;
228 double E =
sqrt(pt * pt + kin * kin);
229 part.
x() = x2 - sByPz * part.
px();
230 part.
y() = y2 - sByPz * part.
py();
231 part.
t() += pt * (refTime / E + sByPz);
240 int order = field.
order();
252 kx = kxt + field.
normal(order) / double(order);
253 ky = kyt - field.
skew(order) / double(order);
267 int order = field.
order();
273 Series ky = - field.
skew(order) / double(order);
276 Series kxt = x * kx - y * ky;
277 Series kyt = x * ky + y * kx;
279 kx = kxt + field.
normal(order) / double(order);
280 ky = kyt - field.
skew(order) / double(order);
283 Series As = x * kx - y * ky;
294 int order = field.
order();
305 for(
int i = order; --i >= 1;) {
306 Ae = Ae * x + field.
normal(i);
307 Ao = Ao * x - field.
skew(i);
313 Ae = + (Ae * hx1).integral(
X);
327 if(++k > order)
break;
331 Ao = Ao.derivative(0);
334 if(++k > order)
break;
346 int order = field.
order();
357 for(
int i = order; --i >= 1;) {
358 Ae = Ae * x + field.
normal(i);
359 Ao = Ao * x - field.
skew(i);
365 Ae = + (Ae * hx1).integral(
X);
379 if(++k > order)
break;
383 Ao = Ao.derivative(
X);
386 if(++k > order)
break;
double & py()
Get reference to vertical momentum (no dimension).
virtual ElementBase * getElement() const
Return the contained element.
Euclid3D & offset() const
Return the offset.
double getX() const
Get displacement.
Track particles or bunches.
int getMaxOrder() const
Get maximum order.
double normal(int) const
Get component.
void addToBunch(const OpalParticle &)
Add particle to bunch.
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
double & x()
Get reference to horizontal position in m.
Define the position of a misaligned element.
double getZ() const
Get displacement.
FTps< double, 2 > buildSBendVectorPotential2D(const BMultipoleField &, double h)
Construct vector potential for a SBend.
virtual Euclid3D getEntranceTransform() const
Get entrance patch.
void applyDrift(double length)
Apply a drift length.
void push_back(OpalParticle p)
virtual void visitPatch(const Patch &pat)
Apply the algorithm to a patch.
double getBeta() const
The relativistic beta per particle.
double M(int row, int col) const
Get component.
Euclid3D Inverse(const Euclid3D &t)
Euclidean inverse.
FTps< double, 6 > buildMultipoleVectorPotential(const BMultipoleField &)
Construct vector potential for a Multipole.
FTps< double, 2 > buildMultipoleVectorPotential2D(const BMultipoleField &)
Construct vector potential for a Multipole.
virtual Euclid3D getExitTransform() const
Get exit patch.
virtual void visitAlignWrapper(const AlignWrapper &)
Apply the algorithm to an align wrapper.
double skew(int) const
Get component.
virtual void accept(BeamlineVisitor &visitor) const =0
Apply visitor.
OpalParticle get_part(int ii)
virtual void trackBunch(PartBunchBase< double, 3 > *bunch, const PartData &, bool revBeam, bool revTrack) const
Track particle bunch.
Displacement and rotation in space.
virtual void visitMapIntegrator(const MapIntegrator &)
Apply the algorithm to an integrator capable of mapping.
bool isIdentity() const
Test for identity.
virtual void trackBunch(PartBunchBase< double, 3 > *, const PartData &, bool revBeam, bool revTrack) const
Track a particle bunch.
An abstract sequence of beam line components.
const PartData itsReference
The reference information.
size_t getLocalNum() const
void set_part(FVector< double, 6 > z, int ii)
double & pt()
Get reference to relative momentum error (no dimension).
T evaluate(const FVector< T, N > &) const
Evaluate FTps at point.
Tps< T > sqrt(const Tps< T > &x)
Square root.
FTps derivative(int var) const
Partial derivative.
virtual void visitComponent(const Component &)
Store the bunch.
double getP() const
The constant reference momentum per particle.
virtual void visitTrackIntegrator(const TrackIntegrator &)
Apply the algorithm to an integrator capable of tracking.
The magnetic field of a multipole.
double getM() const
The constant mass per particle.
FTps< double, 2 > Series2
double & y()
Get reference to vertical displacement in m.
const PartBunchBase< double, 3 > * getBunch() const
Return the current bunch.
FTps< double, 6 > buildSBendVectorPotential(const BMultipoleField &, double h)
Construct vector potential for a SBend.
double & t()
Get reference to longitudinal displacement c*t in m.
void setTruncOrder(int order)
Set truncation order.
double & px()
Get reference to horizontal momentum (no dimension).
Truncated power series in N variables of type T.
Interface for a geometric patch.
Interface for a single beam element.
void applyThinSBend(const BMultipoleField &field, double scale, double h)
virtual const Euclid3D & getPatch() const =0
Get patch transform.
double getY() const
Get displacement.
PartBunchBase< double, 3 > * itsBunch_m
The bunch of particles to be tracked.
static FTps makeVariable(int var)
Make variable.
int order() const
Return order.
void applyThinMultipole(const BMultipoleField &field, double factor)
virtual void trackBunch(PartBunchBase< double, 3 > *, const PartData &, bool revBeam, bool revTrack) const =0
Track a particle bunch.
void applyTransform(const Euclid3D &, double refLength=0.0)
Apply a geometric transformation.