OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
Astra1D_fast.cpp
Go to the documentation of this file.
1 #include "Fields/Astra1D_fast.h"
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 
9 Astra1D_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 != NULL) {
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 = NULL;
30  delete[] zvals_m;
31  zvals_m = NULL;
32 
33  INFOMSG(level3 << typeset_msg("freed fieldmap '" + Filename_m + "'", "info") << endl);
34  }
35 }
36 
37 void Astra1D_fast::getOnaxisEz(std::vector<std::pair<double, double> > & F)
38 { }
39 
40 bool Astra1D_fast::determineNumSamplingPoints(std::ifstream &file) {
41  double tmpDouble, tmpDouble2;
42  unsigned int skippedValues = 0;
43  bool passed = interpreteLine<double, double>(file, zbegin_m, tmpDouble);
44 
45  tmpDouble2 = zbegin_m;
46  while (!file.eof() && passed) {
47  passed = interpreteLine<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 
61 double 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  interpreteLine<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 
85 void 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 
104 std::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 
120 std::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 
148 void 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 }
double zend_m
Definition: Astra1D_fast.h:44
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
constexpr double e
The value of .
Definition: Physics.h:40
gsl_spline * onAxisInterpolants_m[4]
Definition: Astra1D_fast.h:38
double length_m
Definition: Astra1D_fast.h:45
virtual void freeMap()
Tps< T > sin(const Tps< T > &x)
Sine.
Definition: TpsMath.h:111
constexpr double two_pi
The value of .
Definition: Physics.h:34
virtual ~Astra1D_fast()
double * onAxisField_m
Definition: Astra1D_fast.h:36
std::vector< double > getEvenlyDistributedSamplingPoints()
static std::string typeset_msg(const std::string &msg, const std::string &title)
Definition: Fieldmap.cpp:647
virtual void readMap()
bool determineNumSamplingPoints(std::ifstream &file)
bool normalize_m
Definition: Fieldmap.h:113
FLieGenerator< T, N > real(const FLieGenerator< std::complex< T >, N > &)
Take real part of a complex generator.
int lines_read_m
Definition: Fieldmap.h:111
std::vector< double > interpolateFieldData(std::vector< double > &samplingPoints)
double readFieldData(std::ifstream &file)
virtual void getOnaxisEz(std::vector< std::pair< double, double > > &F)
#define INFOMSG(msg)
Definition: IpplInfo.h:397
double * zvals_m
Definition: Astra1D_fast.h:37
gsl_interp_accel * onAxisAccel_m[4]
Definition: Astra1D_fast.h:39
void computeFieldDerivatives(std::vector< double > &fourierComponents, int accuracy)
double zbegin_m
Definition: Astra1D_fast.h:43
std::vector< double > computeFourierCoefficients(int accuracy, std::vector< double > &evenSampling)
Astra1D_fast(std::string aFilename)
Definition: Astra1D_fast.cpp:9
Tps< T > cos(const Tps< T > &x)
Cosine.
Definition: TpsMath.h:129
std::string Filename_m
Definition: Fieldmap.h:110
int numHeaderLines_m
Definition: Astra1D_fast.h:48
Inform & level3(Inform &inf)
Definition: Inform.cpp:47
void normalizeFieldData(double maxEz)
Inform & endl(Inform &inf)
Definition: Inform.cpp:42