OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
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 //
24 #include "Utilities/Util.h"
26 #include "Physics/Physics.h"
27 
28 #include <fstream>
29 #include <ios>
30 
32  Astra1D_fast(aFilename)
33 {
34  numHeaderLines_m = 3;
35 
36  onAxisField_m = NULL;
37 
39 
40  // open field map, parse it and disable element on error
41  std::ifstream file(Filename_m.c_str());
42  if(!file.good()) {
44  zbegin_m = 0.0;
45  zend_m = -1e-3;
46  return;
47  }
48 
49  bool parsing_passed = readFileHeader(file);
50 
51  parsing_passed = parsing_passed && determineNumSamplingPoints(file);
52  file.close();
53 
54  if(!parsing_passed) {
56  zend_m = zbegin_m - 1e-3;
57  throw GeneralClassicException("Astra1DDynamic_fast::Astra1DDynamic_fast",
58  "An error occured when reading the fieldmap '" + Filename_m + "'");
59  }
60 
61  // conversion from MHz to Hz and from frequency to angular frequency
64 
65  hz_m = (zend_m - zbegin_m) / (num_gridpz_m - 1);
66  length_m = 2.0 * num_gridpz_m * hz_m;
67 }
68 
70  freeMap();
71 }
72 
74  if(onAxisField_m == NULL) {
75  std::ifstream file(Filename_m.c_str());
76 
77  onAxisField_m = new double[num_gridpz_m];
78  zvals_m = new double[num_gridpz_m];
79 
80  int accuracy = stripFileHeader(file);
81  double maxEz = readFieldData(file);
82  file.close();
83 
84  normalizeFieldData(maxEz * 1e-6);
85 
86  std::vector<double> zvals = getEvenlyDistributedSamplingPoints();
87  std::vector<double> evenFieldSampling = interpolateFieldData(zvals);
88  std::vector<double> fourierCoefs = computeFourierCoefficients(accuracy, evenFieldSampling);
89 
90  computeFieldDerivatives(fourierCoefs, accuracy);
91 
92  checkMap(accuracy,
93  length_m,
94  zvals,
95  fourierCoefs,
97  onAxisAccel_m[0]);
98 
99  INFOMSG(level3 << typeset_msg("read in fieldmap '" + Filename_m + "'", "info") << endl);
100  }
101 }
102 
104  // do fourier interpolation in z-direction
105  const double RR2 = R(0) * R(0) + R(1) * R(1);
106 
107  double ez, ezp, ezpp, ezppp;
108  try {
109  ez = gsl_spline_eval(onAxisInterpolants_m[0], R(2) - zbegin_m, onAxisAccel_m[0]);
110  ezp = gsl_spline_eval(onAxisInterpolants_m[1], R(2) - zbegin_m, onAxisAccel_m[1]);
111  ezpp = gsl_spline_eval(onAxisInterpolants_m[2], R(2) - zbegin_m, onAxisAccel_m[2]);
112  ezppp = gsl_spline_eval(onAxisInterpolants_m[3], R(2) - zbegin_m, onAxisAccel_m[3]);
113  } catch (OpalException const& e) {
114  throw OpalException("Astra1DDynamic_fast::getFieldstrength",
115  "The requested interpolation point, " + std::to_string(R(2)) + " is out of range");
116  }
117  // expand the field off-axis
118  const double f = -(ezpp + ez * xlrep_m * xlrep_m) / 16.;
119  const double fp = -(ezppp + ezp * xlrep_m * xlrep_m) / 16.;
120 
121  const double EfieldR = -(ezp / 2. + fp * RR2);
122  const double BfieldT = (ez / 2. + f * RR2) * xlrep_m / Physics::c;
123 
124  E(0) += EfieldR * R(0);
125  E(1) += EfieldR * R(1);
126  E(2) += ez + 4. * f * RR2;
127  B(0) += -BfieldT * R(1);
128  B(1) += BfieldT * R(0);
129 
130  return false;
131 }
132 
133 bool Astra1DDynamic_fast::getFieldDerivative(const Vector_t &R, Vector_t &E, Vector_t &/*B*/, const DiffDirection &/*dir*/) const {
134  double ezp = gsl_spline_eval(onAxisInterpolants_m[1], R(2) - zbegin_m, onAxisAccel_m[1]);
135 
136  E(2) += ezp;
137 
138  return false;
139 }
140 
141 void Astra1DDynamic_fast::getFieldDimensions(double &zBegin, double &zEnd) const {
142  zBegin = zbegin_m;
143  zEnd = zend_m;
144 }
145 
146 void Astra1DDynamic_fast::getFieldDimensions(double &/*xIni*/, double &/*xFinal*/, double &/*yIni*/, double &/*yFinal*/, double &/*zIni*/, double &/*zFinal*/) const {}
147 
149 { }
150 
152  (*msg) << Filename_m << " (1D dynamic); zini= " << zbegin_m << " m; zfinal= " << zend_m << " m;" << endl;
153 }
154 
156  return frequency_m;
157 }
158 
160  frequency_m = freq;
161 }
162 
163 void Astra1DDynamic_fast::getOnaxisEz(std::vector<std::pair<double, double> > & F) {
164  F.resize(num_gridpz_m);
165  if(onAxisField_m == NULL) {
166  double Ez_max = 0.0;
167  double tmpDouble;
168  int tmpInt;
169  std::string tmpString;
170 
171  std::ifstream in(Filename_m.c_str());
172  interpretLine<std::string, int>(in, tmpString, tmpInt);
173  interpretLine<double, double, int>(in, tmpDouble, tmpDouble, tmpInt);
174  interpretLine<double>(in, tmpDouble);
175  interpretLine<double, double, int>(in, tmpDouble, tmpDouble, tmpInt);
176 
177  for(int i = 0; i < num_gridpz_m; ++ i) {
178  F[i].first = hz_m * i;
179  interpretLine<double>(in, F[i].second);
180  if(std::abs(F[i].second) > Ez_max) {
181  Ez_max = std::abs(F[i].second);
182  }
183  }
184  in.close();
185 
186  for(int i = 0; i < num_gridpz_m; ++ i) {
187  F[i].second /= Ez_max;
188  }
189  } else {
190  for(int i = 0; i < num_gridpz_m; ++ i) {
191  F[i].first = zvals_m[i];
192  F[i].second = onAxisField_m[i] / 1e6;
193  }
194  }
195 }
196 
197 bool Astra1DDynamic_fast::readFileHeader(std::ifstream &file) {
198  std::string tmpString;
199  int tmpInt;
200  bool passed = true;
201 
202  try {
203  passed = interpretLine<std::string, int>(file, tmpString, tmpInt);
204  } catch (GeneralClassicException &e) {
205  passed = interpretLine<std::string, int, std::string>(file, tmpString, tmpInt, tmpString);
206 
207  tmpString = Util::toUpper(tmpString);
208  if (tmpString != "TRUE" &&
209  tmpString != "FALSE")
210  throw GeneralClassicException("Astra1DDynamic_fast::readFileHeader",
211  "The third string on the first line of 1D field "
212  "maps has to be either TRUE or FALSE");
213 
214  normalize_m = (tmpString == "TRUE");
215  }
216 
217  passed = passed && interpretLine<double>(file, frequency_m);
218 
219  return passed;
220 }
221 
222 int Astra1DDynamic_fast::stripFileHeader(std::ifstream &file) {
223  std::string tmpString;
224  double tmpDouble;
225  int accuracy;
226 
227  try {
228  interpretLine<std::string, int>(file, tmpString, accuracy);
229  } catch (GeneralClassicException &e) {
230  interpretLine<std::string, int, std::string>(file, tmpString, accuracy, tmpString);
231  }
232 
233  interpretLine<double>(file, tmpDouble);
234 
235  return accuracy;
236 }
@ TAstraDynamic
Definition: Fieldmap.h:17
DiffDirection
Definition: Fieldmap.h:54
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
Inform & level3(Inform &inf)
Definition: Inform.cpp:47
#define INFOMSG(msg)
Definition: IpplInfo.h:348
constexpr double two_pi
The value of.
Definition: Physics.h:33
constexpr double e
The value of.
Definition: Physics.h:39
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:51
std::string toUpper(const std::string &str)
Definition: Util.cpp:132
bool determineNumSamplingPoints(std::ifstream &file)
virtual void freeMap()
double zend_m
Definition: Astra1D_fast.h:44
double readFieldData(std::ifstream &file)
void computeFieldDerivatives(std::vector< double > &fourierComponents, int accuracy)
gsl_spline * onAxisInterpolants_m[4]
Definition: Astra1D_fast.h:38
int numHeaderLines_m
Definition: Astra1D_fast.h:48
double length_m
Definition: Astra1D_fast.h:45
std::vector< double > getEvenlyDistributedSamplingPoints()
double * onAxisField_m
Definition: Astra1D_fast.h:36
void normalizeFieldData(double maxEz)
double zbegin_m
Definition: Astra1D_fast.h:43
double * zvals_m
Definition: Astra1D_fast.h:37
std::vector< double > computeFourierCoefficients(int accuracy, std::vector< double > &evenSampling)
gsl_interp_accel * onAxisAccel_m[4]
Definition: Astra1D_fast.h:39
std::vector< double > interpolateFieldData(std::vector< double > &samplingPoints)
bool readFileHeader(std::ifstream &file)
int stripFileHeader(std::ifstream &file)
virtual void getInfo(Inform *)
virtual double getFrequency() const
virtual bool getFieldstrength(const Vector_t &R, Vector_t &E, Vector_t &B) const
virtual void getFieldDimensions(double &zBegin, double &zEnd) const
virtual void setFrequency(double freq)
virtual bool getFieldDerivative(const Vector_t &R, Vector_t &E, Vector_t &B, const DiffDirection &dir) const
virtual void getOnaxisEz(std::vector< std::pair< double, double > > &F)
Astra1DDynamic_fast(std::string aFilename)
MapType Type
Definition: Fieldmap.h:114
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:451
void disableFieldmapWarning()
Definition: Fieldmap.cpp:613
bool normalize_m
Definition: Fieldmap.h:120
static std::string typeset_msg(const std::string &msg, const std::string &title)
Definition: Fieldmap.cpp:652
std::string Filename_m
Definition: Fieldmap.h:117
void noFieldmapWarning()
Definition: Fieldmap.cpp:621
The base class for all OPAL exceptions.
Definition: OpalException.h:28
Definition: Inform.h:42