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