ecpa-flash 1.0.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.
- ecpa_flash-1.0.0/LICENSE +21 -0
- ecpa_flash-1.0.0/PKG-INFO +375 -0
- ecpa_flash-1.0.0/README.md +323 -0
- ecpa_flash-1.0.0/code/CPA.py +2309 -0
- ecpa_flash-1.0.0/code/co2brine_simulator.py +947 -0
- ecpa_flash-1.0.0/code/cpa_worker.py +89 -0
- ecpa_flash-1.0.0/code/ecpa/__init__.py +19 -0
- ecpa_flash-1.0.0/code/ecpa/constants.py +98 -0
- ecpa_flash-1.0.0/code/ecpa/elv.py +291 -0
- ecpa_flash-1.0.0/code/ecpa/envelope.py +407 -0
- ecpa_flash-1.0.0/code/ecpa/exp_data.py +147 -0
- ecpa_flash-1.0.0/code/ecpa/flash.py +1442 -0
- ecpa_flash-1.0.0/code/ecpa/flash_simplified.py +285 -0
- ecpa_flash-1.0.0/code/ecpa/guess_table.py +145 -0
- ecpa_flash-1.0.0/code/ecpa/nn_flash.py +471 -0
- ecpa_flash-1.0.0/code/ecpa/parameters.py +44 -0
- ecpa_flash-1.0.0/code/ecpa/plotting.py +498 -0
- ecpa_flash-1.0.0/code/ecpa/scan.py +554 -0
- ecpa_flash-1.0.0/code/ecpa/solution_table.py +521 -0
- ecpa_flash-1.0.0/code/ecpa/stability.py +1735 -0
- ecpa_flash-1.0.0/code/ecpa/utils.py +174 -0
- ecpa_flash-1.0.0/code/ecpa/validate_co2h2o.py +1486 -0
- ecpa_flash-1.0.0/code/ecpa/validate_nacl.py +916 -0
- ecpa_flash-1.0.0/code/ecpa/warmstart.py +478 -0
- ecpa_flash-1.0.0/code/ecpa_flash.egg-info/PKG-INFO +375 -0
- ecpa_flash-1.0.0/code/ecpa_flash.egg-info/SOURCES.txt +31 -0
- ecpa_flash-1.0.0/code/ecpa_flash.egg-info/dependency_links.txt +1 -0
- ecpa_flash-1.0.0/code/ecpa_flash.egg-info/requires.txt +11 -0
- ecpa_flash-1.0.0/code/ecpa_flash.egg-info/top_level.txt +4 -0
- ecpa_flash-1.0.0/pyproject.toml +52 -0
- ecpa_flash-1.0.0/setup.cfg +4 -0
- ecpa_flash-1.0.0/tests/test_flash.py +53 -0
- ecpa_flash-1.0.0/tests/test_package.py +25 -0
ecpa_flash-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Joachim Moortgat, Felipe Mourão Coelho, Abbas Firoozabadi
|
|
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,375 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ecpa-flash
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Phase stability and flash calculations for CO2 + H2O + NaCl with the electrolyte Cubic-Plus-Association (eCPA) equation of state
|
|
5
|
+
Author: Felipe Mourão Coelho, Abbas Firoozabadi
|
|
6
|
+
Author-email: Joachim Moortgat <moortgat.1@osu.edu>
|
|
7
|
+
License: MIT License
|
|
8
|
+
|
|
9
|
+
Copyright (c) 2026 Joachim Moortgat, Felipe Mourão Coelho, Abbas Firoozabadi
|
|
10
|
+
|
|
11
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
12
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
13
|
+
in the Software without restriction, including without limitation the rights
|
|
14
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
15
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
16
|
+
furnished to do so, subject to the following conditions:
|
|
17
|
+
|
|
18
|
+
The above copyright notice and this permission notice shall be included in all
|
|
19
|
+
copies or substantial portions of the Software.
|
|
20
|
+
|
|
21
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
22
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
23
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
24
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
25
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
26
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
27
|
+
SOFTWARE.
|
|
28
|
+
|
|
29
|
+
Project-URL: Repository, https://github.com/jmoortgat/CPA_and_eCPA_flash
|
|
30
|
+
Project-URL: Issues, https://github.com/jmoortgat/CPA_and_eCPA_flash/issues
|
|
31
|
+
Keywords: equation of state,CPA,electrolyte,flash calculation,phase equilibria,CO2 storage,geothermal,reservoir simulation
|
|
32
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
33
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
34
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
35
|
+
Classifier: Operating System :: MacOS
|
|
36
|
+
Classifier: Intended Audience :: Science/Research
|
|
37
|
+
Classifier: Topic :: Scientific/Engineering :: Chemistry
|
|
38
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
39
|
+
Requires-Python: >=3.11
|
|
40
|
+
Description-Content-Type: text/markdown
|
|
41
|
+
License-File: LICENSE
|
|
42
|
+
Requires-Dist: numpy>=1.24
|
|
43
|
+
Requires-Dist: scipy>=1.10
|
|
44
|
+
Requires-Dist: pandas>=2.0
|
|
45
|
+
Requires-Dist: pyarrow>=14
|
|
46
|
+
Requires-Dist: matplotlib>=3.7
|
|
47
|
+
Provides-Extra: nn
|
|
48
|
+
Requires-Dist: torch>=2.0; extra == "nn"
|
|
49
|
+
Provides-Extra: test
|
|
50
|
+
Requires-Dist: pytest>=7; extra == "test"
|
|
51
|
+
Dynamic: license-file
|
|
52
|
+
|
|
53
|
+
# eCPA Flash
|
|
54
|
+
|
|
55
|
+
### Fast, robust phase equilibrium for CO₂ + H₂O + NaCl
|
|
56
|
+
|
|
57
|
+
[](LICENSE)
|
|
58
|
+
[](https://www.python.org/)
|
|
59
|
+
[](https://github.com/jmoortgat/CPA_and_eCPA_flash/actions/workflows/tests.yml)
|
|
60
|
+
[](https://pubs.acs.org/journal/iecred)
|
|
61
|
+

|
|
62
|
+

|
|
63
|
+
[](https://doi.org/10.5281/zenodo.22212018)
|
|
64
|
+
<!-- Add after JOSS submission:
|
|
65
|
+
[](https://joss.theoj.org/papers/XXXX)
|
|
66
|
+
-->
|
|
67
|
+
|
|
68
|
+
Phase stability and flash calculations for the **CO₂ + H₂O + NaCl** ternary system
|
|
69
|
+
using the electrolyte Cubic-Plus-Association (eCPA) equation of state of
|
|
70
|
+
[Coelho, Franco & Firoozabadi (2025)][coelho2025].
|
|
71
|
+
Covers the full spectrum from shallow CO₂ storage aquifers to deep geothermal reservoirs.
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Highlights
|
|
76
|
+
|
|
77
|
+
| | |
|
|
78
|
+
|:---|:---|
|
|
79
|
+
| ✅ **100% flash convergence** | across >9,800 conditions, *T* = 0–425 °C, *P* = 1–1500 bar |
|
|
80
|
+
| ⚡ **3.2× faster** than cold-start SSI | via precomputed 4D solution table warm-start |
|
|
81
|
+
| 🎯 **6.5% AARE** on CO₂ solubility | validated against >1,100 experimental data points |
|
|
82
|
+
| 🔬 **0.30% AARE** on pure-water density | 475 IAPWS-95 reference conditions |
|
|
83
|
+
| 🏗️ **Reservoir simulator demo** | 50×50 grid, 300 time steps, zero flash failures |
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## What this repository provides
|
|
88
|
+
|
|
89
|
+
1. **Complete eCPA EoS** (`code/ecpa/`) — Debye–Hückel, Born, association, and permittivity
|
|
90
|
+
terms with parameters from Coelho et al. (2025); analytical Jacobians for both Newton
|
|
91
|
+
inner solvers.
|
|
92
|
+
|
|
93
|
+
2. **Salt-free CPA flash** (`code/CPA.py`) — Michelsen TPD stability test with six
|
|
94
|
+
initial guesses and accelerated SSI ([Jex et al., 2024](https://doi.org/10.2118/219490-PA)).
|
|
95
|
+
Hierarchical algorithm achieves **100% convergence** across >29,000 conditions with a
|
|
96
|
+
**2.96×** iteration-count reduction over standard SSI.
|
|
97
|
+
|
|
98
|
+
3. **eCPA stability + flash** (`code/ecpa/flash.py`) — extension to the full ternary
|
|
99
|
+
CO₂ + H₂O + NaCl system via warm-started K-value SSI with optional Newton polish.
|
|
100
|
+
|
|
101
|
+
4. **Precomputed solution table** (`code/results/CPA_ELV_all.parquet`) — 31T × 30P × 18*z* × 14*m*ₛ
|
|
102
|
+
grid covering *T* = 283–728 K, *P* = 1–1500 bar, *z* = 0.05–0.90, *m*ₛ = 0–6 mol/kg.
|
|
103
|
+
|
|
104
|
+
5. **Prototype reservoir simulator** (`code/co2brine_simulator.py`) — IMPEC scheme with
|
|
105
|
+
MFE pressure solver demonstrating production-level flash throughput.
|
|
106
|
+
|
|
107
|
+
See [REPRODUCING_FIGURES.md](REPRODUCING_FIGURES.md) for the complete script-by-script
|
|
108
|
+
guide to regenerating every figure in the paper.
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Installation
|
|
113
|
+
|
|
114
|
+
Requires Python ≥ 3.11.
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
git clone https://github.com/jmoortgat/CPA_and_eCPA_flash.git
|
|
118
|
+
cd CPA_and_eCPA_flash
|
|
119
|
+
pip install -e ".[test]" # editable install + pytest
|
|
120
|
+
pytest # run the test suite
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Optional extras: `pip install -e ".[nn]"` adds PyTorch for the
|
|
124
|
+
neural-network warm-start experiments; a conda environment is provided in
|
|
125
|
+
`code/environment.yml`.
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Quick start
|
|
130
|
+
|
|
131
|
+
**eCPA ternary flash** (CO₂ + H₂O + NaCl) — after `pip install -e .`,
|
|
132
|
+
from anywhere:
|
|
133
|
+
|
|
134
|
+
```python
|
|
135
|
+
from ecpa.flash import flash_co2_h2o_salt_kv
|
|
136
|
+
|
|
137
|
+
# T [K], P [bar], overall CO2 mole fraction, NaCl molality [mol/kg]
|
|
138
|
+
r = flash_co2_h2o_salt_kv(323.15, 100.0, 0.3, 1.0)
|
|
139
|
+
|
|
140
|
+
print(r["beta"]) # vapor fraction -> 0.2814
|
|
141
|
+
print(r["x_aq"]["x4w"]) # CO2 solubility in brine -> 1.670e-02
|
|
142
|
+
print(r["x_c"]["x1c"]) # H2O content of CO2 phase -> 2.727e-03
|
|
143
|
+
print(r["ms_aq"]) # equilibrium aqueous molality
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**Salt-free CPA binary** (CO₂ + H₂O) — run from the `code/` directory:
|
|
147
|
+
|
|
148
|
+
```python
|
|
149
|
+
import CPA
|
|
150
|
+
r = CPA.flash_co2_h2o_tpz(T=323.15, P_bar=100.0, z_co2=0.3)
|
|
151
|
+
print(r['phase'], r['beta'], r['x'])
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Notebooks
|
|
157
|
+
|
|
158
|
+
**Interactive tutorial** — a hands-on user manual covering the basic
|
|
159
|
+
workflows: single CPA and eCPA flash calculations, pressure sweeps compared
|
|
160
|
+
against experimental data, CO₂ solubility in NaCl brines of different
|
|
161
|
+
salinity, phase densities, and warm-started high-throughput calls:
|
|
162
|
+
|
|
163
|
+
[](https://colab.research.google.com/github/jmoortgat/CPA_and_eCPA_flash/blob/main/notebooks/ecpa_flash_tutorial.ipynb)
|
|
164
|
+
[`notebooks/ecpa_flash_tutorial.ipynb`](notebooks/ecpa_flash_tutorial.ipynb)
|
|
165
|
+
|
|
166
|
+
**The executable paper** — the complete journal article and its Supporting
|
|
167
|
+
Information as a single executable notebook — full text, table of contents,
|
|
168
|
+
and collapsed code cells that regenerate every figure from the code and data
|
|
169
|
+
in this repository:
|
|
170
|
+
|
|
171
|
+
[](https://colab.research.google.com/github/jmoortgat/CPA_and_eCPA_flash/blob/main/notebooks/ecpa_flash_paper.ipynb)
|
|
172
|
+
[`notebooks/ecpa_flash_paper.ipynb`](notebooks/ecpa_flash_paper.ipynb)
|
|
173
|
+
|
|
174
|
+
Fast figures render from result caches shipped with the repository; the
|
|
175
|
+
long parameter-space scans and the reservoir-simulation demo can be
|
|
176
|
+
recomputed from scratch by setting `RUN_LONG = True` in the setup cell
|
|
177
|
+
(30–60 min total). See [REPRODUCING_FIGURES.md](REPRODUCING_FIGURES.md)
|
|
178
|
+
for the script-by-script equivalent.
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## Repository structure
|
|
183
|
+
|
|
184
|
+
```
|
|
185
|
+
CPA_and_eCPA_flash/
|
|
186
|
+
├── README.md
|
|
187
|
+
├── REPRODUCING_FIGURES.md
|
|
188
|
+
├── LICENSE, CITATION.cff, CHANGELOG.md
|
|
189
|
+
├── CONTRIBUTING.md, CODE_OF_CONDUCT.md
|
|
190
|
+
├── pyproject.toml # pip install -e .
|
|
191
|
+
├── paper.md, paper.bib # JOSS paper
|
|
192
|
+
├── tests/ # pytest regression suite
|
|
193
|
+
├── notebooks/
|
|
194
|
+
│ ├── ecpa_flash_tutorial.ipynb # interactive user manual
|
|
195
|
+
│ └── ecpa_flash_paper.ipynb # executable paper
|
|
196
|
+
├── EXP/ # experimental VLE database (raw)
|
|
197
|
+
└── code/
|
|
198
|
+
├── ecpa/ # eCPA package
|
|
199
|
+
│ ├── flash.py # flash_co2_h2o_salt_kv ← production flash
|
|
200
|
+
│ ├── stability.py # ecpa_stability, ecpa_stability_flash
|
|
201
|
+
│ ├── guess_table.py # parquet warm-start lookup
|
|
202
|
+
│ ├── solution_table.py # build_solution_table
|
|
203
|
+
│ ├── warmstart.py # ScanTableWarmStart (4D npz lookup)
|
|
204
|
+
│ ├── constants.py # EoS parameters & Péneloux shifts
|
|
205
|
+
│ ├── parameters.py # make_params()
|
|
206
|
+
│ ├── elv.py # ELV residual + analytical Jacobian
|
|
207
|
+
│ ├── flash_simplified.py # low-T simplified flash (T < 80 °C)
|
|
208
|
+
│ ├── envelope.py # phase-boundary tracing
|
|
209
|
+
│ ├── exp_data.py # experimental data loader
|
|
210
|
+
│ └── ...
|
|
211
|
+
├── CPA.py # Salt-free CPA binary flash
|
|
212
|
+
├── co2brine_simulator.py # IMPEC reservoir simulator
|
|
213
|
+
├── ...
|
|
214
|
+
├── scripts/ # Validation, benchmark & figure scripts
|
|
215
|
+
│ ├── validate_co2h2o.py
|
|
216
|
+
│ ├── validate_co2nacl_full.py
|
|
217
|
+
│ ├── benchmark_pure_water_density.py
|
|
218
|
+
│ ├── run_benchmark.py
|
|
219
|
+
│ ├── plot_co2h2o_figures.py
|
|
220
|
+
│ ├── plot_co2nacl_figures.py
|
|
221
|
+
│ └── ...
|
|
222
|
+
└── results/
|
|
223
|
+
├── CPA_ELV_all.parquet # Precomputed solution table (25 MB)
|
|
224
|
+
└── scan_v4_table.npz # 4D warm-start table (23 MB)
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## API reference
|
|
230
|
+
|
|
231
|
+
### `ecpa/flash.py`
|
|
232
|
+
|
|
233
|
+
| Function | Description |
|
|
234
|
+
|:---|:---|
|
|
235
|
+
| `flash_co2_h2o_salt_kv(T, P, z, ms, params, guess_fn)` | **Production flash.** Hierarchical stability+flash with K-value SSI and optional Newton polish. |
|
|
236
|
+
| `flash_co2_h2o_salt_ssi(T, P, z, ms, params)` | Legacy cold-start SSI flash (ω = 0.7). Kept for reference — prefer `flash_co2_h2o_salt_kv`. |
|
|
237
|
+
|
|
238
|
+
### `ecpa/stability.py`
|
|
239
|
+
|
|
240
|
+
| Function | Description |
|
|
241
|
+
|:---|:---|
|
|
242
|
+
| `ecpa_stability(T, P, z, ms, params)` | Michelsen TPD test → `(tpd_min, trial_comp, converged)`. |
|
|
243
|
+
| `stability_map(T_range, P_range, z, ms, params, n_workers)` | Parallel 2-D stability scan. |
|
|
244
|
+
|
|
245
|
+
### `CPA.py`
|
|
246
|
+
|
|
247
|
+
| Function | Description |
|
|
248
|
+
|:---|:---|
|
|
249
|
+
| `flash_co2_h2o_tpz_robust(T, P_bar, z_co2)` | **100% convergence.** Stability → best-K flash → Wilson fallback. |
|
|
250
|
+
| `flash_co2_h2o_tpz(T, P_bar, z_co2, vshift_h2o, vshift_co2)` | Single-call binary flash. Returns compositions, Z-factors, `rho_mass` [kg/L]. |
|
|
251
|
+
| `stability_test(T, P_bar, z, accelerated=True)` | TPD with 6 initial guesses ([Jex et al., 2024](https://doi.org/10.2118/219490-PA)). |
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
## Performance
|
|
256
|
+
|
|
257
|
+
### eCPA ternary flash
|
|
258
|
+
|
|
259
|
+
| Method | SSI iters | Time / call | Speedup |
|
|
260
|
+
|:---|:---:|:---:|:---:|
|
|
261
|
+
| Cold-start SSI (Wilson init) | 11.7 | ~10 ms | 1× |
|
|
262
|
+
| **Warm-start (solution table)** | **3.3** | **~3 ms** | **3.2×** |
|
|
263
|
+
|
|
264
|
+
*Benchmark: T = 398 K, z = 0.5, m*ₛ *= 1.0 mol/kg, 30 pressure points.*
|
|
265
|
+
|
|
266
|
+
### Salt-free CPA binary flash
|
|
267
|
+
|
|
268
|
+
| Strategy | Convergence | Mean iters |
|
|
269
|
+
|:---|:---:|:---:|
|
|
270
|
+
| Standard SSI + Wilson K | 96.0% | 46.6 |
|
|
271
|
+
| Accelerated SSI + Wilson K | 97.1% | 17.0 |
|
|
272
|
+
| **Hierarchical (robust)** | **100%** | **12.0** |
|
|
273
|
+
|
|
274
|
+
*Tested at 631 experimental CO₂+H₂O points (T = 273–623 K, P = 5–3500 bar).*
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
## Validation
|
|
279
|
+
|
|
280
|
+
| System | Quantity | *N* | AARE |
|
|
281
|
+
|:---|:---|:---:|:---:|
|
|
282
|
+
| CO₂ + H₂O (CPA) | *x*_CO₂ in water | 460 | 8.9% |
|
|
283
|
+
| CO₂ + H₂O (eCPA) | *x*_CO₂ in water | 451 | 8.2% |
|
|
284
|
+
| CO₂ + NaCl (eCPA) | *m*_CO₂ [mol/kg] | 440 | 6.9% |
|
|
285
|
+
| CO₂ + NaCl (eCPA) | *x*_CO₂ [mole fraction] | 99 | 7.0% |
|
|
286
|
+
| Pure-water density vs. IAPWS-95 | ρ_W [kg/m³] | 475 | **0.30%** |
|
|
287
|
+
| CO₂-saturated aqueous density (exp.) | ρ_W [kg/m³] | 37 | 0.76% |
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
## Péneloux volume shifts
|
|
292
|
+
|
|
293
|
+
All shifts live in `code/ecpa/constants.py`.
|
|
294
|
+
|
|
295
|
+
| Parameter | Value | Source |
|
|
296
|
+
|:---|:---:|:---|
|
|
297
|
+
| `Penelouxs` (NaCl) | −53.5 cm³/mol | Coelho et al. (2025); applied via `make_params()` |
|
|
298
|
+
| `peneloux_h2o(T)` | degree-4 polynomial in *T*/*T*c | Fitted in this work to 475 IAPWS-95 liquid-water conditions |
|
|
299
|
+
| `Peneloux_CO2` | 0 | Evaluated against Span–Wagner; unshifted performs best |
|
|
300
|
+
|
|
301
|
+
The temperature-dependent H₂O shift is isofugacity-preserving — it improves
|
|
302
|
+
density predictions without affecting phase compositions or VLE results. It is
|
|
303
|
+
applied in the density validation (`scripts/benchmark_pure_water_density.py`,
|
|
304
|
+
which produces the paper's density figures); flash routines report unshifted
|
|
305
|
+
EoS densities unless the shift is passed explicitly (`vshift_h2o`/`vshift_co2`
|
|
306
|
+
in the CPA flash functions).
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
## Reproducing the figures
|
|
311
|
+
|
|
312
|
+
See **[REPRODUCING_FIGURES.md](REPRODUCING_FIGURES.md)** for the complete script-by-script
|
|
313
|
+
commands to regenerate all figures in the paper and supplemental information.
|
|
314
|
+
|
|
315
|
+
Quick summary:
|
|
316
|
+
|
|
317
|
+
```bash
|
|
318
|
+
cd code
|
|
319
|
+
python scripts/validate_co2h2o.py # ~5 min
|
|
320
|
+
python scripts/validate_co2nacl_full.py # ~30 min
|
|
321
|
+
python scripts/run_parameter_scan.py # ~20 min
|
|
322
|
+
python scripts/run_warmstart_scan.py # ~27 min
|
|
323
|
+
python scripts/plot_co2h2o_figures.py # Figs. 1, S1, S6
|
|
324
|
+
python scripts/plot_co2nacl_figures.py # Figs. 2, 3, S2, S4
|
|
325
|
+
python scripts/plot_scan_figures.py # Figs. 7, 8, 9
|
|
326
|
+
# ... see REPRODUCING_FIGURES.md for the full list
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
## Citation
|
|
332
|
+
|
|
333
|
+
If you use this code, please cite:
|
|
334
|
+
|
|
335
|
+
```bibtex
|
|
336
|
+
@article{moortgat2026ecpa,
|
|
337
|
+
author = {Moortgat, Joachim and Coelho, Felipe Mour{\~a}o and Firoozabadi, Abbas},
|
|
338
|
+
title = {Fast and Robust Phase Equilibrium Computations for {CO}$_2$ + {H}$_2${O} + {NaCl}
|
|
339
|
+
Mixtures Using the Electrolyte Cubic-Plus-Association Equation of State},
|
|
340
|
+
journal = {Industrial \& Engineering Chemistry Research},
|
|
341
|
+
year = {2026},
|
|
342
|
+
note = {in press}
|
|
343
|
+
}
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
And the underlying eCPA parametrisation:
|
|
347
|
+
|
|
348
|
+
```bibtex
|
|
349
|
+
@article{coelho2025ecpa,
|
|
350
|
+
author = {Coelho, Felipe Mour{\~a}o and Franco, Lu{\'i}s Fernando Mercier and Firoozabadi, Abbas},
|
|
351
|
+
title = {Phase Equilibria of {CO}$_2$--Water and {CO}$_2$--Brine at High Temperatures:
|
|
352
|
+
From {Monte Carlo} Simulations to the Equation of State},
|
|
353
|
+
journal = {Industrial \& Engineering Chemistry Research},
|
|
354
|
+
volume = {64},
|
|
355
|
+
number = {16},
|
|
356
|
+
pages = {8492--8505},
|
|
357
|
+
year = {2025},
|
|
358
|
+
doi = {10.1021/acs.iecr.5c00134}
|
|
359
|
+
}
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
---
|
|
363
|
+
|
|
364
|
+
## Contributing
|
|
365
|
+
|
|
366
|
+
Bug reports, questions, and pull requests are welcome — see
|
|
367
|
+
[CONTRIBUTING.md](CONTRIBUTING.md). Participation is governed by the
|
|
368
|
+
[Code of Conduct](CODE_OF_CONDUCT.md).
|
|
369
|
+
|
|
370
|
+
## License
|
|
371
|
+
|
|
372
|
+
[MIT](LICENSE). If you use this software, please cite it (see
|
|
373
|
+
[CITATION.cff](CITATION.cff)) together with the companion paper above.
|
|
374
|
+
|
|
375
|
+
[coelho2025]: https://doi.org/10.1021/acs.iecr.5c00134
|