Vulcan
Aerospace Engineering Utilities Built on Janus
Loading...
Searching...
No Matches
MagneticField.hpp
Go to the documentation of this file.
1// Earth Magnetic Field Models
2// Centered dipole model for geomagnetic field
3#pragma once
4
5#include <janus/janus.hpp>
8
10
11namespace constants {
13inline constexpr double B0 = 3.12e-5;
14
16inline constexpr double dipole_tilt = 11.5 * vulcan::constants::angle::deg2rad;
17
19inline constexpr double pole_longitude =
21} // namespace constants
22
38template <typename Scalar>
39Vec3<Scalar> dipole_field_ecef(const Vec3<Scalar> &r_ecef,
40 double B0 = constants::B0,
42 const Scalar x = r_ecef(0);
43 const Scalar y = r_ecef(1);
44 const Scalar z = r_ecef(2);
45
46 const Scalar r2 = x * x + y * y + z * z;
47 const Scalar r = janus::sqrt(r2);
48 const Scalar r5 = r2 * r2 * r;
49
50 // Dipole field coefficient: B0 * R³ / r⁵
51 const Scalar coeff = B0 * (R * R * R) / r5;
52
53 // For centered dipole aligned with Z-axis:
54 // B_x = 3 * coeff * x * z
55 // B_y = 3 * coeff * y * z
56 // B_z = coeff * (2z² - x² - y²)
57 Vec3<Scalar> B;
58 B(0) = 3.0 * coeff * x * z;
59 B(1) = 3.0 * coeff * y * z;
60 B(2) = coeff * (2.0 * z * z - x * x - y * y);
61
62 return B;
63}
64
70template <typename Scalar>
71Scalar field_magnitude(const Vec3<Scalar> &r_ecef, double B0 = constants::B0,
73 const Vec3<Scalar> B = dipole_field_ecef(r_ecef, B0, R);
74 return janus::norm(B);
75}
76
87template <typename Scalar>
88Vec3<Scalar> field_ned(const Scalar &lat, [[maybe_unused]] const Scalar &lon,
89 const Scalar &alt, double B0 = constants::B0,
91 // Spherical approximation: r = R + alt
92 const Scalar r = R + alt;
93
94 // Use geocentric latitude (spherical approx)
95 const Scalar phi = lat;
96
97 // Radial component: B_r = -2 * B0 * (R/r)³ * sin(φ)
98 // Theta component: B_θ = B0 * (R/r)³ * cos(φ)
99 const Scalar R_over_r_cubed = (R * R * R) / (r * r * r);
100
101 const Scalar sin_phi = janus::sin(phi);
102 const Scalar cos_phi = janus::cos(phi);
103
104 const Scalar B_r = -2.0 * B0 * R_over_r_cubed * sin_phi;
105 const Scalar B_theta = B0 * R_over_r_cubed * cos_phi;
106
107 // Convert to NED:
108 // North = -B_θ (θ increases southward)
109 // East = 0 (axial symmetry for centered dipole)
110 // Down = -B_r (down is negative radial)
111 Vec3<Scalar> B_ned;
112 B_ned(0) = -B_theta; // North
113 B_ned(1) = Scalar(0.0); // East
114 B_ned(2) = -B_r; // Down
115
116 return B_ned;
117}
118
127template <typename Scalar>
128Scalar surface_intensity(const Scalar &lat, double B0 = constants::B0) {
129 const Scalar sin_lat = janus::sin(lat);
130 return B0 * janus::sqrt(1.0 + 3.0 * sin_lat * sin_lat);
131}
132
141template <typename Scalar> Scalar inclination(const Scalar &lat) {
142 const Scalar tan_lat = janus::tan(lat);
143 return janus::atan(2.0 * tan_lat);
144}
145
146} // namespace vulcan::environment::magnetic
constexpr double deg2rad
Degrees to radians conversion factor.
Definition Constants.hpp:156
constexpr double R_eq
Equatorial radius [m] (WGS84).
Definition Constants.hpp:16
Definition MagneticField.hpp:11
constexpr double pole_longitude
Magnetic pole longitude (West is negative) [rad].
Definition MagneticField.hpp:19
constexpr double B0
Reference magnetic field at equator surface [T] (~31.2 μT).
Definition MagneticField.hpp:13
constexpr double dipole_tilt
Magnetic dipole tilt angle from rotation axis [rad] (~11.5°).
Definition MagneticField.hpp:16
Definition MagneticField.hpp:9
Scalar field_magnitude(const Vec3< Scalar > &r_ecef, double B0=constants::B0, double R=vulcan::constants::earth::R_eq)
Magnetic field magnitude at given position.
Definition MagneticField.hpp:71
Scalar inclination(const Scalar &lat)
Magnetic inclination (dip angle) at given latitude.
Definition MagneticField.hpp:141
Vec3< Scalar > dipole_field_ecef(const Vec3< Scalar > &r_ecef, double B0=constants::B0, double R=vulcan::constants::earth::R_eq)
Centered dipole magnetic field in ECEF.
Definition MagneticField.hpp:39
Vec3< Scalar > field_ned(const Scalar &lat, const Scalar &lon, const Scalar &alt, double B0=constants::B0, double R=vulcan::constants::earth::R_eq)
Magnetic field in local NED frame at geodetic coordinates.
Definition MagneticField.hpp:88
Scalar surface_intensity(const Scalar &lat, double B0=constants::B0)
Total field intensity at surface for given latitude.
Definition MagneticField.hpp:128