The Spherical Harmonic Model
| This documentation was generated with the assistance of AI. Please report any inaccuracies. |
Classes: WorldMagneticModel, WMMLoader, WMMEarthMagneticFluxDensityEstimator (see the
Class Reference table at the end of this page for Javadoc and source links).
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.