18 std::string tmpString;
27 bool parsing_passed =
true;
29 parsing_passed = interpretLine<std::string, int>(file, tmpString,
accuracy_m);
31 parsing_passed = interpretLine<std::string, int, std::string>(
35 if (tmpString !=
"TRUE" && tmpString !=
"FALSE")
37 "Astra1DDynamic::Astra1DDynamic",
38 "The third string on the first line of 1D field "
39 "maps has to be either TRUE or FALSE");
44 parsing_passed = parsing_passed && interpretLine<double>(file,
frequency_m);
46 int acceptedValues = 0;
49 parsing_passed = parsing_passed && interpretLine<double, double>(file,
zbegin_m, tmpDouble);
60 bool line_ok = interpretLine<double, double>(file,
zend_m, tmpDouble,
false);
65 if (
zend_m - tmpDouble2 > 1e-10) {
74 if (!parsing_passed && !file.eof()) {
78 "Astra1DDynamic::Astra1DDynamic",
79 "Error reading fieldmap '" +
Filename_m +
"'");
105 "Astra1DDynamic::readMap",
106 "Fieldmap must contain at least two valid sampling points");
112 "Astra1DDynamic::readMap",
"Cannot open fieldmap '" +
Filename_m +
"'");
141 FourCoefs_m = Kokkos::DualView<double*>(
"FourCoefs", size);
146 std::string tmpString;
151 double lastAcceptedZ =
zbegin_m - dz;
158 const bool ok = interpretLine<double, double>(in, ztmp, eztmp,
false);
163 if (ztmp - lastAcceptedZ > 1e-10) {
164 zvals[accepted] = ztmp;
165 RealValues[accepted] = eztmp;
166 Ez_max = std::max(Ez_max, std::abs(eztmp));
167 lastAcceptedZ = ztmp;
179 std::ostringstream os;
180 os <<
"Mismatch between counted and parsed fieldmap points in '" <<
Filename_m
181 <<
"': expected " <<
num_gridpz_m <<
", got " << accepted;
192 "Astra1DDynamic::readMap",
193 "Maximum on-axis field is zero in fieldmap '" +
Filename_m +
"'");
209 RealValues[i] = RealValues[ii];
219 for (
int j = 0; j < M; ++j) {
228 for (
int j = 0; j < M; ++j) {
230 a_l += RealValues[j] * std::cos(l * theta);
231 b_l += RealValues[j] * std::sin(l * theta);
234 a_l *= 2.0 / double(M);
235 b_l *= 2.0 / double(M);
237 const int n = 2 * l - 1;
260 Inform m(
"Astra1DDynamic::readMap");
261 m << level3 <<
"Read in fieldmap '" <<
Filename_m <<
"'" << endl;
269 Inform m(
"Astra1DDynamic::freeMap");
270 m << level3 <<
"Freed fieldmap '" <<
Filename_m <<
"'" << endl;
283 const double zend =
zend_m;
287 const size_t nLocal = pc->getLocalNum();
292 auto Rview = pc->R.getView();
293 auto Eview = pc->E.getView();
294 auto Bview = pc->B.getView();
296 Kokkos::parallel_for(
297 "Astra1DDynamic::applyField", nLocal, KOKKOS_LAMBDA(
const size_t i) {
298 const auto& R = Rview(i);
301 if (R(2) >= zbegin && R(2) < zend) {
303 R, Eview(i), Bview(i), FourCoefs_device, zbegin, length, xlrep,
310 std::shared_ptr<ParticleContainer_t> pc,
double electricScale,
double magneticScale,
311 double startField,
double endField) {
313 const double zend =
zend_m;
320 auto Rview = pc->R.getView();
321 auto Eview = pc->E.getView();
322 auto Bview = pc->B.getView();
324 const size_t nLocal = pc->getLocalNum();
326 Kokkos::parallel_for(
327 "Astra1DDynamic::applyRFField", nLocal, KOKKOS_LAMBDA(
const size_t i) {
329 Rview(i), Eview(i), Bview(i), FourCoefs_device, zbegin, zend, length, xlrep,
330 accuracy, electricScale, magneticScale, startField, endField);
335 std::shared_ptr<ParticleContainer_t> pc,
double entryElectricScale,
336 double entryMagneticScale,
double core1ElectricScale,
double core1MagneticScale,
337 double core2ElectricScale,
double core2MagneticScale,
double exitElectricScale,
338 double exitMagneticScale,
double ,
double startCoreField,
339 double startExitField,
double mappedStartExitField,
double periodLength,
double cellLength,
340 double elementLength) {
342 const double zend =
zend_m;
346 const size_t nLocal = pc->getLocalNum();
350 auto Rview = pc->R.getView();
351 auto Eview = pc->E.getView();
352 auto Bview = pc->B.getView();
354 Kokkos::parallel_for(
355 "Astra1DDynamic::applyTravelingWave", nLocal, KOKKOS_LAMBDA(
const size_t i) {
357 Rview(i), Eview(i), Bview(i), FourCoefs_device, zbegin, zend, length, xlrep,
358 accuracy, entryElectricScale, entryMagneticScale, core1ElectricScale,
359 core1MagneticScale, core2ElectricScale, core2MagneticScale,
360 exitElectricScale, exitMagneticScale, startCoreField, startExitField,
361 mappedStartExitField, periodLength, cellLength, elementLength);
393 for (
int l = 1; l <
accuracy_m; ++l, n += 2) {
395 * (-FourCoefs(n) * std::sin(kz * l) - FourCoefs(n + 1) * std::cos(kz * l));
409 double& ,
double& ,
double& ,
double& ,
410 double& ,
double& )
const {
434 std::string tmpString;
439 interpretLine<std::string, int>(in, tmpString, tmpInt);
440 interpretLine<double>(in, tmpDouble);
443 interpretLine<double, double>(in, F[i].first, F[i].second);
444 if (std::abs(F[i].second) > Ez_max) {
445 Ez_max = std::abs(F[i].second);
451 F[i].second /= Ez_max;
ippl::Vector< T, Dim > Vector_t
constexpr int gsl_interp_cspline
double gsl_spline_eval(const gsl_spline *spline, const double x, gsl_interp_accel *accel)
Evaluate a spline at x using an accelerator.
gsl_interp_accel * gsl_interp_accel_alloc()
Allocate an interpolation accelerator.
void gsl_spline_init(gsl_spline *spline, const double *x, const double *y, const size_t n)
Initialize a spline with tabulated data.
void gsl_spline_free(const gsl_spline *spline)
Free a spline instance.
void gsl_interp_accel_free(const gsl_interp_accel *accel)
Free an accelerator instance.
gsl_spline * gsl_spline_alloc(const int type, size_t)
Allocate a spline instance (size ignored).
Template PIC bunch: IPPL PicManager, shared field mesh/solver, and multiple particle containers.
Accelerator caching last interval indices.
Base class for the linear and cubic interpolation spline classes.
double xlrep_m
Wave number (omega / c)
static KOKKOS_INLINE_FUNCTION void computeTravelingWaveField(const Vector_t< double, 3 > &R, Vector_t< double, 3 > &E, Vector_t< double, 3 > &B, const ViewType &FourCoefs, double zbegin, double zend, double length, double xlrep, int accuracy, double entryElectricScale, double entryMagneticScale, double core1ElectricScale, double core1MagneticScale, double core2ElectricScale, double core2MagneticScale, double exitElectricScale, double exitMagneticScale, double startCoreField, double startExitField, double mappedStartExitField, double periodLength, double cellLength, double elementLength)
void freeMap() override
Pure virtual method to free the map data.
virtual double getFrequency() const override
Get the frequency.
Kokkos::DualView< double * > FourCoefs_m
Fourier coefficients of Ez(z) (device-accessible) Stored as: [a0, a1, b1, a2, b2, ....
static KOKKOS_INLINE_FUNCTION void computeField(const Vector_t< double, 3 > &R, Vector_t< double, 3 > &E, Vector_t< double, 3 > &B, const ViewType &FourCoefs, double zbegin, double length, double xlrep, int accuracy)
void applyRFField(std::shared_ptr< ParticleContainer_t > pc, double electricScale, double magneticScale, double startField, double endField)
Apply RF-scaled Astra1DDynamic field to all particles.
virtual void getOnaxisEz(std::vector< std::pair< double, double > > &F) override
static KOKKOS_INLINE_FUNCTION void computeRFField(const Vector_t< double, 3 > &R, Vector_t< double, 3 > &E, Vector_t< double, 3 > &B, const ViewType &FourCoefs, double zbegin, double zend, double length, double xlrep, int accuracy, double electricScale, double magneticScale, double startField, double endField)
int accuracy_m
Number of Fourier modes used.
virtual void setFrequency(double freq) override
Set the frequency.
virtual void getInfo(Inform *msg) override
Print info about the field map.
virtual void swap() override
Swap coordinates.
bool isInside(const Vector_t< double, 3 > &r) const override
Checks if the given coordinate is inside the volume covered by the fieldmap.
void applyField(std::shared_ptr< ParticleContainer_t > pc, double) override
Apply the FM to all the particles.
void applyTravelingWave(std::shared_ptr< ParticleContainer_t > pc, double entryElectricScale, double entryMagneticScale, double core1ElectricScale, double core1MagneticScale, double core2ElectricScale, double core2MagneticScale, double exitElectricScale, double exitMagneticScale, double startField, double startCoreField, double startExitField, double mappedStartExitField, double periodLength, double cellLength, double elementLength)
Apply the traveling-wave RF field map to all particles.
Astra1DDynamic(const std::string &filename)
int num_gridpz_m
Number of grid points in z-direction (input sampling)
double length_m
Effective periodic length of the field map [m].
void readMap() override
Pure virtual method to read the map data. Called by the public static readMap().
double zbegin_m
Z Bounds relative to element edge.
virtual void getFieldDimensions(double &zBegin, double &zEnd) const override
Get the longitudinal dimensions of the field.
virtual bool getFieldDerivative(const Vector_t< double, 3 > &R, Vector_t< double, 3 > &E, Vector_t< double, 3 > &B, const DiffDirection &dir) const override
Get the field derivative with respect to a direction.
virtual bool getFieldstrength(const Vector_t< double, 3 > &R, Vector_t< double, 3 > &E, Vector_t< double, 3 > &B) const override
Get the field strength at a given point.
Abstract base class for all field maps. It acts as a factory for creating specific field map types ba...
void disableFieldmapWarning()
void getLine(std::ifstream &in, std::string &buffer)
constexpr double two_pi
The value of.
constexpr double c
The velocity of light in m/s.
constexpr double pi
The value of.
constexpr double Vpm2MVpm
std::string toUpper(const std::string &str)