UNPKG

keplerian-core

Version:

High-performance TypeScript library for orbital mechanics calculations, providing numerical integration, state propagation, and perturbation modeling for Keplerian orbits.

84 lines (60 loc) 2.8 kB
import { OrbitalState, InitialConditions, SimulationParams } from './types/physics'; import { rk4Integrator } from './physics/integrators/rk4'; import { eulerIntegrator } from './physics/integrators/euler'; import { leapfrogIntegrator } from './physics/integrators/leapfrog'; import { rk2Integrator } from './physics/integrators/rk2'; import { velocityVerletIntegrator } from './physics/integrators/velocity-verlet'; import { exportToCSV } from './utils/export'; import { calculateNetForce } from './physics/forces'; import { Vector2D } from './types/physics'; import { calculateDerivedQuantities } from './utils/calculateDerivedQuantities'; export function simulate(initialConditions: InitialConditions, params: SimulationParams, format: 'json' | 'csv' = 'json'): OrbitalState[] | string { const states: OrbitalState[] = []; let currentState: OrbitalState = { position: initialConditions.position, velocity: initialConditions.velocity, momentum: { x: 0, y: 0 }, // Will be calculated by integrator angularMomentum: 0, // Will be calculated by integrator rungeLenzVector: { x: 0, y: 0 }, // Will be calculated by integrator energy: 0, // Will be calculated by integrator eccentricity: 0 // Will be calculated by integrator }; // Initialize derived quantities for the initial state // This is important for the first state in the array to have correct values const accelerationFunction = (position: Vector2D, velocity: Vector2D, params: SimulationParams): Vector2D => { const force = calculateNetForce(position, velocity, params); return { x: force.x / params.orbitingMass, y: force.y / params.orbitingMass }; }; const derivedQuantities = calculateDerivedQuantities(currentState.position, currentState.velocity, params); currentState = { ...currentState, ...derivedQuantities }; states.push(currentState); let integratorFunction; switch (params.integrator) { case 'rk4': integratorFunction = rk4Integrator.function; break; case 'euler': integratorFunction = eulerIntegrator.function; break; case 'leapfrog': integratorFunction = leapfrogIntegrator.function; break; case 'rk2': integratorFunction = rk2Integrator.function; break; case 'velocity-verlet': integratorFunction = velocityVerletIntegrator.function; break; default: throw new Error(`Unknown integrator: ${params.integrator}`); } const numSteps = Math.ceil(params.totalTime / params.timeStep); for (let i = 0; i < numSteps; i++) { currentState = integratorFunction(currentState, params, accelerationFunction, i * params.timeStep, params.timeStep); states.push(currentState); } if (format === 'csv') { return exportToCSV(states); } return states; }