OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
OPAL
BMultipoleField.cpp
Go to the documentation of this file.
1 // ------------------------------------------------------------------------
2 // $RCSfile: BMultipoleField.cpp,v $
3 // ------------------------------------------------------------------------
4 // $Revision: 1.1.1.1 $
5 // ------------------------------------------------------------------------
6 // Copyright: see Copyright.readme
7 // ------------------------------------------------------------------------
8 //
9 // Class: BMultipoleField
10 // The static magnetic field of a multipole.
11 //
12 // ------------------------------------------------------------------------
13 // Class category: Fields
14 // ------------------------------------------------------------------------
15 //
16 // $Date: 2000/03/27 09:32:35 $
17 // $Author: fci $
18 //
19 // ------------------------------------------------------------------------
20 
21 #include "Fields/BMultipoleField.h"
22 #include "Utilities/LogicalError.h"
23 #include <complex>
24 
25 
26 // Class BMultipoleField::Pair, inline functions.
27 // ------------------------------------------------------------------------
28 // These functions are used only within member functions of BMultipoleField
29 // and can be safely inlined.
30 
32 { B = A = 0.0; }
33 
34 
35 inline BMultipoleField::Pair::Pair(double normal, double skewed)
36 { B = normal; A = skewed; }
37 
38 
40 { B = rhs.B; A = rhs.A; }
41 
42 
44 {}
45 
46 
47 inline void BMultipoleField::Pair::operator=(const Pair &rhs)
48 { B = rhs.B; A = rhs.A; }
49 
50 
53 { return Pair(B + rhs.B, A + rhs.A); }
54 
55 
58 { return Pair(B - rhs.B, A - rhs.A); }
59 
60 
63 { return Pair(B * scale, A * scale); }
64 
65 
66 inline void BMultipoleField::Pair::operator+=(const Pair &rhs)
67 { B += rhs.B; A += rhs.A; }
68 
69 
70 inline void BMultipoleField::Pair::operator-=(const Pair &rhs)
71 { B -= rhs.B; A -= rhs.A; }
72 
73 
75 { B *= scale; A *= scale; }
76 
77 
79 { return Pair(- B, - A); }
80 
81 
82 // Class BMultipoleField
83 // ------------------------------------------------------------------------
84 
86  pairs(NULL),
87  itsOrder(0)
88 {}
89 
90 
92  pairs(NULL),
93  itsOrder(rhs.itsOrder) {
94 
95  if (itsOrder > 0)
96  pairs = new Pair[itsOrder];
97 
98  for(int i = 0; i < itsOrder; i++) {
99  pairs[i] = rhs.pairs[i];
100  }
101 }
102 
103 
105  delete [] pairs;
106 }
107 
108 
110  if(&rhs != this) {
111  delete[] pairs;
112 
113  if (rhs.itsOrder > 0)
114  pairs = new Pair[rhs.itsOrder];
115  itsOrder = rhs.itsOrder;
116 
117  for(int i = 0; i < itsOrder; i++) {
118  pairs[i] = rhs.pairs[i];
119  }
120  }
121 
122  return *this;
123 }
124 
125 
127  std::complex<double> X(point.getX(), point.getY());
128  int i = itsOrder - 1;
129  std::complex<double> B(pairs[i].B, pairs[i].A);
130 
131  while(i-- >= 0) {
132  B = X * B / double(i + 1) + std::complex<double>(pairs[i].B, pairs[i].A);
133  }
134 
135  return BVector(std::imag(B), std::real(B), 0.0);
136 }
137 
138 
139 BVector BMultipoleField::Bfield(const Point3D &point, double) const {
140  return Bfield(point);
141 }
142 
143 
145  if(n <= 0) {
146  throw LogicalError("BMultipoleField::setNormalComponent()",
147  "Field order should be > 0.");
148  }
149 
150  if(n > itsOrder) reserve(n);
151  pairs[n-1].B = b;
152 }
153 
154 
156  if(n <= 0) {
157  throw LogicalError("BMultipoleField::setSkewComponent()",
158  "Field order should be > 0.");
159  }
160 
161  if(n > itsOrder) reserve(n);
162  pairs[n-1].A = a;
163 }
164 
165 
167  if(field.itsOrder > itsOrder) reserve(field.itsOrder);
168  for(int i = 0; i < field.itsOrder; ++i) pairs[i] += field.pairs[i];
169  return *this;
170 }
171 
172 
174  if(field.itsOrder > itsOrder) reserve(field.itsOrder);
175  for(int i = 0; i < field.itsOrder; ++i) pairs[i] -= field.pairs[i];
176  return *this;
177 }
178 
179 
180 void BMultipoleField::scale(double scalar) {
181  for(int i = 0; i < itsOrder; ++i) {
182  pairs[i] *= scalar;
183  }
184 }
185 
186 
188  if(n > itsOrder) {
189  Pair *temp = new Pair[n];
190  for(int i = 0; i < itsOrder; i++) temp[i] = pairs[i];
191  delete [] pairs;
192  itsOrder = n;
193  pairs = temp;
194  }
195 }
FLieGenerator< T, N > imag(const FLieGenerator< std::complex< T >, N > &)
Take imaginary part of a complex generator.
FLieGenerator< T, N > real(const FLieGenerator< std::complex< T >, N > &)
Take real part of a complex generator.
#define X(arg)
Definition: fftpack.cpp:112
std::complex< double > a
The magnetic field of a multipole.
BMultipoleField & addField(const BMultipoleField &field)
Add to field.
virtual BVector Bfield(const Point3D &P) const
Get field.
BMultipoleField & operator=(const BMultipoleField &)
BMultipoleField & subtractField(const BMultipoleField &field)
Subtract from field.
BMultipoleField()
Default constructor.
void scale(double scalar)
Scale the field.
virtual ~BMultipoleField()
void setNormalComponent(int n, double Bn)
Set component.
void setSkewComponent(int n, double Bn)
Set component.
double normal(int) const
Get component.
Pair operator+(const Pair &) const
void operator*=(double scale)
void operator-=(const Pair &)
void operator=(const Pair &)
void operator+=(const Pair &)
Pair operator*(double scale) const
A point in 3 dimensions.
Definition: EMField.h:33
double getX() const
Return coordinate.
Definition: EMField.cpp:34
double getY() const
Return coordinate.
Definition: EMField.cpp:37
A magnetic field vector.
Definition: EMField.h:97
Logical error exception.
Definition: LogicalError.h:33