OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
FM1DDynamic_fast.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_fft_real.h"
8 
9 #include <fstream>
10 #include <ios>
11 
12 FM1DDynamic_fast::FM1DDynamic_fast(std::string aFilename):
13  Fieldmap(aFilename),
14  accuracy_m(0)
15 {
16 
17  Type = T1DDynamic;
18  onAxisField_m = NULL;
19 
20  std::ifstream fieldFile(Filename_m.c_str());
21  if (fieldFile.good()) {
22 
23  bool parsingPassed = readFileHeader(fieldFile);
24  parsingPassed = checkFileData(fieldFile, parsingPassed);
25  fieldFile.close();
26 
27  if (!parsingPassed) {
29  zEnd_m = zBegin_m - 1.0e-3;
30  } else
32 
35 
36  } else {
38  zBegin_m = 0.0;
39  zEnd_m = -1.0e-3;
40  }
41 }
42 
44  freeMap();
45 }
46 
48 
49  if (onAxisField_m == NULL) {
50 
51  std::ifstream fieldFile(Filename_m.c_str());
52  stripFileHeader(fieldFile);
53 
54  onAxisField_m = new double[numberOfGridPoints_m];
55  double maxEz = readFileData(fieldFile, onAxisField_m);
56  fieldFile.close();
57 
58  std::vector<double> fourierCoefs = computeFourierCoefficients(onAxisField_m);
59  normalizeField(maxEz, fourierCoefs);
60 
61  double *onAxisFieldP = new double[numberOfGridPoints_m];
62  double *onAxisFieldPP = new double[numberOfGridPoints_m];
63  double *onAxisFieldPPP = new double[numberOfGridPoints_m];
64  computeFieldDerivatives(fourierCoefs, onAxisFieldP,
65  onAxisFieldPP, onAxisFieldPPP);
66  computeInterpolationVectors(onAxisFieldP, onAxisFieldPP,
67  onAxisFieldPPP);
68 
69  prepareForMapCheck(fourierCoefs);
70 
71  delete [] onAxisFieldP;
72  delete [] onAxisFieldPP;
73  delete [] onAxisFieldPPP;
74 
75  INFOMSG(typeset_msg("Read in fieldmap '" + Filename_m + "'", "info")
76  << endl);
77  }
78 }
79 
81  if (onAxisField_m != NULL) {
82  delete [] onAxisField_m;
83  onAxisField_m = NULL;
84 
85  gsl_spline_free(onAxisFieldInterpolants_m);
86  gsl_spline_free(onAxisFieldPInterpolants_m);
87  gsl_spline_free(onAxisFieldPPInterpolants_m);
88  gsl_spline_free(onAxisFieldPPPInterpolants_m);
89  gsl_interp_accel_free(onAxisFieldAccel_m);
90  gsl_interp_accel_free(onAxisFieldPAccel_m);
91  gsl_interp_accel_free(onAxisFieldPPAccel_m);
92  gsl_interp_accel_free(onAxisFieldPPPAccel_m);
93 
94  INFOMSG(level3 << typeset_msg("freed fieldmap '" + Filename_m + "'", "info")
95  << endl);
96  }
97 }
98 
100  Vector_t &B) const {
101 
102  std::vector<double> fieldComponents;
103  computeFieldOnAxis(R(2), fieldComponents);
104  computeFieldOffAxis(R, E, B, fieldComponents);
105 
106  return false;
107 }
108 
110  Vector_t &E,
111  Vector_t &B,
112  const DiffDirection &dir) const {
113 
114  E(2) += gsl_spline_eval(onAxisFieldPInterpolants_m, R(2),
116 
117  return false;
118 }
119 
120 void FM1DDynamic_fast::getFieldDimensions(double &zBegin, double &zEnd,
121  double &rBegin, double &rEnd) const {
122  zBegin = zBegin_m;
123  zEnd = zEnd_m;
124  rBegin = rBegin_m;
125  rEnd = rEnd_m;
126 }
127 
128 void FM1DDynamic_fast::getFieldDimensions(double &xIni, double &xFinal,
129  double &yIni, double &yFinal,
130  double &zIni, double &zFinal) const {}
131 
133 { }
134 
136  (*msg) << Filename_m
137  << " (1D dynamic); zini= "
138  << zBegin_m << " m; zfinal= "
139  << zEnd_m << " m;" << endl;
140 }
141 
143  return frequency_m;
144 }
145 
147  frequency_m = freq;
148 }
149 
150 void FM1DDynamic_fast::getOnaxisEz(std::vector<std::pair<double, double>> &eZ) {
151 
152  eZ.resize(numberOfGridPoints_m);
153  std::ifstream fieldFile(Filename_m.c_str());
154  stripFileHeader(fieldFile);
155  double maxEz = readFileData(fieldFile, eZ);
156  fieldFile.close();
157  scaleField(maxEz, eZ);
158 
159 }
160 
161 bool FM1DDynamic_fast::checkFileData(std::ifstream &fieldFile,
162  bool parsingPassed) {
163 
164  double tempDouble;
165  for (unsigned int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++ dataIndex)
166  parsingPassed = parsingPassed
167  && interpreteLine<double>(fieldFile, tempDouble);
168 
169  return parsingPassed && interpreteEOF(fieldFile);
170 
171 }
172 
173 void FM1DDynamic_fast::computeFieldDerivatives(std::vector<double> fourierCoefs,
174  double onAxisFieldP[],
175  double onAxisFieldPP[],
176  double onAxisFieldPPP[]) {
177 
178  for (unsigned int zStepIndex = 0; zStepIndex < numberOfGridPoints_m; ++ zStepIndex) {
179 
180  double z = deltaZ_m * zStepIndex;
181  double kz = Physics::two_pi * z / length_m + Physics::pi;
182  onAxisFieldP[zStepIndex] = 0.0;
183  onAxisFieldPP[zStepIndex] = 0.0;
184  onAxisFieldPPP[zStepIndex] = 0.0;
185 
186  int coefIndex = 1;
187  for (unsigned int n = 1; n < accuracy_m; ++ n) {
188 
189  double kn = n * Physics::two_pi / length_m;
190  double coskzn = cos(kz * n);
191  double sinkzn = sin(kz * n);
192 
193  onAxisFieldP[zStepIndex] += kn * (-fourierCoefs.at(coefIndex) * sinkzn
194  - fourierCoefs.at(coefIndex + 1) * coskzn);
195 
196  double derivCoeff = pow(kn, 2.0);
197  onAxisFieldPP[zStepIndex] += derivCoeff * (-fourierCoefs.at(coefIndex) * coskzn
198  + fourierCoefs.at(coefIndex + 1) * sinkzn);
199  derivCoeff *= kn;
200  onAxisFieldPPP[zStepIndex] += derivCoeff * (fourierCoefs.at(coefIndex) * sinkzn
201  + fourierCoefs.at(coefIndex + 1) * coskzn);
202 
203  coefIndex += 2;
204  }
205  }
206 
207 }
208 
210  Vector_t &E,
211  Vector_t &B,
212  std::vector<double> fieldComponents) const {
213 
214  double radiusSq = pow(R(0), 2.0) + pow(R(1), 2.0);
215  double transverseEFactor = (fieldComponents.at(1)
216  * (0.5 - radiusSq * twoPiOverLambdaSq_m / 16.0)
217  - radiusSq * fieldComponents.at(3) / 16.0);
218  double transverseBFactor = ((fieldComponents.at(0)
219  * (0.5 - radiusSq * twoPiOverLambdaSq_m / 16.0)
220  - radiusSq * fieldComponents.at(2) / 16.0)
222 
223  E(0) += - R(0) * transverseEFactor;
224  E(1) += - R(1) * transverseEFactor;
225  E(2) += (fieldComponents.at(0) * (1.0 - radiusSq * twoPiOverLambdaSq_m / 4.0)
226  - radiusSq * fieldComponents.at(2) / 4.0);
227 
228  B(0) += - R(1) * transverseBFactor;
229  B(1) += R(0) * transverseBFactor;
230 
231 }
232 
234  std::vector<double> &fieldComponents)
235  const {
236 
237  fieldComponents.push_back(gsl_spline_eval(onAxisFieldInterpolants_m,
238  z, onAxisFieldAccel_m));
239  fieldComponents.push_back(gsl_spline_eval(onAxisFieldPInterpolants_m,
240  z, onAxisFieldPAccel_m));
241  fieldComponents.push_back(gsl_spline_eval(onAxisFieldPPInterpolants_m,
243  fieldComponents.push_back(gsl_spline_eval(onAxisFieldPPPInterpolants_m,
245 }
246 
247 std::vector<double> FM1DDynamic_fast::computeFourierCoefficients(double fieldData[]) {
248  const unsigned int totalSize = 2 * numberOfGridPoints_m - 1;
249  gsl_fft_real_wavetable *waveTable = gsl_fft_real_wavetable_alloc(totalSize);
250  gsl_fft_real_workspace *workSpace = gsl_fft_real_workspace_alloc(totalSize);
251 
252  // Reflect field about minimum z value to ensure that it is periodic.
253  double *fieldDataReflected = new double[totalSize];
254  for (unsigned int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++ dataIndex) {
255  fieldDataReflected[numberOfGridPoints_m - 1 + dataIndex]
256  = fieldData[dataIndex];
257  if (dataIndex != 0)
258  fieldDataReflected[numberOfGridPoints_m - 1 - dataIndex]
259  = fieldData[dataIndex];
260  }
261 
262  gsl_fft_real_transform(fieldDataReflected, 1,
263  totalSize,
264  waveTable, workSpace);
265 
266  std::vector<double> fourierCoefs;
267  fourierCoefs.push_back(fieldDataReflected[0] / totalSize);
268  for (unsigned int coefIndex = 1; coefIndex < 2 * accuracy_m - 1; ++ coefIndex)
269  fourierCoefs.push_back(2.0 * fieldDataReflected[coefIndex] / totalSize);
270 
271  delete [] fieldDataReflected;
272  gsl_fft_real_workspace_free(workSpace);
273  gsl_fft_real_wavetable_free(waveTable);
274 
275  return fourierCoefs;
276 
277 }
278 
280  double onAxisFieldPP[],
281  double onAxisFieldPPP[]) {
282 
283  onAxisFieldInterpolants_m = gsl_spline_alloc(gsl_interp_cspline,
285  onAxisFieldPInterpolants_m = gsl_spline_alloc(gsl_interp_cspline,
287  onAxisFieldPPInterpolants_m = gsl_spline_alloc(gsl_interp_cspline,
289  onAxisFieldPPPInterpolants_m = gsl_spline_alloc(gsl_interp_cspline,
291 
292  double *z = new double[numberOfGridPoints_m];
293  for (unsigned int zStepIndex = 0; zStepIndex < numberOfGridPoints_m; ++ zStepIndex)
294  z[zStepIndex] = deltaZ_m * zStepIndex;
295  gsl_spline_init(onAxisFieldInterpolants_m, z,
296  onAxisField_m, numberOfGridPoints_m);
297  gsl_spline_init(onAxisFieldPInterpolants_m, z,
298  onAxisFieldP, numberOfGridPoints_m);
299  gsl_spline_init(onAxisFieldPPInterpolants_m, z,
300  onAxisFieldPP, numberOfGridPoints_m);
301  gsl_spline_init(onAxisFieldPPPInterpolants_m, z,
302  onAxisFieldPPP, numberOfGridPoints_m);
303 
304  onAxisFieldAccel_m = gsl_interp_accel_alloc();
305  onAxisFieldPAccel_m = gsl_interp_accel_alloc();
306  onAxisFieldPPAccel_m = gsl_interp_accel_alloc();
307  onAxisFieldPPPAccel_m = gsl_interp_accel_alloc();
308 
309  delete [] z;
310 }
311 
313 
314  // Convert to angular frequency in Hz.
315  frequency_m *= Physics::two_pi * 1.0e6;
316 
317  // Convert to m.
318  rBegin_m /= 100.0;
319  rEnd_m /= 100.0;
320  zBegin_m /= 100.0;
321  zEnd_m /= 100.0;
322 
324 }
325 
327  std::vector<double> &fourierCoefs) {
328 
329  for (unsigned int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++ dataIndex)
330  onAxisField_m[dataIndex] *= 1.0e6 / maxEz;
331 
332  for (std::vector<double>::iterator fourierIterator = fourierCoefs.begin();
333  fourierIterator < fourierCoefs.end(); ++ fourierIterator)
334  *fourierIterator *= 1.0e6 / maxEz;
335 
336 }
337 
338 double FM1DDynamic_fast::readFileData(std::ifstream &fieldFile,
339  double fieldData[]) {
340 
341  double maxEz = 0.0;
342  for (unsigned int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++ dataIndex) {
343  interpreteLine<double>(fieldFile, fieldData[dataIndex]);
344  if (std::abs(fieldData[dataIndex]) > maxEz)
345  maxEz = std::abs(fieldData[dataIndex]);
346  }
347 
348  if (!normalize_m)
349  maxEz = 1.0;
350 
351  return maxEz;
352 }
353 
354 double FM1DDynamic_fast::readFileData(std::ifstream &fieldFile,
355  std::vector<std::pair<double, double>> &eZ) {
356 
357  double maxEz = 0.0;
358  double deltaZ = (zEnd_m - zBegin_m) / (numberOfGridPoints_m - 1);
359  for (unsigned int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++ dataIndex) {
360  eZ.at(dataIndex).first = deltaZ * dataIndex;
361  interpreteLine<double>(fieldFile, eZ.at(dataIndex).second);
362  if (std::abs(eZ.at(dataIndex).second) > maxEz)
363  maxEz = std::abs(eZ.at(dataIndex).second);
364  }
365 
366  if (!normalize_m)
367  maxEz = 1.0;
368 
369  return maxEz;
370 }
371 
372 bool FM1DDynamic_fast::readFileHeader(std::ifstream &fieldFile) {
373 
374  std::string tempString;
375  int tempInt;
376 
377  bool parsingPassed = true;
378  try {
379  parsingPassed = interpreteLine<std::string, unsigned int>(fieldFile,
380  tempString,
381  accuracy_m);
382  } catch (GeneralClassicException &e) {
383  parsingPassed = interpreteLine<std::string, unsigned int, std::string>(fieldFile,
384  tempString,
385  accuracy_m,
386  tempString);
387 
388  tempString = Util::toUpper(tempString);
389  if (tempString != "TRUE" &&
390  tempString != "FALSE")
391  throw GeneralClassicException("FM1DDynamic_fast::readFileHeader",
392  "The third string on the first line of 1D field "
393  "maps has to be either TRUE or FALSE");
394 
395  normalize_m = (tempString == "TRUE");
396  }
397  parsingPassed = parsingPassed &&
398  interpreteLine<double, double, unsigned int>(fieldFile,
399  zBegin_m,
400  zEnd_m,
402  parsingPassed = parsingPassed &&
403  interpreteLine<double>(fieldFile, frequency_m);
404  parsingPassed = parsingPassed &&
405  interpreteLine<double, double, int>(fieldFile,
406  rBegin_m,
407  rEnd_m,
408  tempInt);
409 
411 
412  if (accuracy_m > numberOfGridPoints_m)
414 
415  return parsingPassed;
416 }
417 
419  std::vector<std::pair<double, double>> &eZ) {
420  if (!normalize_m) return;
421 
422  for (unsigned int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++ dataIndex)
423  eZ.at(dataIndex).second /= maxEz;
424 }
425 
426 void FM1DDynamic_fast::stripFileHeader(std::ifstream &fieldFile) {
427 
428  std::string tempString;
429 
430  getLine(fieldFile, tempString);
431  getLine(fieldFile, tempString);
432  getLine(fieldFile, tempString);
433  getLine(fieldFile, tempString);
434 }
435 
436 void FM1DDynamic_fast::prepareForMapCheck(std::vector<double> &fourierCoefs) {
437  std::vector<double> zSampling(numberOfGridPoints_m);
438  for (unsigned int zStepIndex = 0; zStepIndex < numberOfGridPoints_m; ++ zStepIndex)
439  zSampling[zStepIndex] = deltaZ_m * zStepIndex;
440 
442  length_m,
443  zSampling,
444  fourierCoefs,
447 }
gsl_interp_accel * onAxisFieldPPPAccel_m
virtual bool getFieldstrength(const Vector_t &R, Vector_t &E, Vector_t &B) const
virtual void getInfo(Inform *)
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 void swap()
virtual void setFrequency(double freq)
void stripFileHeader(std::ifstream &fieldFile)
double zBegin_m
Maximum radius of field.
DiffDirection
Definition: Fieldmap.h:54
Tps< T > sin(const Tps< T > &x)
Sine.
Definition: TpsMath.h:111
double readFileData(std::ifstream &fieldFile, double fieldData[])
constexpr double two_pi
The value of .
Definition: Physics.h:34
void prepareForMapCheck(std::vector< double > &fourierCoefs)
std::string toUpper(const std::string &str)
Definition: Util.cpp:130
void disableFieldmapWarning()
Definition: Fieldmap.cpp:610
FM1DDynamic_fast(std::string aFilename)
static std::string typeset_msg(const std::string &msg, const std::string &title)
Definition: Fieldmap.cpp:647
virtual void getOnaxisEz(std::vector< std::pair< double, double >> &eZ)
void noFieldmapWarning()
Definition: Fieldmap.cpp:618
double deltaZ_m
Number of grid points in field input file.
bool normalize_m
Definition: Fieldmap.h:113
void scaleField(double maxEz, std::vector< std::pair< double, double >> &eZ)
virtual bool getFieldDerivative(const Vector_t &R, Vector_t &E, Vector_t &B, const DiffDirection &dir) const
bool checkFileData(std::ifstream &fieldFile, bool parsingPassed)
constexpr double pi
The value of .
Definition: Physics.h:31
unsigned int accuracy_m
Field grid point spacing.
gsl_interp_accel * onAxisFieldAccel_m
On axis field third derivative interpolation structure.
unsigned int numberOfGridPoints_m
Field length.
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:52
bool interpreteEOF(std::ifstream &in)
Definition: Fieldmap.cpp:547
#define INFOMSG(msg)
Definition: IpplInfo.h:397
virtual void readMap()
double twoPiOverLambdaSq_m
Field angular frequency (Hz).
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
Definition: TpsMath.h:76
void computeInterpolationVectors(double onAxisFieldP[], double onAxisFieldPP[], double onAxisFieldPPP[])
double rBegin_m
2 Pi divided by the field RF wavelength squared.
double length_m
Longitudinal end of field.
virtual void freeMap()
void computeFieldOffAxis(const Vector_t &R, Vector_t &E, Vector_t &B, std::vector< double > fieldComponents) const
gsl_spline * onAxisFieldInterpolants_m
On axis field data.
Tps< T > cos(const Tps< T > &x)
Cosine.
Definition: TpsMath.h:129
double zEnd_m
Longitudinal start of field.
void getLine(std::ifstream &in, std::string &buffer)
Definition: Fieldmap.h:198
std::string Filename_m
Definition: Fieldmap.h:110
gsl_spline * onAxisFieldPPInterpolants_m
On axis field first derivative interpolation structure.
gsl_interp_accel * onAxisFieldPPAccel_m
gsl_spline * onAxisFieldPPPInterpolants_m
On axis field second derivative interpolation structure.
double rEnd_m
Minimum radius of field.
void computeFieldOnAxis(double z, std::vector< double > &fieldComponents) const
MapType Type
Definition: Fieldmap.h:107
gsl_interp_accel * onAxisFieldPAccel_m
Inform & level3(Inform &inf)
Definition: Inform.cpp:47
std::string::iterator iterator
Definition: MSLang.h:16
virtual double getFrequency() const
void checkMap(unsigned int accuracy, std::pair< double, double > fieldDimensions, double deltaZ, const std::vector< double > &fourierCoefficients, gsl_spline *splineCoefficients, gsl_interp_accel *splineAccelerator)
Definition: Fieldmap.cpp:443
gsl_spline * onAxisFieldPInterpolants_m
On axis field interpolation structure.
Definition: Inform.h:41
bool readFileHeader(std::ifstream &fieldFile)
std::vector< double > computeFourierCoefficients(double fieldData[])
void normalizeField(double maxEz, std::vector< double > &fourierCoefs)
void computeFieldDerivatives(std::vector< double > fourierCoefs, double onAxisFieldP[], double onAxisFieldPP[], double onAxisFieldPPP[])
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
virtual void getFieldDimensions(double &zBegin, double &zEnd, double &rBegin, double &rEnd) const