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