OPAL (Object Oriented Parallel Accelerator Library)  2024.1
OPAL
Astra1DDynamic_fast.cpp
Go to the documentation of this file.
1 //
2 // Class _Astra1DDynamic_fast
3 //
4 // This class provides a reader for Astra style field maps. It pre-computes the field
5 // on a lattice to increase the performance during simulation.
6 //
7 // Copyright (c) 2016, Christof Metzger-Kraus, Helmholtz-Zentrum Berlin, Germany
8 // 2017 - 2020 Christof Metzger-Kraus
9 //
10 // All rights reserved
11 //
12 // This file is part of OPAL.
13 //
14 // OPAL is free software: you can redistribute it and/or modify
15 // it under the terms of the GNU General Public License as published by
16 // the Free Software Foundation, either version 3 of the License, or
17 // (at your option) any later version.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with OPAL. If not, see <https://www.gnu.org/licenses/>.
21 //
23 #include "Physics/Physics.h"
24 #include "Physics/Units.h"
27 #include "Utilities/Util.h"
28 
29 #include <fstream>
30 #include <ios>
31 
32 _Astra1DDynamic_fast::_Astra1DDynamic_fast(const std::string& filename):
33  _Astra1D_fast(filename)
34 {
35  numHeaderLines_m = 3;
36 
37  onAxisField_m = nullptr;
38 
40 
41  // open field map, parse it and disable element on error
42  std::ifstream file(Filename_m.c_str());
43  if(!file.good()) {
45  zbegin_m = 0.0;
46  zend_m = -1e-3;
47  return;
48  }
49 
50  bool parsing_passed = readFileHeader(file);
51 
52  parsing_passed = parsing_passed && determineNumSamplingPoints(file);
53  file.close();
54 
55  if(!parsing_passed) {
57  zend_m = zbegin_m - 1e-3;
58  throw GeneralClassicException("_Astra1DDynamic_fast::_Astra1DDynamic_fast",
59  "An error occured when reading the fieldmap '" + Filename_m + "'");
60  }
61 
62  // conversion from MHz to Hz and from frequency to angular frequency
65 
66  hz_m = (zend_m - zbegin_m) / (num_gridpz_m - 1);
67  length_m = 2.0 * num_gridpz_m * hz_m;
68 }
69 
71  freeMap();
72 }
73 
75 {
76  return Astra1DDynamic_fast(new _Astra1DDynamic_fast(filename));
77 }
78 
80  if(onAxisField_m == nullptr) {
81  std::ifstream file(Filename_m.c_str());
82 
83  onAxisField_m = new double[num_gridpz_m];
84  zvals_m = new double[num_gridpz_m];
85 
86  int accuracy = stripFileHeader(file);
87  double maxEz = readFieldData(file);
88  file.close();
89 
91 
92  std::vector<double> zvals = getEvenlyDistributedSamplingPoints();
93  std::vector<double> evenFieldSampling = interpolateFieldData(zvals);
94  std::vector<double> fourierCoefs = computeFourierCoefficients(accuracy, evenFieldSampling);
95 
96  computeFieldDerivatives(fourierCoefs, accuracy);
97 
98  checkMap(accuracy,
99  length_m,
100  zvals,
101  fourierCoefs,
103  onAxisAccel_m[0]);
104 
105  INFOMSG(level3 << typeset_msg("read in fieldmap '" + Filename_m + "'", "info") << endl);
106  }
107 }
108 
110  // do fourier interpolation in z-direction
111  const double RR2 = R(0) * R(0) + R(1) * R(1);
112 
113  double ez, ezp, ezpp, ezppp;
114  try {
115  ez = gsl_spline_eval(onAxisInterpolants_m[0], R(2) - zbegin_m, onAxisAccel_m[0]);
116  ezp = gsl_spline_eval(onAxisInterpolants_m[1], R(2) - zbegin_m, onAxisAccel_m[1]);
117  ezpp = gsl_spline_eval(onAxisInterpolants_m[2], R(2) - zbegin_m, onAxisAccel_m[2]);
118  ezppp = gsl_spline_eval(onAxisInterpolants_m[3], R(2) - zbegin_m, onAxisAccel_m[3]);
119  } catch (OpalException const& e) {
120  throw OpalException("_Astra1DDynamic_fast::getFieldstrength",
121  "The requested interpolation point, " + std::to_string(R(2)) + " is out of range");
122  }
123  // expand the field off-axis
124  const double f = -(ezpp + ez * xlrep_m * xlrep_m) / 16.;
125  const double fp = -(ezppp + ezp * xlrep_m * xlrep_m) / 16.;
126 
127  const double EfieldR = -(ezp / 2. + fp * RR2);
128  const double BfieldT = (ez / 2. + f * RR2) * xlrep_m / Physics::c;
129 
130  E(0) += EfieldR * R(0);
131  E(1) += EfieldR * R(1);
132  E(2) += ez + 4. * f * RR2;
133  B(0) += -BfieldT * R(1);
134  B(1) += BfieldT * R(0);
135 
136  return false;
137 }
138 
139 bool _Astra1DDynamic_fast::getFieldDerivative(const Vector_t &R, Vector_t &E, Vector_t &/*B*/, const DiffDirection &/*dir*/) const {
140  double ezp = gsl_spline_eval(onAxisInterpolants_m[1], R(2) - zbegin_m, onAxisAccel_m[1]);
141 
142  E(2) += ezp;
143 
144  return false;
145 }
146 
147 void _Astra1DDynamic_fast::getFieldDimensions(double &zBegin, double &zEnd) const {
148  zBegin = zbegin_m;
149  zEnd = zend_m;
150 }
151 
152 void _Astra1DDynamic_fast::getFieldDimensions(double &/*xIni*/, double &/*xFinal*/, double &/*yIni*/, double &/*yFinal*/, double &/*zIni*/, double &/*zFinal*/) const {}
153 
155 { }
156 
158  (*msg) << Filename_m << " (1D dynamic); zini= " << zbegin_m << " m; zfinal= " << zend_m << " m;" << endl;
159 }
160 
162  return frequency_m;
163 }
164 
166  frequency_m = freq;
167 }
168 
169 void _Astra1DDynamic_fast::getOnaxisEz(std::vector<std::pair<double, double> > & F) {
170  F.resize(num_gridpz_m);
171  if(onAxisField_m == nullptr) {
172  double Ez_max = 0.0;
173  double tmpDouble;
174  int tmpInt;
175  std::string tmpString;
176 
177  std::ifstream in(Filename_m.c_str());
178  interpretLine<std::string, int>(in, tmpString, tmpInt);
179  interpretLine<double, double, int>(in, tmpDouble, tmpDouble, tmpInt);
180  interpretLine<double>(in, tmpDouble);
181  interpretLine<double, double, int>(in, tmpDouble, tmpDouble, tmpInt);
182 
183  for(int i = 0; i < num_gridpz_m; ++ i) {
184  F[i].first = hz_m * i;
185  interpretLine<double>(in, F[i].second);
186  if(std::abs(F[i].second) > Ez_max) {
187  Ez_max = std::abs(F[i].second);
188  }
189  }
190  in.close();
191 
192  for(int i = 0; i < num_gridpz_m; ++ i) {
193  F[i].second /= Ez_max;
194  }
195  } else {
196  for(int i = 0; i < num_gridpz_m; ++ i) {
197  F[i].first = zvals_m[i];
198  F[i].second = onAxisField_m[i] / 1e6;
199  }
200  }
201 }
202 
203 bool _Astra1DDynamic_fast::readFileHeader(std::ifstream &file) {
204  std::string tmpString;
205  int tmpInt;
206  bool passed = true;
207 
208  try {
209  passed = interpretLine<std::string, int>(file, tmpString, tmpInt);
210  } catch (GeneralClassicException &e) {
211  passed = interpretLine<std::string, int, std::string>(file, tmpString, tmpInt, tmpString);
212 
213  tmpString = Util::toUpper(tmpString);
214  if (tmpString != "TRUE" &&
215  tmpString != "FALSE")
216  throw GeneralClassicException("_Astra1DDynamic_fast::readFileHeader",
217  "The third string on the first line of 1D field "
218  "maps has to be either TRUE or FALSE");
219 
220  normalize_m = (tmpString == "TRUE");
221  }
222 
223  passed = passed && interpretLine<double>(file, frequency_m);
224 
225  return passed;
226 }
227 
228 int _Astra1DDynamic_fast::stripFileHeader(std::ifstream &file) {
229  std::string tmpString;
230  double tmpDouble;
231  int accuracy;
232 
233  try {
234  interpretLine<std::string, int>(file, tmpString, accuracy);
235  } catch (GeneralClassicException &e) {
236  interpretLine<std::string, int, std::string>(file, tmpString, accuracy, tmpString);
237  }
238 
239  interpretLine<double>(file, tmpDouble);
240 
241  return accuracy;
242 }
virtual bool getFieldDerivative(const Vector_t &R, Vector_t &E, Vector_t &B, const DiffDirection &dir) const
_Astra1DDynamic_fast(const std::string &filename)
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:45
static Astra1DDynamic_fast create(const std::string &filename)
MapType Type
Definition: Fieldmap.h:115
int numHeaderLines_m
Definition: Astra1D_fast.h:49
DiffDirection
Definition: Fieldmap.h:55
std::shared_ptr< _Astra1DDynamic_fast > Astra1DDynamic_fast
constexpr double two_pi
The value of .
Definition: Physics.h:33
void noFieldmapWarning()
Definition: Fieldmap.cpp:618
double length_m
Definition: Astra1D_fast.h:46
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
virtual void getFieldDimensions(double &zBegin, double &zEnd) const
virtual void setFrequency(double freq)
double zbegin_m
Definition: Astra1D_fast.h:44
virtual void getOnaxisEz(std::vector< std::pair< double, double > > &F)
static std::string typeset_msg(const std::string &msg, const std::string &title)
Definition: Fieldmap.cpp:649
virtual bool getFieldstrength(const Vector_t &R, Vector_t &E, Vector_t &B) const
gsl_spline * onAxisInterpolants_m[4]
Definition: Astra1D_fast.h:39
std::string toUpper(const std::string &str)
Definition: Util.cpp:147
constexpr double Vpm2MVpm
Definition: Units.h:125
#define INFOMSG(msg)
Definition: IpplInfo.h:348
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
std::vector< double > interpolateFieldData(std::vector< double > &samplingPoints)
double * onAxisField_m
Definition: Astra1D_fast.h:37
virtual void freeMap()
void normalizeFieldData(double maxEz)
virtual double getFrequency() const
double readFieldData(std::ifstream &file)
The base class for all OPAL exceptions.
Definition: OpalException.h:28
bool normalize_m
Definition: Fieldmap.h:121
Definition: Inform.h:42
bool readFileHeader(std::ifstream &file)
std::vector< double > getEvenlyDistributedSamplingPoints()
void disableFieldmapWarning()
Definition: Fieldmap.cpp:610
constexpr double MHz2Hz
Definition: Units.h:113
gsl_interp_accel * onAxisAccel_m[4]
Definition: Astra1D_fast.h:40
int stripFileHeader(std::ifstream &file)
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
void computeFieldDerivatives(std::vector< double > &fourierComponents, int accuracy)
std::vector< double > computeFourierCoefficients(int accuracy, std::vector< double > &evenSampling)
double * zvals_m
Definition: Astra1D_fast.h:38
void checkMap(unsigned int accuracy, std::pair< double, double > fieldDimensions, double deltaZ, const std::vector< double > &fourierCoefficients, gsl_spline *splineCoefficients, gsl_interp_accel *splineAccelerator)
Definition: Fieldmap.cpp:448
virtual void getInfo(Inform *)
bool determineNumSamplingPoints(std::ifstream &file)