OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
FM1DMagnetoStatic_fast.cpp
Go to the documentation of this file.
2#include "Fields/Fieldmap.hpp"
3#include "Physics/Physics.h"
4#include "Physics/Units.h"
5#include "Utilities/Util.h"
7
8#include "gsl/gsl_fft_real.h"
9
10#include <fstream>
11#include <ios>
12
14 Fieldmap(aFilename) {
15
17 onAxisField_m = nullptr;
18
19 std::ifstream fieldFile(Filename_m.c_str());
20 if(fieldFile.good()) {
21
22 bool parsingPassed = readFileHeader(fieldFile);
23 parsingPassed = checkFileData(fieldFile, parsingPassed);
24 fieldFile.close();
25
26 if(!parsingPassed) {
28 zEnd_m = zBegin_m - 1.0e-3;
29 } else
31
34
35 } else {
37 zBegin_m = 0.0;
38 zEnd_m = -1.0e-3;
39 }
40}
41
43 freeMap();
44}
45
47
48 if(onAxisField_m == nullptr) {
49
50 std::ifstream fieldFile(Filename_m.c_str());
51 stripFileHeader(fieldFile);
52
54 double maxBz = readFileData(fieldFile, onAxisField_m);
55 fieldFile.close();
56
57 std::vector<double> fourierCoefs
59 normalizeField(maxBz, fourierCoefs);
60
61 double *onAxisFieldP = new double[numberOfGridPoints_m];
62 double *onAxisFieldPP = new double[numberOfGridPoints_m];
63 double *onAxisFieldPPP = new double[numberOfGridPoints_m];
64 computeFieldDerivatives(fourierCoefs, onAxisFieldP,
65 onAxisFieldPP, onAxisFieldPPP);
66 computeInterpolationVectors(onAxisFieldP, onAxisFieldPP,
67 onAxisFieldPPP);
68
69 prepareForMapCheck(fourierCoefs);
70
71 delete [] onAxisFieldP;
72 delete [] onAxisFieldPP;
73 delete [] onAxisFieldPPP;
74
75 INFOMSG(level3 << typeset_msg("read in fieldmap '" + Filename_m + "'", "info")
76 << endl);
77 }
78}
79
81 if(onAxisField_m != nullptr) {
82 delete [] onAxisField_m;
83 onAxisField_m = nullptr;
84
85 gsl_spline_free(onAxisFieldInterpolants_m);
86 gsl_spline_free(onAxisFieldPInterpolants_m);
87 gsl_spline_free(onAxisFieldPPInterpolants_m);
88 gsl_spline_free(onAxisFieldPPPInterpolants_m);
89 gsl_interp_accel_free(onAxisFieldAccel_m);
90 gsl_interp_accel_free(onAxisFieldPAccel_m);
91 gsl_interp_accel_free(onAxisFieldPPAccel_m);
92 gsl_interp_accel_free(onAxisFieldPPPAccel_m);
93
94 INFOMSG(level3 << typeset_msg("freed fieldmap '" + Filename_m + "'", "info")
95 << endl);
96 }
97}
98
100 Vector_t &B) const {
101
102 std::vector<double> fieldComponents;
103 computeFieldOnAxis(R(2) - zBegin_m, fieldComponents);
104 computeFieldOffAxis(R, E, B, fieldComponents);
105
106 return false;
107
108}
109
111 Vector_t &/*E*/,
112 Vector_t &B,
113 const DiffDirection &/*dir*/) const {
114
115 B(2) += gsl_spline_eval(onAxisFieldPInterpolants_m, R(2) - zBegin_m,
117
118 return false;
119
120}
121
122void FM1DMagnetoStatic_fast::getFieldDimensions(double &zBegin, double &zEnd) const {
123 zBegin = zBegin_m;
124 zEnd = zEnd_m;
125}
126
127void FM1DMagnetoStatic_fast::getFieldDimensions(double &/*xIni*/, double &/*xFinal*/,
128 double &/*yIni*/, double &/*yFinal*/,
129 double &/*zIni*/, double &/*zFinal*/) const {}
130
132{ }
133
135 (*msg) << Filename_m
136 << " (1D magnetostatic); zini= "
137 << zBegin_m << " m; zfinal= "
138 << zEnd_m << " m;" << endl;
139}
140
142 return 0.0;
143}
144
146{ }
147
148bool FM1DMagnetoStatic_fast::checkFileData(std::ifstream &fieldFile,
149 bool parsingPassed) {
150
151 double tempDouble;
152 for (unsigned int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++ dataIndex)
153 parsingPassed = parsingPassed
154 && interpretLine<double>(fieldFile, tempDouble);
155
156 return parsingPassed && interpreteEOF(fieldFile);
157
158}
159
160void FM1DMagnetoStatic_fast::computeFieldDerivatives(std::vector<double> fourierCoefs,
161 double onAxisFieldP[],
162 double onAxisFieldPP[],
163 double onAxisFieldPPP[]) {
164
165 for (unsigned int zStepIndex = 0; zStepIndex < numberOfGridPoints_m; ++ zStepIndex) {
166
167 double z = deltaZ_m * zStepIndex;
168 double kz = Physics::two_pi * z / length_m + Physics::pi;
169 onAxisFieldP[zStepIndex] = 0.0;
170 onAxisFieldPP[zStepIndex] = 0.0;
171 onAxisFieldPPP[zStepIndex] = 0.0;
172
173 int coefIndex = 1;
174 for (unsigned int n = 1; n < accuracy_m; ++ n) {
175
176 double kn = n * Physics::two_pi / length_m;
177 double coskzn = cos(kz * n);
178 double sinkzn = sin(kz * n);
179
180 onAxisFieldP[zStepIndex] += kn * (-fourierCoefs.at(coefIndex) * sinkzn
181 - fourierCoefs.at(coefIndex + 1) * coskzn);
182
183 double derivCoeff = pow(kn, 2.0);
184 onAxisFieldPP[zStepIndex] += derivCoeff * (-fourierCoefs.at(coefIndex) * coskzn
185 + fourierCoefs.at(coefIndex + 1) * sinkzn);
186 derivCoeff *= kn;
187 onAxisFieldPPP[zStepIndex] += derivCoeff * (fourierCoefs.at(coefIndex) * sinkzn
188 + fourierCoefs.at(coefIndex + 1) * coskzn);
189
190 coefIndex += 2;
191 }
192 }
193}
194
196 Vector_t &/*E*/,
197 Vector_t &B,
198 std::vector<double> fieldComponents) const {
199
200 double radiusSq = pow(R(0), 2.0) + pow(R(1), 2.0);
201 double transverseBFactor = -fieldComponents.at(1) / 2.0
202 + radiusSq * fieldComponents.at(3) / 16.0;
203
204 B(0) += R(0) * transverseBFactor;
205 B(1) += R(1) * transverseBFactor;
206 B(2) += fieldComponents.at(0) - fieldComponents.at(2) * radiusSq / 4.0;
207
208}
209
211 std::vector<double> &fieldComponents) const {
212
213 fieldComponents.push_back(gsl_spline_eval(onAxisFieldInterpolants_m,
215 fieldComponents.push_back(gsl_spline_eval(onAxisFieldPInterpolants_m,
217 fieldComponents.push_back(gsl_spline_eval(onAxisFieldPPInterpolants_m,
219 fieldComponents.push_back(gsl_spline_eval(onAxisFieldPPPInterpolants_m,
221}
222
223std::vector<double> FM1DMagnetoStatic_fast::computeFourierCoefficients(double fieldData[]) {
224
225 const unsigned int totalSize = 2 * numberOfGridPoints_m - 1;
226 gsl_fft_real_wavetable *waveTable = gsl_fft_real_wavetable_alloc(totalSize);
227 gsl_fft_real_workspace *workSpace = gsl_fft_real_workspace_alloc(totalSize);
228
229 // Reflect field about minimum z value to ensure that it is periodic.
230 double *fieldDataReflected = new double[totalSize];
231 for (unsigned int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++ dataIndex) {
232 fieldDataReflected[numberOfGridPoints_m - 1 + dataIndex]
233 = fieldData[dataIndex];
234 if(dataIndex != 0)
235 fieldDataReflected[numberOfGridPoints_m - 1 - dataIndex]
236 = fieldData[dataIndex];
237 }
238
239 gsl_fft_real_transform(fieldDataReflected, 1, totalSize, waveTable, workSpace);
240
241 std::vector<double> fourierCoefs;
242 fourierCoefs.push_back(fieldDataReflected[0] / totalSize);
243 for (unsigned int coefIndex = 1; coefIndex + 1 < 2 * accuracy_m; ++ coefIndex)
244 fourierCoefs.push_back(2.0 * fieldDataReflected[coefIndex] / totalSize);
245
246 delete [] fieldDataReflected;
247 gsl_fft_real_workspace_free(workSpace);
248 gsl_fft_real_wavetable_free(waveTable);
249
250 return fourierCoefs;
251
252}
253
255 double onAxisFieldPP[],
256 double onAxisFieldPPP[]) {
257
258 onAxisFieldInterpolants_m = gsl_spline_alloc(gsl_interp_cspline,
260 onAxisFieldPInterpolants_m = gsl_spline_alloc(gsl_interp_cspline,
262 onAxisFieldPPInterpolants_m = gsl_spline_alloc(gsl_interp_cspline,
264 onAxisFieldPPPInterpolants_m = gsl_spline_alloc(gsl_interp_cspline,
266
267 double *z = new double[numberOfGridPoints_m];
268 for (unsigned int zStepIndex = 0; zStepIndex < numberOfGridPoints_m; ++ zStepIndex)
269 z[zStepIndex] = deltaZ_m * zStepIndex;
270
271 gsl_spline_init(onAxisFieldInterpolants_m, z,
273 gsl_spline_init(onAxisFieldPInterpolants_m, z,
274 onAxisFieldP, numberOfGridPoints_m);
275 gsl_spline_init(onAxisFieldPPInterpolants_m, z,
276 onAxisFieldPP, numberOfGridPoints_m);
277 gsl_spline_init(onAxisFieldPPPInterpolants_m, z,
278 onAxisFieldPPP, numberOfGridPoints_m);
279
280 onAxisFieldAccel_m = gsl_interp_accel_alloc();
281 onAxisFieldPAccel_m = gsl_interp_accel_alloc();
282 onAxisFieldPPAccel_m = gsl_interp_accel_alloc();
283 onAxisFieldPPPAccel_m = gsl_interp_accel_alloc();
284
285 delete [] z;
286}
287
289
290 // Convert to m.
295}
296
297void FM1DMagnetoStatic_fast::normalizeField(double maxBz, std::vector<double> &fourierCoefs) {
298 if (!normalize_m) return;
299
300 for (unsigned int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++ dataIndex)
301 onAxisField_m[dataIndex] /= maxBz;
302
303 for (std::vector<double>::iterator fourierIterator = fourierCoefs.begin();
304 fourierIterator < fourierCoefs.end(); ++ fourierIterator)
305 *fourierIterator /= maxBz;
306
307}
308
309double FM1DMagnetoStatic_fast::readFileData(std::ifstream &fieldFile,
310 double fieldData[]) {
311
312 double maxBz = 0.0;
313 for (unsigned int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++ dataIndex) {
314 interpretLine<double>(fieldFile, fieldData[dataIndex]);
315 if(std::abs(fieldData[dataIndex]) > maxBz)
316 maxBz = std::abs(fieldData[dataIndex]);
317 }
318
319 return maxBz;
320}
321
322bool FM1DMagnetoStatic_fast::readFileHeader(std::ifstream &fieldFile) {
323
324 std::string tempString;
325 int tempInt;
326
327 bool parsingPassed = true;
328
329 try {
330 parsingPassed = interpretLine<std::string, unsigned int>(fieldFile,
331 tempString,
332 accuracy_m);
333 } catch (GeneralClassicException &e) {
334 parsingPassed = interpretLine<std::string, unsigned int, std::string>(fieldFile,
335 tempString,
337 tempString);
338
339 tempString = Util::toUpper(tempString);
340 if (tempString != "TRUE" &&
341 tempString != "FALSE")
342 throw GeneralClassicException("FM1DMagnetoStatic_fast::readFileHeader",
343 "The third string on the first line of 1D field "
344 "maps has to be either TRUE or FALSE");
345
346 normalize_m = (tempString == "TRUE");
347 }
348
349 parsingPassed = parsingPassed &&
350 interpretLine<double, double, unsigned int>(fieldFile,
351 zBegin_m,
352 zEnd_m,
354 parsingPassed = parsingPassed &&
355 interpretLine<double, double, int>(fieldFile,
356 rBegin_m,
357 rEnd_m,
358 tempInt);
359
361
364
365 return parsingPassed;
366}
367
368void FM1DMagnetoStatic_fast::stripFileHeader(std::ifstream &fieldFile) {
369
370 std::string tempString;
371
372 getLine(fieldFile, tempString);
373 getLine(fieldFile, tempString);
374 getLine(fieldFile, tempString);
375}
376
377void FM1DMagnetoStatic_fast::prepareForMapCheck(std::vector<double> &fourierCoefs) {
378 std::vector<double> zSampling(numberOfGridPoints_m);
379 for (unsigned int zStepIndex = 0; zStepIndex < numberOfGridPoints_m; ++ zStepIndex)
380 zSampling[zStepIndex] = deltaZ_m * zStepIndex;
381
383 length_m,
384 zSampling,
385 fourierCoefs,
388}
@ T1DMagnetoStatic
Definition: Fieldmap.h:20
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 pi
The value of.
Definition: Physics.h:30
constexpr double cm2m
Definition: Units.h:35
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
virtual double getFrequency() const
void computeFieldDerivatives(std::vector< double > fourierCoefs, double onAxisFieldP[], double onAxisFieldPP[], double onAxisFieldPPP[])
void computeInterpolationVectors(double onAxisFieldP[], double onAxisFieldPP[], double onAxisFieldPPP[])
gsl_interp_accel * onAxisFieldAccel_m
On axis field third derivative interpolation structure.
void stripFileHeader(std::ifstream &fieldFile)
std::vector< double > computeFourierCoefficients(double fieldData[])
virtual bool getFieldstrength(const Vector_t &R, Vector_t &E, Vector_t &B) const
bool readFileHeader(std::ifstream &fieldFile)
unsigned int accuracy_m
Field grid point spacing.
FM1DMagnetoStatic_fast(std::string aFilename)
void computeFieldOnAxis(double z, std::vector< double > &fieldComponents) const
gsl_spline * onAxisFieldPPInterpolants_m
On axis field first derivative interpolation structure.
gsl_spline * onAxisFieldPInterpolants_m
On axis field interpolation structure.
gsl_spline * onAxisFieldPPPInterpolants_m
On axis field second derivative interpolation structure.
unsigned int numberOfGridPoints_m
Field length.
double rEnd_m
Minimum radius of field.
void prepareForMapCheck(std::vector< double > &fourierCoefs)
virtual void getInfo(Inform *)
double deltaZ_m
Number of grid points in field input file.
void normalizeField(double maxBz, std::vector< double > &fourierCoefs)
double readFileData(std::ifstream &fieldFile, double fieldData[])
double zEnd_m
Longitudinal start of field.
gsl_interp_accel * onAxisFieldPAccel_m
void computeFieldOffAxis(const Vector_t &R, Vector_t &E, Vector_t &B, std::vector< double > fieldComponents) const
double length_m
Longitudinal end of field.
virtual void setFrequency(double freq)
bool checkFileData(std::ifstream &fieldFile, bool parsingPassed)
virtual void getFieldDimensions(double &zBegin, double &zEnd) const
gsl_interp_accel * onAxisFieldPPAccel_m
gsl_spline * onAxisFieldInterpolants_m
On axis field data.
gsl_interp_accel * onAxisFieldPPPAccel_m
double zBegin_m
Maximum radius of field.
virtual bool getFieldDerivative(const Vector_t &R, Vector_t &E, Vector_t &B, const DiffDirection &dir) const
Definition: Inform.h:42