OPAL (Object Oriented Parallel Accelerator Library)  2024.1
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"
4 #include "Physics/Units.h"
6 #include "Utilities/Util.h"
7 
8 #include "gsl/gsl_fft_real.h"
9 
10 #include <fstream>
11 #include <iostream>
12 
13 _FM1DDynamic::_FM1DDynamic(const std::string& filename):
14  _Fieldmap(filename) {
15 
16  Type = T1DDynamic;
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 
34  } else {
36  zBegin_m = 0.0;
37  zEnd_m = -1e-3;
38  }
39 }
40 
42  freeMap();
43 }
44 
45 FM1DDynamic _FM1DDynamic::create(const std::string& filename) {
46  return FM1DDynamic(new _FM1DDynamic(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(typeset_msg("Read in field map '" + Filename_m + "'", "info") << endl);
63  }
64 }
65 
67 
68  if(!fourierCoefs_m.empty()) {
69  fourierCoefs_m.clear();
70  }
71 }
72 
74  Vector_t &B) const {
75 
76  std::vector<double> fieldComponents;
77  computeFieldOnAxis(R(2) - zBegin_m, fieldComponents);
78  computeFieldOffAxis(R, E, B, fieldComponents);
79 
80  return false;
81 }
82 
84  Vector_t &E,
85  Vector_t &/*B*/,
86  const DiffDirection &/*dir*/) const {
87 
88  double kz = Physics::two_pi * (R(2) - zBegin_m) / length_m + Physics::pi;
89  double eZPrime = 0.0;
90 
91  int coefIndex = 1;
92  for(int n = 1; n < accuracy_m; ++ n) {
93 
94  eZPrime += (n * Physics::two_pi / length_m
95  * (-fourierCoefs_m.at(coefIndex) * sin(kz * n)
96  - fourierCoefs_m.at(coefIndex + 1) * cos(kz * n)));
97  coefIndex += 2;
98 
99  }
100 
101  E(2) += eZPrime;
102 
103  return false;
104 }
105 
106 void _FM1DDynamic::getFieldDimensions(double &zBegin, double &zEnd) const {
107  zBegin = zBegin_m;
108  zEnd = zEnd_m;
109 }
110 
111 void _FM1DDynamic::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 dynamic); zini= "
122  << zBegin_m << " m; zfinal= "
123  << zEnd_m << " m;" << endl;
124 }
125 
127  return frequency_m;
128 }
129 
130 void _FM1DDynamic::setFrequency(double frequency) {
131  frequency_m = frequency;
132 }
133 
134 void _FM1DDynamic::getOnaxisEz(std::vector<std::pair<double, double> > &eZ) {
135 
136  eZ.resize(numberOfGridPoints_m);
137  std::ifstream fieldFile(Filename_m.c_str());
138  stripFileHeader(fieldFile);
139  double maxEz = readFileData(fieldFile, eZ);
140  fieldFile.close();
141  scaleField(maxEz, eZ);
142 
143 }
144 
145 bool _FM1DDynamic::checkFileData(std::ifstream &fieldFile, bool parsingPassed) {
146 
147  double tempDouble;
148  for(int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++ dataIndex)
149  parsingPassed = parsingPassed
150  && interpretLine<double>(fieldFile, tempDouble);
151 
152  return parsingPassed && interpreteEOF(fieldFile);
153 
154 }
155 
157  Vector_t &E,
158  Vector_t &B,
159  std::vector<double> fieldComponents) const {
160 
161  double radiusSq = pow(R(0), 2.0) + pow(R(1), 2.0);
162  double transverseEFactor = (fieldComponents.at(1)
163  * (0.5 - radiusSq * twoPiOverLambdaSq_m / 16.0)
164  - radiusSq * fieldComponents.at(3) / 16.0);
165  double transverseBFactor = ((fieldComponents.at(0)
166  * (0.5 - radiusSq * twoPiOverLambdaSq_m / 16.0)
167  - radiusSq * fieldComponents.at(2) / 16.0)
169 
170  E(0) += - R(0) * transverseEFactor;
171  E(1) += - R(1) * transverseEFactor;
172  E(2) += (fieldComponents.at(0)
173  * (1.0 - radiusSq * twoPiOverLambdaSq_m / 4.0)
174  - radiusSq * fieldComponents.at(2) / 4.0);
175 
176  B(0) += - R(1) * transverseBFactor;
177  B(1) += R(0) * transverseBFactor;
178 
179 }
180 
182  std::vector<double> &fieldComponents) const {
183 
184  double kz = Physics::two_pi * z / length_m + Physics::pi;
185  fieldComponents.push_back(fourierCoefs_m.at(0));
186  fieldComponents.push_back(0.0);
187  fieldComponents.push_back(0.0);
188  fieldComponents.push_back(0.0);
189 
190  int coefIndex = 1;
191  for(int n = 1; n < accuracy_m; ++ n) {
192 
193  double kn = n * Physics::two_pi / length_m;
194  double coskzn = cos(kz * n);
195  double sinkzn = sin(kz * n);
196 
197  fieldComponents.at(0) += (fourierCoefs_m.at(coefIndex) * coskzn
198  - fourierCoefs_m.at(coefIndex + 1) * sinkzn);
199 
200  fieldComponents.at(1) += kn * (-fourierCoefs_m.at(coefIndex) * sinkzn
201  - fourierCoefs_m.at(coefIndex + 1) * coskzn);
202 
203  double derivCoeff = pow(kn, 2.0);
204  fieldComponents.at(2) += derivCoeff * (-fourierCoefs_m.at(coefIndex) * coskzn
205  + fourierCoefs_m.at(coefIndex + 1) * sinkzn);
206  derivCoeff *= kn;
207  fieldComponents.at(3) += derivCoeff * (fourierCoefs_m.at(coefIndex) * sinkzn
208  + fourierCoefs_m.at(coefIndex + 1) * coskzn);
209 
210  coefIndex += 2;
211  }
212 }
213 
214 void _FM1DDynamic::computeFourierCoefficients(double maxEz, double fieldData[]) {
215  const unsigned int totalSize = 2 * numberOfGridPoints_m - 1;
216  gsl_fft_real_wavetable *waveTable = gsl_fft_real_wavetable_alloc(totalSize);
217  gsl_fft_real_workspace *workSpace = gsl_fft_real_workspace_alloc(totalSize);
218  gsl_fft_real_transform(fieldData, 1, totalSize, waveTable, workSpace);
219 
220  /*
221  * Normalize the Fourier coefficients such that the max field value
222  * is 1 V/m.
223  */
224  maxEz *= Units::Vpm2MVpm;
225 
226  fourierCoefs_m.push_back(fieldData[0] / (totalSize * maxEz));
227  for(int coefIndex = 1; coefIndex < 2 * accuracy_m - 1; ++ coefIndex)
228  fourierCoefs_m.push_back(2.0 * fieldData[coefIndex] / (totalSize * maxEz));
229 
230  gsl_fft_real_workspace_free(workSpace);
231  gsl_fft_real_wavetable_free(waveTable);
232 
233 }
234 
236 
237  // Convert to angular frequency in Hz.
239 
240  // Convert to m.
242  rEnd_m *= Units::cm2m;
244  zEnd_m *= Units::cm2m;
245 
247 }
248 
249 double _FM1DDynamic::readFileData(std::ifstream &fieldFile, double fieldData[]) {
250 
251  double maxEz = 0.0;
252  for(int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++ dataIndex) {
253  interpretLine<double>(fieldFile, fieldData[numberOfGridPoints_m
254  - 1 + dataIndex]);
255  if(std::abs(fieldData[numberOfGridPoints_m + dataIndex]) > maxEz)
256  maxEz = std::abs(fieldData[numberOfGridPoints_m + dataIndex]);
257 
258  /*
259  * Mirror the field map about minimum z value to ensure that it
260  * is periodic.
261  */
262  if(dataIndex != 0)
263  fieldData[numberOfGridPoints_m - 1 - dataIndex]
264  = fieldData[numberOfGridPoints_m + dataIndex];
265  }
266 
267  if (!normalize_m)
268  maxEz = 1.0;
269 
270  return maxEz;
271 }
272 
273 double _FM1DDynamic::readFileData(std::ifstream &fieldFile,
274  std::vector<std::pair<double, double>> &eZ) {
275 
276  double maxEz = 0.0;
277  double deltaZ = (zEnd_m - zBegin_m) / (numberOfGridPoints_m - 1);
278  for(int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++ dataIndex) {
279  eZ.at(dataIndex).first = deltaZ * dataIndex;
280  interpretLine<double>(fieldFile, eZ.at(dataIndex).second);
281  if(std::abs(eZ.at(dataIndex).second) > maxEz)
282  maxEz = std::abs(eZ.at(dataIndex).second);
283  }
284 
285  if (!normalize_m)
286  maxEz = 1.0;
287 
288  return maxEz;
289 }
290 
291 bool _FM1DDynamic::readFileHeader(std::ifstream &fieldFile) {
292 
293  std::string tempString;
294  int tempInt;
295 
296  bool parsingPassed = true;
297  try {
298  parsingPassed = interpretLine<std::string, int>(fieldFile,
299  tempString,
300  accuracy_m);
301  } catch (GeneralClassicException &e) {
302  parsingPassed = interpretLine<std::string, int, std::string>(fieldFile,
303  tempString,
304  accuracy_m,
305  tempString);
306 
307  tempString = Util::toUpper(tempString);
308  if (tempString != "TRUE" &&
309  tempString != "FALSE")
310  throw GeneralClassicException("_FM1DDynamic::_FM1DDynamic",
311  "The third string on the first line of 1D field "
312  "maps has to be either TRUE or FALSE");
313 
314  normalize_m = (tempString == "TRUE");
315  }
316 
317  parsingPassed = parsingPassed &&
318  interpretLine<double, double, int>(fieldFile,
319  zBegin_m,
320  zEnd_m,
322  parsingPassed = parsingPassed &&
323  interpretLine<double>(fieldFile, frequency_m);
324  parsingPassed = parsingPassed &&
325  interpretLine<double, double, int>(fieldFile,
326  rBegin_m,
327  rEnd_m,
328  tempInt);
329 
331 
332  if(accuracy_m > numberOfGridPoints_m)
334 
335  return parsingPassed;
336 }
337 
338 void _FM1DDynamic::scaleField(double maxEz, std::vector<std::pair<double, double>> &eZ) {
339  for(int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++ dataIndex)
340  eZ.at(dataIndex).second /= maxEz;
341 }
342 
343 void _FM1DDynamic::stripFileHeader(std::ifstream &fieldFile) {
344 
345  std::string tempString;
346 
347  getLine(fieldFile, tempString);
348  getLine(fieldFile, tempString);
349  getLine(fieldFile, tempString);
350  getLine(fieldFile, tempString);
351 }
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:45
virtual void setFrequency(double freq)
virtual bool getFieldDerivative(const Vector_t &R, Vector_t &E, Vector_t &B, const DiffDirection &dir) const
Definition: FM1DDynamic.cpp:83
MapType Type
Definition: Fieldmap.h:115
bool checkFileData(std::ifstream &fieldFile, bool parsingPassed)
DiffDirection
Definition: Fieldmap.h:55
constexpr double two_pi
The value of .
Definition: Physics.h:33
void noFieldmapWarning()
Definition: Fieldmap.cpp:618
void computeFieldOnAxis(double z, std::vector< double > &fieldComponents) const
virtual double getFrequency() const
double frequency_m
Definition: FM1DDynamic.h:46
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
virtual void swap()
static FM1DDynamic create(const std::string &filename)
Definition: FM1DDynamic.cpp:45
constexpr double cm2m
Definition: Units.h:35
virtual void getOnaxisEz(std::vector< std::pair< double, double >> &eZ)
bool readFileHeader(std::ifstream &fieldFile)
static std::string typeset_msg(const std::string &msg, const std::string &title)
Definition: Fieldmap.cpp:649
int numberOfGridPoints_m
Field length.
Definition: FM1DDynamic.h:54
constexpr double pi
The value of .
Definition: Physics.h:30
std::string toUpper(const std::string &str)
Definition: Util.cpp:147
constexpr double Vpm2MVpm
Definition: Units.h:125
#define INFOMSG(msg)
Definition: IpplInfo.h:348
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
double zEnd_m
Longitudinal start of field.
Definition: FM1DDynamic.h:52
double zBegin_m
Maximum radius of field.
Definition: FM1DDynamic.h:51
bool interpreteEOF(std::ifstream &in)
Definition: Fieldmap.cpp:555
void convertHeaderData()
void stripFileHeader(std::ifstream &fieldFile)
virtual void getInfo(Inform *)
void computeFieldOffAxis(const Vector_t &R, Vector_t &E, Vector_t &B, std::vector< double > fieldComponents) const
bool normalize_m
Definition: Fieldmap.h:121
Definition: Inform.h:42
double length_m
Longitudinal end of field.
Definition: FM1DDynamic.h:53
double twoPiOverLambdaSq_m
Field angular frequency (Hz).
Definition: FM1DDynamic.h:47
_FM1DDynamic(const std::string &filename)
Definition: FM1DDynamic.cpp:13
virtual ~_FM1DDynamic()
Definition: FM1DDynamic.cpp:41
void disableFieldmapWarning()
Definition: Fieldmap.cpp:610
Tps< T > cos(const Tps< T > &x)
Cosine.
Definition: TpsMath.h:129
double rEnd_m
Minimum radius of field.
Definition: FM1DDynamic.h:50
std::shared_ptr< _FM1DDynamic > FM1DDynamic
Definition: Definitions.h:27
constexpr double MHz2Hz
Definition: Units.h:113
void scaleField(double maxEz, std::vector< std::pair< double, double >> &eZ)
virtual void getFieldDimensions(double &zBegin, double &zEnd) const
void getLine(std::ifstream &in, std::string &buffer)
Definition: Fieldmap.h:122
virtual bool getFieldstrength(const Vector_t &R, Vector_t &E, Vector_t &B) const
Definition: FM1DDynamic.cpp:73
void computeFourierCoefficients(double maxEz, double fieldData[])
double rBegin_m
2 Pi divided by the field RF wavelength squared.
Definition: FM1DDynamic.h:49
constexpr double e
The value of .
Definition: Physics.h:39
int accuracy_m
Number of grid points in field input file.
Definition: FM1DDynamic.h:56
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
virtual void readMap()
Definition: FM1DDynamic.cpp:49
double readFileData(std::ifstream &fieldFile, double fieldData[])
virtual void freeMap()
Definition: FM1DDynamic.cpp:66
std::vector< double > fourierCoefs_m
Number of Fourier coefficients to use reconstructing field.
Definition: FM1DDynamic.h:57