OPAL (Object Oriented Parallel Accelerator Library)  2024.1
OPAL
FM1DMagnetoStatic.cpp
Go to the documentation of this file.
2 #include "Fields/Fieldmap.hpp"
3 #include "Physics/Physics.h"
4 #include "Physics/Units.h"
6 #include "Utilities/Util.h"
7 
8 #include "gsl/gsl_fft_real.h"
9 
10 #include <fstream>
11 #include <ios>
12 
13 _FM1DMagnetoStatic::_FM1DMagnetoStatic(const std::string& filename)
14  : _Fieldmap(filename) {
15 
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 
32  / (numberOfGridPoints_m - 1);
33  } else {
35  zBegin_m = 0.0;
36  zEnd_m = -1.0e-3;
37  }
38 }
39 
41  freeMap();
42 }
43 
44 FM1DMagnetoStatic _FM1DMagnetoStatic::create(const std::string& filename)
45 {
46  return FM1DMagnetoStatic(new _FM1DMagnetoStatic(filename));
47 }
48 
50 
51  if(fourierCoefs_m.empty()) {
52 
53  std::ifstream fieldFile(Filename_m.c_str());
54  stripFileHeader(fieldFile);
55 
56  double *fieldData = new double[2 * numberOfGridPoints_m - 1];
57  double maxBz = readFileData(fieldFile, fieldData);
58  fieldFile.close();
59  computeFourierCoefficients(maxBz, fieldData);
60  delete [] fieldData;
61 
62  INFOMSG(level3 << typeset_msg("read in fieldmap '" + Filename_m + "'", "info")
63  << endl);
64  }
65 }
66 
68 
69  if(!fourierCoefs_m.empty()) {
70  fourierCoefs_m.clear();
71  }
72 }
73 
75  Vector_t &B) const {
76 
77  std::vector<double> fieldComponents;
78  computeFieldOnAxis(R(2) - zBegin_m, fieldComponents);
79  computeFieldOffAxis(R, E, B, fieldComponents);
80 
81  return false;
82 }
83 
85  Vector_t &/*E*/,
86  Vector_t &B,
87  const DiffDirection &/*dir*/) const {
88 
89  double kz = Physics::two_pi * (R(2) - zBegin_m) / length_m + Physics::pi;
90  double bZPrime = 0.0;
91 
92  int coefIndex = 1;
93  for(int n = 1; n < accuracy_m; n++) {
94 
95  bZPrime += n * Physics::two_pi / length_m
96  * (-fourierCoefs_m.at(coefIndex) * sin(kz * n)
97  - fourierCoefs_m.at(coefIndex + 1) * cos(kz * n));
98  coefIndex += 2;
99 
100  }
101 
102  B(2) += bZPrime;
103 
104  return false;
105 }
106 
107 void _FM1DMagnetoStatic::getFieldDimensions(double &zBegin, double &zEnd) const {
108  zBegin = zBegin_m;
109  zEnd = zEnd_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 
130 void _FM1DMagnetoStatic::setFrequency(double /*freq*/)
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  && interpretLine<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.
219  rEnd_m *= Units::cm2m;
221  zEnd_m *= Units::cm2m;
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  interpretLine<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 = interpretLine<std::string, int>(fieldFile,
257  tempString,
258  accuracy_m);
259  } catch (GeneralClassicException &e) {
260  parsingPassed = interpretLine<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  interpretLine<double, double, int>(fieldFile, zBegin_m,
276  zEnd_m,
278  parsingPassed = parsingPassed &&
279  interpretLine<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 }
MapType Type
Definition: Fieldmap.h:115
DiffDirection
Definition: Fieldmap.h:55
constexpr double two_pi
The value of .
Definition: Physics.h:33
void noFieldmapWarning()
Definition: Fieldmap.cpp:618
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
virtual bool getFieldDerivative(const Vector_t &R, Vector_t &E, Vector_t &B, const DiffDirection &dir) const
std::vector< double > fourierCoefs_m
Number of Fourier coefficients to use reconstructing field.
void computeFourierCoefficients(double maxEz, double fieldData[])
virtual void freeMap()
constexpr double cm2m
Definition: Units.h:35
virtual void readMap()
static std::string typeset_msg(const std::string &msg, const std::string &title)
Definition: Fieldmap.cpp:649
bool checkFileData(std::ifstream &fieldFile, bool parsingPassed)
constexpr double pi
The value of .
Definition: Physics.h:30
std::string toUpper(const std::string &str)
Definition: Util.cpp:147
#define INFOMSG(msg)
Definition: IpplInfo.h:348
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
bool interpreteEOF(std::ifstream &in)
Definition: Fieldmap.cpp:555
void computeFieldOnAxis(double z, std::vector< double > &fieldComponents) const
void stripFileHeader(std::ifstream &fieldFile)
bool normalize_m
Definition: Fieldmap.h:121
Definition: Inform.h:42
virtual double getFrequency() const
std::shared_ptr< _FM1DMagnetoStatic > FM1DMagnetoStatic
Definition: Definitions.h:39
virtual void setFrequency(double freq)
virtual void getInfo(Inform *)
void disableFieldmapWarning()
Definition: Fieldmap.cpp:610
double rEnd_m
Minimum radius of field.
double readFileData(std::ifstream &fieldFile, double fieldData[])
Tps< T > cos(const Tps< T > &x)
Cosine.
Definition: TpsMath.h:129
_FM1DMagnetoStatic(const std::string &filename)
int accuracy_m
Number of grid points in field input file.
void getLine(std::ifstream &in, std::string &buffer)
Definition: Fieldmap.h:122
double length_m
Longitudinal end of field.
Inform & level3(Inform &inf)
Definition: Inform.cpp:47
bool readFileHeader(std::ifstream &fieldFile)
constexpr double e
The value of .
Definition: Physics.h:39
double zEnd_m
Longitudinal start of field.
int numberOfGridPoints_m
Field length.
std::string Filename_m
Definition: Fieldmap.h:118
void computeFieldOffAxis(const Vector_t &R, Vector_t &E, Vector_t &B, std::vector< double > fieldComponents) const
virtual void getFieldDimensions(double &zBegin, double &zEnd) const
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
virtual bool getFieldstrength(const Vector_t &R, Vector_t &E, Vector_t &B) const
double zBegin_m
Maximum radius of field.
static FM1DMagnetoStatic create(const std::string &filename)