The Spherical Harmonic Model
| This documentation was generated with the assistance of AI. Please report any inaccuracies. |
Classes: WorldMagneticModel, WMMLoader, WMMEarthMagneticFluxDensityEstimator.
Coefficient files
The WMM represents the Earth’s main magnetic field (and its slow year-on-year drift) as a degree-and-order-12
spherical harmonic expansion of the geomagnetic potential. Its 168+134 Gauss coefficients are re-fit
every 5 years by NCEI/NGA/BGS from satellite, aircraft, and observatory measurements, and published as a
plain-text .cof coefficient file — see
NOAA coefficient downloads
and the file-format description
([wmm-site]). This library bundles a wmm.cof resource and loads it
through WMMLoader; a newer release can be substituted by loading a different file, resource, or URL.
|
Each WMM release is only valid for |
Each data line in the file has the form:
n m gnm hnm dgnm dhnm
and are the spherical harmonic degree and order; , are the
main-field Gauss coefficients (nT) at the model epoch; , are their
secular-variation rates (nT/year). WorldMagneticModel stores these (Schmidt semi-normalized, see
below) together with the epoch year.
WMMLoader: Schmidt semi-normalization
Raw Gauss coefficients are published in Schmidt quasi-normalized form. WMMLoader converts them, once,
into the fully normalized form used internally, via the recursive Schmidt normalization factor:
and rescales (and equivalently for , , ). It also precomputes the recursion coefficients
used by WMMEarthMagneticFluxDensityEstimator to generate the associated Legendre functions.
// load a specific coefficient file (e.g. a newer WMM release than the bundled one)
WorldMagneticModel model = WMMLoader.loadFromFile("/path/to/WMM.COF");
// or from an arbitrary resource/URL:
// WMMLoader.loadFromResource("/com/irurueta/navigation/inertial/wmm/wmm.cof");
// WMMLoader.loadFromUrl("https://example.org/WMM.COF");
WMMEarthMagneticFluxDensityEstimator: evaluating the model
Given a geodetic position and a decimal year, the estimator:
1. Geodetic-to-geocentric conversion. Because the WGS84 ellipsoid is not a sphere, geodetic latitude must first be converted to a geocentric colatitude and radius before the spherical-harmonic sum applies.
2. Time adjustment. Coefficients are linearly extrapolated from the model epoch:
This is only a good approximation within the model’s 5-year validity window (see World Magnetic Model (WMM)) — extrapolating far past years accumulates error.
3. Legendre recursion. The Schmidt semi-normalized associated Legendre functions
and their colatitude derivatives are generated by the stable recursion (using from
WMMLoader):
4. Spherical-harmonic sum. The field components in geocentric spherical coordinates (radial , colatitude , longitude ) accumulate one term per pair, using raised to the -th power ( = 6371.2 km, the WMM reference radius):
(with the term handled by a separate polar-region recursion at the geographic poles, where ). See the NOAA WMM technical report ([wmm-site]) for the full derivation.
5. Rotate to geodetic North/East/Down. The geocentric components are rotated back into the geodetic frame using the geocentric/geodetic latitude difference angle computed during step 1:
6. Derived quantities. Horizontal intensity, total intensity, declination, and dip follow directly:
WMMEarthMagneticFluxDensityEstimator exposes each of these individually (getDeclination, getDip,
getIntensity, getHorizontalIntensity, getNorthIntensity, getEastIntensity,
getVerticalIntensity) as well as the full NEDMagneticFluxDensity vector via estimate(…).
// no-arg constructor loads the coefficient file bundled with this library
WMMEarthMagneticFluxDensityEstimator estimator = new WMMEarthMagneticFluxDensityEstimator();
NEDPosition position = new NEDPosition(Math.toRadians(41.3851), Math.toRadians(2.1734), 0.0);
double year = 2026.5; // decimal year
double declination = estimator.getDeclination(position, year); // radians
double dip = estimator.getDip(position.getLatitude(), position.getLongitude(), position.getHeight(), year);
NEDMagneticFluxDensity b = new NEDMagneticFluxDensity();
estimator.estimate(position.getLatitude(), position.getLongitude(), position.getHeight(), year, b);
Where to go next
-
Earth Magnetic Flux Density Container and Simple Estimator — the simpler magnitude/declination/dip container classes.
-
Attitude Estimators: Leveling, Gyrocompassing, and Magnetic Heading — how the resulting declination/dip feed into heading estimation.
-
reference.adoc#bibliography — bibliography.