prometheus-equilibrium 0.1.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.
- prometheus_equilibrium-0.1.0/.claude/settings.local.json +10 -0
- prometheus_equilibrium-0.1.0/.github/CODEOWNERS +5 -0
- prometheus_equilibrium-0.1.0/.github/workflows/ci.yml +30 -0
- prometheus_equilibrium-0.1.0/.github/workflows/python-publish-testpypi.yml +95 -0
- prometheus_equilibrium-0.1.0/.github/workflows/python-publish.yml +93 -0
- prometheus_equilibrium-0.1.0/.gitignore +168 -0
- prometheus_equilibrium-0.1.0/.gitmodules +6 -0
- prometheus_equilibrium-0.1.0/.pre-commit-config.yaml +12 -0
- prometheus_equilibrium-0.1.0/.readthedocs.yaml +17 -0
- prometheus_equilibrium-0.1.0/CLAUDE.md +159 -0
- prometheus_equilibrium-0.1.0/LICENSE.txt +674 -0
- prometheus_equilibrium-0.1.0/PKG-INFO +269 -0
- prometheus_equilibrium-0.1.0/README.md +239 -0
- prometheus_equilibrium-0.1.0/demonstration.ipynb +374 -0
- prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.core.constants.rst +6 -0
- prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.core.rst +12 -0
- prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.equilibrium.element_matrix.rst +12 -0
- prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.equilibrium.mixture.rst +12 -0
- prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.equilibrium.performance.rst +13 -0
- prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.equilibrium.problem.rst +13 -0
- prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.equilibrium.rst +19 -0
- prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.equilibrium.solution.rst +4 -0
- prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.equilibrium.solver.rst +15 -0
- prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.equilibrium.species.rst +20 -0
- prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.propellants.loader.rst +4 -0
- prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.propellants.rst +13 -0
- prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.rst +15 -0
- prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.thermo_data.compiler.rst +12 -0
- prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.thermo_data.parsers.burcat.rst +13 -0
- prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.thermo_data.parsers.cea.rst +12 -0
- prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.thermo_data.parsers.janaf.rst +12 -0
- prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.thermo_data.parsers.rst +16 -0
- prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.thermo_data.parsers.shomate.rst +12 -0
- prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.thermo_data.parsers.terra.rst +12 -0
- prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.thermo_data.rst +13 -0
- prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.tools.build_all_thermo.rst +13 -0
- prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.tools.build_db.rst +12 -0
- prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.tools.build_legacy_thermo.rst +15 -0
- prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.tools.build_propellants.rst +21 -0
- prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.tools.compare_databases.rst +13 -0
- prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.tools.rst +16 -0
- prometheus_equilibrium-0.1.0/docs/conf.py +96 -0
- prometheus_equilibrium-0.1.0/docs/index.rst +66 -0
- prometheus_equilibrium-0.1.0/docs/requirements.txt +2 -0
- prometheus_equilibrium-0.1.0/docs/solver_comparison.rst +300 -0
- prometheus_equilibrium-0.1.0/docs/thermo/index.rst +8 -0
- prometheus_equilibrium-0.1.0/docs/thermo/terra_integration.rst +115 -0
- prometheus_equilibrium-0.1.0/docs/thermo/thermo_database_guide.rst +135 -0
- prometheus_equilibrium-0.1.0/memory/MEMORY.md +4 -0
- prometheus_equilibrium-0.1.0/memory/feedback_schema_versioning.md +11 -0
- prometheus_equilibrium-0.1.0/papers/NASA-RP-1311.pdf +0 -0
- prometheus_equilibrium-0.1.0/papers/NASApolynomial.pdf +0 -0
- prometheus_equilibrium-0.1.0/papers/PEP.pdf +0 -0
- prometheus_equilibrium-0.1.0/papers/PEP_Extracted.txt +7054 -0
- prometheus_equilibrium-0.1.0/papers/TERRA_user_guide.pdf +0 -0
- prometheus_equilibrium-0.1.0/papers/burcat_intro.pdf +0 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/__init__.py +62 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/core/__init__.py +0 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/core/constants.py +144 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/equilibrium/__init__.py +95 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/equilibrium/_thermo_kernels.py +418 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/equilibrium/element_matrix.py +411 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/equilibrium/mixture.py +388 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/equilibrium/performance.py +587 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/equilibrium/problem.py +330 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/equilibrium/solution.py +327 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/equilibrium/solver.py +2852 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/equilibrium/species.py +2270 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/gui/__init__.py +1 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/gui/__main__.py +6 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/gui/app.py +84 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/gui/dialogs/__init__.py +0 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/gui/dialogs/add_propellant.py +75 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/gui/dialogs/database_search.py +45 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/gui/engine.py +743 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/gui/main_window.py +250 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/gui/pages/__init__.py +0 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/gui/pages/analysis.py +255 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/gui/pages/library.py +298 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/gui/pages/simulator.py +596 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/gui/widgets/__init__.py +0 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/gui/widgets/graph_canvas.py +21 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/propellants/PEPCODED.DAF +1158 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/propellants/__init__.py +37 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/propellants/loader.py +426 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/propellants/propellants.toml +9712 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/__init__.py +0 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/afcesic.json +40501 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/compiler.py +606 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/janaf.csv +84025 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/nasa7.json +116337 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/nasa9.json +277856 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/parsers/__init__.py +32 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/parsers/_common.py +542 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/parsers/afcesic.py +391 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/parsers/burcat.py +405 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/parsers/cea.py +184 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/parsers/janaf.py +161 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/parsers/shomate.py +187 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/parsers/terra.py +384 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/raw/ALLPROP.DAT +0 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/raw/JANAF.jnf +89278 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/raw/THERGG.DAT +0 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/raw/THERII.DAT +0 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/raw/THERSS.DAT +0 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/raw/burcat7.thr +13568 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/raw/burcat9.thr +26392 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/raw/cea_thermo.inp +15802 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/raw/terra.bas +0 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/raw/terra_a.bas +0 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/shomate.json +14 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/terra.json +85381 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/tools/__init__.py +0 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/tools/build_all_thermo.py +133 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/tools/build_db.py +285 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/tools/build_legacy_thermo.py +326 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/tools/build_propellants.py +381 -0
- prometheus_equilibrium-0.1.0/prometheus_equilibrium/tools/compare_databases.py +102 -0
- prometheus_equilibrium-0.1.0/pyproject.toml +86 -0
- prometheus_equilibrium-0.1.0/tests/benchmark.py +626 -0
- prometheus_equilibrium-0.1.0/tests/benchmark_db.py +684 -0
- prometheus_equilibrium-0.1.0/tests/test_build_propellants_tool.py +65 -0
- prometheus_equilibrium-0.1.0/tests/test_element_matrix.py +245 -0
- prometheus_equilibrium-0.1.0/tests/test_mixture.py +160 -0
- prometheus_equilibrium-0.1.0/tests/test_performance.py +54 -0
- prometheus_equilibrium-0.1.0/tests/test_problem.py +294 -0
- prometheus_equilibrium-0.1.0/tests/test_propellants.py +418 -0
- prometheus_equilibrium-0.1.0/tests/test_solution.py +249 -0
- prometheus_equilibrium-0.1.0/tests/test_solver_gmcb.py +659 -0
- prometheus_equilibrium-0.1.0/tests/test_solver_pep.py +265 -0
- prometheus_equilibrium-0.1.0/tests/test_species.py +312 -0
- prometheus_equilibrium-0.1.0/uv.lock +2085 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
lint:
|
|
11
|
+
name: Lint (black + isort)
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v5
|
|
15
|
+
- uses: astral-sh/setup-uv@v5
|
|
16
|
+
with:
|
|
17
|
+
python-version: "3.12"
|
|
18
|
+
- run: uv sync --group dev
|
|
19
|
+
- run: uv run pre-commit run --all-files
|
|
20
|
+
|
|
21
|
+
test:
|
|
22
|
+
name: Tests
|
|
23
|
+
runs-on: ubuntu-latest
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v5
|
|
26
|
+
- uses: astral-sh/setup-uv@v5
|
|
27
|
+
with:
|
|
28
|
+
python-version: "3.12"
|
|
29
|
+
- run: uv sync --group dev
|
|
30
|
+
- run: uv run pytest
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
name: Upload Python Package (TestPyPI)
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [prereleased]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
inputs:
|
|
8
|
+
release_tag:
|
|
9
|
+
description: "Release tag to publish (for example: v0.2.0rc1)"
|
|
10
|
+
required: true
|
|
11
|
+
type: string
|
|
12
|
+
|
|
13
|
+
permissions:
|
|
14
|
+
contents: read
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
release-build:
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/setup-python@v6
|
|
22
|
+
with:
|
|
23
|
+
python-version: "3.12"
|
|
24
|
+
|
|
25
|
+
- name: Resolve and validate release tag format
|
|
26
|
+
env:
|
|
27
|
+
EVENT_NAME: ${{ github.event_name }}
|
|
28
|
+
RELEASE_TAG_FROM_EVENT: ${{ github.event.release.tag_name }}
|
|
29
|
+
RELEASE_TAG_FROM_INPUT: ${{ github.event.inputs.release_tag }}
|
|
30
|
+
run: |
|
|
31
|
+
python - <<'PY'
|
|
32
|
+
import os
|
|
33
|
+
import re
|
|
34
|
+
import sys
|
|
35
|
+
|
|
36
|
+
event_name = os.environ.get("EVENT_NAME", "").strip()
|
|
37
|
+
if event_name == "release":
|
|
38
|
+
tag = os.environ.get("RELEASE_TAG_FROM_EVENT", "").strip()
|
|
39
|
+
else:
|
|
40
|
+
tag = os.environ.get("RELEASE_TAG_FROM_INPUT", "").strip()
|
|
41
|
+
|
|
42
|
+
if not tag:
|
|
43
|
+
print("No release tag provided.")
|
|
44
|
+
sys.exit(1)
|
|
45
|
+
|
|
46
|
+
if not re.fullmatch(r"v\d+\.\d+\.\d+(?:(a|b|rc)\d+)?", tag):
|
|
47
|
+
print(
|
|
48
|
+
f"Invalid release tag '{tag}'. Expected vMAJOR.MINOR.PATCH "
|
|
49
|
+
"(optionally with a/b/rc prerelease suffix)."
|
|
50
|
+
)
|
|
51
|
+
sys.exit(1)
|
|
52
|
+
|
|
53
|
+
print(f"Using release tag: {tag}")
|
|
54
|
+
with open(os.environ["GITHUB_ENV"], "a", encoding="utf-8") as fh:
|
|
55
|
+
fh.write(f"RELEASE_TAG={tag}\n")
|
|
56
|
+
PY
|
|
57
|
+
|
|
58
|
+
- uses: actions/checkout@v5
|
|
59
|
+
with:
|
|
60
|
+
fetch-depth: 0
|
|
61
|
+
ref: refs/tags/${{ env.RELEASE_TAG }}
|
|
62
|
+
|
|
63
|
+
- name: Build release distributions
|
|
64
|
+
run: |
|
|
65
|
+
python -m pip install build
|
|
66
|
+
python -m build
|
|
67
|
+
|
|
68
|
+
- name: Upload distributions
|
|
69
|
+
uses: actions/upload-artifact@v4
|
|
70
|
+
with:
|
|
71
|
+
name: release-dists-testpypi
|
|
72
|
+
path: dist/
|
|
73
|
+
|
|
74
|
+
testpypi-publish:
|
|
75
|
+
runs-on: ubuntu-latest
|
|
76
|
+
needs:
|
|
77
|
+
- release-build
|
|
78
|
+
permissions:
|
|
79
|
+
id-token: write
|
|
80
|
+
environment:
|
|
81
|
+
name: testpypi
|
|
82
|
+
|
|
83
|
+
steps:
|
|
84
|
+
- name: Retrieve release distributions
|
|
85
|
+
uses: actions/download-artifact@v4
|
|
86
|
+
with:
|
|
87
|
+
name: release-dists-testpypi
|
|
88
|
+
path: dist/
|
|
89
|
+
|
|
90
|
+
- name: Publish release distributions to TestPyPI
|
|
91
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
92
|
+
with:
|
|
93
|
+
packages-dir: dist/
|
|
94
|
+
repository-url: https://test.pypi.org/legacy/
|
|
95
|
+
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
name: Upload Python Package
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
inputs:
|
|
8
|
+
release_tag:
|
|
9
|
+
description: "Release tag to publish (for example: v0.2.0)"
|
|
10
|
+
required: true
|
|
11
|
+
type: string
|
|
12
|
+
|
|
13
|
+
permissions:
|
|
14
|
+
contents: read
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
release-build:
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/setup-python@v6
|
|
22
|
+
with:
|
|
23
|
+
python-version: "3.12"
|
|
24
|
+
|
|
25
|
+
- name: Resolve and validate release tag format
|
|
26
|
+
env:
|
|
27
|
+
EVENT_NAME: ${{ github.event_name }}
|
|
28
|
+
RELEASE_TAG_FROM_EVENT: ${{ github.event.release.tag_name }}
|
|
29
|
+
RELEASE_TAG_FROM_INPUT: ${{ github.event.inputs.release_tag }}
|
|
30
|
+
run: |
|
|
31
|
+
python - <<'PY'
|
|
32
|
+
import os
|
|
33
|
+
import re
|
|
34
|
+
import sys
|
|
35
|
+
|
|
36
|
+
event_name = os.environ.get("EVENT_NAME", "").strip()
|
|
37
|
+
if event_name == "release":
|
|
38
|
+
tag = os.environ.get("RELEASE_TAG_FROM_EVENT", "").strip()
|
|
39
|
+
else:
|
|
40
|
+
tag = os.environ.get("RELEASE_TAG_FROM_INPUT", "").strip()
|
|
41
|
+
|
|
42
|
+
if not tag:
|
|
43
|
+
print("No release tag provided.")
|
|
44
|
+
sys.exit(1)
|
|
45
|
+
|
|
46
|
+
if not re.fullmatch(r"v\d+\.\d+\.\d+(?:(a|b|rc)\d+)?", tag):
|
|
47
|
+
print(
|
|
48
|
+
f"Invalid release tag '{tag}'. Expected vMAJOR.MINOR.PATCH "
|
|
49
|
+
"(optionally with a/b/rc prerelease suffix)."
|
|
50
|
+
)
|
|
51
|
+
sys.exit(1)
|
|
52
|
+
|
|
53
|
+
print(f"Using release tag: {tag}")
|
|
54
|
+
with open(os.environ["GITHUB_ENV"], "a", encoding="utf-8") as fh:
|
|
55
|
+
fh.write(f"RELEASE_TAG={tag}\n")
|
|
56
|
+
PY
|
|
57
|
+
|
|
58
|
+
- uses: actions/checkout@v5
|
|
59
|
+
with:
|
|
60
|
+
fetch-depth: 0
|
|
61
|
+
ref: refs/tags/${{ env.RELEASE_TAG }}
|
|
62
|
+
|
|
63
|
+
- name: Build release distributions
|
|
64
|
+
run: |
|
|
65
|
+
python -m pip install build
|
|
66
|
+
python -m build
|
|
67
|
+
|
|
68
|
+
- name: Upload distributions
|
|
69
|
+
uses: actions/upload-artifact@v4
|
|
70
|
+
with:
|
|
71
|
+
name: release-dists-pypi
|
|
72
|
+
path: dist/
|
|
73
|
+
|
|
74
|
+
pypi-publish:
|
|
75
|
+
runs-on: ubuntu-latest
|
|
76
|
+
needs:
|
|
77
|
+
- release-build
|
|
78
|
+
permissions:
|
|
79
|
+
id-token: write
|
|
80
|
+
environment:
|
|
81
|
+
name: publishers
|
|
82
|
+
|
|
83
|
+
steps:
|
|
84
|
+
- name: Retrieve release distributions
|
|
85
|
+
uses: actions/download-artifact@v4
|
|
86
|
+
with:
|
|
87
|
+
name: release-dists-pypi
|
|
88
|
+
path: dist/
|
|
89
|
+
|
|
90
|
+
- name: Publish release distributions to PyPI
|
|
91
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
92
|
+
with:
|
|
93
|
+
packages-dir: dist/
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
# Usually these files are written by a python script from a template
|
|
31
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
32
|
+
*.manifest
|
|
33
|
+
*.spec
|
|
34
|
+
|
|
35
|
+
# Installer logs
|
|
36
|
+
pip-log.txt
|
|
37
|
+
pip-delete-this-directory.txt
|
|
38
|
+
|
|
39
|
+
# Unit test / coverage reports
|
|
40
|
+
htmlcov/
|
|
41
|
+
.tox/
|
|
42
|
+
.nox/
|
|
43
|
+
.coverage
|
|
44
|
+
.coverage.*
|
|
45
|
+
.cache
|
|
46
|
+
nosetests.xml
|
|
47
|
+
coverage.xml
|
|
48
|
+
*.cover
|
|
49
|
+
*.py,cover
|
|
50
|
+
.hypothesis/
|
|
51
|
+
.pytest_cache/
|
|
52
|
+
cover/
|
|
53
|
+
|
|
54
|
+
# Translations
|
|
55
|
+
*.mo
|
|
56
|
+
*.pot
|
|
57
|
+
|
|
58
|
+
# Django stuff:
|
|
59
|
+
*.log
|
|
60
|
+
local_settings.py
|
|
61
|
+
db.sqlite3
|
|
62
|
+
db.sqlite3-journal
|
|
63
|
+
|
|
64
|
+
# Flask stuff:
|
|
65
|
+
instance/
|
|
66
|
+
.webassets-cache
|
|
67
|
+
|
|
68
|
+
# Scrapy stuff:
|
|
69
|
+
.scrapy
|
|
70
|
+
|
|
71
|
+
# Sphinx documentation
|
|
72
|
+
docs/_build/
|
|
73
|
+
|
|
74
|
+
# PyBuilder
|
|
75
|
+
.pybuilder/
|
|
76
|
+
target/
|
|
77
|
+
|
|
78
|
+
# Jupyter Notebook
|
|
79
|
+
.ipynb_checkpoints
|
|
80
|
+
|
|
81
|
+
# IPython
|
|
82
|
+
profile_default/
|
|
83
|
+
ipython_config.py
|
|
84
|
+
|
|
85
|
+
# pyenv
|
|
86
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
87
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
88
|
+
# .python-version
|
|
89
|
+
|
|
90
|
+
# pipenv
|
|
91
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
92
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
93
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
94
|
+
# install all needed dependencies.
|
|
95
|
+
#Pipfile.lock
|
|
96
|
+
|
|
97
|
+
# poetry
|
|
98
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
99
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
100
|
+
# commonly ignored for libraries.
|
|
101
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
102
|
+
#poetry.lock
|
|
103
|
+
|
|
104
|
+
# pdm
|
|
105
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
106
|
+
#pdm.lock
|
|
107
|
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
|
108
|
+
# in version control.
|
|
109
|
+
# https://pdm.fming.dev/#use-with-ide
|
|
110
|
+
.pdm.toml
|
|
111
|
+
|
|
112
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
113
|
+
__pypackages__/
|
|
114
|
+
|
|
115
|
+
# Celery stuff
|
|
116
|
+
celerybeat-schedule
|
|
117
|
+
celerybeat.pid
|
|
118
|
+
|
|
119
|
+
# SageMath parsed files
|
|
120
|
+
*.sage.py
|
|
121
|
+
|
|
122
|
+
# Environments
|
|
123
|
+
.env
|
|
124
|
+
.venv
|
|
125
|
+
env/
|
|
126
|
+
venv/
|
|
127
|
+
ENV/
|
|
128
|
+
env.bak/
|
|
129
|
+
venv.bak/
|
|
130
|
+
|
|
131
|
+
# Spyder project settings
|
|
132
|
+
.spyderproject
|
|
133
|
+
.spyproject
|
|
134
|
+
|
|
135
|
+
# Rope project settings
|
|
136
|
+
.ropeproject
|
|
137
|
+
|
|
138
|
+
# mkdocs documentation
|
|
139
|
+
/site
|
|
140
|
+
|
|
141
|
+
# mypy
|
|
142
|
+
.mypy_cache/
|
|
143
|
+
.dmypy.json
|
|
144
|
+
dmypy.json
|
|
145
|
+
|
|
146
|
+
# Pyre type checker
|
|
147
|
+
.pyre/
|
|
148
|
+
|
|
149
|
+
# pytype static type analyzer
|
|
150
|
+
.pytype/
|
|
151
|
+
|
|
152
|
+
# Cython debug symbols
|
|
153
|
+
cython_debug/
|
|
154
|
+
|
|
155
|
+
# PyCharm
|
|
156
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
157
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
158
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
159
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
160
|
+
#.idea/
|
|
161
|
+
/.idea
|
|
162
|
+
/Prometheus/JANAF_Cache
|
|
163
|
+
|
|
164
|
+
# Benchmark output files
|
|
165
|
+
benchmark_output.txt
|
|
166
|
+
benchmark_db_output.txt
|
|
167
|
+
benchmark_debug.log
|
|
168
|
+
solver_debug.log
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
|
|
3
|
+
build:
|
|
4
|
+
os: ubuntu-22.04
|
|
5
|
+
tools:
|
|
6
|
+
python: "3.13"
|
|
7
|
+
|
|
8
|
+
sphinx:
|
|
9
|
+
configuration: docs/conf.py
|
|
10
|
+
|
|
11
|
+
python:
|
|
12
|
+
install:
|
|
13
|
+
# Install the package itself so autodoc can import prometheus and its deps
|
|
14
|
+
- method: pip
|
|
15
|
+
path: .
|
|
16
|
+
# Doc-only dependencies (Sphinx theme etc.)
|
|
17
|
+
- requirements: docs/requirements.txt
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
Prometheus is an open-source combustion equilibrium solver for Python. It parses thermodynamic data from multiple sources (BURCAT/NASA-7, NASA-9, JANAF, CEA), builds a species database, and implements equilibrium solvers. The long-term goal is H₂/O₂ combustion validation against RocketCEA.
|
|
8
|
+
|
|
9
|
+
## Development Commands
|
|
10
|
+
|
|
11
|
+
This project uses [uv](https://docs.astral.sh/uv/) for dependency management.
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
uv sync # Install dependencies
|
|
15
|
+
uv run pytest # Run the test suite
|
|
16
|
+
uv run pytest tests/test_solver_gmcb.py # Run a single test file
|
|
17
|
+
uv run pytest tests/test_solver_gmcb.py::test_hp_h2o2 # Run a single test
|
|
18
|
+
uv run python tests/benchmark.py # Full solver vs. RocketCEA benchmark (170 cases)
|
|
19
|
+
uv run python compare_rocketcea.py # G-McB vs. CEA single-case comparison
|
|
20
|
+
uv run python prometheus_equilibrium/thermo_data/parsers/cea.py # Re-convert CEA thermo.inp → cea_nasa9.json
|
|
21
|
+
uv run prometheus-build-all-thermo # Re-generate all thermo databases in one command
|
|
22
|
+
uv run prometheus-build-legacy all # Re-generate terra.json + afcesic.json (calibrated)
|
|
23
|
+
uv run black prometheus_equilibrium/ tests/ # Format code
|
|
24
|
+
uv run isort prometheus_equilibrium/ tests/ # Sort imports
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
`tests/benchmark.py` is the primary regression benchmark. It tests H2/O2, CH4/O2, N2H4/N2O4, and NH3/O2 across 11 O/F ratios and 5 pressures (170 cases) against RocketCEA and reports temperature error, mean molar mass, γ, Cp, and speed of sound.
|
|
28
|
+
|
|
29
|
+
## Implementation Status
|
|
30
|
+
|
|
31
|
+
Current state:
|
|
32
|
+
|
|
33
|
+
- **Complete**: all thermodynamic data parsing; `Chemical`, `Species`, `JANAF`, `NASASevenCoeff`, `NASANineCoeff`, `SpeciesDatabase`; `Mixture` (all properties); `ElementMatrix` (all methods including `select_basis`); `EquilibriumProblem`; `EquilibriumSolution` (all derived properties); `GordonMcBrideSolver`; `MajorSpeciesSolver`.
|
|
34
|
+
- **Not yet implemented**: `PEPSolver._tp_equilibrium` (raises `NotImplementedError`).
|
|
35
|
+
|
|
36
|
+
## Architecture
|
|
37
|
+
|
|
38
|
+
### Module layout
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
prometheus_equilibrium/
|
|
42
|
+
core/constants.py — element molar masses, R, P° = 1e5 Pa
|
|
43
|
+
equilibrium/
|
|
44
|
+
species.py — Chemical, Species, JANAF, NASASevenCoeff, NASANineCoeff, SpeciesDatabase
|
|
45
|
+
_thermo_kernels.py — optional Numba JIT kernels for NASASevenCoeff/NASANineCoeff hot path
|
|
46
|
+
mixture.py — Mixture (species list + mutable moles array)
|
|
47
|
+
element_matrix.py — ElementMatrix (stoichiometric matrix A)
|
|
48
|
+
problem.py — EquilibriumProblem, ProblemType enum
|
|
49
|
+
solution.py — EquilibriumSolution dataclass + derived properties
|
|
50
|
+
solver.py — EquilibriumSolver ABC, _ReactionAdjustmentBase, all three solver classes
|
|
51
|
+
performance.py — PerformanceSolver (frozen + shifting nozzle expansion)
|
|
52
|
+
gui/ — PySide6 desktop interface
|
|
53
|
+
propellants/
|
|
54
|
+
loader.py — PropellantDatabase, SyntheticSpecies, TOML-based propellant definitions
|
|
55
|
+
thermo_data/
|
|
56
|
+
compiler.py — thermo data compiler
|
|
57
|
+
parsers/ — individual format parsers
|
|
58
|
+
burcat.py — BURCAT/NASA-7 format
|
|
59
|
+
cea.py — CEA thermo.inp format (also converts thermo.inp → cea_nasa9.json)
|
|
60
|
+
janaf.py — JANAF CSV format
|
|
61
|
+
shomate.py — Shomate polynomial format
|
|
62
|
+
terra.py — TERRA binary format
|
|
63
|
+
_common.py — shared parsing utilities
|
|
64
|
+
tools/build_db.py — parse raw .thr/.jnf files → nasa7.json, nasa9.json, janaf.csv
|
|
65
|
+
tools/build_legacy_thermo.py — parse TERRA/AFCESIC binaries + calibrate AFCESIC references
|
|
66
|
+
tests/ — pytest unit tests (mock species, no external DB dependency)
|
|
67
|
+
tests/benchmark.py — integration benchmark vs. RocketCEA
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Species and database
|
|
71
|
+
|
|
72
|
+
`Chemical` → `Species` (abstract) → `JANAF`, `NASASevenCoeff`, `NASANineCoeff`. All species carry `elements: dict[str, float]`, `state`, `condensed` (0=gas, 1=condensed), and `alias`. Thermodynamic methods accept scalar float or `np.ndarray`; scalar calls take a fast path that skips NumPy overhead (and optionally uses Numba from `_thermo_kernels.py`).
|
|
73
|
+
|
|
74
|
+
`SpeciesDatabase` loads up to five sources; call `load()` before use:
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
db = SpeciesDatabase(
|
|
78
|
+
nasa7_path="prometheus_equilibrium/thermo_data/nasa7.json",
|
|
79
|
+
nasa9_path="prometheus_equilibrium/thermo_data/nasa9.json",
|
|
80
|
+
janaf_path="prometheus_equilibrium/thermo_data/janaf.csv",
|
|
81
|
+
cea_nasa9_path="prometheus_equilibrium/thermo_data/cea_nasa9.json", # optional, CEA-sourced polynomials
|
|
82
|
+
)
|
|
83
|
+
db.load(include_janaf=False) # benchmark.py uses include_janaf=False for stability
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Priority when the same species ID appears in multiple sources (default): NASA-9 > NASA-7 > JANAF > TERRA > AFCESIC. This can be overridden via `SpeciesDatabase(..., source_priority=...)` or `db.load(source_priority=...)`. `get_species(elements, max_atoms=N)` returns all species whose element set is a subset of `elements`; `max_atoms` filters out large molecules (benchmark.py uses `max_atoms=20`).
|
|
87
|
+
|
|
88
|
+
Canonical species ID: `{HillFormula}_{PHASE}` — e.g. `CO2_G`, `H2O_L`, `Al2O3_S`. Hill order: C first, H second, then alphabetical.
|
|
89
|
+
|
|
90
|
+
### Equilibrium data flow
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
EquilibriumProblem → Solver.solve() → EquilibriumSolution
|
|
94
|
+
↑ ↑
|
|
95
|
+
reactants+products ElementMatrix
|
|
96
|
+
(ProblemType.HP etc) (from mixture.species)
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
`EquilibriumProblem` is purely declarative. `initial_mixture()` distributes moles equally across all gas-phase products as a starting guess. `b0_array(elements)` returns the element-abundance vector from reactants.
|
|
100
|
+
|
|
101
|
+
`Mixture` always keeps gas species before condensed (enforced at construction). The solver mutates `mixture.moles` in-place during Newton iteration.
|
|
102
|
+
|
|
103
|
+
`ElementMatrix` stores `A[i,k]` = atoms of element k in species i. Key methods: `element_abundances(n)` → `Aᵀ·n`, `select_basis(moles)` → Browne/Gram-Schmidt basis indices, `reaction_coefficients(basis)` → ν = C·B⁻¹ (used by Hybrid).
|
|
104
|
+
|
|
105
|
+
### Solver hierarchy
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
EquilibriumSolver (ABC)
|
|
109
|
+
├── _ReactionAdjustmentBase
|
|
110
|
+
│ ├── MajorSpeciesSolver ← recommended default
|
|
111
|
+
│ └── PEPSolver ← not yet implemented
|
|
112
|
+
└── GordonMcBrideSolver ← reference / validation
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**`MajorSpeciesSolver`** (96.5% convergence, 0.013% mean T error vs RocketCEA):
|
|
116
|
+
- Inner loop (`_tp_equilibrium`): compressed Newton on major gas species only — matrix is always S×S regardless of species count. Minor species set analytically from element potentials π after each Newton step.
|
|
117
|
+
- Outer loop (`_temperature_search`): Newton + interval-halving to satisfy energy constraint (HP/SP).
|
|
118
|
+
- `_tp_equilibrium` returns a 4-tuple `(mixture, pi, n_iters, converged_bool)`; `_temperature_search` returns a 5-tuple `(mixture, T, pi, n_outer, converged_bool)`. `solve()` uses the returned `converged` flag directly — it does NOT recheck element residuals, as the "final exact update" in `_temperature_search` temporarily disturbs element balance.
|
|
119
|
+
|
|
120
|
+
**`GordonMcBrideSolver`** (72.9% convergence, 0.82% mean T error — reference/validation):
|
|
121
|
+
- Single Newton loop solving π, Δnc, Δln(n), Δln(T) simultaneously. Matrix size (S+nc+1)² for TP or (S+nc+2)² for HP/SP.
|
|
122
|
+
- Stability fix: tracks `n_var` as the *previous iteration's* `n_gas_total`. This gives `G[idx_n, idx_n] = n_gas_total_current − n_gas_total_prev ≠ 0`, preventing runaway `delta_ln_n` on lean mixtures. `n_var` is stored before `_apply_update`, so the next iteration sees the change. `mu_gas` always uses the actual current `n_gas_total`, not `n_var`.
|
|
123
|
+
|
|
124
|
+
**Shared** (`_ReactionAdjustmentBase`): `_temperature_search`, `_split_major_minor`, `_manage_condensed_phases`, `_initialise` (validates, filters ionic species, removes products not coverable from reactant elements).
|
|
125
|
+
|
|
126
|
+
### Key design constants
|
|
127
|
+
|
|
128
|
+
- All temperatures in Kelvin, energies in J/mol, pressures in Pa (P° = 1e5 Pa = 1 bar)
|
|
129
|
+
- `_LOG_CONC_TOL = math.log(1e-8)` — concentration floor; species with `ln(nⱼ) - ln(n) ≤ _LOG_CONC_TOL` are zeroed
|
|
130
|
+
- Convergence tolerance: `5e-6` (step size criterion) for both solvers
|
|
131
|
+
- `_ReactionAdjustmentBase.__init__` defaults: `max_iterations=50`, `tolerance=5e-6`, `minor_threshold=1e-2`
|
|
132
|
+
|
|
133
|
+
### Reference material and submodules
|
|
134
|
+
|
|
135
|
+
- `cea/` — git submodule: NASA CEA Fortran source (Gordon-McBride reference implementation, especially `cea/source/`)
|
|
136
|
+
- `pypropep/` — git submodule: C implementation of Propep (PEP reference); uses NASA-format thermo data — **not relevant to AFCESIC**
|
|
137
|
+
- `pep-for-zos/` — git submodule: historical PEP Fortran source for z/OS (1970s Naval Weapons Center origin)
|
|
138
|
+
- `terra/` — external equilibrium solver (BASIC source + compiled binaries); not integrated into Prometheus
|
|
139
|
+
- `papers/` — Villars-Browne PEP paper and NASA RP-1311
|
|
140
|
+
|
|
141
|
+
We use Google-style docstrings throughout. **All new docstrings must use Google style** (`Args:`, `Returns:`, `Raises:`, `Attributes:`, `Example:`, `Note:` sections with 4-space-indented content). NumPy/reStructuredText docstring styles are not used in this project.
|
|
142
|
+
|
|
143
|
+
## Documentation
|
|
144
|
+
|
|
145
|
+
Sphinx docs live in `docs/`. Build with:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
uv run --group docs sphinx-build -b html docs docs/_build/html
|
|
149
|
+
# or, on Unix/macOS:
|
|
150
|
+
cd docs && make html
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
The docs use `sphinx.ext.autodoc` + `sphinx.ext.autosummary` (with `:recursive:`) to automatically discover and document every module, class, and function in `prometheus_equilibrium/`. The Napoleon extension translates Google-style docstrings. Theme: `renku` (package: `renku-sphinx-theme`).
|
|
154
|
+
|
|
155
|
+
The `docs/` directory structure:
|
|
156
|
+
- `index.rst` — landing page + quick-start
|
|
157
|
+
- `thermo/` — thermodynamic database guide and TERRA integration notes
|
|
158
|
+
- `solver_comparison.rst` — algorithm analysis for MajorSpeciesSolver, G-McB, PEP
|
|
159
|
+
- `api/` — auto-generated API reference stubs
|