OPAL (Object Oriented Parallel Accelerator Library)  2024.1
OPAL
Astra1DMagnetoStatic.cpp
Go to the documentation of this file.
2 #include "Fields/Fieldmap.hpp"
3 #include "Physics/Physics.h"
5 #include "Utilities/Util.h"
6 
7 #include "gsl/gsl_interp.h"
8 #include "gsl/gsl_spline.h"
9 #include "gsl/gsl_fft_real.h"
10 
11 #include <fstream>
12 #include <ios>
13 
14 
16  : _Fieldmap(filename),
17  FourCoefs_m(nullptr) {
18  std::ifstream file;
19  int skippedValues = 0;
20  std::string tmpString;
21  double tmpDouble;
22 
24 
25  // open field map, parse it and disable element on error
26  file.open(Filename_m.c_str());
27  if (file.good()) {
28  bool parsing_passed = true;
29  try {
30  parsing_passed = interpretLine<std::string, int>(file, tmpString, accuracy_m);
31  } catch (GeneralClassicException &e) {
32  parsing_passed = interpretLine<std::string, int, std::string>(file, tmpString, accuracy_m, tmpString);
33 
34  tmpString = Util::toUpper(tmpString);
35  if (tmpString != "TRUE" &&
36  tmpString != "FALSE")
37  throw GeneralClassicException("_Astra1DMagnetoStatic::_Astra1DMagnetoStatic",
38  "The third string on the first line of 1D field "
39  "maps has to be either TRUE or FALSE");
40 
41  normalize_m = (tmpString == "TRUE");
42  }
43  parsing_passed = parsing_passed &&
44  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  file.close();
57  num_gridpz_m = lines_read_m - 2 - skippedValues;
58  lines_read_m = 0;
59 
60  if (!parsing_passed && !file.eof()) {
62  zend_m = zbegin_m - 1e-3;
63  throw GeneralClassicException("_Astra1DMagnetoStatic::_Astra1DMagnetoStatic",
64  "An error occured when reading the fieldmap '" + Filename_m + "'");
65  }
66  length_m = 2.0 * num_gridpz_m * (zend_m - zbegin_m) / (num_gridpz_m - 1);
67  } else {
69  zbegin_m = 0.0;
70  zend_m = -1e-3;
71  }
72 }
73 
75  freeMap();
76 }
77 
79 {
80  return Astra1DMagnetoStatic(new _Astra1DMagnetoStatic(filename));
81 }
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 Bz_max = 0.0;
93  double dz = (zend_m - zbegin_m) / (num_gridpz_m - 1);
94  double tmpDouble = zbegin_m - dz;
95 
96  double *RealValues = new double[2 * num_gridpz_m];
97  double *zvals = new double[num_gridpz_m];
98 
99  gsl_spline *Bz_interpolant = gsl_spline_alloc(gsl_interp_cspline, num_gridpz_m);
100  gsl_interp_accel *Bz_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 
111  for (int i = 0; i < num_gridpz_m && parsing_passed;/* skip increment on i here */) {
112  parsing_passed = interpretLine<double, double>(in, zvals[i], RealValues[i]);
113  // the sequence of z-position should be strictly increasing
114  // drop sampling points that don't comply to this
115  if (zvals[i] - tmpDouble > 1e-10) {
116  if (std::abs(RealValues[i]) > Bz_max) {
117  Bz_max = std::abs(RealValues[i]);
118  }
119  tmpDouble = zvals[i];
120  ++ i; // increment i only if sampling point is accepted
121  }
122  }
123  in.close();
124 
125  gsl_spline_init(Bz_interpolant, zvals, RealValues, num_gridpz_m);
126 
127  // get equidistant sampling from the, possibly, non-equidistant sampling
128  // using cubic spline for this
129  int ii = num_gridpz_m;
130  for (int i = 0; i < num_gridpz_m - 1; ++ i, ++ ii) {
131  double z = zbegin_m + dz * i;
132  RealValues[ii] = gsl_spline_eval(Bz_interpolant, z, Bz_accel);
133  }
134  RealValues[ii ++] = RealValues[num_gridpz_m - 1];
135  // prepend mirror sampling points such that field values are periodic for sure
136  -- ii; // ii == 2*num_gridpz_m at the moment
137  for (int i = 0; i < num_gridpz_m; ++ i, -- ii) {
138  RealValues[i] = RealValues[ii];
139  }
140 
141  gsl_fft_real_transform(RealValues, 1, 2 * num_gridpz_m, real, work);
142 
143  if (!normalize_m) {
144  Bz_max = 1.0;
145  }
146  // normalize to Bz_max = 1 A/m
147  FourCoefs_m[0] = RealValues[0] / (Bz_max * 2. * num_gridpz_m);
148  for (int i = 1; i < 2 * accuracy_m - 1; i++) {
149  FourCoefs_m[i] = RealValues[i] / (Bz_max * num_gridpz_m);
150  }
151 
152  gsl_spline_free(Bz_interpolant);
153  gsl_interp_accel_free(Bz_accel);
154 
155  gsl_fft_real_workspace_free(work);
156  gsl_fft_real_wavetable_free(real);
157 
158  delete[] zvals;
159  delete[] RealValues;
160 
161  INFOMSG(level3 << typeset_msg("read in fieldmap '" + Filename_m + "'", "info") << endl);
162  }
163 }
164 
166  if (FourCoefs_m != nullptr) {
167 
168  delete[] FourCoefs_m;
169  FourCoefs_m = nullptr;
170  }
171 }
172 
174  // do fourier interpolation in z-direction
175  const double RR2 = R(0) * R(0) + R(1) * R(1);
176 
177  const double kz = Physics::two_pi * (R(2) - zbegin_m) / length_m + Physics::pi;
178 
179  double ez = FourCoefs_m[0];
180  double ezp = 0.0;
181  double ezpp = 0.0;
182  double ezppp = 0.0;
183 
184  int n = 1;
185  for (int l = 1; l < accuracy_m ; l++, n += 2) {
186  double somefactor_base = Physics::two_pi / length_m * l; // = \frac{d(kz*l)}{dz}
187  double somefactor = 1.0;
188  double coskzl = cos(kz * l);
189  double sinkzl = sin(kz * l);
190  ez += (FourCoefs_m[n] * coskzl - FourCoefs_m[n + 1] * sinkzl);
191  somefactor *= somefactor_base;
192  ezp += somefactor * (-FourCoefs_m[n] * sinkzl - FourCoefs_m[n + 1] * coskzl);
193  somefactor *= somefactor_base;
194  ezpp += somefactor * (-FourCoefs_m[n] * coskzl + FourCoefs_m[n + 1] * sinkzl);
195  somefactor *= somefactor_base;
196  ezppp += somefactor * (FourCoefs_m[n] * sinkzl + FourCoefs_m[n + 1] * coskzl);
197  }
198  // expand the field off-axis
199  const double BfieldR = -ezp / 2. + ezppp / 16. * RR2;
200 
201  B(0) += BfieldR * R(0);
202  B(1) += BfieldR * R(1);
203  B(2) += ez - ezpp * RR2 / 4.;
204 
205  return false;
206 }
207 
208 bool _Astra1DMagnetoStatic::getFieldDerivative(const Vector_t &/*R*/, Vector_t &/*E*/, Vector_t &/*B*/, const DiffDirection &/*dir*/) const {
209  return false;
210 }
211 
212 void _Astra1DMagnetoStatic::getFieldDimensions(double &zBegin, double &zEnd) const {
213  zBegin = zbegin_m;
214  zEnd = zend_m;
215 }
216 void _Astra1DMagnetoStatic::getFieldDimensions(double &/*xIni*/, double &/*xFinal*/, double &/*yIni*/, double &/*yFinal*/, double &/*zIni*/, double &/*zFinal*/) const {}
217 
219 { }
220 
222  (*msg) << Filename_m << " (1D magnetostatic); zini= " << zbegin_m << " m; zfinal= " << zend_m << " m;" << endl;
223 }
224 
226  return 0.0;
227 }
228 
230 { }
virtual void getInfo(Inform *)
virtual bool getFieldstrength(const Vector_t &R, Vector_t &E, Vector_t &B) const
MapType Type
Definition: Fieldmap.h:115
DiffDirection
Definition: Fieldmap.h:55
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)
virtual double getFrequency() const
virtual void setFrequency(double freq)
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
virtual void getFieldDimensions(double &zBegin, double &zEnd) const
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
static Astra1DMagnetoStatic create(const std::string &filename)
_Astra1DMagnetoStatic(const std::string &filename)
std::shared_ptr< _Astra1DMagnetoStatic > Astra1DMagnetoStatic
bool normalize_m
Definition: Fieldmap.h:121
Definition: Inform.h:42
virtual bool getFieldDerivative(const Vector_t &R, Vector_t &E, Vector_t &B, const DiffDirection &dir) const
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
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
FLieGenerator< T, N > real(const FLieGenerator< std::complex< T >, N > &)
Take real part of a complex generator.