Skip to content

Unify propagator force model; cap gravity coefficient table#114

Merged
ssmichael1 merged 2 commits into
mainfrom
force-model-unification-gravity-cap
Jun 3, 2026
Merged

Unify propagator force model; cap gravity coefficient table#114
ssmichael1 merged 2 commits into
mainfrom
force-model-unification-gravity-cap

Conversation

@ssmichael1

Copy link
Copy Markdown
Owner

Summary

Two internal refactor/perf changes to the high-precision propagator and Earth-gravity model. No behavior change — end states are bit-identical and the full Rust test suite (including the ESA SP3 GPS regression) passes unchanged.

1. Force model unified across all integrators

The RKV ydot, RODAS4 ydot_vec/jac_fn, and Gauss-Jackson accel_fn each carried a near-identical copy of the acceleration physics (gravity, Sun/Moon, solid tides, GR, SRP, drag, thrust) — ~200 lines duplicated four ways, where adding a force term meant editing every copy in lockstep.

  • A single force_model() now holds the physics; each integrator closure is a thin adapter over its own state layout (Matrix<6, C> / Vector<f64, 6> / (r, v)).
  • A ForceEval mode selector (Accel / AccelAndPartials / PartialsOnly) preserves each integrator's cost. Every call site passes a compile-time-constant mode and force_model is #[inline], so the branches constant-fold away — no extra call, no runtime dispatch. The RODAS4 Jacobian path skips the tide/GR/SRP/thrust terms (no partials), so it does not regress.
  • Drag altitude gate uses norm_squared() against a precomputed squared limit instead of norm(), dropping a sqrt from every force eval.

2. Earth gravity: coefficient table capped at the evaluation degree

The evaluator dispatches at degree ≤ 40 (divisor tables are 44×44), so higher coefficients were never used — yet the default EGM96 model (file degree 360) stored a 361×361 DMatrix (~1 MB).

  • Gravity::parse now caps the stored table at degree 44 (MAX_COEFF_DIM). Drops EGM96 to ~15 KB and shrinks the column stride 361 → 44, keeping the strided S-coefficient reads coeffs[(m-1, n)] resident in L1.
  • Coefficients for n,m ≤ 43 are untouched → bit-identical results. Microbenchmark shows ~5–15% faster accel/accel_and_partials on EGM96 and removes the cache-miss timing variance in the hot loop.

Test plan

  • cargo test full suite with SATKIT_DATA + test vectors — zero failures
  • earthgravity unit tests 10/10
  • Force-model results verified bit-identical (benchmark sink values matched across the change)
  • cargo fmt --all clean
  • Python suite not run (needs pip install -e . rebuild)

🤖 Generated with Claude Code

ssmichael1 and others added 2 commits May 30, 2026 19:30
Collapse the four near-identical force closures (RKV ydot, RODAS4
ydot_vec/jac_fn, Gauss-Jackson accel_fn) into a single inlined
force_model() with a ForceEval mode selector. Each integrator closure
is now a thin adapter over its own state layout. Because every call
site passes a compile-time-constant mode, the partials/accel branches
constant-fold away, reproducing the prior per-integrator specialization
with no extra call or runtime dispatch. End states are bit-identical.

Also gate atmospheric drag on norm_squared() against a precomputed
squared limit instead of norm(), dropping a sqrt from every force eval.

Cap the stored Earth-gravity coefficient table at degree 44
(MAX_COEFF_DIM) instead of the file's full resolution. The evaluator
dispatches at degree <= 40 and the divisor tables are 44x44, so higher
coefficients were never used; EGM96 (file degree 360) was holding a
~1 MB 361x361 DMatrix. Capping drops it to ~15 KB and shrinks the
column stride 361 -> 44, keeping the strided S-coefficient reads in L1.
Coefficients for n,m <= 43 are untouched, so results are bit-identical;
~5-15% faster accel/accel_and_partials on EGM96 plus removal of
cache-miss timing variance.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ssmichael1 ssmichael1 merged commit 67f7240 into main Jun 3, 2026
10 checks passed
@ssmichael1 ssmichael1 deleted the force-model-unification-gravity-cap branch June 3, 2026 00:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant