OPAL (Object Oriented Parallel Accelerator Library)  2024.1
OPAL
Astra1DElectroStatic.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 
16  : _Fieldmap(filename),
17  FourCoefs_m(nullptr) {
18 
19  std::ifstream file;
20  int skippedValues = 0;
21  std::string tmpString;
22  double tmpDouble;
23 
25 
26  // open field map, parse it and disable element on error
27  file.open(Filename_m.c_str());
28  if (file.good()) {
29  bool parsing_passed = true;
30  try {
31  parsing_passed = interpretLine<std::string, int>(file, tmpString, accuracy_m);
32  } catch (GeneralClassicException &e) {
33  parsing_passed = interpretLine<std::string, int, std::string>(file,
34  tmpString,
35  accuracy_m,
36  tmpString);
37 
38  tmpString = Util::toUpper(tmpString);
39  if (tmpString != "TRUE" &&
40  tmpString != "FALSE")
41  throw GeneralClassicException("_Astra1DElectroStatic::_Astra1DElectroStatic",
42  "The third string on the first line of 1D field "
43  "maps has to be either TRUE or FALSE");
44 
45  normalize_m = (tmpString == "TRUE");
46  }
47 
48  parsing_passed = parsing_passed &&
49  interpretLine<double, double>(file, zbegin_m, tmpDouble);
50 
51  double tmpDouble2 = zbegin_m;
52  while(!file.eof() && parsing_passed) {
53  parsing_passed = interpretLine<double, double>(file, zend_m, tmpDouble, false);
54  if (zend_m - tmpDouble2 > 1e-10) {
55  tmpDouble2 = zend_m;
56  } else if (parsing_passed) {
57  ++ skippedValues;
58  }
59  }
60 
61  num_gridpz_m = lines_read_m - 2 - skippedValues;
62  lines_read_m = 0;
63 
64  if (!parsing_passed && !file.eof()) {
66  zend_m = zbegin_m - 1e-3;
67  throw GeneralClassicException("_Astra1DElectroStatic::_Astra1DElectroStatic",
68  "An error occured when reading the fieldmap '" + Filename_m + "'");
69  }
70  length_m = 2.0 * num_gridpz_m * (zend_m - zbegin_m) / (num_gridpz_m - 1);
71  file.close();
72  } else {
74  zbegin_m = 0.0;
75  zend_m = -1e-3;
76  }
77 }
78 
80  freeMap();
81 }
82 
84 {
85  return Astra1DElectroStatic(new _Astra1DElectroStatic(filename));
86 }
87 
89  if (FourCoefs_m == nullptr) {
90  // declare variables and allocate memory
91 
92  std::ifstream in;
93 
94  bool parsing_passed = true;
95 
96  std::string tmpString;
97 
98  double Ez_max = 0.0;
99  double dz = (zend_m - zbegin_m) / (num_gridpz_m - 1);
100  double tmpDouble = zbegin_m - dz;
101 
102  double *RealValues = new double[2 * num_gridpz_m];
103  double *zvals = new double[num_gridpz_m];
104 
105  gsl_spline *Ez_interpolant = gsl_spline_alloc(gsl_interp_cspline, num_gridpz_m);
106  gsl_interp_accel *Ez_accel = gsl_interp_accel_alloc();
107 
108  gsl_fft_real_wavetable *real = gsl_fft_real_wavetable_alloc(2 * num_gridpz_m);
109  gsl_fft_real_workspace *work = gsl_fft_real_workspace_alloc(2 * num_gridpz_m);
110 
111  FourCoefs_m = new double[2 * accuracy_m - 1];
112 
113  // read in and parse field map
114  in.open(Filename_m.c_str());
115  getLine(in, tmpString);
116 
117  for (int i = 0; i < num_gridpz_m && parsing_passed; /* skip increment of i here */) {
118  parsing_passed = interpretLine<double, double>(in, zvals[i], RealValues[i]);
119  // the sequence of z-position should be strictly increasing
120  // drop sampling points that don't comply to this
121  if (zvals[i] - tmpDouble > 1e-10) {
122  if (std::abs(RealValues[i]) > Ez_max) {
123  Ez_max = std::abs(RealValues[i]);
124  }
125  tmpDouble = zvals[i];
126  ++ i; // increment i only if sampling point is accepted
127  }
128  }
129  in.close();
130 
131  gsl_spline_init(Ez_interpolant, zvals, RealValues, num_gridpz_m);
132 
133  // get equidistant sampling from the, possibly, non-equidistant sampling
134  // using cubic spline for this
135  int ii = num_gridpz_m;
136  for (int i = 0; i < num_gridpz_m - 1; ++ i, ++ ii) {
137  double z = zbegin_m + dz * i;
138  RealValues[ii] = gsl_spline_eval(Ez_interpolant, z, Ez_accel);
139  }
140  RealValues[ii ++] = RealValues[num_gridpz_m - 1];
141  // prepend mirror sampling points such that field values are periodic for sure
142  -- ii; // ii == 2*num_gridpz_m at the moment
143  for (int i = 0; i < num_gridpz_m; ++ i, -- ii) {
144  RealValues[i] = RealValues[ii];
145  }
146 
147 
148  num_gridpz_m *= 2; // we doubled the sampling points
149 
150  gsl_fft_real_transform(RealValues, 1, num_gridpz_m, real, work);
151 
152  if (!normalize_m)
153  Ez_max = 1.0;
154 
155  // normalize to Ez_max = 1 MV/m
156  FourCoefs_m[0] = Units::MVpm2Vpm * RealValues[0] / (Ez_max * num_gridpz_m);
157  for (int i = 1; i < 2 * accuracy_m - 1; i++) {
158  FourCoefs_m[i] = Units::MVpm2Vpm * 2.* RealValues[i] / (Ez_max * num_gridpz_m);
159  }
160 
161  gsl_fft_real_workspace_free(work);
162  gsl_fft_real_wavetable_free(real);
163 
164  gsl_spline_free(Ez_interpolant);
165  gsl_interp_accel_free(Ez_accel);
166 
167  delete[] zvals;
168  delete[] RealValues;
169 
170  INFOMSG(level3 << typeset_msg("read in fieldmap '" + Filename_m + "'", "info") << endl);
171 
172  }
173 }
174 
176  if (FourCoefs_m != nullptr) {
177 
178  delete[] FourCoefs_m;
179  FourCoefs_m = nullptr;
180  }
181 }
182 
184  // do fourier interpolation in z-direction
185  const double RR2 = R(0) * R(0) + R(1) * R(1);
186 
187  const double kz = Physics::two_pi * (R(2) - zbegin_m) / length_m + Physics::pi;
188 
189  double ez = FourCoefs_m[0];
190  double ezp = 0.0;
191  double ezpp = 0.0;
192  double ezppp = 0.0;
193 
194  int n = 1;
195  for (int l = 1; l < accuracy_m ; l++, n += 2) {
196  double somefactor_base = Physics::two_pi / length_m * l; // = \frac{d(kz*l)}{dz}
197  double somefactor = 1.0;
198  double coskzl = cos(kz * l);
199  double sinkzl = sin(kz * l);
200  ez += (FourCoefs_m[n] * coskzl - FourCoefs_m[n + 1] * sinkzl);
201  somefactor *= somefactor_base;
202  ezp += somefactor * (-FourCoefs_m[n] * sinkzl - FourCoefs_m[n + 1] * coskzl);
203  somefactor *= somefactor_base;
204  ezpp += somefactor * (-FourCoefs_m[n] * coskzl + FourCoefs_m[n + 1] * sinkzl);
205  somefactor *= somefactor_base;
206  ezppp += somefactor * (FourCoefs_m[n] * sinkzl + FourCoefs_m[n + 1] * coskzl);
207  }
208 
209  // expand the field to off-axis
210  const double EfieldR = -ezp / 2. + ezppp / 16. * RR2;
211 
212  E(0) += EfieldR * R(0);
213  E(1) += EfieldR * R(1);
214  E(2) += ez - ezpp * RR2 / 4.;
215  return false;
216 }
217 
218 bool _Astra1DElectroStatic::getFieldDerivative(const Vector_t &/*R*/, Vector_t &/*E*/, Vector_t &/*B*/, const DiffDirection &/*dir*/) const {
219  return false;
220 }
221 
222 void _Astra1DElectroStatic::getFieldDimensions(double &zBegin, double &zEnd) const {
223  zBegin = zbegin_m;
224  zEnd = zend_m;
225 }
226 
227 void _Astra1DElectroStatic::getFieldDimensions(double &/*xIni*/, double &/*xFinal*/, double &/*yIni*/, double &/*yFinal*/, double &/*zIni*/, double &/*zFinal*/) const {}
228 
230 { }
231 
233  (*msg) << Filename_m << " (1D electrostatic); zini= " << zbegin_m << " m; zfinal= " << zend_m << " m;" << endl;
234 }
235 
237  return 0.0;
238 }
239 
241 { }
static Astra1DElectroStatic create(const std::string &filename)
virtual double getFrequency() const
virtual void getFieldDimensions(double &zBegin, double &zEnd) const
MapType Type
Definition: Fieldmap.h:115
virtual bool getFieldstrength(const Vector_t &R, Vector_t &E, Vector_t &B) const
DiffDirection
Definition: Fieldmap.h:55
constexpr double MVpm2Vpm
Definition: Units.h:128
constexpr double two_pi
The value of .
Definition: Physics.h:33
void noFieldmapWarning()
Definition: Fieldmap.cpp:618
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
int lines_read_m
Definition: Fieldmap.h:119
static std::string typeset_msg(const std::string &msg, const std::string &title)
Definition: Fieldmap.cpp:649
constexpr double pi
The value of .
Definition: Physics.h:30
std::string toUpper(const std::string &str)
Definition: Util.cpp:147
#define INFOMSG(msg)
Definition: IpplInfo.h:348
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
_Astra1DElectroStatic(const std::string &filename)
virtual void setFrequency(double freq)
bool normalize_m
Definition: Fieldmap.h:121
Definition: Inform.h:42
virtual void getInfo(Inform *)
void disableFieldmapWarning()
Definition: Fieldmap.cpp:610
Tps< T > cos(const Tps< T > &x)
Cosine.
Definition: TpsMath.h:129
and that you know you can do these things To protect your we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights These restrictions translate to certain responsibilities for you if you distribute copies of the or if you modify it For if you distribute copies of such a whether gratis or for a you must give the recipients all the rights that you have You must make sure that receive or can get the source code And you must show them these terms so they know their rights We protect your rights with two distribute and or modify the software for each author s protection and we want to make certain that everyone understands that there is no warranty for this free software If the software is modified by someone else and passed we want its recipients to know that what they have is not the so that any problems introduced by others will not reflect on the original authors reputations any free program is threatened constantly by software patents We wish to avoid the danger that redistributors of a free program will individually obtain patent in effect making the program proprietary To prevent we have made it clear that any patent must be licensed for everyone s free use or not licensed at all The precise terms and conditions for distribution and modification follow GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR DISTRIBUTION AND MODIFICATION This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License The refers to any such program or work
Definition: LICENSE:43
void getLine(std::ifstream &in, std::string &buffer)
Definition: Fieldmap.h:122
std::shared_ptr< _Astra1DElectroStatic > Astra1DElectroStatic
Inform & level3(Inform &inf)
Definition: Inform.cpp:47
constexpr double e
The value of .
Definition: Physics.h:39
std::string Filename_m
Definition: Fieldmap.h:118
Tps< T > sin(const Tps< T > &x)
Sine.
Definition: TpsMath.h:111
virtual bool getFieldDerivative(const Vector_t &R, Vector_t &E, Vector_t &B, const DiffDirection &dir) const
FLieGenerator< T, N > real(const FLieGenerator< std::complex< T >, N > &)
Take real part of a complex generator.