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