OPALX (Object Oriented Parallel Accelerator Library for Exascal) MINIorX
OPALX
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
13FM1DMagnetoStatic::FM1DMagnetoStatic(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 maxBz = readFileData(fieldFile, fieldData);
47 fieldFile.close();
48 computeFourierCoefficients(maxBz, 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 bZPrime = 0.0;
78
79 int coefIndex = 1;
80 for (int n = 1; n < accuracy_m; n++) {
81 bZPrime += 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 B(2) += bZPrime;
88
89 return false;
90}
91
92void FM1DMagnetoStatic::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 FM1DMagnetoStatic::getInfo(Inform* msg) {
105 (*msg) << Filename_m << " (1D magnetostatic); zini= " << zBegin_m << " m; zfinal= " << zEnd_m
106 << " m;" << endl;
107}
108
110 return 0.0;
111}
112
113void FM1DMagnetoStatic::setFrequency(double /*freq*/) {
114}
115
116bool FM1DMagnetoStatic::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 transverseBFactor =
129 -fieldComponents.at(1) / 2.0 + radiusSq * fieldComponents.at(3) / 16.0;
130
131 B(0) += R(0) * transverseBFactor;
132 B(1) += R(1) * transverseBFactor;
133 B(2) += fieldComponents.at(0) - fieldComponents.at(2) * radiusSq / 4.0;
134}
135
136void FM1DMagnetoStatic::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 FM1DMagnetoStatic::computeFourierCoefficients(double maxBz, 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 * maxBz));
182 for (int coefIndex = 1; coefIndex < 2 * accuracy_m - 1; coefIndex++)
183 fourierCoefs_m.push_back(2.0 * fieldData[coefIndex] / (totalSize * maxBz));
184
185 gsl_fft_real_workspace_free(workSpace);
186 gsl_fft_real_wavetable_free(waveTable);
187}
188
190 // Convert to m.
195}
196
197double FM1DMagnetoStatic::readFileData(std::ifstream& fieldFile, double fieldData[]) {
198 double maxBz = 0.0;
199 for (int dataIndex = 0; dataIndex < numberOfGridPoints_m; dataIndex++) {
200 interpretLine<double>(fieldFile, fieldData[numberOfGridPoints_m - 1 + dataIndex]);
201 if (std::abs(fieldData[numberOfGridPoints_m + dataIndex]) > maxBz)
202 maxBz = std::abs(fieldData[numberOfGridPoints_m + dataIndex]);
203
204 /*
205 * Mirror the field map about minimum z value to ensure that
206 * it is periodic.
207 */
208 if (dataIndex != 0)
209 fieldData[numberOfGridPoints_m - 1 - dataIndex] =
210 fieldData[numberOfGridPoints_m + dataIndex];
211 }
212
213 if (!normalize_m)
214 maxBz = 1.0;
215
216 return maxBz;
217}
218
219bool FM1DMagnetoStatic::readFileHeader(std::ifstream& fieldFile) {
220 std::string tempString;
221 int tempInt;
222
223 bool parsingPassed = true;
224 try {
225 parsingPassed = interpretLine<std::string, int>(fieldFile, tempString, accuracy_m);
226 } catch (GeneralClassicException& e) {
228 fieldFile, tempString, accuracy_m, tempString);
229
230 tempString = Util::toUpper(tempString);
231 if (tempString != "TRUE" && tempString != "FALSE")
233 "FM1DMagnetoStatic::readFileHeader",
234 "The third string on the first line of 1D field "
235 "maps has to be either TRUE or FALSE");
236
237 normalize_m = (tempString == "TRUE");
238 }
239 parsingPassed =
240 parsingPassed
242 parsingPassed =
243 parsingPassed && interpretLine<double, double, int>(fieldFile, rBegin_m, rEnd_m, tempInt);
244
246
249
250 return parsingPassed;
251}
252
253void FM1DMagnetoStatic::stripFileHeader(std::ifstream& fieldFile) {
254 std::string tempString;
255
256 getLine(fieldFile, tempString);
257 getLine(fieldFile, tempString);
258 getLine(fieldFile, tempString);
259}
ippl::Vector< T, Dim > Vector_t
@ T1DMagnetoStatic
Definition Fieldmap.h:21
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
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
virtual bool getFieldstrength(const Vector_t< double, 3 > &R, Vector_t< double, 3 > &E, Vector_t< double, 3 > &B) const
bool readFileHeader(std::ifstream &fieldFile)
std::vector< double > fourierCoefs_m
Number of Fourier coefficients to use reconstructing field.
virtual void setFrequency(double freq)
void computeFieldOffAxis(const Vector_t< double, 3 > &R, Vector_t< double, 3 > &E, Vector_t< double, 3 > &B, std::vector< double > fieldComponents) const
int numberOfGridPoints_m
Field length.
int accuracy_m
Number of grid points in field input file.
void stripFileHeader(std::ifstream &fieldFile)
friend class Fieldmap
Fourier coefficients derived from field map.
virtual double getFrequency() const
double length_m
Longitudinal end of field.
void computeFourierCoefficients(double maxEz, double fieldData[])
double rEnd_m
Minimum radius of field.
bool checkFileData(std::ifstream &fieldFile, bool parsingPassed)
double zBegin_m
Maximum 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 getFieldDimensions(double &zBegin, double &zEnd) const
double readFileData(std::ifstream &fieldFile, double fieldData[])
void computeFieldOnAxis(double z, std::vector< double > &fieldComponents) const
double zEnd_m
Longitudinal start of field.
virtual void getInfo(Inform *)
FM1DMagnetoStatic(std::string aFilename)