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.
Files changed (33) hide show
  1. ecpa_flash-1.0.0/LICENSE +21 -0
  2. ecpa_flash-1.0.0/PKG-INFO +375 -0
  3. ecpa_flash-1.0.0/README.md +323 -0
  4. ecpa_flash-1.0.0/code/CPA.py +2309 -0
  5. ecpa_flash-1.0.0/code/co2brine_simulator.py +947 -0
  6. ecpa_flash-1.0.0/code/cpa_worker.py +89 -0
  7. ecpa_flash-1.0.0/code/ecpa/__init__.py +19 -0
  8. ecpa_flash-1.0.0/code/ecpa/constants.py +98 -0
  9. ecpa_flash-1.0.0/code/ecpa/elv.py +291 -0
  10. ecpa_flash-1.0.0/code/ecpa/envelope.py +407 -0
  11. ecpa_flash-1.0.0/code/ecpa/exp_data.py +147 -0
  12. ecpa_flash-1.0.0/code/ecpa/flash.py +1442 -0
  13. ecpa_flash-1.0.0/code/ecpa/flash_simplified.py +285 -0
  14. ecpa_flash-1.0.0/code/ecpa/guess_table.py +145 -0
  15. ecpa_flash-1.0.0/code/ecpa/nn_flash.py +471 -0
  16. ecpa_flash-1.0.0/code/ecpa/parameters.py +44 -0
  17. ecpa_flash-1.0.0/code/ecpa/plotting.py +498 -0
  18. ecpa_flash-1.0.0/code/ecpa/scan.py +554 -0
  19. ecpa_flash-1.0.0/code/ecpa/solution_table.py +521 -0
  20. ecpa_flash-1.0.0/code/ecpa/stability.py +1735 -0
  21. ecpa_flash-1.0.0/code/ecpa/utils.py +174 -0
  22. ecpa_flash-1.0.0/code/ecpa/validate_co2h2o.py +1486 -0
  23. ecpa_flash-1.0.0/code/ecpa/validate_nacl.py +916 -0
  24. ecpa_flash-1.0.0/code/ecpa/warmstart.py +478 -0
  25. ecpa_flash-1.0.0/code/ecpa_flash.egg-info/PKG-INFO +375 -0
  26. ecpa_flash-1.0.0/code/ecpa_flash.egg-info/SOURCES.txt +31 -0
  27. ecpa_flash-1.0.0/code/ecpa_flash.egg-info/dependency_links.txt +1 -0
  28. ecpa_flash-1.0.0/code/ecpa_flash.egg-info/requires.txt +11 -0
  29. ecpa_flash-1.0.0/code/ecpa_flash.egg-info/top_level.txt +4 -0
  30. ecpa_flash-1.0.0/pyproject.toml +52 -0
  31. ecpa_flash-1.0.0/setup.cfg +4 -0
  32. ecpa_flash-1.0.0/tests/test_flash.py +53 -0
  33. ecpa_flash-1.0.0/tests/test_package.py +25 -0
@@ -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: MIT](https://img.shields.io/badge/License-MIT-BA0C2F.svg?style=flat-square)](LICENSE)
58
+ [![Python 3.11+](https://img.shields.io/badge/Python-3.11+-3776AB.svg?style=flat-square&logo=python&logoColor=white)](https://www.python.org/)
59
+ [![tests](https://github.com/jmoortgat/CPA_and_eCPA_flash/actions/workflows/tests.yml/badge.svg)](https://github.com/jmoortgat/CPA_and_eCPA_flash/actions/workflows/tests.yml)
60
+ [![Paper](https://img.shields.io/badge/paper-in%20press%20%40%20I%26ECR-2563EB.svg?style=flat-square)](https://pubs.acs.org/journal/iecred)
61
+ ![Coverage](https://img.shields.io/badge/T%20range-0–425%20°C-teal.svg?style=flat-square)
62
+ ![Coverage](https://img.shields.io/badge/P%20range-1–1500%20bar-teal.svg?style=flat-square)
63
+ [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.22212018.svg)](https://doi.org/10.5281/zenodo.22212018)
64
+ <!-- Add after JOSS submission:
65
+ [![status](https://joss.theoj.org/papers/XXXX/status.svg)](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
+ [![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/jmoortgat/CPA_and_eCPA_flash/blob/main/notebooks/ecpa_flash_tutorial.ipynb)
164
+ &nbsp;[`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
+ [![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/jmoortgat/CPA_and_eCPA_flash/blob/main/notebooks/ecpa_flash_paper.ipynb)
172
+ &nbsp;[`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