chemthermo 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.
- chemthermo-0.4.0/CHANGELOG.md +172 -0
- chemthermo-0.4.0/LICENSE +21 -0
- chemthermo-0.4.0/MANIFEST.in +11 -0
- chemthermo-0.4.0/PKG-INFO +196 -0
- chemthermo-0.4.0/README.md +154 -0
- chemthermo-0.4.0/pyproject.toml +103 -0
- chemthermo-0.4.0/setup.cfg +4 -0
- chemthermo-0.4.0/src/chemthermo/__init__.py +96 -0
- chemthermo-0.4.0/src/chemthermo/__main__.py +8 -0
- chemthermo-0.4.0/src/chemthermo/_eos_memo.py +214 -0
- chemthermo-0.4.0/src/chemthermo/bench/__init__.py +313 -0
- chemthermo-0.4.0/src/chemthermo/bench/__main__.py +10 -0
- chemthermo-0.4.0/src/chemthermo/bench/_cases.py +614 -0
- chemthermo-0.4.0/src/chemthermo/bench/_record.py +187 -0
- chemthermo-0.4.0/src/chemthermo/bench/robustness.py +2101 -0
- chemthermo-0.4.0/src/chemthermo/citations.py +59 -0
- chemthermo-0.4.0/src/chemthermo/cli.py +509 -0
- chemthermo-0.4.0/src/chemthermo/core/__init__.py +7 -0
- chemthermo-0.4.0/src/chemthermo/core/component.py +197 -0
- chemthermo-0.4.0/src/chemthermo/core/composition.py +48 -0
- chemthermo-0.4.0/src/chemthermo/core/mixture.py +66 -0
- chemthermo-0.4.0/src/chemthermo/data/__init__.py +88 -0
- chemthermo-0.4.0/src/chemthermo/data/components.json +3449 -0
- chemthermo-0.4.0/src/chemthermo/data/references.bib +6 -0
- chemthermo-0.4.0/src/chemthermo/data/schema.py +9 -0
- chemthermo-0.4.0/src/chemthermo/eos/__init__.py +13 -0
- chemthermo-0.4.0/src/chemthermo/eos/_pcsaft_association.py +664 -0
- chemthermo-0.4.0/src/chemthermo/eos/_pcsaft_density.py +653 -0
- chemthermo-0.4.0/src/chemthermo/eos/api.py +29 -0
- chemthermo-0.4.0/src/chemthermo/eos/pcsaft.py +1456 -0
- chemthermo-0.4.0/src/chemthermo/eos/registry.py +44 -0
- chemthermo-0.4.0/src/chemthermo/exceptions.py +25 -0
- chemthermo-0.4.0/src/chemthermo/flash/__init__.py +7 -0
- chemthermo-0.4.0/src/chemthermo/flash/_assemble.py +129 -0
- chemthermo-0.4.0/src/chemthermo/flash/_common.py +327 -0
- chemthermo-0.4.0/src/chemthermo/flash/_detect.py +1768 -0
- chemthermo-0.4.0/src/chemthermo/flash/_legacy.py +143 -0
- chemthermo-0.4.0/src/chemthermo/flash/_log_space.py +698 -0
- chemthermo-0.4.0/src/chemthermo/flash/_multiphase.py +1404 -0
- chemthermo-0.4.0/src/chemthermo/flash/_multiphase_log_space.py +406 -0
- chemthermo-0.4.0/src/chemthermo/flash/_multiphase_rr.py +433 -0
- chemthermo-0.4.0/src/chemthermo/flash/_second_order.py +263 -0
- chemthermo-0.4.0/src/chemthermo/flash/_split.py +764 -0
- chemthermo-0.4.0/src/chemthermo/flash/_verify.py +310 -0
- chemthermo-0.4.0/src/chemthermo/flash/api.py +5 -0
- chemthermo-0.4.0/src/chemthermo/flash/results.py +99 -0
- chemthermo-0.4.0/src/chemthermo/flash/settings.py +154 -0
- chemthermo-0.4.0/src/chemthermo/flash/tp.py +519 -0
- chemthermo-0.4.0/src/chemthermo/models/__init__.py +7 -0
- chemthermo-0.4.0/src/chemthermo/models/_antoine.py +125 -0
- chemthermo-0.4.0/src/chemthermo/models/_kij.py +115 -0
- chemthermo-0.4.0/src/chemthermo/models/base.py +216 -0
- chemthermo-0.4.0/src/chemthermo/models/nrtl.py +148 -0
- chemthermo-0.4.0/src/chemthermo/models/peng_robinson.py +459 -0
- chemthermo-0.4.0/src/chemthermo/parameters/__init__.py +21 -0
- chemthermo-0.4.0/src/chemthermo/parameters/activity.py +23 -0
- chemthermo-0.4.0/src/chemthermo/parameters/data/activity/nrtl.json +32 -0
- chemthermo-0.4.0/src/chemthermo/parameters/data/eos/pcsaft.json +189 -0
- chemthermo-0.4.0/src/chemthermo/parameters/nrtl.py +163 -0
- chemthermo-0.4.0/src/chemthermo/parameters/pcsaft.py +458 -0
- chemthermo-0.4.0/src/chemthermo/phase_boundary.py +479 -0
- chemthermo-0.4.0/src/chemthermo/py.typed +0 -0
- chemthermo-0.4.0/src/chemthermo/schemas.py +93 -0
- chemthermo-0.4.0/src/chemthermo/stability/__init__.py +7 -0
- chemthermo-0.4.0/src/chemthermo/stability/_evaluator.py +1087 -0
- chemthermo-0.4.0/src/chemthermo/stability/results.py +224 -0
- chemthermo-0.4.0/src/chemthermo/stability/settings.py +73 -0
- chemthermo-0.4.0/src/chemthermo/stability/tp.py +1165 -0
- chemthermo-0.4.0/src/chemthermo/units.py +10 -0
- chemthermo-0.4.0/src/chemthermo/validation.py +72 -0
- chemthermo-0.4.0/src/chemthermo/vle.py +11 -0
- chemthermo-0.4.0/src/chemthermo.egg-info/PKG-INFO +196 -0
- chemthermo-0.4.0/src/chemthermo.egg-info/SOURCES.txt +75 -0
- chemthermo-0.4.0/src/chemthermo.egg-info/dependency_links.txt +1 -0
- chemthermo-0.4.0/src/chemthermo.egg-info/entry_points.txt +2 -0
- chemthermo-0.4.0/src/chemthermo.egg-info/requires.txt +16 -0
- chemthermo-0.4.0/src/chemthermo.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
Versions follow PEP 440 and are tagged `v<version>` on one tested commit
|
|
4
|
+
(policy: `.agents/brain/adr/0031-versioned-releases.md`). Releases up to
|
|
5
|
+
0.3.0b1 were GitHub-only; from 0.4.0 the owner also publishes to PyPI by hand
|
|
6
|
+
(ADR-0038).
|
|
7
|
+
|
|
8
|
+
## 0.4.0 (2026-09-25) - first PyPI release (Beta)
|
|
9
|
+
|
|
10
|
+
The first release published to PyPI (`pip install chemthermo`), with a short,
|
|
11
|
+
honest README, the reference material moved to `docs/`, and packaging checked
|
|
12
|
+
for PyPI. Beta: validated against independent implementations on macOS arm64
|
|
13
|
+
and Linux x86_64, but the public API may still change before 1.0.
|
|
14
|
+
|
|
15
|
+
### Breaking
|
|
16
|
+
- **`chemthermo.vlle` is removed** (deprecated since ADR-0013; ADR-0037).
|
|
17
|
+
`import chemthermo.vlle` raises `ModuleNotFoundError`; three-phase
|
|
18
|
+
equilibrium is found by `flash_tp` itself (`FlashSettings(max_phases=3)`,
|
|
19
|
+
the default). `flash_mode="vlle"` still raises `ModelError` with that pointer.
|
|
20
|
+
|
|
21
|
+
### Packaging
|
|
22
|
+
- PyPI metadata (summary, classifiers, URLs, keywords), `py.typed`, an sdist
|
|
23
|
+
that carries the library only (tests are excluded: some of their fixtures
|
|
24
|
+
are not redistributable). Supported and CI-tested on Python 3.11, 3.12 and
|
|
25
|
+
3.13; CI also runs `twine check --strict`.
|
|
26
|
+
|
|
27
|
+
### Documentation
|
|
28
|
+
- README rewritten as a summary: quick start, a capability table naming what
|
|
29
|
+
each claim was checked against, and the limits. The previous detail is in
|
|
30
|
+
`docs/` (installation, flash, stability, PC-SAFT, CLI, extending,
|
|
31
|
+
benchmarks). `CONTRIBUTING.md` added.
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
- PC-SAFT **association** temperature derivative: `residual_helmholtz_temperature_derivative`
|
|
35
|
+
and `residual_properties` now work for water, alcohols and their mixtures
|
|
36
|
+
(they raised `ModelError` in 0.3.0b1). Checked against FeOs residual entropy
|
|
37
|
+
and enthalpy (2.1e-15 with matched universal constants). ADR-0034 amendment,
|
|
38
|
+
ledger Case P-20.
|
|
39
|
+
|
|
40
|
+
### Fixed
|
|
41
|
+
- `flash_tp` (phi-phi): a split whose two phases are identical (the trivial
|
|
42
|
+
solution) no longer counts as converged, so the stability-seed ladder runs.
|
|
43
|
+
Around the Mw 53000 polyethylene ladder state, 29 of 135 neighbouring
|
|
44
|
+
pressures (+-64 ULP) refused; now none does. The full 2505-state
|
|
45
|
+
robustness map is unchanged field for field. ADR-0036.
|
|
46
|
+
|
|
47
|
+
### Changed
|
|
48
|
+
- `stability_tp`: on a `tpd` tie (within 1e-12) the reported minimizing trial
|
|
49
|
+
is one converged at least 1000x better, when one exists; flagged by
|
|
50
|
+
`diagnostics["minimizing_trial_tie_break"] = "residual"`. Changes only such
|
|
51
|
+
ties (none on any captured state). ADR-0035.
|
|
52
|
+
|
|
53
|
+
### Validation for this release
|
|
54
|
+
- Full 2505-state robustness map at `761fd57` (Linux): 2500 converge, 5
|
|
55
|
+
by-design gamma-phi refusals, 0 invariant violations; identical state by
|
|
56
|
+
state to the earlier macOS record at `f852726` (`benchmarks/robustness_761fd57.*`).
|
|
57
|
+
- Default suite on Python 3.11 / 3.12 / 3.13 (numpy 2.4.6 and 2.5.3), and
|
|
58
|
+
with the validation extras (teqp, FeOs, thermo) on 3.11.
|
|
59
|
+
|
|
60
|
+
## 0.3.0b1 (2026-09-25) - prerelease
|
|
61
|
+
|
|
62
|
+
The CLI reaches the equilibrium work, PC-SAFT gains residual caloric
|
|
63
|
+
properties, and the test suite is green on Linux for the first time. A
|
|
64
|
+
prerelease because the CLI contract (ADR-0033) and the two PC-SAFT methods
|
|
65
|
+
(ADR-0034) are new. Validation now spans two platforms (macOS arm64 inherited
|
|
66
|
+
at 0.2.0b1; Linux x86_64 on GitHub Actions and a cloud session for this
|
|
67
|
+
release), but this release's new code was exercised on Linux only.
|
|
68
|
+
There is no 0.2.0b2; its planned content (the cross-platform guards) is here.
|
|
69
|
+
|
|
70
|
+
### Compatibility
|
|
71
|
+
- Library: additive only (two new `PCSAFTEOS` methods). No existing number
|
|
72
|
+
moved: the new derivative is a separate function, and no solver was touched.
|
|
73
|
+
- CLI: `cli_schema_version` stays 1; previously valid invocations print
|
|
74
|
+
byte-identical output (checked on 11 invocations).
|
|
75
|
+
|
|
76
|
+
### Added
|
|
77
|
+
- **CLI `chemthermo stability-tp`**: tangent-plane stability of a feed with
|
|
78
|
+
Peng-Robinson or PC-SAFT (`--eos`), JSON or text; `stable` is reported with
|
|
79
|
+
`stability_scope = "bounded-trial-set"`; an `inconclusive` verdict exits 3
|
|
80
|
+
with the payload printed. ADR-0033.
|
|
81
|
+
- **CLI `tp-flash --eos {peng-robinson,pc-saft}` and `--max-phases N`**:
|
|
82
|
+
PC-SAFT flashes (packaged parameters, `kij = 0`, phi-phi) and an explicit
|
|
83
|
+
phase budget; three-phase answers use the existing name-keyed layout.
|
|
84
|
+
`cli_schema_version` stays 1 and every previously valid invocation prints
|
|
85
|
+
byte-identical output. `examples/cli/stability_and_multiphase.sh`.
|
|
86
|
+
|
|
87
|
+
- **PC-SAFT temperature derivative and residual properties** (non-associating):
|
|
88
|
+
`PCSAFTEOS.residual_helmholtz_temperature_derivative` and
|
|
89
|
+
`PCSAFTEOS.residual_properties` (`h_res`, `u_res`, `s_res_tv/tp`,
|
|
90
|
+
`g_res_tv/tp`, reduced). Checked against teqp `get_Ar10` (<= 5.2e-16 relative
|
|
91
|
+
over 14 states), Gibbs-Helmholtz through the fugacity route, and
|
|
92
|
+
`dH_vap = T dS_vap` at saturation. Associating mixtures raise `ModelError`.
|
|
93
|
+
ADR-0034; `examples/basic/pcsaft_residual_properties_demo.py`.
|
|
94
|
+
|
|
95
|
+
### Changed (tests and policy only; no library code)
|
|
96
|
+
- Guards that compare against floats captured on macOS arm64 are exact there
|
|
97
|
+
and, on any other platform, exact on every discrete field and bounded on
|
|
98
|
+
floats (1e-12 flash fixture, 5e-14 PC-SAFT literals); last-bit ties are
|
|
99
|
+
counted as ties. Makes the Linux CI and cloud runs green without weakening
|
|
100
|
+
the capture-platform check. ADR-0032; ledger Cases P-11 and P-17.
|
|
101
|
+
|
|
102
|
+
### Known limitations found
|
|
103
|
+
- One polymer ladder state (Mw 53000, 15 wt%, 8.1 MPa) refuses at 1 of 17
|
|
104
|
+
pressures within +-8 ULP of the grid point, and its solver route depends on
|
|
105
|
+
the last bit; every converged answer is the same tie line.
|
|
106
|
+
- `stability_tp` breaks an exact `tpd` tie by trial order, so the reported
|
|
107
|
+
`trial_composition` can be the less-converged of two tied trials (good to
|
|
108
|
+
the stationarity tolerance, 1e-10 residual).
|
|
109
|
+
|
|
110
|
+
## 0.2.0b1 (2026-09-25) - prerelease
|
|
111
|
+
|
|
112
|
+
First release of the phase-equilibrium campaign (121 commits and 38
|
|
113
|
+
distinct `Slice:` trailers since `v0.1.0`; ADR-0003 to ADR-0031). A prerelease because its
|
|
114
|
+
validation comes from one development machine plus the release gates of
|
|
115
|
+
ADR-0031, and because the CLI does not yet expose the equilibrium work.
|
|
116
|
+
|
|
117
|
+
### Added
|
|
118
|
+
- **Phase stability** `chemthermo.stability_tp` (Michelsen tangent-plane
|
|
119
|
+
distance) with `StabilityResult` / `StabilitySettings` / `StabilityTrial`,
|
|
120
|
+
incipient-phase compositions and per-trial diagnostics, for an equation of
|
|
121
|
+
state, an activity model alone (liquid-liquid), or an activity liquid against
|
|
122
|
+
an ideal-gas vapour (`vapor="ideal"`). ADR-0005, 0007, 0010, 0012, 0021, 0025.
|
|
123
|
+
- **Phase-count discovery in `flash_tp`**: one, two or three phases found by
|
|
124
|
+
stability analysis, a verified split, post-split stability of every phase,
|
|
125
|
+
and phase addition/removal (`FlashSettings.max_phases`, default 3), on the
|
|
126
|
+
EOS (`phi-phi`) and `modified-raoult` paths; liquid-liquid `gamma-gamma`
|
|
127
|
+
mode (two phases). ADR-0008, 0009, 0011, 0016, 0019, 0020, 0024, 0026, 0029.
|
|
128
|
+
- **PC-SAFT** `chemthermo.PCSAFTEOS`: Gross-Sadowski (2001) hard chain +
|
|
129
|
+
dispersion with the 2002 association term, analytic composition/density
|
|
130
|
+
derivatives, density roots, log-space fugacities for long chains; packaged
|
|
131
|
+
parameters for 11 non-associating compounds; user records incl. association
|
|
132
|
+
(`PCSAFTRecord`, `PCSAFTAssociationRecord`) and polymers via
|
|
133
|
+
`segments_per_g` + `Component.custom(...)`. ADR-0014, 0015, 0018, 0022.
|
|
134
|
+
- Peng-Robinson `kij` matrices (ADR-0006); phase labels by compressibility
|
|
135
|
+
(ADR-0017).
|
|
136
|
+
- CLI `chemthermo tp-flash` (`cli_schema_version` 1; Peng-Robinson phi-phi and
|
|
137
|
+
deprecated gamma-phi; exit codes 0/1/2/3). ADR-0003, 0004.
|
|
138
|
+
- Internal (not public API) benchmark and robustness harness
|
|
139
|
+
`python -m chemthermo.bench` (ADR-0023, 0027) and a call-local EOS solve memo
|
|
140
|
+
(ADR-0030).
|
|
141
|
+
|
|
142
|
+
### Changed / compatibility
|
|
143
|
+
- `NRTL.activity_coefficients` now implements the standard Renon-Prausnitz
|
|
144
|
+
equation (column sums); values for **asymmetric** parameters differ from
|
|
145
|
+
`v0.1.0`, which violated Gibbs-Duhem. Bug fix, not a model change.
|
|
146
|
+
- `flash_tp`: `eos` is optional; `flash_mode=None` infers the mode; phi-phi
|
|
147
|
+
phase detection defaults to `"tangent-plane"` (`"wilson-heuristic"` keeps the
|
|
148
|
+
old behaviour). Single-phase tangent-plane results no longer carry
|
|
149
|
+
`k_min`/`k_max`/`max_delta_k`/`rr_*` diagnostics.
|
|
150
|
+
- `flash_mode="gamma-phi"` and the `chemthermo.vlle` plugin boundary are
|
|
151
|
+
**deprecated** (docs only; still work). ADR-0013.
|
|
152
|
+
- Package version moves from `0.0.0` to `0.2.0b1`. (The existing `v0.1.0`
|
|
153
|
+
tag points at a commit whose metadata says `0.0.0`; it is left as published.)
|
|
154
|
+
|
|
155
|
+
### Known limitations
|
|
156
|
+
- `stability_tp` "stable" means no negative tangent-plane distance was found
|
|
157
|
+
from a bounded deterministic trial set - not a proof of global stability.
|
|
158
|
+
- PC-SAFT parameters and the association equation rest on secondary sources
|
|
159
|
+
(primary papers not read); polymer parameters are a labelled test fixture
|
|
160
|
+
from one secondary source and are **not packaged**; polymers are monodisperse.
|
|
161
|
+
- No temperature derivatives for PC-SAFT: no residual enthalpy/entropy or
|
|
162
|
+
caloric properties.
|
|
163
|
+
- The robustness map (2505 states, macOS arm64) refuses 5 states, all in the
|
|
164
|
+
deprecated gamma-phi path by design; it measures coverage, not correctness.
|
|
165
|
+
- The CLI does not expose stability, multiphase flash or PC-SAFT yet.
|
|
166
|
+
- Default test suite takes ~4-5 min; `pytest -m slow` and the full sweep
|
|
167
|
+
(~37 min) are not run by CI.
|
|
168
|
+
|
|
169
|
+
## 0.1.0
|
|
170
|
+
|
|
171
|
+
Tag `v0.1.0` on `a7a8ca7` (Feb 2026). No GitHub release was created and its
|
|
172
|
+
package metadata reads `0.0.0`.
|
chemthermo-0.4.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Ahmad Alkadri
|
|
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,11 @@
|
|
|
1
|
+
# sdist contents: the library, its metadata and user-facing docs.
|
|
2
|
+
# tests/ is excluded on purpose: several tests read fixtures that are not
|
|
3
|
+
# redistributable (e.g. DECHEMA-derived NRTL data, test-only by ADR policy),
|
|
4
|
+
# so a partial test tree would not run. Run the tests from a git checkout.
|
|
5
|
+
include LICENSE README.md CHANGELOG.md
|
|
6
|
+
prune tests
|
|
7
|
+
prune .agents
|
|
8
|
+
prune benchmarks
|
|
9
|
+
prune notebooks
|
|
10
|
+
prune database
|
|
11
|
+
prune tools
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: chemthermo
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: Phase equilibrium for chemical engineering: tangent-plane stability, multiphase TP flash, Peng-Robinson, PC-SAFT and NRTL.
|
|
5
|
+
Author: Ahmad Alkadri
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/AhmadAlkadri/Chemical-Thermodynamics
|
|
8
|
+
Project-URL: Documentation, https://github.com/AhmadAlkadri/Chemical-Thermodynamics/tree/main/docs
|
|
9
|
+
Project-URL: Changelog, https://github.com/AhmadAlkadri/Chemical-Thermodynamics/blob/main/CHANGELOG.md
|
|
10
|
+
Project-URL: Issues, https://github.com/AhmadAlkadri/Chemical-Thermodynamics/issues
|
|
11
|
+
Keywords: thermodynamics,phase equilibrium,flash,stability,PC-SAFT,Peng-Robinson,NRTL,chemical engineering
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Science/Research
|
|
14
|
+
Classifier: Intended Audience :: Education
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering :: Chemistry
|
|
22
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
23
|
+
Classifier: Typing :: Typed
|
|
24
|
+
Requires-Python: >=3.11
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
License-File: LICENSE
|
|
27
|
+
Requires-Dist: numpy>=1.24
|
|
28
|
+
Requires-Dist: pydantic>=2.0
|
|
29
|
+
Requires-Dist: bibtexparser<2,>=1.4.0
|
|
30
|
+
Provides-Extra: dev
|
|
31
|
+
Requires-Dist: build>=1.2.2; extra == "dev"
|
|
32
|
+
Requires-Dist: twine>=5; extra == "dev"
|
|
33
|
+
Requires-Dist: nbstripout>=0.7.1; extra == "dev"
|
|
34
|
+
Requires-Dist: pytest>=7.4; extra == "dev"
|
|
35
|
+
Requires-Dist: ruff==0.14.13; extra == "dev"
|
|
36
|
+
Requires-Dist: pyright>=1.1.350; extra == "dev"
|
|
37
|
+
Provides-Extra: validation
|
|
38
|
+
Requires-Dist: thermo>=0.6.0; extra == "validation"
|
|
39
|
+
Requires-Dist: teqp>=0.23; extra == "validation"
|
|
40
|
+
Requires-Dist: feos>=0.10; extra == "validation"
|
|
41
|
+
Dynamic: license-file
|
|
42
|
+
|
|
43
|
+
# chemthermo
|
|
44
|
+
|
|
45
|
+
Phase equilibrium for chemical engineering in Python: tangent-plane
|
|
46
|
+
stability, multiphase TP flash, Peng-Robinson, PC-SAFT (with association and
|
|
47
|
+
polymers) and NRTL, in SI units, with every numerical claim traceable to a
|
|
48
|
+
recorded cross-check.
|
|
49
|
+
|
|
50
|
+
**Status: beta (0.4.0).** The science is checked against independent
|
|
51
|
+
implementations, but the public API may still change before 1.0. Python
|
|
52
|
+
>= 3.11; tested on macOS arm64 and Linux x86_64. MIT licence.
|
|
53
|
+
|
|
54
|
+
## Install
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
pip install chemthermo
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
or pin a tagged commit from GitHub:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
pip install "chemthermo @ git+https://github.com/AhmadAlkadri/Chemical-Thermodynamics.git@v0.4.0"
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Runtime dependencies: numpy, pydantic, bibtexparser (< 2).
|
|
67
|
+
|
|
68
|
+
## Quick start
|
|
69
|
+
|
|
70
|
+
A flash that decides for itself how many phases there are:
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
import chemthermo as ct
|
|
74
|
+
|
|
75
|
+
mixture = ct.Mixture.from_database(["Methane", "Ethane", "Propane"], [0.5, 0.3, 0.2])
|
|
76
|
+
result = ct.flash_tp(mixture, temperature_K=240.0, pressure_Pa=3.0e6, eos=ct.PengRobinsonEOS())
|
|
77
|
+
|
|
78
|
+
print(result.phase_names()) # ['liquid', 'vapor']
|
|
79
|
+
print(result.vapor_fraction) # 0.468...
|
|
80
|
+
print(result.phases["vapor"].composition.fractions)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Stability of a feed, and the phase it would split off:
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
check = ct.stability_tp(
|
|
87
|
+
ct.Mixture.from_database(["Methane", "n-Hexane"], [0.5, 0.5]),
|
|
88
|
+
temperature_K=300.0, pressure_Pa=2.0e6, eos=ct.PengRobinsonEOS(),
|
|
89
|
+
)
|
|
90
|
+
print(check.status, check.tpd_min) # unstable -1.2558...
|
|
91
|
+
print(check.phase_branch, check.trial_composition)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Three liquids, PC-SAFT, and residual properties:
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
from chemthermo.eos import PCSAFTEOS
|
|
98
|
+
|
|
99
|
+
three = ct.flash_tp(
|
|
100
|
+
ct.Mixture.from_database(["Water", "Ethanol", "n-Hexane"], [0.2, 0.4, 0.4]),
|
|
101
|
+
temperature_K=280.0, pressure_Pa=101325.0, eos=ct.PengRobinsonEOS(),
|
|
102
|
+
)
|
|
103
|
+
print(three.phase_names()) # ['liquid1', 'liquid2', 'liquid3']
|
|
104
|
+
|
|
105
|
+
water = PCSAFTEOS(components=("Water",))
|
|
106
|
+
rho = max(water.density_roots(temperature_K=300.0, pressure_Pa=1.0e5, composition=[1.0]))
|
|
107
|
+
props = water.residual_properties(temperature_K=300.0, density_mol_m3=rho, composition=[1.0])
|
|
108
|
+
print(props["h_res"], props["s_res_tp"]) # H^res/RT and S^res/R (ideal gas at same T, P)
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
From the command line:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
chemthermo tp-flash --components Methane,Ethane,Propane --z 0.5,0.3,0.2 \
|
|
115
|
+
--temperature-k 240 --pressure-pa 3e6 --format json
|
|
116
|
+
chemthermo stability-tp --components Methane,n-Hexane --z 0.5,0.5 \
|
|
117
|
+
--temperature-k 300 --pressure-pa 2e6 --eos pc-saft
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## What it does
|
|
121
|
+
|
|
122
|
+
| Capability | Models | Checked against (ledger case) |
|
|
123
|
+
| --- | --- | --- |
|
|
124
|
+
| Tangent-plane stability, incipient-phase composition (`stability_tp`) | Peng-Robinson, PC-SAFT, NRTL (liquid-liquid), NRTL + ideal gas | `thermo` 0.6 Michelsen test, same verdicts (S-4); Tessier et al. (2000) published global minima to 2e-11 (S-6, S-7); teqp (P-4) |
|
|
125
|
+
| TP flash with automatic phase count, 1-3 phases (`flash_tp`) | Peng-Robinson and PC-SAFT (`phi-phi`), NRTL (`gamma-gamma`), NRTL + Raoult (`modified-raoult`) | `thermo` `FlashVL` (F-1); teqp's traced PC-SAFT isotherm, tie lines to 2e-9 (P-5); FeOs flash and chemical potentials (P-7, P-8); a published multiphase Rachford-Rice table (V-4); a ternary VLLE tie triangle (V-1) |
|
|
126
|
+
| Peng-Robinson with per-pair `kij` | cubic EOS | `thermo` PRMIX (K-1); agreement floored at ~1e-4 in `ln phi` by chemthermo's rounded constants (S-4) |
|
|
127
|
+
| PC-SAFT residual Helmholtz, `Z`, `ln phi`, density roots | Gross & Sadowski 2001 | teqp, better than 3e-14 (P-1, P-3) |
|
|
128
|
+
| PC-SAFT association (2B scheme) | Gross & Sadowski 2002 | FeOs, association term to 3e-15 (P-6) |
|
|
129
|
+
| PC-SAFT polymers (segments per mass, long chains in log space) | monodisperse chains | FeOs, 5e-12 with matched constants (P-12 - P-14) |
|
|
130
|
+
| PC-SAFT residual `H`, `S`, `U`, `G` and `d(A^res/RT)/dT` | incl. association | teqp `Ar10` to 5e-16 (P-19); FeOs residual entropy/enthalpy to 2e-15 (P-20) |
|
|
131
|
+
| NRTL activity coefficients | NRTL | `thermo` NRTL to 9e-16 (N-2) |
|
|
132
|
+
| Command line: `tp-flash`, `stability-tp` | PR, PC-SAFT | golden JSON fixtures; exit-code contract |
|
|
133
|
+
|
|
134
|
+
Packaged data: critical constants, acentric factors and Antoine coefficients
|
|
135
|
+
for **82 components** (from Koretsky, *Engineering and Chemical
|
|
136
|
+
Thermodynamics*); PC-SAFT parameters for **16** (11 non-associating, plus
|
|
137
|
+
water, methanol, ethanol, 1-propanol and n-butanol with 2B association).
|
|
138
|
+
|
|
139
|
+
**What "checked" means here.** The comparisons above are code against
|
|
140
|
+
independent implementations (teqp, FeOs, `thermo`) or published worked
|
|
141
|
+
problems. They show the equations are implemented correctly. They say nothing
|
|
142
|
+
about how well a model with these parameters matches experiment, and nothing
|
|
143
|
+
in this repository claims that.
|
|
144
|
+
|
|
145
|
+
## Limits, stated plainly
|
|
146
|
+
|
|
147
|
+
- **"Stable" is not a proof.** It means no negative tangent-plane distance was
|
|
148
|
+
found from a deterministic set of trial compositions. A phase that no trial
|
|
149
|
+
reaches can be missed, and a flash's phase count inherits that limit.
|
|
150
|
+
- **Bring your own interaction parameters.** No binary `kij` table ships.
|
|
151
|
+
The two packaged NRTL pairs are **synthetic placeholders** for demos: real
|
|
152
|
+
NRTL work needs your own parameters (`NRTLParameters.from_pairs`). PC-SAFT
|
|
153
|
+
with `kij = 0` gets water / hydrocarbon mutual solubilities badly wrong.
|
|
154
|
+
- **Residual properties only.** No ideal-gas heat capacities are packaged, so
|
|
155
|
+
no total enthalpy, entropy or `Cp`; no `Cp^res` yet.
|
|
156
|
+
- **PC-SAFT scope:** no polar terms; only the 2B association scheme is
|
|
157
|
+
validated; no induced association; polymers are monodisperse; no polymer
|
|
158
|
+
parameters are packaged.
|
|
159
|
+
- **Modified Raoult is a low-pressure model** (ideal vapour, no Poynting
|
|
160
|
+
correction); Antoine ranges are enforced, never extrapolated.
|
|
161
|
+
- **Cost:** a Peng-Robinson or activity-model flash takes milliseconds; PC-SAFT
|
|
162
|
+
flashes take up to a few seconds (polymer and associating states the
|
|
163
|
+
longest), and a three-phase PC-SAFT flash about 35 s.
|
|
164
|
+
- **Deprecated:** `flash_mode="gamma-phi"` (kept for the CLI v1 contract;
|
|
165
|
+
emits `DeprecationWarning`). `chemthermo.vlle` was removed in 0.4.0.
|
|
166
|
+
|
|
167
|
+
Longer, model-specific limits are in the docs below.
|
|
168
|
+
|
|
169
|
+
## Documentation
|
|
170
|
+
|
|
171
|
+
- [Installation and development setup](https://github.com/AhmadAlkadri/Chemical-Thermodynamics/blob/main/docs/installation.md)
|
|
172
|
+
- [TP flash](https://github.com/AhmadAlkadri/Chemical-Thermodynamics/blob/main/docs/flash.md) - phase detection, flash modes, three phases, `kij`, NRTL
|
|
173
|
+
- [Phase stability](https://github.com/AhmadAlkadri/Chemical-Thermodynamics/blob/main/docs/stability.md)
|
|
174
|
+
- [PC-SAFT](https://github.com/AhmadAlkadri/Chemical-Thermodynamics/blob/main/docs/pcsaft.md) - parameters, association, polymers, residual properties, limits and their validation
|
|
175
|
+
- [Command line](https://github.com/AhmadAlkadri/Chemical-Thermodynamics/blob/main/docs/cli.md)
|
|
176
|
+
- [Extending with a new equation of state](https://github.com/AhmadAlkadri/Chemical-Thermodynamics/blob/main/docs/extending.md)
|
|
177
|
+
- [Benchmarks and the robustness map](https://github.com/AhmadAlkadri/Chemical-Thermodynamics/blob/main/docs/benchmarks.md)
|
|
178
|
+
- Runnable scripts: [`examples/`](https://github.com/AhmadAlkadri/Chemical-Thermodynamics/blob/main/examples/README.md); notebooks: [`notebooks/`](https://github.com/AhmadAlkadri/Chemical-Thermodynamics/blob/main/notebooks/README.md)
|
|
179
|
+
- [Changelog](https://github.com/AhmadAlkadri/Chemical-Thermodynamics/blob/main/CHANGELOG.md)
|
|
180
|
+
|
|
181
|
+
## How it is validated and developed
|
|
182
|
+
|
|
183
|
+
Every number quoted above has an entry in the validation ledger,
|
|
184
|
+
[`.agents/brain/validation-cases.md`](https://github.com/AhmadAlkadri/Chemical-Thermodynamics/blob/main/.agents/brain/validation-cases.md), with
|
|
185
|
+
its source, tolerance, achieved value and test. Design decisions are
|
|
186
|
+
recorded as ADRs in [`.agents/brain/adr/`](https://github.com/AhmadAlkadri/Chemical-Thermodynamics/tree/main/.agents/brain/adr/). The tests that
|
|
187
|
+
compare against teqp, FeOs and `thermo` run with `pip install -e
|
|
188
|
+
".[validation]"` and skip cleanly otherwise. A 2505-state robustness map
|
|
189
|
+
(`python -m chemthermo.bench robustness`) sweeps every model family; its only
|
|
190
|
+
refusals are 5 states of the deprecated gamma-phi path.
|
|
191
|
+
|
|
192
|
+
Contributions: see [CONTRIBUTING.md](https://github.com/AhmadAlkadri/Chemical-Thermodynamics/blob/main/CONTRIBUTING.md).
|
|
193
|
+
|
|
194
|
+
## Licence
|
|
195
|
+
|
|
196
|
+
MIT - see [LICENSE](https://github.com/AhmadAlkadri/Chemical-Thermodynamics/blob/main/LICENSE).
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# chemthermo
|
|
2
|
+
|
|
3
|
+
Phase equilibrium for chemical engineering in Python: tangent-plane
|
|
4
|
+
stability, multiphase TP flash, Peng-Robinson, PC-SAFT (with association and
|
|
5
|
+
polymers) and NRTL, in SI units, with every numerical claim traceable to a
|
|
6
|
+
recorded cross-check.
|
|
7
|
+
|
|
8
|
+
**Status: beta (0.4.0).** The science is checked against independent
|
|
9
|
+
implementations, but the public API may still change before 1.0. Python
|
|
10
|
+
>= 3.11; tested on macOS arm64 and Linux x86_64. MIT licence.
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
pip install chemthermo
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
or pin a tagged commit from GitHub:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pip install "chemthermo @ git+https://github.com/AhmadAlkadri/Chemical-Thermodynamics.git@v0.4.0"
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Runtime dependencies: numpy, pydantic, bibtexparser (< 2).
|
|
25
|
+
|
|
26
|
+
## Quick start
|
|
27
|
+
|
|
28
|
+
A flash that decides for itself how many phases there are:
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
import chemthermo as ct
|
|
32
|
+
|
|
33
|
+
mixture = ct.Mixture.from_database(["Methane", "Ethane", "Propane"], [0.5, 0.3, 0.2])
|
|
34
|
+
result = ct.flash_tp(mixture, temperature_K=240.0, pressure_Pa=3.0e6, eos=ct.PengRobinsonEOS())
|
|
35
|
+
|
|
36
|
+
print(result.phase_names()) # ['liquid', 'vapor']
|
|
37
|
+
print(result.vapor_fraction) # 0.468...
|
|
38
|
+
print(result.phases["vapor"].composition.fractions)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Stability of a feed, and the phase it would split off:
|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
check = ct.stability_tp(
|
|
45
|
+
ct.Mixture.from_database(["Methane", "n-Hexane"], [0.5, 0.5]),
|
|
46
|
+
temperature_K=300.0, pressure_Pa=2.0e6, eos=ct.PengRobinsonEOS(),
|
|
47
|
+
)
|
|
48
|
+
print(check.status, check.tpd_min) # unstable -1.2558...
|
|
49
|
+
print(check.phase_branch, check.trial_composition)
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Three liquids, PC-SAFT, and residual properties:
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
from chemthermo.eos import PCSAFTEOS
|
|
56
|
+
|
|
57
|
+
three = ct.flash_tp(
|
|
58
|
+
ct.Mixture.from_database(["Water", "Ethanol", "n-Hexane"], [0.2, 0.4, 0.4]),
|
|
59
|
+
temperature_K=280.0, pressure_Pa=101325.0, eos=ct.PengRobinsonEOS(),
|
|
60
|
+
)
|
|
61
|
+
print(three.phase_names()) # ['liquid1', 'liquid2', 'liquid3']
|
|
62
|
+
|
|
63
|
+
water = PCSAFTEOS(components=("Water",))
|
|
64
|
+
rho = max(water.density_roots(temperature_K=300.0, pressure_Pa=1.0e5, composition=[1.0]))
|
|
65
|
+
props = water.residual_properties(temperature_K=300.0, density_mol_m3=rho, composition=[1.0])
|
|
66
|
+
print(props["h_res"], props["s_res_tp"]) # H^res/RT and S^res/R (ideal gas at same T, P)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
From the command line:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
chemthermo tp-flash --components Methane,Ethane,Propane --z 0.5,0.3,0.2 \
|
|
73
|
+
--temperature-k 240 --pressure-pa 3e6 --format json
|
|
74
|
+
chemthermo stability-tp --components Methane,n-Hexane --z 0.5,0.5 \
|
|
75
|
+
--temperature-k 300 --pressure-pa 2e6 --eos pc-saft
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## What it does
|
|
79
|
+
|
|
80
|
+
| Capability | Models | Checked against (ledger case) |
|
|
81
|
+
| --- | --- | --- |
|
|
82
|
+
| Tangent-plane stability, incipient-phase composition (`stability_tp`) | Peng-Robinson, PC-SAFT, NRTL (liquid-liquid), NRTL + ideal gas | `thermo` 0.6 Michelsen test, same verdicts (S-4); Tessier et al. (2000) published global minima to 2e-11 (S-6, S-7); teqp (P-4) |
|
|
83
|
+
| TP flash with automatic phase count, 1-3 phases (`flash_tp`) | Peng-Robinson and PC-SAFT (`phi-phi`), NRTL (`gamma-gamma`), NRTL + Raoult (`modified-raoult`) | `thermo` `FlashVL` (F-1); teqp's traced PC-SAFT isotherm, tie lines to 2e-9 (P-5); FeOs flash and chemical potentials (P-7, P-8); a published multiphase Rachford-Rice table (V-4); a ternary VLLE tie triangle (V-1) |
|
|
84
|
+
| Peng-Robinson with per-pair `kij` | cubic EOS | `thermo` PRMIX (K-1); agreement floored at ~1e-4 in `ln phi` by chemthermo's rounded constants (S-4) |
|
|
85
|
+
| PC-SAFT residual Helmholtz, `Z`, `ln phi`, density roots | Gross & Sadowski 2001 | teqp, better than 3e-14 (P-1, P-3) |
|
|
86
|
+
| PC-SAFT association (2B scheme) | Gross & Sadowski 2002 | FeOs, association term to 3e-15 (P-6) |
|
|
87
|
+
| PC-SAFT polymers (segments per mass, long chains in log space) | monodisperse chains | FeOs, 5e-12 with matched constants (P-12 - P-14) |
|
|
88
|
+
| PC-SAFT residual `H`, `S`, `U`, `G` and `d(A^res/RT)/dT` | incl. association | teqp `Ar10` to 5e-16 (P-19); FeOs residual entropy/enthalpy to 2e-15 (P-20) |
|
|
89
|
+
| NRTL activity coefficients | NRTL | `thermo` NRTL to 9e-16 (N-2) |
|
|
90
|
+
| Command line: `tp-flash`, `stability-tp` | PR, PC-SAFT | golden JSON fixtures; exit-code contract |
|
|
91
|
+
|
|
92
|
+
Packaged data: critical constants, acentric factors and Antoine coefficients
|
|
93
|
+
for **82 components** (from Koretsky, *Engineering and Chemical
|
|
94
|
+
Thermodynamics*); PC-SAFT parameters for **16** (11 non-associating, plus
|
|
95
|
+
water, methanol, ethanol, 1-propanol and n-butanol with 2B association).
|
|
96
|
+
|
|
97
|
+
**What "checked" means here.** The comparisons above are code against
|
|
98
|
+
independent implementations (teqp, FeOs, `thermo`) or published worked
|
|
99
|
+
problems. They show the equations are implemented correctly. They say nothing
|
|
100
|
+
about how well a model with these parameters matches experiment, and nothing
|
|
101
|
+
in this repository claims that.
|
|
102
|
+
|
|
103
|
+
## Limits, stated plainly
|
|
104
|
+
|
|
105
|
+
- **"Stable" is not a proof.** It means no negative tangent-plane distance was
|
|
106
|
+
found from a deterministic set of trial compositions. A phase that no trial
|
|
107
|
+
reaches can be missed, and a flash's phase count inherits that limit.
|
|
108
|
+
- **Bring your own interaction parameters.** No binary `kij` table ships.
|
|
109
|
+
The two packaged NRTL pairs are **synthetic placeholders** for demos: real
|
|
110
|
+
NRTL work needs your own parameters (`NRTLParameters.from_pairs`). PC-SAFT
|
|
111
|
+
with `kij = 0` gets water / hydrocarbon mutual solubilities badly wrong.
|
|
112
|
+
- **Residual properties only.** No ideal-gas heat capacities are packaged, so
|
|
113
|
+
no total enthalpy, entropy or `Cp`; no `Cp^res` yet.
|
|
114
|
+
- **PC-SAFT scope:** no polar terms; only the 2B association scheme is
|
|
115
|
+
validated; no induced association; polymers are monodisperse; no polymer
|
|
116
|
+
parameters are packaged.
|
|
117
|
+
- **Modified Raoult is a low-pressure model** (ideal vapour, no Poynting
|
|
118
|
+
correction); Antoine ranges are enforced, never extrapolated.
|
|
119
|
+
- **Cost:** a Peng-Robinson or activity-model flash takes milliseconds; PC-SAFT
|
|
120
|
+
flashes take up to a few seconds (polymer and associating states the
|
|
121
|
+
longest), and a three-phase PC-SAFT flash about 35 s.
|
|
122
|
+
- **Deprecated:** `flash_mode="gamma-phi"` (kept for the CLI v1 contract;
|
|
123
|
+
emits `DeprecationWarning`). `chemthermo.vlle` was removed in 0.4.0.
|
|
124
|
+
|
|
125
|
+
Longer, model-specific limits are in the docs below.
|
|
126
|
+
|
|
127
|
+
## Documentation
|
|
128
|
+
|
|
129
|
+
- [Installation and development setup](https://github.com/AhmadAlkadri/Chemical-Thermodynamics/blob/main/docs/installation.md)
|
|
130
|
+
- [TP flash](https://github.com/AhmadAlkadri/Chemical-Thermodynamics/blob/main/docs/flash.md) - phase detection, flash modes, three phases, `kij`, NRTL
|
|
131
|
+
- [Phase stability](https://github.com/AhmadAlkadri/Chemical-Thermodynamics/blob/main/docs/stability.md)
|
|
132
|
+
- [PC-SAFT](https://github.com/AhmadAlkadri/Chemical-Thermodynamics/blob/main/docs/pcsaft.md) - parameters, association, polymers, residual properties, limits and their validation
|
|
133
|
+
- [Command line](https://github.com/AhmadAlkadri/Chemical-Thermodynamics/blob/main/docs/cli.md)
|
|
134
|
+
- [Extending with a new equation of state](https://github.com/AhmadAlkadri/Chemical-Thermodynamics/blob/main/docs/extending.md)
|
|
135
|
+
- [Benchmarks and the robustness map](https://github.com/AhmadAlkadri/Chemical-Thermodynamics/blob/main/docs/benchmarks.md)
|
|
136
|
+
- Runnable scripts: [`examples/`](https://github.com/AhmadAlkadri/Chemical-Thermodynamics/blob/main/examples/README.md); notebooks: [`notebooks/`](https://github.com/AhmadAlkadri/Chemical-Thermodynamics/blob/main/notebooks/README.md)
|
|
137
|
+
- [Changelog](https://github.com/AhmadAlkadri/Chemical-Thermodynamics/blob/main/CHANGELOG.md)
|
|
138
|
+
|
|
139
|
+
## How it is validated and developed
|
|
140
|
+
|
|
141
|
+
Every number quoted above has an entry in the validation ledger,
|
|
142
|
+
[`.agents/brain/validation-cases.md`](https://github.com/AhmadAlkadri/Chemical-Thermodynamics/blob/main/.agents/brain/validation-cases.md), with
|
|
143
|
+
its source, tolerance, achieved value and test. Design decisions are
|
|
144
|
+
recorded as ADRs in [`.agents/brain/adr/`](https://github.com/AhmadAlkadri/Chemical-Thermodynamics/tree/main/.agents/brain/adr/). The tests that
|
|
145
|
+
compare against teqp, FeOs and `thermo` run with `pip install -e
|
|
146
|
+
".[validation]"` and skip cleanly otherwise. A 2505-state robustness map
|
|
147
|
+
(`python -m chemthermo.bench robustness`) sweeps every model family; its only
|
|
148
|
+
refusals are 5 states of the deprecated gamma-phi path.
|
|
149
|
+
|
|
150
|
+
Contributions: see [CONTRIBUTING.md](https://github.com/AhmadAlkadri/Chemical-Thermodynamics/blob/main/CONTRIBUTING.md).
|
|
151
|
+
|
|
152
|
+
## Licence
|
|
153
|
+
|
|
154
|
+
MIT - see [LICENSE](https://github.com/AhmadAlkadri/Chemical-Thermodynamics/blob/main/LICENSE).
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "chemthermo"
|
|
7
|
+
version = "0.4.0"
|
|
8
|
+
description = "Phase equilibrium for chemical engineering: tangent-plane stability, multiphase TP flash, Peng-Robinson, PC-SAFT and NRTL."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.11"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
authors = [{ name = "Ahmad Alkadri" }]
|
|
14
|
+
keywords = [
|
|
15
|
+
"thermodynamics",
|
|
16
|
+
"phase equilibrium",
|
|
17
|
+
"flash",
|
|
18
|
+
"stability",
|
|
19
|
+
"PC-SAFT",
|
|
20
|
+
"Peng-Robinson",
|
|
21
|
+
"NRTL",
|
|
22
|
+
"chemical engineering",
|
|
23
|
+
]
|
|
24
|
+
classifiers = [
|
|
25
|
+
"Development Status :: 4 - Beta",
|
|
26
|
+
"Intended Audience :: Science/Research",
|
|
27
|
+
"Intended Audience :: Education",
|
|
28
|
+
"Operating System :: OS Independent",
|
|
29
|
+
"Programming Language :: Python :: 3",
|
|
30
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
31
|
+
"Programming Language :: Python :: 3.11",
|
|
32
|
+
"Programming Language :: Python :: 3.12",
|
|
33
|
+
"Programming Language :: Python :: 3.13",
|
|
34
|
+
"Topic :: Scientific/Engineering :: Chemistry",
|
|
35
|
+
"Topic :: Scientific/Engineering :: Physics",
|
|
36
|
+
"Typing :: Typed",
|
|
37
|
+
]
|
|
38
|
+
dependencies = [
|
|
39
|
+
"numpy>=1.24",
|
|
40
|
+
"pydantic>=2.0",
|
|
41
|
+
"bibtexparser>=1.4.0,<2",
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
[project.urls]
|
|
45
|
+
Homepage = "https://github.com/AhmadAlkadri/Chemical-Thermodynamics"
|
|
46
|
+
Documentation = "https://github.com/AhmadAlkadri/Chemical-Thermodynamics/tree/main/docs"
|
|
47
|
+
Changelog = "https://github.com/AhmadAlkadri/Chemical-Thermodynamics/blob/main/CHANGELOG.md"
|
|
48
|
+
Issues = "https://github.com/AhmadAlkadri/Chemical-Thermodynamics/issues"
|
|
49
|
+
|
|
50
|
+
[project.scripts]
|
|
51
|
+
chemthermo = "chemthermo.cli:main"
|
|
52
|
+
|
|
53
|
+
[project.optional-dependencies]
|
|
54
|
+
dev = [
|
|
55
|
+
"build>=1.2.2",
|
|
56
|
+
"twine>=5",
|
|
57
|
+
"nbstripout>=0.7.1",
|
|
58
|
+
"pytest>=7.4",
|
|
59
|
+
"ruff==0.14.13",
|
|
60
|
+
"pyright>=1.1.350",
|
|
61
|
+
]
|
|
62
|
+
validation = [
|
|
63
|
+
"thermo>=0.6.0",
|
|
64
|
+
"teqp>=0.23",
|
|
65
|
+
# FeOs is the reference for the PC-SAFT **association** term (ADR-0018):
|
|
66
|
+
# teqp's PCSAFT kind does not implement association. It pulls in its own
|
|
67
|
+
# units package, whose PyPI name is `si-units` and whose import name is
|
|
68
|
+
# `si_units`; it is not listed separately because feos depends on it.
|
|
69
|
+
"feos>=0.10",
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
[tool.pytest.ini_options]
|
|
73
|
+
markers = [
|
|
74
|
+
"slow: a full validation grid whose representative subset runs by default (e.g. the 188-state PC-SAFT grid of Case F-4), or a repetition of a capability the default run already covers (ADR-0020); deselected by default (see addopts below), opt in with `pytest -q -m slow`. Never the only test of a capability - see `.agents/dev-contract.md`",
|
|
75
|
+
]
|
|
76
|
+
# Deselected, not skipped, by default: `-m slow` on the command line overrides
|
|
77
|
+
# this addopts entry (pytest keeps the last `-m` value), so `pytest -q -m slow`
|
|
78
|
+
# runs exactly the slow-marked tests and nothing else. See
|
|
79
|
+
# `.agents/dev-contract.md` for the full-grid command and CI's choice.
|
|
80
|
+
addopts = "-m 'not slow'"
|
|
81
|
+
|
|
82
|
+
[tool.setuptools]
|
|
83
|
+
package-dir = { "" = "src" }
|
|
84
|
+
|
|
85
|
+
[tool.setuptools.packages.find]
|
|
86
|
+
where = ["src"]
|
|
87
|
+
|
|
88
|
+
[tool.setuptools.package-data]
|
|
89
|
+
"chemthermo" = ["py.typed"]
|
|
90
|
+
"chemthermo.data" = ["components.json", "references.bib"]
|
|
91
|
+
"chemthermo.parameters" = ["data/activity/nrtl.json", "data/eos/pcsaft.json"]
|
|
92
|
+
|
|
93
|
+
[tool.ruff]
|
|
94
|
+
target-version = "py311"
|
|
95
|
+
line-length = 100
|
|
96
|
+
exclude = [
|
|
97
|
+
"database",
|
|
98
|
+
"notebooks",
|
|
99
|
+
]
|
|
100
|
+
|
|
101
|
+
[tool.ruff.lint]
|
|
102
|
+
ignore = ["E501"]
|
|
103
|
+
extend-select = ["I"]
|