OPAL (Object Oriented Parallel Accelerator Library) 2024.2
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{
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
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,
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
139bool _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
147void _Astra1DDynamic_fast::getFieldDimensions(double &zBegin, double &zEnd) const {
148 zBegin = zbegin_m;
149 zEnd = zend_m;
150}
151
152void _Astra1DDynamic_fast::getFieldDimensions(double &/*xIni*/, double &/*xFinal*/, double &/*yIni*/, double &/*yFinal*/, double &/*zIni*/, double &/*zFinal*/) const {}
153
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
169void _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
203bool _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
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}
std::shared_ptr< _Astra1DDynamic_fast > Astra1DDynamic_fast
@ TAstraDynamic
Definition Fieldmap.h:18
DiffDirection
Definition Fieldmap.h:55
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 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:147
double * zvals_m
std::vector< double > computeFourierCoefficients(int accuracy, std::vector< double > &evenSampling)
double readFieldData(std::ifstream &file)
std::vector< double > getEvenlyDistributedSamplingPoints()
std::vector< double > interpolateFieldData(std::vector< double > &samplingPoints)
gsl_spline * onAxisInterpolants_m[4]
bool determineNumSamplingPoints(std::ifstream &file)
double * onAxisField_m
void computeFieldDerivatives(std::vector< double > &fourierComponents, int accuracy)
_Astra1D_fast(const std::string &filename)
gsl_interp_accel * onAxisAccel_m[4]
virtual void freeMap()
void normalizeFieldData(double maxEz)
virtual void setFrequency(double freq)
virtual void getFieldDimensions(double &zBegin, double &zEnd) const
virtual void getInfo(Inform *)
int stripFileHeader(std::ifstream &file)
virtual void getOnaxisEz(std::vector< std::pair< double, double > > &F)
_Astra1DDynamic_fast(const std::string &filename)
bool readFileHeader(std::ifstream &file)
static Astra1DDynamic_fast create(const std::string &filename)
virtual bool getFieldstrength(const Vector_t &R, Vector_t &E, Vector_t &B) const
virtual bool getFieldDerivative(const Vector_t &R, Vector_t &E, Vector_t &B, const DiffDirection &dir) const
virtual double getFrequency() const
bool normalize_m
Definition Fieldmap.h:121
static std::string typeset_msg(const std::string &msg, const std::string &title)
Definition Fieldmap.cpp:649
void disableFieldmapWarning()
Definition Fieldmap.cpp:610
void noFieldmapWarning()
Definition Fieldmap.cpp:618
bool interpretLine(std::ifstream &in, S &value, const bool &file_length_known=true)
std::string Filename_m
Definition Fieldmap.h:118
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
MapType Type
Definition Fieldmap.h:116
The base class for all OPAL exceptions.
Vektor< double, 3 > Vector_t