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.
Files changed (132) hide show
  1. prometheus_equilibrium-0.1.0/.claude/settings.local.json +10 -0
  2. prometheus_equilibrium-0.1.0/.github/CODEOWNERS +5 -0
  3. prometheus_equilibrium-0.1.0/.github/workflows/ci.yml +30 -0
  4. prometheus_equilibrium-0.1.0/.github/workflows/python-publish-testpypi.yml +95 -0
  5. prometheus_equilibrium-0.1.0/.github/workflows/python-publish.yml +93 -0
  6. prometheus_equilibrium-0.1.0/.gitignore +168 -0
  7. prometheus_equilibrium-0.1.0/.gitmodules +6 -0
  8. prometheus_equilibrium-0.1.0/.pre-commit-config.yaml +12 -0
  9. prometheus_equilibrium-0.1.0/.readthedocs.yaml +17 -0
  10. prometheus_equilibrium-0.1.0/CLAUDE.md +159 -0
  11. prometheus_equilibrium-0.1.0/LICENSE.txt +674 -0
  12. prometheus_equilibrium-0.1.0/PKG-INFO +269 -0
  13. prometheus_equilibrium-0.1.0/README.md +239 -0
  14. prometheus_equilibrium-0.1.0/demonstration.ipynb +374 -0
  15. prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.core.constants.rst +6 -0
  16. prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.core.rst +12 -0
  17. prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.equilibrium.element_matrix.rst +12 -0
  18. prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.equilibrium.mixture.rst +12 -0
  19. prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.equilibrium.performance.rst +13 -0
  20. prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.equilibrium.problem.rst +13 -0
  21. prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.equilibrium.rst +19 -0
  22. prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.equilibrium.solution.rst +4 -0
  23. prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.equilibrium.solver.rst +15 -0
  24. prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.equilibrium.species.rst +20 -0
  25. prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.propellants.loader.rst +4 -0
  26. prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.propellants.rst +13 -0
  27. prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.rst +15 -0
  28. prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.thermo_data.compiler.rst +12 -0
  29. prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.thermo_data.parsers.burcat.rst +13 -0
  30. prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.thermo_data.parsers.cea.rst +12 -0
  31. prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.thermo_data.parsers.janaf.rst +12 -0
  32. prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.thermo_data.parsers.rst +16 -0
  33. prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.thermo_data.parsers.shomate.rst +12 -0
  34. prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.thermo_data.parsers.terra.rst +12 -0
  35. prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.thermo_data.rst +13 -0
  36. prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.tools.build_all_thermo.rst +13 -0
  37. prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.tools.build_db.rst +12 -0
  38. prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.tools.build_legacy_thermo.rst +15 -0
  39. prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.tools.build_propellants.rst +21 -0
  40. prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.tools.compare_databases.rst +13 -0
  41. prometheus_equilibrium-0.1.0/docs/api/prometheus_equilibrium.tools.rst +16 -0
  42. prometheus_equilibrium-0.1.0/docs/conf.py +96 -0
  43. prometheus_equilibrium-0.1.0/docs/index.rst +66 -0
  44. prometheus_equilibrium-0.1.0/docs/requirements.txt +2 -0
  45. prometheus_equilibrium-0.1.0/docs/solver_comparison.rst +300 -0
  46. prometheus_equilibrium-0.1.0/docs/thermo/index.rst +8 -0
  47. prometheus_equilibrium-0.1.0/docs/thermo/terra_integration.rst +115 -0
  48. prometheus_equilibrium-0.1.0/docs/thermo/thermo_database_guide.rst +135 -0
  49. prometheus_equilibrium-0.1.0/memory/MEMORY.md +4 -0
  50. prometheus_equilibrium-0.1.0/memory/feedback_schema_versioning.md +11 -0
  51. prometheus_equilibrium-0.1.0/papers/NASA-RP-1311.pdf +0 -0
  52. prometheus_equilibrium-0.1.0/papers/NASApolynomial.pdf +0 -0
  53. prometheus_equilibrium-0.1.0/papers/PEP.pdf +0 -0
  54. prometheus_equilibrium-0.1.0/papers/PEP_Extracted.txt +7054 -0
  55. prometheus_equilibrium-0.1.0/papers/TERRA_user_guide.pdf +0 -0
  56. prometheus_equilibrium-0.1.0/papers/burcat_intro.pdf +0 -0
  57. prometheus_equilibrium-0.1.0/prometheus_equilibrium/__init__.py +62 -0
  58. prometheus_equilibrium-0.1.0/prometheus_equilibrium/core/__init__.py +0 -0
  59. prometheus_equilibrium-0.1.0/prometheus_equilibrium/core/constants.py +144 -0
  60. prometheus_equilibrium-0.1.0/prometheus_equilibrium/equilibrium/__init__.py +95 -0
  61. prometheus_equilibrium-0.1.0/prometheus_equilibrium/equilibrium/_thermo_kernels.py +418 -0
  62. prometheus_equilibrium-0.1.0/prometheus_equilibrium/equilibrium/element_matrix.py +411 -0
  63. prometheus_equilibrium-0.1.0/prometheus_equilibrium/equilibrium/mixture.py +388 -0
  64. prometheus_equilibrium-0.1.0/prometheus_equilibrium/equilibrium/performance.py +587 -0
  65. prometheus_equilibrium-0.1.0/prometheus_equilibrium/equilibrium/problem.py +330 -0
  66. prometheus_equilibrium-0.1.0/prometheus_equilibrium/equilibrium/solution.py +327 -0
  67. prometheus_equilibrium-0.1.0/prometheus_equilibrium/equilibrium/solver.py +2852 -0
  68. prometheus_equilibrium-0.1.0/prometheus_equilibrium/equilibrium/species.py +2270 -0
  69. prometheus_equilibrium-0.1.0/prometheus_equilibrium/gui/__init__.py +1 -0
  70. prometheus_equilibrium-0.1.0/prometheus_equilibrium/gui/__main__.py +6 -0
  71. prometheus_equilibrium-0.1.0/prometheus_equilibrium/gui/app.py +84 -0
  72. prometheus_equilibrium-0.1.0/prometheus_equilibrium/gui/dialogs/__init__.py +0 -0
  73. prometheus_equilibrium-0.1.0/prometheus_equilibrium/gui/dialogs/add_propellant.py +75 -0
  74. prometheus_equilibrium-0.1.0/prometheus_equilibrium/gui/dialogs/database_search.py +45 -0
  75. prometheus_equilibrium-0.1.0/prometheus_equilibrium/gui/engine.py +743 -0
  76. prometheus_equilibrium-0.1.0/prometheus_equilibrium/gui/main_window.py +250 -0
  77. prometheus_equilibrium-0.1.0/prometheus_equilibrium/gui/pages/__init__.py +0 -0
  78. prometheus_equilibrium-0.1.0/prometheus_equilibrium/gui/pages/analysis.py +255 -0
  79. prometheus_equilibrium-0.1.0/prometheus_equilibrium/gui/pages/library.py +298 -0
  80. prometheus_equilibrium-0.1.0/prometheus_equilibrium/gui/pages/simulator.py +596 -0
  81. prometheus_equilibrium-0.1.0/prometheus_equilibrium/gui/widgets/__init__.py +0 -0
  82. prometheus_equilibrium-0.1.0/prometheus_equilibrium/gui/widgets/graph_canvas.py +21 -0
  83. prometheus_equilibrium-0.1.0/prometheus_equilibrium/propellants/PEPCODED.DAF +1158 -0
  84. prometheus_equilibrium-0.1.0/prometheus_equilibrium/propellants/__init__.py +37 -0
  85. prometheus_equilibrium-0.1.0/prometheus_equilibrium/propellants/loader.py +426 -0
  86. prometheus_equilibrium-0.1.0/prometheus_equilibrium/propellants/propellants.toml +9712 -0
  87. prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/__init__.py +0 -0
  88. prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/afcesic.json +40501 -0
  89. prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/compiler.py +606 -0
  90. prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/janaf.csv +84025 -0
  91. prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/nasa7.json +116337 -0
  92. prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/nasa9.json +277856 -0
  93. prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/parsers/__init__.py +32 -0
  94. prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/parsers/_common.py +542 -0
  95. prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/parsers/afcesic.py +391 -0
  96. prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/parsers/burcat.py +405 -0
  97. prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/parsers/cea.py +184 -0
  98. prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/parsers/janaf.py +161 -0
  99. prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/parsers/shomate.py +187 -0
  100. prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/parsers/terra.py +384 -0
  101. prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/raw/ALLPROP.DAT +0 -0
  102. prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/raw/JANAF.jnf +89278 -0
  103. prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/raw/THERGG.DAT +0 -0
  104. prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/raw/THERII.DAT +0 -0
  105. prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/raw/THERSS.DAT +0 -0
  106. prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/raw/burcat7.thr +13568 -0
  107. prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/raw/burcat9.thr +26392 -0
  108. prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/raw/cea_thermo.inp +15802 -0
  109. prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/raw/terra.bas +0 -0
  110. prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/raw/terra_a.bas +0 -0
  111. prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/shomate.json +14 -0
  112. prometheus_equilibrium-0.1.0/prometheus_equilibrium/thermo_data/terra.json +85381 -0
  113. prometheus_equilibrium-0.1.0/prometheus_equilibrium/tools/__init__.py +0 -0
  114. prometheus_equilibrium-0.1.0/prometheus_equilibrium/tools/build_all_thermo.py +133 -0
  115. prometheus_equilibrium-0.1.0/prometheus_equilibrium/tools/build_db.py +285 -0
  116. prometheus_equilibrium-0.1.0/prometheus_equilibrium/tools/build_legacy_thermo.py +326 -0
  117. prometheus_equilibrium-0.1.0/prometheus_equilibrium/tools/build_propellants.py +381 -0
  118. prometheus_equilibrium-0.1.0/prometheus_equilibrium/tools/compare_databases.py +102 -0
  119. prometheus_equilibrium-0.1.0/pyproject.toml +86 -0
  120. prometheus_equilibrium-0.1.0/tests/benchmark.py +626 -0
  121. prometheus_equilibrium-0.1.0/tests/benchmark_db.py +684 -0
  122. prometheus_equilibrium-0.1.0/tests/test_build_propellants_tool.py +65 -0
  123. prometheus_equilibrium-0.1.0/tests/test_element_matrix.py +245 -0
  124. prometheus_equilibrium-0.1.0/tests/test_mixture.py +160 -0
  125. prometheus_equilibrium-0.1.0/tests/test_performance.py +54 -0
  126. prometheus_equilibrium-0.1.0/tests/test_problem.py +294 -0
  127. prometheus_equilibrium-0.1.0/tests/test_propellants.py +418 -0
  128. prometheus_equilibrium-0.1.0/tests/test_solution.py +249 -0
  129. prometheus_equilibrium-0.1.0/tests/test_solver_gmcb.py +659 -0
  130. prometheus_equilibrium-0.1.0/tests/test_solver_pep.py +265 -0
  131. prometheus_equilibrium-0.1.0/tests/test_species.py +312 -0
  132. prometheus_equilibrium-0.1.0/uv.lock +2085 -0
@@ -0,0 +1,10 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(uv run python -c \":*)",
5
+ "Bash(uv run:*)",
6
+ "Bash(python3 -)",
7
+ "Bash(python3 -c ':*)"
8
+ ]
9
+ }
10
+ }
@@ -0,0 +1,5 @@
1
+ # Require explicit owner review for deployment and packaging surfaces.
2
+ /.github/workflows/ @1ckendall
3
+ /pyproject.toml @1ckendall
4
+ /uv.lock @1ckendall
5
+
@@ -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,6 @@
1
+ [submodule "pypropep"]
2
+ path = pypropep
3
+ url = https://github.com/jonnydyer/pypropep.git
4
+ [submodule "cea"]
5
+ path = cea
6
+ url = https://github.com/nasa/cea.git
@@ -0,0 +1,12 @@
1
+ repos:
2
+ - repo: https://github.com/psf/black
3
+ rev: 25.1.0
4
+ hooks:
5
+ - id: black
6
+ language_version: python3.12
7
+
8
+ - repo: https://github.com/PyCQA/isort
9
+ rev: 5.13.2
10
+ hooks:
11
+ - id: isort
12
+ args: ["--profile", "black"]
@@ -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