import { describe, expect, it } from "vitest"; import { EARTH, initialState, propagate, type PropagationRequest } from "./propagator"; const request = (): PropagationRequest => ({ altitudeKm: 500, eccentricity: 0, inclinationDeg: 51.6, raanDeg: 0, argumentOfPeriapsisDeg: 0, trueAnomalyDeg: 0, durationSeconds: 5_600, sampleCount: 121, massKg: 1_000, areaM2: 10, dragCoefficient: 2.2, reflectivityCoefficient: 1.2, forces: { gravity: true, j2: false, drag: false, moon: false, sun: false, solarRadiationPressure: false }, }); function specificEnergy(state: readonly number[]): number { const radius = Math.hypot(state[0]!, state[1]!, state[2]!); const speed = Math.hypot(state[3]!, state[4]!, state[5]!); return speed ** 2 / 2 - EARTH.mu / radius; } describe("custom propagation", () => { it("creates the expected circular LEO state", () => { const state = initialState(request()); expect(Math.hypot(state[0], state[1], state[2]) - EARTH.radius).toBeCloseTo(500_000, -1); expect(Math.hypot(state[3], state[4], state[5])).toBeGreaterThan(7_500); }); it("keeps two-body specific energy bounded through one orbit", () => { const samples = propagate(request()); const energies = samples.map(({ state }) => specificEnergy(state)); expect(Math.max(...energies) - Math.min(...energies)).toBeLessThan(25); }); it("accepts third-body, drag, and radiation-pressure force configurations", () => { const samples = propagate({ ...request(), durationSeconds: 600, sampleCount: 31, forces: { gravity: true, j2: true, drag: true, moon: true, sun: true, solarRadiationPressure: true } }); expect(samples).toHaveLength(31); expect(samples.at(-1)?.elapsedSeconds).toBeCloseTo(600); }); });