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