OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
AbstractMapper.cpp
Go to the documentation of this file.
1 // ------------------------------------------------------------------------
2 // $RCSfile: AbstractMapper.cpp,v $
3 // ------------------------------------------------------------------------
4 // $Revision: 1.1.1.1.2.3 $
5 // ------------------------------------------------------------------------
6 // Copyright: see Copyright.readme
7 // ------------------------------------------------------------------------
8 //
9 // Class: AbstractMapper
10 // This abstract visitor class defines part of the interface for building
11 // the transfer map for a beamline.
12 //
13 // ------------------------------------------------------------------------
14 // Class category: Algorithms
15 // ------------------------------------------------------------------------
16 //
17 // $Date: 2004/11/12 18:57:53 $
18 // $Author: adelmann $
19 //
20 // ------------------------------------------------------------------------
21 
23 #include "Fields/BMultipoleField.h"
24 #include "FixedAlgebra/FTps.h"
25 
27 
28 // namespace {
29 // void printSciForm(std::ostream &os, double num, int prec = 14, int fw = 22) {
30 // std::streamsize old_prec = os.precision(prec); // Save old,
31 // os.setf(std::ios::scientific, std::ios::floatfield); // and set new formats.
32 // os << std::setw(fw) << num; // Print number.
33 // os.precision(old_prec); // Restore old formats.
34 // os.setf(std::ios::fixed, std::ios::floatfield);
35 // }
36 // }
37 
38 // Class AbstractMapper
39 // ------------------------------------------------------------------------
40 
42  const PartData &reference,
43  bool backBeam, bool backTrack):
44  DefaultVisitor(beamline, backBeam, backTrack),
45  itsReference(reference)
46 {}
47 
48 
50 {}
51 
52 
55  int order = field.order();
56 
57  if(order > 0) {
58  static const Series x = Series::makeVariable(X);
59  static const Series y = Series::makeVariable(Y);
60  Series kx = + field.normal(order) / double(order);
61  Series ky = - field.skew(order) / double(order);
62 
63  while(order > 1) {
64  Series kxt = x * kx - y * ky;
65  Series kyt = x * ky + y * kx;
66  order--;
67  kx = kxt + field.normal(order) / double(order);
68  ky = kyt - field.skew(order) / double(order);
69  }
70 
71  Series As = x * kx - y * ky;
72  As.setTruncOrder(As.getMaxOrder());
73  return As;
74  } else {
75  return Series(0.0);
76  }
77 }
78 
80 buildSBendVectorPotential(const BMultipoleField &field, double h) {
81  //std::cerr << "==> In AbstractMapper::buildSBendVectorPotential(const BMultipoleField &field, double h)"
82  // << std::endl;
83  int order = field.order();
84  Series As;
85 
86  //std::cerr << " h = "; printSciForm(std::cerr,h);
87  //std::cerr << "\n" << order << std::endl;
88  //std::cerr << std::endl;
89  //for (int m = 1; m <= order; ++m) {
90  // std::cerr << " B(" << m << ") = "; printSciForm(std::cerr, field.normal(m));
91  // std::cerr << " A(" << m << ") = "; printSciForm(std::cerr, field.skew(m));
92  // std::cerr << std::endl;
93  //}
94 
95  if(order > 0) {
96  static const Series x = Series::makeVariable(X);
97  static const Series y = Series::makeVariable(Y);
98 
99  // Construct terms constant and linear in y.
100  Series Ae = + field.normal(order); // Term even in y.
101  Series Ao = - field.skew(order); // Term odd in y.
102 
103  for(int i = order; --i >= 1;) {
104  Ae = Ae * x + field.normal(i);
105  Ao = Ao * x - field.skew(i);
106  }
107  Ae.setTruncOrder(Ae.getMaxOrder());
108  Ao.setTruncOrder(Ao.getMaxOrder());
109 
110  Series hx1 = 1. + h * x; // normalized radius
111  Ae = + (Ae * hx1).integral(X);
112  Ao = - (Ao * hx1);
113  // Add terms up to maximum order.
114  As = Ae + y * Ao;
115 
116  int k = 2;
117  if(k <= order) {
118  Series yp = y * y / 2.0;
119 
120  while(true) {
121  // Terms even in y.
122  Ae = Ae.derivative(X);
123  Ae = h * Ae / hx1 - Ae.derivative(X);
124  As += Ae * yp;
125  if(++k > order) break;
126  yp *= y / double(k);
127 
128  // Terms odd in y.
129  Ao = Ao.derivative(X);
130  Ao = h * Ao / hx1 - Ao.derivative(X);
131  As += Ao * yp;
132  if(++k > order) break;
133  yp *= y / double(k);
134  }
135  }
136  }
137  //std::cerr << " As = " << As << std::endl;
138  //std::cerr << "==> Leaving AbstractMapper::buildSBendVectorPotential(...)" << std::endl;
139 
140  return As;
141 }
int getMaxOrder() const
Get maximum order.
Definition: FTps.h:174
double normal(int) const
Get component.
Particle reference data.
Definition: PartData.h:38
Default algorithms.
FTps< double, 6 > Series
Definition: LieMapper.cpp:60
virtual ~AbstractMapper()
double skew(int) const
Get component.
FTps< double, 6 > buildSBendVectorPotential(const BMultipoleField &, double h)
Construct the vector potential for an SBend.
An abstract sequence of beam line components.
Definition: Beamline.h:37
FTps derivative(int var) const
Partial derivative.
Definition: FTps.hpp:1396
The magnetic field of a multipole.
FTps< double, 6 > buildMultipoleVectorPotential(const BMultipoleField &)
Construct the vector potential for a Multipole.
void setTruncOrder(int order)
Set truncation order.
Definition: FTps.hpp:393
static FTps makeVariable(int var)
Make variable.
int order() const
Return order.