OPALX (Object Oriented Parallel Accelerator Library for Exascal) MINIorX
OPALX
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
13FM1DElectroStatic::FM1DElectroStatic(std::string aFilename) : Fieldmap(aFilename) {
15
16 std::ifstream fieldFile(Filename_m.c_str());
17 if (fieldFile.good()) {
18 bool parsingPassed = readFileHeader(fieldFile);
19 parsingPassed = checkFileData(fieldFile, parsingPassed);
20 fieldFile.close();
21
22 if (!parsingPassed) {
24 zEnd_m = zBegin_m - 1.0e-3;
25 } else
27
29 } else {
31 zBegin_m = 0.0;
32 zEnd_m = -1.0e-3;
33 }
34}
35
39
41 if (fourierCoefs_m.empty()) {
42 std::ifstream fieldFile(Filename_m.c_str());
43 stripFileHeader(fieldFile);
44
45 double* fieldData = new double[2 * numberOfGridPoints_m - 1];
46 double maxEz = readFileData(fieldFile, fieldData);
47 fieldFile.close();
48 computeFourierCoefficients(maxEz, fieldData);
49 delete[] fieldData;
50
51 *ippl::Info << level3 << typeset_msg("read in fieldmap '" + Filename_m + "'", "info")
52 << endl;
53 }
54}
55
57 if (!fourierCoefs_m.empty()) {
58 fourierCoefs_m.clear();
59
60 *ippl::Info << level3 << typeset_msg("freed fieldmap '" + Filename_m + "'", "info") << endl;
61 }
62}
63
66 std::vector<double> fieldComponents;
67 computeFieldOnAxis(R(2) - zBegin_m, fieldComponents);
68 computeFieldOffAxis(R, E, B, fieldComponents);
69
70 return false;
71}
72
75 const DiffDirection& /*dir*/) const {
76 double kz = Physics::two_pi * (R(2) - zBegin_m) / length_m + Physics::pi;
77 double eZPrime = 0.0;
78
79 int coefIndex = 1;
80 for (int n = 1; n < accuracy_m; ++n) {
81 eZPrime += n * Physics::two_pi / length_m
82 * (-fourierCoefs_m.at(coefIndex) * sin(kz * n)
83 - fourierCoefs_m.at(coefIndex + 1) * cos(kz * n));
84 coefIndex += 2;
85 }
86
87 E(2) += eZPrime;
88
89 return false;
90}
91
92void FM1DElectroStatic::getFieldDimensions(double& zBegin, double& zEnd) const {
93 zBegin = zBegin_m;
94 zEnd = zEnd_m;
95}
97 double& /*xIni*/, double& /*xFinal*/, double& /*yIni*/, double& /*yFinal*/, double& /*zIni*/,
98 double& /*zFinal*/) const {
99}
100
103
104void FM1DElectroStatic::getInfo(Inform* msg) {
105 (*msg) << Filename_m << " (1D electrostatic); zini= " << zBegin_m << " m; zfinal= " << zEnd_m
106 << " m;" << endl;
107}
108
110 return 0.0;
111}
112
113void FM1DElectroStatic::setFrequency(double /*freq*/) {
114}
115
116bool FM1DElectroStatic::checkFileData(std::ifstream& fieldFile, bool parsingPassed) {
117 double tempDouble;
118 for (int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++dataIndex)
119 parsingPassed = parsingPassed && interpretLine<double>(fieldFile, tempDouble);
120
121 return parsingPassed && interpreteEOF(fieldFile);
122}
123
126 std::vector<double> fieldComponents) const {
127 double radiusSq = pow(R(0), 2.0) + pow(R(1), 2.0);
128 double transverseEFactor =
129 -fieldComponents.at(1) / 2.0 + radiusSq * fieldComponents.at(3) / 16.0;
130
131 E(0) += R(0) * transverseEFactor;
132 E(1) += R(1) * transverseEFactor;
133 E(2) += fieldComponents.at(0) - fieldComponents.at(2) * radiusSq / 4.0;
134}
135
136void FM1DElectroStatic::computeFieldOnAxis(double z, std::vector<double>& fieldComponents) const {
137 double kz = Physics::two_pi * z / length_m + Physics::pi;
138 fieldComponents.push_back(fourierCoefs_m.at(0));
139 fieldComponents.push_back(0.0);
140 fieldComponents.push_back(0.0);
141 fieldComponents.push_back(0.0);
142
143 int coefIndex = 1;
144 for (int n = 1; n < accuracy_m; ++n) {
145 double kn = n * Physics::two_pi / length_m;
146 double coskzn = cos(kz * n);
147 double sinkzn = sin(kz * n);
148
149 fieldComponents.at(0) +=
150 fourierCoefs_m.at(coefIndex) * coskzn - fourierCoefs_m.at(coefIndex + 1) * sinkzn;
151
152 fieldComponents.at(1) +=
153 kn
154 * (-fourierCoefs_m.at(coefIndex) * sinkzn - fourierCoefs_m.at(coefIndex + 1) * coskzn);
155
156 double derivCoeff = pow(kn, 2.0);
157 fieldComponents.at(2) +=
158 derivCoeff
159 * (-fourierCoefs_m.at(coefIndex) * coskzn + fourierCoefs_m.at(coefIndex + 1) * sinkzn);
160 derivCoeff *= kn;
161 fieldComponents.at(3) +=
162 derivCoeff
163 * (fourierCoefs_m.at(coefIndex) * sinkzn + fourierCoefs_m.at(coefIndex + 1) * coskzn);
164
165 coefIndex += 2;
166 }
167}
168
169void FM1DElectroStatic::computeFourierCoefficients(double maxEz, double fieldData[]) {
170 const unsigned int totalSize = 2 * numberOfGridPoints_m - 1;
171 gsl_fft_real_wavetable* waveTable = gsl_fft_real_wavetable_alloc(totalSize);
172 gsl_fft_real_workspace* workSpace = gsl_fft_real_workspace_alloc(totalSize);
173
174 gsl_fft_real_transform(fieldData, 1, totalSize, waveTable, workSpace);
175
176 /*
177 * Normalize the Fourier coefficients such that the max field
178 * value is 1 V/m.
179 */
180
181 fourierCoefs_m.push_back(fieldData[0] / (totalSize * maxEz * Units::Vpm2MVpm));
182 for (int coefIndex = 1; coefIndex < 2 * accuracy_m - 1; ++coefIndex)
183 fourierCoefs_m.push_back(
184 2.0 * fieldData[coefIndex] / (totalSize * maxEz * Units::Vpm2MVpm));
185
186 gsl_fft_real_workspace_free(workSpace);
187 gsl_fft_real_wavetable_free(waveTable);
188}
189
191 // Convert to m.
196}
197
198double FM1DElectroStatic::readFileData(std::ifstream& fieldFile, double fieldData[]) {
199 double maxEz = 0.0;
200 for (int dataIndex = 0; dataIndex < numberOfGridPoints_m; ++dataIndex) {
201 interpretLine<double>(fieldFile, fieldData[numberOfGridPoints_m - 1 + dataIndex]);
202 if (std::abs(fieldData[numberOfGridPoints_m + dataIndex]) > maxEz)
203 maxEz = std::abs(fieldData[numberOfGridPoints_m + dataIndex]);
204
205 /*
206 * Mirror the field map about minimum z value to ensure that
207 * it is periodic.
208 */
209 if (dataIndex != 0)
210 fieldData[numberOfGridPoints_m - 1 - dataIndex] =
211 fieldData[numberOfGridPoints_m + dataIndex];
212 }
213
214 if (!normalize_m)
215 maxEz = 1.0;
216
217 return maxEz;
218}
219
220bool FM1DElectroStatic::readFileHeader(std::ifstream& fieldFile) {
221 std::string tempString;
222 int tempInt;
223
224 bool parsingPassed = true;
225 try {
226 parsingPassed = interpretLine<std::string, int>(fieldFile, tempString, accuracy_m);
227 } catch (GeneralClassicException& e) {
229 fieldFile, tempString, accuracy_m, tempString);
230
231 tempString = Util::toUpper(tempString);
232 if (tempString != "TRUE" && tempString != "FALSE")
234 "FM1DElectroStatic::readFileHeader",
235 "The third string on the first line of 1D field "
236 "maps has to be either TRUE or FALSE");
237
238 normalize_m = (tempString == "TRUE");
239 }
240
241 parsingPassed =
242 parsingPassed
244 parsingPassed =
245 parsingPassed && interpretLine<double, double, int>(fieldFile, rBegin_m, rEnd_m, tempInt);
246
248
251
252 return parsingPassed;
253}
254
255void FM1DElectroStatic::stripFileHeader(std::ifstream& fieldFile) {
256 std::string tempString;
257
258 getLine(fieldFile, tempString);
259 getLine(fieldFile, tempString);
260 getLine(fieldFile, tempString);
261}
ippl::Vector< T, Dim > Vector_t
@ T1DElectroStatic
Definition Fieldmap.h:19
DiffDirection
Definition Fieldmap.h:55
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:145
MapType Type
Definition Fieldmap.h:118
bool interpreteEOF(std::ifstream &in)
Definition Fieldmap.cpp:516
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
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 bool getFieldDerivative(const Vector_t< double, 3 > &R, Vector_t< double, 3 > &E, Vector_t< double, 3 > &B, const DiffDirection &dir) const
virtual void setFrequency(double freq)
int accuracy_m
Number of grid points in field input file.
friend class Fieldmap
Fourier coefficients derived from field map.
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)
void computeFieldOffAxis(const Vector_t< double, 3 > &R, Vector_t< double, 3 > &E, Vector_t< double, 3 > &B, std::vector< double > fieldComponents) const
virtual bool getFieldstrength(const Vector_t< double, 3 > &R, Vector_t< double, 3 > &E, Vector_t< double, 3 > &B) 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.