Skip to main content

Kelvin Zero

PyPI DOI tests

Eclipse-minimising sun-synchronous orbits in a mean-Sun rotating frame — the open model.

This package is the complete, inspectable source of every number, figure and 3-D view in the Kelvin Zero whitepaper and the interactive visualizer at https://colure.space/kelvinzero/. It is pure NumPy, a few hundred lines, and organised the way the paper is:

module what it holds
kelvinzero.sun the apparent Sun (USNO low-precision ephemeris), the mean Sun, the analemma, Earth's heliocentric position
kelvinzero.frames the ECI (inertial) and MSSI (mean-Sun synchronous) frames, sidereal time
kelvinzero.orbit the sun-synchronous condition, J2 nodal precession, 3-D positions, the β angle, the cylindrical-shadow eclipse fraction, yearly statistics
kelvinzero.regions the always / sometimes / never-eclipsed region maps and their ∂U / ∂I contours
kelvinzero.figures the paper's figures (matplotlib)
kelvinzero.viz runs the visualizer locally — the same one as the website
kelvinzero.reference reference values for cross-checking other implementations
kelvinzero.hifi the high-fidelity cross-check: numerical propagation with J2–J6, Sun and Moon from JPL DE440 and a conical umbra/penumbra (pip install "kelvinzero[hifi]")

Install

pip install kelvinzero            # model + the built visualizer (NumPy only)
pip install "kelvinzero[figures]" # + matplotlib, for the figures

or from a checkout: pip install -e ".[dev]".

Thirty seconds

from kelvinzero import Orbit, yearly_eclipse_stats, no_eclipse_beta_deg

o = Orbit(altitude_km=800, raan_offset_deg=270)   # dawn–dusk, LTAN 06:00; inclination is set by the SSO condition
print(o.inclination_deg)                           # 98.603
print(no_eclipse_beta_deg(800))                    # 62.69  — eclipse-free once |β| exceeds this
print(yearly_eclipse_stats(o))                     # eclipse_fraction≈0.0267, eclipse_days≈74, β from −89.9° to −58.0°
kelvinzero stats --alt 1500 --raan 270      # a fixed plane that is never eclipsed
kelvinzero sweep --alt 800                  # yearly eclipse versus node offset
kelvinzero figures out/                     # regenerate the paper's figures
kelvinzero viz --alt 800 --raan 270 --view eclipse    # the visualizer, in your browser, served from your machine
kelvinzero hifi --alt 800 --raan 270        # closed form vs a full-force-model propagation (needs the [hifi] extra; downloads DE440s once)
kelvinzero reference reference.json         # values to test another implementation against

The visualizer

kelvinzero viz serves a built copy of the visualizer from https://colure.space/kelvinzero/ on a local port and opens it — the identical React + Three.js application, minus the website chrome. Its source is in viewer/: the JavaScript model in viewer/src/model mirrors this package function for function (sun.js, frames.js, orbit.js, regions.js), and the 3-D scene is viewer/src/scene/OrbitScene.js. To work on it:

cd viewer && npm install
npm run dev      # live-reloading dev server
npm test         # the JS model against this package's reference values (reference.json)
npm run build    # refreshes the copy shipped in src/kelvinzero/viewer_dist

The model in one paragraph

A circular orbit of altitude h is sun-synchronous when its J2 nodal precession equals the mean Sun's rate, which fixes the inclination (sso_inclination_deg). In the MSSI frame — ECI rotated about the spin axis by the mean solar longitude L(d) — such a plane is frozen and the real Sun traces the analemma (sun_direction_mssi, analemma_mssi). The Sun's elevation above the plane is the β angle (beta_angle); the fraction of each revolution spent in Earth's cylindrical shadow is the closed form eclipse_fraction_per_orbit, zero once |β| ≥ asin(R/(R+h)). Averaging over the year gives yearly_eclipse_stats. Mapping max_t p·s and min_t p·s over the sphere (compute_sun_dot_extrema) classifies every direction as always / sometimes / never eclipsed for a given altitude (classify_regions, region_contours).

Conventions: d is days since J2000.0 (2000-01-01 12:00); the node offset Ω is measured from the mean Sun (Ω = 0 → LTAN 12:00, 90 → 18:00, 270 → 06:00); ECI has x toward the vernal equinox and z along the spin axis.

Verification

kelvinzero hifi propagates an orbit through a year with the EGM96 zonal field J2–J6, the Sun and Moon as point masses from the JPL DE440s ephemeris (33 MB, fetched once into ~/.cache/kelvinzero), DOP853 integration and a conical umbra/penumbra, and prints the eclipse hours, days with eclipse and the longest pass next to the closed form — plus the node drift the J2-only inclination leaves and the inclination that cancels it. The paper's verification table is kelvinzero hifi for nine cases.

pytest checks the closed-form eclipse fraction against brute-force cylindrical-shadow sweeps, the USNO ephemeris against the NOAA/Spencer series, frame conventions (an exact SSO is frozen in MSSI, the Sun is west of the mean Sun in November, Ω = 90° ⇒ LTAN 18:00), the region maps against the β-angle picture, and the headline numbers of the paper. kelvinzero reference writes the values that the visualizer's JavaScript model is tested against.

Citing

If you use the model or the paper, please cite the release (a CITATION.cff is included, so GitHub's "Cite this repository" button gives you BibTeX/APA):

K. Cooper and Y. Nikas, Kelvin Zero: eclipse-minimising sun-synchronous orbits in a mean-Sun rotating frame, v0.2.5 (2026). https://doi.org/10.5281/zenodo.23382386

License

MIT.

Metadata

Release files for kelvinzero 0.2.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for kelvinzero 0.2.5
File Size Uploaded
kelvinzero-0.2.5.tar.gz 969.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for kelvinzero 0.2.5
File Interpreter ABI Platform
kelvinzero-0.2.5-py3-none-any.whl Python 3 none any Details

Total release size: 1.9 MB

Release files / kelvinzero-0.2.5.tar.gz

Download URL kelvinzero-0.2.5.tar.gz
Size 969.2 kB
Tags Source
SHA-256 checksum
How to use checksums
70cee0f048144788859ad6925a53e7902f6f0487e1021fb4a64d0a74d3f824f1
BLAKE2b-256 checksum
How to use checksums
df0b5c052bc37eee08724a5a0b5ff58f60398109dc9c5fc616d835abe0fd695e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.

Transparency log

Release files / kelvinzero-0.2.5-py3-none-any.whl

Download URL kelvinzero-0.2.5-py3-none-any.whl
Size 966.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2f1b5cf36a5e486c543962ff64aff8b04f6689e4d2c8f1f862ed055b0e736424
BLAKE2b-256 checksum
How to use checksums
2ac88ee12130f0df1e60da0a2ffbd01348f3b46848bb5761ec2c1ed6d8128e9b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.5 This release

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page