OPALX (Object Oriented Parallel Accelerator Library for Exascal) MINIorX
OPALX
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_fft_real.h"
9#include "gsl/gsl_interp.h"
10#include "gsl/gsl_spline.h"
11
12#include <fstream>
13#include <ios>
14
15Astra1DDynamic::Astra1DDynamic(std::string aFilename) : Fieldmap(aFilename), FourCoefs_m(nullptr) {
16 std::ifstream file;
17 int skippedValues = 0;
18 std::string tmpString;
19 double tmpDouble;
20
22
23 // open field map, parse it and disable element on error
24 file.open(Filename_m.c_str());
25 if (file.good()) {
26 bool parsing_passed = true;
27 try {
28 parsing_passed = interpretLine<std::string, int>(file, tmpString, accuracy_m);
29 } catch (GeneralClassicException& e) {
31 file, tmpString, accuracy_m, tmpString);
32
33 tmpString = Util::toUpper(tmpString);
34 if (tmpString != "TRUE" && tmpString != "FALSE")
36 "Astra1DDynamic::Astra1DDynamic",
37 "The third string on the first line of 1D field "
38 "maps has to be either TRUE or FALSE");
39
40 normalize_m = (tmpString == "TRUE");
41 }
42
43 parsing_passed = parsing_passed && interpretLine<double>(file, frequency_m);
44 parsing_passed = parsing_passed && 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 num_gridpz_m = lines_read_m - 3 - skippedValues;
57 lines_read_m = 0;
58
59 if (!parsing_passed && !file.eof()) {
61 zend_m = zbegin_m - 1e-3;
63 "Astra1DDynamic::Astra1DDynamic",
64 "An error occured when reading the fieldmap '" + Filename_m + "'");
65 } else {
66 // conversion from MHz to Hz and from frequency to angular frequency
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 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 tmpDouble;
93 double Ez_max = 0.0;
94 double dz = (zend_m - zbegin_m) / (num_gridpz_m - 1);
95
96 double* RealValues = new double[2 * num_gridpz_m];
97 double* zvals = new double[num_gridpz_m];
98
99 gsl_spline* Ez_interpolant = gsl_spline_alloc(gsl_interp_cspline, num_gridpz_m);
100 gsl_interp_accel* Ez_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 getLine(in, tmpString);
111
112 tmpDouble = zbegin_m - dz;
113 for (int i = 0; i < num_gridpz_m && parsing_passed; /* skip increment of i here */) {
114 parsing_passed = interpretLine<double, double>(in, zvals[i], RealValues[i]);
115 // the sequence of z-position should be strictly increasing
116 // drop sampling points that don't comply to this
117 if (zvals[i] - tmpDouble > 1e-10) {
118 if (std::abs(RealValues[i]) > Ez_max) {
119 Ez_max = std::abs(RealValues[i]);
120 }
121 tmpDouble = zvals[i];
122 ++i; // increment i only if sampling point is accepted
123 }
124 }
125 in.close();
126
127 gsl_spline_init(Ez_interpolant, zvals, RealValues, num_gridpz_m);
128
129 // get equidistant sampling from the, possibly, non-equidistant sampling
130 // using cubic spline for this
131 int ii = num_gridpz_m;
132 for (int i = 0; i < num_gridpz_m - 1; ++i, ++ii) {
133 double z = zbegin_m + dz * i;
134 RealValues[ii] = gsl_spline_eval(Ez_interpolant, z, Ez_accel);
135 }
136 RealValues[ii++] = RealValues[num_gridpz_m - 1];
137 // prepend mirror sampling points such that field values are periodic for sure
138 --ii; // ii == 2*num_gridpz_m at the moment
139 for (int i = 0; i < num_gridpz_m; ++i, --ii) {
140 RealValues[i] = RealValues[ii];
141 }
142
143 gsl_fft_real_transform(RealValues, 1, 2 * num_gridpz_m, real, work);
144
145 if (!normalize_m) {
146 Ez_max = 1.0;
147 }
148
149 FourCoefs_m[0] = RealValues[0] / (Ez_max * Units::Vpm2MVpm * 2. * num_gridpz_m);
150 for (int i = 1; i < 2 * accuracy_m - 1; ++i) {
151 FourCoefs_m[i] = RealValues[i] / (Ez_max * Units::Vpm2MVpm * num_gridpz_m);
152 }
153
154 gsl_spline_free(Ez_interpolant);
155 gsl_interp_accel_free(Ez_accel);
156
157 gsl_fft_real_workspace_free(work);
158 gsl_fft_real_wavetable_free(real);
159
160 delete[] zvals;
161 delete[] RealValues;
162
163 *ippl::Info << level3 << typeset_msg("read in fieldmap '" + Filename_m + "'", "info")
164 << endl;
165 }
166}
167
169 if (FourCoefs_m != nullptr) {
170 delete[] FourCoefs_m;
171 FourCoefs_m = nullptr;
172
173 *ippl::Info << level3 << typeset_msg("freed fieldmap '" + Filename_m + "'", "info") << endl;
174 }
175}
176
179 // do fourier interpolation in z-direction
180 const double RR2 = R(0) * R(0) + R(1) * R(1);
181
182 const double kz = Physics::two_pi * (R(2) - zbegin_m) / length_m + Physics::pi;
183
184 double ez = FourCoefs_m[0];
185 double ezp = 0.0;
186 double ezpp = 0.0;
187 double ezppp = 0.0;
188
189 int n = 1;
190 for (int l = 1; l < accuracy_m; ++l, n += 2) {
191 double somefactor_base = Physics::two_pi / length_m * l; // = \frac{d(kz*l)}{dz}
192 double somefactor = 1.0;
193 double coskzl = cos(kz * l);
194 double sinkzl = sin(kz * l);
195 ez += (FourCoefs_m[n] * coskzl - FourCoefs_m[n + 1] * sinkzl);
196 somefactor *= somefactor_base;
197 ezp += somefactor * (-FourCoefs_m[n] * sinkzl - FourCoefs_m[n + 1] * coskzl);
198 somefactor *= somefactor_base;
199 ezpp += somefactor * (-FourCoefs_m[n] * coskzl + FourCoefs_m[n + 1] * sinkzl);
200 somefactor *= somefactor_base;
201 ezppp += somefactor * (FourCoefs_m[n] * sinkzl + FourCoefs_m[n + 1] * coskzl);
202 }
203 // expand the field off-axis
204 const double f = -(ezpp + ez * xlrep_m * xlrep_m) / 16.;
205 const double fp = -(ezppp + ezp * xlrep_m * xlrep_m) / 16.;
206
207 const double EfieldR = -(ezp / 2. + fp * RR2);
208 const double BfieldT = (ez / 2. + f * RR2) * xlrep_m / Physics::c;
209
210 E(0) += EfieldR * R(0);
211 E(1) += EfieldR * R(1);
212 E(2) += ez + 4. * f * RR2;
213 B(0) += -BfieldT * R(1);
214 B(1) += BfieldT * R(0);
215
216 return false;
217}
218
221 const DiffDirection& /*dir*/) const {
222 const double kz = Physics::two_pi * (R(2) - zbegin_m) / length_m + Physics::pi;
223 double ezp = 0.0;
224
225 int n = 1;
226 for (int l = 1; l < accuracy_m; ++l, n += 2)
227 ezp += Physics::two_pi / length_m * l
228 * (-FourCoefs_m[n] * sin(kz * l) - FourCoefs_m[n + 1] * cos(kz * l));
229
230 E(2) += ezp;
231
232 return false;
233}
234
235void Astra1DDynamic::getFieldDimensions(double& zBegin, double& zEnd) const {
236 zBegin = zbegin_m;
237 zEnd = zend_m;
238}
239
241 double& /*xIni*/, double& /*xFinal*/, double& /*yIni*/, double& /*yFinal*/, double& /*zIni*/,
242 double& /*zFinal*/) const {
243}
244
247
248void Astra1DDynamic::getInfo(Inform* msg) {
249 (*msg) << Filename_m << " (1D dynamic); zini= " << zbegin_m << " m; zfinal= " << zend_m << " m;"
250 << 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}
ippl::Vector< T, Dim > Vector_t
@ TAstraDynamic
Definition Fieldmap.h:18
DiffDirection
Definition Fieldmap.h:55
constexpr double two_pi
The value of.
Definition Physics.h:33
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:145
virtual void setFrequency(double freq)
virtual bool getFieldstrength(const Vector_t< double, 3 > &R, Vector_t< double, 3 > &E, Vector_t< double, 3 > &B) const
virtual double getFrequency() const
virtual void readMap()
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
virtual void getOnaxisEz(std::vector< std::pair< double, double > > &F)
friend class Fieldmap
double *__restrict__ FourCoefs_m
virtual void getInfo(Inform *)
virtual void swap()
virtual void freeMap()
Astra1DDynamic(std::string aFilename)
MapType Type
Definition Fieldmap.h:118
void disableFieldmapWarning()
Definition Fieldmap.cpp:569
bool normalize_m
Definition Fieldmap.h:123
int lines_read_m
Definition Fieldmap.h:121
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