spacedc-mdao 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- spacedc_mdao-0.4.0/.github/workflows/ci.yml +65 -0
- spacedc_mdao-0.4.0/.github/workflows/release.yml +48 -0
- spacedc_mdao-0.4.0/.gitignore +37 -0
- spacedc_mdao-0.4.0/CHANGELOG.md +97 -0
- spacedc_mdao-0.4.0/CLAUDE.md +162 -0
- spacedc_mdao-0.4.0/LICENSE +21 -0
- spacedc_mdao-0.4.0/PKG-INFO +123 -0
- spacedc_mdao-0.4.0/README.md +74 -0
- spacedc_mdao-0.4.0/SPEC.md +605 -0
- spacedc_mdao-0.4.0/background_information/EQUATIONS.md +741 -0
- spacedc_mdao-0.4.0/background_information/THEMRAL_RADIATOR_DEEPDIVE.md +382 -0
- spacedc_mdao-0.4.0/docs/api.md +45 -0
- spacedc_mdao-0.4.0/docs/architecture.md +50 -0
- spacedc_mdao-0.4.0/docs/equations.md +10 -0
- spacedc_mdao-0.4.0/docs/gen_provenance.py +40 -0
- spacedc_mdao-0.4.0/docs/index.md +29 -0
- spacedc_mdao-0.4.0/docs/quickstart.md +57 -0
- spacedc_mdao-0.4.0/docs/tiers.md +53 -0
- spacedc_mdao-0.4.0/examples/dashboard_app.py +19 -0
- spacedc_mdao-0.4.0/examples/notebooks/00_quick_start.ipynb +62 -0
- spacedc_mdao-0.4.0/examples/notebooks/01_compare.ipynb +77 -0
- spacedc_mdao-0.4.0/examples/notebooks/02_radiator_feasibility.ipynb +151 -0
- spacedc_mdao-0.4.0/examples/notebooks/03_pareto_exploration.ipynb +81 -0
- spacedc_mdao-0.4.0/examples/notebooks/04_monte_carlo_uncertainty.ipynb +65 -0
- spacedc_mdao-0.4.0/examples/scenarios/earth_constrained_grid.yaml +15 -0
- spacedc_mdao-0.4.0/examples/scenarios/earth_gas_backed.yaml +15 -0
- spacedc_mdao-0.4.0/examples/scenarios/earth_hyperscale_baseline.yaml +15 -0
- spacedc_mdao-0.4.0/examples/scenarios/earth_leased_colo.yaml +15 -0
- spacedc_mdao-0.4.0/examples/scenarios/earth_renewable_storage.yaml +15 -0
- spacedc_mdao-0.4.0/examples/scenarios/orbital_1mw_inference.yaml +38 -0
- spacedc_mdao-0.4.0/mkdocs.yml +59 -0
- spacedc_mdao-0.4.0/pyproject.toml +98 -0
- spacedc_mdao-0.4.0/src/orbitdc/__init__.py +41 -0
- spacedc_mdao-0.4.0/src/orbitdc/calibrate.py +56 -0
- spacedc_mdao-0.4.0/src/orbitdc/cli.py +208 -0
- spacedc_mdao-0.4.0/src/orbitdc/compare.py +695 -0
- spacedc_mdao-0.4.0/src/orbitdc/core/__init__.py +1 -0
- spacedc_mdao-0.4.0/src/orbitdc/core/assumptions.py +76 -0
- spacedc_mdao-0.4.0/src/orbitdc/core/catalog_loader.py +38 -0
- spacedc_mdao-0.4.0/src/orbitdc/core/constants.py +25 -0
- spacedc_mdao-0.4.0/src/orbitdc/core/registry.py +158 -0
- spacedc_mdao-0.4.0/src/orbitdc/core/scenario.py +22 -0
- spacedc_mdao-0.4.0/src/orbitdc/core/schema.py +165 -0
- spacedc_mdao-0.4.0/src/orbitdc/core/units.py +24 -0
- spacedc_mdao-0.4.0/src/orbitdc/data/__init__.py +1 -0
- spacedc_mdao-0.4.0/src/orbitdc/data/accelerators.yaml +206 -0
- spacedc_mdao-0.4.0/src/orbitdc/data/batteries.yaml +39 -0
- spacedc_mdao-0.4.0/src/orbitdc/data/chip_stacks.yaml +49 -0
- spacedc_mdao-0.4.0/src/orbitdc/data/coatings.yaml +61 -0
- spacedc_mdao-0.4.0/src/orbitdc/data/comms.yaml +33 -0
- spacedc_mdao-0.4.0/src/orbitdc/data/coolants.yaml +45 -0
- spacedc_mdao-0.4.0/src/orbitdc/data/cost_structure.yaml +60 -0
- spacedc_mdao-0.4.0/src/orbitdc/data/embodied_factors.yaml +25 -0
- spacedc_mdao-0.4.0/src/orbitdc/data/launch.yaml +62 -0
- spacedc_mdao-0.4.0/src/orbitdc/data/mass_structure.yaml +38 -0
- spacedc_mdao-0.4.0/src/orbitdc/data/radiation_env.yaml +14 -0
- spacedc_mdao-0.4.0/src/orbitdc/data/radiator_panels.yaml +58 -0
- spacedc_mdao-0.4.0/src/orbitdc/data/radiators.yaml +42 -0
- spacedc_mdao-0.4.0/src/orbitdc/data/solar_arrays.yaml +51 -0
- spacedc_mdao-0.4.0/src/orbitdc/data/workloads.yaml +39 -0
- spacedc_mdao-0.4.0/src/orbitdc/diagnostics.py +145 -0
- spacedc_mdao-0.4.0/src/orbitdc/evaluation.py +43 -0
- spacedc_mdao-0.4.0/src/orbitdc/mdao/__init__.py +9 -0
- spacedc_mdao-0.4.0/src/orbitdc/mdao/problem.py +96 -0
- spacedc_mdao-0.4.0/src/orbitdc/models/__init__.py +2 -0
- spacedc_mdao-0.4.0/src/orbitdc/models/comms_link.py +65 -0
- spacedc_mdao-0.4.0/src/orbitdc/models/compute.py +33 -0
- spacedc_mdao-0.4.0/src/orbitdc/models/cost.py +185 -0
- spacedc_mdao-0.4.0/src/orbitdc/models/earth_baseline.py +39 -0
- spacedc_mdao-0.4.0/src/orbitdc/models/environmental.py +68 -0
- spacedc_mdao-0.4.0/src/orbitdc/models/formation.py +90 -0
- spacedc_mdao-0.4.0/src/orbitdc/models/lasercom.py +67 -0
- spacedc_mdao-0.4.0/src/orbitdc/models/mass.py +54 -0
- spacedc_mdao-0.4.0/src/orbitdc/models/network.py +35 -0
- spacedc_mdao-0.4.0/src/orbitdc/models/orbit.py +113 -0
- spacedc_mdao-0.4.0/src/orbitdc/models/orbit_skyfield.py +95 -0
- spacedc_mdao-0.4.0/src/orbitdc/models/power.py +79 -0
- spacedc_mdao-0.4.0/src/orbitdc/models/radiation.py +76 -0
- spacedc_mdao-0.4.0/src/orbitdc/models/reliability.py +107 -0
- spacedc_mdao-0.4.0/src/orbitdc/models/rf.py +88 -0
- spacedc_mdao-0.4.0/src/orbitdc/models/thermal.py +63 -0
- spacedc_mdao-0.4.0/src/orbitdc/optimize/__init__.py +10 -0
- spacedc_mdao-0.4.0/src/orbitdc/optimize/design.py +87 -0
- spacedc_mdao-0.4.0/src/orbitdc/optimize/doe.py +49 -0
- spacedc_mdao-0.4.0/src/orbitdc/optimize/pareto.py +154 -0
- spacedc_mdao-0.4.0/src/orbitdc/optimize/robust.py +111 -0
- spacedc_mdao-0.4.0/src/orbitdc/optimize/sensitivity.py +95 -0
- spacedc_mdao-0.4.0/src/orbitdc/optimize/uncertainty.py +117 -0
- spacedc_mdao-0.4.0/src/orbitdc/py.typed +0 -0
- spacedc_mdao-0.4.0/src/orbitdc/reporting.py +83 -0
- spacedc_mdao-0.4.0/src/orbitdc/thermal/__init__.py +27 -0
- spacedc_mdao-0.4.0/src/orbitdc/thermal/catalog.py +61 -0
- spacedc_mdao-0.4.0/src/orbitdc/thermal/codesign.py +170 -0
- spacedc_mdao-0.4.0/src/orbitdc/thermal/coolant.py +45 -0
- spacedc_mdao-0.4.0/src/orbitdc/thermal/degradation.py +94 -0
- spacedc_mdao-0.4.0/src/orbitdc/thermal/diagnosis.py +58 -0
- spacedc_mdao-0.4.0/src/orbitdc/thermal/network.py +35 -0
- spacedc_mdao-0.4.0/src/orbitdc/thermal/presets.py +27 -0
- spacedc_mdao-0.4.0/src/orbitdc/thermal/radiation.py +67 -0
- spacedc_mdao-0.4.0/src/orbitdc/thermal/surfaces.py +112 -0
- spacedc_mdao-0.4.0/src/orbitdc/thermal/transient.py +94 -0
- spacedc_mdao-0.4.0/src/orbitdc/thermal/validation.py +71 -0
- spacedc_mdao-0.4.0/src/orbitdc/thermal/view_factors.py +59 -0
- spacedc_mdao-0.4.0/src/orbitdc/viz/__init__.py +9 -0
- spacedc_mdao-0.4.0/src/orbitdc/viz/dashboard.py +69 -0
- spacedc_mdao-0.4.0/src/orbitdc/viz/plotly_figures.py +307 -0
- spacedc_mdao-0.4.0/src/orbitdc/viz/plots.py +78 -0
- spacedc_mdao-0.4.0/src/orbitdc/viz/provenance.py +68 -0
- spacedc_mdao-0.4.0/src/orbitdc/waterfall.py +48 -0
- spacedc_mdao-0.4.0/tests/test_assumptions.py +55 -0
- spacedc_mdao-0.4.0/tests/test_cli.py +35 -0
- spacedc_mdao-0.4.0/tests/test_comms.py +30 -0
- spacedc_mdao-0.4.0/tests/test_comms_link.py +50 -0
- spacedc_mdao-0.4.0/tests/test_compare.py +73 -0
- spacedc_mdao-0.4.0/tests/test_degradation.py +57 -0
- spacedc_mdao-0.4.0/tests/test_edge_cases.py +54 -0
- spacedc_mdao-0.4.0/tests/test_fidelity.py +83 -0
- spacedc_mdao-0.4.0/tests/test_formation.py +61 -0
- spacedc_mdao-0.4.0/tests/test_graceful_degradation.py +57 -0
- spacedc_mdao-0.4.0/tests/test_learning_robust.py +63 -0
- spacedc_mdao-0.4.0/tests/test_mdao.py +92 -0
- spacedc_mdao-0.4.0/tests/test_models.py +81 -0
- spacedc_mdao-0.4.0/tests/test_published_cases.py +52 -0
- spacedc_mdao-0.4.0/tests/test_radiation.py +50 -0
- spacedc_mdao-0.4.0/tests/test_references.py +70 -0
- spacedc_mdao-0.4.0/tests/test_reporting.py +35 -0
- spacedc_mdao-0.4.0/tests/test_skyfield_orbit.py +75 -0
- spacedc_mdao-0.4.0/tests/test_thermal.py +112 -0
- spacedc_mdao-0.4.0/tests/test_transient.py +43 -0
- spacedc_mdao-0.4.0/tests/test_view_factors.py +49 -0
- spacedc_mdao-0.4.0/tests/test_viz_plotly.py +87 -0
- spacedc_mdao-0.4.0/tests/test_workloads.py +43 -0
- spacedc_mdao-0.4.0/uv.lock +2452 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
name: ci
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
check:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
- name: Install uv
|
|
14
|
+
uses: astral-sh/setup-uv@v5
|
|
15
|
+
- name: Set up Python
|
|
16
|
+
run: uv python install 3.12
|
|
17
|
+
- name: Sync
|
|
18
|
+
run: uv sync --extra dev --extra mdao --extra viz
|
|
19
|
+
- name: Editable install guard
|
|
20
|
+
run: |
|
|
21
|
+
for i in 1 2 3; do
|
|
22
|
+
uv sync --extra dev --extra mdao --extra viz
|
|
23
|
+
uv run --no-sync python -c "import orbitdc; print(orbitdc.__version__)"
|
|
24
|
+
done
|
|
25
|
+
- name: Ruff lint
|
|
26
|
+
run: uv run ruff check .
|
|
27
|
+
- name: Ruff format
|
|
28
|
+
run: uv run ruff format --check .
|
|
29
|
+
- name: Mypy
|
|
30
|
+
run: uv run mypy src
|
|
31
|
+
- name: Pytest
|
|
32
|
+
run: uv run pytest
|
|
33
|
+
|
|
34
|
+
docs:
|
|
35
|
+
runs-on: ubuntu-latest
|
|
36
|
+
steps:
|
|
37
|
+
- uses: actions/checkout@v4
|
|
38
|
+
- name: Install uv
|
|
39
|
+
uses: astral-sh/setup-uv@v5
|
|
40
|
+
- name: Set up Python
|
|
41
|
+
run: uv python install 3.12
|
|
42
|
+
- name: Sync
|
|
43
|
+
run: uv sync --extra docs
|
|
44
|
+
- name: Build docs (strict)
|
|
45
|
+
run: uv run --no-sync python -m mkdocs build --strict
|
|
46
|
+
- name: Upload Pages artifact
|
|
47
|
+
if: github.ref == 'refs/heads/main'
|
|
48
|
+
uses: actions/upload-pages-artifact@v3
|
|
49
|
+
with:
|
|
50
|
+
path: site
|
|
51
|
+
|
|
52
|
+
deploy-docs:
|
|
53
|
+
needs: docs
|
|
54
|
+
if: github.ref == 'refs/heads/main'
|
|
55
|
+
runs-on: ubuntu-latest
|
|
56
|
+
permissions:
|
|
57
|
+
pages: write
|
|
58
|
+
id-token: write
|
|
59
|
+
environment:
|
|
60
|
+
name: github-pages
|
|
61
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
62
|
+
steps:
|
|
63
|
+
- name: Deploy to GitHub Pages
|
|
64
|
+
id: deployment
|
|
65
|
+
uses: actions/deploy-pages@v4
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
name: release
|
|
2
|
+
|
|
3
|
+
# Publishes to PyPI when a v* tag is pushed, using PyPI Trusted Publishing
|
|
4
|
+
# (OIDC — no stored token). One-time setup required (see below):
|
|
5
|
+
# 1. Create the `spacedc-mdao` project on PyPI (or let the first publish create
|
|
6
|
+
# it once a Trusted Publisher is configured as a "pending" publisher).
|
|
7
|
+
# 2. On PyPI, add a Trusted Publisher: owner `jman4162`, repo `spacedc-mdao`,
|
|
8
|
+
# workflow `release.yml`, environment `pypi`.
|
|
9
|
+
# 3. In GitHub repo settings, create an Environment named `pypi`.
|
|
10
|
+
# Then: bump the version, tag `vX.Y.Z`, and push the tag.
|
|
11
|
+
|
|
12
|
+
on:
|
|
13
|
+
push:
|
|
14
|
+
tags: ["v*"]
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
build:
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v4
|
|
21
|
+
- name: Install uv
|
|
22
|
+
uses: astral-sh/setup-uv@v5
|
|
23
|
+
- name: Build sdist + wheel
|
|
24
|
+
run: uv build
|
|
25
|
+
- name: Check metadata
|
|
26
|
+
run: uvx twine check dist/*
|
|
27
|
+
- name: Upload artifacts
|
|
28
|
+
uses: actions/upload-artifact@v4
|
|
29
|
+
with:
|
|
30
|
+
name: dist
|
|
31
|
+
path: dist/
|
|
32
|
+
|
|
33
|
+
publish:
|
|
34
|
+
needs: build
|
|
35
|
+
runs-on: ubuntu-latest
|
|
36
|
+
environment:
|
|
37
|
+
name: pypi
|
|
38
|
+
url: https://pypi.org/p/spacedc-mdao
|
|
39
|
+
permissions:
|
|
40
|
+
id-token: write # required for Trusted Publishing (OIDC)
|
|
41
|
+
steps:
|
|
42
|
+
- name: Download artifacts
|
|
43
|
+
uses: actions/download-artifact@v4
|
|
44
|
+
with:
|
|
45
|
+
name: dist
|
|
46
|
+
path: dist/
|
|
47
|
+
- name: Publish to PyPI
|
|
48
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Reference papers — not redistributed; cite by arXiv ID (e.g. arXiv:2511.19468)
|
|
2
|
+
*.pdf
|
|
3
|
+
|
|
4
|
+
# Local-only reference (CC BY-SA from Wikipedia; kept out of this MIT repo).
|
|
5
|
+
# Cited by URL: https://en.wikipedia.org/wiki/Wikipedia:Signs_of_AI_writing
|
|
6
|
+
AI_WRITING_SLOP_Guide.md
|
|
7
|
+
|
|
8
|
+
# Python
|
|
9
|
+
__pycache__/
|
|
10
|
+
*.py[cod]
|
|
11
|
+
*.egg-info/
|
|
12
|
+
.eggs/
|
|
13
|
+
build/
|
|
14
|
+
dist/
|
|
15
|
+
.venv/
|
|
16
|
+
venv/
|
|
17
|
+
env/
|
|
18
|
+
.python-version
|
|
19
|
+
|
|
20
|
+
# Tooling caches
|
|
21
|
+
.pytest_cache/
|
|
22
|
+
.ruff_cache/
|
|
23
|
+
.mypy_cache/
|
|
24
|
+
.ipynb_checkpoints/
|
|
25
|
+
|
|
26
|
+
# OpenMDAO run artifacts (reports / recordings)
|
|
27
|
+
*_out/
|
|
28
|
+
reports/
|
|
29
|
+
|
|
30
|
+
# OS / editor
|
|
31
|
+
.DS_Store
|
|
32
|
+
.vscode/
|
|
33
|
+
.idea/
|
|
34
|
+
|
|
35
|
+
# Generated by docs/gen_provenance.py at mkdocs build time
|
|
36
|
+
docs/provenance.md
|
|
37
|
+
site/
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `spacedc-mdao`. The package optimizes delivered useful
|
|
4
|
+
compute and reports the feasibility boundary; it is skeptical by default.
|
|
5
|
+
|
|
6
|
+
## 0.4.0 — Phase 4
|
|
7
|
+
|
|
8
|
+
Credibility & validation, breadth, deepened physics (all opt-in), a docs site,
|
|
9
|
+
and the first PyPI release. Reserve 1.0.0 for an API-stability commitment.
|
|
10
|
+
|
|
11
|
+
### 4E — PyPI release
|
|
12
|
+
- Version 0.4.0; clean-venv install from the built wheel imports `orbitdc`, ships
|
|
13
|
+
`py.typed` + the data catalogs, and runs the CLI. `twine check` passes.
|
|
14
|
+
- `release.yml`: publish-on-tag via PyPI Trusted Publishing (OIDC, no token).
|
|
15
|
+
|
|
16
|
+
### 4A — credibility & validation
|
|
17
|
+
- HBM thermal limit wired into the radiator-temperature ceiling and bottleneck
|
|
18
|
+
diagnosis (`hbm-limited`); the demo H100 is HBM-limited.
|
|
19
|
+
- Crosslink bandwidth derived from formation geometry + an optical link budget
|
|
20
|
+
(`models/comms_link.py`); `crosslink_gbps` is now an explicit override.
|
|
21
|
+
- Reproduce Google Suncatcher and McCalip references from the model
|
|
22
|
+
(`tests/test_references.py`); `calibrate.fit_parameter` Tier-4 harness.
|
|
23
|
+
- `logging` + `orbitdc --verbose`.
|
|
24
|
+
|
|
25
|
+
### 4B — breadth of trade studies
|
|
26
|
+
- Real accelerators with cited specs: AMD MI300X and Google TPU v5e (now five
|
|
27
|
+
catalog entries); added catalog variety (current heavy-lift launch,
|
|
28
|
+
high-energy battery, flexible/ROSA solar, composite-deployable radiator).
|
|
29
|
+
- Cost learning curves (Wright's law, `learning_multiplier`) and a TRL premium
|
|
30
|
+
(`trl_multiplier`) in `models/cost.py`; `learning_rate`/`bus_trl` in
|
|
31
|
+
`data/cost_structure.yaml`. `learning_rate` is a sensitivity/Sobol driver.
|
|
32
|
+
- Multi-scenario robustness (`optimize/robust.py`): `batch_compare` matrices one
|
|
33
|
+
space design against every Earth baseline; `robust_optimize` minimizes space
|
|
34
|
+
LCOC and reports baselines beaten. CLI `orbitdc robust <space> <earth...>`.
|
|
35
|
+
|
|
36
|
+
### 4C — deepen physics (all opt-in; defaults unchanged)
|
|
37
|
+
- Formation dynamics (`models/formation.py`): Clohessy-Wiltshire mean motion,
|
|
38
|
+
differential-drag drift cancellation, and a collision-avoidance margin
|
|
39
|
+
(separation / nav uncertainty) that drives conjunction maneuvers. Folds into
|
|
40
|
+
station-keeping; `formation_separation_m` is an override.
|
|
41
|
+
- Thermal Level 4 (`thermal/view_factors.py`): parametric effective view factor
|
|
42
|
+
from articulation, self-view, and solar-array blocking; behind
|
|
43
|
+
`thermal_view_factors`.
|
|
44
|
+
- Thermal Level 5 (`thermal/degradation.py`): mission-integrated coating
|
|
45
|
+
trajectory + MMOD area loss + single-loop-out derate on f_thermal; behind
|
|
46
|
+
`thermal_degradation`.
|
|
47
|
+
- Skyfield orbit fidelity: ground-station access fraction (SGP4) refines optical
|
|
48
|
+
downlink availability behind `orbit_fidelity="skyfield"` + the `orbit` extra,
|
|
49
|
+
with a logged graceful fallback to closed-form.
|
|
50
|
+
- Graceful degradation (`reliability.fleet_health_curve`): a time-stepped fleet
|
|
51
|
+
capacity curve with launch-quantized resupply (sawtooth), exposed as
|
|
52
|
+
`Evaluation.availability_curve`; behind `graceful_degradation`.
|
|
53
|
+
|
|
54
|
+
### 4D — documentation site
|
|
55
|
+
- MkDocs Material site (`docs/`, `mkdocs.yml`, `[docs]` extra): quick start, user
|
|
56
|
+
tiers, model architecture, embedded governing equations, an mkdocstrings API
|
|
57
|
+
reference, and an assumptions/provenance page generated from the catalogs at
|
|
58
|
+
build time. CI builds with `--strict` and deploys to GitHub Pages on `main`.
|
|
59
|
+
- `pyproject` metadata for release: classifiers, `[project.urls]`.
|
|
60
|
+
|
|
61
|
+
## 0.3.0 — Phase 3
|
|
62
|
+
|
|
63
|
+
### 3A — credibility & provenance
|
|
64
|
+
- Moved soft cost/mass/embodied factors into provenance-tagged catalogs
|
|
65
|
+
(`cost_structure`, `mass_structure`, `embodied_factors`); unified the YAML
|
|
66
|
+
loaders in `core/catalog_loader.py`.
|
|
67
|
+
- `tests/test_published_cases.py` recovers Starcloud ~633 W/m² and the ISS PVR
|
|
68
|
+
band from the model, not stored constants.
|
|
69
|
+
- Orbit-dependent radiation (`models/radiation.py`, TID/SEU) feeds the failure rate.
|
|
70
|
+
- RF TT&C margin and optical-downlink weather availability now bind in `compare()`.
|
|
71
|
+
- `launch_case` selector pulls from the launch-cost distribution.
|
|
72
|
+
- Override validation and a solar-array packaging budget (`f_power` can drop below 1).
|
|
73
|
+
|
|
74
|
+
### 3B — real MDAO + transient thermal + visualization
|
|
75
|
+
- Mixed-integer architecture optimization (`pareto_nsga2_mixed`): n_satellites,
|
|
76
|
+
accelerators/sat, altitude, radiator setpoint.
|
|
77
|
+
- Transient orbit thermal (`thermal/transient.py`), behind `thermal_fidelity`.
|
|
78
|
+
- Workload library (space-native vs Earth-dependent) and a duty cycle.
|
|
79
|
+
- New figures: cost waterfall, Monte Carlo fan, orbit timeline, link-budget heatmap;
|
|
80
|
+
`ComparisonResult.monte_carlo()`; dashboard Uncertainty tab.
|
|
81
|
+
|
|
82
|
+
### 3C — UX, reporting, hygiene
|
|
83
|
+
- CLI `doe` / `sobol` / `provenance` / `--version`; friendly scenario-load errors.
|
|
84
|
+
- `evaluate` exported; `list_scenarios()` / `list_catalogs()`; `Evaluation.to_dict()`.
|
|
85
|
+
- HTML/Markdown report export (`reporting.export_report`).
|
|
86
|
+
- `py.typed`, `LICENSE`, this changelog; beginner→advanced notebook ladder.
|
|
87
|
+
|
|
88
|
+
## 0.2.0 — Phase 2
|
|
89
|
+
- Thermal radiator co-design module (`thermal/`).
|
|
90
|
+
- OpenMDAO + pymoo optimization, scipy DOE, SALib Sobol (`mdao/`, `optimize/`).
|
|
91
|
+
- Interactive plotly + Panel dashboard (`viz/`).
|
|
92
|
+
- Environmental CO₂e/water, station-keeping Δv, RF/orbit fidelity, five Earth baselines.
|
|
93
|
+
|
|
94
|
+
## 0.1.0 — Phase 1
|
|
95
|
+
- Discipline models, the delivered-compute waterfall, `compare()` with
|
|
96
|
+
binding-constraint diagnosis and feasibility thresholds, Monte Carlo and
|
|
97
|
+
tornado, matplotlib plots, a CLI, and provenance-tagged catalogs.
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Status: Phases 1–3 complete; Phase 4A landed
|
|
6
|
+
|
|
7
|
+
The Phase 1 thin end-to-end slice is built and passing (ruff + mypy --strict + pytest). The package is `orbitdc` (importable) / `spacedc-mdao` (distribution), under `src/orbitdc/`. Implemented: `core/` (Assumption, schema, scenario loader, units, registry), provenance-tagged `data/` catalogs, the discipline models in `models/`, the delivered-compute waterfall + diagnostics + `compare()` spine, Monte Carlo and tornado in `optimize/`, matplotlib `viz/`, a CLI, and example scenarios + notebooks.
|
|
8
|
+
|
|
9
|
+
**Phase 2A — thermal radiator co-design (`src/orbitdc/thermal/`)** replaced the Tier-0 radiator with a radiator-in-the-loop module: net radiator flux (emission minus absorbed solar/albedo/Earth-IR, EOL coatings), the chip-to-radiator resistance stack that bounds the radiator temperature, a coolant loop whose pump power feeds back as a bus load, a mass build-up, and a bottleneck classifier (chip/coolant/transport/radiator/orientation-limited). It carries catalogs (`coatings`, `coolants`, `chip_stacks`, `radiator_panels`) and validation anchors (ISS PVR/EATCS, Starcloud, NASA high-temp). `compare()` now surfaces T_rad, junction temp, m²/kW, kg/kW, and the bottleneck. See `examples/notebooks/02_radiator_feasibility.ipynb`. No new dependencies. Authoritative source: `background_information/THEMRAL_RADIATOR_DEEPDIVE.md`.
|
|
10
|
+
|
|
11
|
+
**Phase 2B — MDAO + optimization (`src/orbitdc/mdao/`, `src/orbitdc/optimize/`, optional `[mdao]` extra)**: `OrbitDCComponent` wraps `evaluate_space` as an OpenMDAO `ExplicitComponent` (FD partials; `run_model` matches `evaluate_space` exactly); `optimize_single` does constrained gradient-free single-objective optimization (ScipyOptimizeDriver/COBYLA). Multi-objective Pareto is pymoo NSGA-II (`optimize/pareto.py`) called directly on the evaluator. `optimize/doe.py` is a scipy-QMC Latin-hypercube sweep; `optimize/sensitivity.py` adds SALib Sobol indices. Shared design-variable/objective spec in `optimize/design.py`. CLI: `orbitdc optimize <scenario> [--objective lcoc | --pareto lcoc,kg_per_kw]`. Note: the OpenMDAO Pareto driver class is `pymooDriver` (lowercase) with a thin API, so we use pymoo directly. `import orbitdc.mdao` requires the extra; the base package never imports it.
|
|
12
|
+
|
|
13
|
+
**Phase 2C — interactive dashboard (`src/orbitdc/viz/`, optional `[viz]` extra)**: plotly figure builders in `viz/plotly_figures.py` (delivered/cost/mass/power-sankey, tornado, pareto scatter/parcoords, constellation graph, and the thermal panels: area-vs-temperature, net-W/m² waterfall, chip-to-radiator ladder); `viz/provenance.py` enumerates every provenance-tagged catalog value into a table; `viz/dashboard.py` assembles a tabbed Panel app. Run: `uv run panel serve examples/dashboard_app.py --show`. The matplotlib `viz/plots.py` stays in the base install; plotly/panel/networkx are import-on-use.
|
|
14
|
+
|
|
15
|
+
**Phase 2D — fidelity upgrades**: `models/environmental.py` (EQUATIONS §13 — operational/embodied/launch CO₂e and water, normalized per delivered PFLOP-day; wired into `compare()` and the summary, where space shows zero operational water and higher embodied/launch carbon per unit delivered while Earth carries grid carbon + water); station-keeping in `models/orbit.py` (coarse atmospheric density, drag Δv, rocket-equation propellant → launch mass) plus beta-angle eclipse via `sp.beta_deg`; the opensatcom Tier-1 RF backend wired behind a best-effort seam in `models/rf.py` (`fspl_db(..., backend=...)`, falls back to inline); optional Skyfield ground-access in `models/orbit_skyfield.py` (`[orbit]` extra; needs ephemeris, so local/plugin only, not in CI); and four more Earth baselines (`examples/scenarios/earth_*.yaml`: leased colo, renewable+storage, gas-backed, constrained-grid).
|
|
16
|
+
|
|
17
|
+
Phase 2 is complete. Extras: `[mdao]`, `[viz]`, `[orbit]`, `[rf]`. The base install stays numpy/scipy/pydantic/pint/pyyaml/matplotlib.
|
|
18
|
+
|
|
19
|
+
**Phase 3A — credibility & provenance.** Soft cost/mass/embodied factors moved out of `compare.py`/`environmental.py` into provenance-tagged catalogs (`data/cost_structure.yaml`, `mass_structure.yaml`, `embodied_factors.yaml`); the duplicated YAML loaders are unified in `core/catalog_loader.py` (note: write YAML numbers as plain decimals — `2000000.0`, not `2.0e6`, which PyYAML parses as a string). `tests/test_published_cases.py` recovers Starcloud's ~633 W/m² and the ISS PVR band from the model, not stored constants. `models/radiation.py` + `data/radiation_env.yaml` add an orbit-dependent TID/SEU failure-rate contribution (accelerators carry `tid_tolerance_krad`/`seu_susceptibility`/`ecc_mitigation`), added to the base `annual_failure_rate`. RF TT&C margin and optical-downlink weather availability (`data/comms.yaml`, `Architecture.downlink_type`) now bind in `compare()` — optical availability multiplies `f_network`. A `launch_case` selector (current/pessimistic/aggressive/speculative) pulls from the `launch.yaml` distribution. `evaluate_space` validates overrides (finite, non-negative) and applies a solar-array packaging budget (`Architecture.solar_area_m2_per_sat`) so `f_power` can drop below 1. **Phase 3B — real MDAO + transient thermal + missing viz.** `evaluate_space` accepts architecture overrides (`n_satellites`, `accelerators_per_satellite`, `altitude_km`, `radiator_t_rad_setpoint_k`); `optimize/design.py` adds `DISCRETE_VARS`; `optimize/pareto.py` `pareto_nsga2_mixed` runs pymoo mixed Integer/Real NSGA-II over the architecture. `thermal/transient.py` integrates panel temperature over the sunlit/eclipse cycle (behind `SpaceParams.thermal_fidelity="transient"`, which orbit-averages and relaxes the worst-case `f_thermal`); steady is the default. `data/workloads.yaml` + `Workload.workload_type` supply comm intensity (llm_inference/training/earth_observation/edge — the space-native vs Earth-dependent split; training is hopelessly comms-bound); `SpaceParams.duty_cycle_fraction` sizes power+thermal for a bursty average. New plotly figures: `cost_waterfall` (true waterfall), `monte_carlo_fan`, `orbit_timeline` (from `compare.scenario_transient`), `link_budget_heatmap`; `ComparisonResult.monte_carlo()` convenience; dashboard gained an Uncertainty tab (4 tabs).
|
|
20
|
+
|
|
21
|
+
**Phase 3C — UX, reporting, hygiene.** CLI gained `provenance`, `doe`, `sobol`, and `--version`, plus friendly scenario-load errors (`cli._load`). `Evaluation.to_dict()`/`to_json()`; `list_catalogs()` and `export_report` exported from the package root. `reporting.py` writes a shareable HTML (plotly figures + narrative) or Markdown report with git commit + timestamp + scenario. Added `py.typed`, `LICENSE`, `CHANGELOG.md`; version bumped to **0.3.0**; CI gained an editable-install loop guard (the flakiness was uv skipping the editable rebuild when the version was unchanged — `--reinstall-package spacedc-mdao` forces it). Notebook ladder: `00_quick_start`, `03_pareto_exploration`, `04_monte_carlo_uncertainty` (+ existing 01/02).
|
|
22
|
+
|
|
23
|
+
Phase 3 is complete. The package is a credible, provenance-driven, optimizable exploration environment. Extras: `[mdao]`, `[viz]`, `[orbit]`, `[rf]`.
|
|
24
|
+
|
|
25
|
+
**Phase 4A — credibility & validation.** The HBM limit is wired in: `thermal/network.max_radiator_temp_k` now uses the tighter of the junction and HBM limits, so the demo H100 is **HBM-limited** (radiator runs cooler at ~312 K, thermal mass up to ~18 kg/kW); `thermal/diagnosis` has an `hbm-limited` label. Crosslink bandwidth is **derived** from formation geometry via `models/comms_link.crosslink_capacity` (modem-capped, photon-limited at long range — reproduces Suncatcher's ~12.8 Tbps per aperture); `Architecture.formation_separation_m` drives it, the scalar `crosslink_gbps` is now an explicit override, and crosslink folds into the network factor. `tests/test_references.py` reproduces Suncatcher (crosslink, <$200/kg launch) and McCalip (orbital several× costlier) from the model. `calibrate.fit_parameter` (scipy least-squares → provenance-tagged `Assumption`) is the Tier-4 entry point. `logging` + `orbitdc --verbose` trace intermediate values.
|
|
26
|
+
|
|
27
|
+
**Phase 4B — breadth of trade studies.** `data/accelerators.yaml` now has five entries with cited specs, adding **AMD MI300X** (1300 dense FP16 TFLOPS, 750 W, 192 GB HBM3) and **Google TPU v5e** (197 bf16 TFLOPS, 16 GB); catalog variety added across launch (`current_heavy_lift` ~$1500/kg), batteries (`li_ion_high_energy` 250 Wh/kg), solar (`flexible_rosa` 150 W/kg), and radiators (`composite_deployable` 4 kg/m²). `models/cost.py` gained a Wright's-law learning curve (`learning_multiplier(quantity, rate)`, `unit_cost ∝ n^log2(rate)`) applied to accelerator and bus costs, plus a TRL premium (`trl_multiplier`); `data/cost_structure.yaml` carries `learning_rate` (default 1.0 = off) and `bus_trl` (default 9). `learning_rate` is an `evaluate_space` override and a tornado/Sobol driver. `optimize/robust.py`: `batch_compare(space, earths)` returns a verdict matrix (space LCOC is Earth-independent, so robustness reduces to beating the cheapest baseline), `robust_optimize` minimizes space LCOC and counts baselines beaten; CLI `orbitdc robust <space> <earth...>`.
|
|
28
|
+
|
|
29
|
+
**Phase 4C — deepen physics (all opt-in; defaults unchanged).** Five parametric-fidelity additions, each behind a flag so the default evaluation is identical. (1) **Formation dynamics** (`models/formation.py`): Clohessy-Wiltshire mean motion, differential-drag drift cancellation, and a collision-avoidance margin (separation / nav uncertainty) that triggers conjunction maneuvers; folds into station-keeping Δv, and `formation_separation_m` is now an override (so the 4A crosslink and 4C keeping/risk share one knob — tighter = more bandwidth, lower margin). (2) **Thermal Level 4** (`thermal/view_factors.py`): an effective view factor from articulation/self-view/solar-array blocking that derates emission, behind `SpaceParams.thermal_view_factors`. (3) **Thermal Level 5** (`thermal/degradation.py`): a mission-integrated coating trajectory + MMOD area loss + single-loop-out derate on `f_thermal`, behind `thermal_degradation`. (4) **Skyfield orbit** (`models/orbit_skyfield.py` wired into `evaluate_space`): ground-station access fraction (SGP4) refines optical-downlink availability behind `orbit_fidelity="skyfield"` + the `[orbit]` extra, with a logged graceful fallback to closed-form on any failure (a few-station optical architecture shows ~4% access → LCOC explodes, the honest result). (5) **Graceful degradation** (`reliability.fleet_health_curve`): a time-stepped fleet-capacity sawtooth with launch-quantized resupply, exposed as `Evaluation.availability_curve`, behind `graceful_degradation` (+ `resupply_interval_years`).
|
|
30
|
+
|
|
31
|
+
**Phase 4D — documentation site.** MkDocs Material under `docs/` (`mkdocs.yml`, new `[docs]` extra: mkdocs, mkdocs-material, mkdocstrings[python]). Pages: home, quick start, the three user tiers, model architecture, the governing equations (embedded from `background_information/EQUATIONS.md` via a pymdownx snippet), an mkdocstrings API reference, and an assumptions/provenance page **generated at build time** by the `docs/gen_provenance.py` MkDocs hook (writes `docs/provenance.md`, gitignored, from `collect_provenance()`). Build: `uv run --no-sync python -m mkdocs build --strict` (invoke via `python -m mkdocs`, not the bare `mkdocs` shim, or it resolves the global pyenv install). CI has a `docs` job (strict build) + a `deploy-docs` job (GitHub Pages on `main`); README links the site.
|
|
32
|
+
|
|
33
|
+
**Phase 4E — PyPI release.** Version bumped to **0.4.0** (pyproject + `__init__`). The wheel ships `py.typed` + the 15 data catalogs (`uv build` → `twine check` passes; a clean-venv install imports `orbitdc`, runs the CLI). `.github/workflows/release.yml` publishes on a `v*` tag via **PyPI Trusted Publishing** (OIDC, no stored token). **One-time admin the maintainer must do before the first tag:** (1) configure a Trusted Publisher on PyPI (owner `jman4162`, repo `spacedc-mdao`, workflow `release.yml`, environment `pypi`) — can be a "pending" publisher so the first publish creates the project; (2) create a GitHub Environment named `pypi`. Then bump the version, tag `vX.Y.Z`, and push the tag. **Phase 4 is complete.**
|
|
34
|
+
|
|
35
|
+
Key reference docs:
|
|
36
|
+
|
|
37
|
+
- `SPEC.md` — the design contract: package concept, model families, full target layout, and MVP scope.
|
|
38
|
+
- `background_information/EQUATIONS.md` — the equation map behind every model, in GitHub-rendered `$$` LaTeX. The v0.1 minimum equation set per discipline is §15; what to avoid early is §16. Each `models/` module cites its section. (Reference docs live in `background_information/`; the arXiv PDF and `AI_WRITING_SLOP_Guide.md` are gitignored and stay local.)
|
|
39
|
+
- `2511.19468v1.pdf` — reference orbital-data-center feasibility paper (arXiv:2511.19468). Excluded from git (see `.gitignore`); cite by ID.
|
|
40
|
+
- The approved Phase 1 plan: `~/.claude/plans/please-make-an-implementation-rustling-puddle.md`.
|
|
41
|
+
|
|
42
|
+
Note the layout differs slightly from the SPEC's aspirational tree: Phase 1 keeps power/thermal sizing inside the discipline models, sizes power/thermal to load (so the feasibility pressure surfaces as mass, cost, radiator-packaging ratio, and network throttling rather than an `f_power` < 1), and defers the `mdao/` and `formation/environmental` modules.
|
|
43
|
+
|
|
44
|
+
## What this package is
|
|
45
|
+
|
|
46
|
+
`spacedc-mdao`: an open-source Python package for **multidisciplinary design analysis and optimization (MDAO) of orbital compute infrastructure**, with comparable terrestrial data-center baselines. (The spec also floats `orbitdc` as the importable package name; the example code uses `import orbitdc as odc`.)
|
|
47
|
+
|
|
48
|
+
### The one principle that governs every model
|
|
49
|
+
|
|
50
|
+
**Optimize delivered useful compute-years, not nominal watts or nominal GPUs.** Every model exists to take installed/nominal capacity and degrade it through real constraints. The central artifact is the **delivered-compute waterfall**:
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
installed compute
|
|
54
|
+
→ thermally allowable compute
|
|
55
|
+
→ power-available compute
|
|
56
|
+
→ network-limited compute
|
|
57
|
+
→ reliability-adjusted compute
|
|
58
|
+
→ utilization-adjusted delivered compute
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Equivalently (per `EQUATIONS.md` §1), `C_delivered = C_peak · f_power · f_thermal · f_network · f_availability · f_utilization · f_software` — each factor is a model that multiplies installed capacity down. And the same chain drives cost: useful compute → power → heat → radiator area → mass → launch cost → lifetime delivered compute. Power closure does **not** imply thermal closure; never silently assume all IT power can be rejected.
|
|
62
|
+
|
|
63
|
+
The package's job is **not** to prove space data centers are viable. It is to make the feasibility boundary visible — to report **binding constraints and sensitivity**, so a user can see *which* uncertain assumptions (launch $/kg, satellite $/W, solar W/kg, radiator kg/kW, utilization, communication intensity, failure rate, mission life) are doing the work. Be skeptical by default. Prefer diagnostics like "space does not close because radiator area exceeds packaging by 38%" over a single headline cost number.
|
|
64
|
+
|
|
65
|
+
## Architectural shape (from SPEC.md)
|
|
66
|
+
|
|
67
|
+
Three user levels, layered on shared models:
|
|
68
|
+
- **Beginner:** YAML scenarios, built-in assumptions, calculator notebooks, Pareto plots, "why did this design fail?" diagnostics.
|
|
69
|
+
- **Power-user:** Python API with swappable models, Monte Carlo, sensitivity, custom optimizers.
|
|
70
|
+
- **Advanced MDAO:** derivative-aware OpenMDAO components, coupled solves, constrained optimization, surrogates, high-fidelity plugin hooks.
|
|
71
|
+
|
|
72
|
+
Planned source layout (target; create as needed):
|
|
73
|
+
```
|
|
74
|
+
core/ units, schema, scenario, registry, assumptions
|
|
75
|
+
data/ catalogs: accelerators, launch, solar_arrays, batteries, radiators,
|
|
76
|
+
antennas, optical_terminals, earth_datacenters, cost_indices
|
|
77
|
+
models/ compute, power, thermal, orbit, formation, rf, lasercom,
|
|
78
|
+
reliability, cost, earth_baseline, environmental
|
|
79
|
+
mdao/ openmdao_components, drivers, constraints, objectives
|
|
80
|
+
optimize/ doe, pareto, uncertainty, sensitivity, surrogate
|
|
81
|
+
viz/ dashboard, pareto, sankey, thermal, orbit3d, constellation_graph,
|
|
82
|
+
link_budget, cost_waterfall
|
|
83
|
+
examples/ notebooks/, scenarios/
|
|
84
|
+
cli.py
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Two cross-cutting conventions that must hold across all models:
|
|
88
|
+
1. **Model tiers (Tier 0–4).** Default fidelity is **Tier 1** (engineering trade studies). Tier 0 (scalar calculators) is "too easy to misuse"; Tier 3 (high-fidelity external plugins) is too slow for broad sweeps. Each physical model should offer tiered implementations behind a common interface, with plugins optional, never mandatory.
|
|
89
|
+
2. **Assumption provenance.** Every default number must carry source, date, confidence, and a flag for empirical / vendor-stated / estimated / speculative. This feeds the assumption-provenance viz and is a first-class requirement, not a nicety. Do **not** bake in single magic numbers for sensitive inputs (especially launch $/kg) — treat them as scenario distributions (pessimistic / current / aggressive / speculative).
|
|
90
|
+
|
|
91
|
+
## Tech stack
|
|
92
|
+
|
|
93
|
+
Phase 1 (current) is deliberately dependency-light. The fuller stack below is the eventual target, phased in as fidelity grows. See the approved plan at `~/.claude/plans/please-make-an-implementation-rustling-puddle.md` for the Phase 1 scope and rationale.
|
|
94
|
+
|
|
95
|
+
Phase 1 (in use now):
|
|
96
|
+
- `pydantic` v2 for validated input schemas and the `Assumption` provenance type.
|
|
97
|
+
- `pint` for units **at the I/O boundary only**; model math runs on plain SI floats (documented in names/docstrings) to stay fast and mypy-clean.
|
|
98
|
+
- `numpy` / `scipy` for analysis; `pyyaml` for scenarios; `matplotlib` for the Phase 1 static plots (waterfall, cost waterfall, tornado).
|
|
99
|
+
- `pytest` with **golden-value regression tests** — every physics/cost model ships with a hand-checkable fixture. This is a hard requirement, not optional.
|
|
100
|
+
- Optional `[rf]` extra: **`opensatcom`** (John's MIT satcom library) as the Tier-1 RF link-budget backend; `rf.py` falls back to inline Friis/FSPL when it is not installed.
|
|
101
|
+
|
|
102
|
+
Deferred to later phases (do not pull in for Phase 1):
|
|
103
|
+
- **OpenMDAO** — the eventual MDAO backbone (Tier 2 coupled solves). Keep model functions pure/side-effect-free so they wrap cleanly as `ExplicitComponent`s later. Do *not* hand-roll an optimizer framework when this lands.
|
|
104
|
+
- `gpkit` (convex/GP trade studies, only where physics is cleanly monomial/posynomial); the interactive viz stack (`plotly` / `altair` / `pyvista` / `networkx` / `panel`); `SALib` for Sobol sensitivity; `pandas` / `polars`.
|
|
105
|
+
- Orbital-mechanics library: **`poliastro` is archived/unmaintained (since Oct 2023) — do not adopt it.** Phase 1 uses closed-form orbit math (period, circular velocity, cylindrical-shadow eclipse fraction). If a library is later needed, prefer the maintained fork **`hapsira`** or `astropy` + `sgp4`.
|
|
106
|
+
|
|
107
|
+
## MVP scope — build this first, in this spirit
|
|
108
|
+
|
|
109
|
+
Terrestrial baseline (PUE/WUE/energy price/capex/utilization) + orbital scalar model (launch $/kg, satellite $/W, W/kg, life, failure rate, utilization) + solar/radiator/battery sizing + simple RF and optical link budgets + accelerator catalog (H100, AMD MI300X, Google TPU v5e, TPU-like, generic ASIC) + Monte Carlo & tornado sensitivity + Pareto dashboard + assumption provenance.
|
|
110
|
+
|
|
111
|
+
**Explicitly out of MVP:** formation-flying dynamics, detailed radiation transport, full thermal FEM. The MVP wins by making first-order physics and economics impossible to hand-wave — not by depth in any one discipline.
|
|
112
|
+
|
|
113
|
+
Terrestrial baselines must use best-in-class hyperscale numbers (e.g. PUE ~1.08–1.10), never a strawman PUE 1.5 facility.
|
|
114
|
+
|
|
115
|
+
## Target user-facing API (the shape to build toward)
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
import orbitdc as odc
|
|
119
|
+
space = odc.scenarios.load("orbital_1mw_inference.yaml")
|
|
120
|
+
earth = odc.scenarios.load("earth_hyperscale_baseline.yaml")
|
|
121
|
+
result = odc.compare(space, earth)
|
|
122
|
+
result.summary()
|
|
123
|
+
result.plot_cost_waterfall()
|
|
124
|
+
result.plot_delivered_compute_waterfall()
|
|
125
|
+
result.explain_binding_constraints()
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Commands
|
|
129
|
+
|
|
130
|
+
The project uses `uv` for environment and dependency management.
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
uv sync --extra dev --extra mdao # create venv + install package with extras (add --extra rf as needed)
|
|
134
|
+
uv run ruff check . # lint
|
|
135
|
+
uv run ruff format --check . # formatting check (drop --check to apply)
|
|
136
|
+
uv run mypy src # type-check (strict)
|
|
137
|
+
uv run pytest # run the test suite
|
|
138
|
+
uv run pytest tests/test_orbit.py -k eclipse # run a single test
|
|
139
|
+
uv run python -m orbitdc compare examples/scenarios/orbital_1mw_inference.yaml examples/scenarios/earth_hyperscale_baseline.yaml
|
|
140
|
+
uv run orbitdc optimize examples/scenarios/orbital_1mw_inference.yaml --pareto lcoc,kg_per_kw # needs [mdao]
|
|
141
|
+
uv run orbitdc robust examples/scenarios/orbital_1mw_inference.yaml examples/scenarios/earth_*.yaml # space vs every Earth baseline
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**Code-quality gate:** all code must pass `ruff check`, `ruff format`, and `mypy --strict` (configured over `src/`) before commit. CI (`.github/workflows/ci.yml`) enforces ruff + mypy + pytest; do not commit changes that break them.
|
|
145
|
+
|
|
146
|
+
## Writing style — avoid AI slop
|
|
147
|
+
|
|
148
|
+
These rules apply to everything we publish: README, docs, docstrings, code comments, commit/PR messages, `SPEC.md`/`EQUATIONS.md` prose, and any papers. They are distilled from Wikipedia's "Signs of AI writing" (<https://en.wikipedia.org/wiki/Wikipedia:Signs_of_AI_writing>). The goal is plain, specific, falsifiable technical writing.
|
|
149
|
+
|
|
150
|
+
Do not write:
|
|
151
|
+
- **Significance inflation / puffery:** "stands as a testament", "plays a pivotal/vital/crucial role", "marks a turning point", "evolving landscape", "rich tapestry", "groundbreaking", "renowned", "seamless", "robust" (as filler), "boasts" (meaning "has").
|
|
152
|
+
- **Trailing "-ing" significance clauses:** "…, highlighting its importance", "…, reflecting broader trends", "…, underscoring the need for…", "…, showcasing…". Delete them or state the concrete consequence.
|
|
153
|
+
- **Vague attribution / weasel sourcing:** "experts argue", "studies show", "it is widely regarded", "industry reports suggest". Cite a specific source (with a number or link) or drop the claim.
|
|
154
|
+
- **Boilerplate "Challenges / Future Outlook / Despite its … faces several challenges" sections.** State concrete limitations with numbers instead.
|
|
155
|
+
- **Negative-parallelism filler:** "not just X, but Y", "it's not merely X — it's Y". Compulsive rule-of-three triads. Elegant variation (call the same thing by the same name every time; don't swap synonyms for variety).
|
|
156
|
+
- **The AI-vocab cluster:** *additionally* (as a sentence-opener), *crucial, delve, leverage, underscore, intricate, testament, tapestry, foster, meticulous, comprehensive, pivotal, vibrant, garner, bolster*.
|
|
157
|
+
|
|
158
|
+
Formatting:
|
|
159
|
+
- Sentence-case headings, not Title Case. Use boldface sparingly. Straight quotes, no decorative em-dash runs, no emoji. Standard Markdown only.
|
|
160
|
+
- Plain "X is Y" copula sentences are good — don't contort to avoid "is"/"are".
|
|
161
|
+
|
|
162
|
+
Default to concrete, specific statements with numbers and a source. When a number is uncertain, say so and tag it (the `Assumption` provenance type — source, date, confidence, kind — is the structural antidote to slop; see below). When you don't know, say so plainly rather than generating confident filler.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 John Hodge
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: spacedc-mdao
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: Multidisciplinary design analysis and optimization of orbital compute infrastructure, with terrestrial data-center baselines.
|
|
5
|
+
Project-URL: Repository, https://github.com/jman4162/spacedc-mdao
|
|
6
|
+
Project-URL: Documentation, https://jman4162.github.io/spacedc-mdao/
|
|
7
|
+
Project-URL: Changelog, https://github.com/jman4162/spacedc-mdao/blob/main/CHANGELOG.md
|
|
8
|
+
Author: John Hodge
|
|
9
|
+
License: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: compute,data-center,mdao,orbital,space,trade-study
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Science/Research
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering
|
|
19
|
+
Classifier: Typing :: Typed
|
|
20
|
+
Requires-Python: >=3.11
|
|
21
|
+
Requires-Dist: matplotlib>=3.7
|
|
22
|
+
Requires-Dist: numpy>=1.24
|
|
23
|
+
Requires-Dist: pint>=0.23
|
|
24
|
+
Requires-Dist: pydantic>=2.0
|
|
25
|
+
Requires-Dist: pyyaml>=6.0
|
|
26
|
+
Requires-Dist: scipy>=1.10
|
|
27
|
+
Provides-Extra: dev
|
|
28
|
+
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
29
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
30
|
+
Requires-Dist: ruff>=0.6; extra == 'dev'
|
|
31
|
+
Requires-Dist: types-pyyaml>=6.0; extra == 'dev'
|
|
32
|
+
Provides-Extra: docs
|
|
33
|
+
Requires-Dist: mkdocs-material>=9.5; extra == 'docs'
|
|
34
|
+
Requires-Dist: mkdocs>=1.6; extra == 'docs'
|
|
35
|
+
Requires-Dist: mkdocstrings[python]>=0.25; extra == 'docs'
|
|
36
|
+
Provides-Extra: mdao
|
|
37
|
+
Requires-Dist: openmdao>=3.44; extra == 'mdao'
|
|
38
|
+
Requires-Dist: pymoo>=0.6; extra == 'mdao'
|
|
39
|
+
Requires-Dist: salib>=1.5; extra == 'mdao'
|
|
40
|
+
Provides-Extra: orbit
|
|
41
|
+
Requires-Dist: skyfield>=1.54; extra == 'orbit'
|
|
42
|
+
Provides-Extra: rf
|
|
43
|
+
Requires-Dist: opensatcom>=0.4.0; extra == 'rf'
|
|
44
|
+
Provides-Extra: viz
|
|
45
|
+
Requires-Dist: networkx>=3; extra == 'viz'
|
|
46
|
+
Requires-Dist: panel>=1.9; extra == 'viz'
|
|
47
|
+
Requires-Dist: plotly>=6; extra == 'viz'
|
|
48
|
+
Description-Content-Type: text/markdown
|
|
49
|
+
|
|
50
|
+
# spacedc-mdao
|
|
51
|
+
|
|
52
|
+
A Python package for multidisciplinary design analysis and optimization (MDAO) of orbital compute infrastructure, with terrestrial data-center baselines for comparison.
|
|
53
|
+
|
|
54
|
+
The package optimizes **delivered useful compute**, not nominal watts or nominal GPUs. It takes installed capacity and degrades it through power, thermal, network, reliability, and utilization limits, then reports where a design fails and which assumptions decide the outcome. Its job is to make the feasibility boundary visible, not to argue that space wins.
|
|
55
|
+
|
|
56
|
+
**Documentation:** <https://jman4162.github.io/spacedc-mdao/> (quick start, user tiers, model architecture, API reference, and a generated assumptions/provenance table). See `SPEC.md` for the design contract and `background_information/EQUATIONS.md` for the governing equations.
|
|
57
|
+
|
|
58
|
+
## Status
|
|
59
|
+
|
|
60
|
+
Phases 1 and 2 are complete. Implemented:
|
|
61
|
+
|
|
62
|
+
- **Core (Phase 1):** scenario loading, the discipline models in the v0.1 minimum set (`background_information/EQUATIONS.md` §15), the delivered-compute waterfall, an Earth-vs-space comparison with binding-constraint diagnosis and feasibility thresholds, Monte Carlo and tornado sensitivity, matplotlib plots, and a CLI.
|
|
63
|
+
- **Thermal radiator co-design (2A):** a `thermal/` module coupling chip power → junction temperature → coolant loop → radiator temperature → area → mass, with net radiator flux (emission minus absorbed solar/albedo/Earth-IR at end-of-life coatings), a bottleneck classifier, and validation anchors (ISS PVR/EATCS, Starcloud, NASA high-temp). The radiator temperature is bounded by the chip stack; closure is checked at end of life.
|
|
64
|
+
- **MDAO + optimization (2B):** OpenMDAO components wrap the evaluator (FD partials), `optimize_single` for constrained single-objective optimization, pymoo NSGA-II Pareto fronts, a scipy Latin-hypercube DOE, and SALib Sobol indices.
|
|
65
|
+
- **Interactive dashboard (2C):** plotly figures (delivered/cost/mass/power-sankey, tornado, Pareto, constellation graph, thermal panels) and a Panel app, plus an assumption-provenance table.
|
|
66
|
+
- **Fidelity (2D):** environmental CO₂e/water accounting, station-keeping Δv and propellant, beta-angle eclipse, an optional Skyfield ground-access seam, and five Earth baselines.
|
|
67
|
+
- **Credibility (3A):** all soft factors moved to provenance-tagged catalogs; Starcloud/ISS recovered from the model; orbit-dependent radiation (TID/SEU); RF margin and optical weather availability bind; launch-cost cases; input validation.
|
|
68
|
+
- **Real MDAO (3B):** mixed-integer architecture optimization (satellites, accelerators/sat, altitude); transient orbit thermal; a workload library (space-native vs Earth-dependent); uncertainty fan / orbit-timeline / link-budget-heatmap figures.
|
|
69
|
+
- **UX (3C):** CLI `provenance`/`doe`/`sobol`/`--version`, HTML/Markdown report export, `Evaluation.to_dict()`, and a beginner→advanced notebook ladder.
|
|
70
|
+
|
|
71
|
+
The package is skeptical by default. For the bundled 1 MW inference scenario, Earth wins on levelized cost: the orbital design is downlink-limited, its radiators are a multi-tonne burden (chip-limited temperature), and station-keeping plus replacement add up.
|
|
72
|
+
|
|
73
|
+
## Install
|
|
74
|
+
|
|
75
|
+
`spacedc-mdao` uses `uv`. The base install is light; capabilities live behind extras.
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
uv sync # base (numpy/scipy/pydantic/pint/matplotlib)
|
|
79
|
+
uv sync --extra dev --extra mdao --extra viz # development + optimization + dashboard
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
| Extra | Pulls in | Enables |
|
|
83
|
+
| -------- | --------------------------------- | -------------------------------------------------- |
|
|
84
|
+
| `mdao` | openmdao, pymoo, SALib | optimization, Pareto fronts, DOE, Sobol |
|
|
85
|
+
| `viz` | plotly, panel, networkx | interactive figures + dashboard |
|
|
86
|
+
| `orbit` | skyfield | ground-station access windows (needs ephemeris) |
|
|
87
|
+
| `rf` | [opensatcom](https://github.com/jman4162/opensatcom) | Tier-1 RF link-budget backend (else inline Friis/FSPL) |
|
|
88
|
+
|
|
89
|
+
## Use
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
import orbitdc as odc
|
|
93
|
+
|
|
94
|
+
space = odc.load_scenario("examples/scenarios/orbital_1mw_inference.yaml")
|
|
95
|
+
earth = odc.load_scenario("examples/scenarios/earth_hyperscale_baseline.yaml")
|
|
96
|
+
|
|
97
|
+
result = odc.compare(space, earth)
|
|
98
|
+
print(result.summary())
|
|
99
|
+
print(result.explain_binding_constraints())
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
From the command line:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
orbitdc compare examples/scenarios/orbital_1mw_inference.yaml examples/scenarios/earth_hyperscale_baseline.yaml
|
|
106
|
+
orbitdc optimize examples/scenarios/orbital_1mw_inference.yaml --pareto lcoc,kg_per_kw # needs [mdao]
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Notebooks: `examples/notebooks/01_compare.ipynb` (Earth-vs-space) and `examples/notebooks/02_radiator_feasibility.ipynb` (how big and heavy the radiators must be). Dashboard: `uv run panel serve examples/dashboard_app.py --show` (needs `[viz]`).
|
|
110
|
+
|
|
111
|
+
## Development
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
uv run ruff check . && uv run ruff format --check .
|
|
115
|
+
uv run mypy src
|
|
116
|
+
uv run pytest
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
All code must pass ruff, `ruff format`, and `mypy --strict` before commit. CI enforces this. Every default number in the catalogs carries provenance (source, date, confidence, kind); see `background_information/THEMRAL_RADIATOR_DEEPDIVE.md` for the thermal modeling background.
|
|
120
|
+
|
|
121
|
+
## License
|
|
122
|
+
|
|
123
|
+
MIT.
|