OPAL (Object Oriented Parallel Accelerator Library) 2024.2
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(filename),
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 &&
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 {
68 noFieldmapWarning();
69 zbegin_m = 0.0;
70 zend_m = -1e-3;
71 }
72}
73
77
79{
80 return Astra1DMagnetoStatic(new _Astra1DMagnetoStatic(filename));
81}
82
84 if (FourCoefs_m == nullptr) {
85 // declare variables and allocate memory
86 std::ifstream in;
87
88 bool parsing_passed = true;
89
90 std::string tmpString;
91
92 double Bz_max = 0.0;
93 double dz = (zend_m - zbegin_m) / (num_gridpz_m - 1);
94 double tmpDouble = zbegin_m - dz;
95
96 double *RealValues = new double[2 * num_gridpz_m];
97 double *zvals = new double[num_gridpz_m];
98
99 gsl_spline *Bz_interpolant = gsl_spline_alloc(gsl_interp_cspline, num_gridpz_m);
100 gsl_interp_accel *Bz_accel = gsl_interp_accel_alloc();
101
102 gsl_fft_real_wavetable *real = gsl_fft_real_wavetable_alloc(2 * num_gridpz_m);
103 gsl_fft_real_workspace *work = gsl_fft_real_workspace_alloc(2 * num_gridpz_m);
104
105 FourCoefs_m = new double[2 * accuracy_m - 1];
106
107 // read in and parse field map
108 in.open(Filename_m.c_str());
109 getLine(in, tmpString);
110
111 for (int i = 0; i < num_gridpz_m && parsing_passed;/* skip increment on i here */) {
112 parsing_passed = interpretLine<double, double>(in, zvals[i], RealValues[i]);
113 // the sequence of z-position should be strictly increasing
114 // drop sampling points that don't comply to this
115 if (zvals[i] - tmpDouble > 1e-10) {
116 if (std::abs(RealValues[i]) > Bz_max) {
117 Bz_max = std::abs(RealValues[i]);
118 }
119 tmpDouble = zvals[i];
120 ++ i; // increment i only if sampling point is accepted
121 }
122 }
123 in.close();
124
125 gsl_spline_init(Bz_interpolant, zvals, RealValues, num_gridpz_m);
126
127 // get equidistant sampling from the, possibly, non-equidistant sampling
128 // using cubic spline for this
129 int ii = num_gridpz_m;
130 for (int i = 0; i < num_gridpz_m - 1; ++ i, ++ ii) {
131 double z = zbegin_m + dz * i;
132 RealValues[ii] = gsl_spline_eval(Bz_interpolant, z, Bz_accel);
133 }
134 RealValues[ii ++] = RealValues[num_gridpz_m - 1];
135 // prepend mirror sampling points such that field values are periodic for sure
136 -- ii; // ii == 2*num_gridpz_m at the moment
137 for (int i = 0; i < num_gridpz_m; ++ i, -- ii) {
138 RealValues[i] = RealValues[ii];
139 }
140
141 gsl_fft_real_transform(RealValues, 1, 2 * num_gridpz_m, real, work);
142
143 if (!normalize_m) {
144 Bz_max = 1.0;
145 }
146 // normalize to Bz_max = 1 A/m
147 FourCoefs_m[0] = RealValues[0] / (Bz_max * 2. * num_gridpz_m);
148 for (int i = 1; i < 2 * accuracy_m - 1; i++) {
149 FourCoefs_m[i] = RealValues[i] / (Bz_max * num_gridpz_m);
150 }
151
152 gsl_spline_free(Bz_interpolant);
153 gsl_interp_accel_free(Bz_accel);
154
155 gsl_fft_real_workspace_free(work);
156 gsl_fft_real_wavetable_free(real);
157
158 delete[] zvals;
159 delete[] RealValues;
160
161 INFOMSG(level3 << typeset_msg("read in fieldmap '" + Filename_m + "'", "info") << endl);
162 }
163}
164
166 if (FourCoefs_m != nullptr) {
167
168 delete[] FourCoefs_m;
169 FourCoefs_m = nullptr;
170 }
171}
172
174 // do fourier interpolation in z-direction
175 const double RR2 = R(0) * R(0) + R(1) * R(1);
176
177 const double kz = Physics::two_pi * (R(2) - zbegin_m) / length_m + Physics::pi;
178
179 double ez = FourCoefs_m[0];
180 double ezp = 0.0;
181 double ezpp = 0.0;
182 double ezppp = 0.0;
183
184 int n = 1;
185 for (int l = 1; l < accuracy_m ; l++, n += 2) {
186 double somefactor_base = Physics::two_pi / length_m * l; // = \frac{d(kz*l)}{dz}
187 double somefactor = 1.0;
188 double coskzl = cos(kz * l);
189 double sinkzl = sin(kz * l);
190 ez += (FourCoefs_m[n] * coskzl - FourCoefs_m[n + 1] * sinkzl);
191 somefactor *= somefactor_base;
192 ezp += somefactor * (-FourCoefs_m[n] * sinkzl - FourCoefs_m[n + 1] * coskzl);
193 somefactor *= somefactor_base;
194 ezpp += somefactor * (-FourCoefs_m[n] * coskzl + FourCoefs_m[n + 1] * sinkzl);
195 somefactor *= somefactor_base;
196 ezppp += somefactor * (FourCoefs_m[n] * sinkzl + FourCoefs_m[n + 1] * coskzl);
197 }
198 // expand the field off-axis
199 const double BfieldR = -ezp / 2. + ezppp / 16. * RR2;
200
201 B(0) += BfieldR * R(0);
202 B(1) += BfieldR * R(1);
203 B(2) += ez - ezpp * RR2 / 4.;
204
205 return false;
206}
207
208bool _Astra1DMagnetoStatic::getFieldDerivative(const Vector_t &/*R*/, Vector_t &/*E*/, Vector_t &/*B*/, const DiffDirection &/*dir*/) const {
209 return false;
210}
211
212void _Astra1DMagnetoStatic::getFieldDimensions(double &zBegin, double &zEnd) const {
213 zBegin = zbegin_m;
214 zEnd = zend_m;
215}
216void _Astra1DMagnetoStatic::getFieldDimensions(double &/*xIni*/, double &/*xFinal*/, double &/*yIni*/, double &/*yFinal*/, double &/*zIni*/, double &/*zFinal*/) const {}
217
220
222 (*msg) << Filename_m << " (1D magnetostatic); zini= " << zbegin_m << " m; zfinal= " << zend_m << " m;" << endl;
223}
224
226 return 0.0;
227}
228
230{ }
FLieGenerator< T, N > real(const FLieGenerator< std::complex< T >, N > &)
Take real part of a complex generator.
std::shared_ptr< _Astra1DMagnetoStatic > Astra1DMagnetoStatic
@ TAstraMagnetoStatic
Definition Fieldmap.h:22
DiffDirection
Definition Fieldmap.h:55
Tps< T > cos(const Tps< T > &x)
Cosine.
Definition TpsMath.h:129
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
std::string toUpper(const std::string &str)
Definition Util.cpp:147
virtual void getInfo(Inform *)
virtual void setFrequency(double freq)
static Astra1DMagnetoStatic create(const std::string &filename)
_Astra1DMagnetoStatic(const std::string &filename)
virtual void getFieldDimensions(double &zBegin, double &zEnd) const
virtual bool getFieldstrength(const Vector_t &R, Vector_t &E, Vector_t &B) const
virtual double getFrequency() const
virtual bool getFieldDerivative(const Vector_t &R, Vector_t &E, Vector_t &B, const DiffDirection &dir) const
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
bool interpretLine(std::ifstream &in, S &value, const bool &file_length_known=true)
int lines_read_m
Definition Fieldmap.h:119
std::string Filename_m
Definition Fieldmap.h:118
MapType Type
Definition Fieldmap.h:116
Vektor< double, 3 > Vector_t