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