30 std::string tmpString;
39 bool parsing_passed =
true;
41 parsing_passed = interpretLine<std::string, int>(file, tmpString,
accuracy_m);
43 parsing_passed = interpretLine<std::string, int, std::string>(
47 if (tmpString !=
"TRUE" && tmpString !=
"FALSE")
49 "Astra1DMagnetoStatic::Astra1DMagnetoStatic",
50 "The third string on the first line of 1D field maps "
51 "has to be either TRUE or FALSE");
56 int acceptedValues = 0;
58 parsing_passed = parsing_passed && interpretLine<double, double>(file,
zbegin_m, tmpDouble);
68 const bool line_ok = interpretLine<double, double>(file,
zend_m, tmpDouble,
false);
73 if (
zend_m - lastAcceptedZ > 1e-10) {
82 if (!parsing_passed && !file.eof()) {
86 "Astra1DMagnetoStatic::Astra1DMagnetoStatic",
87 "Error reading fieldmap '" +
Filename_m +
"'");
92 "Astra1DMagnetoStatic::Astra1DMagnetoStatic",
93 "Fieldmap must contain at least two valid sampling points");
114 "Astra1DMagnetoStatic::readMap",
115 "Fieldmap must contain at least two valid sampling points");
121 "Astra1DMagnetoStatic::readMap",
"Cannot open fieldmap '" +
Filename_m +
"'");
142 FourCoefs_m = Kokkos::DualView<double*>(
"FourCoefs", size);
145 std::string tmpString;
149 double lastAcceptedZ =
zbegin_m - dz;
156 const bool ok = interpretLine<double, double>(in, ztmp, bztmp,
false);
161 if (ztmp - lastAcceptedZ > 1e-10) {
162 zvals[accepted] = ztmp;
163 RealValues[accepted] = bztmp;
164 Bz_max = std::max(Bz_max, std::abs(bztmp));
165 lastAcceptedZ = ztmp;
177 std::ostringstream os;
178 os <<
"Mismatch between counted and parsed fieldmap points in '" <<
Filename_m
179 <<
"': expected " <<
num_gridpz_m <<
", got " << accepted;
190 "Astra1DMagnetoStatic::readMap",
191 "Maximum on-axis magnetic field is zero in fieldmap '" +
Filename_m +
"'");
206 RealValues[i] = RealValues[ii];
216 for (
int j = 0; j < M; ++j) {
219 coefs(0) = a0 / (norm * M);
225 for (
int j = 0; j < M; ++j) {
227 a_l += RealValues[j] * std::cos(l * theta);
228 b_l += RealValues[j] * std::sin(l * theta);
231 a_l *= 2.0 / double(M);
232 b_l *= 2.0 / double(M);
234 const int n = 2 * l - 1;
236 coefs(n) = a_l / norm;
237 coefs(n + 1) = -b_l / norm;
249 Inform m(
"Astra1DMagnetoStatic::readMap");
250 m << level3 <<
"Read in fieldmap '" <<
Filename_m <<
"'" << endl;
257 Inform m(
"Astra1DMagnetoStatic::freeMap");
258 m << level3 <<
"Freed fieldmap '" <<
Filename_m <<
"'" << endl;
269 const double zend =
zend_m;
272 const size_t nLocal = pc->getLocalNum();
276 auto Rview = pc->R.getView();
277 auto Eview = pc->E.getView();
278 auto Bview = pc->B.getView();
280 Kokkos::parallel_for(
281 "Astra1DMagnetoStatic::applyField", nLocal, KOKKOS_LAMBDA(
const size_t i) {
282 const auto& R = Rview(i);
284 if (R(2) >= zbegin && R(2) < zend) {
288 computeField(R, localE, localB, FourCoefs_device, zbegin, length, accuracy);
290 Eview(i) += scale * localE;
291 Bview(i) += scale * localB;
338 double& ,
double& ,
double& ,
double& ,
339 double& ,
double& )
const {
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.
bool isInside(const Vector_t< double, 3 > &r) const override
Check if a point is inside the field map.
Astra1DMagnetoStatic(const std::string &filename)
Constructor for 1D magnetostatic field map.
double getFrequency() const override
Get the frequency.
static KOKKOS_INLINE_FUNCTION void computeField(const Vector_t< double, 3 > &R, Vector_t< double, 3 > &, Vector_t< double, 3 > &B, const ViewType &FourCoefs, double zbegin, double length, int accuracy)
Kokkos::DualView< double * > FourCoefs_m
void swap() override
Swap coordinates (implementation dependent).
void freeMap() override
Pure virtual method to free the map data.
void applyField(std::shared_ptr< ParticleContainer_t > pc, double scale) override
Apply the FM to all the particles.
void getInfo(Inform *msg) override
Print info about the field map.
void getFieldDimensions(double &zBegin, double &zEnd) const override
Get the longitudinal dimensions of the field.
bool getFieldstrength(const Vector_t< double, 3 > &R, Vector_t< double, 3 > &E, Vector_t< double, 3 > &B) const override
Get the fieldstrength at position R.
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 derivative of the field at position R.
void setFrequency(double freq) override
Set the frequency.
void readMap() override
Pure virtual method to read the map data. Called by the public static readMap().
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.
std::string toUpper(const std::string &str)