OPALX (Object Oriented Parallel Accelerator Library for Exascal) MINIorX
OPALX
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
32Astra1DDynamic_fast::Astra1DDynamic_fast(std::string aFilename) : Astra1D_fast(aFilename) {
34
35 onAxisField_m = nullptr;
36
38
39 // open field map, parse it and disable element on error
40 std::ifstream file(Filename_m.c_str());
41 if (!file.good()) {
43 zbegin_m = 0.0;
44 zend_m = -1e-3;
45 return;
46 }
47
48 bool parsing_passed = readFileHeader(file);
49
50 parsing_passed = parsing_passed && determineNumSamplingPoints(file);
51 file.close();
52
53 if (!parsing_passed) {
55 zend_m = zbegin_m - 1e-3;
57 "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
72
74 if (onAxisField_m == nullptr) {
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
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
93 accuracy, length_m, zvals, fourierCoefs, onAxisInterpolants_m[0], onAxisAccel_m[0]);
94
95 *ippl::Info << level3 << typeset_msg("read in fieldmap '" + Filename_m + "'", "info")
96 << endl;
97 }
98}
99
102 // do fourier interpolation in z-direction
103 const double RR2 = R(0) * R(0) + R(1) * R(1);
104
105 double ez, ezp, ezpp, ezppp;
106 try {
107 ez = gsl_spline_eval(onAxisInterpolants_m[0], R(2) - zbegin_m, onAxisAccel_m[0]);
108 ezp = gsl_spline_eval(onAxisInterpolants_m[1], R(2) - zbegin_m, onAxisAccel_m[1]);
109 ezpp = gsl_spline_eval(onAxisInterpolants_m[2], R(2) - zbegin_m, onAxisAccel_m[2]);
110 ezppp = gsl_spline_eval(onAxisInterpolants_m[3], R(2) - zbegin_m, onAxisAccel_m[3]);
111 } catch (OpalException const& e) {
112 throw OpalException(
113 "Astra1DDynamic_fast::getFieldstrength",
114 "The requested interpolation point, " + std::to_string(R(2)) + " is out of range");
115 }
116 // expand the field off-axis
117 const double f = -(ezpp + ez * xlrep_m * xlrep_m) / 16.;
118 const double fp = -(ezppp + ezp * xlrep_m * xlrep_m) / 16.;
119
120 const double EfieldR = -(ezp / 2. + fp * RR2);
121 const double BfieldT = (ez / 2. + f * RR2) * xlrep_m / Physics::c;
122
123 E(0) += EfieldR * R(0);
124 E(1) += EfieldR * R(1);
125 E(2) += ez + 4. * f * RR2;
126 B(0) += -BfieldT * R(1);
127 B(1) += BfieldT * R(0);
128
129 return false;
130}
131
134 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
148 double& /*xIni*/, double& /*xFinal*/, double& /*yIni*/, double& /*yFinal*/, double& /*zIni*/,
149 double& /*zFinal*/) const {
150}
151
154
156 (*msg) << Filename_m << " (1D dynamic); zini= " << zbegin_m << " m; zfinal= " << zend_m << " m;"
157 << endl;
158}
159
161 return frequency_m;
162}
163
165 frequency_m = freq;
166}
167
168void Astra1DDynamic_fast::getOnaxisEz(std::vector<std::pair<double, double> >& F) {
169 F.resize(num_gridpz_m);
170 if (onAxisField_m == nullptr) {
171 double Ez_max = 0.0;
172 double tmpDouble;
173 int tmpInt;
174 std::string tmpString;
175
176 std::ifstream in(Filename_m.c_str());
177 interpretLine<std::string, int>(in, tmpString, tmpInt);
178 interpretLine<double, double, int>(in, tmpDouble, tmpDouble, tmpInt);
179 interpretLine<double>(in, tmpDouble);
180 interpretLine<double, double, int>(in, tmpDouble, tmpDouble, tmpInt);
181
182 for (int i = 0; i < num_gridpz_m; ++i) {
183 F[i].first = hz_m * i;
184 interpretLine<double>(in, F[i].second);
185 if (std::abs(F[i].second) > Ez_max) {
186 Ez_max = std::abs(F[i].second);
187 }
188 }
189 in.close();
190
191 for (int i = 0; i < num_gridpz_m; ++i) {
192 F[i].second /= Ez_max;
193 }
194 } else {
195 for (int i = 0; i < num_gridpz_m; ++i) {
196 F[i].first = zvals_m[i];
197 F[i].second = onAxisField_m[i] / 1e6;
198 }
199 }
200}
201
202bool Astra1DDynamic_fast::readFileHeader(std::ifstream& file) {
203 std::string tmpString;
204 int tmpInt;
205 bool passed = true;
206
207 try {
208 passed = interpretLine<std::string, int>(file, tmpString, tmpInt);
209 } catch (GeneralClassicException& e) {
210 passed = interpretLine<std::string, int, std::string>(file, tmpString, tmpInt, tmpString);
211
212 tmpString = Util::toUpper(tmpString);
213 if (tmpString != "TRUE" && tmpString != "FALSE")
215 "Astra1DDynamic_fast::readFileHeader",
216 "The third string on the first line of 1D field "
217 "maps has to be either TRUE or FALSE");
218
219 normalize_m = (tmpString == "TRUE");
220 }
221
222 passed = passed && interpretLine<double>(file, frequency_m);
223
224 return passed;
225}
226
227int Astra1DDynamic_fast::stripFileHeader(std::ifstream& file) {
228 std::string tmpString;
229 double tmpDouble;
230 int accuracy;
231
232 try {
233 interpretLine<std::string, int>(file, tmpString, accuracy);
234 } catch (GeneralClassicException& e) {
235 interpretLine<std::string, int, std::string>(file, tmpString, accuracy, tmpString);
236 }
237
238 interpretLine<double>(file, tmpDouble);
239
240 return accuracy;
241}
ippl::Vector< T, Dim > Vector_t
@ TAstraDynamic
Definition Fieldmap.h:18
DiffDirection
Definition Fieldmap.h:55
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:145
bool determineNumSamplingPoints(std::ifstream &file)
Astra1D_fast(std::string aFilename)
virtual void freeMap()
double readFieldData(std::ifstream &file)
void computeFieldDerivatives(std::vector< double > &fourierComponents, int accuracy)
gsl_spline * onAxisInterpolants_m[4]
double length_m
std::vector< double > getEvenlyDistributedSamplingPoints()
double * onAxisField_m
void normalizeFieldData(double maxEz)
double zbegin_m
double * zvals_m
std::vector< double > computeFourierCoefficients(int accuracy, std::vector< double > &evenSampling)
gsl_interp_accel * onAxisAccel_m[4]
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 getFieldDerivative(const Vector_t< double, 3 > &R, Vector_t< double, 3 > &E, Vector_t< double, 3 > &B, const DiffDirection &dir) const
virtual void getFieldDimensions(double &zBegin, double &zEnd) const
virtual void setFrequency(double freq)
virtual void getOnaxisEz(std::vector< std::pair< double, double > > &F)
virtual bool getFieldstrength(const Vector_t< double, 3 > &R, Vector_t< double, 3 > &E, Vector_t< double, 3 > &B) const
Astra1DDynamic_fast(std::string aFilename)
MapType Type
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:413
void disableFieldmapWarning()
Definition Fieldmap.cpp:569
bool normalize_m
Definition Fieldmap.h:123
static std::string typeset_msg(const std::string &msg, const std::string &title)
Definition Fieldmap.cpp:607
std::string Filename_m
Definition Fieldmap.h:120
bool interpretLine(std::ifstream &in, S &value, const bool &file_length_known=true)
void noFieldmapWarning()
Definition Fieldmap.cpp:576
The base class for all OPAL exceptions.