OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
FM1DDynamic_fast.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 <ios>
12
14 Fieldmap(aFilename),
15 accuracy_m(0)
16{
17
19 onAxisField_m = nullptr;
20
21 std::ifstream fieldFile(Filename_m.c_str());
22 if (fieldFile.good()) {
23
24 bool parsingPassed = readFileHeader(fieldFile);
25 parsingPassed = checkFileData(fieldFile, parsingPassed);
26 fieldFile.close();
27
28 if (!parsingPassed) {
30 zEnd_m = zBegin_m - 1.0e-3;
31 } else
33
36
37 } else {
39 zBegin_m = 0.0;
40 zEnd_m = -1.0e-3;
41 }
42}
43
45 freeMap();
46}
47
49
50 if (onAxisField_m == nullptr) {
51
52 std::ifstream fieldFile(Filename_m.c_str());
53 stripFileHeader(fieldFile);
54
56 double maxEz = readFileData(fieldFile, onAxisField_m);
57 fieldFile.close();
58
59 std::vector<double> fourierCoefs = computeFourierCoefficients(onAxisField_m);
60 normalizeField(maxEz, fourierCoefs);
61
62 double *onAxisFieldP = new double[numberOfGridPoints_m];
63 double *onAxisFieldPP = new double[numberOfGridPoints_m];
64 double *onAxisFieldPPP = new double[numberOfGridPoints_m];
65 computeFieldDerivatives(fourierCoefs, onAxisFieldP,
66 onAxisFieldPP, onAxisFieldPPP);
67 computeInterpolationVectors(onAxisFieldP, onAxisFieldPP,
68 onAxisFieldPPP);
69
70 prepareForMapCheck(fourierCoefs);
71
72 delete [] onAxisFieldP;
73 delete [] onAxisFieldPP;
74 delete [] onAxisFieldPPP;
75
76 INFOMSG(typeset_msg("Read in fieldmap '" + Filename_m + "'", "info")
77 << endl);
78 }
79}
80
82 if (onAxisField_m != nullptr) {
83 delete [] onAxisField_m;
84 onAxisField_m = nullptr;
85
86 gsl_spline_free(onAxisFieldInterpolants_m);
87 gsl_spline_free(onAxisFieldPInterpolants_m);
88 gsl_spline_free(onAxisFieldPPInterpolants_m);
89 gsl_spline_free(onAxisFieldPPPInterpolants_m);
90 gsl_interp_accel_free(onAxisFieldAccel_m);
91 gsl_interp_accel_free(onAxisFieldPAccel_m);
92 gsl_interp_accel_free(onAxisFieldPPAccel_m);
93 gsl_interp_accel_free(onAxisFieldPPPAccel_m);
94
95 INFOMSG(level3 << typeset_msg("freed fieldmap '" + Filename_m + "'", "info")
96 << endl);
97 }
98}
99
101 Vector_t &B) const {
102
103 std::vector<double> fieldComponents;
104 computeFieldOnAxis(R(2) - zBegin_m, fieldComponents);
105 computeFieldOffAxis(R, E, B, fieldComponents);
106
107 return false;
108}
109
111 Vector_t &E,
112 Vector_t &/*B*/,
113 const DiffDirection &/*dir*/) const {
114
115 E(2) += gsl_spline_eval(onAxisFieldPInterpolants_m, R(2) - zBegin_m,
117
118 return false;
119}
120
121void FM1DDynamic_fast::getFieldDimensions(double &zBegin, double &zEnd) const {
122 zBegin = zBegin_m;
123 zEnd = zEnd_m;
124}
125
126void FM1DDynamic_fast::getFieldDimensions(double &/*xIni*/, double &/*xFinal*/,
127 double &/*yIni*/, double &/*yFinal*/,
128 double &/*zIni*/, double &/*zFinal*/) const {}
129
131{ }
132
134 (*msg) << Filename_m
135 << " (1D dynamic); zini= "
136 << zBegin_m << " m; zfinal= "
137 << zEnd_m << " m;" << endl;
138}
139
141 return frequency_m;
142}
143
145 frequency_m = freq;
146}
147
148void FM1DDynamic_fast::getOnaxisEz(std::vector<std::pair<double, double>> &eZ) {
149
150 eZ.resize(numberOfGridPoints_m);
151 std::ifstream fieldFile(Filename_m.c_str());
152 stripFileHeader(fieldFile);
153 double maxEz = readFileData(fieldFile, eZ);
154 fieldFile.close();
155 scaleField(maxEz, eZ);
156
157}
158
159bool FM1DDynamic_fast::checkFileData(std::ifstream &fieldFile,
160 bool parsingPassed) {
161
162 double tempDouble;
163 for (unsigned int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++ dataIndex)
164 parsingPassed = parsingPassed
165 && interpretLine<double>(fieldFile, tempDouble);
166
167 return parsingPassed && interpreteEOF(fieldFile);
168
169}
170
171void FM1DDynamic_fast::computeFieldDerivatives(std::vector<double> fourierCoefs,
172 double onAxisFieldP[],
173 double onAxisFieldPP[],
174 double onAxisFieldPPP[]) {
175
176 for (unsigned int zStepIndex = 0; zStepIndex < numberOfGridPoints_m; ++ zStepIndex) {
177
178 double z = deltaZ_m * zStepIndex;
179 double kz = Physics::two_pi * z / length_m + Physics::pi;
180 onAxisFieldP[zStepIndex] = 0.0;
181 onAxisFieldPP[zStepIndex] = 0.0;
182 onAxisFieldPPP[zStepIndex] = 0.0;
183
184 int coefIndex = 1;
185 for (unsigned int n = 1; n < accuracy_m; ++ n) {
186
187 double kn = n * Physics::two_pi / length_m;
188 double coskzn = cos(kz * n);
189 double sinkzn = sin(kz * n);
190
191 onAxisFieldP[zStepIndex] += kn * (-fourierCoefs.at(coefIndex) * sinkzn
192 - fourierCoefs.at(coefIndex + 1) * coskzn);
193
194 double derivCoeff = pow(kn, 2.0);
195 onAxisFieldPP[zStepIndex] += derivCoeff * (-fourierCoefs.at(coefIndex) * coskzn
196 + fourierCoefs.at(coefIndex + 1) * sinkzn);
197 derivCoeff *= kn;
198 onAxisFieldPPP[zStepIndex] += derivCoeff * (fourierCoefs.at(coefIndex) * sinkzn
199 + fourierCoefs.at(coefIndex + 1) * coskzn);
200
201 coefIndex += 2;
202 }
203 }
204
205}
206
208 Vector_t &E,
209 Vector_t &B,
210 std::vector<double> fieldComponents) const {
211
212 double radiusSq = pow(R(0), 2.0) + pow(R(1), 2.0);
213 double transverseEFactor = (fieldComponents.at(1)
214 * (0.5 - radiusSq * twoPiOverLambdaSq_m / 16.0)
215 - radiusSq * fieldComponents.at(3) / 16.0);
216 double transverseBFactor = ((fieldComponents.at(0)
217 * (0.5 - radiusSq * twoPiOverLambdaSq_m / 16.0)
218 - radiusSq * fieldComponents.at(2) / 16.0)
220
221 E(0) += - R(0) * transverseEFactor;
222 E(1) += - R(1) * transverseEFactor;
223 E(2) += (fieldComponents.at(0) * (1.0 - radiusSq * twoPiOverLambdaSq_m / 4.0)
224 - radiusSq * fieldComponents.at(2) / 4.0);
225
226 B(0) += - R(1) * transverseBFactor;
227 B(1) += R(0) * transverseBFactor;
228
229}
230
232 std::vector<double> &fieldComponents)
233 const {
234
235 fieldComponents.push_back(gsl_spline_eval(onAxisFieldInterpolants_m,
237 fieldComponents.push_back(gsl_spline_eval(onAxisFieldPInterpolants_m,
239 fieldComponents.push_back(gsl_spline_eval(onAxisFieldPPInterpolants_m,
241 fieldComponents.push_back(gsl_spline_eval(onAxisFieldPPPInterpolants_m,
243}
244
245std::vector<double> FM1DDynamic_fast::computeFourierCoefficients(double fieldData[]) {
246 const unsigned int totalSize = 2 * numberOfGridPoints_m - 1;
247 gsl_fft_real_wavetable *waveTable = gsl_fft_real_wavetable_alloc(totalSize);
248 gsl_fft_real_workspace *workSpace = gsl_fft_real_workspace_alloc(totalSize);
249
250 // Reflect field about minimum z value to ensure that it is periodic.
251 double *fieldDataReflected = new double[totalSize];
252 for (unsigned int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++ dataIndex) {
253 fieldDataReflected[numberOfGridPoints_m - 1 + dataIndex]
254 = fieldData[dataIndex];
255 if (dataIndex != 0)
256 fieldDataReflected[numberOfGridPoints_m - 1 - dataIndex]
257 = fieldData[dataIndex];
258 }
259
260 gsl_fft_real_transform(fieldDataReflected, 1,
261 totalSize,
262 waveTable, workSpace);
263
264 std::vector<double> fourierCoefs;
265 fourierCoefs.push_back(fieldDataReflected[0] / totalSize);
266 for (unsigned int coefIndex = 1; coefIndex < 2 * accuracy_m - 1; ++ coefIndex)
267 fourierCoefs.push_back(2.0 * fieldDataReflected[coefIndex] / totalSize);
268
269 delete [] fieldDataReflected;
270 gsl_fft_real_workspace_free(workSpace);
271 gsl_fft_real_wavetable_free(waveTable);
272
273 return fourierCoefs;
274
275}
276
278 double onAxisFieldPP[],
279 double onAxisFieldPPP[]) {
280
281 onAxisFieldInterpolants_m = gsl_spline_alloc(gsl_interp_cspline,
283 onAxisFieldPInterpolants_m = gsl_spline_alloc(gsl_interp_cspline,
285 onAxisFieldPPInterpolants_m = gsl_spline_alloc(gsl_interp_cspline,
287 onAxisFieldPPPInterpolants_m = gsl_spline_alloc(gsl_interp_cspline,
289
290 double *z = new double[numberOfGridPoints_m];
291 for (unsigned int zStepIndex = 0; zStepIndex < numberOfGridPoints_m; ++ zStepIndex)
292 z[zStepIndex] = deltaZ_m * zStepIndex;
293 gsl_spline_init(onAxisFieldInterpolants_m, z,
295 gsl_spline_init(onAxisFieldPInterpolants_m, z,
296 onAxisFieldP, numberOfGridPoints_m);
297 gsl_spline_init(onAxisFieldPPInterpolants_m, z,
298 onAxisFieldPP, numberOfGridPoints_m);
299 gsl_spline_init(onAxisFieldPPPInterpolants_m, z,
300 onAxisFieldPPP, numberOfGridPoints_m);
301
302 onAxisFieldAccel_m = gsl_interp_accel_alloc();
303 onAxisFieldPAccel_m = gsl_interp_accel_alloc();
304 onAxisFieldPPAccel_m = gsl_interp_accel_alloc();
305 onAxisFieldPPPAccel_m = gsl_interp_accel_alloc();
306
307 delete [] z;
308}
309
311
312 // Convert to angular frequency in Hz.
314
315 // Convert to m.
320
322}
323
325 std::vector<double> &fourierCoefs) {
326
327 for (unsigned int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++ dataIndex)
328 onAxisField_m[dataIndex] /= (maxEz * Units::Vpm2MVpm);
329
330 for (std::vector<double>::iterator fourierIterator = fourierCoefs.begin();
331 fourierIterator < fourierCoefs.end(); ++ fourierIterator)
332 *fourierIterator/= (maxEz * Units::Vpm2MVpm);
333
334}
335
336double FM1DDynamic_fast::readFileData(std::ifstream &fieldFile,
337 double fieldData[]) {
338
339 double maxEz = 0.0;
340 for (unsigned int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++ dataIndex) {
341 interpretLine<double>(fieldFile, fieldData[dataIndex]);
342 if (std::abs(fieldData[dataIndex]) > maxEz)
343 maxEz = std::abs(fieldData[dataIndex]);
344 }
345
346 if (!normalize_m)
347 maxEz = 1.0;
348
349 return maxEz;
350}
351
352double FM1DDynamic_fast::readFileData(std::ifstream &fieldFile,
353 std::vector<std::pair<double, double>> &eZ) {
354
355 double maxEz = 0.0;
356 double deltaZ = (zEnd_m - zBegin_m) / (numberOfGridPoints_m - 1);
357 for (unsigned int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++ dataIndex) {
358 eZ.at(dataIndex).first = deltaZ * dataIndex;
359 interpretLine<double>(fieldFile, eZ.at(dataIndex).second);
360 if (std::abs(eZ.at(dataIndex).second) > maxEz)
361 maxEz = std::abs(eZ.at(dataIndex).second);
362 }
363
364 if (!normalize_m)
365 maxEz = 1.0;
366
367 return maxEz;
368}
369
370bool FM1DDynamic_fast::readFileHeader(std::ifstream &fieldFile) {
371
372 std::string tempString;
373 int tempInt;
374
375 bool parsingPassed = true;
376 try {
377 parsingPassed = interpretLine<std::string, unsigned int>(fieldFile,
378 tempString,
379 accuracy_m);
380 } catch (GeneralClassicException &e) {
381 parsingPassed = interpretLine<std::string, unsigned int, std::string>(fieldFile,
382 tempString,
384 tempString);
385
386 tempString = Util::toUpper(tempString);
387 if (tempString != "TRUE" &&
388 tempString != "FALSE")
389 throw GeneralClassicException("FM1DDynamic_fast::readFileHeader",
390 "The third string on the first line of 1D field "
391 "maps has to be either TRUE or FALSE");
392
393 normalize_m = (tempString == "TRUE");
394 }
395 parsingPassed = parsingPassed &&
396 interpretLine<double, double, unsigned int>(fieldFile,
397 zBegin_m,
398 zEnd_m,
400 parsingPassed = parsingPassed &&
401 interpretLine<double>(fieldFile, frequency_m);
402 parsingPassed = parsingPassed &&
403 interpretLine<double, double, int>(fieldFile,
404 rBegin_m,
405 rEnd_m,
406 tempInt);
407
409
412
413 return parsingPassed;
414}
415
417 std::vector<std::pair<double, double>> &eZ) {
418 if (!normalize_m) return;
419
420 for (unsigned int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++ dataIndex)
421 eZ.at(dataIndex).second /= maxEz;
422}
423
424void FM1DDynamic_fast::stripFileHeader(std::ifstream &fieldFile) {
425
426 std::string tempString;
427
428 getLine(fieldFile, tempString);
429 getLine(fieldFile, tempString);
430 getLine(fieldFile, tempString);
431 getLine(fieldFile, tempString);
432}
433
434void FM1DDynamic_fast::prepareForMapCheck(std::vector<double> &fourierCoefs) {
435 std::vector<double> zSampling(numberOfGridPoints_m);
436 for (unsigned int zStepIndex = 0; zStepIndex < numberOfGridPoints_m; ++ zStepIndex)
437 zSampling[zStepIndex] = deltaZ_m * zStepIndex;
438
440 length_m,
441 zSampling,
442 fourierCoefs,
445}
@ 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
Inform & level3(Inform &inf)
Definition: Inform.cpp:47
#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::iterator iterator
Definition: MSLang.h:16
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 checkMap(unsigned int accuracy, std::pair< double, double > fieldDimensions, double deltaZ, const std::vector< double > &fourierCoefficients, gsl_spline *splineCoefficients, gsl_interp_accel *splineAccelerator)
Definition: Fieldmap.cpp:451
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
gsl_interp_accel * onAxisFieldAccel_m
On axis field third derivative interpolation structure.
FM1DDynamic_fast(std::string aFilename)
virtual void getFieldDimensions(double &zBegin, double &zEnd) const
gsl_spline * onAxisFieldPInterpolants_m
On axis field interpolation structure.
void stripFileHeader(std::ifstream &fieldFile)
virtual bool getFieldstrength(const Vector_t &R, Vector_t &E, Vector_t &B) const
gsl_spline * onAxisFieldInterpolants_m
On axis field data.
double rEnd_m
Minimum radius of field.
double zBegin_m
Maximum radius of field.
gsl_interp_accel * onAxisFieldPPPAccel_m
void computeFieldOffAxis(const Vector_t &R, Vector_t &E, Vector_t &B, std::vector< double > fieldComponents) const
double zEnd_m
Longitudinal start of field.
void computeFieldOnAxis(double z, std::vector< double > &fieldComponents) const
virtual void setFrequency(double freq)
gsl_interp_accel * onAxisFieldPPAccel_m
std::vector< double > computeFourierCoefficients(double fieldData[])
double length_m
Longitudinal end of field.
virtual void readMap()
gsl_spline * onAxisFieldPPPInterpolants_m
On axis field second derivative interpolation structure.
virtual double getFrequency() const
void normalizeField(double maxEz, std::vector< double > &fourierCoefs)
void scaleField(double maxEz, std::vector< std::pair< double, double > > &eZ)
virtual void swap()
virtual void getOnaxisEz(std::vector< std::pair< double, double > > &eZ)
void computeInterpolationVectors(double onAxisFieldP[], double onAxisFieldPP[], double onAxisFieldPPP[])
double readFileData(std::ifstream &fieldFile, double fieldData[])
void prepareForMapCheck(std::vector< double > &fourierCoefs)
unsigned int numberOfGridPoints_m
Field length.
void computeFieldDerivatives(std::vector< double > fourierCoefs, double onAxisFieldP[], double onAxisFieldPP[], double onAxisFieldPPP[])
virtual bool getFieldDerivative(const Vector_t &R, Vector_t &E, Vector_t &B, const DiffDirection &dir) const
gsl_spline * onAxisFieldPPInterpolants_m
On axis field first derivative interpolation structure.
virtual void freeMap()
bool checkFileData(std::ifstream &fieldFile, bool parsingPassed)
bool readFileHeader(std::ifstream &fieldFile)
virtual void getInfo(Inform *)
gsl_interp_accel * onAxisFieldPAccel_m
unsigned int accuracy_m
Field grid point spacing.
double deltaZ_m
Number of grid points in field input file.
double rBegin_m
2 Pi divided by the field RF wavelength squared.
double twoPiOverLambdaSq_m
Field angular frequency (Hz).
Definition: Inform.h:42