OPAL (Object Oriented Parallel Accelerator Library) 2024.2
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
13_FM1DDynamic::_FM1DDynamic(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
33
34 } else {
36 zBegin_m = 0.0;
37 zEnd_m = -1e-3;
38 }
39}
40
44
45FM1DDynamic _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
106void _FM1DDynamic::getFieldDimensions(double &zBegin, double &zEnd) const {
107 zBegin = zBegin_m;
108 zEnd = zEnd_m;
109}
110
111void _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
130void _FM1DDynamic::setFrequency(double frequency) {
131 frequency_m = frequency;
132}
133
134void _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
145bool _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
214void _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.
245
247}
248
249double _FM1DDynamic::readFileData(std::ifstream &fieldFile, double fieldData[]) {
250
251 double maxEz = 0.0;
252 for(int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++ dataIndex) {
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
273double _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
291bool _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,
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 &&
319 zBegin_m,
320 zEnd_m,
322 parsingPassed = parsingPassed &&
324 parsingPassed = parsingPassed &&
326 rBegin_m,
327 rEnd_m,
328 tempInt);
329
331
334
335 return parsingPassed;
336}
337
338void _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
343void _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}
std::shared_ptr< _FM1DDynamic > FM1DDynamic
Definition FM1DDynamic.h:67
@ T1DDynamic
Definition Fieldmap.h:17
DiffDirection
Definition Fieldmap.h:55
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
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 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:147
bool interpreteEOF(std::ifstream &in)
Definition Fieldmap.cpp:555
bool normalize_m
Definition Fieldmap.h:121
static std::string typeset_msg(const std::string &msg, const std::string &title)
Definition Fieldmap.cpp:649
void disableFieldmapWarning()
Definition Fieldmap.cpp:610
void getLine(std::ifstream &in, std::string &buffer)
Definition Fieldmap.h:122
void noFieldmapWarning()
Definition Fieldmap.cpp:618
bool interpretLine(std::ifstream &in, S &value, const bool &file_length_known=true)
std::string Filename_m
Definition Fieldmap.h:118
MapType Type
Definition Fieldmap.h:116
double readFileData(std::ifstream &fieldFile, double fieldData[])
void computeFieldOffAxis(const Vector_t &R, Vector_t &E, Vector_t &B, std::vector< double > fieldComponents) const
int accuracy_m
Number of grid points in field input file.
Definition FM1DDynamic.h:56
void scaleField(double maxEz, std::vector< std::pair< double, double > > &eZ)
friend class _Fieldmap
Fourier coefficients derived from field map.
Definition FM1DDynamic.h:59
virtual bool getFieldDerivative(const Vector_t &R, Vector_t &E, Vector_t &B, const DiffDirection &dir) const
virtual void getOnaxisEz(std::vector< std::pair< double, double > > &eZ)
virtual void getInfo(Inform *)
virtual void readMap()
double zEnd_m
Longitudinal start of field.
Definition FM1DDynamic.h:52
virtual bool getFieldstrength(const Vector_t &R, Vector_t &E, Vector_t &B) const
void convertHeaderData()
void computeFieldOnAxis(double z, std::vector< double > &fieldComponents) const
virtual double getFrequency() const
bool checkFileData(std::ifstream &fieldFile, bool parsingPassed)
double rEnd_m
Minimum radius of field.
Definition FM1DDynamic.h:50
virtual void setFrequency(double freq)
static FM1DDynamic create(const std::string &filename)
int numberOfGridPoints_m
Field length.
Definition FM1DDynamic.h:54
bool readFileHeader(std::ifstream &fieldFile)
double zBegin_m
Maximum radius of field.
Definition FM1DDynamic.h:51
virtual ~_FM1DDynamic()
_FM1DDynamic(const std::string &filename)
double rBegin_m
2 Pi divided by the field RF wavelength squared.
Definition FM1DDynamic.h:49
void stripFileHeader(std::ifstream &fieldFile)
double frequency_m
Definition FM1DDynamic.h:46
double length_m
Longitudinal end of field.
Definition FM1DDynamic.h:53
virtual void freeMap()
virtual void swap()
double twoPiOverLambdaSq_m
Field angular frequency (Hz).
Definition FM1DDynamic.h:47
virtual void getFieldDimensions(double &zBegin, double &zEnd) const
std::vector< double > fourierCoefs_m
Number of Fourier coefficients to use reconstructing field.
Definition FM1DDynamic.h:57
void computeFourierCoefficients(double maxEz, double fieldData[])
Vektor< double, 3 > Vector_t