Skip to main content

Kelvin Zero

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://k0webapp.web.app. 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 EMI (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

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 reference reference.json         # values to test another implementation against

The visualizer

kelvinzero viz serves a built copy of the visualizer from https://k0webapp.web.app 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 — EMI 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); EMI has x toward the vernal equinox and z along the spin axis.

Verification

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.1.0 (2026). https://github.com/kylecooper7/kelvin-zero

License

MIT.

Metadata

Release files for kelvinzero 0.1.0

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.1.0
File Size Uploaded
kelvinzero-0.1.0.tar.gz 956.4 kB Details

Built distribution (wheel)

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

Total release size: 1.9 MB

Release files / kelvinzero-0.1.0.tar.gz

Download URL kelvinzero-0.1.0.tar.gz
Size 956.4 kB
Tags Source
SHA-256 checksum
How to use checksums
5bc73abe12b5f7467d5cf07d09e8ce8983821576a653db313161a09193e4a385
BLAKE2b-256 checksum
How to use checksums
a529bff38b77d980ff2443f5a915da0b669495e116466b2c4eb611ab17a77ec1
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.1.0-py3-none-any.whl

Download URL kelvinzero-0.1.0-py3-none-any.whl
Size 954.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a9ef72a1781b4bd17429bf1d20be31c7ac9677dfbea5e8f6106d73b9f13d0b4c
BLAKE2b-256 checksum
How to use checksums
98e317ea079d716ec3813ed70bdf5c1f8a1015b03f8059f1592c97cea64385d9
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

0.2.5

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

This release

0.1.0 This release

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