OPAL (Object Oriented Parallel Accelerator Library) 2024.2
OPAL
FM1DMagnetoStatic.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
13_FM1DMagnetoStatic::_FM1DMagnetoStatic(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 } else {
35 zBegin_m = 0.0;
36 zEnd_m = -1.0e-3;
37 }
38}
39
43
45{
46 return FM1DMagnetoStatic(new _FM1DMagnetoStatic(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 maxBz = readFileData(fieldFile, fieldData);
58 fieldFile.close();
59 computeFourierCoefficients(maxBz, fieldData);
60 delete [] fieldData;
61
62 INFOMSG(level3 << typeset_msg("read in fieldmap '" + Filename_m + "'", "info")
63 << endl);
64 }
65}
66
68
69 if(!fourierCoefs_m.empty()) {
70 fourierCoefs_m.clear();
71 }
72}
73
75 Vector_t &B) const {
76
77 std::vector<double> fieldComponents;
78 computeFieldOnAxis(R(2) - zBegin_m, fieldComponents);
79 computeFieldOffAxis(R, E, B, fieldComponents);
80
81 return false;
82}
83
85 Vector_t &/*E*/,
86 Vector_t &B,
87 const DiffDirection &/*dir*/) const {
88
89 double kz = Physics::two_pi * (R(2) - zBegin_m) / length_m + Physics::pi;
90 double bZPrime = 0.0;
91
92 int coefIndex = 1;
93 for(int n = 1; n < accuracy_m; n++) {
94
95 bZPrime += n * Physics::two_pi / length_m
96 * (-fourierCoefs_m.at(coefIndex) * sin(kz * n)
97 - fourierCoefs_m.at(coefIndex + 1) * cos(kz * n));
98 coefIndex += 2;
99
100 }
101
102 B(2) += bZPrime;
103
104 return false;
105}
106
107void _FM1DMagnetoStatic::getFieldDimensions(double &zBegin, double &zEnd) const {
108 zBegin = zBegin_m;
109 zEnd = zEnd_m;
110}
111void _FM1DMagnetoStatic::getFieldDimensions(double &/*xIni*/, double &/*xFinal*/,
112 double &/*yIni*/, double &/*yFinal*/,
113 double &/*zIni*/, double &/*zFinal*/) const {
114}
115
118
120 (*msg) << Filename_m
121 << " (1D magnetostatic); zini= "
122 << zBegin_m << " m; zfinal= "
123 << zEnd_m << " m;" << endl;
124}
125
127 return 0.0;
128}
129
131{ }
132
133bool _FM1DMagnetoStatic::checkFileData(std::ifstream &fieldFile,
134 bool parsingPassed) {
135
136 double tempDouble;
137 for(int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++ dataIndex)
138 parsingPassed = parsingPassed
139 && interpretLine<double>(fieldFile, tempDouble);
140
141 return parsingPassed && interpreteEOF(fieldFile);
142
143}
144
146 Vector_t &/*E*/,
147 Vector_t &B,
148 std::vector<double> fieldComponents) const {
149
150 double radiusSq = pow(R(0), 2.0) + pow(R(1), 2.0);
151 double transverseBFactor = -fieldComponents.at(1) / 2.0
152 + radiusSq * fieldComponents.at(3) / 16.0;
153
154 B(0) += R(0) * transverseBFactor;
155 B(1) += R(1) * transverseBFactor;
156 B(2) += fieldComponents.at(0) - fieldComponents.at(2) * radiusSq / 4.0;
157
158}
159
161 std::vector<double> &fieldComponents) const {
162
163 double kz = Physics::two_pi * z / length_m + Physics::pi;
164 fieldComponents.push_back(fourierCoefs_m.at(0));
165 fieldComponents.push_back(0.0);
166 fieldComponents.push_back(0.0);
167 fieldComponents.push_back(0.0);
168
169 int coefIndex = 1;
170 for(int n = 1; n < accuracy_m; n++) {
171
172 double kn = n * Physics::two_pi / length_m;
173 double coskzn = cos(kz * n);
174 double sinkzn = sin(kz * n);
175
176 fieldComponents.at(0) += fourierCoefs_m.at(coefIndex) * coskzn
177 - fourierCoefs_m.at(coefIndex + 1) * sinkzn;
178
179 fieldComponents.at(1) += kn * (-fourierCoefs_m.at(coefIndex) * sinkzn
180 - fourierCoefs_m.at(coefIndex + 1) * coskzn);
181
182 double derivCoeff = pow(kn, 2.0);
183 fieldComponents.at(2) += derivCoeff * (-fourierCoefs_m.at(coefIndex) * coskzn
184 + fourierCoefs_m.at(coefIndex + 1) * sinkzn);
185 derivCoeff *= kn;
186 fieldComponents.at(3) += derivCoeff * (fourierCoefs_m.at(coefIndex) * sinkzn
187 + fourierCoefs_m.at(coefIndex + 1) * coskzn);
188
189 coefIndex += 2;
190 }
191}
192
194 double fieldData[]) {
195 const unsigned int totalSize = 2 * numberOfGridPoints_m - 1;
196 gsl_fft_real_wavetable *waveTable = gsl_fft_real_wavetable_alloc(totalSize);
197 gsl_fft_real_workspace *workSpace = gsl_fft_real_workspace_alloc(totalSize);
198
199 gsl_fft_real_transform(fieldData, 1, totalSize, waveTable, workSpace);
200
201 /*
202 * Normalize the Fourier coefficients such that the max field
203 * value is 1 V/m.
204 */
205
206 fourierCoefs_m.push_back(fieldData[0] / (totalSize * maxBz));
207 for(int coefIndex = 1; coefIndex < 2 * accuracy_m - 1; coefIndex++)
208 fourierCoefs_m.push_back(2.0 * fieldData[coefIndex] / (totalSize * maxBz));
209
210 gsl_fft_real_workspace_free(workSpace);
211 gsl_fft_real_wavetable_free(waveTable);
212
213}
214
216
217 // Convert to m.
222}
223
224double _FM1DMagnetoStatic::readFileData(std::ifstream &fieldFile,
225 double fieldData[]) {
226
227 double maxBz = 0.0;
228 for(int dataIndex = 0; dataIndex < numberOfGridPoints_m; dataIndex++) {
230 - 1 + dataIndex]);
231 if(std::abs(fieldData[numberOfGridPoints_m + dataIndex]) > maxBz)
232 maxBz = std::abs(fieldData[numberOfGridPoints_m + dataIndex]);
233
234 /*
235 * Mirror the field map about minimum z value to ensure that
236 * it is periodic.
237 */
238 if(dataIndex != 0)
239 fieldData[numberOfGridPoints_m - 1 - dataIndex]
240 = fieldData[numberOfGridPoints_m + dataIndex];
241 }
242
243 if (!normalize_m)
244 maxBz = 1.0;
245
246 return maxBz;
247}
248
249bool _FM1DMagnetoStatic::readFileHeader(std::ifstream &fieldFile) {
250
251 std::string tempString;
252 int tempInt;
253
254 bool parsingPassed = true;
255 try {
256 parsingPassed = interpretLine<std::string, int>(fieldFile,
257 tempString,
258 accuracy_m);
259 } catch (GeneralClassicException &e) {
260 parsingPassed = interpretLine<std::string, int, std::string>(fieldFile,
261 tempString,
263 tempString);
264
265 tempString = Util::toUpper(tempString);
266 if (tempString != "TRUE" &&
267 tempString != "FALSE")
268 throw GeneralClassicException("_FM1DMagnetoStatic::readFileHeader",
269 "The third string on the first line of 1D field "
270 "maps has to be either TRUE or FALSE");
271
272 normalize_m = (tempString == "TRUE");
273 }
274 parsingPassed = parsingPassed &&
276 zEnd_m,
278 parsingPassed = parsingPassed &&
280 rEnd_m, tempInt);
281
283
286
287 return parsingPassed;
288}
289
290void _FM1DMagnetoStatic::stripFileHeader(std::ifstream &fieldFile) {
291
292 std::string tempString;
293
294 getLine(fieldFile, tempString);
295 getLine(fieldFile, tempString);
296 getLine(fieldFile, tempString);
297}
std::shared_ptr< _FM1DMagnetoStatic > FM1DMagnetoStatic
@ T1DMagnetoStatic
Definition Fieldmap.h:21
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
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 pi
The value of.
Definition Physics.h:30
constexpr double cm2m
Definition Units.h:35
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
virtual bool getFieldDerivative(const Vector_t &R, Vector_t &E, Vector_t &B, const DiffDirection &dir) const
friend class _Fieldmap
Fourier coefficients derived from field map.
virtual void getInfo(Inform *)
virtual void setFrequency(double freq)
virtual void getFieldDimensions(double &zBegin, double &zEnd) const
int numberOfGridPoints_m
Field length.
double rEnd_m
Minimum radius of field.
void computeFourierCoefficients(double maxEz, double fieldData[])
virtual bool getFieldstrength(const Vector_t &R, Vector_t &E, Vector_t &B) const
void stripFileHeader(std::ifstream &fieldFile)
int accuracy_m
Number of grid points in field input file.
virtual double getFrequency() const
double length_m
Longitudinal end of field.
bool readFileHeader(std::ifstream &fieldFile)
bool checkFileData(std::ifstream &fieldFile, bool parsingPassed)
static FM1DMagnetoStatic create(const std::string &filename)
double readFileData(std::ifstream &fieldFile, double fieldData[])
void computeFieldOnAxis(double z, std::vector< double > &fieldComponents) const
std::vector< double > fourierCoefs_m
Number of Fourier coefficients to use reconstructing field.
_FM1DMagnetoStatic(const std::string &filename)
double zBegin_m
Maximum radius of field.
double zEnd_m
Longitudinal start of field.
void computeFieldOffAxis(const Vector_t &R, Vector_t &E, Vector_t &B, std::vector< double > fieldComponents) const
Vektor< double, 3 > Vector_t