GeographicLib  1.43
MagneticModel.hpp
Go to the documentation of this file.
1 /**
2  * \file MagneticModel.hpp
3  * \brief Header for GeographicLib::MagneticModel class
4  *
5  * Copyright (c) Charles Karney (2011-2015) <charles@karney.com> and licensed
6  * under the MIT/X11 License. For more information, see
7  * http://geographiclib.sourceforge.net/
8  **********************************************************************/
9 
10 #if !defined(GEOGRAPHICLIB_MAGNETICMODEL_HPP)
11 #define GEOGRAPHICLIB_MAGNETICMODEL_HPP 1
12 
16 
17 #if defined(_MSC_VER)
18 // Squelch warnings about dll vs vector
19 # pragma warning (push)
20 # pragma warning (disable: 4251)
21 #endif
22 
23 namespace GeographicLib {
24 
25  class MagneticCircle;
26 
27  /**
28  * \brief Model of the earth's magnetic field
29  *
30  * Evaluate the earth's magnetic field according to a model. At present only
31  * internal magnetic fields are handled. These are due to the earth's code
32  * and crust; these vary slowly (over many years). Excluded are the effects
33  * of currents in the ionosphere and magnetosphere which have daily and
34  * annual variations.
35  *
36  * See \ref magnetic for details of how to install the magnetic models and
37  * the data format.
38  *
39  * See
40  * - General information:
41  * - http://geomag.org/models/index.html
42  * - WMM2010:
43  * - http://ngdc.noaa.gov/geomag/WMM/DoDWMM.shtml
44  * - http://ngdc.noaa.gov/geomag/WMM/data/WMM2010/WMM2010COF.zip
45  * - WMM2015:
46  * - http://ngdc.noaa.gov/geomag/WMM/DoDWMM.shtml
47  * - http://ngdc.noaa.gov/geomag/WMM/data/WMM2015/WMM2015COF.zip
48  * - IGRF11:
49  * - http://ngdc.noaa.gov/IAGA/vmod/igrf.html
50  * - http://ngdc.noaa.gov/IAGA/vmod/igrf11coeffs.txt
51  * - http://ngdc.noaa.gov/IAGA/vmod/geomag70_linux.tar.gz
52  * - EMM2010:
53  * - http://ngdc.noaa.gov/geomag/EMM/index.html
54  * - http://ngdc.noaa.gov/geomag/EMM/data/geomag/EMM2010_Sph_Windows_Linux.zip
55  *
56  * Example of use:
57  * \include example-MagneticModel.cpp
58  *
59  * <a href="MagneticField.1.html">MagneticField</a> is a command-line utility
60  * providing access to the functionality of MagneticModel and MagneticCircle.
61  **********************************************************************/
62 
64  private:
65  typedef Math::real real;
66  static const int idlength_ = 8;
67  std::string _name, _dir, _description, _date, _filename, _id;
68  real _t0, _dt0, _tmin, _tmax, _a, _hmin, _hmax;
69  int _Nmodels, _Nconstants;
71  Geocentric _earth;
72  std::vector< std::vector<real> > _G;
73  std::vector< std::vector<real> > _H;
74  std::vector<SphericalHarmonic> _harm;
75  void Field(real t, real lat, real lon, real h, bool diffp,
76  real& Bx, real& By, real& Bz,
77  real& Bxt, real& Byt, real& Bzt) const;
78  void ReadMetadata(const std::string& name);
79  MagneticModel(const MagneticModel&); // copy constructor not allowed
80  MagneticModel& operator=(const MagneticModel&); // nor copy assignment
81  public:
82 
83  /** \name Setting up the magnetic model
84  **********************************************************************/
85  ///@{
86  /**
87  * Construct a magnetic model.
88  *
89  * @param[in] name the name of the model.
90  * @param[in] path (optional) directory for data file.
91  * @param[in] earth (optional) Geocentric object for converting
92  * coordinates; default Geocentric::WGS84().
93  * @exception GeographicErr if the data file cannot be found, is
94  * unreadable, or is corrupt.
95  * @exception std::bad_alloc if the memory necessary for storing the model
96  * can't be allocated.
97  *
98  * A filename is formed by appending ".wmm" (World Magnetic Model) to the
99  * name. If \e path is specified (and is non-empty), then the file is
100  * loaded from directory, \e path. Otherwise the path is given by the
101  * DefaultMagneticPath().
102  *
103  * This file contains the metadata which specifies the properties of the
104  * model. The coefficients for the spherical harmonic sums are obtained
105  * from a file obtained by appending ".cof" to metadata file (so the
106  * filename ends in ".wwm.cof").
107  *
108  * The model is not tied to a particular ellipsoidal model of the earth.
109  * The final earth argument to the constructor specifies an ellipsoid to
110  * allow geodetic coordinates to the transformed into the spherical
111  * coordinates used in the spherical harmonic sum.
112  **********************************************************************/
113  explicit MagneticModel(const std::string& name,
114  const std::string& path = "",
115  const Geocentric& earth = Geocentric::WGS84());
116  ///@}
117 
118  /** \name Compute the magnetic field
119  **********************************************************************/
120  ///@{
121  /**
122  * Evaluate the components of the geomagnetic field.
123  *
124  * @param[in] t the time (years).
125  * @param[in] lat latitude of the point (degrees).
126  * @param[in] lon longitude of the point (degrees).
127  * @param[in] h the height of the point above the ellipsoid (meters).
128  * @param[out] Bx the easterly component of the magnetic field (nanotesla).
129  * @param[out] By the northerly component of the magnetic field (nanotesla).
130  * @param[out] Bz the vertical (up) component of the magnetic field
131  * (nanotesla).
132  **********************************************************************/
133  void operator()(real t, real lat, real lon, real h,
134  real& Bx, real& By, real& Bz) const {
135  real dummy;
136  Field(t, lat, lon, h, false, Bx, By, Bz, dummy, dummy, dummy);
137  }
138 
139  /**
140  * Evaluate the components of the geomagnetic field and their time
141  * derivatives
142  *
143  * @param[in] t the time (years).
144  * @param[in] lat latitude of the point (degrees).
145  * @param[in] lon longitude of the point (degrees).
146  * @param[in] h the height of the point above the ellipsoid (meters).
147  * @param[out] Bx the easterly component of the magnetic field (nanotesla).
148  * @param[out] By the northerly component of the magnetic field (nanotesla).
149  * @param[out] Bz the vertical (up) component of the magnetic field
150  * (nanotesla).
151  * @param[out] Bxt the rate of change of \e Bx (nT/yr).
152  * @param[out] Byt the rate of change of \e By (nT/yr).
153  * @param[out] Bzt the rate of change of \e Bz (nT/yr).
154  **********************************************************************/
155  void operator()(real t, real lat, real lon, real h,
156  real& Bx, real& By, real& Bz,
157  real& Bxt, real& Byt, real& Bzt) const {
158  Field(t, lat, lon, h, true, Bx, By, Bz, Bxt, Byt, Bzt);
159  }
160 
161  /**
162  * Create a MagneticCircle object to allow the geomagnetic field at many
163  * points with constant \e lat, \e h, and \e t and varying \e lon to be
164  * computed efficiently.
165  *
166  * @param[in] t the time (years).
167  * @param[in] lat latitude of the point (degrees).
168  * @param[in] h the height of the point above the ellipsoid (meters).
169  * @exception std::bad_alloc if the memory necessary for creating a
170  * MagneticCircle can't be allocated.
171  * @return a MagneticCircle object whose MagneticCircle::operator()(real
172  * lon) member function computes the field at particular values of \e
173  * lon.
174  *
175  * If the field at several points on a circle of latitude need to be
176  * calculated then creating a MagneticCircle and using its member functions
177  * will be substantially faster, especially for high-degree models.
178  **********************************************************************/
179  MagneticCircle Circle(real t, real lat, real h) const;
180 
181  /**
182  * Compute various quantities dependent on the magnetic field.
183  *
184  * @param[in] Bx the \e x (easterly) component of the magnetic field (nT).
185  * @param[in] By the \e y (northerly) component of the magnetic field (nT).
186  * @param[in] Bz the \e z (vertical, up positive) component of the magnetic
187  * field (nT).
188  * @param[out] H the horizontal magnetic field (nT).
189  * @param[out] F the total magnetic field (nT).
190  * @param[out] D the declination of the field (degrees east of north).
191  * @param[out] I the inclination of the field (degrees down from
192  * horizontal).
193  **********************************************************************/
194  static void FieldComponents(real Bx, real By, real Bz,
195  real& H, real& F, real& D, real& I) {
196  real Ht, Ft, Dt, It;
197  FieldComponents(Bx, By, Bz, real(0), real(1), real(0),
198  H, F, D, I, Ht, Ft, Dt, It);
199  }
200 
201  /**
202  * Compute various quantities dependent on the magnetic field and its rate
203  * of change.
204  *
205  * @param[in] Bx the \e x (easterly) component of the magnetic field (nT).
206  * @param[in] By the \e y (northerly) component of the magnetic field (nT).
207  * @param[in] Bz the \e z (vertical, up positive) component of the magnetic
208  * field (nT).
209  * @param[in] Bxt the rate of change of \e Bx (nT/yr).
210  * @param[in] Byt the rate of change of \e By (nT/yr).
211  * @param[in] Bzt the rate of change of \e Bz (nT/yr).
212  * @param[out] H the horizontal magnetic field (nT).
213  * @param[out] F the total magnetic field (nT).
214  * @param[out] D the declination of the field (degrees east of north).
215  * @param[out] I the inclination of the field (degrees down from
216  * horizontal).
217  * @param[out] Ht the rate of change of \e H (nT/yr).
218  * @param[out] Ft the rate of change of \e F (nT/yr).
219  * @param[out] Dt the rate of change of \e D (degrees/yr).
220  * @param[out] It the rate of change of \e I (degrees/yr).
221  **********************************************************************/
222  static void FieldComponents(real Bx, real By, real Bz,
223  real Bxt, real Byt, real Bzt,
224  real& H, real& F, real& D, real& I,
225  real& Ht, real& Ft, real& Dt, real& It);
226  ///@}
227 
228  /** \name Inspector functions
229  **********************************************************************/
230  ///@{
231  /**
232  * @return the description of the magnetic model, if available, from the
233  * Description file in the data file; if absent, return "NONE".
234  **********************************************************************/
235  const std::string& Description() const { return _description; }
236 
237  /**
238  * @return date of the model, if available, from the ReleaseDate field in
239  * the data file; if absent, return "UNKNOWN".
240  **********************************************************************/
241  const std::string& DateTime() const { return _date; }
242 
243  /**
244  * @return full file name used to load the magnetic model.
245  **********************************************************************/
246  const std::string& MagneticFile() const { return _filename; }
247 
248  /**
249  * @return "name" used to load the magnetic model (from the first argument
250  * of the constructor, but this may be overridden by the model file).
251  **********************************************************************/
252  const std::string& MagneticModelName() const { return _name; }
253 
254  /**
255  * @return directory used to load the magnetic model.
256  **********************************************************************/
257  const std::string& MagneticModelDirectory() const { return _dir; }
258 
259  /**
260  * @return the minimum height above the ellipsoid (in meters) for which
261  * this MagneticModel should be used.
262  *
263  * Because the model will typically provide useful results
264  * slightly outside the range of allowed heights, no check of \e t
265  * argument is made by MagneticModel::operator()() or
266  * MagneticModel::Circle.
267  **********************************************************************/
268  Math::real MinHeight() const { return _hmin; }
269 
270  /**
271  * @return the maximum height above the ellipsoid (in meters) for which
272  * this MagneticModel should be used.
273  *
274  * Because the model will typically provide useful results
275  * slightly outside the range of allowed heights, no check of \e t
276  * argument is made by MagneticModel::operator()() or
277  * MagneticModel::Circle.
278  **********************************************************************/
279  Math::real MaxHeight() const { return _hmax; }
280 
281  /**
282  * @return the minimum time (in years) for which this MagneticModel should
283  * be used.
284  *
285  * Because the model will typically provide useful results
286  * slightly outside the range of allowed times, no check of \e t
287  * argument is made by MagneticModel::operator()() or
288  * MagneticModel::Circle.
289  **********************************************************************/
290  Math::real MinTime() const { return _tmin; }
291 
292  /**
293  * @return the maximum time (in years) for which this MagneticModel should
294  * be used.
295  *
296  * Because the model will typically provide useful results
297  * slightly outside the range of allowed times, no check of \e t
298  * argument is made by MagneticModel::operator()() or
299  * MagneticModel::Circle.
300  **********************************************************************/
301  Math::real MaxTime() const { return _tmax; }
302 
303  /**
304  * @return \e a the equatorial radius of the ellipsoid (meters). This is
305  * the value of \e a inherited from the Geocentric object used in the
306  * constructor.
307  **********************************************************************/
308  Math::real MajorRadius() const { return _earth.MajorRadius(); }
309 
310  /**
311  * @return \e f the flattening of the ellipsoid. This is the value
312  * inherited from the Geocentric object used in the constructor.
313  **********************************************************************/
314  Math::real Flattening() const { return _earth.Flattening(); }
315  ///@}
316 
317  /**
318  * @return the default path for magnetic model data files.
319  *
320  * This is the value of the environment variable
321  * GEOGRAPHICLIB_MAGNETIC_PATH, if set; otherwise, it is
322  * $GEOGRAPHICLIB_DATA/magnetic if the environment variable
323  * GEOGRAPHICLIB_DATA is set; otherwise, it is a compile-time default
324  * (/usr/local/share/GeographicLib/magnetic on non-Windows systems and
325  * C:/ProgramData/GeographicLib/magnetic on Windows systems).
326  **********************************************************************/
327  static std::string DefaultMagneticPath();
328 
329  /**
330  * @return the default name for the magnetic model.
331  *
332  * This is the value of the environment variable
333  * GEOGRAPHICLIB_MAGNETIC_NAME, if set; otherwise, it is "wmm2015". The
334  * MagneticModel class does not use this function; it is just provided as a
335  * convenience for a calling program when constructing a MagneticModel
336  * object.
337  **********************************************************************/
338  static std::string DefaultMagneticName();
339  };
340 
341 } // namespace GeographicLib
342 
343 #if defined(_MSC_VER)
344 # pragma warning (pop)
345 #endif
346 
347 #endif // GEOGRAPHICLIB_MAGNETICMODEL_HPP
Math::real MinHeight() const
#define GEOGRAPHICLIB_EXPORT
Definition: Constants.hpp:90
const std::string & Description() const
Math::real MajorRadius() const
GeographicLib::Math::real real
Definition: GeodSolve.cpp:32
Model of the earth&#39;s magnetic field.
Geomagnetic field on a circle of latitude.
static void FieldComponents(real Bx, real By, real Bz, real &H, real &F, real &D, real &I)
void operator()(real t, real lat, real lon, real h, real &Bx, real &By, real &Bz, real &Bxt, real &Byt, real &Bzt) const
const std::string & MagneticModelDirectory() const
Geocentric coordinates
Definition: Geocentric.hpp:67
void operator()(real t, real lat, real lon, real h, real &Bx, real &By, real &Bz) const
static const Geocentric & WGS84()
Definition: Geocentric.cpp:31
Namespace for GeographicLib.
Definition: Accumulator.cpp:12
const std::string & MagneticModelName() const
Header for GeographicLib::Geocentric class.
Math::real Flattening() const
Math::real Flattening() const
Definition: Geocentric.hpp:256
Header for GeographicLib::SphericalHarmonic class.
Math::real MaxHeight() const
Header for GeographicLib::Constants class.
const std::string & MagneticFile() const
Math::real MajorRadius() const
Definition: Geocentric.hpp:249
const std::string & DateTime() const