AstroForceModels.jl
Julia package for modeling astrodynamics perturbation forces. Repo: HAMMERHEAD-Space/AstroForceModels.jl
Architecture
Type Hierarchy
AbstractAstroForceModel
├── AbstractPotentialBasedForce
│ └── AbstractGravityAstroModel
│ ├── GravityHarmonicsAstroModel # Spherical harmonics (EGM96 etc.)
│ └── KeplerianGravityAstroModel # Two-body point mass
└── AbstractNonPotentialBasedForce
├── DragAstroModel # Atmospheric drag
├── SRPAstroModel # Solar radiation pressure
├── ThirdBodyModel # Sun, Moon, planets
└── RelativityModel # GR corrections
AbstractDynamicsModel
└── CentralBodyDynamicsModel{N,GT,PT} # Gravity + N perturbations
Source Layout
src/
AstroForceModels.jl # Module entry, abstract types, exports
constants.jl # Physical constants (R_EARTH, μ_SUN, etc.)
utils.jl # angle_between_vectors()
dynamics_builder.jl # CentralBodyDynamicsModel, build_dynamics_model
force_models/
drag/ # satellite_shape_model.jl, density_calculator.jl, drag_accel.jl
gravity/ # utils.jl, gravity_accel.jl
relativity/ # relativity_accel.jl
solar_radiation_pressure/ # satellite_shape_model.jl, shadow_models.jl, srp_accel.jl
third_body/ # celestial_body.jl, third_body_model.jl, third_body_accel.jl
Key Patterns
Unified Acceleration Interface
Every force model implements the same 4-argument signature:
@inline function acceleration(
u::AbstractVector, p::ComponentVector, t::Number, model::SomeForceModel
)::SVector{3}
# ... compute and return acceleration in km/s^2 ...
end
Gravity models additionally implement:
potential(u, p, t, model) -> Number
potential_time_derivative(u, p, t, model) -> Number
Force Composition
grav = GravityHarmonicsAstroModel(; gravity_model=..., eop_data=..., order=36, degree=36)
sun = ThirdBodyModel(; body=SunBody(), eop_data=eop_data)
moon = ThirdBodyModel(; body=MoonBody(), eop_data=eop_data)
srp = SRPAstroModel(; satellite_srp_model=CannonballFixedSRP(0.2), ...)
drag = DragAstroModel(; satellite_drag_model=CannonballFixedDrag(0.2), ...)
model = CentralBodyDynamicsModel(grav, (sun, moon, srp, drag))
accel = build_dynamics_model(u, p, t, model) # Returns SVector{3}
sum_accelerations uses compile-time tuple recursion (first/Base.tail) for zero-overhead force summation.
Satellite Shape Models
- Drag:
CannonballFixedDrag(area_mass_ratio), StateDragModel(f)
- SRP:
CannonballFixedSRP(area_mass_ratio), StateSRPModel(f)
- Shadow:
Conical(), Cylindrical(), No_Shadow()
Atmospheric Density
compute_density() dispatches on atmosphere model type: JB2008, JR1971, MSIS2000, ExpAtmo, NoDensityModel.
Units Convention
- Input/output: km, km/s, km/s^2 (J2000 ECI)
- Internal SatelliteToolbox calls: convert to/from meters (
* 1E3, / 1E3)
Adding a New Force Model
- Create struct
<: AbstractNonPotentialBasedForce (or AbstractPotentialBasedForce)
- Implement
acceleration(u, p, t, model) returning SVector{3}
- Use
@inline, return SVector{3}, use promote_type for AD
- Add to
CentralBodyDynamicsModel perturbation tuple
- Tests: correctness against reference, AD with all 5 backends,
@check_allocs
Dependencies
ComponentArrays 0.15, Parameters 0.12, StaticArraysCore 1.4
- SatelliteToolbox: atmospheric, gravity, celestial bodies, transformations
SpaceIndices 2 for space weather data
1---2name: astroforcemodels-jl3description: Develop and maintain AstroForceModels.jl, a Julia library for astrodynamics force modeling (gravity, drag, SRP, third-body, relativity). Use when working on AstroForceModels.jl, adding new force models, or computing orbital perturbation accelerations.4---5
6# AstroForceModels.jl
7
8Julia package for modeling astrodynamics perturbation forces. Repo: [HAMMERHEAD-Space/AstroForceModels.jl](https://github.com/HAMMERHEAD-Space/AstroForceModels.jl)
9
10## Architecture
11
12### Type Hierarchy
13```
14AbstractAstroForceModel
15├── AbstractPotentialBasedForce
16│ └── AbstractGravityAstroModel
17│ ├── GravityHarmonicsAstroModel # Spherical harmonics (EGM96 etc.)
18│ └── KeplerianGravityAstroModel # Two-body point mass
19└── AbstractNonPotentialBasedForce
20 ├── DragAstroModel # Atmospheric drag
21 ├── SRPAstroModel # Solar radiation pressure
22 ├── ThirdBodyModel # Sun, Moon, planets
23 └── RelativityModel # GR corrections
24
25AbstractDynamicsModel
26└── CentralBodyDynamicsModel{N,GT,PT} # Gravity + N perturbations
27```
28
29### Source Layout
30```
31src/
32 AstroForceModels.jl # Module entry, abstract types, exports
33 constants.jl # Physical constants (R_EARTH, μ_SUN, etc.)
34 utils.jl # angle_between_vectors()
35 dynamics_builder.jl # CentralBodyDynamicsModel, build_dynamics_model
36 force_models/
37 drag/ # satellite_shape_model.jl, density_calculator.jl, drag_accel.jl
38 gravity/ # utils.jl, gravity_accel.jl
39 relativity/ # relativity_accel.jl
40 solar_radiation_pressure/ # satellite_shape_model.jl, shadow_models.jl, srp_accel.jl
41 third_body/ # celestial_body.jl, third_body_model.jl, third_body_accel.jl
42```
43
44## Key Patterns
45
46### Unified Acceleration Interface
47Every force model implements the same 4-argument signature:
48
49```julia
50@inline function acceleration(
51 u::AbstractVector, p::ComponentVector, t::Number, model::SomeForceModel
52)::SVector{3}
53 # ... compute and return acceleration in km/s^2 ...
54end
55```
56
57Gravity models additionally implement:
58- `potential(u, p, t, model) -> Number`
59- `potential_time_derivative(u, p, t, model) -> Number`
60
61### Force Composition
62```julia
63grav = GravityHarmonicsAstroModel(; gravity_model=..., eop_data=..., order=36, degree=36)
64sun = ThirdBodyModel(; body=SunBody(), eop_data=eop_data)
65moon = ThirdBodyModel(; body=MoonBody(), eop_data=eop_data)
66srp = SRPAstroModel(; satellite_srp_model=CannonballFixedSRP(0.2), ...)
67drag = DragAstroModel(; satellite_drag_model=CannonballFixedDrag(0.2), ...)
68
69model = CentralBodyDynamicsModel(grav, (sun, moon, srp, drag))
70accel = build_dynamics_model(u, p, t, model) # Returns SVector{3}
71```
72
73`sum_accelerations` uses compile-time tuple recursion (`first`/`Base.tail`) for zero-overhead force summation.
74
75### Satellite Shape Models
76- **Drag**: `CannonballFixedDrag(area_mass_ratio)`, `StateDragModel(f)`
77- **SRP**: `CannonballFixedSRP(area_mass_ratio)`, `StateSRPModel(f)`
78- **Shadow**: `Conical()`, `Cylindrical()`, `No_Shadow()`
79
80### Atmospheric Density
81`compute_density()` dispatches on atmosphere model type: `JB2008`, `JR1971`, `MSIS2000`, `ExpAtmo`, `NoDensityModel`.
82
83### Units Convention
84- Input/output: km, km/s, km/s^2 (J2000 ECI)
85- Internal SatelliteToolbox calls: convert to/from meters (`* 1E3`, `/ 1E3`)
86
87## Adding a New Force Model
88
891. Create struct `<: AbstractNonPotentialBasedForce` (or `AbstractPotentialBasedForce`)
902. Implement `acceleration(u, p, t, model)` returning `SVector{3}`
913. Use `@inline`, return `SVector{3}`, use `promote_type` for AD
924. Add to `CentralBodyDynamicsModel` perturbation tuple
935. Tests: correctness against reference, AD with all 5 backends, `@check_allocs`
94
95## Dependencies
96- `ComponentArrays` 0.15, `Parameters` 0.12, `StaticArraysCore` 1.4
97- SatelliteToolbox: atmospheric, gravity, celestial bodies, transformations
98- `SpaceIndices` 2 for space weather data