OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
Astra1DMagnetoStatic.cpp
Go to the documentation of this file.
2#include "Fields/Fieldmap.hpp"
3#include "Physics/Physics.h"
5#include "Utilities/Util.h"
6
7#include "gsl/gsl_interp.h"
8#include "gsl/gsl_spline.h"
9#include "gsl/gsl_fft_real.h"
10
11#include <fstream>
12#include <ios>
13
14
16 : Fieldmap(aFilename),
17 FourCoefs_m(nullptr) {
18 std::ifstream file;
19 int skippedValues = 0;
20 std::string tmpString;
21 double tmpDouble;
22
24
25 // open field map, parse it and disable element on error
26 file.open(Filename_m.c_str());
27 if (file.good()) {
28 bool parsing_passed = true;
29 try {
30 parsing_passed = interpretLine<std::string, int>(file, tmpString, accuracy_m);
31 } catch (GeneralClassicException &e) {
32 parsing_passed = interpretLine<std::string, int, std::string>(file, tmpString, accuracy_m, tmpString);
33
34 tmpString = Util::toUpper(tmpString);
35 if (tmpString != "TRUE" &&
36 tmpString != "FALSE")
37 throw GeneralClassicException("Astra1DMagnetoStatic::Astra1DMagnetoStatic",
38 "The third string on the first line of 1D field "
39 "maps has to be either TRUE or FALSE");
40
41 normalize_m = (tmpString == "TRUE");
42 }
43 parsing_passed = parsing_passed &&
44 interpretLine<double, double>(file, zbegin_m, tmpDouble);
45
46 double tmpDouble2 = zbegin_m;
47 while(!file.eof() && parsing_passed) {
48 parsing_passed = interpretLine<double, double>(file, zend_m, tmpDouble, false);
49 if (zend_m - tmpDouble2 > 1e-10) {
50 tmpDouble2 = zend_m;
51 } else if (parsing_passed) {
52 ++ skippedValues;
53 }
54 }
55
56 file.close();
57 num_gridpz_m = lines_read_m - 2 - skippedValues;
58 lines_read_m = 0;
59
60 if (!parsing_passed && !file.eof()) {
62 zend_m = zbegin_m - 1e-3;
63 throw GeneralClassicException("Astra1DMagnetoStatic::Astra1DMagnetoStatic",
64 "An error occured when reading the fieldmap '" + Filename_m + "'");
65 }
66 length_m = 2.0 * num_gridpz_m * (zend_m - zbegin_m) / (num_gridpz_m - 1);
67 } else {
69 zbegin_m = 0.0;
70 zend_m = -1e-3;
71 }
72}
73
75 freeMap();
76}
77
79 if (FourCoefs_m == nullptr) {
80 // declare variables and allocate memory
81 std::ifstream in;
82
83 bool parsing_passed = true;
84
85 std::string tmpString;
86
87 double Bz_max = 0.0;
88 double dz = (zend_m - zbegin_m) / (num_gridpz_m - 1);
89 double tmpDouble = zbegin_m - dz;
90
91 double *RealValues = new double[2 * num_gridpz_m];
92 double *zvals = new double[num_gridpz_m];
93
94 gsl_spline *Bz_interpolant = gsl_spline_alloc(gsl_interp_cspline, num_gridpz_m);
95 gsl_interp_accel *Bz_accel = gsl_interp_accel_alloc();
96
97 gsl_fft_real_wavetable *real = gsl_fft_real_wavetable_alloc(2 * num_gridpz_m);
98 gsl_fft_real_workspace *work = gsl_fft_real_workspace_alloc(2 * num_gridpz_m);
99
100 FourCoefs_m = new double[2 * accuracy_m - 1];
101
102 // read in and parse field map
103 in.open(Filename_m.c_str());
104 getLine(in, tmpString);
105
106 for (int i = 0; i < num_gridpz_m && parsing_passed;/* skip increment on i here */) {
107 parsing_passed = interpretLine<double, double>(in, zvals[i], RealValues[i]);
108 // the sequence of z-position should be strictly increasing
109 // drop sampling points that don't comply to this
110 if (zvals[i] - tmpDouble > 1e-10) {
111 if (std::abs(RealValues[i]) > Bz_max) {
112 Bz_max = std::abs(RealValues[i]);
113 }
114 tmpDouble = zvals[i];
115 ++ i; // increment i only if sampling point is accepted
116 }
117 }
118 in.close();
119
120 gsl_spline_init(Bz_interpolant, zvals, RealValues, num_gridpz_m);
121
122 // get equidistant sampling from the, possibly, non-equidistant sampling
123 // using cubic spline for this
124 int ii = num_gridpz_m;
125 for (int i = 0; i < num_gridpz_m - 1; ++ i, ++ ii) {
126 double z = zbegin_m + dz * i;
127 RealValues[ii] = gsl_spline_eval(Bz_interpolant, z, Bz_accel);
128 }
129 RealValues[ii ++] = RealValues[num_gridpz_m - 1];
130 // prepend mirror sampling points such that field values are periodic for sure
131 -- ii; // ii == 2*num_gridpz_m at the moment
132 for (int i = 0; i < num_gridpz_m; ++ i, -- ii) {
133 RealValues[i] = RealValues[ii];
134 }
135
136 gsl_fft_real_transform(RealValues, 1, 2 * num_gridpz_m, real, work);
137
138 if (!normalize_m) {
139 Bz_max = 1.0;
140 }
141 // normalize to Bz_max = 1 A/m
142 FourCoefs_m[0] = RealValues[0] / (Bz_max * 2. * num_gridpz_m);
143 for (int i = 1; i < 2 * accuracy_m - 1; i++) {
144 FourCoefs_m[i] = RealValues[i] / (Bz_max * num_gridpz_m);
145 }
146
147 gsl_spline_free(Bz_interpolant);
148 gsl_interp_accel_free(Bz_accel);
149
150 gsl_fft_real_workspace_free(work);
151 gsl_fft_real_wavetable_free(real);
152
153 delete[] zvals;
154 delete[] RealValues;
155
156 INFOMSG(level3 << typeset_msg("read in fieldmap '" + Filename_m + "'", "info") << endl);
157 }
158}
159
161 if (FourCoefs_m != nullptr) {
162
163 delete[] FourCoefs_m;
164 FourCoefs_m = nullptr;
165
166 INFOMSG(level3 << typeset_msg("freed fieldmap '" + Filename_m + "'", "info") << endl);
167 }
168}
169
171 // do fourier interpolation in z-direction
172 const double RR2 = R(0) * R(0) + R(1) * R(1);
173
174 const double kz = Physics::two_pi * (R(2) - zbegin_m) / length_m + Physics::pi;
175
176 double ez = FourCoefs_m[0];
177 double ezp = 0.0;
178 double ezpp = 0.0;
179 double ezppp = 0.0;
180
181 int n = 1;
182 for (int l = 1; l < accuracy_m ; l++, n += 2) {
183 double somefactor_base = Physics::two_pi / length_m * l; // = \frac{d(kz*l)}{dz}
184 double somefactor = 1.0;
185 double coskzl = cos(kz * l);
186 double sinkzl = sin(kz * l);
187 ez += (FourCoefs_m[n] * coskzl - FourCoefs_m[n + 1] * sinkzl);
188 somefactor *= somefactor_base;
189 ezp += somefactor * (-FourCoefs_m[n] * sinkzl - FourCoefs_m[n + 1] * coskzl);
190 somefactor *= somefactor_base;
191 ezpp += somefactor * (-FourCoefs_m[n] * coskzl + FourCoefs_m[n + 1] * sinkzl);
192 somefactor *= somefactor_base;
193 ezppp += somefactor * (FourCoefs_m[n] * sinkzl + FourCoefs_m[n + 1] * coskzl);
194 }
195 // expand the field off-axis
196 const double BfieldR = -ezp / 2. + ezppp / 16. * RR2;
197
198 B(0) += BfieldR * R(0);
199 B(1) += BfieldR * R(1);
200 B(2) += ez - ezpp * RR2 / 4.;
201
202 return false;
203}
204
205bool Astra1DMagnetoStatic::getFieldDerivative(const Vector_t &/*R*/, Vector_t &/*E*/, Vector_t &/*B*/, const DiffDirection &/*dir*/) const {
206 return false;
207}
208
209void Astra1DMagnetoStatic::getFieldDimensions(double &zBegin, double &zEnd) const {
210 zBegin = zbegin_m;
211 zEnd = zend_m;
212}
213void Astra1DMagnetoStatic::getFieldDimensions(double &/*xIni*/, double &/*xFinal*/, double &/*yIni*/, double &/*yFinal*/, double &/*zIni*/, double &/*zFinal*/) const {}
214
216{ }
217
219 (*msg) << Filename_m << " (1D magnetostatic); zini= " << zbegin_m << " m; zfinal= " << zend_m << " m;" << endl;
220}
221
223 return 0.0;
224}
225
227{ }
FLieGenerator< T, N > real(const FLieGenerator< std::complex< T >, N > &)
Take real part of a complex generator.
@ TAstraMagnetoStatic
Definition: Fieldmap.h:21
DiffDirection
Definition: Fieldmap.h:54
Tps< T > cos(const Tps< T > &x)
Cosine.
Definition: TpsMath.h:129
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
std::string toUpper(const std::string &str)
Definition: Util.cpp:146
virtual void getInfo(Inform *)
virtual bool getFieldstrength(const Vector_t &R, Vector_t &E, Vector_t &B) const
virtual void setFrequency(double freq)
virtual void getFieldDimensions(double &zBegin, double &zEnd) const
virtual bool getFieldDerivative(const Vector_t &R, Vector_t &E, Vector_t &B, const DiffDirection &dir) const
Astra1DMagnetoStatic(std::string aFilename)
virtual double getFrequency() const
MapType Type
Definition: Fieldmap.h:114
void disableFieldmapWarning()
Definition: Fieldmap.cpp:613
bool normalize_m
Definition: Fieldmap.h:120
int lines_read_m
Definition: Fieldmap.h:118
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
Definition: Inform.h:42