OPAL (Object Oriented Parallel Accelerator Library) 2024.2
OPAL
FM1DElectroStatic.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_FM1DElectroStatic::_FM1DElectroStatic(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
32 / (numberOfGridPoints_m - 1));
33 } else {
35 zBegin_m = 0.0;
36 zEnd_m = -1.0e-3;
37 }
38}
39
43
45{
46 return FM1DElectroStatic(new _FM1DElectroStatic(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(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 eZPrime = 0.0;
91
92 int coefIndex = 1;
93 for (int n = 1; n < accuracy_m; ++ n) {
94
95 eZPrime += 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 E(2) += eZPrime;
103
104 return false;
105}
106
107void _FM1DElectroStatic::getFieldDimensions(double &zBegin, double &zEnd) const {
108 zBegin = zBegin_m;
109 zEnd = zEnd_m;
110}
111void _FM1DElectroStatic::getFieldDimensions(double &/*xIni*/, double &/*xFinal*/,
112 double &/*yIni*/, double &/*yFinal*/,
113 double &/*zIni*/, double &/*zFinal*/) const {}
114
117
119 (*msg) << Filename_m
120 << " (1D electrostatic); zini= "
121 << zBegin_m << " m; zfinal= "
122 << zEnd_m << " m;" << endl;
123}
124
126 return 0.0;
127}
128
130{ }
131
132bool _FM1DElectroStatic::checkFileData(std::ifstream &fieldFile,
133 bool parsingPassed) {
134
135 double tempDouble;
136 for (int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++ dataIndex)
137 parsingPassed = parsingPassed
138 && interpretLine<double>(fieldFile, tempDouble);
139
140 return parsingPassed && interpreteEOF(fieldFile);
141
142}
143
145 Vector_t &E,
146 Vector_t &/*B*/,
147 std::vector<double> fieldComponents) const {
148
149 double radiusSq = pow(R(0), 2.0) + pow(R(1), 2.0);
150 double transverseEFactor = -fieldComponents.at(1) / 2.0
151 + radiusSq * fieldComponents.at(3) / 16.0;
152
153 E(0) += R(0) * transverseEFactor;
154 E(1) += R(1) * transverseEFactor;
155 E(2) += fieldComponents.at(0) - fieldComponents.at(2) * radiusSq / 4.0;
156
157}
158
160 std::vector<double> &fieldComponents) const {
161
162 double kz = Physics::two_pi * z / length_m + Physics::pi;
163 fieldComponents.push_back(fourierCoefs_m.at(0));
164 fieldComponents.push_back(0.0);
165 fieldComponents.push_back(0.0);
166 fieldComponents.push_back(0.0);
167
168 int coefIndex = 1;
169 for (int n = 1; n < accuracy_m; ++ n) {
170
171 double kn = n * Physics::two_pi / length_m;
172 double coskzn = cos(kz * n);
173 double sinkzn = sin(kz * n);
174
175 fieldComponents.at(0) += fourierCoefs_m.at(coefIndex) * coskzn
176 - fourierCoefs_m.at(coefIndex + 1) * sinkzn;
177
178 fieldComponents.at(1) += kn * (-fourierCoefs_m.at(coefIndex) * sinkzn
179 - fourierCoefs_m.at(coefIndex + 1) * coskzn);
180
181 double derivCoeff = pow(kn, 2.0);
182 fieldComponents.at(2) += derivCoeff * (-fourierCoefs_m.at(coefIndex) * coskzn
183 + fourierCoefs_m.at(coefIndex + 1) * sinkzn);
184 derivCoeff *= kn;
185 fieldComponents.at(3) += derivCoeff * (fourierCoefs_m.at(coefIndex) * sinkzn
186 + fourierCoefs_m.at(coefIndex + 1) * coskzn);
187
188 coefIndex += 2;
189 }
190}
191
193 double fieldData[]) {
194 const unsigned int totalSize = 2 * numberOfGridPoints_m - 1;
195 gsl_fft_real_wavetable *waveTable = gsl_fft_real_wavetable_alloc(totalSize);
196 gsl_fft_real_workspace *workSpace = gsl_fft_real_workspace_alloc(totalSize);
197
198 gsl_fft_real_transform(fieldData, 1, totalSize, waveTable, workSpace);
199
200 /*
201 * Normalize the Fourier coefficients such that the max field
202 * value is 1 V/m.
203 */
204
205 fourierCoefs_m.push_back(fieldData[0] / (totalSize * maxEz * Units::Vpm2MVpm));
206 for (int coefIndex = 1; coefIndex < 2 * accuracy_m - 1; ++ coefIndex)
207 fourierCoefs_m.push_back(2.0 * fieldData[coefIndex] / (totalSize * maxEz * Units::Vpm2MVpm));
208
209 gsl_fft_real_workspace_free(workSpace);
210 gsl_fft_real_wavetable_free(waveTable);
211
212}
213
215
216 // Convert to m.
221}
222
223double _FM1DElectroStatic::readFileData(std::ifstream &fieldFile,
224 double fieldData[]) {
225
226 double maxEz = 0.0;
227 for (int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++ dataIndex) {
228 interpretLine<double>(fieldFile,
229 fieldData[numberOfGridPoints_m - 1 + dataIndex]);
230 if (std::abs(fieldData[numberOfGridPoints_m + dataIndex]) > maxEz)
231 maxEz = std::abs(fieldData[numberOfGridPoints_m + dataIndex]);
232
233 /*
234 * Mirror the field map about minimum z value to ensure that
235 * it is periodic.
236 */
237 if (dataIndex != 0)
238 fieldData[numberOfGridPoints_m - 1 - dataIndex]
239 = fieldData[numberOfGridPoints_m + dataIndex];
240 }
241
242 if (!normalize_m)
243 maxEz = 1.0;
244
245 return maxEz;
246}
247
248bool _FM1DElectroStatic::readFileHeader(std::ifstream &fieldFile) {
249
250 std::string tempString;
251 int tempInt;
252
253 bool parsingPassed = true;
254 try {
255 parsingPassed = interpretLine<std::string, int>(fieldFile,
256 tempString,
257 accuracy_m);
258 } catch (GeneralClassicException &e) {
259 parsingPassed = interpretLine<std::string, int, std::string>(fieldFile,
260 tempString,
262 tempString);
263
264 tempString = Util::toUpper(tempString);
265 if (tempString != "TRUE" &&
266 tempString != "FALSE")
267 throw GeneralClassicException("_FM1DElectroStatic::readFileHeader",
268 "The third string on the first line of 1D field "
269 "maps has to be either TRUE or FALSE");
270
271 normalize_m = (tempString == "TRUE");
272 }
273
274 parsingPassed = parsingPassed &&
276 zBegin_m,
277 zEnd_m,
279 parsingPassed = parsingPassed &&
281 rEnd_m, tempInt);
282
284
287
288 return parsingPassed;
289}
290
291void _FM1DElectroStatic::stripFileHeader(std::ifstream &fieldFile) {
292
293 std::string tempString;
294
295 getLine(fieldFile, tempString);
296 getLine(fieldFile, tempString);
297 getLine(fieldFile, tempString);
298}
std::shared_ptr< _FM1DElectroStatic > FM1DElectroStatic
@ T1DElectroStatic
Definition Fieldmap.h:19
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
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
friend class _Fieldmap
Fourier coefficients derived from field map.
virtual bool getFieldstrength(const Vector_t &R, Vector_t &E, Vector_t &B) const
double rEnd_m
Minimum radius of field.
double length_m
Longitudinal end of field.
virtual void getInfo(Inform *)
void computeFourierCoefficients(double maxEz, double fieldData[])
void stripFileHeader(std::ifstream &fieldFile)
virtual void getFieldDimensions(double &zBegin, double &zEnd) const
double zBegin_m
Maximum radius of field.
double readFileData(std::ifstream &fieldFile, double fieldData[])
bool readFileHeader(std::ifstream &fieldFile)
double zEnd_m
Longitudinal start of field.
virtual double getFrequency() const
std::vector< double > fourierCoefs_m
Number of Fourier coefficients to use reconstructing field.
bool checkFileData(std::ifstream &fieldFile, bool parsingPassed)
void computeFieldOnAxis(double z, std::vector< double > &fieldComponents) const
_FM1DElectroStatic(const std::string &filename)
int numberOfGridPoints_m
Field length.
virtual bool getFieldDerivative(const Vector_t &R, Vector_t &E, Vector_t &B, const DiffDirection &dir) const
virtual void setFrequency(double freq)
int accuracy_m
Number of grid points in field input file.
static FM1DElectroStatic create(const std::string &filename)
void computeFieldOffAxis(const Vector_t &R, Vector_t &E, Vector_t &B, std::vector< double > fieldComponents) const
Vektor< double, 3 > Vector_t