OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
Astra1D_fast.cpp
Go to the documentation of this file.
2#include "Fields/Fieldmap.hpp"
3#include "Physics/Physics.h"
4#include "gsl/gsl_fft_real.h"
5
6#include <fstream>
7#include <ios>
8
9Astra1D_fast::Astra1D_fast(std::string aFilename):
10 Fieldmap(aFilename) {
11 normalize_m = true;
12}
13
15 freeMap();
16}
17
19{ }
20
22 if(onAxisField_m != nullptr) {
23 for(int i = 0; i < 4; ++i) {
24 gsl_spline_free(onAxisInterpolants_m[i]);
25 gsl_interp_accel_free(onAxisAccel_m[i]);
26 }
27
28 delete[] onAxisField_m;
29 onAxisField_m = nullptr;
30 delete[] zvals_m;
31 zvals_m = nullptr;
32
33 INFOMSG(level3 << typeset_msg("freed fieldmap '" + Filename_m + "'", "info") << endl);
34 }
35}
36
37void Astra1D_fast::getOnaxisEz(std::vector<std::pair<double, double> > & /*F*/)
38{ }
39
41 double tmpDouble, tmpDouble2;
42 unsigned int skippedValues = 0;
43 bool passed = interpretLine<double, double>(file, zbegin_m, tmpDouble);
44
45 tmpDouble2 = zbegin_m;
46 while (!file.eof() && passed) {
47 passed = interpretLine<double, double>(file, zend_m, tmpDouble, false);
48 if (zend_m - tmpDouble2 > 1e-10) {
49 tmpDouble2 = zend_m;
50 } else if (passed) {
51 ++ skippedValues;
52 }
53 }
54
55 num_gridpz_m = lines_read_m - numHeaderLines_m - skippedValues;
56 lines_read_m = 0;
57
58 return passed || file.eof();
59}
60
61double Astra1D_fast::readFieldData(std::ifstream &file) {
62 double tmpDouble = zbegin_m - hz_m;
63 double maxValue = 0;
64 int nsp;
65
66 for (nsp = 0; nsp < num_gridpz_m; ) {
67 interpretLine<double, double>(file, zvals_m[nsp], onAxisField_m[nsp]);
68
69 if(zvals_m[nsp] - tmpDouble > 1e-10) {
70 if(std::abs(onAxisField_m[nsp]) > maxValue) {
71 maxValue = std::abs(onAxisField_m[nsp]);
72 }
73 tmpDouble = zvals_m[nsp];
74 ++ nsp;
75 }
76 }
77 num_gridpz_m = nsp;
78 hz_m = (zend_m - zbegin_m) / (num_gridpz_m - 1);
79
80 if (!normalize_m) return 1.0;
81
82 return maxValue;
83}
84
85void Astra1D_fast::normalizeFieldData(double maxValue) {
86 int ii = num_gridpz_m - 1;
87 for(int i = 0; i < num_gridpz_m; ++ i, -- ii) {
88 onAxisField_m[i] /= maxValue;
89 zvals_m[ii] -= zvals_m[0];
90 }
91}
92
94 std::vector<double> zvals(num_gridpz_m, 0.0);
95
96 for(int i = 1; i < num_gridpz_m - 1; ++ i) {
97 zvals[i] = zvals[i - 1] + hz_m;
98 }
99 zvals[num_gridpz_m - 1] = zvals_m[num_gridpz_m - 1];
100
101 return zvals;
102}
103
104std::vector<double> Astra1D_fast::interpolateFieldData(std::vector<double> &samplingPoints) {
105 std::vector<double> realValues(num_gridpz_m);
106
107 onAxisInterpolants_m[0] = gsl_spline_alloc(gsl_interp_cspline, num_gridpz_m);
108 onAxisAccel_m[0] = gsl_interp_accel_alloc();
109
111
112 for (int i = 0; i < num_gridpz_m - 1; ++ i) {
113 realValues[i] = gsl_spline_eval(onAxisInterpolants_m[0], samplingPoints[i], onAxisAccel_m[0]);
114 }
115 realValues[num_gridpz_m - 1] = onAxisField_m[num_gridpz_m - 1];
116
117 return realValues;
118}
119
120std::vector<double> Astra1D_fast::computeFourierCoefficients(int accuracy,
121 std::vector<double> &evenFieldSampling) {
122 std::vector<double> fourierCoefficients(2 * accuracy - 1);
123 std::vector<double> RealValues(2 * num_gridpz_m, 0.0);
124 int ii = num_gridpz_m, iii = num_gridpz_m - 1;
125
126 for(int i = 0; i < num_gridpz_m; ++ i, ++ ii, -- iii) {
127 RealValues[ii] = evenFieldSampling[i];
128 RealValues[iii] = evenFieldSampling[i];
129 }
130
131 gsl_fft_real_wavetable *real = gsl_fft_real_wavetable_alloc(2 * num_gridpz_m);
132 gsl_fft_real_workspace *work = gsl_fft_real_workspace_alloc(2 * num_gridpz_m);
133
134 gsl_fft_real_transform(&RealValues[0], 1, 2 * num_gridpz_m, real, work);
135
136 gsl_fft_real_workspace_free(work);
137 gsl_fft_real_wavetable_free(real);
138
139 // normalize to Ez_max = 1 MV/m
140 fourierCoefficients[0] = RealValues[0] / (2 * num_gridpz_m);
141 for(int i = 1; i < 2 * accuracy - 1; i++) {
142 fourierCoefficients[i] = RealValues[i] / num_gridpz_m;
143 }
144
145 return fourierCoefficients;
146}
147
148void Astra1D_fast::computeFieldDerivatives(std::vector<double> & fourierComponents, int accuracy) {
149 double interiorDerivative, base;
150 double coskzl, sinkzl, z = 0.0;
151 std::vector<double> zvals(num_gridpz_m);
152 std::vector<double> higherDerivatives[3];
153 higherDerivatives[0].resize(num_gridpz_m, 0.0);
154 higherDerivatives[1].resize(num_gridpz_m, 0.0);
155 higherDerivatives[2].resize(num_gridpz_m, 0.0);
156
157 for(int i = 0; i < num_gridpz_m; ++ i, z += hz_m) {
158 zvals[i] = z;
159 const double kz = Physics::two_pi * (zvals[i] / length_m + 0.5);
160
161 for(int l = 1; l < accuracy; ++l) {
162 int coefIndex = 2 * l - 1;
163 base = Physics::two_pi / length_m * l;
164 interiorDerivative = base;
165 coskzl = cos(kz * l);
166 sinkzl = sin(kz * l);
167
168 higherDerivatives[0][i] += interiorDerivative * (-fourierComponents[coefIndex] * sinkzl
169 - fourierComponents[coefIndex + 1] * coskzl);
170 interiorDerivative *= base;
171 higherDerivatives[1][i] += interiorDerivative * (-fourierComponents[coefIndex] * coskzl
172 + fourierComponents[coefIndex + 1] * sinkzl);
173 interiorDerivative *= base;
174 higherDerivatives[2][i] += interiorDerivative * (fourierComponents[coefIndex] * sinkzl
175 + fourierComponents[coefIndex + 1] * coskzl);
176 }
177 }
178
179 for(int i = 1; i < 4; ++i) {
180 onAxisInterpolants_m[i] = gsl_spline_alloc(gsl_interp_cspline, num_gridpz_m);
181 onAxisAccel_m[i] = gsl_interp_accel_alloc();
182 gsl_spline_init(onAxisInterpolants_m[i], &zvals[0], &higherDerivatives[i - 1][0], num_gridpz_m);
183 }
184}
185
FLieGenerator< T, N > real(const FLieGenerator< std::complex< T >, N > &)
Take real part of a complex generator.
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
bool determineNumSamplingPoints(std::ifstream &file)
Astra1D_fast(std::string aFilename)
Definition: Astra1D_fast.cpp:9
virtual void freeMap()
double zend_m
Definition: Astra1D_fast.h:44
double readFieldData(std::ifstream &file)
void computeFieldDerivatives(std::vector< double > &fourierComponents, int accuracy)
gsl_spline * onAxisInterpolants_m[4]
Definition: Astra1D_fast.h:38
int numHeaderLines_m
Definition: Astra1D_fast.h:48
virtual void getOnaxisEz(std::vector< std::pair< double, double > > &F)
double length_m
Definition: Astra1D_fast.h:45
virtual ~Astra1D_fast()
std::vector< double > getEvenlyDistributedSamplingPoints()
double * onAxisField_m
Definition: Astra1D_fast.h:36
void normalizeFieldData(double maxEz)
double zbegin_m
Definition: Astra1D_fast.h:43
double * zvals_m
Definition: Astra1D_fast.h:37
std::vector< double > computeFourierCoefficients(int accuracy, std::vector< double > &evenSampling)
gsl_interp_accel * onAxisAccel_m[4]
Definition: Astra1D_fast.h:39
std::vector< double > interpolateFieldData(std::vector< double > &samplingPoints)
virtual void readMap()
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