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