OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
Astra1DDynamic.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
15
16Astra1DDynamic::Astra1DDynamic(std::string aFilename):
17 Fieldmap(aFilename),
18 FourCoefs_m(nullptr) {
19
20 std::ifstream file;
21 int skippedValues = 0;
22 std::string tmpString;
23 double tmpDouble;
24
26
27 // open field map, parse it and disable element on error
28 file.open(Filename_m.c_str());
29 if (file.good()) {
30 bool parsing_passed = true;
31 try {
32 parsing_passed = interpretLine<std::string, int>(file,
33 tmpString,
35 } catch (GeneralClassicException &e) {
36 parsing_passed = interpretLine<std::string, int, std::string>(file,
37 tmpString,
39 tmpString);
40
41 tmpString = Util::toUpper(tmpString);
42 if (tmpString != "TRUE" &&
43 tmpString != "FALSE")
44 throw GeneralClassicException("Astra1DDynamic::Astra1DDynamic",
45 "The third string on the first line of 1D field "
46 "maps has to be either TRUE or FALSE");
47
48 normalize_m = (tmpString == "TRUE");
49 }
50
51 parsing_passed = parsing_passed &&
52 interpretLine<double>(file, frequency_m);
53 parsing_passed = parsing_passed &&
54 interpretLine<double, double>(file, zbegin_m, tmpDouble);
55
56 double tmpDouble2 = zbegin_m;
57 while(!file.eof() && parsing_passed) {
58 parsing_passed = interpretLine<double, double>(file, zend_m, tmpDouble, false);
59 if (zend_m - tmpDouble2 > 1e-10) {
60 tmpDouble2 = zend_m;
61 } else if (parsing_passed) {
62 ++ skippedValues;
63 }
64 }
65
66 num_gridpz_m = lines_read_m - 3 - skippedValues;
67 lines_read_m = 0;
68
69 if (!parsing_passed && !file.eof()) {
71 zend_m = zbegin_m - 1e-3;
72 throw GeneralClassicException("Astra1DDynamic::Astra1DDynamic",
73 "An error occured when reading the fieldmap '" + Filename_m + "'");
74 } else {
75 // conversion from MHz to Hz and from frequency to angular frequency
78 }
79 length_m = 2.0 * num_gridpz_m * (zend_m - zbegin_m) / (num_gridpz_m - 1);
80 file.close();
81 } else {
83 zbegin_m = 0.0;
84 zend_m = -1e-3;
85 }
86}
87
89 freeMap();
90}
91
93 if (FourCoefs_m == nullptr) {
94 // declare variables and allocate memory
95 std::ifstream in;
96
97 bool parsing_passed = true;
98
99 std::string tmpString;
100
101 double tmpDouble;
102 double Ez_max = 0.0;
103 double dz = (zend_m - zbegin_m) / (num_gridpz_m - 1);
104
105 double *RealValues = new double[2 * num_gridpz_m];
106 double *zvals = new double[num_gridpz_m];
107
108 gsl_spline *Ez_interpolant = gsl_spline_alloc(gsl_interp_cspline, num_gridpz_m);
109 gsl_interp_accel *Ez_accel = gsl_interp_accel_alloc();
110
111 gsl_fft_real_wavetable *real = gsl_fft_real_wavetable_alloc(2 * num_gridpz_m);
112 gsl_fft_real_workspace *work = gsl_fft_real_workspace_alloc(2 * num_gridpz_m);
113
114 FourCoefs_m = new double[2 * accuracy_m - 1];
115
116 // read in and parse field map
117 in.open(Filename_m.c_str());
118 getLine(in, tmpString);
119 getLine(in, tmpString);
120
121 tmpDouble = zbegin_m - dz;
122 for (int i = 0; i < num_gridpz_m && parsing_passed; /* skip increment of i here */) {
123 parsing_passed = interpretLine<double, double>(in, zvals[i], RealValues[i]);
124 // the sequence of z-position should be strictly increasing
125 // drop sampling points that don't comply to this
126 if (zvals[i] - tmpDouble > 1e-10) {
127 if (std::abs(RealValues[i]) > Ez_max) {
128 Ez_max = std::abs(RealValues[i]);
129 }
130 tmpDouble = zvals[i];
131 ++ i; // increment i only if sampling point is accepted
132 }
133 }
134 in.close();
135
136 gsl_spline_init(Ez_interpolant, zvals, RealValues, num_gridpz_m);
137
138 // get equidistant sampling from the, possibly, non-equidistant sampling
139 // using cubic spline for this
140 int ii = num_gridpz_m;
141 for (int i = 0; i < num_gridpz_m - 1; ++ i, ++ ii) {
142 double z = zbegin_m + dz * i;
143 RealValues[ii] = gsl_spline_eval(Ez_interpolant, z, Ez_accel);
144 }
145 RealValues[ii ++] = RealValues[num_gridpz_m - 1];
146 // prepend mirror sampling points such that field values are periodic for sure
147 -- ii; // ii == 2*num_gridpz_m at the moment
148 for (int i = 0; i < num_gridpz_m; ++ i, -- ii) {
149 RealValues[i] = RealValues[ii];
150 }
151
152 gsl_fft_real_transform(RealValues, 1, 2 * num_gridpz_m, real, work);
153
154 if (!normalize_m) {
155 Ez_max = 1.0;
156 }
157
158 FourCoefs_m[0] = RealValues[0] / (Ez_max * Units::Vpm2MVpm* 2. * num_gridpz_m);
159 for (int i = 1; i < 2 * accuracy_m - 1; ++ i) {
160 FourCoefs_m[i] = RealValues[i] / (Ez_max * Units::Vpm2MVpm * num_gridpz_m);
161 }
162
163 gsl_spline_free(Ez_interpolant);
164 gsl_interp_accel_free(Ez_accel);
165
166 gsl_fft_real_workspace_free(work);
167 gsl_fft_real_wavetable_free(real);
168
169 delete[] zvals;
170 delete[] RealValues;
171
172 INFOMSG(level3 << typeset_msg("read in fieldmap '" + Filename_m + "'", "info") << endl);
173 }
174}
175
177 if (FourCoefs_m != nullptr) {
178 delete[] FourCoefs_m;
179 FourCoefs_m = nullptr;
180
181 INFOMSG(level3 << typeset_msg("freed fieldmap '" + Filename_m + "'", "info") << endl);
182 }
183}
184
186 // do fourier interpolation in z-direction
187 const double RR2 = R(0) * R(0) + R(1) * R(1);
188
189 const double kz = Physics::two_pi * (R(2) - zbegin_m) / length_m + Physics::pi;
190
191 double ez = FourCoefs_m[0];
192 double ezp = 0.0;
193 double ezpp = 0.0;
194 double ezppp = 0.0;
195
196 int n = 1;
197 for (int l = 1; l < accuracy_m ; ++ l, n += 2) {
198 double somefactor_base = Physics::two_pi / length_m * l; // = \frac{d(kz*l)}{dz}
199 double somefactor = 1.0;
200 double coskzl = cos(kz * l);
201 double sinkzl = sin(kz * l);
202 ez += (FourCoefs_m[n] * coskzl - FourCoefs_m[n + 1] * sinkzl);
203 somefactor *= somefactor_base;
204 ezp += somefactor * (-FourCoefs_m[n] * sinkzl - FourCoefs_m[n + 1] * coskzl);
205 somefactor *= somefactor_base;
206 ezpp += somefactor * (-FourCoefs_m[n] * coskzl + FourCoefs_m[n + 1] * sinkzl);
207 somefactor *= somefactor_base;
208 ezppp += somefactor * (FourCoefs_m[n] * sinkzl + FourCoefs_m[n + 1] * coskzl);
209 }
210 // expand the field off-axis
211 const double f = -(ezpp + ez * xlrep_m * xlrep_m) / 16.;
212 const double fp = -(ezppp + ezp * xlrep_m * xlrep_m) / 16.;
213
214 const double EfieldR = -(ezp / 2. + fp * RR2);
215 const double BfieldT = (ez / 2. + f * RR2) * xlrep_m / Physics::c;
216
217 E(0) += EfieldR * R(0);
218 E(1) += EfieldR * R(1);
219 E(2) += ez + 4. * f * RR2;
220 B(0) += -BfieldT * R(1);
221 B(1) += BfieldT * R(0);
222
223 return false;
224}
225
226bool Astra1DDynamic::getFieldDerivative(const Vector_t &R, Vector_t &E, Vector_t &/*B*/, const DiffDirection &/*dir*/) const {
227 const double kz = Physics::two_pi * (R(2) - zbegin_m) / length_m + Physics::pi;
228 double ezp = 0.0;
229
230 int n = 1;
231 for (int l = 1; l < accuracy_m; ++ l, n += 2)
232 ezp += Physics::two_pi / length_m * l * (-FourCoefs_m[n] * sin(kz * l) - FourCoefs_m[n + 1] * cos(kz * l));
233
234 E(2) += ezp;
235
236 return false;
237}
238
239void Astra1DDynamic::getFieldDimensions(double &zBegin, double &zEnd) const {
240 zBegin = zbegin_m;
241 zEnd = zend_m;
242}
243
244void Astra1DDynamic::getFieldDimensions(double &/*xIni*/, double &/*xFinal*/, double &/*yIni*/, double &/*yFinal*/, double &/*zIni*/, double &/*zFinal*/) const {}
245
247{ }
248
250 (*msg) << Filename_m << " (1D dynamic); zini= " << zbegin_m << " m; zfinal= " << zend_m << " m;" << endl;
251}
252
254 return frequency_m;
255}
256
258 frequency_m = freq;
259}
260
261void Astra1DDynamic::getOnaxisEz(std::vector<std::pair<double, double> > & F) {
262 double Ez_max = 0.0;
263 double tmpDouble;
264 int tmpInt;
265 std::string tmpString;
266 F.resize(num_gridpz_m);
267
268 std::ifstream in(Filename_m.c_str());
269 interpretLine<std::string, int>(in, tmpString, tmpInt);
270 interpretLine<double>(in, tmpDouble);
271
272 for (int i = 0; i < num_gridpz_m; ++ i) {
273 interpretLine<double, double>(in, F[i].first, F[i].second);
274 if (std::abs(F[i].second) > Ez_max) {
275 Ez_max = std::abs(F[i].second);
276 }
277 }
278 in.close();
279
280 for (int i = 0; i < num_gridpz_m; ++ i) {
281 F[i].second /= Ez_max;
282 }
283}
FLieGenerator< T, N > real(const FLieGenerator< std::complex< T >, N > &)
Take real part of a complex generator.
@ TAstraDynamic
Definition: Fieldmap.h:17
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 c
The velocity of light in m/s.
Definition: Physics.h:45
constexpr double pi
The value of.
Definition: Physics.h:30
constexpr double MHz2Hz
Definition: Units.h:113
constexpr double Vpm2MVpm
Definition: Units.h:125
std::string toUpper(const std::string &str)
Definition: Util.cpp:146
virtual bool getFieldstrength(const Vector_t &R, Vector_t &E, Vector_t &B) const
virtual bool getFieldDerivative(const Vector_t &R, Vector_t &E, Vector_t &B, const DiffDirection &dir) const
virtual void setFrequency(double freq)
virtual double getFrequency() const
virtual void readMap()
virtual void getFieldDimensions(double &zBegin, double &zEnd) const
virtual void getOnaxisEz(std::vector< std::pair< double, double > > &F)
double *__restrict__ FourCoefs_m
virtual void getInfo(Inform *)
virtual void swap()
virtual void freeMap()
Astra1DDynamic(std::string aFilename)
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