OPAL (Object Oriented Parallel Accelerator Library)  2024.1
OPAL
SectorMagneticFieldMap.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012, Chris Rogers
3  * All rights reserved.
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  * 1. Redistributions of source code must retain the above copyright notice,
7  * this list of conditions and the following disclaimer.
8  * 2. Redistributions in binary form must reproduce the above copyright notice,
9  * this list of conditions and the following disclaimer in the documentation
10  * and/or other materials provided with the distribution.
11  * 3. Neither the name of STFC nor the names of its contributors may be used to
12  * endorse or promote products derived from this software without specific
13  * prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25  * POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 
30 // Grid on which field values are stored
33 // Linear interpolation routines
36 // Higher order interpolation routines
39 
40 #include "Utilities/LogicalError.h"
41 
42 #include <algorithm>
43 #include <cmath>
44 #include <fstream>
45 #include <iostream>
46 #include <string>
47 #include <vector>
48 
49 using namespace interpolation;
50 
51 extern Inform *gmsg;
52 
53 // allow a fairly generous phi tolerance - we don't care about phi much and
54 // calculation can be flaky due to ascii truncation of double and conversions
55 // from polar to Cartesian
57 std::map<std::string, SectorMagneticFieldMap*> SectorMagneticFieldMap::_fields;
58 
60  std::string symmetry,
61  double length_units,
62  double field_units,
63  int polynomial_order,
64  int smoothing_order)
65  : SectorField(file_name), interpolator_m(nullptr), symmetry_m(dipole),
66  units_m(6, 1.), filename_m(file_name), phiOffset_m(0.),
67  poly_order_m(polynomial_order), smoothing_order_m(smoothing_order) {
68  units_m[0] *= length_units;
69  units_m[1] *= length_units;
70  units_m[2] *= length_units;
71  units_m[3] *= field_units;
72  units_m[4] *= field_units;
73  units_m[5] *= field_units;
74  setSymmetry(symmetry);
75  if (_fields.find(file_name) == _fields.end()) {
76  readMap();
77  _fields[file_name] = new SectorMagneticFieldMap(*this);
78  } else {
79  SectorMagneticFieldMap* tgt = _fields[file_name];
80  if (symmetry_m != tgt->symmetry_m ||
81  units_m != tgt->units_m ||
82  filename_m != tgt->filename_m) {
83  throw(LogicalError(
84  "SectorMagneticFieldMap::SectorMagneticFieldMap",
85  "Attempt to construct different SectorFieldMaps with same "+
86  std::string("file but different settings")
87  ));
88  }
90  }
91  ThreeDGrid* grid = dynamic_cast<ThreeDGrid*>(interpolator_m->getMesh());
92  phiOffset_m = -grid->minZ();
93 }
94 
96  (const SectorMagneticFieldMap& field)
97  : SectorField(field), interpolator_m(nullptr), symmetry_m(field.symmetry_m),
98  units_m(field.units_m),
99  filename_m(field.filename_m), phiOffset_m(field.phiOffset_m) {
100  VectorMap* interpolator = nullptr;
101  if (field.interpolator_m != nullptr) {
102  interpolator = field.interpolator_m;
103  }
104  setInterpolator(interpolator);
105 }
106 
108  // delete interpolator_m; We reuse the interpolators... hack! should use smart pointer
109 }
110 
112  return interpolator_m;
113 }
114 
116  if (interpolator_m != nullptr) {
117  delete interpolator_m;
118  }
119  interpolator_m = interpolator;
120  if (interpolator_m != nullptr) {
121  if (interpolator_m->getPointDimension() != 3)
122  throw(LogicalError(
123  "SectorMagneticFieldMap::setInterpolator",
124  "Attempt to load interpolator with PointDimension != 3")
125  );
126  if (interpolator_m->getValueDimension() != 3)
127  throw(LogicalError(
128  "SectorMagneticFieldMap::setInterpolator",
129  "Attempt to load interpolator with ValueDimension != 3"
130  ));
131  ThreeDGrid* grid = dynamic_cast<ThreeDGrid*>(interpolator_m->getMesh());
132  if (grid == nullptr)
133  throw(LogicalError(
134  "SectorMagneticFieldMap::setInterpolator",
135  "Attempt to load interpolator with grid not ThreeDGrid"
136  ));
138  (grid->minX(), grid->minY()-grid->maxY(), grid->minZ(),
139  grid->maxX(), grid->maxY(), grid->maxZ(),
140  0., 0., 0.);
141  }
142  getInfo(gmsg);
143 }
144 
147 }
148 
151 }
152 
154  VectorMap* interpolator = IO::readMap
156  setInterpolator(interpolator);
157 
158 }
159 
161  setInterpolator(nullptr);
162 }
163 
165  (std::string sym) {
166  if (sym == "None") {
167  return none;
168  }
169  if (sym == "Dipole") {
170  return dipole;
171  }
172  throw(LogicalError(
173  "SectorMagneticFieldMap::StringToSymmetry",
174  "Didn't recognise symmetry type "+sym
175  ));
176 }
177 
180  if (sym == none) {
181  return "None";
182  }
183  if (sym == dipole) {
184  return "Dipole";
185  }
186  throw(LogicalError(
187  "SectorMagneticFieldMap::SymmetryToString",
188  "Didn't recognise symmetry type " + std::to_string(sym)
189  ));
190 }
191 
192 /*
193 bool SectorMagneticFieldMap::getFieldstrengthPolar
194  (const Vector_t &R_p, Vector_t &, Vector_t &B_p) const {
195  // vector_t::operator[i] const returns by value, not by const reference
196  // so we need to make an array here
197  double R_temp[3] = {R_p[0], R_p[1], R_p[2]};
198  R_temp[2] += phiOffset_m;
199  // bounding box
200  if (!isInBoundingBox(R_temp))
201  return true;
202  interpolator_m->function(R_temp, &B_p[0]);
203  SectorField::convertToPolar(R_temp, &(B_p[0]));
204  return false;
205 }
206 */
207 
209  const Vector_t &R_c, Vector_t &/*E_c*/, Vector_t &B_c) const {
210  // coordinate transform; field is in the x-z plane but OPAL-CYCL assumes
211  // x-y plane; rotate to the start of the bend and into polar coordinates;
212  // apply mirror symmetry about the midplane
213  double radius = (getPolarBoundingBoxMin()[0]+getPolarBoundingBoxMax()[0])/2;
214  double midplane = (getPolarBoundingBoxMin()[1]+getPolarBoundingBoxMax()[1])/2;
215  double R_temp[3] = {R_c(0)+radius, R_c(1), R_c(2)};
216  double B_temp[3] = {0., 0., 0.};
218  bool mirror = R_temp[1] < midplane;
219  if (mirror) {
220  R_temp[1] = midplane + (midplane - R_temp[1]);
221  }
222  // interpolator has phi in 0. to dphi
223  R_temp[2] -= phiOffset_m;
224  // bool symmetryWasApplied = applySymmetry(R_temp);
225  if (!isInBoundingBox(R_temp)) {
226  return true;
227  }
228  interpolator_m->function(R_temp, B_temp);
229  // and here we transform back
230  // we want phi in 0. to dphi
231  if (mirror) {
232  B_temp[0] *= -1; // reflect Bx
233  B_temp[2] *= -1; // reflect Bz
234  }
235  B_c(0) = B_temp[0]*cos(phiOffset_m)-B_temp[2]*sin(phiOffset_m); // x
236  B_c(1) = B_temp[1]; // axial
237  B_c(2) = B_temp[0]*sin(phiOffset_m)+B_temp[2]*cos(phiOffset_m); // z
238  return false;
239 }
240 
241 bool SectorMagneticFieldMap::applySymmetry(double* R_temp) const {
242  double ymin = SectorField::getPolarBoundingBoxMin()[1];
243  if (symmetry_m == dipole && R_temp[1] <= ymin) {
244  R_temp[1] = 2*ymin-R_temp[1];
245  return true;
246  }
247  return false;
248 }
249 
252  _fields.begin(); it != _fields.end(); ++it) {
253  delete (*it).second;
254  }
255  _fields = std::map<std::string, SectorMagneticFieldMap*>();
256 }
257 
259  std::vector<double> bbmin = SectorField::getPolarBoundingBoxMin();
260  std::vector<double> bbmax = SectorField::getPolarBoundingBoxMax();
261  (*msg) << Filename_m << " (3D Sector Magnetostatic);\n"
262  << " zini= " << bbmin[1] << " mm; zfinal= " << bbmax[1] << " mm;\n"
263  << " phiini= " << bbmin[2] << " rad; phifinal= " << bbmax[2] << " rad;\n"
264  << " rini= " << bbmin[0] << " mm; rfinal= " << bbmax[0] << " mm;"
265  << endl;
266 }
267 
268 void SectorMagneticFieldMap::print(std::ostream& out) {
269  std::vector<double> bbmin = SectorField::getPolarBoundingBoxMin();
270  std::vector<double> bbmax = SectorField::getPolarBoundingBoxMax();
271  out << Filename_m << " (3D Sector Magnetostatic);\n"
272  << " zini= " << bbmin[1] << " m; zfinal= " << bbmax[1] << " mm;\n"
273  << " phiini= " << bbmin[2] << " rad; phifinal= " << bbmax[2] << " rad;\n"
274  << " rini= " << bbmin[0] << " m; rfinal= " << bbmax[0] << " mm;\n"
275  << std::endl;
276 }
277 
279  Vector_t &/*B*/, const DiffDirection &/*dir*/) const {
280  throw(LogicalError("SectorMagneticFieldMap::getFieldDerivative",
281  "Field map derivatives not implemented"));
282 }
283 
285 
286 
288  ThreeDGrid* grid = reinterpret_cast<ThreeDGrid*>(interpolator_m->getMesh());
289  return grid->maxZ() - grid->minZ();
290 }
291 
293 const int SectorMagneticFieldMap::IO::sortOrder_m[3] = {0, 1, 2};
294 
296  std::string file_name,
297  std::vector<double> units,
299  int polynomial_order,
300  int smoothing_order) {
301  try {
302  *gmsg <<"* Opening sector field map " << file_name
303  << " fit order " << polynomial_order
304  << " smoothing order " << smoothing_order << endl;
305  // get raw data
306  std::vector< std::vector<double> > field_points = readLines
307  (file_name, units);
308  // build grid
309  ThreeDGrid* grid = generateGrid(field_points, sym);
310  // build interpolator (convert grid to useful units)
311  if (polynomial_order == 1 && smoothing_order == 1) {
312  VectorMap* interpolator = getInterpolator(field_points, grid, sym);
313  return interpolator;
314  } else {
315  VectorMap* interpolator = getInterpolatorPolyPatch(
316  field_points,
317  grid,
318  sym,
319  polynomial_order,
320  smoothing_order);
321  return interpolator;
322  }
323  } catch(std::exception& exc) {
324  throw(LogicalError(
325  "SectorMagneticFieldMap::IO::ReadMap",
326  "Failed to read file "+file_name+" with "+(&exc)->what()
327  ));
328  }
329  return nullptr;
330 }
331 
333  std::vector< std::vector<double> > field_points,
334  ThreeDGrid* grid,
336  int polynomial_order,
337  int smoothing_order) {
338  // too lazy to write code to handle this case - not available to user anyway
339  if (sym != SectorMagneticFieldMap::dipole) {
340  throw(LogicalError(
341  "SectorMagneticFieldMap::IO::getInterpolatorPolyPatch",
342  "Failed to recognise symmetry type"
343  ));
344  }
345  std::vector< std::vector<double> > data(field_points.size(),
346  std::vector<double>(3));
347  for (size_t i = 0; i < field_points.size(); ++i) {
348  data[i][0] = field_points[i][3];
349  data[i][1] = field_points[i][4];
350  data[i][2] = field_points[i][5];
351  }
352  // symmetry is dipole
353  try {
354  *gmsg << "Calculating polynomials..." << endl;
355  PPSolveFactory solver(grid, data, polynomial_order, smoothing_order);
356  PolynomialPatch* patch = solver.solve();
357  *gmsg << " ... done" << endl;
358  return patch;
359  } catch (GeneralClassicException& exc) {
360  throw;
361  }
362 
363 }
364 
365 const std::string SectorMagneticFieldMap::IO::errMsg1 =
366  std::string("field points during read ")+
367  std::string("operation; this could mean that the field ")+
368  std::string("map was not complete, or that OPAL could ")+
369  std::string("not calculate regular grid spacings properly. ")+
370  std::string("Check that the field map is on a cylindrical ")+
371  std::string("grid written in Cartesian coordinates and the ")+
372  std::string("grid points are written with enough precision (")+
373  std::string("check the grid size information above).");
374 
376  (const std::vector< std::vector<double> > field_points,
377  ThreeDGrid* grid,
379  // build field arrays
380  double *** Bx, *** By, *** Bz;
381  int index = 0;
382  Bx = new double**[grid->xSize()];
383  By = new double**[grid->xSize()];
384  Bz = new double**[grid->xSize()];
385  for (int i = 0; i < grid->xSize(); ++i) {
386  Bx[i] = new double*[grid->ySize()];
387  By[i] = new double*[grid->ySize()];
388  Bz[i] = new double*[grid->ySize()];
389  for (int j = 0; j < grid->ySize(); ++j) {
390  Bx[i][j] = new double[grid->zSize()];
391  By[i][j] = new double[grid->zSize()];
392  Bz[i][j] = new double[grid->zSize()];
393  for (int k = 0; k < grid->zSize(); ++k) {
394  if (index >= int(field_points.size())) {
395  throw(
396  LogicalError(
397  "SectorMagneticFieldMap::IO::getInterpolator",
398  "Ran out of "+errMsg1)
399  );
400  }
401  Bx[i][j][k] = field_points[index][3];
402  By[i][j][k] = field_points[index][4];
403  Bz[i][j][k] = field_points[index][5];
404  ++index;
405  }
406  }
407  }
408  if (index != int(field_points.size())) {
409  throw(LogicalError(
410  "SectorMagneticFieldMap::IO::getInterpolator",
411  "Too many "+errMsg1
412  ));
413  }
414  Interpolator3dGridTo3d* interpolator = new Interpolator3dGridTo3d(grid, Bx, By, Bz);
415  VectorMap* interpolatorMap = dynamic_cast<VectorMap*>(interpolator);
416  return interpolatorMap;
417 }
418 
419 bool SectorMagneticFieldMap::IO::comparator(std::vector<double> field_item1,
420  std::vector<double> field_item2) {
421  const int* order = sortOrder_m;
422  if (std::abs(field_item1[order[0]] - field_item2[order[0]]) > floatTolerance_m) {
423  return field_item1[order[0]] < field_item2[order[0]];
424  }
425  if (std::abs(field_item1[order[1]] - field_item2[order[1]]) > floatTolerance_m) {
426  return field_item1[order[1]] < field_item2[order[1]];
427  }
428  return field_item1[order[2]] < field_item2[order[2]];
429 }
430 
431 std::vector< std::vector<double> > SectorMagneticFieldMap::IO::readLines
432  (std::string file_name, std::vector<double> units) {
433  std::vector< std::vector<double> > field_points;
434  std::string line;
435  if (units.size() != 6) {
436  throw(LogicalError(
437  "SectorMagneticFieldMap::IO::ReadLines",
438  "Units should be of length 6"
439  ));
440  }
441 
442  std::ifstream fin(file_name.c_str());
443  if (!fin || !fin.is_open()) {
444  throw(LogicalError(
445  "SectorMagneticFieldMap::IO::ReadLines",
446  "Failed to open file "+file_name
447  ));
448  }
449  // skip header lines
450  *gmsg << "* Opened "+file_name << endl;
451  for (size_t i = 0; i < 8; ++i) {
452  std::getline(fin, line);
453  }
454  // read in field map
455  int line_number = 0;
456  while (fin) {
457  std::vector<double> field(6);
458  fin >> field[0] >> field[1] >> field[2] >> field[3] >> field[4]
459  >> field[5];
460  if (fin) {
461  for (size_t i = 0; i < 6; ++i) {
462  field[i] *= units[i];
463  }
464  field_points.push_back(field);
465  line_number++;
466  }
467  }
468  *gmsg << "* Read " << line_number << " lines" << endl;
469 
470  // convert coordinates to polar; nb we leave field as cartesian
471  for (size_t i = 0; i < field_points.size(); ++i) {
472  SectorField::convertToPolar(&field_points[i][0]);
473  }
474 
475  // force check sort order
476  std::sort(field_points.begin(), field_points.end(),
478  return field_points;
479 }
480 
481 bool SectorMagneticFieldMap::IO::floatGreaterEqual(double in1, double in2) {
482  in2 = in2*(1+floatTolerance_m)+floatTolerance_m;
483  return in1 > in2;
484 }
485 
487  (const std::vector< std::vector<double> > field_points,
489  std::vector<double> r_grid(1, field_points[0][0]);
490  std::vector<double> y_grid(1, field_points[0][1]);
491  std::vector<double> phi_grid(1, field_points[0][2]);
492  for (size_t i = 0; i < field_points.size(); ++i) {
493  if (floatGreaterEqual(field_points[i][0], r_grid.back())) {
494  r_grid.push_back(field_points[i][0]);
495  }
496  if (floatGreaterEqual(field_points[i][1], y_grid.back())) {
497  y_grid.push_back(field_points[i][1]);
498  }
499  if (floatGreaterEqual(field_points[i][2], phi_grid.back())) {
500  phi_grid.push_back(field_points[i][2]);
501  }
502  }
503 
504  // reflect about y if symmetry is dipole
505  *gmsg << "* Grid size (r, y, phi) = ("
506  << r_grid.size() << ", " << y_grid.size() << ", " << phi_grid.size()
507  << ")" << endl;
508  *gmsg << "* Grid min (r [mm], y [mm], phi [rad]) = ("
509  << r_grid[0] << ", " << y_grid[0] << ", " << phi_grid[0]
510  << ")" << endl;
511  *gmsg << "* Grid max (r [mm], y [mm], phi [rad]) = ("
512  << r_grid.back() << ", " << y_grid.back() << ", " << phi_grid.back()
513  << ")" << endl;
514 
515  ThreeDGrid* grid = new ThreeDGrid(r_grid, y_grid, phi_grid);
516  grid->setConstantSpacing(true);
517  return grid;
518 }
virtual unsigned int getValueDimension() const =0
void setInterpolator(interpolation::VectorMap *interpolator)
SDDS1 &description units
Definition: test.stat:6
and that you know you can do these things To protect your we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights These restrictions translate to certain responsibilities for you if you distribute copies of the or if you modify it For if you distribute copies of such a whether gratis or for a you must give the recipients all the rights that you have You must make sure that receive or can get the source code And you must show them these terms so they know their rights We protect your rights with two distribute and or modify the software for each author s protection and we want to make certain that everyone understands that there is no warranty for this free software If the software is modified by someone else and passed we want its recipients to know that what they have is not the so that any problems introduced by others will not reflect on the original authors reputations any free program is threatened constantly by software patents We wish to avoid the danger that redistributors of a free program will individually obtain patent in effect making the program proprietary To prevent we have made it clear that any patent must be licensed for everyone s free use or not licensed at all The precise terms and conditions for distribution and modification follow GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR DISTRIBUTION AND MODIFICATION This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License The refers to any such program or and a work based on the Program means either the Program or any derivative work under copyright a work containing the Program or a portion of it
Definition: LICENSE:43
double minY() const
Definition: ThreeDGrid.h:430
DiffDirection
Definition: Fieldmap.h:55
static const std::string errMsg1
bool getFieldstrength(const Vector_t &R_c, Vector_t &E_c, Vector_t &B_c) const
std::vector< double > units_m
double maxY() const
Definition: ThreeDGrid.h:434
double maxX() const
Definition: ThreeDGrid.h:426
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
SectorMagneticFieldMap(std::string file_name, std::string symmetry, double length_units, double field_units, int polynomial_order, int smoothing_order)
double minX() const
Definition: ThreeDGrid.h:422
bool applySymmetry(double *R_temp) const
static interpolation::VectorMap * getInterpolator(const std::vector< std::vector< double > > field_points, interpolation::ThreeDGrid *grid, SectorMagneticFieldMap::symmetry sym)
void setConstantSpacing(bool spacing)
Definition: ThreeDGrid.h:468
void setSymmetry(std::string name)
virtual std::vector< double > getPolarBoundingBoxMax() const
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)
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
static interpolation::ThreeDGrid * generateGrid(const std::vector< std::vector< double > > field_points, SectorMagneticFieldMap::symmetry sym)
virtual void function(const double *point, double *value) const =0
interpolation::VectorMap * interpolator_m
std::string::iterator iterator
Definition: MSLang.h:15
bool isInBoundingBox(const double R_p[]) const
Definition: SectorField.h:224
static const double fractionalBBPhiTolerance_m
bool getFieldDerivative(const Vector_t &R, Vector_t &E, Vector_t &B, const DiffDirection &dir) const
Definition: Inform.h:42
PPSolveFactory solves the system of linear equations to interpolate from a grid of points using highe...
static const double floatTolerance_m
virtual std::vector< double > getPolarBoundingBoxMin() const
static std::vector< std::vector< double > > readLines(std::string file_name, std::vector< double > units)
static std::string SymmetryToString(symmetry sym)
double minZ() const
Definition: ThreeDGrid.h:438
handles field map grids with sector geometry
void setPolarBoundingBox(double bbMinR, double bbMinY, double bbMinPhi, double bbMaxR, double bbMaxY, double bbMaxPhi, double bbTolR, double bbTolY, double bbTolPhi)
Definition: SectorField.cpp:87
Tps< T > cos(const Tps< T > &x)
Cosine.
Definition: TpsMath.h:129
virtual Mesh * getMesh() const
Definition: VectorMap.h:91
void print(std::ostream &out)
const std::string name
c Accompany it with the information you received as to the offer to distribute corresponding source complete source code means all the source code for all modules it plus any associated interface definition plus the scripts used to control compilation and installation of the executable as a special exception
Definition: LICENSE:157
static symmetry StringToSymmetry(std::string name)
double maxZ() const
Definition: ThreeDGrid.h:442
interpolation::VectorMap * getInterpolator()
static void convertToPolar(double *position)
Definition: SectorField.cpp:54
Patches together many SquarePolynomialVectors to make a multidimensional polynomial spline...
std::string getSymmetry() const
virtual unsigned int getPointDimension() const =0
constexpr double e
The value of .
Definition: Physics.h:39
Tps< T > sin(const Tps< T > &x)
Sine.
Definition: TpsMath.h:111
static std::map< std::string, SectorMagneticFieldMap * > _fields
Logical error exception.
Definition: LogicalError.h:33
static bool floatGreaterEqual(double in1, double in2)
static interpolation::VectorMap * readMap(std::string file_name, std::vector< double > units, SectorMagneticFieldMap::symmetry sym, int poly_order, int smoothing_order)
Inform * gmsg
Definition: Main.cpp:70
std::string Filename_m
Definition: SectorField.h:217