OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
Astra1DMagnetoStatic.cpp
Go to the documentation of this file.
2 #include "Fields/Fieldmap.hpp"
3 #include "Physics/Physics.h"
5 #include "Utilities/Util.h"
6 
7 #include "gsl/gsl_interp.h"
8 #include "gsl/gsl_spline.h"
9 #include "gsl/gsl_fft_real.h"
10 
11 #include <fstream>
12 #include <ios>
13 
14 using namespace std;
15 using Physics::mu_0;
16 using Physics::c;
17 using Physics::two_pi;
18 
20  : Fieldmap(aFilename),
21  FourCoefs_m(NULL) {
22  ifstream file;
23  int skippedValues = 0;
24  std::string tmpString;
25  double tmpDouble;
26  double tmpDouble2;
27 
29 
30  // open field map, parse it and disable element on error
31  file.open(Filename_m.c_str());
32  if(file.good()) {
33  bool parsing_passed = true;
34  try {
35  parsing_passed = interpreteLine<std::string, int>(file, tmpString, accuracy_m);
36  } catch (GeneralClassicException &e) {
37  parsing_passed = interpreteLine<std::string, int, std::string>(file, tmpString, accuracy_m, tmpString);
38 
39  tmpString = Util::toUpper(tmpString);
40  if (tmpString != "TRUE" &&
41  tmpString != "FALSE")
42  throw GeneralClassicException("Astra1DMagnetoStatic::Astra1DMagnetoStatic",
43  "The third string on the first line of 1D field "
44  "maps has to be either TRUE or FALSE");
45 
46  normalize_m = (tmpString == "TRUE");
47  }
48  parsing_passed = parsing_passed &&
49  interpreteLine<double, double>(file, zbegin_m, tmpDouble);
50 
51  tmpDouble2 = zbegin_m;
52  while(!file.eof() && parsing_passed) {
53  parsing_passed = interpreteLine<double, double>(file, zend_m, tmpDouble, false);
54  if(zend_m - tmpDouble2 > 1e-10) {
55  tmpDouble2 = zend_m;
56  } else if(parsing_passed) {
57  ++ skippedValues;
58  }
59  }
60 
61  file.close();
62  num_gridpz_m = lines_read_m - 2 - skippedValues;
63  lines_read_m = 0;
64 
65  if(!parsing_passed && !file.eof()) {
67  zend_m = zbegin_m - 1e-3;
68  throw GeneralClassicException("Astra1DMagnetoStatic::Astra1DMagnetoStatic",
69  "An error occured when reading the fieldmap '" + Filename_m + "'");
70  }
71  length_m = 2.0 * num_gridpz_m * (zend_m - zbegin_m) / (num_gridpz_m - 1);
72  } else {
74  zbegin_m = 0.0;
75  zend_m = -1e-3;
76  }
77 }
78 
80  freeMap();
81 }
82 
84  if(FourCoefs_m == NULL) {
85  // declare variables and allocate memory
86  ifstream in;
87 
88  bool parsing_passed = true;
89 
90  std::string tmpString;
91 
92  double Bz_max = 0.0;
93  double dz = (zend_m - zbegin_m) / (num_gridpz_m - 1);
94  double tmpDouble = zbegin_m - dz;
95 
96  double *RealValues = new double[2 * num_gridpz_m];
97  double *zvals = new double[num_gridpz_m];
98 
99  gsl_spline *Bz_interpolant = gsl_spline_alloc(gsl_interp_cspline, num_gridpz_m);
100  gsl_interp_accel *Bz_accel = gsl_interp_accel_alloc();
101 
102  gsl_fft_real_wavetable *real = gsl_fft_real_wavetable_alloc(2 * num_gridpz_m);
103  gsl_fft_real_workspace *work = gsl_fft_real_workspace_alloc(2 * num_gridpz_m);
104 
105  FourCoefs_m = new double[2 * accuracy_m - 1];
106 
107  // read in and parse field map
108  in.open(Filename_m.c_str());
109  getLine(in, tmpString);
110 
111  for(int i = 0; i < num_gridpz_m && parsing_passed;/* skip increment on i here */) {
112  parsing_passed = interpreteLine<double, double>(in, zvals[i], RealValues[i]);
113  // the sequence of z-position should be strictly increasing
114  // drop sampling points that don't comply to this
115  if(zvals[i] - tmpDouble > 1e-10) {
116  if(fabs(RealValues[i]) > Bz_max) {
117  Bz_max = fabs(RealValues[i]);
118  }
119  tmpDouble = zvals[i];
120  ++ i; // increment i only if sampling point is accepted
121  }
122  }
123  in.close();
124 
125  gsl_spline_init(Bz_interpolant, zvals, RealValues, num_gridpz_m);
126 
127  // get equidistant sampling from the, possibly, non-equidistant sampling
128  // using cubic spline for this
129  int ii = num_gridpz_m;
130  for(int i = 0; i < num_gridpz_m - 1; ++ i, ++ ii) {
131  double z = zbegin_m + dz * i;
132  RealValues[ii] = gsl_spline_eval(Bz_interpolant, z, Bz_accel);
133  }
134  RealValues[ii ++] = RealValues[num_gridpz_m - 1];
135  // prepend mirror sampling points such that field values are periodic for sure
136  -- ii; // ii == 2*num_gridpz_m at the moment
137  for(int i = 0; i < num_gridpz_m; ++ i, -- ii) {
138  RealValues[i] = RealValues[ii];
139  }
140 
141  gsl_fft_real_transform(RealValues, 1, 2 * num_gridpz_m, real, work);
142 
143  if (!normalize_m) {
144  Bz_max = 1.0;
145  }
146  // normalize to Bz_max = 1 A/m
147  FourCoefs_m[0] = RealValues[0] / (Bz_max * 2. * num_gridpz_m);
148  for(int i = 1; i < 2 * accuracy_m - 1; i++) {
149  FourCoefs_m[i] = RealValues[i] / (Bz_max * num_gridpz_m);
150  }
151 
152  gsl_spline_free(Bz_interpolant);
153  gsl_interp_accel_free(Bz_accel);
154 
155  gsl_fft_real_workspace_free(work);
156  gsl_fft_real_wavetable_free(real);
157 
158  delete[] zvals;
159  delete[] RealValues;
160 
161  INFOMSG(level3 << typeset_msg("read in fieldmap '" + Filename_m + "'", "info") << endl);
162  }
163 }
164 
166  if(FourCoefs_m != NULL) {
167 
168  delete[] FourCoefs_m;
169  FourCoefs_m = NULL;
170 
171  INFOMSG(level3 << typeset_msg("freed fieldmap '" + Filename_m + "'", "info") << endl);
172  }
173 }
174 
176  // do fourier interpolation in z-direction
177  const double RR2 = R(0) * R(0) + R(1) * R(1);
178 
179  const double kz = two_pi * R(2) / length_m + Physics::pi;
180 
181  double ez = FourCoefs_m[0];
182  double ezp = 0.0;
183  double ezpp = 0.0;
184  double ezppp = 0.0;
185  double somefactor_base, somefactor;
186  double coskzl;
187  double sinkzl;
188 
189  int n = 1;
190  for(int l = 1; l < accuracy_m ; l++, n += 2) {
191  somefactor_base = two_pi / length_m * l; // = \frac{d(kz*l)}{dz}
192  somefactor = 1.0;
193  coskzl = cos(kz * l);
194  sinkzl = sin(kz * l);
195  ez += (FourCoefs_m[n] * coskzl - FourCoefs_m[n + 1] * sinkzl);
196  somefactor *= somefactor_base;
197  ezp += somefactor * (-FourCoefs_m[n] * sinkzl - FourCoefs_m[n + 1] * coskzl);
198  somefactor *= somefactor_base;
199  ezpp += somefactor * (-FourCoefs_m[n] * coskzl + FourCoefs_m[n + 1] * sinkzl);
200  somefactor *= somefactor_base;
201  ezppp += somefactor * (FourCoefs_m[n] * sinkzl + FourCoefs_m[n + 1] * coskzl);
202  }
203  // expand the field off-axis
204  const double BfieldR = -ezp / 2. + ezppp / 16. * RR2;
205 
206  B(0) += BfieldR * R(0);
207  B(1) += BfieldR * R(1);
208  B(2) += ez - ezpp * RR2 / 4.;
209 
210  return false;
211 }
212 
214  return false;
215 }
216 
217 void Astra1DMagnetoStatic::getFieldDimensions(double &zBegin, double &zEnd, double &rBegin, double &rEnd) const {
218  zBegin = zbegin_m;
219  zEnd = zend_m;
220 }
221 void Astra1DMagnetoStatic::getFieldDimensions(double &xIni, double &xFinal, double &yIni, double &yFinal, double &zIni, double &zFinal) const {}
222 
224 { }
225 
227  (*msg) << Filename_m << " (1D magnetostatic); zini= " << zbegin_m << " m; zfinal= " << zend_m << " m;" << endl;
228 }
229 
231  return 0.0;
232 }
233 
235 { }
Astra1DMagnetoStatic(std::string aFilename)
constexpr double e
The value of .
Definition: Physics.h:40
virtual void getFieldDimensions(double &zBegin, double &zEnd, double &rBegin, double &rEnd) const
virtual double getFrequency() const
DiffDirection
Definition: Fieldmap.h:54
virtual bool getFieldDerivative(const Vector_t &R, Vector_t &E, Vector_t &B, const DiffDirection &dir) const
PETE_TUTree< FnFabs, typename T::PETE_Expr_t > fabs(const PETE_Expr< T > &l)
Definition: PETE.h:815
Tps< T > sin(const Tps< T > &x)
Sine.
Definition: TpsMath.h:111
virtual void getInfo(Inform *)
constexpr double two_pi
The value of .
Definition: Physics.h:34
std::string toUpper(const std::string &str)
Definition: Util.cpp:130
void disableFieldmapWarning()
Definition: Fieldmap.cpp:610
static std::string typeset_msg(const std::string &msg, const std::string &title)
Definition: Fieldmap.cpp:647
void noFieldmapWarning()
Definition: Fieldmap.cpp:618
bool normalize_m
Definition: Fieldmap.h:113
FLieGenerator< T, N > real(const FLieGenerator< std::complex< T >, N > &)
Take real part of a complex generator.
int lines_read_m
Definition: Fieldmap.h:111
virtual void setFrequency(double freq)
constexpr double pi
The value of .
Definition: Physics.h:31
constexpr double mu_0
The permeability of vacuum in Vs/Am.
Definition: Physics.h:55
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:52
#define INFOMSG(msg)
Definition: IpplInfo.h:397
Tps< T > cos(const Tps< T > &x)
Cosine.
Definition: TpsMath.h:129
void getLine(std::ifstream &in, std::string &buffer)
Definition: Fieldmap.h:198
std::string Filename_m
Definition: Fieldmap.h:110
MapType Type
Definition: Fieldmap.h:107
Inform & level3(Inform &inf)
Definition: Inform.cpp:47
Definition: Inform.h:41
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
virtual bool getFieldstrength(const Vector_t &R, Vector_t &E, Vector_t &B) const