OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
rbendmap.h
Go to the documentation of this file.
2 
3 #include "FixedAlgebra/FTps.h"
4 #include "FixedAlgebra/FVps.h"
6 
7 
8 enum { X, PX, Y, PY, T, PT }; // !!!!! used by sbendmap.hh and quadmap.h
9 
11 
12 class RbendMap {
13 
14 
15 public:
16  RbendMap() { };
17 
18  FVps<double, 6> getBodyMap(const BMultipoleField &field, double length, double beta,
19  double scale, double p, double mass,
20  FVps<double, 6> map);
21 
22  Series_t getHamiltonian(const BMultipoleField &field, double beta,
23  double scale, double p, double mass);
24 
25  FVps<double, 6> getEntranceFringeMap(double angle, double curve,
26  const BMultipoleField &field,
27  double scale, FVps<double, 6> map);
28 
29  FVps<double, 6> getExitFringeMap(double angle, double curve,
30  const BMultipoleField &field,
31  double scale, FVps<double, 6> map);
32 
33  FVps<double, 6> getTransformMap(const Euclid3D &euclid, double refLength,
34  double beta, double scale, double p,
35  double mass, FVps<double, 6> map);
36 
40 
41 };
42 
44  const BMultipoleField &field,
45  double scale, FVps<double, 6> map) {
46  // *** MISSING *** Higher order terms for entrance fringe.
47  double hx = scale * field.normal(1);
48  double ex = hx * tan(angle);
49  double ey = hx * tan(angle + map[PX][0]);
50  map[PX] += ex * map[X];
51  map[PY] -= ey * map[Y];
52  return map;
53 }
54 
55 FVps<double, 6> RbendMap::getExitFringeMap(double angle, double curve,
56  const BMultipoleField &field,
57  double scale, FVps<double, 6> map) {
58  // *** MISSING *** Higher order terms for exit fringe.
59  double hx = scale * field.normal(1);
60  double ex = hx * tan(angle);
61  double ey = hx * tan(angle - map[PX][0]);
62  map[PX] += ex * map[X];
63  map[PY] -= ey * map[Y];
64  return map;
65 }
66 
67 FVps<double, 6> RbendMap::getBodyMap(const BMultipoleField &field, double length, double beta,
68  double scale, double p, double mass,
69  FVps<double, 6> map) {
70  // Build Hamiltonian in local coordinates; substitution done later.
71  // Step 1: Define variables.
75 
76  // Step 2: Kinematic terms.
78  Series_t pz = sqrt(pt * pt - px * px - py * py);
79  double kin = mass / p;
80  Series_t E = sqrt(pt * pt + kin * kin) / beta;
81 
82  // Step 3: Vector potential (1 + h*x) * As in curved reference.
83  Series_t As = getMultipoleMap(field) * scale;
84 
85  //cout << "As= " << As << endl;
86 
87  // Step 4: Finish Hamiltonian, substitute previous map,
88  // and apply result to the previous map.
89  Series_t H = As + E - pz;
90 
91  // cout << "H= " << H << endl;
92  map = ExpMap(- H * length).substitute(map);
93  return map;
94 }
95 
97  double scale, double p, double mass) {
98  // Build Hamiltonian in local coordinates; substitution done later.
99  // Step 1: Define variables.
102  Series_t pt = Series_t::makeVariable(PT) + 1.0;
103 
104  // Step 2: Kinematic terms.
106  Series_t pz = sqrt(pt * pt - px * px - py * py);
107  double kin = mass / p;
108  Series_t E = sqrt(pt * pt + kin * kin) / beta;
109 
110  // Step 3: Vector potential (1 + h*x) * As in curved reference.
111  Series_t As = getMultipoleMap(field) * scale;
112 
113  // Step 4: Finish Hamiltonian
114  Series_t H = As + E - pz;
115  return H;
116 }
117 
119  int order = field.order();
120 
121  if(order > 0) {
122  static const Series_t x = Series_t::makeVariable(X);
123  static const Series_t y = Series_t::makeVariable(Y);
124  Series_t kx = + field.normal(order) / double(order);
125  Series_t ky = - field.skew(order) / double(order);
126 
127  while(order > 1) {
128  Series_t kxt = x * kx - y * ky;
129  Series_t kyt = x * ky + y * kx;
130  order--;
131  kx = kxt + field.normal(order) / double(order);
132  ky = kyt - field.skew(order) / double(order);
133  }
134 
135  return (x * kx - y * ky);
136  } else {
137  return Series_t(0.0);
138  }
139 
140 
141 
142 }
143 
145  int order = field.order();
146 
147  if(order > 0) {
148  static const Series_t x = Series_t::makeVariable(X);
149  static const Series_t y = Series_t::makeVariable(Y);
150  Series_t kx = + field.normal(order) / double(order);
151  Series_t ky = - field.skew(order) / double(order);
152 
153  while(order > 1) {
154  Series_t kxt = x * kx - y * ky;
155  Series_t kyt = x * ky + y * kx;
156  order--;
157  kx = kxt + field.normal(order) / double(order);
158  ky = kyt - field.skew(order) / double(order);
159  }
160  m[PX] -= kx * scale;
161  m[PY] += ky * scale;
162  }
163  return m;
164 }
165 
166 
167 FVps<double, 6> RbendMap::getTransformMap(const Euclid3D &euclid, double refLength,
168  double beta, double scale, double p,
169  double mass, FVps<double, 6> map) {
170  if(! euclid.isIdentity()) {
171  double kin = mass / p;
172  double refTime = refLength / beta;
173  Series_t px = map[PX];
174  Series_t py = map[PY];
175  Series_t pt = map[PT] + 1.0;
176  Series_t pz = sqrt(pt * pt - px * px - py * py);
177 
178  map[PX] = euclid.M(0, 0) * px + euclid.M(1, 0) * py + euclid.M(2, 0) * pz;
179  map[PY] = euclid.M(0, 1) * px + euclid.M(1, 1) * py + euclid.M(2, 1) * pz;
180  pz = euclid.M(0, 2) * px + euclid.M(1, 2) * py + euclid.M(2, 2) * pz;
181 
182  Series_t x = map[X] - euclid.getX();
183  Series_t y = map[Y] - euclid.getY();
184  Series_t x2 =
185  euclid.M(0, 0) * x + euclid.M(1, 0) * y - euclid.M(2, 0) * euclid.getZ();
186  Series_t y2 =
187  euclid.M(0, 1) * x + euclid.M(1, 1) * y - euclid.M(2, 1) * euclid.getZ();
188  Series_t s2 =
189  euclid.M(0, 2) * x + euclid.M(1, 2) * y - euclid.M(2, 2) * euclid.getZ();
190  Series_t sByPz = s2 / pz;
191 
192  Series_t E = sqrt(pt * pt + kin * kin);
193  map[X] = x2 - sByPz * map[PX];
194  map[Y] = y2 - sByPz * map[PY];
195  map[T] += pt * (refTime / E + sByPz);
196  return map;
197  } else
198  return map;
199 }
Definition: rbendmap.h:8
double getX() const
Get displacement.
Definition: Euclid3D.h:216
double normal(int) const
Get component.
Definition: rbendmap.h:8
Definition: rbendmap.h:8
double getZ() const
Get displacement.
Definition: Euclid3D.h:224
Definition: rbendmap.h:8
Tps< T > tan(const Tps< T > &x)
Tangent.
Definition: TpsMath.h:147
double M(int row, int col) const
Get component.
Definition: Euclid3D.h:228
Series_t getHamiltonian(const BMultipoleField &field, double beta, double scale, double p, double mass)
Definition: rbendmap.h:96
RbendMap()
Definition: rbendmap.h:16
FVps< double, 6 > getTransformMap(const Euclid3D &euclid, double refLength, double beta, double scale, double p, double mass, FVps< double, 6 > map)
Definition: rbendmap.h:167
double skew(int) const
Get component.
Series_t getMultipoleMap(const BMultipoleField &)
Construct the vector potential for a Rbend.
Definition: rbendmap.h:118
Displacement and rotation in space.
Definition: Euclid3D.h:68
bool isIdentity() const
Test for identity.
Definition: Euclid3D.h:233
FVps< T, N > ExpMap(const FTps< T, N > &H, int trunc=FTps< T, N >::EXACT)
Build the exponential series.
Definition: FTps.hpp:1994
FVps< double, 6 > getBodyMap(const BMultipoleField &field, double length, double beta, double scale, double p, double mass, FVps< double, 6 > map)
Definition: rbendmap.h:67
FTps< double, 6 > Series_t
Definition: rbendmap.h:10
Tps< T > sqrt(const Tps< T > &x)
Square root.
Definition: TpsMath.h:91
The magnetic field of a multipole.
FVps< double, 6 > getThinMultipoleMap(const BMultipoleField &field, double scale, FVps< double, 6 > &m)
Definition: rbendmap.h:144
FVps< double, 6 > getExitFringeMap(double angle, double curve, const BMultipoleField &field, double scale, FVps< double, 6 > map)
Definition: rbendmap.h:55
Definition: rbendmap.h:8
double getY() const
Get displacement.
Definition: Euclid3D.h:220
static FTps makeVariable(int var)
Make variable.
int order() const
Return order.
Definition: rbendmap.h:8
FVps< double, 6 > getEntranceFringeMap(double angle, double curve, const BMultipoleField &field, double scale, FVps< double, 6 > map)
Definition: rbendmap.h:43