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