OPALX (Object Oriented Parallel Accelerator Library for Exascal) MINIorX
OPALX
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) : Fieldmap(aFilename) {
10 normalize_m = true;
11}
12
16
19
21 if (onAxisField_m != nullptr) {
22 for (int i = 0; i < 4; ++i) {
23 gsl_spline_free(onAxisInterpolants_m[i]);
24 gsl_interp_accel_free(onAxisAccel_m[i]);
25 }
26
27 delete[] onAxisField_m;
28 onAxisField_m = nullptr;
29 delete[] zvals_m;
30 zvals_m = nullptr;
31
32 *ippl::Info << level3 << typeset_msg("freed fieldmap '" + Filename_m + "'", "info") << endl;
33 }
34}
35
36void Astra1D_fast::getOnaxisEz(std::vector<std::pair<double, double> >& /*F*/) {
37}
38
40 double tmpDouble, tmpDouble2;
41 unsigned int skippedValues = 0;
42 bool passed = interpretLine<double, double>(file, zbegin_m, tmpDouble);
43
44 tmpDouble2 = zbegin_m;
45 while (!file.eof() && passed) {
46 passed = interpretLine<double, double>(file, zend_m, tmpDouble, false);
47 if (zend_m - tmpDouble2 > 1e-10) {
48 tmpDouble2 = zend_m;
49 } else if (passed) {
50 ++skippedValues;
51 }
52 }
53
54 num_gridpz_m = lines_read_m - numHeaderLines_m - skippedValues;
55 lines_read_m = 0;
56
57 return passed || file.eof();
58}
59
60double Astra1D_fast::readFieldData(std::ifstream& file) {
61 double tmpDouble = zbegin_m - hz_m;
62 double maxValue = 0;
63 int nsp;
64
65 for (nsp = 0; nsp < num_gridpz_m;) {
67
68 if (zvals_m[nsp] - tmpDouble > 1e-10) {
69 if (std::abs(onAxisField_m[nsp]) > maxValue) {
70 maxValue = std::abs(onAxisField_m[nsp]);
71 }
72 tmpDouble = zvals_m[nsp];
73 ++nsp;
74 }
75 }
76 num_gridpz_m = nsp;
77 hz_m = (zend_m - zbegin_m) / (num_gridpz_m - 1);
78
79 if (!normalize_m)
80 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] =
114 gsl_spline_eval(onAxisInterpolants_m[0], samplingPoints[i], onAxisAccel_m[0]);
115 }
116 realValues[num_gridpz_m - 1] = onAxisField_m[num_gridpz_m - 1];
117
118 return realValues;
119}
120
122 int accuracy, std::vector<double>& evenFieldSampling) {
123 std::vector<double> fourierCoefficients(2 * accuracy - 1);
124 std::vector<double> RealValues(2 * num_gridpz_m, 0.0);
125 int ii = num_gridpz_m, iii = num_gridpz_m - 1;
126
127 for (int i = 0; i < num_gridpz_m; ++i, ++ii, --iii) {
128 RealValues[ii] = evenFieldSampling[i];
129 RealValues[iii] = evenFieldSampling[i];
130 }
131
132 gsl_fft_real_wavetable* real = gsl_fft_real_wavetable_alloc(2 * num_gridpz_m);
133 gsl_fft_real_workspace* work = gsl_fft_real_workspace_alloc(2 * num_gridpz_m);
134
135 gsl_fft_real_transform(&RealValues[0], 1, 2 * num_gridpz_m, real, work);
136
137 gsl_fft_real_workspace_free(work);
138 gsl_fft_real_wavetable_free(real);
139
140 // normalize to Ez_max = 1 MV/m
141 fourierCoefficients[0] = RealValues[0] / (2 * num_gridpz_m);
142 for (int i = 1; i < 2 * accuracy - 1; i++) {
143 fourierCoefficients[i] = RealValues[i] / num_gridpz_m;
144 }
145
146 return fourierCoefficients;
147}
148
149void Astra1D_fast::computeFieldDerivatives(std::vector<double>& fourierComponents, int accuracy) {
150 double interiorDerivative, base;
151 double coskzl, sinkzl, z = 0.0;
152 std::vector<double> zvals(num_gridpz_m);
153 std::vector<double> higherDerivatives[3];
154 higherDerivatives[0].resize(num_gridpz_m, 0.0);
155 higherDerivatives[1].resize(num_gridpz_m, 0.0);
156 higherDerivatives[2].resize(num_gridpz_m, 0.0);
157
158 for (int i = 0; i < num_gridpz_m; ++i, z += hz_m) {
159 zvals[i] = z;
160 const double kz = Physics::two_pi * (zvals[i] / length_m + 0.5);
161
162 for (int l = 1; l < accuracy; ++l) {
163 int coefIndex = 2 * l - 1;
164 base = Physics::two_pi / length_m * l;
165 interiorDerivative = base;
166 coskzl = cos(kz * l);
167 sinkzl = sin(kz * l);
168
169 higherDerivatives[0][i] += interiorDerivative
170 * (-fourierComponents[coefIndex] * sinkzl
171 - fourierComponents[coefIndex + 1] * coskzl);
172 interiorDerivative *= base;
173 higherDerivatives[1][i] += interiorDerivative
174 * (-fourierComponents[coefIndex] * coskzl
175 + fourierComponents[coefIndex + 1] * sinkzl);
176 interiorDerivative *= base;
177 higherDerivatives[2][i] += interiorDerivative
178 * (fourierComponents[coefIndex] * sinkzl
179 + fourierComponents[coefIndex + 1] * coskzl);
180 }
181 }
182
183 for (int i = 1; i < 4; ++i) {
184 onAxisInterpolants_m[i] = gsl_spline_alloc(gsl_interp_cspline, num_gridpz_m);
185 onAxisAccel_m[i] = gsl_interp_accel_alloc();
186 gsl_spline_init(
187 onAxisInterpolants_m[i], &zvals[0], &higherDerivatives[i - 1][0], num_gridpz_m);
188 }
189}
constexpr double two_pi
The value of.
Definition Physics.h:33
bool determineNumSamplingPoints(std::ifstream &file)
Astra1D_fast(std::string aFilename)
virtual void freeMap()
double readFieldData(std::ifstream &file)
void computeFieldDerivatives(std::vector< double > &fourierComponents, int accuracy)
gsl_spline * onAxisInterpolants_m[4]
friend class Fieldmap
virtual void getOnaxisEz(std::vector< std::pair< double, double > > &F)
double length_m
virtual ~Astra1D_fast()
std::vector< double > getEvenlyDistributedSamplingPoints()
double * onAxisField_m
void normalizeFieldData(double maxEz)
double zbegin_m
double * zvals_m
std::vector< double > computeFourierCoefficients(int accuracy, std::vector< double > &evenSampling)
gsl_interp_accel * onAxisAccel_m[4]
std::vector< double > interpolateFieldData(std::vector< double > &samplingPoints)
virtual void readMap()
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)