OPALX (Object Oriented Parallel Accelerator Library for Exascal) MINIorX
OPALX
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
13FM1DDynamic_fast::FM1DDynamic_fast(std::string aFilename) : Fieldmap(aFilename), accuracy_m(0) {
15 onAxisField_m = nullptr;
16
17 std::ifstream fieldFile(Filename_m.c_str());
18 if (fieldFile.good()) {
19 bool parsingPassed = readFileHeader(fieldFile);
20 parsingPassed = checkFileData(fieldFile, parsingPassed);
21 fieldFile.close();
22
23 if (!parsingPassed) {
25 zEnd_m = zBegin_m - 1.0e-3;
26 } else
28
31
32 } else {
34 zBegin_m = 0.0;
35 zEnd_m = -1.0e-3;
36 }
37}
38
42
44 if (onAxisField_m == nullptr) {
45 std::ifstream fieldFile(Filename_m.c_str());
46 stripFileHeader(fieldFile);
47
49 double maxEz = readFileData(fieldFile, onAxisField_m);
50 fieldFile.close();
51
52 std::vector<double> fourierCoefs = computeFourierCoefficients(onAxisField_m);
53 normalizeField(maxEz, fourierCoefs);
54
55 double* onAxisFieldP = new double[numberOfGridPoints_m];
56 double* onAxisFieldPP = new double[numberOfGridPoints_m];
57 double* onAxisFieldPPP = new double[numberOfGridPoints_m];
58 computeFieldDerivatives(fourierCoefs, onAxisFieldP, onAxisFieldPP, onAxisFieldPPP);
59 computeInterpolationVectors(onAxisFieldP, onAxisFieldPP, onAxisFieldPPP);
60
61 prepareForMapCheck(fourierCoefs);
62
63 delete[] onAxisFieldP;
64 delete[] onAxisFieldPP;
65 delete[] onAxisFieldPPP;
66
67 *ippl::Info << typeset_msg("Read in fieldmap '" + Filename_m + "'", "info") << endl;
68 }
69}
70
72 if (onAxisField_m != nullptr) {
73 delete[] onAxisField_m;
74 onAxisField_m = nullptr;
75
76 gsl_spline_free(onAxisFieldInterpolants_m);
77 gsl_spline_free(onAxisFieldPInterpolants_m);
78 gsl_spline_free(onAxisFieldPPInterpolants_m);
79 gsl_spline_free(onAxisFieldPPPInterpolants_m);
80 gsl_interp_accel_free(onAxisFieldAccel_m);
81 gsl_interp_accel_free(onAxisFieldPAccel_m);
82 gsl_interp_accel_free(onAxisFieldPPAccel_m);
83 gsl_interp_accel_free(onAxisFieldPPPAccel_m);
84
85 *ippl::Info << level3 << typeset_msg("freed fieldmap '" + Filename_m + "'", "info") << endl;
86 }
87}
88
91 std::vector<double> fieldComponents;
92 computeFieldOnAxis(R(2) - zBegin_m, fieldComponents);
93 computeFieldOffAxis(R, E, B, fieldComponents);
94
95 return false;
96}
97
100 const DiffDirection& /*dir*/) const {
101 E(2) += gsl_spline_eval(onAxisFieldPInterpolants_m, R(2) - zBegin_m, onAxisFieldPAccel_m);
102
103 return false;
104}
105
106void FM1DDynamic_fast::getFieldDimensions(double& zBegin, double& zEnd) const {
107 zBegin = zBegin_m;
108 zEnd = zEnd_m;
109}
110
112 double& /*xIni*/, double& /*xFinal*/, double& /*yIni*/, double& /*yFinal*/, double& /*zIni*/,
113 double& /*zFinal*/) const {
114}
115
118
119void FM1DDynamic_fast::getInfo(Inform* msg) {
120 (*msg) << Filename_m << " (1D dynamic); zini= " << zBegin_m << " m; zfinal= " << zEnd_m << " m;"
121 << endl;
122}
123
125 return frequency_m;
126}
127
129 frequency_m = freq;
130}
131
132void FM1DDynamic_fast::getOnaxisEz(std::vector<std::pair<double, double>>& eZ) {
133 eZ.resize(numberOfGridPoints_m);
134 std::ifstream fieldFile(Filename_m.c_str());
135 stripFileHeader(fieldFile);
136 double maxEz = readFileData(fieldFile, eZ);
137 fieldFile.close();
138 scaleField(maxEz, eZ);
139}
140
141bool FM1DDynamic_fast::checkFileData(std::ifstream& fieldFile, bool parsingPassed) {
142 double tempDouble;
143 for (unsigned int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++dataIndex)
144 parsingPassed = parsingPassed && interpretLine<double>(fieldFile, tempDouble);
145
146 return parsingPassed && interpreteEOF(fieldFile);
147}
148
150 std::vector<double> fourierCoefs, double onAxisFieldP[], double onAxisFieldPP[],
151 double onAxisFieldPPP[]) {
152 for (unsigned int zStepIndex = 0; zStepIndex < numberOfGridPoints_m; ++zStepIndex) {
153 double z = deltaZ_m * zStepIndex;
154 double kz = Physics::two_pi * z / length_m + Physics::pi;
155 onAxisFieldP[zStepIndex] = 0.0;
156 onAxisFieldPP[zStepIndex] = 0.0;
157 onAxisFieldPPP[zStepIndex] = 0.0;
158
159 int coefIndex = 1;
160 for (unsigned int n = 1; n < accuracy_m; ++n) {
161 double kn = n * Physics::two_pi / length_m;
162 double coskzn = cos(kz * n);
163 double sinkzn = sin(kz * n);
164
165 onAxisFieldP[zStepIndex] +=
166 kn
167 * (-fourierCoefs.at(coefIndex) * sinkzn - fourierCoefs.at(coefIndex + 1) * coskzn);
168
169 double derivCoeff = pow(kn, 2.0);
170 onAxisFieldPP[zStepIndex] +=
171 derivCoeff
172 * (-fourierCoefs.at(coefIndex) * coskzn + fourierCoefs.at(coefIndex + 1) * sinkzn);
173 derivCoeff *= kn;
174 onAxisFieldPPP[zStepIndex] +=
175 derivCoeff
176 * (fourierCoefs.at(coefIndex) * sinkzn + fourierCoefs.at(coefIndex + 1) * coskzn);
177
178 coefIndex += 2;
179 }
180 }
181}
182
185 std::vector<double> fieldComponents) const {
186 double radiusSq = pow(R(0), 2.0) + pow(R(1), 2.0);
187 double transverseEFactor =
188 (fieldComponents.at(1) * (0.5 - radiusSq * twoPiOverLambdaSq_m / 16.0)
189 - radiusSq * fieldComponents.at(3) / 16.0);
190 double transverseBFactor =
191 ((fieldComponents.at(0) * (0.5 - radiusSq * twoPiOverLambdaSq_m / 16.0)
192 - radiusSq * fieldComponents.at(2) / 16.0)
194
195 E(0) += -R(0) * transverseEFactor;
196 E(1) += -R(1) * transverseEFactor;
197 E(2) +=
198 (fieldComponents.at(0) * (1.0 - radiusSq * twoPiOverLambdaSq_m / 4.0)
199 - radiusSq * fieldComponents.at(2) / 4.0);
200
201 B(0) += -R(1) * transverseBFactor;
202 B(1) += R(0) * transverseBFactor;
203}
204
205void FM1DDynamic_fast::computeFieldOnAxis(double z, std::vector<double>& fieldComponents) const {
206 fieldComponents.push_back(gsl_spline_eval(onAxisFieldInterpolants_m, z, onAxisFieldAccel_m));
207 fieldComponents.push_back(gsl_spline_eval(onAxisFieldPInterpolants_m, z, onAxisFieldPAccel_m));
208 fieldComponents.push_back(
210 fieldComponents.push_back(
212}
213
214std::vector<double> FM1DDynamic_fast::computeFourierCoefficients(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
219 // Reflect field about minimum z value to ensure that it is periodic.
220 double* fieldDataReflected = new double[totalSize];
221 for (unsigned int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++dataIndex) {
222 fieldDataReflected[numberOfGridPoints_m - 1 + dataIndex] = fieldData[dataIndex];
223 if (dataIndex != 0)
224 fieldDataReflected[numberOfGridPoints_m - 1 - dataIndex] = fieldData[dataIndex];
225 }
226
227 gsl_fft_real_transform(fieldDataReflected, 1, totalSize, waveTable, workSpace);
228
229 std::vector<double> fourierCoefs;
230 fourierCoefs.push_back(fieldDataReflected[0] / totalSize);
231 for (unsigned int coefIndex = 1; coefIndex < 2 * accuracy_m - 1; ++coefIndex)
232 fourierCoefs.push_back(2.0 * fieldDataReflected[coefIndex] / totalSize);
233
234 delete[] fieldDataReflected;
235 gsl_fft_real_workspace_free(workSpace);
236 gsl_fft_real_wavetable_free(waveTable);
237
238 return fourierCoefs;
239}
240
242 double onAxisFieldP[], double onAxisFieldPP[], double onAxisFieldPPP[]) {
243 onAxisFieldInterpolants_m = gsl_spline_alloc(gsl_interp_cspline, numberOfGridPoints_m);
244 onAxisFieldPInterpolants_m = gsl_spline_alloc(gsl_interp_cspline, numberOfGridPoints_m);
245 onAxisFieldPPInterpolants_m = gsl_spline_alloc(gsl_interp_cspline, numberOfGridPoints_m);
246 onAxisFieldPPPInterpolants_m = gsl_spline_alloc(gsl_interp_cspline, numberOfGridPoints_m);
247
248 double* z = new double[numberOfGridPoints_m];
249 for (unsigned int zStepIndex = 0; zStepIndex < numberOfGridPoints_m; ++zStepIndex)
250 z[zStepIndex] = deltaZ_m * zStepIndex;
252 gsl_spline_init(onAxisFieldPInterpolants_m, z, onAxisFieldP, numberOfGridPoints_m);
253 gsl_spline_init(onAxisFieldPPInterpolants_m, z, onAxisFieldPP, numberOfGridPoints_m);
254 gsl_spline_init(onAxisFieldPPPInterpolants_m, z, onAxisFieldPPP, numberOfGridPoints_m);
255
256 onAxisFieldAccel_m = gsl_interp_accel_alloc();
257 onAxisFieldPAccel_m = gsl_interp_accel_alloc();
258 onAxisFieldPPAccel_m = gsl_interp_accel_alloc();
259 onAxisFieldPPPAccel_m = gsl_interp_accel_alloc();
260
261 delete[] z;
262}
263
265 // Convert to angular frequency in Hz.
267
268 // Convert to m.
273
275}
276
277void FM1DDynamic_fast::normalizeField(double maxEz, std::vector<double>& fourierCoefs) {
278 for (unsigned int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++dataIndex)
279 onAxisField_m[dataIndex] /= (maxEz * Units::Vpm2MVpm);
280
281 for (std::vector<double>::iterator fourierIterator = fourierCoefs.begin();
282 fourierIterator < fourierCoefs.end(); ++fourierIterator)
283 *fourierIterator /= (maxEz * Units::Vpm2MVpm);
284}
285
286double FM1DDynamic_fast::readFileData(std::ifstream& fieldFile, double fieldData[]) {
287 double maxEz = 0.0;
288 for (unsigned int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++dataIndex) {
289 interpretLine<double>(fieldFile, fieldData[dataIndex]);
290 if (std::abs(fieldData[dataIndex]) > maxEz)
291 maxEz = std::abs(fieldData[dataIndex]);
292 }
293
294 if (!normalize_m)
295 maxEz = 1.0;
296
297 return maxEz;
298}
299
301 std::ifstream& fieldFile, std::vector<std::pair<double, double>>& eZ) {
302 double maxEz = 0.0;
303 double deltaZ = (zEnd_m - zBegin_m) / (numberOfGridPoints_m - 1);
304 for (unsigned int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++dataIndex) {
305 eZ.at(dataIndex).first = deltaZ * dataIndex;
306 interpretLine<double>(fieldFile, eZ.at(dataIndex).second);
307 if (std::abs(eZ.at(dataIndex).second) > maxEz)
308 maxEz = std::abs(eZ.at(dataIndex).second);
309 }
310
311 if (!normalize_m)
312 maxEz = 1.0;
313
314 return maxEz;
315}
316
317bool FM1DDynamic_fast::readFileHeader(std::ifstream& fieldFile) {
318 std::string tempString;
319 int tempInt;
320
321 bool parsingPassed = true;
322 try {
323 parsingPassed = interpretLine<std::string, unsigned int>(fieldFile, tempString, accuracy_m);
324 } catch (GeneralClassicException& e) {
326 fieldFile, tempString, accuracy_m, tempString);
327
328 tempString = Util::toUpper(tempString);
329 if (tempString != "TRUE" && tempString != "FALSE")
331 "FM1DDynamic_fast::readFileHeader",
332 "The third string on the first line of 1D field "
333 "maps has to be either TRUE or FALSE");
334
335 normalize_m = (tempString == "TRUE");
336 }
337 parsingPassed = parsingPassed
340 parsingPassed = parsingPassed && interpretLine<double>(fieldFile, frequency_m);
341 parsingPassed =
342 parsingPassed && interpretLine<double, double, int>(fieldFile, rBegin_m, rEnd_m, tempInt);
343
345
348
349 return parsingPassed;
350}
351
352void FM1DDynamic_fast::scaleField(double maxEz, std::vector<std::pair<double, double>>& eZ) {
353 if (!normalize_m)
354 return;
355
356 for (unsigned int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++dataIndex)
357 eZ.at(dataIndex).second /= maxEz;
358}
359
360void FM1DDynamic_fast::stripFileHeader(std::ifstream& fieldFile) {
361 std::string tempString;
362
363 getLine(fieldFile, tempString);
364 getLine(fieldFile, tempString);
365 getLine(fieldFile, tempString);
366 getLine(fieldFile, tempString);
367}
368
369void FM1DDynamic_fast::prepareForMapCheck(std::vector<double>& fourierCoefs) {
370 std::vector<double> zSampling(numberOfGridPoints_m);
371 for (unsigned int zStepIndex = 0; zStepIndex < numberOfGridPoints_m; ++zStepIndex)
372 zSampling[zStepIndex] = deltaZ_m * zStepIndex;
373
374 checkMap(
375 accuracy_m, length_m, zSampling, fourierCoefs, onAxisFieldInterpolants_m,
377}
ippl::Vector< T, Dim > Vector_t
@ T1DDynamic
Definition Fieldmap.h:17
DiffDirection
Definition Fieldmap.h:55
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:145
MapType Type
Definition Fieldmap.h:118
bool interpreteEOF(std::ifstream &in)
Definition Fieldmap.cpp:516
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:413
void disableFieldmapWarning()
Definition Fieldmap.cpp:569
bool normalize_m
Definition Fieldmap.h:123
static std::string typeset_msg(const std::string &msg, const std::string &title)
Definition Fieldmap.cpp:607
std::string Filename_m
Definition Fieldmap.h:120
bool interpretLine(std::ifstream &in, S &value, const bool &file_length_known=true)
void getLine(std::ifstream &in, std::string &buffer)
Definition Fieldmap.h:124
void noFieldmapWarning()
Definition Fieldmap.cpp:576
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 computeFieldOffAxis(const Vector_t< double, 3 > &R, Vector_t< double, 3 > &E, Vector_t< double, 3 > &B, std::vector< double > fieldComponents) const
void stripFileHeader(std::ifstream &fieldFile)
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
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.
friend class Fieldmap
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 getOnaxisEz(std::vector< std::pair< double, double > > &eZ)
void computeInterpolationVectors(double onAxisFieldP[], double onAxisFieldPP[], double onAxisFieldPPP[])
virtual bool getFieldstrength(const Vector_t< double, 3 > &R, Vector_t< double, 3 > &E, Vector_t< double, 3 > &B) const
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[])
gsl_spline * onAxisFieldPPInterpolants_m
On axis field first derivative interpolation structure.
virtual void freeMap()
virtual bool getFieldDerivative(const Vector_t< double, 3 > &R, Vector_t< double, 3 > &E, Vector_t< double, 3 > &B, const DiffDirection &dir) const
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).