OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
OPAL
FM1DMagnetoStatic_fast.cpp
Go to the documentation of this file.
2 #include "Fields/Fieldmap.hpp"
3 #include "Physics/Physics.h"
4 #include "Utilities/Util.h"
6 
7 #include "gsl/gsl_fft_real.h"
8 
9 #include <fstream>
10 #include <ios>
11 
13  Fieldmap(aFilename) {
14 
16  onAxisField_m = NULL;
17 
18  std::ifstream fieldFile(Filename_m.c_str());
19  if(fieldFile.good()) {
20 
21  bool parsingPassed = readFileHeader(fieldFile);
22  parsingPassed = checkFileData(fieldFile, parsingPassed);
23  fieldFile.close();
24 
25  if(!parsingPassed) {
27  zEnd_m = zBegin_m - 1.0e-3;
28  } else
30 
33 
34  } else {
36  zBegin_m = 0.0;
37  zEnd_m = -1.0e-3;
38  }
39 }
40 
42  freeMap();
43 }
44 
46 
47  if(onAxisField_m == NULL) {
48 
49  std::ifstream fieldFile(Filename_m.c_str());
50  stripFileHeader(fieldFile);
51 
52  onAxisField_m = new double[numberOfGridPoints_m];
53  double maxBz = readFileData(fieldFile, onAxisField_m);
54  fieldFile.close();
55 
56  std::vector<double> fourierCoefs
58  normalizeField(maxBz, fourierCoefs);
59 
60  double *onAxisFieldP = new double[numberOfGridPoints_m];
61  double *onAxisFieldPP = new double[numberOfGridPoints_m];
62  double *onAxisFieldPPP = new double[numberOfGridPoints_m];
63  computeFieldDerivatives(fourierCoefs, onAxisFieldP,
64  onAxisFieldPP, onAxisFieldPPP);
65  computeInterpolationVectors(onAxisFieldP, onAxisFieldPP,
66  onAxisFieldPPP);
67 
68  prepareForMapCheck(fourierCoefs);
69 
70  delete [] onAxisFieldP;
71  delete [] onAxisFieldPP;
72  delete [] onAxisFieldPPP;
73 
74  INFOMSG(level3 << typeset_msg("read in fieldmap '" + Filename_m + "'", "info")
75  << endl);
76  }
77 }
78 
80  if(onAxisField_m != NULL) {
81  delete [] onAxisField_m;
82  onAxisField_m = NULL;
83 
84  gsl_spline_free(onAxisFieldInterpolants_m);
85  gsl_spline_free(onAxisFieldPInterpolants_m);
86  gsl_spline_free(onAxisFieldPPInterpolants_m);
87  gsl_spline_free(onAxisFieldPPPInterpolants_m);
88  gsl_interp_accel_free(onAxisFieldAccel_m);
89  gsl_interp_accel_free(onAxisFieldPAccel_m);
90  gsl_interp_accel_free(onAxisFieldPPAccel_m);
91  gsl_interp_accel_free(onAxisFieldPPPAccel_m);
92 
93  INFOMSG(level3 << typeset_msg("freed fieldmap '" + Filename_m + "'", "info")
94  << endl);
95  }
96 }
97 
99  Vector_t &B) const {
100 
101  std::vector<double> fieldComponents;
102  computeFieldOnAxis(R(2) - zBegin_m, fieldComponents);
103  computeFieldOffAxis(R, E, B, fieldComponents);
104 
105  return false;
106 
107 }
108 
110  Vector_t &/*E*/,
111  Vector_t &B,
112  const DiffDirection &/*dir*/) const {
113 
114  B(2) += gsl_spline_eval(onAxisFieldPInterpolants_m, R(2) - zBegin_m,
116 
117  return false;
118 
119 }
120 
121 void FM1DMagnetoStatic_fast::getFieldDimensions(double &zBegin, double &zEnd) const {
122  zBegin = zBegin_m;
123  zEnd = zEnd_m;
124 }
125 
126 void FM1DMagnetoStatic_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 magnetostatic); zini= "
136  << zBegin_m << " m; zfinal= "
137  << zEnd_m << " m;" << endl;
138 }
139 
141  return 0.0;
142 }
143 
145 { }
146 
147 bool FM1DMagnetoStatic_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 FM1DMagnetoStatic_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  Vector_t &/*E*/,
196  Vector_t &B,
197  std::vector<double> fieldComponents) const {
198 
199  double radiusSq = pow(R(0), 2.0) + pow(R(1), 2.0);
200  double transverseBFactor = -fieldComponents.at(1) / 2.0
201  + radiusSq * fieldComponents.at(3) / 16.0;
202 
203  B(0) += R(0) * transverseBFactor;
204  B(1) += R(1) * transverseBFactor;
205  B(2) += fieldComponents.at(0) - fieldComponents.at(2) * radiusSq / 4.0;
206 
207 }
208 
210  std::vector<double> &fieldComponents) const {
211 
212  fieldComponents.push_back(gsl_spline_eval(onAxisFieldInterpolants_m,
213  z, onAxisFieldAccel_m));
214  fieldComponents.push_back(gsl_spline_eval(onAxisFieldPInterpolants_m,
215  z, onAxisFieldPAccel_m));
216  fieldComponents.push_back(gsl_spline_eval(onAxisFieldPPInterpolants_m,
218  fieldComponents.push_back(gsl_spline_eval(onAxisFieldPPPInterpolants_m,
220 }
221 
222 std::vector<double> FM1DMagnetoStatic_fast::computeFourierCoefficients(double fieldData[]) {
223 
224  const unsigned int totalSize = 2 * numberOfGridPoints_m - 1;
225  gsl_fft_real_wavetable *waveTable = gsl_fft_real_wavetable_alloc(totalSize);
226  gsl_fft_real_workspace *workSpace = gsl_fft_real_workspace_alloc(totalSize);
227 
228  // Reflect field about minimum z value to ensure that it is periodic.
229  double *fieldDataReflected = new double[totalSize];
230  for (unsigned int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++ dataIndex) {
231  fieldDataReflected[numberOfGridPoints_m - 1 + dataIndex]
232  = fieldData[dataIndex];
233  if(dataIndex != 0)
234  fieldDataReflected[numberOfGridPoints_m - 1 - dataIndex]
235  = fieldData[dataIndex];
236  }
237 
238  gsl_fft_real_transform(fieldDataReflected, 1, totalSize, waveTable, workSpace);
239 
240  std::vector<double> fourierCoefs;
241  fourierCoefs.push_back(fieldDataReflected[0] / totalSize);
242  for (unsigned int coefIndex = 1; coefIndex + 1 < 2 * accuracy_m; ++ coefIndex)
243  fourierCoefs.push_back(2.0 * fieldDataReflected[coefIndex] / totalSize);
244 
245  delete [] fieldDataReflected;
246  gsl_fft_real_workspace_free(workSpace);
247  gsl_fft_real_wavetable_free(waveTable);
248 
249  return fourierCoefs;
250 
251 }
252 
254  double onAxisFieldPP[],
255  double onAxisFieldPPP[]) {
256 
257  onAxisFieldInterpolants_m = gsl_spline_alloc(gsl_interp_cspline,
259  onAxisFieldPInterpolants_m = gsl_spline_alloc(gsl_interp_cspline,
261  onAxisFieldPPInterpolants_m = gsl_spline_alloc(gsl_interp_cspline,
263  onAxisFieldPPPInterpolants_m = gsl_spline_alloc(gsl_interp_cspline,
265 
266  double *z = new double[numberOfGridPoints_m];
267  for (unsigned int zStepIndex = 0; zStepIndex < numberOfGridPoints_m; ++ zStepIndex)
268  z[zStepIndex] = deltaZ_m * zStepIndex;
269 
270  gsl_spline_init(onAxisFieldInterpolants_m, z,
272  gsl_spline_init(onAxisFieldPInterpolants_m, z,
273  onAxisFieldP, numberOfGridPoints_m);
274  gsl_spline_init(onAxisFieldPPInterpolants_m, z,
275  onAxisFieldPP, numberOfGridPoints_m);
276  gsl_spline_init(onAxisFieldPPPInterpolants_m, z,
277  onAxisFieldPPP, numberOfGridPoints_m);
278 
279  onAxisFieldAccel_m = gsl_interp_accel_alloc();
280  onAxisFieldPAccel_m = gsl_interp_accel_alloc();
281  onAxisFieldPPAccel_m = gsl_interp_accel_alloc();
282  onAxisFieldPPPAccel_m = gsl_interp_accel_alloc();
283 
284  delete [] z;
285 }
286 
288 
289  // Convert to m.
290  rBegin_m /= 100.0;
291  rEnd_m /= 100.0;
292  zBegin_m /= 100.0;
293  zEnd_m /= 100.0;
294 }
295 
296 void FM1DMagnetoStatic_fast::normalizeField(double maxBz, std::vector<double> &fourierCoefs) {
297  if (!normalize_m) return;
298 
299  for (unsigned int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++ dataIndex)
300  onAxisField_m[dataIndex] /= maxBz;
301 
302  for (std::vector<double>::iterator fourierIterator = fourierCoefs.begin();
303  fourierIterator < fourierCoefs.end(); ++ fourierIterator)
304  *fourierIterator /= maxBz;
305 
306 }
307 
308 double FM1DMagnetoStatic_fast::readFileData(std::ifstream &fieldFile,
309  double fieldData[]) {
310 
311  double maxBz = 0.0;
312  for (unsigned int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++ dataIndex) {
313  interpretLine<double>(fieldFile, fieldData[dataIndex]);
314  if(std::abs(fieldData[dataIndex]) > maxBz)
315  maxBz = std::abs(fieldData[dataIndex]);
316  }
317 
318  return maxBz;
319 }
320 
321 bool FM1DMagnetoStatic_fast::readFileHeader(std::ifstream &fieldFile) {
322 
323  std::string tempString;
324  int tempInt;
325 
326  bool parsingPassed = true;
327 
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("FM1DMagnetoStatic_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 
348  parsingPassed = parsingPassed &&
349  interpretLine<double, double, unsigned int>(fieldFile,
350  zBegin_m,
351  zEnd_m,
353  parsingPassed = parsingPassed &&
354  interpretLine<double, double, int>(fieldFile,
355  rBegin_m,
356  rEnd_m,
357  tempInt);
358 
360 
363 
364  return parsingPassed;
365 }
366 
367 void FM1DMagnetoStatic_fast::stripFileHeader(std::ifstream &fieldFile) {
368 
369  std::string tempString;
370 
371  getLine(fieldFile, tempString);
372  getLine(fieldFile, tempString);
373  getLine(fieldFile, tempString);
374 }
375 
376 void FM1DMagnetoStatic_fast::prepareForMapCheck(std::vector<double> &fourierCoefs) {
377  std::vector<double> zSampling(numberOfGridPoints_m);
378  for (unsigned int zStepIndex = 0; zStepIndex < numberOfGridPoints_m; ++ zStepIndex)
379  zSampling[zStepIndex] = deltaZ_m * zStepIndex;
380 
382  length_m,
383  zSampling,
384  fourierCoefs,
387 }
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
@ T1DMagnetoStatic
Definition: Fieldmap.h:20
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::iterator iterator
Definition: MSLang.h:16
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
virtual double getFrequency() const
void computeFieldDerivatives(std::vector< double > fourierCoefs, double onAxisFieldP[], double onAxisFieldPP[], double onAxisFieldPPP[])
void computeInterpolationVectors(double onAxisFieldP[], double onAxisFieldPP[], double onAxisFieldPPP[])
gsl_interp_accel * onAxisFieldAccel_m
On axis field third derivative interpolation structure.
void stripFileHeader(std::ifstream &fieldFile)
std::vector< double > computeFourierCoefficients(double fieldData[])
virtual bool getFieldstrength(const Vector_t &R, Vector_t &E, Vector_t &B) const
bool readFileHeader(std::ifstream &fieldFile)
unsigned int accuracy_m
Field grid point spacing.
FM1DMagnetoStatic_fast(std::string aFilename)
void computeFieldOnAxis(double z, std::vector< double > &fieldComponents) const
gsl_spline * onAxisFieldPPInterpolants_m
On axis field first derivative interpolation structure.
gsl_spline * onAxisFieldPInterpolants_m
On axis field interpolation structure.
gsl_spline * onAxisFieldPPPInterpolants_m
On axis field second derivative interpolation structure.
unsigned int numberOfGridPoints_m
Field length.
double rEnd_m
Minimum radius of field.
void prepareForMapCheck(std::vector< double > &fourierCoefs)
virtual void getInfo(Inform *)
double deltaZ_m
Number of grid points in field input file.
void normalizeField(double maxBz, std::vector< double > &fourierCoefs)
double readFileData(std::ifstream &fieldFile, double fieldData[])
double zEnd_m
Longitudinal start of field.
gsl_interp_accel * onAxisFieldPAccel_m
void computeFieldOffAxis(const Vector_t &R, Vector_t &E, Vector_t &B, std::vector< double > fieldComponents) const
double length_m
Longitudinal end of field.
virtual void setFrequency(double freq)
bool checkFileData(std::ifstream &fieldFile, bool parsingPassed)
virtual void getFieldDimensions(double &zBegin, double &zEnd) const
gsl_interp_accel * onAxisFieldPPAccel_m
gsl_spline * onAxisFieldInterpolants_m
On axis field data.
gsl_interp_accel * onAxisFieldPPPAccel_m
double zBegin_m
Maximum radius of field.
virtual bool getFieldDerivative(const Vector_t &R, Vector_t &E, Vector_t &B, const DiffDirection &dir) const
Definition: Inform.h:42