OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
FM1DElectroStatic.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 
12 FM1DElectroStatic::FM1DElectroStatic(std::string aFilename):
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 maxEz = readFileData(fieldFile, fieldData);
52  fieldFile.close();
53  computeFourierCoefficients(maxEz, 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 eZPrime = 0.0;
88 
89  int coefIndex = 1;
90  for (int n = 1; n < accuracy_m; ++ n) {
91 
92  eZPrime += 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  E(2) += eZPrime;
100 
101  return false;
102 }
103 
104 void FM1DElectroStatic::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 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 
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  && interpreteLine<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(1.0e6 * fieldData[0] / (totalSize * maxEz));
206  for (int coefIndex = 1; coefIndex < 2 * accuracy_m - 1; ++ coefIndex)
207  fourierCoefs_m.push_back(2.0 * 1.0e6 * fieldData[coefIndex] / (totalSize * maxEz));
208 
209  gsl_fft_real_workspace_free(workSpace);
210  gsl_fft_real_wavetable_free(waveTable);
211 
212 }
213 
215 
216  // Convert to m.
217  rBegin_m /= 100.0;
218  rEnd_m /= 100.0;
219  zBegin_m /= 100.0;
220  zEnd_m /= 100.0;
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  interpreteLine<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 = interpreteLine<std::string, int>(fieldFile,
256  tempString,
257  accuracy_m);
258  } catch (GeneralClassicException &e) {
259  parsingPassed = interpreteLine<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  interpreteLine<double, double, int>(fieldFile,
276  zBegin_m,
277  zEnd_m,
279  parsingPassed = parsingPassed &&
280  interpreteLine<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 }
bool readFileHeader(std::ifstream &fieldFile)
void computeFourierCoefficients(double maxEz, double fieldData[])
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
virtual bool getFieldstrength(const Vector_t &R, Vector_t &E, Vector_t &B) const
constexpr double e
The value of .
Definition: Physics.h:40
DiffDirection
Definition: Fieldmap.h:54
Tps< T > sin(const Tps< T > &x)
Sine.
Definition: TpsMath.h:111
virtual void freeMap()
constexpr double two_pi
The value of .
Definition: Physics.h:34
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 checkFileData(std::ifstream &fieldFile, bool parsingPassed)
std::string toUpper(const std::string &str)
Definition: Util.cpp:130
virtual void getFieldDimensions(double &zBegin, double &zEnd, double &rBegin, double &rEnd) const
void disableFieldmapWarning()
Definition: Fieldmap.cpp:610
static std::string typeset_msg(const std::string &msg, const std::string &title)
Definition: Fieldmap.cpp:647
int accuracy_m
Number of grid points in field input file.
void noFieldmapWarning()
Definition: Fieldmap.cpp:618
bool normalize_m
Definition: Fieldmap.h:113
virtual double getFrequency() const
virtual void getInfo(Inform *)
constexpr double pi
The value of .
Definition: Physics.h:31
double length_m
Longitudinal end of field.
bool interpreteEOF(std::ifstream &in)
Definition: Fieldmap.cpp:547
#define INFOMSG(msg)
Definition: IpplInfo.h:397
virtual void readMap()
virtual void setFrequency(double freq)
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
Definition: TpsMath.h:76
double zEnd_m
Longitudinal start of field.
std::vector< double > fourierCoefs_m
Number of Fourier coefficients to use reconstructing field.
void computeFieldOnAxis(double z, std::vector< double > &fieldComponents) const
void stripFileHeader(std::ifstream &fieldFile)
double rEnd_m
Minimum radius of field.
FM1DElectroStatic(std::string aFilename)
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
double zBegin_m
Maximum radius of field.
Definition: Inform.h:41
int numberOfGridPoints_m
Field length.
void computeFieldOffAxis(const Vector_t &R, Vector_t &E, Vector_t &B, std::vector< double > fieldComponents) const
Inform & endl(Inform &inf)
Definition: Inform.cpp:42