OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
OPAL
FM1DElectroStatic_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 
13  Fieldmap(aFilename),
14  accuracy_m(0)
15 {
16 
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  if (onAxisField_m == NULL) {
49 
50  std::ifstream fieldFile(Filename_m.c_str());
51  stripFileHeader(fieldFile);
52 
53  onAxisField_m = new double[numberOfGridPoints_m];
54  double maxEz = readFileData(fieldFile, onAxisField_m);
55  fieldFile.close();
56 
57  std::vector<double> fourierCoefs
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(level3 << 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) - zBegin_m, fieldComponents);
104  computeFieldOffAxis(R, E, B, fieldComponents);
105 
106  return false;
107 
108 }
109 
111  Vector_t &E,
112  Vector_t &/*B*/,
113  const DiffDirection &/*dir*/) const {
114 
115  E(2) += gsl_spline_eval(onAxisFieldPInterpolants_m, R(2) - zBegin_m,
117 
118  return false;
119 
120 }
121 
122 void FM1DElectroStatic_fast::getFieldDimensions(double &zBegin, double &zEnd) const {
123  zBegin = zBegin_m;
124  zEnd = zEnd_m;
125 }
126 void FM1DElectroStatic_fast::getFieldDimensions(double &/*xIni*/, double &/*xFinal*/,
127  double &/*yIni*/, double &/*yFinal*/,
128  double &/*zIni*/, double &/*zFinal*/) const {}
129 
131 { }
132 
134  (*msg) << Filename_m
135  << " (1D electrotostatic); zini= "
136  << zBegin_m << " m; zfinal= "
137  << zEnd_m << " m;" << endl;
138 }
139 
141  return 0.0;
142 }
143 
145 { }
146 
147 bool FM1DElectroStatic_fast::checkFileData(std::ifstream &fieldFile,
148  bool parsingPassed) {
149 
150  double tempDouble;
151  for (unsigned int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++ dataIndex)
152  parsingPassed = parsingPassed
153  && interpretLine<double>(fieldFile, tempDouble);
154 
155  return parsingPassed && interpreteEOF(fieldFile);
156 
157 }
158 
159 void FM1DElectroStatic_fast::computeFieldDerivatives(std::vector<double> fourierCoefs,
160  double onAxisFieldP[],
161  double onAxisFieldPP[],
162  double onAxisFieldPPP[]) {
163 
164  for (unsigned int zStepIndex = 0; zStepIndex < numberOfGridPoints_m; ++ zStepIndex) {
165 
166  double z = deltaZ_m * zStepIndex;
167  double kz = Physics::two_pi * z / length_m + Physics::pi;
168  onAxisFieldP[zStepIndex] = 0.0;
169  onAxisFieldPP[zStepIndex] = 0.0;
170  onAxisFieldPPP[zStepIndex] = 0.0;
171 
172  int coefIndex = 1;
173  for (unsigned int n = 1; n < accuracy_m; ++ n) {
174 
175  double kn = n * Physics::two_pi / length_m;
176  double coskzn = cos(kz * n);
177  double sinkzn = sin(kz * n);
178 
179  onAxisFieldP[zStepIndex] += kn * (-fourierCoefs.at(coefIndex) * sinkzn
180  - fourierCoefs.at(coefIndex + 1) * coskzn);
181 
182  double derivCoeff = pow(kn, 2.0);
183  onAxisFieldPP[zStepIndex] += derivCoeff * (-fourierCoefs.at(coefIndex) * coskzn
184  + fourierCoefs.at(coefIndex + 1) * sinkzn);
185  derivCoeff *= kn;
186  onAxisFieldPPP[zStepIndex] += derivCoeff * (fourierCoefs.at(coefIndex) * sinkzn
187  + fourierCoefs.at(coefIndex + 1) * coskzn);
188 
189  coefIndex += 2;
190  }
191  }
192 }
193 
195  std::vector<double> fieldComponents) const {
196 
197  double radiusSq = pow(R(0), 2.0) + pow(R(1), 2.0);
198  double transverseEFactor = -fieldComponents.at(1) / 2.0
199  + radiusSq * fieldComponents.at(3) / 16.0;
200 
201  E(0) += R(0) * transverseEFactor;
202  E(1) += R(1) * transverseEFactor;
203  E(2) += fieldComponents.at(0) - fieldComponents.at(2) * radiusSq / 4.0;
204 
205 }
206 
208  std::vector<double> &fieldComponents) const {
209 
210  fieldComponents.push_back(gsl_spline_eval(onAxisFieldInterpolants_m,
211  z, onAxisFieldAccel_m));
212  fieldComponents.push_back(gsl_spline_eval(onAxisFieldPInterpolants_m,
213  z, onAxisFieldPAccel_m));
214  fieldComponents.push_back(gsl_spline_eval(onAxisFieldPPInterpolants_m,
216  fieldComponents.push_back(gsl_spline_eval(onAxisFieldPPPInterpolants_m,
218 }
219 
220 std::vector<double> FM1DElectroStatic_fast::computeFourierCoefficients(double fieldData[]) {
221 
222  const unsigned int totalSize = 2 * numberOfGridPoints_m - 1;
223  gsl_fft_real_wavetable *waveTable = gsl_fft_real_wavetable_alloc(totalSize);
224  gsl_fft_real_workspace *workSpace = gsl_fft_real_workspace_alloc(totalSize);
225 
226  // Reflect field about minimum z value to ensure that it is periodic.
227  double *fieldDataReflected = new double[totalSize];
228  for (unsigned int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++ dataIndex) {
229  fieldDataReflected[numberOfGridPoints_m - 1 + dataIndex] =
230  fieldData[dataIndex];
231  fieldDataReflected[numberOfGridPoints_m - 1 - dataIndex] =
232  fieldData[dataIndex];
233  }
234 
235  gsl_fft_real_transform(fieldDataReflected, 1,
236  totalSize,
237  waveTable, workSpace);
238 
239  std::vector<double> fourierCoefs;
240  fourierCoefs.push_back(fieldDataReflected[0] / totalSize);
241  for (unsigned int coefIndex = 1; coefIndex + 1 < 2 * accuracy_m; ++ coefIndex)
242  fourierCoefs.push_back(2.0 * fieldDataReflected[coefIndex] / totalSize);
243 
244  delete [] fieldDataReflected;
245  gsl_fft_real_workspace_free(workSpace);
246  gsl_fft_real_wavetable_free(waveTable);
247 
248  return fourierCoefs;
249 
250 }
251 
253  double onAxisFieldPP[],
254  double onAxisFieldPPP[]) {
255 
256  onAxisFieldInterpolants_m = gsl_spline_alloc(gsl_interp_cspline,
258  onAxisFieldPInterpolants_m = gsl_spline_alloc(gsl_interp_cspline,
260  onAxisFieldPPInterpolants_m = gsl_spline_alloc(gsl_interp_cspline,
262  onAxisFieldPPPInterpolants_m = gsl_spline_alloc(gsl_interp_cspline,
264 
265  double *z = new double[numberOfGridPoints_m];
266  for (unsigned int zStepIndex = 0; zStepIndex < numberOfGridPoints_m; ++ zStepIndex)
267  z[zStepIndex] = deltaZ_m * zStepIndex;
268 
269  gsl_spline_init(onAxisFieldInterpolants_m, z,
271  gsl_spline_init(onAxisFieldPInterpolants_m, z,
272  onAxisFieldP, numberOfGridPoints_m);
273  gsl_spline_init(onAxisFieldPPInterpolants_m, z,
274  onAxisFieldPP, numberOfGridPoints_m);
275  gsl_spline_init(onAxisFieldPPPInterpolants_m, z,
276  onAxisFieldPPP, numberOfGridPoints_m);
277 
278  onAxisFieldAccel_m = gsl_interp_accel_alloc();
279  onAxisFieldPAccel_m = gsl_interp_accel_alloc();
280  onAxisFieldPPAccel_m = gsl_interp_accel_alloc();
281  onAxisFieldPPPAccel_m = gsl_interp_accel_alloc();
282 
283  delete [] z;
284 }
285 
287 
288  // Convert to m.
289  rBegin_m /= 100.0;
290  rEnd_m /= 100.0;
291  zBegin_m /= 100.0;
292  zEnd_m /= 100.0;
293 
294 }
295 
296 void FM1DElectroStatic_fast::normalizeField(double maxEz, std::vector<double> &fourierCoefs) {
297 
298  for (unsigned int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++ dataIndex)
299  onAxisField_m[dataIndex] *= 1.0e6 / maxEz;
300 
301  for (auto fourierIt = fourierCoefs.begin(); fourierIt < fourierCoefs.end(); ++ fourierIt)
302  *fourierIt *= 1.0e6 / maxEz;
303 
304 }
305 
306 double FM1DElectroStatic_fast::readFileData(std::ifstream &fieldFile,
307  double fieldData[]) {
308 
309  double maxEz = 0.0;
310  for (unsigned int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++ dataIndex) {
311  interpretLine<double>(fieldFile, fieldData[dataIndex]);
312  if (std::abs(fieldData[dataIndex]) > maxEz)
313  maxEz = std::abs(fieldData[dataIndex]);
314  }
315 
316  if (!normalize_m)
317  maxEz = 1.0;
318 
319  return maxEz;
320 }
321 
322 bool FM1DElectroStatic_fast::readFileHeader(std::ifstream &fieldFile) {
323 
324  std::string tempString;
325  int tempInt;
326 
327  bool parsingPassed = true;
328  try {
329  parsingPassed = interpretLine<std::string, unsigned int>(fieldFile,
330  tempString,
331  accuracy_m);
332  } catch (GeneralClassicException &e) {
333  parsingPassed = interpretLine<std::string, unsigned int, std::string>(fieldFile,
334  tempString,
335  accuracy_m,
336  tempString);
337 
338  tempString = Util::toUpper(tempString);
339  if (tempString != "TRUE" &&
340  tempString != "FALSE")
341  throw GeneralClassicException("FM1DElectroStatic_fast::readFileHeader",
342  "The third string on the first line of 1D field "
343  "maps has to be either TRUE or FALSE");
344 
345  normalize_m = (tempString == "TRUE");
346  }
347  parsingPassed = parsingPassed &&
348  interpretLine<double, double, unsigned int>(fieldFile,
349  zBegin_m,
350  zEnd_m,
352  parsingPassed = parsingPassed &&
353  interpretLine<double, double, int>(fieldFile,
354  rBegin_m,
355  rEnd_m,
356  tempInt);
357 
361 
362  return parsingPassed;
363 }
364 
365 void FM1DElectroStatic_fast::stripFileHeader(std::ifstream &fieldFile) {
366 
367  std::string tempString;
368 
369  getLine(fieldFile, tempString);
370  getLine(fieldFile, tempString);
371  getLine(fieldFile, tempString);
372 }
373 
374 void FM1DElectroStatic_fast::prepareForMapCheck(std::vector<double> &fourierCoefs) {
375  std::vector<double> zSampling(numberOfGridPoints_m);
376  for (unsigned int zStepIndex = 0; zStepIndex < numberOfGridPoints_m; ++ zStepIndex)
377  zSampling[zStepIndex] = deltaZ_m * zStepIndex;
378 
380  length_m,
381  zSampling,
382  fourierCoefs,
385 }
Tps< T > cos(const Tps< T > &x)
Cosine.
Definition: TpsMath.h:129
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
Definition: TpsMath.h:76
Tps< T > sin(const Tps< T > &x)
Sine.
Definition: TpsMath.h:111
@ T1DElectroStatic
Definition: Fieldmap.h:18
DiffDirection
Definition: Fieldmap.h:54
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
MapType Type
Definition: Fieldmap.h:114
bool interpreteEOF(std::ifstream &in)
Definition: Fieldmap.cpp:558
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:451
void disableFieldmapWarning()
Definition: Fieldmap.cpp:613
bool normalize_m
Definition: Fieldmap.h:120
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
gsl_spline * onAxisFieldPInterpolants_m
On axis field interpolation structure.
std::vector< double > computeFourierCoefficients(double fieldData[])
void computeFieldDerivatives(std::vector< double > fourierCoefs, double onAxisFieldP[], double onAxisFieldPP[], double onAxisFieldPPP[])
void normalizeField(double maxEz, std::vector< double > &fourierCoefs)
virtual bool getFieldstrength(const Vector_t &R, Vector_t &E, Vector_t &B) const
gsl_interp_accel * onAxisFieldPAccel_m
void computeFieldOnAxis(double z, std::vector< double > &fieldComponents) const
void stripFileHeader(std::ifstream &fieldFile)
unsigned int numberOfGridPoints_m
Field length.
virtual void getInfo(Inform *)
unsigned int accuracy_m
Field grid point spacing.
FM1DElectroStatic_fast(std::string aFilename)
virtual void getFieldDimensions(double &zBegin, double &zEnd) const
double zEnd_m
Longitudinal start of field.
gsl_spline * onAxisFieldInterpolants_m
On axis field data.
virtual double getFrequency() const
double readFileData(std::ifstream &fieldFile, double fieldData[])
gsl_interp_accel * onAxisFieldPPPAccel_m
gsl_spline * onAxisFieldPPInterpolants_m
On axis field first derivative interpolation structure.
gsl_interp_accel * onAxisFieldAccel_m
On axis field third derivative interpolation structure.
double rEnd_m
Minimum radius of field.
virtual void setFrequency(double freq)
bool readFileHeader(std::ifstream &fieldFile)
double length_m
Longitudinal end of field.
double zBegin_m
Maximum radius of field.
void computeFieldOffAxis(const Vector_t &R, Vector_t &E, Vector_t &B, std::vector< double > fieldComponents) const
bool checkFileData(std::ifstream &fieldFile, bool parsingPassed)
double deltaZ_m
Number of grid points in field input file.
virtual bool getFieldDerivative(const Vector_t &R, Vector_t &E, Vector_t &B, const DiffDirection &dir) const
gsl_spline * onAxisFieldPPPInterpolants_m
On axis field second derivative interpolation structure.
void computeInterpolationVectors(double onAxisFieldP[], double onAxisFieldPP[], double onAxisFieldPPP[])
gsl_interp_accel * onAxisFieldPPAccel_m
void prepareForMapCheck(std::vector< double > &fourierCoefs)
Definition: Inform.h:42