TsyganenkoModels

DOI version

Modeling of Earth's Magnetosphere Using Spacecraft Magnetometer Data.

Features

  • Magnetic field model (native Julia implementations)
    • [x] T89: A magnetospheric magnetic field model with a warped tail current sheet
    • [x] T96: Effects of the solar wind conditions on the global magnetospheric configuration
    • [x] T01/T02: A model of the near magnetosphere with a dawn-dusk asymmetry
    • [x] TS05/TS04: a dynamical empirical model of the inner storm-time magnetosphere
IRBEM.jl

IRBEM.jl is a Julia wrapper for the IRBEM Fortran library that exposes magnetic field computation via GET_FIELD_MULTI and supports more Tsyganenko models, but may be outdated and slower than the native Julia implementations.

Installation

using Pkg
Pkg.add("TsyganenkoModels")

Quickstart

The model interface allows you to configure a model once and use it for multiple field calculations:

using TsyganenkoModels
using Dates

# Create model configurations
model_t89 = T89(2)  # Kp level 2
param = (; pdyn=2.0, dst=-87.0, byimf=2.0, bzimf=-5.0)
# pdyn: Solar wind dynamic pressure [nPa]
# dst: Dst index [nT]
# byimf: IMF By [nT]
# bzimf: IMF Bz [nT]

# Calculate fields at position
t = DateTime("1970-01-01T00:01:40")
𝐫 = [1, 2, 3]
ps = -0.533585131  # dipole tilt angle [radians]

# Using dipole tilt angle
B_t89 = T89(2)(𝐫, ps)
3-element GeoCotrans.CoordinateVector{GSM, SpaceDataModel.Cartesian3, Float64, Nothing} with indices SOneTo(3):
   5.367416991592773
  -3.448905444772822
 -17.29126736398316
julia> # Compare with other models
       B_t96 = T96(param)(𝐫, ps)3-element GeoCotrans.CoordinateVector{GSM, SpaceDataModel.Cartesian3, Float64, Nothing} with indices SOneTo(3):
  39.34888430483087
  -9.327382852686146
 -90.39880058123812
julia> B_t01 = T01(param)(𝐫, ps)3-element GeoCotrans.CoordinateVector{GSM, SpaceDataModel.Cartesian3, Float64, Nothing} with indices SOneTo(3): 25.017949957632542 -4.606333301128644 -66.82317110266318
julia> B_ts04 = TS04(param)(𝐫, ps)3-element GeoCotrans.CoordinateVector{GSM, SpaceDataModel.Cartesian3, Float64, Nothing} with indices SOneTo(3): 13.497153413146576 -0.13916234543149042 -24.928503548859755
julia> # Using time (auto-calculates dipole tilt) T89(3)(𝐫, t)3-element GeoCotrans.CoordinateVector{GSM, SpaceDataModel.Cartesian3, Float64, Nothing} with indices SOneTo(3): 7.173912838767684 -3.7801244076510705 -19.9277123686887
julia> # Using `TsyIGRF` to combine IGRF14 model and one Tsyganenko model (default T89) TsyIGRF()(𝐫, t)3-element GeoCotrans.CoordinateVector{GSM, SpaceDataModel.Cartesian3, Float64, Nothing} with indices SOneTo(3): -541.7175541221735 -576.5916824422504 -339.77872971738
julia> # This is equivalent to IGRF()(GSM(𝐫), t) .+ T89(3)(𝐫, t)3-element GeoCotrans.CoordinateVector{GSM, SpaceDataModel.Cartesian3, Float64, Nothing} with indices SOneTo(3): -541.7175541221735 -576.5916824422504 -339.77872971738

Comparison with geopack

using TsyganenkoModels
using GeoCotrans
using Test
using Geopack
using Dates

t = DateTime("1970-01-01T00:01:40")
𝐫 = [1, 2, 3]

# using geopack
xgsm, ygsm, zgsm = 𝐫
opt = 2
ut = datetime2unix(t)
ps = Geopack.recalc(ut)
db_py = Geopack.t89(opt, ps, xgsm, ygsm, zgsm)

# using TsyganenkoModels
db_jl = T89(opt)(𝐫, ps)

@test db_py ≈ db_jl
Test Passed

Model Result Comparison

# T01 model comparison
pdyn = 2.0   # Solar wind dynamic pressure [nPa]
dst = -87.0  # Dst index [nT]
byimf = 2.0  # IMF By [nT]
bzimf = -5.0 # IMF Bz [nT]
g1 = 0.0
g2 = 0.0
parmod = [pdyn, dst, byimf, bzimf, g1, g2]

db_t96_py = Geopack.t96(parmod, ps, xgsm, ygsm, zgsm)
db_t96_jl = T96(; pdyn, dst, byimf, bzimf)(𝐫, ps)
@test db_t96_jl ≈ db_t96_py rtol = 1e-6

db_t01_py = Geopack.t01(parmod, ps, xgsm, ygsm, zgsm)
db_t01_jl = T01(; pdyn, dst, byimf, bzimf)(𝐫, ps)

@test db_t01_jl ≈ db_t01_py rtol = 1e-6
Test Passed

The internal magnetic field could be computed using igrf from GeoCotrans.

Here we verify the result with igrf_gsm from Geopack.

julia> using GeoCotrans
julia> b0_py = Geopack.igrf_gsm(xgsm, ygsm, zgsm)3-element StaticArraysCore.SVector{3, Float64} with indices SOneTo(3): -548.892407931754 -572.8105422196072 -319.8493868519125
julia> b0_jl = GeoCotrans.igrf(GSM(𝐫), t)3-element GeoCotrans.CoordinateVector{GSM, SpaceDataModel.Cartesian3, Float64, Dates.DateTime} with indices SOneTo(3): -548.8914669609412 -572.8115580345993 -319.8510173486913
julia> @test b0_jl ≈ b0_py rtol = 1e-5Test Passed
julia> @test GeoCotrans.get_igrf_coeffs(t)[1] ≈ Geopack.load_igrf(ut)[1]Test Passed

Performance Benchmarks

julia> using Chairmarks
julia> @b TsyganenkoModels.T89(2)($𝐫, $ps), Geopack.t89(2, $ps, $𝐫...)(180.000 ns, 51.275 μs (25 allocs: 624 bytes))
julia> @b TsyganenkoModels.T96($pdyn, $dst, $byimf, $bzimf)($𝐫, $ps), Geopack.t96([$pdyn, $dst, $byimf, $bzimf, 0, 0], $ps, $𝐫...)(6.342 μs, 1.193 ms (101 allocs: 2.812 KiB))
julia> @b TsyganenkoModels.T01(; pdyn, dst, byimf, bzimf)($𝐫, $ps), Geopack.t01([pdyn, dst, byimf, bzimf, 0, 0], $ps, $𝐫...)(17.964 μs (5 allocs: 208 bytes), 2.481 ms (148 allocs: 4.078 KiB))
julia> @b GeoCotrans.igrf(GSM($𝐫), t), Geopack.igrf_gsm($𝐫...)(2.795 μs (2 allocs: 80 bytes), 133.779 μs (11 allocs: 192 bytes))

API

TsyganenkoModels.T01Type
T01(; pdyn, dst, byimf, bzimf, g1=0.0, g2=0.0)

Tsyganenko 01 model with solar wind parameters.

Parameters

  • pdyn: Solar wind dynamic pressure [nPa]
  • dst: Dst index [nT]
  • byimf: IMF By component [nT]
  • bzimf: IMF Bz component [nT]
  • g1: G1 index (default: 0.0)
  • g2: G2 index (default: 0.0)

Usage

model = T01(pdyn=2.0, dst=-87.0, byimf=2.0, bzimf=-5.0)
B = model([1, 2, 3], ps)  # Compute field at position

Model Description

Data-based model of the external magnetospheric magnetic field, calibrated by:

  1. Solar wind pressure PDYN (nanopascals)
  2. Dst (nanotesla)
  3. IMF By and Bz (nanotesla)
  4. G1 and G2 indices

ATTENTION: The model is based on data taken sunward from X=-15 Re, and hence becomes invalid at larger tailward distances.

References

  • Tsyganenko, N.A., JGR, 2002
source
TsyganenkoModels.T89Type
T89(iopt::Integer)

Tsyganenko 89 model with Kp-dependent parameters.

Parameters

  • iopt: Ground disturbance level index (1-7)
    • 1: Kp = 0, 0+
    • 2: Kp = 1-, 1, 1+
    • 3: Kp = 2-, 2, 2+
    • 4: Kp = 3-, 3, 3+
    • 5: Kp = 4-, 4, 4+
    • 6: Kp = 5-, 5, 5+
    • 7: Kp ≥ 6-

Model Description

Valid up to geocentric distances of 70 RE. Based on merged IMP-A through J (1966-1974), HEOS-1 and -2 (1969-1974), and ISEE-1 and -2 spacecraft data.

Usage

model = T89(2)  # Kp level 2
B = model([1, 2, 3], ps)  # Compute field at position

References

  • Tsyganenko, N.A., "A magnetospheric magnetic field model with a warped tail current sheet", Planet. Space Sci., 37, 5-20, 1989.
  • Fortran implementation
source
TsyganenkoModels.T96Type
T96(; pdyn, dst, byimf, bzimf)

Tsyganenko 96 model with solar wind parameters.

Parameters

  • pdyn: Solar wind dynamic pressure [nPa]
  • dst: Dst index [nT]
  • byimf: IMF By component [nT]
  • bzimf: IMF Bz component [nT]

Usage

model = T96(pdyn=2.0, dst=-87.0, byimf=2.0, bzimf=-5.0)
B = model([1, 2, 3], ps)  # Compute field at position

Model Description

Data-based model calibrated by solar wind pressure, Dst index, and IMF By/Bz components. Includes realistic magnetopause, Region 1 and 2 Birkeland current systems, and IMF penetration.

Valid parameter ranges (caution needed outside these ranges):

  • Pdyn: 0.5 to 10 nPa
  • Dst: -100 to +20 nT
  • ByIMF and BzIMF: -10 to +10 nT

References

  • Tsyganenko & Stern, JGR, v.101, p.27187-27198, 1996
  • Tsyganenko, JGR, v.100, p.5599-5612, 1995
source
TsyganenkoModels.TS04Type
TS04(; pdyn, dst, byimf, bzimf, w1=0.0, w2=0.0, w3=0.0, w4=0.0, w5=0.0, w6=0.0)

Tsyganenko-Sitnov 04 model with solar wind parameters and W indices.

Parameters

  • pdyn: Solar wind dynamic pressure [nPa]
  • dst: Dst index [nT]
  • byimf: IMF By component [nT]
  • bzimf: IMF Bz component [nT]
  • w1-w6: Time integrals of the driving variables (time integrals from the beginning of a storm, see reference for definitions)

Usage

model = TS04(pdyn=2.0, dst=-87.0, byimf=2.0, bzimf=-5.0, w1=0.5)
B = model([1, 2, 3], ps)  # Compute field at position

References

source
TsyganenkoModels.TsyIGRFType
TsyIGRF(model = T89(iopt=3); name=nothing)

Create a composite Earth magnetic field model combining internal IGRF and external Tsyganenko field model.

Example

model = TsyIGRF(T89(iopt=3))

# Evaluate at position (in Earth radii, spherical coordinates)
r, θ, φ = 6.6, π/2, 0.0  # 6.6 RE at equator
t = Date(2020, 6, 21)    # Summer solstice 2020
B = model(r, θ, φ, t)    # Returns B in spherical coordinates (Br, Bθ, Bφ) in nT
source
TsyganenkoModels.TsyganenkoModelType
(m::TsyganenkoModel)(x, y, z, ps, args...; kw...) -> (Bx, By, Bz)

Compute GSM components of the external magnetic field [nT] using Tsyganenko model m, given position in GSM coordinates (x, y, z) [Earth radii] and geodipole tilt angle [radians] ps.

source
TsyganenkoModels.t01Function
t01(x, y, z, ps, pdyn, dst, byimf, bzimf, g1 = 0.0, g2 = 0.0) -> (Bx, By, Bz)

Compute GSM components of the external magnetic field using the Tsyganenko 01 model.

source
TsyganenkoModels.t89Method
t89(𝐫, ps, iopt; cache=nothing) -> GSM(Bx, By, Bz)
t89(x, y, z, ps, iopt)
t89(x, y, z, t::AbstractTime, iopt)

Compute GSM components of the magnetic field [nT] produced by extraterrestrial current systems in the geomagnetosphere using the Tsyganenko 89 model, given the position 𝐫 or x, y, z in GSM coordinates [Earth radii], the geodipole tilt angle ps [radians] / time t.

source
TsyganenkoModels.t96Method
t96(x, y, z, ps, pdyn, dst, byimf, bzimf) -> (Bx, By, Bz)

Compute GSM components of the external magnetic field using the Tsyganenko 96 model.

source