OPAL (Object Oriented Parallel Accelerator Library)  2024.1
OPAL
FM1DElectroStatic.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 _FM1DElectroStatic::_FM1DElectroStatic(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 FM1DElectroStatic _FM1DElectroStatic::create(const std::string& filename)
45 {
46  return FM1DElectroStatic(new _FM1DElectroStatic(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 maxEz = readFileData(fieldFile, fieldData);
58  fieldFile.close();
59  computeFourierCoefficients(maxEz, 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 eZPrime = 0.0;
91 
92  int coefIndex = 1;
93  for (int n = 1; n < accuracy_m; ++ n) {
94 
95  eZPrime += 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  E(2) += eZPrime;
103 
104  return false;
105 }
106 
107 void _FM1DElectroStatic::getFieldDimensions(double &zBegin, double &zEnd) const {
108  zBegin = zBegin_m;
109  zEnd = zEnd_m;
110 }
111 void _FM1DElectroStatic::getFieldDimensions(double &/*xIni*/, double &/*xFinal*/,
112  double &/*yIni*/, double &/*yFinal*/,
113  double &/*zIni*/, double &/*zFinal*/) const {}
114 
116 { }
117 
119  (*msg) << Filename_m
120  << " (1D electrostatic); zini= "
121  << zBegin_m << " m; zfinal= "
122  << zEnd_m << " m;" << endl;
123 }
124 
126  return 0.0;
127 }
128 
129 void _FM1DElectroStatic::setFrequency(double /*freq*/)
130 { }
131 
132 bool _FM1DElectroStatic::checkFileData(std::ifstream &fieldFile,
133  bool parsingPassed) {
134 
135  double tempDouble;
136  for (int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++ dataIndex)
137  parsingPassed = parsingPassed
138  && interpretLine<double>(fieldFile, tempDouble);
139 
140  return parsingPassed && interpreteEOF(fieldFile);
141 
142 }
143 
145  Vector_t &E,
146  Vector_t &/*B*/,
147  std::vector<double> fieldComponents) const {
148 
149  double radiusSq = pow(R(0), 2.0) + pow(R(1), 2.0);
150  double transverseEFactor = -fieldComponents.at(1) / 2.0
151  + radiusSq * fieldComponents.at(3) / 16.0;
152 
153  E(0) += R(0) * transverseEFactor;
154  E(1) += R(1) * transverseEFactor;
155  E(2) += fieldComponents.at(0) - fieldComponents.at(2) * radiusSq / 4.0;
156 
157 }
158 
160  std::vector<double> &fieldComponents) const {
161 
162  double kz = Physics::two_pi * z / length_m + Physics::pi;
163  fieldComponents.push_back(fourierCoefs_m.at(0));
164  fieldComponents.push_back(0.0);
165  fieldComponents.push_back(0.0);
166  fieldComponents.push_back(0.0);
167 
168  int coefIndex = 1;
169  for (int n = 1; n < accuracy_m; ++ n) {
170 
171  double kn = n * Physics::two_pi / length_m;
172  double coskzn = cos(kz * n);
173  double sinkzn = sin(kz * n);
174 
175  fieldComponents.at(0) += fourierCoefs_m.at(coefIndex) * coskzn
176  - fourierCoefs_m.at(coefIndex + 1) * sinkzn;
177 
178  fieldComponents.at(1) += kn * (-fourierCoefs_m.at(coefIndex) * sinkzn
179  - fourierCoefs_m.at(coefIndex + 1) * coskzn);
180 
181  double derivCoeff = pow(kn, 2.0);
182  fieldComponents.at(2) += derivCoeff * (-fourierCoefs_m.at(coefIndex) * coskzn
183  + fourierCoefs_m.at(coefIndex + 1) * sinkzn);
184  derivCoeff *= kn;
185  fieldComponents.at(3) += derivCoeff * (fourierCoefs_m.at(coefIndex) * sinkzn
186  + fourierCoefs_m.at(coefIndex + 1) * coskzn);
187 
188  coefIndex += 2;
189  }
190 }
191 
193  double fieldData[]) {
194  const unsigned int totalSize = 2 * numberOfGridPoints_m - 1;
195  gsl_fft_real_wavetable *waveTable = gsl_fft_real_wavetable_alloc(totalSize);
196  gsl_fft_real_workspace *workSpace = gsl_fft_real_workspace_alloc(totalSize);
197 
198  gsl_fft_real_transform(fieldData, 1, totalSize, waveTable, workSpace);
199 
200  /*
201  * Normalize the Fourier coefficients such that the max field
202  * value is 1 V/m.
203  */
204 
205  fourierCoefs_m.push_back(fieldData[0] / (totalSize * maxEz * Units::Vpm2MVpm));
206  for (int coefIndex = 1; coefIndex < 2 * accuracy_m - 1; ++ coefIndex)
207  fourierCoefs_m.push_back(2.0 * fieldData[coefIndex] / (totalSize * maxEz * Units::Vpm2MVpm));
208 
209  gsl_fft_real_workspace_free(workSpace);
210  gsl_fft_real_wavetable_free(waveTable);
211 
212 }
213 
215 
216  // Convert to m.
218  rEnd_m *= Units::cm2m;
220  zEnd_m *= Units::cm2m;
221 }
222 
223 double _FM1DElectroStatic::readFileData(std::ifstream &fieldFile,
224  double fieldData[]) {
225 
226  double maxEz = 0.0;
227  for (int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++ dataIndex) {
228  interpretLine<double>(fieldFile,
229  fieldData[numberOfGridPoints_m - 1 + dataIndex]);
230  if (std::abs(fieldData[numberOfGridPoints_m + dataIndex]) > maxEz)
231  maxEz = std::abs(fieldData[numberOfGridPoints_m + dataIndex]);
232 
233  /*
234  * Mirror the field map about minimum z value to ensure that
235  * it is periodic.
236  */
237  if (dataIndex != 0)
238  fieldData[numberOfGridPoints_m - 1 - dataIndex]
239  = fieldData[numberOfGridPoints_m + dataIndex];
240  }
241 
242  if (!normalize_m)
243  maxEz = 1.0;
244 
245  return maxEz;
246 }
247 
248 bool _FM1DElectroStatic::readFileHeader(std::ifstream &fieldFile) {
249 
250  std::string tempString;
251  int tempInt;
252 
253  bool parsingPassed = true;
254  try {
255  parsingPassed = interpretLine<std::string, int>(fieldFile,
256  tempString,
257  accuracy_m);
258  } catch (GeneralClassicException &e) {
259  parsingPassed = interpretLine<std::string, int, std::string>(fieldFile,
260  tempString,
261  accuracy_m,
262  tempString);
263 
264  tempString = Util::toUpper(tempString);
265  if (tempString != "TRUE" &&
266  tempString != "FALSE")
267  throw GeneralClassicException("_FM1DElectroStatic::readFileHeader",
268  "The third string on the first line of 1D field "
269  "maps has to be either TRUE or FALSE");
270 
271  normalize_m = (tempString == "TRUE");
272  }
273 
274  parsingPassed = parsingPassed &&
275  interpretLine<double, double, int>(fieldFile,
276  zBegin_m,
277  zEnd_m,
279  parsingPassed = parsingPassed &&
280  interpretLine<double, double, int>(fieldFile, rBegin_m,
281  rEnd_m, tempInt);
282 
284 
285  if (accuracy_m > numberOfGridPoints_m)
287 
288  return parsingPassed;
289 }
290 
291 void _FM1DElectroStatic::stripFileHeader(std::ifstream &fieldFile) {
292 
293  std::string tempString;
294 
295  getLine(fieldFile, tempString);
296  getLine(fieldFile, tempString);
297  getLine(fieldFile, tempString);
298 }
virtual void readMap()
MapType Type
Definition: Fieldmap.h:115
DiffDirection
Definition: Fieldmap.h:55
_FM1DElectroStatic(const std::string &filename)
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)
constexpr double cm2m
Definition: Units.h:35
virtual void getInfo(Inform *)
static std::string typeset_msg(const std::string &msg, const std::string &title)
Definition: Fieldmap.cpp:649
virtual void getFieldDimensions(double &zBegin, double &zEnd) const
constexpr double pi
The value of .
Definition: Physics.h:30
std::string toUpper(const std::string &str)
Definition: Util.cpp:147
virtual void freeMap()
constexpr double Vpm2MVpm
Definition: Units.h:125
#define INFOMSG(msg)
Definition: IpplInfo.h:348
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
void computeFieldOnAxis(double z, std::vector< double > &fieldComponents) const
bool interpreteEOF(std::ifstream &in)
Definition: Fieldmap.cpp:555
void computeFourierCoefficients(double maxEz, double fieldData[])
bool checkFileData(std::ifstream &fieldFile, bool parsingPassed)
virtual double getFrequency() const
double zBegin_m
Maximum radius of field.
virtual bool getFieldstrength(const Vector_t &R, Vector_t &E, Vector_t &B) const
double zEnd_m
Longitudinal start of field.
bool normalize_m
Definition: Fieldmap.h:121
Definition: Inform.h:42
static FM1DElectroStatic create(const std::string &filename)
double readFileData(std::ifstream &fieldFile, double fieldData[])
virtual bool getFieldDerivative(const Vector_t &R, Vector_t &E, Vector_t &B, const DiffDirection &dir) const
bool readFileHeader(std::ifstream &fieldFile)
std::shared_ptr< _FM1DElectroStatic > FM1DElectroStatic
Definition: Definitions.h:33
virtual void setFrequency(double freq)
void disableFieldmapWarning()
Definition: Fieldmap.cpp:610
Tps< T > cos(const Tps< T > &x)
Cosine.
Definition: TpsMath.h:129
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
constexpr double e
The value of .
Definition: Physics.h:39
std::string Filename_m
Definition: Fieldmap.h:118
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
int accuracy_m
Number of grid points in field input file.
int numberOfGridPoints_m
Field length.
double rEnd_m
Minimum radius of field.
void stripFileHeader(std::ifstream &fieldFile)
std::vector< double > fourierCoefs_m
Number of Fourier coefficients to use reconstructing field.
void computeFieldOffAxis(const Vector_t &R, Vector_t &E, Vector_t &B, std::vector< double > fieldComponents) const