OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
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 
15  : Fieldmap(aFilename),
16  FourCoefs_m(NULL) {
17 
18  std::ifstream file;
19  int skippedValues = 0;
20  std::string tmpString;
21  double tmpDouble;
22 
24 
25  // open field map, parse it and disable element on error
26  file.open(Filename_m.c_str());
27  if (file.good()) {
28  bool parsing_passed = true;
29  try {
30  parsing_passed = interpretLine<std::string, int>(file, tmpString, accuracy_m);
31  } catch (GeneralClassicException &e) {
32  parsing_passed = interpretLine<std::string, int, std::string>(file,
33  tmpString,
34  accuracy_m,
35  tmpString);
36 
37  tmpString = Util::toUpper(tmpString);
38  if (tmpString != "TRUE" &&
39  tmpString != "FALSE")
40  throw GeneralClassicException("Astra1DElectroStatic::Astra1DElectroStatic",
41  "The third string on the first line of 1D field "
42  "maps has to be either TRUE or FALSE");
43 
44  normalize_m = (tmpString == "TRUE");
45  }
46 
47  parsing_passed = parsing_passed &&
48  interpretLine<double, double>(file, zbegin_m, tmpDouble);
49 
50  double tmpDouble2 = zbegin_m;
51  while(!file.eof() && parsing_passed) {
52  parsing_passed = interpretLine<double, double>(file, zend_m, tmpDouble, false);
53  if (zend_m - tmpDouble2 > 1e-10) {
54  tmpDouble2 = zend_m;
55  } else if (parsing_passed) {
56  ++ skippedValues;
57  }
58  }
59 
60  num_gridpz_m = lines_read_m - 2 - skippedValues;
61  lines_read_m = 0;
62 
63  if (!parsing_passed && !file.eof()) {
65  zend_m = zbegin_m - 1e-3;
66  throw GeneralClassicException("Astra1DElectroStatic::Astra1DElectroStatic",
67  "An error occured when reading the fieldmap '" + Filename_m + "'");
68  }
69  length_m = 2.0 * num_gridpz_m * (zend_m - zbegin_m) / (num_gridpz_m - 1);
70  file.close();
71  } else {
73  zbegin_m = 0.0;
74  zend_m = -1e-3;
75  }
76 }
77 
79  freeMap();
80 }
81 
83  if (FourCoefs_m == NULL) {
84  // declare variables and allocate memory
85 
86  std::ifstream in;
87 
88  bool parsing_passed = true;
89 
90  std::string tmpString;
91 
92  double Ez_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 *Ez_interpolant = gsl_spline_alloc(gsl_interp_cspline, num_gridpz_m);
100  gsl_interp_accel *Ez_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 of i here */) {
112  parsing_passed = interpretLine<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 (std::abs(RealValues[i]) > Ez_max) {
117  Ez_max = std::abs(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(Ez_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(Ez_interpolant, z, Ez_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 
142  num_gridpz_m *= 2; // we doubled the sampling points
143 
144  gsl_fft_real_transform(RealValues, 1, num_gridpz_m, real, work);
145 
146  if (!normalize_m)
147  Ez_max = 1.0;
148 
149  // normalize to Ez_max = 1 MV/m
150  FourCoefs_m[0] = 1e6 * RealValues[0] / (Ez_max * num_gridpz_m); // factor 1e6 due to conversion MV/m to V/m
151  for (int i = 1; i < 2 * accuracy_m - 1; i++) {
152  FourCoefs_m[i] = 1e6 * 2.* RealValues[i] / (Ez_max * num_gridpz_m);
153  }
154 
155  gsl_fft_real_workspace_free(work);
156  gsl_fft_real_wavetable_free(real);
157 
158  gsl_spline_free(Ez_interpolant);
159  gsl_interp_accel_free(Ez_accel);
160 
161  delete[] zvals;
162  delete[] RealValues;
163 
164  INFOMSG(level3 << typeset_msg("read in fieldmap '" + Filename_m + "'", "info") << endl);
165 
166  }
167 }
168 
170  if (FourCoefs_m != NULL) {
171 
172  delete[] FourCoefs_m;
173  FourCoefs_m = NULL;
174 
175  INFOMSG(level3 << typeset_msg("freed fieldmap '" + Filename_m + "'", "info") << endl);
176  }
177 }
178 
180  // do fourier interpolation in z-direction
181  const double RR2 = R(0) * R(0) + R(1) * R(1);
182 
183  const double kz = Physics::two_pi * (R(2) - zbegin_m) / length_m + Physics::pi;
184 
185  double ez = FourCoefs_m[0];
186  double ezp = 0.0;
187  double ezpp = 0.0;
188  double ezppp = 0.0;
189 
190  int n = 1;
191  for (int l = 1; l < accuracy_m ; l++, n += 2) {
192  double somefactor_base = Physics::two_pi / length_m * l; // = \frac{d(kz*l)}{dz}
193  double somefactor = 1.0;
194  double coskzl = cos(kz * l);
195  double sinkzl = sin(kz * l);
196  ez += (FourCoefs_m[n] * coskzl - FourCoefs_m[n + 1] * sinkzl);
197  somefactor *= somefactor_base;
198  ezp += somefactor * (-FourCoefs_m[n] * sinkzl - FourCoefs_m[n + 1] * coskzl);
199  somefactor *= somefactor_base;
200  ezpp += somefactor * (-FourCoefs_m[n] * coskzl + FourCoefs_m[n + 1] * sinkzl);
201  somefactor *= somefactor_base;
202  ezppp += somefactor * (FourCoefs_m[n] * sinkzl + FourCoefs_m[n + 1] * coskzl);
203  }
204 
205  // expand the field to off-axis
206  const double EfieldR = -ezp / 2. + ezppp / 16. * RR2;
207 
208  E(0) += EfieldR * R(0);
209  E(1) += EfieldR * R(1);
210  E(2) += ez - ezpp * RR2 / 4.;
211  return false;
212 }
213 
214 bool Astra1DElectroStatic::getFieldDerivative(const Vector_t &/*R*/, Vector_t &/*E*/, Vector_t &/*B*/, const DiffDirection &/*dir*/) const {
215  return false;
216 }
217 
218 void Astra1DElectroStatic::getFieldDimensions(double &zBegin, double &zEnd) const {
219  zBegin = zbegin_m;
220  zEnd = zend_m;
221 }
222 
223 void Astra1DElectroStatic::getFieldDimensions(double &/*xIni*/, double &/*xFinal*/, double &/*yIni*/, double &/*yFinal*/, double &/*zIni*/, double &/*zFinal*/) const {}
224 
226 { }
227 
229  (*msg) << Filename_m << " (1D electrostatic); zini= " << zbegin_m << " m; zfinal= " << zend_m << " m;" << endl;
230 }
231 
233  return 0.0;
234 }
235 
237 { }
Tps< T > cos(const Tps< T > &x)
Cosine.
Definition: TpsMath.h:129
Tps< T > sin(const Tps< T > &x)
Sine.
Definition: TpsMath.h:111
@ TAstraElectroStatic
Definition: Fieldmap.h:19
DiffDirection
Definition: Fieldmap.h:54
FLieGenerator< T, N > real(const FLieGenerator< std::complex< T >, N > &)
Take real part of a complex generator.
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
Inform & level3(Inform &inf)
Definition: Inform.cpp:47
#define INFOMSG(msg)
Definition: IpplInfo.h:348
constexpr double two_pi
The value of.
Definition: Physics.h:33
constexpr double e
The value of.
Definition: Physics.h:39
constexpr double pi
The value of.
Definition: Physics.h:30
std::string toUpper(const std::string &str)
Definition: Util.cpp:132
virtual bool getFieldstrength(const Vector_t &R, Vector_t &E, Vector_t &B) const
virtual double getFrequency() const
Astra1DElectroStatic(std::string aFilename)
virtual void setFrequency(double freq)
virtual void getFieldDimensions(double &zBegin, double &zEnd) const
virtual bool getFieldDerivative(const Vector_t &R, Vector_t &E, Vector_t &B, const DiffDirection &dir) const
virtual void getInfo(Inform *)
MapType Type
Definition: Fieldmap.h:114
void disableFieldmapWarning()
Definition: Fieldmap.cpp:613
bool normalize_m
Definition: Fieldmap.h:120
int lines_read_m
Definition: Fieldmap.h:118
static std::string typeset_msg(const std::string &msg, const std::string &title)
Definition: Fieldmap.cpp:652
std::string Filename_m
Definition: Fieldmap.h:117
void getLine(std::ifstream &in, std::string &buffer)
Definition: Fieldmap.h:121
void noFieldmapWarning()
Definition: Fieldmap.cpp:621
Definition: Inform.h:42