OPAL (Object Oriented Parallel Accelerator Library) 2022.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
33 Astra1D_fast(aFilename)
34{
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 if(onAxisField_m == nullptr) {
76 std::ifstream file(Filename_m.c_str());
77
78 onAxisField_m = new double[num_gridpz_m];
79 zvals_m = new double[num_gridpz_m];
80
81 int accuracy = stripFileHeader(file);
82 double maxEz = readFieldData(file);
83 file.close();
84
86
87 std::vector<double> zvals = getEvenlyDistributedSamplingPoints();
88 std::vector<double> evenFieldSampling = interpolateFieldData(zvals);
89 std::vector<double> fourierCoefs = computeFourierCoefficients(accuracy, evenFieldSampling);
90
91 computeFieldDerivatives(fourierCoefs, accuracy);
92
93 checkMap(accuracy,
95 zvals,
96 fourierCoefs,
98 onAxisAccel_m[0]);
99
100 INFOMSG(level3 << typeset_msg("read in fieldmap '" + Filename_m + "'", "info") << endl);
101 }
102}
103
105 // do fourier interpolation in z-direction
106 const double RR2 = R(0) * R(0) + R(1) * R(1);
107
108 double ez, ezp, ezpp, ezppp;
109 try {
110 ez = gsl_spline_eval(onAxisInterpolants_m[0], R(2) - zbegin_m, onAxisAccel_m[0]);
111 ezp = gsl_spline_eval(onAxisInterpolants_m[1], R(2) - zbegin_m, onAxisAccel_m[1]);
112 ezpp = gsl_spline_eval(onAxisInterpolants_m[2], R(2) - zbegin_m, onAxisAccel_m[2]);
113 ezppp = gsl_spline_eval(onAxisInterpolants_m[3], R(2) - zbegin_m, onAxisAccel_m[3]);
114 } catch (OpalException const& e) {
115 throw OpalException("Astra1DDynamic_fast::getFieldstrength",
116 "The requested interpolation point, " + std::to_string(R(2)) + " is out of range");
117 }
118 // expand the field off-axis
119 const double f = -(ezpp + ez * xlrep_m * xlrep_m) / 16.;
120 const double fp = -(ezppp + ezp * xlrep_m * xlrep_m) / 16.;
121
122 const double EfieldR = -(ezp / 2. + fp * RR2);
123 const double BfieldT = (ez / 2. + f * RR2) * xlrep_m / Physics::c;
124
125 E(0) += EfieldR * R(0);
126 E(1) += EfieldR * R(1);
127 E(2) += ez + 4. * f * RR2;
128 B(0) += -BfieldT * R(1);
129 B(1) += BfieldT * R(0);
130
131 return false;
132}
133
134bool Astra1DDynamic_fast::getFieldDerivative(const Vector_t &R, Vector_t &E, Vector_t &/*B*/, const DiffDirection &/*dir*/) const {
135 double ezp = gsl_spline_eval(onAxisInterpolants_m[1], R(2) - zbegin_m, onAxisAccel_m[1]);
136
137 E(2) += ezp;
138
139 return false;
140}
141
142void Astra1DDynamic_fast::getFieldDimensions(double &zBegin, double &zEnd) const {
143 zBegin = zbegin_m;
144 zEnd = zend_m;
145}
146
147void Astra1DDynamic_fast::getFieldDimensions(double &/*xIni*/, double &/*xFinal*/, double &/*yIni*/, double &/*yFinal*/, double &/*zIni*/, double &/*zFinal*/) const {}
148
150{ }
151
153 (*msg) << Filename_m << " (1D dynamic); zini= " << zbegin_m << " m; zfinal= " << zend_m << " m;" << endl;
154}
155
157 return frequency_m;
158}
159
161 frequency_m = freq;
162}
163
164void Astra1DDynamic_fast::getOnaxisEz(std::vector<std::pair<double, double> > & F) {
165 F.resize(num_gridpz_m);
166 if(onAxisField_m == nullptr) {
167 double Ez_max = 0.0;
168 double tmpDouble;
169 int tmpInt;
170 std::string tmpString;
171
172 std::ifstream in(Filename_m.c_str());
173 interpretLine<std::string, int>(in, tmpString, tmpInt);
174 interpretLine<double, double, int>(in, tmpDouble, tmpDouble, tmpInt);
175 interpretLine<double>(in, tmpDouble);
176 interpretLine<double, double, int>(in, tmpDouble, tmpDouble, tmpInt);
177
178 for(int i = 0; i < num_gridpz_m; ++ i) {
179 F[i].first = hz_m * i;
180 interpretLine<double>(in, F[i].second);
181 if(std::abs(F[i].second) > Ez_max) {
182 Ez_max = std::abs(F[i].second);
183 }
184 }
185 in.close();
186
187 for(int i = 0; i < num_gridpz_m; ++ i) {
188 F[i].second /= Ez_max;
189 }
190 } else {
191 for(int i = 0; i < num_gridpz_m; ++ i) {
192 F[i].first = zvals_m[i];
193 F[i].second = onAxisField_m[i] / 1e6;
194 }
195 }
196}
197
198bool Astra1DDynamic_fast::readFileHeader(std::ifstream &file) {
199 std::string tmpString;
200 int tmpInt;
201 bool passed = true;
202
203 try {
204 passed = interpretLine<std::string, int>(file, tmpString, tmpInt);
205 } catch (GeneralClassicException &e) {
206 passed = interpretLine<std::string, int, std::string>(file, tmpString, tmpInt, tmpString);
207
208 tmpString = Util::toUpper(tmpString);
209 if (tmpString != "TRUE" &&
210 tmpString != "FALSE")
211 throw GeneralClassicException("Astra1DDynamic_fast::readFileHeader",
212 "The third string on the first line of 1D field "
213 "maps has to be either TRUE or FALSE");
214
215 normalize_m = (tmpString == "TRUE");
216 }
217
218 passed = passed && interpretLine<double>(file, frequency_m);
219
220 return passed;
221}
222
223int Astra1DDynamic_fast::stripFileHeader(std::ifstream &file) {
224 std::string tmpString;
225 double tmpDouble;
226 int accuracy;
227
228 try {
229 interpretLine<std::string, int>(file, tmpString, accuracy);
230 } catch (GeneralClassicException &e) {
231 interpretLine<std::string, int, std::string>(file, tmpString, accuracy, tmpString);
232 }
233
234 interpretLine<double>(file, tmpDouble);
235
236 return accuracy;
237}
@ 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:45
constexpr double MHz2Hz
Definition: Units.h:113
constexpr double Vpm2MVpm
Definition: Units.h:125
std::string toUpper(const std::string &str)
Definition: Util.cpp:146
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