Magnetism Models

This example demonstrates the pytcl.magnetism module capabilities, including World Magnetic Model (WMM2020) coefficients, dipole moment calculations, and geomagnetic field properties.

Overview

Earth’s magnetic field models are essential for:

  • Navigation: Compass corrections and heading reference

  • Aerospace: Attitude determination using magnetometers

  • Geophysics: Understanding Earth’s core dynamics

  • Space weather: Radiation environment modeling

WMM2020 Coefficients

The World Magnetic Model uses spherical harmonic coefficients:

Gauss Coefficients (g, h)
  • g[n,m]: coefficients for cos(m*lambda) terms

  • h[n,m]: coefficients for sin(m*lambda) terms

  • Units: nanoTesla (nT)

Secular Variation (g_dot, h_dot)
  • Rate of change of coefficients

  • Units: nT/year

  • Used for temporal extrapolation

Epoch and Validity
  • WMM2020 epoch: 2020.0

  • Valid period: 2020-2025

  • Maximum order: n_max = 12

Global Magnetic Field: Earth’s magnetic field varies with latitude and longitude, with field strength strongest near the poles.

Dipole Properties

Magnetic Dipole Moment
  • Earth’s main field approximated as dipole

  • Moment: ~8 x 10^22 A*m^2

  • Decreasing ~5% per century

Dipole Axis
  • Tilted ~11° from rotation axis

  • Magnetic poles vs geographic poles

  • Axis drifts over time (secular variation)

Harmonic Strength by Order
  • n=1: Dipole (dominant)

  • n=2-4: Quadrupole, octupole terms

  • Higher orders: smaller contributions

Code Highlights

The example demonstrates:

  • WMM2020 coefficient creation with create_wmm2020_coefficients()

  • Dipole moment calculation with dipole_moment()

  • Dipole axis orientation with dipole_axis()

  • Coefficient structure and magnitudes

Source Code

  1"""Magnetism module demonstration with geomagnetic models.
  2
  3This example demonstrates the pytcl.magnetism module capabilities, including
  4World Magnetic Model (WMM2020) coefficients, dipole moment calculations, and
  5geomagnetic field properties.
  6
  7Functions demonstrated:
  8- create_wmm2020_coefficients(): Create WMM2020 magnetic coefficients
  9- dipole_moment(): Calculate Earth's magnetic dipole moment
 10- dipole_axis(): Calculate dipole axis orientation
 11"""
 12
 13from pathlib import Path
 14
 15import numpy as np
 16import plotly.graph_objects as go
 17from plotly.subplots import make_subplots
 18
 19from pytcl.magnetism import (
 20    create_wmm2020_coefficients,
 21    dipole_axis,
 22    dipole_moment,
 23)
 24
 25# Controls for visualization
 26SHOW_PLOTS = False
 27
 28
 29def demo_wmm2020_coefficients() -> None:
 30    """Demonstrate WMM2020 magnetic coefficients."""
 31    print("\n" + "=" * 60)
 32    print("WMM2020 Magnetic Coefficients")
 33    print("=" * 60)
 34
 35    # Create WMM2020 coefficients
 36    coeffs = create_wmm2020_coefficients()
 37
 38    print(f"\nCoefficients created for epoch: {coeffs.epoch}")
 39    print(f"Maximum order (n_max): {coeffs.n_max}")
 40    print(f"G coefficients shape (Gauss): {coeffs.g.shape}")
 41    print(f"H coefficients shape (Gauss): {coeffs.h.shape}")
 42    print(f"G-dot coefficients shape (Gauss/year): {coeffs.g_dot.shape}")
 43    print(f"H-dot coefficients shape (Gauss/year): {coeffs.h_dot.shape}")
 44
 45    # Show some sample coefficients
 46    print("\nSample Gauss coefficients (g) [nT]:")
 47    print(f"  g[1,0] = {coeffs.g[1, 0]:.2f}")
 48    print(f"  g[1,1] = {coeffs.g[1, 1]:.2f}")
 49    print(f"  g[2,0] = {coeffs.g[2, 0]:.2f}")
 50
 51    print("\nSample Schmidt coefficients (h) [nT]:")
 52    print(f"  h[1,1] = {coeffs.h[1, 1]:.2f}")
 53    print(f"  h[2,1] = {coeffs.h[2, 1]:.2f}")
 54    print(f"  h[2,2] = {coeffs.h[2, 2]:.2f}")
 55
 56    # Show secular variation rates
 57    print("\nSample secular variation rates [nT/year]:")
 58    print(f"  g_dot[1,0] = {coeffs.g_dot[1, 0]:.2f}")
 59    print(f"  h_dot[1,1] = {coeffs.h_dot[1, 1]:.2f}")
 60
 61    # Visualization: Coefficient magnitudes by order
 62    fig = make_subplots(
 63        rows=2,
 64        cols=1,
 65        subplot_titles=("G Coefficients by Order", "H Coefficients by Order"),
 66        vertical_spacing=0.12,
 67    )
 68
 69    orders = np.arange(coeffs.n_max + 1)
 70    g_means = [np.mean(np.abs(coeffs.g[n, :])) for n in orders]
 71    h_means = [np.mean(np.abs(coeffs.h[n, :])) for n in orders]
 72
 73    fig.add_trace(
 74        go.Bar(x=orders, y=g_means, name="G coefficients", marker_color="steelblue"),
 75        row=1,
 76        col=1,
 77    )
 78    fig.add_trace(
 79        go.Bar(x=orders, y=h_means, name="H coefficients", marker_color="coral"),
 80        row=2,
 81        col=1,
 82    )
 83
 84    fig.update_xaxes(title_text="Order (n)", row=1, col=1)
 85    fig.update_xaxes(title_text="Order (n)", row=2, col=1)
 86    fig.update_yaxes(title_text="Mean |Coefficient| [nT]", row=1, col=1)
 87    fig.update_yaxes(title_text="Mean |Coefficient| [nT]", row=2, col=1)
 88    fig.update_layout(height=500, showlegend=True)
 89
 90    if SHOW_PLOTS:
 91        fig.show()
 92    else:
 93        fig.write_html(str(OUTPUT_DIR / "magnetism_demo.html"))
 94
 95
 96def demo_dipole_moment() -> None:
 97    """Demonstrate dipole moment calculation."""
 98    print("\n" + "=" * 60)
 99    print("Earth's Magnetic Dipole Moment")
100    print("=" * 60)
101
102    # Get WMM2020 coefficients
103    coeffs = create_wmm2020_coefficients()
104
105    # Calculate dipole moment
106    moment = dipole_moment(coeffs)
107    print(f"\nMagnetic dipole moment: {moment:.4e} A·m²")
108    print(f"Equivalent magnitude: {moment:.2e} Tesla·m³")
109
110    # Extract individual dipole components from coefficients
111    g10 = coeffs.g[1, 0]  # Axial dipole coefficient
112    g11 = coeffs.g[1, 1]  # Equatorial dipole component
113    h11 = coeffs.h[1, 1]  # Equatorial dipole component
114
115    print(f"\nDipole components:")
116    print(f"  g10 (axial): {g10:.2f} nT")
117    print(f"  g11: {g11:.2f} nT")
118    print(f"  h11: {h11:.2f} nT")
119
120    # Calculate dipole direction and magnitude
121    dipole_magnitude = np.sqrt(g10**2 + g11**2 + h11**2)
122    print(f"\nDipole magnitude from coefficients: {dipole_magnitude:.2f} nT")
123
124    # Visualization: Dipole strength over harmonic orders
125    fig = go.Figure()
126
127    orders = np.arange(1, coeffs.n_max + 1)
128    order_moments = []
129
130    for n in orders:
131        order_coeffs = np.sqrt(
132            np.sum(coeffs.g[n, :] ** 2) + np.sum(coeffs.h[n, :] ** 2)
133        )
134        order_moments.append(order_coeffs)
135
136    fig.add_trace(
137        go.Scatter(
138            x=orders,
139            y=order_moments,
140            mode="lines+markers",
141            name="Harmonic strength",
142            line=dict(color="darkblue", width=2),
143            marker=dict(size=8),
144        )
145    )
146
147    fig.update_layout(
148        title="Magnetic Field Harmonic Strength by Order",
149        xaxis_title="Harmonic Order (n)",
150        yaxis_title="RMS Strength [nT]",
151        height=400,
152        hovermode="x unified",
153    )
154
155    if SHOW_PLOTS:
156        fig.show()
157    else:
158        fig.write_html(str(OUTPUT_DIR / "magnetism_demo.html"))
159
160
161def demo_dipole_axis() -> None:
162    """Demonstrate dipole axis calculation."""
163    print("\n" + "=" * 60)
164    print("Magnetic Dipole Axis")
165    print("=" * 60)
166
167    # Get WMM2020 coefficients
168    coeffs = create_wmm2020_coefficients()
169
170    # Calculate dipole axis
171    dipole_axis_result = dipole_axis(coeffs)
172    print(f"\nDipole axis: {dipole_axis_result}")
173
174    # Calculate poles from coefficients
175    # Magnetic poles are where field lines are vertical
176    g10 = coeffs.g[1, 0]
177    g11 = coeffs.g[1, 1]
178    h11 = coeffs.h[1, 1]
179
180    # Calculate magnetic inclination (dip angle) at equator
181    # At magnetic equator, inclination = arctan(2 * g10 / sqrt(g11^2 + h11^2))
182    equatorial_dip = 2 * g10 / np.sqrt(g11**2 + h11**2)
183    inclination_deg = np.degrees(np.arctan(equatorial_dip))
184
185    print(f"\nDipole field properties:")
186    print(f"  Axial dipole ratio: {g10 / np.sqrt(g11**2 + h11**2):.4f}")
187    print(f"  Field inclination estimate: {inclination_deg:.2f}°")
188
189    # Visualization: Dipole offset from center
190    # Geographic pole vs Magnetic pole
191    fig = go.Figure()
192
193    # Add geographic pole
194    fig.add_trace(
195        go.Scattergeo(
196            lon=[0],
197            lat=[90],
198            mode="markers",
199            marker=dict(size=12, color="blue", symbol="star"),
200            name="Geographic North Pole",
201        )
202    )
203
204    # Add magnetic dipole approximation
205    # Magnetic declination and inclination affect pole position
206    mag_lat_offset = np.degrees(np.arctan2(h11, g11))
207    mag_lon_offset = np.degrees(np.arctan2(g11, g10))
208
209    fig.add_trace(
210        go.Scattergeo(
211            lon=[mag_lon_offset],
212            lat=[90 - np.degrees(np.arctan2(np.sqrt(g11**2 + h11**2), g10))],
213            mode="markers",
214            marker=dict(size=12, color="red", symbol="x"),
215            name="Magnetic Dipole Location",
216        )
217    )
218
219    fig.update_layout(
220        title="Magnetic Dipole Axis Orientation (Approximate)",
221        geo=dict(projection_type="orthographic"),
222        height=500,
223        showlegend=True,
224    )
225
226    if SHOW_PLOTS:
227        fig.show()
228    else:
229        fig.write_html(str(OUTPUT_DIR / "magnetism_demo.html"))
230
231
232def main() -> None:
233    """Run all demonstrations."""
234    print("\n" + "=" * 60)
235    print("Magnetism Module Demonstration")
236    print("=" * 60)
237
238    demo_wmm2020_coefficients()
239    demo_dipole_moment()
240    demo_dipole_axis()
241
242    print("\n" + "=" * 60)
243    print("Demonstration Complete")
244    print("=" * 60)
245
246
247OUTPUT_DIR = Path("docs/_static/images/examples")
248OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
249
250if __name__ == "__main__":
251    main()

Running the Example

python examples/magnetism_demo.py

See Also

  • Geophysical Models - Gravity and magnetic field models

  • ins_gnss_navigation - Navigation applications

  • coordinate_systems - Coordinate transformations