progenax.analytical¶
Auto-generated by scripts/build_api_reference.py from progenax source. Re-run after public-API changes; the script is idempotent.
Module path: progenax/analytical/
Public symbols: 15
Contents¶
analytical.AnalyticalIC¶
class
AnalyticalIC(positions: "Float[Array, 'N 3']", velocities: "Float[Array, 'N 3']", masses: "Float[Array, 'N']", name: 'str' = '', period: 'Optional[float]' = None, energy: 'Optional[float]' = None) -> NoneResult from analytical IC generation (immutable Equinox module / PyTree).
Attributes
| Parameter | Description |
|---|---|
positions | Particle positions (N, 3) |
velocities | Particle velocities (N, 3) |
masses | Particle masses (N,) |
name | System name (e.g., “two_body_kepler”, “figure_eight”) |
period | Orbital period (if applicable) |
energy | Analytical total energy (if applicable) |
Source: src/progenax/analytical/base.py#L11
analytical.SOLAR_SYSTEM_PLANETS¶
value
Built-in mutable sequence.
If no argument is given, the constructor creates a new empty list. The argument must be an iterable if specified.
analytical.get_planet¶
function
get_planet(name: 'str') -> 'dict'Get orbital elements for a Solar System planet.
Args
| Parameter | Description |
|---|---|
name | Planet name (case-insensitive) |
Valid | Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune |
Returns: dict with keys: - name: Planet name (str) - M: Mass in solar masses (float) - a: Semi-major axis in AU (float) - e: Eccentricity (float) - inc: Inclination in degrees (float) - Omega: Longitude of ascending node in degrees (float) - omega: Argument of perihelion in degrees (float) - nu: True anomaly in degrees (float)
Raises: ValueError: If planet name not recognized
Example. >>> jupiter = get_planet(“Jupiter”)
print(f"Mass: {jupiter[‘M’]:.4e} Msun, a: {jupiter[‘a’]:.2f} AU") Mass: 9.5479e-04 Msun, a: 5.20 AU
Source: src/progenax/analytical/base.py#L131
analytical.two_body_kepler¶
function
two_body_kepler(M1: 'float', M2: 'float', a: 'float', G: 'float', e: 'float' = 0.0, inclination: 'float' = 0.0, Omega: 'float' = 0.0, omega: 'float' = 0.0, true_anomaly: 'float' = 0.0) -> 'AnalyticalIC'Create 2-body Keplerian orbit with analytical solution.
Orbital Elements: - a: Semi-major axis (length units) - e: Eccentricity (0 = circular, 0 < e < 1 = ellipse) - inclination: Orbital tilt [radians] (0 = x-y plane) - Omega: Longitude of ascending node [radians] - omega: Argument of periapsis [radians] - true_anomaly: Initial position angle [radians]
Args
| Parameter | Description |
|---|---|
M1 | Primary mass [Msun] |
M2 | Secondary mass [Msun] |
a | Semi-major axis [length units] |
G | Gravitational constant [appropriate units] |
e | Eccentricity (default: 0.0, circular) |
inclination | Orbital inclination [radians] (default: 0, planar) |
Omega | Longitude of ascending node [radians] (default: 0) |
omega | Argument of periapsis [radians] (default: 0) |
true_anomaly | Initial true anomaly [radians] (default: 0) |
Returns: AnalyticalIC with 2 particles in Keplerian orbit Analytical solution: - Period: T = 2π√(a³/(G(M1+M2))) - Total energy: E = -G M1 M2 / (2a) - Total angular momentum: L = μ√(G M_tot a (1-e²)) - Conservation: ΔE/E and ΔL/L should be < machine precision
Example. >>> G = 39.478 # Binary units (AU³/Msun/yr²)
ic = two_body_kepler(M1=1.0, M2=0.001, a=1.0, e=0.0, G=G)
Period = 1.0 yr (by construction)¶
Notes. - e=0 (circular) is best for initial validation
Reduced mass μ = M1*M2/(M1+M2)
Center of mass at origin (p_total = 0)
References. - Murray & Dermott (1999), “Solar System Dynamics”, Ch. 2
Hairer et al. (2006), “Geometric Numerical Integration”, §I.2.4
Source: src/progenax/analytical/two_body.py#L15
analytical.two_body_period¶
function
two_body_period(M1: 'ArrayLike', M2: 'ArrayLike', a: 'ArrayLike', G: 'ArrayLike') -> "Float[Array, '']"Compute orbital period for 2-body system (Kepler’s 3rd law).
Args
| Parameter | Description |
|---|---|
M1 | Primary mass [Msun] |
M2 | Secondary mass [Msun] |
a | Semi-major axis [length units] |
G | Gravitational constant [appropriate units] |
Returns: Orbital period [time units]
Example. >>> G = 39.478 # Binary units
T = two_body_period(M1=1.0, M2=0.001, a=1.0, G=G)
T = 1.0 yr (Earth orbit)¶
Source: src/progenax/analytical/two_body.py#L157
analytical.two_body_energy¶
function
two_body_energy(M1: 'float', M2: 'float', a: 'float', G: 'float') -> 'float'Compute total energy for 2-body Keplerian orbit.
Args
| Parameter | Description |
|---|---|
M1 | Primary mass [Msun] |
M2 | Secondary mass [Msun] |
a | Semi-major axis [length units] |
G | Gravitational constant [appropriate units] |
Returns: Total energy (negative for bound orbit)
Notes. E = -G M1 M2 / (2a) Independent of eccentricity!
Source: src/progenax/analytical/two_body.py#L181
analytical.three_body_figure_eight¶
function
three_body_figure_eight(mass: 'float' = 1.0, scale: 'float' = 1.0, G: 'float' = 1.0) -> 'AnalyticalIC'Create three-body figure-8 periodic orbit.
This is a famous periodic solution to the 3-body problem discovered by Chenciner & Montgomery (2000). Three equal masses chase each other in a figure-8 pattern with period T ≈ 6.3259 [dimensionless units].
The orbit is:
Planar (z=0)
Periodic with known period
Choreographic (particles equally spaced along curve)
Stable under small perturbations
Args
| Parameter | Description |
|---|---|
mass | Mass of each particle [Msun] (default: 1.0) |
scale | Spatial scale factor (default: 1.0) |
G | Gravitational constant (default: 1.0, dimensionless) |
Returns: AnalyticalIC with 3 equal masses in figure-8 orbit Analytical solution: - Period: T = 6.3259... [dimensionless, G=1 units] - Total energy: E = constant (conserved to machine precision) - Angular momentum: L = 0 (zero total angular momentum) - Symmetry: 3-fold rotational symmetry
Example. >>> # Dimensionless units (default, for mathematical testing)
ic = three_body_figure_eight(mass=1.0, scale=1.0, G=1.0)
Integrate for 1 period: t_end = 6.3259¶
Physical units (use jaxstro.units for consistent G)¶
from jaxstro.units import STELLAR ic = three_body_figure_eight(mass=1.0, scale=1.0, G=STELLAR.G)
Notes. - Uses dimensionless units by default (G=1, m=1, scale=1)
This is a mathematical test problem with known exact solution
For physical units, pass G from jaxstro.units (STELLAR or PLANETARY)
Period scales as T ∝ sqrt(scale³ / G) from dimensionless T₀ = 6.3259
Works best with zero softening (pure Newtonian)
References. - Chenciner & Montgomery (2000), Ann. Math., 152, 881
Simó (2001), private communication (numerical coefficients)
Montgomery (2001), Notices AMS, 48, 471 - Popular review
Source: src/progenax/analytical/few_body.py#L17
analytical.figure_eight_period¶
function
figure_eight_period(scale: 'ArrayLike' = 1.0, G: 'ArrayLike' = 1.0, mass: 'ArrayLike' = 1.0) -> "Float[Array, '']"Return period of figure-8 orbit.
Args
| Parameter | Description |
|---|---|
scale | Spatial scale factor used in three_body_figure_eight() |
G | Gravitational constant [appropriate units] |
mass | Mass of each particle [same units as three_body_figure_eight] (default 1.0) |
Returns: Period in time units
Notes. - Period is T₀ = 6.32591398 in dimensionless units (G=1, m=1, scale=1)
Scales as T = T₀ · √(scale³ / (G·m))
Source: src/progenax/analytical/few_body.py#L113
analytical.harmonic_oscillator¶
function
harmonic_oscillator(amplitude: 'float' = 1.0, omega: 'float' = 1.0, phase: 'float' = 0.0, mass: 'float' = 1.0, dimension: "Literal['1D', '2D']" = '1D') -> 'AnalyticalIC'Create 1D or 2D harmonic oscillator for integrator testing.
Simple harmonic motion: F = -k x, with k = m ω² Analytical solution: x(t) = A cos(ωt + φ)
This is the SIMPLEST possible test for an integrator:
Linear dynamics (no chaos)
Known exact solution
Energy conserved exactly
Period independent of amplitude
Args
| Parameter | Description |
|---|---|
amplitude | Oscillation amplitude (default: 1.0) |
omega | Angular frequency (default: 1.0) → Period = 2π/ω |
phase | Initial phase [radians] (default: 0) |
mass | Particle mass (default: 1.0) |
dimension | “1D” or “2D” (default: “1D”) |
Returns: AnalyticalIC with 1 particle in harmonic potential Analytical solution: x(t) = A cos(ωt + φ) v(t) = -A ω sin(ωt + φ) E = (1/2) k A² = (1/2) m ω² A² (constant)
Example. >>> ic = harmonic_oscillator(amplitude=1.0, omega=2*jnp.pi)
Period T = 1.0, x(0)=1.0, v(0)=0¶
Notes. - This tests integrator mechanics WITHOUT gravitational forces
Requires external force implementation: F_ext = -k·x
1D: oscillation along x-axis
2D: circular motion (2D isotropic oscillator)
Use for sanity checks before testing gravity
Warning. This returns initial conditions for an external harmonic potential
(F_ext = -k·x), not a self-gravitating system. Most N-body integrators
provide only pairwise gravity, so they cannot evolve this case without an
external-force hook. Use two_body_kepler() for gravity-only tests.
Source: src/progenax/analytical/few_body.py#L140
analytical.harmonic_solution¶
function
harmonic_solution(t: 'float', amplitude: 'float', omega: 'float', phase: 'float' = 0.0, dimension: "Literal['1D', '2D']" = '1D') -> "tuple[Float[Array, '1 3'], Float[Array, '1 3']]"Compute analytical solution for harmonic oscillator at time t.
Args
| Parameter | Description |
|---|---|
t | Time |
amplitude | Oscillation amplitude |
omega | Angular frequency |
phase | Initial phase [radians] |
dimension | “1D” or “2D” |
Returns: (positions, velocities) at time t
Example. >>> pos, vel = harmonic_solution(t=1.0, amplitude=1.0, omega=2*jnp.pi)
Compare with integrated result¶
Source: src/progenax/analytical/few_body.py#L225
analytical.earth_sun_2body¶
function
earth_sun_2body(G: 'float') -> 'AnalyticalIC'Earth-Sun system for validation (circular orbit approximation).
Physical parameters: - M_sun = 1.0 Msun - M_earth = 3.0035e-6 Msun (1 Earth mass) - a = 1.0 AU (semi-major axis) - e = 0.0167 (actual eccentricity, approximated as circular)
Args
| Parameter | Description |
|---|---|
G | Gravitational constant [appropriate units, e.g., AU³/Msun/yr²] |
Returns: AnalyticalIC with Sun + Earth in circular orbit Validation targets: - Period: T = 1.0 yr (by construction with binary units) - Energy conservation: |ΔE/E| < 10^-12 - Angular momentum conservation: |ΔL/L| < 10^-15
Example. >>> G = 39.478 # Binary units
ic = earth_sun_2body(G=G)
Integrate for 10 orbits, check energy conservation¶
Notes. - Uses circular orbit (e=0) for simplicity
True Earth orbit has e=0.0167 (use earth_sun_eccentric() for that)
Mass ratio: M_sun/M_earth ≈ 333,000
References. - JPL Horizons ephemeris data
Murray & Dermott (1999), “Solar System Dynamics”, Appendix B
Source: src/progenax/analytical/solar_system.py#L56
analytical.earth_sun_eccentric¶
function
earth_sun_eccentric(G: 'float') -> 'AnalyticalIC'Earth-Sun system with true eccentricity.
Uses actual Earth orbital parameters for more realistic validation.
Physical parameters: - M_sun = 1.0 Msun - M_earth = 3.0035e-6 Msun - a = 1.0 AU - e = 0.0167 (true eccentricity)
Args
| Parameter | Description |
|---|---|
G | Gravitational constant [appropriate units] |
Returns: AnalyticalIC with Sun + Earth in eccentric orbit Validation targets: - Perihelion distance: r_peri = a(1-e) = 0.9833 AU - Aphelion distance: r_aph = a(1+e) = 1.0167 AU - Period: T = 1.0 yr - Energy conservation: |ΔE/E| < 10^-12
Example. >>> G = 39.478 # Binary units
ic = earth_sun_eccentric(G=G)
Tests adaptive timestep handling (dt varies by ~3%)¶
Source: src/progenax/analytical/solar_system.py#L99
analytical.sun_earth_jupiter_3body¶
function
sun_earth_jupiter_3body(G: 'float') -> 'AnalyticalIC'Sun-Earth-Jupiter system for 3-body validation.
This is a realistic hierarchical 3-body problem:
Inner binary: Sun-Earth (a=1 AU, T=1 yr)
Outer planet: Jupiter (a=5.2 AU, T=11.86 yr)
Physical parameters: - M_sun = 1.0 Msun - M_earth = 3.0035e-6 Msun - M_jupiter = 9.548e-4 Msun (1 Jupiter mass) - a_earth = 1.0 AU, e_earth = 0.0167 - a_jupiter = 5.2044 AU, e_jupiter = 0.04839
Args
| Parameter | Description |
|---|---|
G | Gravitational constant [appropriate units] |
Returns: AnalyticalIC with Sun + Earth + Jupiter Validation targets: - Hierarchical timesteps: Jupiter needs ~10× longer dt than Earth - Energy conservation: |ΔE/E| < 10^-10 (3-body is harder than 2-body) - Perturbations: Earth’s orbit perturbed by Jupiter (~0.1% level)
Example. >>> G = 39.478 # Binary units
ic = sun_earth_jupiter_3body(G=G)
Integrate for 100 yr, check energy conservation¶
Notes. - Jupiter mass ≈ 318 Earth masses
Mass ratio: M_jup/M_earth ≈ 318
Hierarchical: a_jup/a_earth ≈ 5.2 (well-separated)
References. - JPL Horizons ephemeris (epoch J2000.0)
Murray & Dermott (1999), Appendix B
Source: src/progenax/analytical/solar_system.py#L136
analytical.solar_system_inner_4¶
function
solar_system_inner_4(G: 'float') -> 'AnalyticalIC'Inner solar system: Sun + Mercury + Venus + Earth + Mars.
Realistic N=5 system for testing block timesteps and hierarchical integration.
Physical parameters (epoch J2000.0): - Sun: M = 1.0 Msun - Mercury: M = 1.66e-7 Msun, a = 0.387 AU, e = 0.206 - Venus: M = 2.45e-6 Msun, a = 0.723 AU, e = 0.007 - Earth: M = 3.00e-6 Msun, a = 1.000 AU, e = 0.017 - Mars: M = 3.23e-7 Msun, a = 1.524 AU, e = 0.093
Args
| Parameter | Description |
|---|---|
G | Gravitational constant [appropriate units] |
Returns: AnalyticalIC with Sun + 4 inner planets Validation targets: - Timestep hierarchy: Mercury (88 d) → Venus (225 d) → Earth (365 d) → Mars (687 d) - Energy conservation: |ΔE/E| < 10^-9 (more challenging than 2-body) - Secular perturbations: orbital precession over centuries
Example. >>> G = 39.478 # Binary units
ic = solar_system_inner_4(G=G)
Integrate for 1000 yr, measure energy drift¶
Notes. - Mercury has highest eccentricity (e=0.206) → needs shortest timestep
Venus nearly circular (e=0.007) → can use longer timestep
Mars eccentric (e=0.093) → moderate timestep variation
References. - JPL Horizons ephemeris (J2000.0)
Source: src/progenax/analytical/solar_system.py#L229
analytical.solar_system_full¶
function
solar_system_full(G: 'float') -> 'AnalyticalIC'Full solar system: Sun + 8 planets with true orbital elements.
The ultimate N-body validation test for gravitational integrators. Includes all 8 planets with realistic masses, semi-major axes, and eccentricities.
Physical parameters (epoch J2000.0): - Sun: M = 1.0 Msun - Mercury: a = 0.387 AU, e = 0.206, T = 0.241 yr - Venus: a = 0.723 AU, e = 0.007, T = 0.615 yr - Earth: a = 1.000 AU, e = 0.017, T = 1.000 yr - Mars: a = 1.524 AU, e = 0.093, T = 1.881 yr - Jupiter: a = 5.204 AU, e = 0.049, T = 11.86 yr - Saturn: a = 9.582 AU, e = 0.057, T = 29.46 yr - Uranus: a = 19.20 AU, e = 0.046, T = 84.01 yr - Neptune: a = 30.05 AU, e = 0.011, T = 164.8 yr
Args
| Parameter | Description |
|---|---|
G | Gravitational constant [appropriate units] |
Returns: AnalyticalIC with Sun + 8 planets (N=9) Validation targets: - Energy conservation: |ΔE/E| < 10^-8 over 1000 yr - Secular dynamics: planetary precession over millennia - Timestep hierarchy: Mercury (88 d) to Neptune (60,190 d) → 680× range - Conservation over long timescales (Myr)
Example. >>> G = 39.478 # Binary units
ic = solar_system_full(G=G)
Integrate for 10,000 yr with block timesteps¶
Notes. - Block timestepping essential: 680× timestep range (Mercury to Neptune)
Excludes Pluto (dwarf planet, highly eccentric/inclined)
Excludes moons (would need hierarchical treatment)
Uses J2000.0 epoch osculating elements
True 3D orbits (includes inclinations)
Warning. - Long-term integration (>10 Myr) requires symplectic integrators
Chaotic on 5-10 Myr timescales (Laskar 1989)
Use for validation, not production solar system ephemeris
References. - JPL Horizons: https://
Standish & Williams (2012), “Orbital Ephemerides”
Laskar (1989), Nature, 338, 237 - Solar system chaos