OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
FM1DMagnetoStatic.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 
16 
17  std::ifstream fieldFile(Filename_m.c_str());
18  if(fieldFile.good()) {
19 
20  bool parsingPassed = readFileHeader(fieldFile);
21  parsingPassed = checkFileData(fieldFile, parsingPassed);
22  fieldFile.close();
23 
24  if(!parsingPassed) {
26  zEnd_m = zBegin_m - 1.0e-3;
27  } else
29 
31  / (numberOfGridPoints_m - 1);
32  } else {
34  zBegin_m = 0.0;
35  zEnd_m = -1.0e-3;
36  }
37 }
38 
40  freeMap();
41 }
42 
44 
45  if(fourierCoefs_m.empty()) {
46 
47  std::ifstream fieldFile(Filename_m.c_str());
48  stripFileHeader(fieldFile);
49 
50  double *fieldData = new double[2 * numberOfGridPoints_m - 1];
51  double maxBz = readFileData(fieldFile, fieldData);
52  fieldFile.close();
53  computeFourierCoefficients(maxBz, fieldData);
54  delete [] fieldData;
55 
56  INFOMSG(level3 << typeset_msg("read in fieldmap '" + Filename_m + "'", "info")
57  << endl);
58  }
59 }
60 
62 
63  if(!fourierCoefs_m.empty()) {
64  fourierCoefs_m.clear();
65 
66  INFOMSG(level3 << typeset_msg("freed fieldmap '" + Filename_m + "'", "info")
67  << endl);
68  }
69 }
70 
72  Vector_t &B) const {
73 
74  std::vector<double> fieldComponents;
75  computeFieldOnAxis(R(2), fieldComponents);
76  computeFieldOffAxis(R, E, B, fieldComponents);
77 
78  return false;
79 }
80 
82  Vector_t &E,
83  Vector_t &B,
84  const DiffDirection &dir) const {
85 
86  double kz = Physics::two_pi * R(2) / length_m + Physics::pi;
87  double bZPrime = 0.0;
88 
89  int coefIndex = 1;
90  for(int n = 1; n < accuracy_m; n++) {
91 
92  bZPrime += n * Physics::two_pi / length_m
93  * (-fourierCoefs_m.at(coefIndex) * sin(kz * n)
94  - fourierCoefs_m.at(coefIndex + 1) * cos(kz * n));
95  coefIndex += 2;
96 
97  }
98 
99  B(2) += bZPrime;
100 
101  return false;
102 }
103 
104 void FM1DMagnetoStatic::getFieldDimensions(double &zBegin, double &zEnd,
105  double &rBegin, double &rEnd) const {
106  zBegin = zBegin_m;
107  zEnd = zEnd_m;
108  rBegin = rBegin_m;
109  rEnd = rEnd_m;
110 }
111 void FM1DMagnetoStatic::getFieldDimensions(double &xIni, double &xFinal,
112  double &yIni, double &yFinal,
113  double &zIni, double &zFinal) const {
114 }
115 
117 { }
118 
120  (*msg) << Filename_m
121  << " (1D magnetostatic); zini= "
122  << zBegin_m << " m; zfinal= "
123  << zEnd_m << " m;" << endl;
124 }
125 
127  return 0.0;
128 }
129 
131 { }
132 
133 bool FM1DMagnetoStatic::checkFileData(std::ifstream &fieldFile,
134  bool parsingPassed) {
135 
136  double tempDouble;
137  for(int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++ dataIndex)
138  parsingPassed = parsingPassed
139  && interpreteLine<double>(fieldFile, tempDouble);
140 
141  return parsingPassed && interpreteEOF(fieldFile);
142 
143 }
144 
146  Vector_t &E,
147  Vector_t &B,
148  std::vector<double> fieldComponents) const {
149 
150  double radiusSq = pow(R(0), 2.0) + pow(R(1), 2.0);
151  double transverseBFactor = -fieldComponents.at(1) / 2.0
152  + radiusSq * fieldComponents.at(3) / 16.0;
153 
154  B(0) += R(0) * transverseBFactor;
155  B(1) += R(1) * transverseBFactor;
156  B(2) += fieldComponents.at(0) - fieldComponents.at(2) * radiusSq / 4.0;
157 
158 }
159 
161  std::vector<double> &fieldComponents) const {
162 
163  double kz = Physics::two_pi * z / length_m + Physics::pi;
164  fieldComponents.push_back(fourierCoefs_m.at(0));
165  fieldComponents.push_back(0.0);
166  fieldComponents.push_back(0.0);
167  fieldComponents.push_back(0.0);
168 
169  int coefIndex = 1;
170  for(int n = 1; n < accuracy_m; n++) {
171 
172  double kn = n * Physics::two_pi / length_m;
173  double coskzn = cos(kz * n);
174  double sinkzn = sin(kz * n);
175 
176  fieldComponents.at(0) += fourierCoefs_m.at(coefIndex) * coskzn
177  - fourierCoefs_m.at(coefIndex + 1) * sinkzn;
178 
179  fieldComponents.at(1) += kn * (-fourierCoefs_m.at(coefIndex) * sinkzn
180  - fourierCoefs_m.at(coefIndex + 1) * coskzn);
181 
182  double derivCoeff = pow(kn, 2.0);
183  fieldComponents.at(2) += derivCoeff * (-fourierCoefs_m.at(coefIndex) * coskzn
184  + fourierCoefs_m.at(coefIndex + 1) * sinkzn);
185  derivCoeff *= kn;
186  fieldComponents.at(3) += derivCoeff * (fourierCoefs_m.at(coefIndex) * sinkzn
187  + fourierCoefs_m.at(coefIndex + 1) * coskzn);
188 
189  coefIndex += 2;
190  }
191 }
192 
194  double fieldData[]) {
195  const unsigned int totalSize = 2 * numberOfGridPoints_m - 1;
196  gsl_fft_real_wavetable *waveTable = gsl_fft_real_wavetable_alloc(totalSize);
197  gsl_fft_real_workspace *workSpace = gsl_fft_real_workspace_alloc(totalSize);
198 
199  gsl_fft_real_transform(fieldData, 1, totalSize, waveTable, workSpace);
200 
201  /*
202  * Normalize the Fourier coefficients such that the max field
203  * value is 1 V/m.
204  */
205 
206  fourierCoefs_m.push_back(fieldData[0] / (totalSize * maxBz));
207  for(int coefIndex = 1; coefIndex < 2 * accuracy_m - 1; coefIndex++)
208  fourierCoefs_m.push_back(2.0 * fieldData[coefIndex] / (totalSize * maxBz));
209 
210  gsl_fft_real_workspace_free(workSpace);
211  gsl_fft_real_wavetable_free(waveTable);
212 
213 }
214 
216 
217  // Convert to m.
218  rBegin_m /= 100.0;
219  rEnd_m /= 100.0;
220  zBegin_m /= 100.0;
221  zEnd_m /= 100.0;
222 }
223 
224 double FM1DMagnetoStatic::readFileData(std::ifstream &fieldFile,
225  double fieldData[]) {
226 
227  double maxBz = 0.0;
228  for(int dataIndex = 0; dataIndex < numberOfGridPoints_m; dataIndex++) {
229  interpreteLine<double>(fieldFile, fieldData[numberOfGridPoints_m
230  - 1 + dataIndex]);
231  if(std::abs(fieldData[numberOfGridPoints_m + dataIndex]) > maxBz)
232  maxBz = std::abs(fieldData[numberOfGridPoints_m + dataIndex]);
233 
234  /*
235  * Mirror the field map about minimum z value to ensure that
236  * it is periodic.
237  */
238  if(dataIndex != 0)
239  fieldData[numberOfGridPoints_m - 1 - dataIndex]
240  = fieldData[numberOfGridPoints_m + dataIndex];
241  }
242 
243  if (!normalize_m)
244  maxBz = 1.0;
245 
246  return maxBz;
247 }
248 
249 bool FM1DMagnetoStatic::readFileHeader(std::ifstream &fieldFile) {
250 
251  std::string tempString;
252  int tempInt;
253 
254  bool parsingPassed = true;
255  try {
256  parsingPassed = interpreteLine<std::string, int>(fieldFile,
257  tempString,
258  accuracy_m);
259  } catch (GeneralClassicException &e) {
260  parsingPassed = interpreteLine<std::string, int, std::string>(fieldFile,
261  tempString,
262  accuracy_m,
263  tempString);
264 
265  tempString = Util::toUpper(tempString);
266  if (tempString != "TRUE" &&
267  tempString != "FALSE")
268  throw GeneralClassicException("FM1DMagnetoStatic::readFileHeader",
269  "The third string on the first line of 1D field "
270  "maps has to be either TRUE or FALSE");
271 
272  normalize_m = (tempString == "TRUE");
273  }
274  parsingPassed = parsingPassed &&
275  interpreteLine<double, double, int>(fieldFile, zBegin_m,
276  zEnd_m,
278  parsingPassed = parsingPassed &&
279  interpreteLine<double, double, int>(fieldFile, rBegin_m,
280  rEnd_m, tempInt);
281 
283 
284  if(accuracy_m > numberOfGridPoints_m)
286 
287  return parsingPassed;
288 }
289 
290 void FM1DMagnetoStatic::stripFileHeader(std::ifstream &fieldFile) {
291 
292  std::string tempString;
293 
294  getLine(fieldFile, tempString);
295  getLine(fieldFile, tempString);
296  getLine(fieldFile, tempString);
297 }
virtual void getFieldDimensions(double &zBegin, double &zEnd, double &rBegin, double &rEnd) const
void computeFourierCoefficients(double maxEz, double fieldData[])
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
double readFileData(std::ifstream &fieldFile, double fieldData[])
constexpr double e
The value of .
Definition: Physics.h:40
bool readFileHeader(std::ifstream &fieldFile)
DiffDirection
Definition: Fieldmap.h:54
Tps< T > sin(const Tps< T > &x)
Sine.
Definition: TpsMath.h:111
constexpr double two_pi
The value of .
Definition: Physics.h:34
void stripFileHeader(std::ifstream &fieldFile)
double length_m
Longitudinal end of field.
FM1DMagnetoStatic(std::string aFilename)
std::string toUpper(const std::string &str)
Definition: Util.cpp:130
virtual bool getFieldDerivative(const Vector_t &R, Vector_t &E, Vector_t &B, const DiffDirection &dir) const
void disableFieldmapWarning()
Definition: Fieldmap.cpp:610
virtual void readMap()
int accuracy_m
Number of grid points in field input file.
virtual void freeMap()
bool checkFileData(std::ifstream &fieldFile, bool parsingPassed)
static std::string typeset_msg(const std::string &msg, const std::string &title)
Definition: Fieldmap.cpp:647
std::vector< double > fourierCoefs_m
Number of Fourier coefficients to use reconstructing field.
virtual bool getFieldstrength(const Vector_t &R, Vector_t &E, Vector_t &B) const
void noFieldmapWarning()
Definition: Fieldmap.cpp:618
bool normalize_m
Definition: Fieldmap.h:113
virtual double getFrequency() const
void computeFieldOffAxis(const Vector_t &R, Vector_t &E, Vector_t &B, std::vector< double > fieldComponents) const
double rEnd_m
Minimum radius of field.
virtual void setFrequency(double freq)
double zEnd_m
Longitudinal start of field.
constexpr double pi
The value of .
Definition: Physics.h:31
bool interpreteEOF(std::ifstream &in)
Definition: Fieldmap.cpp:547
#define INFOMSG(msg)
Definition: IpplInfo.h:397
double zBegin_m
Maximum radius of field.
int numberOfGridPoints_m
Field length.
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
Definition: TpsMath.h:76
virtual void getInfo(Inform *)
Tps< T > cos(const Tps< T > &x)
Cosine.
Definition: TpsMath.h:129
void getLine(std::ifstream &in, std::string &buffer)
Definition: Fieldmap.h:198
std::string Filename_m
Definition: Fieldmap.h:110
MapType Type
Definition: Fieldmap.h:107
Inform & level3(Inform &inf)
Definition: Inform.cpp:47
Definition: Inform.h:41
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
void computeFieldOnAxis(double z, std::vector< double > &fieldComponents) const