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