OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
FM1DDynamic.cpp
Go to the documentation of this file.
1 #include "Fields/FM1DDynamic.h"
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 <iostream>
11 
12 FM1DDynamic::FM1DDynamic(std::string aFilename):
13  Fieldmap(aFilename) {
14 
15  Type = T1DDynamic;
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 
33  } else {
35  zBegin_m = 0.0;
36  zEnd_m = -1e-3;
37  }
38 }
39 
41  freeMap();
42 }
43 
45 
46  if(fourierCoefs_m.empty()) {
47 
48  std::ifstream fieldFile(Filename_m.c_str());
49  stripFileHeader(fieldFile);
50 
51  double *fieldData = new double[2 * numberOfGridPoints_m - 1];
52  double maxEz = readFileData(fieldFile, fieldData);
53  fieldFile.close();
54  computeFourierCoefficients(maxEz, fieldData);
55  delete [] fieldData;
56 
57  INFOMSG(typeset_msg("Read in field map '" + Filename_m + "'", "info") << endl);
58  }
59 }
60 
62 
63  if(!fourierCoefs_m.empty()) {
64  fourierCoefs_m.clear();
65 
66  INFOMSG(typeset_msg("Freed field map '" + 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 FM1DDynamic::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 
112 void FM1DDynamic::getFieldDimensions(double &xIni, double &xFinal,
113  double &yIni, double &yFinal,
114  double &zIni, double &zFinal) const {
115 }
116 
118 { }
119 
121  (*msg) << Filename_m
122  << " (1D dynamic); zini= "
123  << zBegin_m << " m; zfinal= "
124  << zEnd_m << " m;" << endl;
125 }
126 
128  return frequency_m;
129 }
130 
131 void FM1DDynamic::setFrequency(double frequency) {
132  frequency_m = frequency;
133 }
134 
135 void FM1DDynamic::getOnaxisEz(std::vector<std::pair<double, double> > &eZ) {
136 
137  eZ.resize(numberOfGridPoints_m);
138  std::ifstream fieldFile(Filename_m.c_str());
139  stripFileHeader(fieldFile);
140  double maxEz = readFileData(fieldFile, eZ);
141  fieldFile.close();
142  scaleField(maxEz, eZ);
143 
144 }
145 
146 bool FM1DDynamic::checkFileData(std::ifstream &fieldFile, bool parsingPassed) {
147 
148  double tempDouble;
149  for(int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++ dataIndex)
150  parsingPassed = parsingPassed
151  && interpreteLine<double>(fieldFile, tempDouble);
152 
153  return parsingPassed && interpreteEOF(fieldFile);
154 
155 }
156 
158  Vector_t &E,
159  Vector_t &B,
160  std::vector<double> fieldComponents) const {
161 
162  double radiusSq = pow(R(0), 2.0) + pow(R(1), 2.0);
163  double transverseEFactor = (fieldComponents.at(1)
164  * (0.5 - radiusSq * twoPiOverLambdaSq_m / 16.0)
165  - radiusSq * fieldComponents.at(3) / 16.0);
166  double transverseBFactor = ((fieldComponents.at(0)
167  * (0.5 - radiusSq * twoPiOverLambdaSq_m / 16.0)
168  - radiusSq * fieldComponents.at(2) / 16.0)
170 
171  E(0) += - R(0) * transverseEFactor;
172  E(1) += - R(1) * transverseEFactor;
173  E(2) += (fieldComponents.at(0)
174  * (1.0 - radiusSq * twoPiOverLambdaSq_m / 4.0)
175  - radiusSq * fieldComponents.at(2) / 4.0);
176 
177  B(0) += - R(1) * transverseBFactor;
178  B(1) += R(0) * transverseBFactor;
179 
180 }
181 
183  std::vector<double> &fieldComponents) const {
184 
185  double kz = Physics::two_pi * z / length_m + Physics::pi;
186  fieldComponents.push_back(fourierCoefs_m.at(0));
187  fieldComponents.push_back(0.0);
188  fieldComponents.push_back(0.0);
189  fieldComponents.push_back(0.0);
190 
191  int coefIndex = 1;
192  for(int n = 1; n < accuracy_m; ++ n) {
193 
194  double kn = n * Physics::two_pi / length_m;
195  double coskzn = cos(kz * n);
196  double sinkzn = sin(kz * n);
197 
198  fieldComponents.at(0) += (fourierCoefs_m.at(coefIndex) * coskzn
199  - fourierCoefs_m.at(coefIndex + 1) * sinkzn);
200 
201  fieldComponents.at(1) += kn * (-fourierCoefs_m.at(coefIndex) * sinkzn
202  - fourierCoefs_m.at(coefIndex + 1) * coskzn);
203 
204  double derivCoeff = pow(kn, 2.0);
205  fieldComponents.at(2) += derivCoeff * (-fourierCoefs_m.at(coefIndex) * coskzn
206  + fourierCoefs_m.at(coefIndex + 1) * sinkzn);
207  derivCoeff *= kn;
208  fieldComponents.at(3) += derivCoeff * (fourierCoefs_m.at(coefIndex) * sinkzn
209  + fourierCoefs_m.at(coefIndex + 1) * coskzn);
210 
211  coefIndex += 2;
212  }
213 }
214 
215 void FM1DDynamic::computeFourierCoefficients(double maxEz, double fieldData[]) {
216  const unsigned int totalSize = 2 * numberOfGridPoints_m - 1;
217  gsl_fft_real_wavetable *waveTable = gsl_fft_real_wavetable_alloc(totalSize);
218  gsl_fft_real_workspace *workSpace = gsl_fft_real_workspace_alloc(totalSize);
219  gsl_fft_real_transform(fieldData, 1, totalSize, waveTable, workSpace);
220 
221  /*
222  * Normalize the Fourier coefficients such that the max field value
223  * is 1 V/m.
224  */
225  maxEz /= 1.0e6;
226 
227  fourierCoefs_m.push_back(fieldData[0] / (totalSize * maxEz));
228  for(int coefIndex = 1; coefIndex < 2 * accuracy_m - 1; ++ coefIndex)
229  fourierCoefs_m.push_back(2.0 * fieldData[coefIndex] / (totalSize * maxEz));
230 
231  gsl_fft_real_workspace_free(workSpace);
232  gsl_fft_real_wavetable_free(waveTable);
233 
234 }
235 
237 
238  // Convert to angular frequency in Hz.
239  frequency_m *= Physics::two_pi * 1.0e6;
240 
241  // Convert to m.
242  rBegin_m /= 100.0;
243  rEnd_m /= 100.0;
244  zBegin_m /= 100.0;
245  zEnd_m /= 100.0;
246 
248 }
249 
250 double FM1DDynamic::readFileData(std::ifstream &fieldFile, double fieldData[]) {
251 
252  double maxEz = 0.0;
253  for(int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++ dataIndex) {
254  interpreteLine<double>(fieldFile, fieldData[numberOfGridPoints_m
255  - 1 + dataIndex]);
256  if(std::abs(fieldData[numberOfGridPoints_m + dataIndex]) > maxEz)
257  maxEz = std::abs(fieldData[numberOfGridPoints_m + dataIndex]);
258 
259  /*
260  * Mirror the field map about minimum z value to ensure that it
261  * is periodic.
262  */
263  if(dataIndex != 0)
264  fieldData[numberOfGridPoints_m - 1 - dataIndex]
265  = fieldData[numberOfGridPoints_m + dataIndex];
266  }
267 
268  if (!normalize_m)
269  maxEz = 1.0;
270 
271  return maxEz;
272 }
273 
274 double FM1DDynamic::readFileData(std::ifstream &fieldFile,
275  std::vector<std::pair<double, double>> &eZ) {
276 
277  double maxEz = 0.0;
278  double deltaZ = (zEnd_m - zBegin_m) / (numberOfGridPoints_m - 1);
279  for(int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++ dataIndex) {
280  eZ.at(dataIndex).first = deltaZ * dataIndex;
281  interpreteLine<double>(fieldFile, eZ.at(dataIndex).second);
282  if(std::abs(eZ.at(dataIndex).second) > maxEz)
283  maxEz = std::abs(eZ.at(dataIndex).second);
284  }
285 
286  if (!normalize_m)
287  maxEz = 1.0;
288 
289  return maxEz;
290 }
291 
292 bool FM1DDynamic::readFileHeader(std::ifstream &fieldFile) {
293 
294  std::string tempString;
295  int tempInt;
296 
297  bool parsingPassed = true;
298  try {
299  parsingPassed = interpreteLine<std::string, int>(fieldFile,
300  tempString,
301  accuracy_m);
302  } catch (GeneralClassicException &e) {
303  parsingPassed = interpreteLine<std::string, int, std::string>(fieldFile,
304  tempString,
305  accuracy_m,
306  tempString);
307 
308  tempString = Util::toUpper(tempString);
309  if (tempString != "TRUE" &&
310  tempString != "FALSE")
311  throw GeneralClassicException("FM1DDynamic::FM1DDynamic",
312  "The third string on the first line of 1D field "
313  "maps has to be either TRUE or FALSE");
314 
315  normalize_m = (tempString == "TRUE");
316  }
317 
318  parsingPassed = parsingPassed &&
319  interpreteLine<double, double, int>(fieldFile,
320  zBegin_m,
321  zEnd_m,
323  parsingPassed = parsingPassed &&
324  interpreteLine<double>(fieldFile, frequency_m);
325  parsingPassed = parsingPassed &&
326  interpreteLine<double, double, int>(fieldFile,
327  rBegin_m,
328  rEnd_m,
329  tempInt);
330 
332 
333  if(accuracy_m > numberOfGridPoints_m)
335 
336  return parsingPassed;
337 }
338 
339 void FM1DDynamic::scaleField(double maxEz, std::vector<std::pair<double, double>> &eZ) {
340  for(int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++ dataIndex)
341  eZ.at(dataIndex).second /= maxEz;
342 }
343 
344 void FM1DDynamic::stripFileHeader(std::ifstream &fieldFile) {
345 
346  std::string tempString;
347 
348  getLine(fieldFile, tempString);
349  getLine(fieldFile, tempString);
350  getLine(fieldFile, tempString);
351  getLine(fieldFile, tempString);
352 }
virtual void setFrequency(double freq)
int accuracy_m
Number of grid points in field input file.
Definition: FM1DDynamic.h:55
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
virtual void getFieldDimensions(double &zBegin, double &zEnd, double &rBegin, double &rEnd) const
constexpr double e
The value of .
Definition: Physics.h:40
virtual void freeMap()
Definition: FM1DDynamic.cpp:61
int numberOfGridPoints_m
Field length.
Definition: FM1DDynamic.h:53
DiffDirection
Definition: Fieldmap.h:54
Tps< T > sin(const Tps< T > &x)
Sine.
Definition: TpsMath.h:111
double rBegin_m
2 Pi divided by the field RF wavelength squared.
Definition: FM1DDynamic.h:48
constexpr double two_pi
The value of .
Definition: Physics.h:34
double rEnd_m
Minimum radius of field.
Definition: FM1DDynamic.h:49
double readFileData(std::ifstream &fieldFile, double fieldData[])
std::string toUpper(const std::string &str)
Definition: Util.cpp:130
void disableFieldmapWarning()
Definition: Fieldmap.cpp:610
virtual void getOnaxisEz(std::vector< std::pair< double, double >> &eZ)
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
double frequency_m
Definition: FM1DDynamic.h:45
FM1DDynamic(std::string aFilename)
Definition: FM1DDynamic.cpp:12
virtual void swap()
void computeFieldOnAxis(double z, std::vector< double > &fieldComponents) const
bool readFileHeader(std::ifstream &fieldFile)
constexpr double pi
The value of .
Definition: Physics.h:31
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:52
bool interpreteEOF(std::ifstream &in)
Definition: Fieldmap.cpp:547
double length_m
Longitudinal end of field.
Definition: FM1DDynamic.h:52
#define INFOMSG(msg)
Definition: IpplInfo.h:397
virtual bool getFieldDerivative(const Vector_t &R, Vector_t &E, Vector_t &B, const DiffDirection &dir) const
Definition: FM1DDynamic.cpp:81
double zBegin_m
Maximum radius of field.
Definition: FM1DDynamic.h:50
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
Definition: TpsMath.h:76
std::vector< double > fourierCoefs_m
Number of Fourier coefficients to use reconstructing field.
Definition: FM1DDynamic.h:56
void scaleField(double maxEz, std::vector< std::pair< double, double >> &eZ)
virtual double getFrequency() const
bool checkFileData(std::ifstream &fieldFile, bool parsingPassed)
virtual void readMap()
Definition: FM1DDynamic.cpp:44
Tps< T > cos(const Tps< T > &x)
Cosine.
Definition: TpsMath.h:129
void computeFieldOffAxis(const Vector_t &R, Vector_t &E, Vector_t &B, std::vector< double > fieldComponents) const
void getLine(std::ifstream &in, std::string &buffer)
Definition: Fieldmap.h:198
std::string Filename_m
Definition: Fieldmap.h:110
double twoPiOverLambdaSq_m
Field angular frequency (Hz).
Definition: FM1DDynamic.h:46
void convertHeaderData()
MapType Type
Definition: Fieldmap.h:107
double zEnd_m
Longitudinal start of field.
Definition: FM1DDynamic.h:51
Definition: Inform.h:41
void stripFileHeader(std::ifstream &fieldFile)
void computeFourierCoefficients(double maxEz, double fieldData[])
virtual void getInfo(Inform *)
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
virtual bool getFieldstrength(const Vector_t &R, Vector_t &E, Vector_t &B) const
Definition: FM1DDynamic.cpp:71