50 using namespace interpolation;
66 :
SectorField(file_name), interpolator_m(NULL), symmetry_m(dipole),
67 units_m(6, 1.), filename_m(file_name), phiOffset_m(0.),
68 poly_order_m(polynomial_order), smoothing_order_m(smoothing_order) {
85 "SectorMagneticFieldMap::SectorMagneticFieldMap",
86 "Attempt to construct different SectorFieldMaps with same "+
87 std::string(
"file but different settings")
105 setInterpolator(interpolator);
124 "SectorMagneticFieldMap::setInterpolator",
125 "Attempt to load interpolator with PointDimension != 3")
129 "SectorMagneticFieldMap::setInterpolator",
130 "Attempt to load interpolator with ValueDimension != 3"
135 "SectorMagneticFieldMap::setInterpolator",
136 "Attempt to load interpolator with grid not ThreeDGrid"
170 if (sym ==
"Dipole") {
174 "SectorMagneticFieldMap::StringToSymmetry",
175 "Didn't recognise symmetry type "+sym
188 "SectorMagneticFieldMap::SymmetryToString",
189 "Didn't recognise symmetry type " + std::to_string(sym)
197 double R_temp[3] = {R_p[0], R_p[1], R_p[2]};
198 R_temp[2] += phiOffset_m;
200 if (!isInBoundingBox(R_temp))
202 interpolator_m->function(R_temp, &B_p[0]);
212 double radius = (getPolarBoundingBoxMin()[0]+getPolarBoundingBoxMax()[0])/2;
213 double midplane = (getPolarBoundingBoxMin()[1]+getPolarBoundingBoxMax()[1])/2;
214 double R_temp[3] = {R_c(0)+radius, R_c(1), R_c(2)};
215 double B_temp[3] = {0., 0., 0.};
217 bool mirror = R_temp[1] < midplane;
219 R_temp[1] = midplane + (midplane - R_temp[1]);
222 R_temp[2] -= phiOffset_m;
224 if (!isInBoundingBox(R_temp)) {
227 interpolator_m->function(R_temp, B_temp);
234 B_c(0) = B_temp[0]*
cos(phiOffset_m)-B_temp[2]*
sin(phiOffset_m);
236 B_c(2) = B_temp[0]*
sin(phiOffset_m)+B_temp[2]*
cos(phiOffset_m);
243 R_temp[1] = 2*ymin-R_temp[1];
254 _fields = std::map<std::string, SectorMagneticFieldMap*>();
260 (*msg) <<
Filename_m <<
" (3D Sector Magnetostatic);\n"
261 <<
" zini= " << bbmin[1] <<
" mm; zfinal= " << bbmax[1] <<
" mm;\n"
262 <<
" phiini= " << bbmin[2] <<
" rad; phifinal= " << bbmax[2] <<
" rad;\n"
263 <<
" rini= " << bbmin[0] <<
" mm; rfinal= " << bbmax[0] <<
" mm;"
270 out <<
Filename_m <<
" (3D Sector Magnetostatic);\n"
271 <<
" zini= " << bbmin[1] <<
" m; zfinal= " << bbmax[1] <<
" mm;\n"
272 <<
" phiini= " << bbmin[2] <<
" rad; phifinal= " << bbmax[2] <<
" rad;\n"
273 <<
" rini= " << bbmin[0] <<
" m; rfinal= " << bbmax[0] <<
" mm;\n"
279 throw(
LogicalError(
"SectorMagneticFieldMap::getFieldDerivative",
280 "Field map derivatives not implemented"));
295 std::string file_name,
296 std::vector<double> units,
298 int polynomial_order,
299 int smoothing_order) {
301 *
gmsg <<
"* Opening sector field map " << file_name
302 <<
" fit order " << polynomial_order
303 <<
" smoothing order " << smoothing_order <<
endl;
305 std::vector< std::vector<double> > field_points =
readLines
310 if (polynomial_order == 1 && smoothing_order == 1) {
322 }
catch(std::exception& exc) {
324 "SectorMagneticFieldMap::IO::ReadMap",
325 "Failed to read file "+file_name+
" with "+(&exc)->what()
332 std::vector< std::vector<double> > field_points,
335 int polynomial_order,
336 int smoothing_order) {
340 "SectorMagneticFieldMap::IO::getInterpolatorPolyPatch",
341 "Failed to recognise symmetry type"
344 std::vector< std::vector<double> > data(field_points.size(),
345 std::vector<double>(3));
346 for (
size_t i = 0; i < field_points.size(); ++i) {
347 data[i][0] = field_points[i][3];
348 data[i][1] = field_points[i][4];
349 data[i][2] = field_points[i][5];
353 *
gmsg <<
"Calculating polynomials..." <<
endl;
354 PPSolveFactory solver(grid, data, polynomial_order, smoothing_order);
365 std::string(
"field points during read ")+
366 std::string(
"operation; this could mean that the field ")+
367 std::string(
"map was not complete, or that OPAL could ")+
368 std::string(
"not calculate regular grid spacings properly. ")+
369 std::string(
"Check that the field map is on a cylindrical ")+
370 std::string(
"grid written in Cartesian coordinates and the ")+
371 std::string(
"grid points are written with enough precision (")+
372 std::string(
"check the grid size information above).");
375 (
const std::vector< std::vector<double> > field_points,
379 double *** Bx, *** By, *** Bz;
381 Bx =
new double**[grid->
xSize()];
382 By =
new double**[grid->
xSize()];
383 Bz =
new double**[grid->
xSize()];
384 for (
int i = 0; i < grid->
xSize(); ++i) {
385 Bx[i] =
new double*[grid->
ySize()];
386 By[i] =
new double*[grid->
ySize()];
387 Bz[i] =
new double*[grid->
ySize()];
388 for (
int j = 0; j < grid->
ySize(); ++j) {
389 Bx[i][j] =
new double[grid->
zSize()];
390 By[i][j] =
new double[grid->
zSize()];
391 Bz[i][j] =
new double[grid->
zSize()];
392 for (
int k = 0; k < grid->
zSize(); ++k) {
393 if (index >=
int(field_points.size())) {
396 "SectorMagneticFieldMap::IO::getInterpolator",
397 "Ran out of "+errMsg1)
400 Bx[i][j][k] = field_points[index][3];
401 By[i][j][k] = field_points[index][4];
402 Bz[i][j][k] = field_points[index][5];
407 if (index !=
int(field_points.size())) {
409 "SectorMagneticFieldMap::IO::getInterpolator",
415 return interpolatorMap;
419 std::vector<double> field_item2) {
420 const int* order = sortOrder_m;
421 if (
fabs(field_item1[order[0]] - field_item2[order[0]]) > floatTolerance_m) {
422 return field_item1[order[0]] < field_item2[order[0]];
424 if (
fabs(field_item1[order[1]] - field_item2[order[1]]) > floatTolerance_m) {
425 return field_item1[order[1]] < field_item2[order[1]];
427 return field_item1[order[2]] < field_item2[order[2]];
431 (std::string file_name, std::vector<double> units) {
432 std::vector< std::vector<double> > field_points;
434 if (units.size() != 6) {
436 "SectorMagneticFieldMap::IO::ReadLines",
437 "Units should be of length 6"
441 std::ifstream fin(file_name.c_str());
442 if (!fin || !fin.is_open()) {
444 "SectorMagneticFieldMap::IO::ReadLines",
445 "Failed to open file "+file_name
449 *
gmsg <<
"* Opened "+file_name <<
endl;
450 for (
size_t i = 0; i < 8; ++i) {
451 std::getline(fin, line);
456 std::vector<double> field(6);
457 fin >> field[0] >> field[1] >> field[2] >> field[3] >> field[4]
460 for (
size_t i = 0; i < 6; ++i) {
461 field[i] *= units[i];
463 field_points.push_back(field);
467 *
gmsg <<
"* Read " << line_number <<
" lines" <<
endl;
470 for (
size_t i = 0; i < field_points.size(); ++i) {
475 std::sort(field_points.begin(), field_points.end(),
481 in2 = in2*(1+floatTolerance_m)+floatTolerance_m;
486 (
const std::vector< std::vector<double> > field_points,
488 std::vector<double> r_grid(1, field_points[0][0]);
489 std::vector<double> y_grid(1, field_points[0][1]);
490 std::vector<double> phi_grid(1, field_points[0][2]);
491 for (
size_t i = 0; i < field_points.size(); ++i) {
492 if (floatGreaterEqual(field_points[i][0], r_grid.back())) {
493 r_grid.push_back(field_points[i][0]);
495 if (floatGreaterEqual(field_points[i][1], y_grid.back())) {
496 y_grid.push_back(field_points[i][1]);
498 if (floatGreaterEqual(field_points[i][2], phi_grid.back())) {
499 phi_grid.push_back(field_points[i][2]);
504 *
gmsg <<
"* Grid size (r, y, phi) = ("
505 << r_grid.size() <<
", " << y_grid.size() <<
", " << phi_grid.size()
507 *
gmsg <<
"* Grid min (r [mm], y [mm], phi [rad]) = ("
508 << r_grid[0] <<
", " << y_grid[0] <<
", " << phi_grid[0]
510 *
gmsg <<
"* Grid max (r [mm], y [mm], phi [rad]) = ("
511 << r_grid.back() <<
", " << y_grid.back() <<
", " << phi_grid.back()
void setInterpolator(interpolation::VectorMap *interpolator)
static std::string SymmetryToString(symmetry sym)
static const double fractionalBBPhiTolerance_m
constexpr double e
The value of .
void setPolarBoundingBox(double bbMinR, double bbMinY, double bbMinPhi, double bbMaxR, double bbMaxY, double bbMaxPhi, double bbTolR, double bbTolY, double bbTolPhi)
handles field map grids with sector geometry
static interpolation::VectorMap * readMap(std::string file_name, std::vector< double > units, SectorMagneticFieldMap::symmetry sym, int poly_order, int smoothing_order)
bool getFieldstrength(const Vector_t &R_c, Vector_t &E_c, Vector_t &B_c) const
interpolation::VectorMap * interpolator_m
PETE_TUTree< FnFabs, typename T::PETE_Expr_t > fabs(const PETE_Expr< T > &l)
Tps< T > sin(const Tps< T > &x)
Sine.
static const std::string errMsg1
virtual unsigned int getPointDimension() const =0
double getDeltaPhi() const
void getInfo(Inform *msg)
static interpolation::VectorMap * getInterpolatorPolyPatch(const std::vector< std::vector< double > > field_points, interpolation::ThreeDGrid *grid, SectorMagneticFieldMap::symmetry sym, int poly_order, int smoothing_order)
static bool comparator(std::vector< double > field_item1, std::vector< double > field_item2)
void print(std::ostream &out)
static interpolation::ThreeDGrid * generateGrid(const std::vector< std::vector< double > > field_points, SectorMagneticFieldMap::symmetry sym)
bool getFieldstrengthPolar(const Vector_t &R_p, Vector_t &E_p, Vector_t &B_p) const
bool applySymmetry(double *R_temp) const
const std::string filename_m
static const double floatTolerance_m
static std::vector< std::vector< double > > readLines(std::string file_name, std::vector< double > units)
PolynomialPatch * solve()
virtual Mesh * getMesh() const
static const int sortOrder_m[3]
static void clearFieldCache()
virtual std::vector< double > getPolarBoundingBoxMax() const
interpolation::VectorMap * getInterpolator()
Tps< T > cos(const Tps< T > &x)
Cosine.
static bool floatGreaterEqual(double in1, double in2)
Patches together many SquarePolynomialVectors to make a multidimensional polynomial spline...
~SectorMagneticFieldMap()
SectorMagneticFieldMap(std::string file_name, std::string symmetry, double length_units, double field_units, int polynomial_order, int smoothing_order)
static std::map< std::string, SectorMagneticFieldMap * > _fields
std::string::iterator iterator
virtual unsigned int getValueDimension() const =0
static void convertToPolar(double *position)
virtual std::vector< double > getPolarBoundingBoxMin() const
void setConstantSpacing(bool spacing)
void setSymmetry(std::string name)
static symmetry StringToSymmetry(std::string name)
std::string getSymmetry() const
Inform & endl(Inform &inf)
PPSolveFactory solves the system of linear equations to interpolate from a grid of points using highe...
static interpolation::VectorMap * getInterpolator(const std::vector< std::vector< double > > field_points, interpolation::ThreeDGrid *grid, SectorMagneticFieldMap::symmetry sym)
std::vector< double > units_m
bool getFieldDerivative(const Vector_t &R, Vector_t &E, Vector_t &B, const DiffDirection &dir) const