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