pyrestoolbox 3.1.2__tar.gz → 3.1.3__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.
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/PKG-INFO +1 -1
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyproject.toml +1 -1
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/docs/changelist.rst +8 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/gas/gas.py +17 -15
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/setup.cfg +1 -1
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/setup.py +1 -1
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/src/gas_viscosity/mod.rs +51 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/src/lib.rs +9 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/src/zfactor/mod.rs +74 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/.github/workflows/build-wheels.yml +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/.gitignore +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/Cargo.lock +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/Cargo.toml +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/LICENSE +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/MANIFEST.in +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/README.rst +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/ResToolbox/privacy_policy.md +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/benchmark_rust_vs_python.py +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/build_pure_python.py +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/__init__.py +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/_accelerator.py +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/brine/__init__.py +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/brine/_lib_salting_library.py +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/brine/_lib_vle_engine.py +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/brine/brine.py +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/classes/__init__.py +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/classes/classes.py +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/constants/__init__.py +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/constants/constants.py +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/dca/__init__.py +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/dca/dca.py +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/docs/brine.rst +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/docs/dca.rst +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/docs/examples.ipynb +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/docs/gas.rst +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/docs/img/bot.png +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/docs/img/bot_PVTO.png +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/docs/img/bot_img.png +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/docs/img/dry_gas.png +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/docs/img/grid_sat_df.png +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/docs/img/influence.png +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/docs/img/properties_df.png +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/docs/img/sgof.png +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/docs/img/swof.png +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/docs/layer.rst +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/docs/library.rst +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/docs/matbal.rst +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/docs/nodal.rst +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/docs/nodal_examples.ipynb +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/docs/nodal_hydrate_demo.ipynb +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/docs/oil.rst +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/docs/recommend.rst +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/docs/sensitivity.rst +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/docs/simtools.rst +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/gas/__init__.py +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/layer/__init__.py +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/layer/layer.py +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/library/__init__.py +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/library/component_library.xlsx +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/library/library.py +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/matbal/__init__.py +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/matbal/matbal.py +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/nodal/__init__.py +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/nodal/nodal.py +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/oil/__init__.py +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/oil/oil.py +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/plyasunov/__init__.py +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/plyasunov/iapws_if97.py +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/plyasunov/plyasunov_model.py +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/plyasunov/water_properties.py +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/recommend/__init__.py +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/recommend/recommend.py +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/sensitivity/__init__.py +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/sensitivity/sensitivity.py +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/shared_fns/__init__.py +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/shared_fns/shared_fns.py +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/simtools/__init__.py +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/simtools/simtools.py +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/validate/__init__.py +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/pyrestoolbox/validate/validate.py +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/src/bessel.rs +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/src/critical_properties/mod.rs +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/src/dca/hyperbolic.rs +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/src/dca/mod.rs +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/src/dca/ransac.rs +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/src/gwr.rs +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/src/matbal/mod.rs +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/src/matbal/objective.rs +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/src/oil/density.rs +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/src/oil/mod.rs +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/src/pseudopressure.rs +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/src/spycher_pruess/mod.rs +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/src/spycher_pruess/solubility.rs +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/src/vle/alpha.rs +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/src/vle/bip.rs +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/src/vle/components.rs +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/src/vle/eos.rs +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/src/vle/flash.rs +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/src/vle/fugacity.rs +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/src/vle/k_init.rs +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/src/vle/mod.rs +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/src/vle/rachford_rice.rs +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/src/vlp/friction.rs +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/src/vlp/holdup_bb.rs +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/src/vlp/holdup_gray.rs +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/src/vlp/holdup_hb.rs +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/src/vlp/holdup_wg.rs +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/src/vlp/ift.rs +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/src/vlp/mod.rs +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/src/vlp/pvt_helpers.rs +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/src/vlp/segment_gas.rs +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/src/vlp/segment_oil.rs +0 -0
- {pyrestoolbox-3.1.2 → pyrestoolbox-3.1.3}/src/vlp/static_column.rs +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "maturin"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pyrestoolbox"
|
|
7
|
-
version = "3.1.
|
|
7
|
+
version = "3.1.3"
|
|
8
8
|
description = "pyResToolbox - A collection of Reservoir Engineering Utilities"
|
|
9
9
|
license = {text = "GPL-3.0-or-later"}
|
|
10
10
|
authors = [{name = "Mark W. Burgoyne", email = "mark.w.burgoyne@gmail.com"}]
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
Changelist in 3.1.3:
|
|
2
|
+
|
|
3
|
+
- **Z-factor Z*=Z-B reformulation**: BNS Peng-Robinson cubic solver now uses Aaron Zick's Z* = Z - B variable substitution, which bounds all physical roots to (0, 1] and guarantees Halley solver convergence. Eliminates rare failures at extreme pressures. Falls back to Cardano analytically if needed.
|
|
4
|
+
- **Rust batch vectorization**: Rust-accelerated ``gas_z()`` and ``gas_ug()`` now use batch dispatch (single FFI call for all pressures) instead of per-pressure scalar loops. Precomputes critical properties, BIPs, and LBC mixture parameters once per call. New Rust functions: ``bns_zfactor_batch``, ``dak_zfactor_batch``, ``hy_zfactor_batch``, ``gas_ug_lge_batch``, ``gas_ug_lbc_batch``. LBC viscosity batch is 9.3x faster than scalar; full BNS pipeline (Z + viscosity) is 2x faster than pure Python.
|
|
5
|
+
- **Rust GWR inverse Laplace transform**: Rust/MPFR-accelerated Gaver-Wynn-Rho algorithm and Bessel functions for influence table generation. Switched dependency from ``gwr_inversion`` to ``ilt-inversion``.
|
|
6
|
+
- **oil_co() Pb discontinuity fix**: Fixed oil compressibility discontinuity at bubble point in black oil tables. Added ``undersaturated_only`` mode.
|
|
7
|
+
- 630 validation tests (up from 603 in 3.0.5).
|
|
8
|
+
|
|
1
9
|
Changelist in 3.0.5:
|
|
2
10
|
|
|
3
11
|
- **Rust acceleration (optional)**: Computationally intensive algorithms now have optional Rust-compiled acceleration. When the compiled extension is present it is used automatically with no API changes; when unavailable, all functions fall back silently to pure Python. Accelerated functions include all 8 VLP segment loops (4 methods x gas/oil), gas Z-factor (DAK, HY, BNS), gas viscosity (LGE, LBC), gas pseudopressure, oil density (SWMH), oil FVF (McCain), DCA hyperbolic grid search (``fit_decline``, ``fit_decline_cum``), and the material balance regression objective. Set ``PYRESTOOLBOX_NO_RUST=1`` to force pure Python; set ``PYRESTOOLBOX_RETRY_RUST=1`` to retry after a blocked probe. Use ``from pyrestoolbox._accelerator import get_status`` for programmatic status checks.
|
|
@@ -840,29 +840,29 @@ def gas_z(
|
|
|
840
840
|
|
|
841
841
|
zfuncs = {"DAK": zdak, "HY": z_hy, "WYW": z_wyw, "BUR": z_bur}
|
|
842
842
|
|
|
843
|
-
# Rust acceleration dispatch
|
|
843
|
+
# Rust acceleration dispatch (batch — single FFI call for all pressures)
|
|
844
844
|
if RUST_AVAILABLE:
|
|
845
845
|
if zmethod.name in ('BNS', 'BUR'):
|
|
846
|
-
zout = np.array(
|
|
847
|
-
|
|
846
|
+
zout = np.array(_rust_module.bns_zfactor_batch(
|
|
847
|
+
p.tolist(), float(degf), float(sg),
|
|
848
848
|
float(co2), float(h2s), float(n2), float(h2)
|
|
849
|
-
)
|
|
849
|
+
))
|
|
850
850
|
return process_output(zout, is_list)
|
|
851
851
|
elif zmethod.name == 'DAK':
|
|
852
852
|
if cmethod.name == 'SUT':
|
|
853
|
-
zout = np.array(
|
|
854
|
-
|
|
853
|
+
zout = np.array(_rust_module.dak_zfactor_batch(
|
|
854
|
+
p.tolist(), float(degf), float(sg),
|
|
855
855
|
float(co2), float(h2s), float(n2)
|
|
856
|
-
)
|
|
856
|
+
))
|
|
857
857
|
else:
|
|
858
858
|
zout = np.array([_rust_module.dak_zfactor(float(pr_i), float(tr)) for pr_i in pprs])
|
|
859
859
|
return process_output(zout, is_list)
|
|
860
860
|
elif zmethod.name == 'HY':
|
|
861
861
|
if cmethod.name == 'SUT':
|
|
862
|
-
zout = np.array(
|
|
863
|
-
|
|
862
|
+
zout = np.array(_rust_module.hy_zfactor_batch(
|
|
863
|
+
p.tolist(), float(degf), float(sg),
|
|
864
864
|
float(co2), float(h2s), float(n2)
|
|
865
|
-
)
|
|
865
|
+
))
|
|
866
866
|
else:
|
|
867
867
|
zout = np.array([_rust_module.hall_yarborough_zfactor(float(pr_i), float(tr)) for pr_i in pprs])
|
|
868
868
|
return process_output(zout, is_list)
|
|
@@ -945,15 +945,17 @@ def gas_ug(
|
|
|
945
945
|
|
|
946
946
|
rho = m * p / (t * zee * R * 62.37)
|
|
947
947
|
|
|
948
|
-
# Rust-accelerated viscosity (
|
|
948
|
+
# Rust-accelerated viscosity (batch — single FFI call for all pressures)
|
|
949
949
|
if RUST_AVAILABLE:
|
|
950
950
|
if zmethod.name not in ('BNS', 'BUR'):
|
|
951
|
-
ug_list = np.array(
|
|
952
|
-
|
|
951
|
+
ug_list = np.array(_rust_module.gas_ug_lge_batch(
|
|
952
|
+
p.tolist(), zee.tolist(), sg, degf
|
|
953
|
+
))
|
|
953
954
|
ug = process_output(ug_list, is_list)
|
|
954
955
|
else:
|
|
955
|
-
ug_list = np.array(
|
|
956
|
-
|
|
956
|
+
ug_list = np.array(_rust_module.gas_ug_lbc_batch(
|
|
957
|
+
p.tolist(), zee.tolist(), sg, degf, co2, h2s, n2, h2
|
|
958
|
+
))
|
|
957
959
|
ug = process_output(ug_list, is_list)
|
|
958
960
|
if ugz:
|
|
959
961
|
return process_output(ug * zee, is_list)
|
|
@@ -12,7 +12,7 @@ with open(os.path.join(ROOT, 'README.rst'), 'r', encoding='utf-8') as f:
|
|
|
12
12
|
setup(
|
|
13
13
|
name='pyrestoolbox',
|
|
14
14
|
include_package_data=True,
|
|
15
|
-
version='3.1.
|
|
15
|
+
version='3.1.3', # Ideally should be same as your GitHub release tag version
|
|
16
16
|
packages=find_packages(exclude=['pyrestoolbox.tests', 'pyrestoolbox.tests.*']),
|
|
17
17
|
description='pyResToolbox - A collection of Reservoir Engineering Utilities',
|
|
18
18
|
license="GNU General Public License v3 or later (GPLv3+)",
|
|
@@ -159,3 +159,54 @@ pub fn gas_ug_lbc(
|
|
|
159
159
|
let params = lbc_params(degf, sg, co2, h2s, n2, h2);
|
|
160
160
|
Ok(lbc_viscosity_with_params(p_psia, deg_r, zee, ¶ms))
|
|
161
161
|
}
|
|
162
|
+
|
|
163
|
+
// =========================================================================
|
|
164
|
+
// Batch (vectorized) viscosity functions
|
|
165
|
+
// =========================================================================
|
|
166
|
+
|
|
167
|
+
/// LGE viscosity for a batch of (pressure, z-factor) pairs.
|
|
168
|
+
#[pyfunction]
|
|
169
|
+
pub fn gas_ug_lge_batch(
|
|
170
|
+
pressures: Vec<f64>,
|
|
171
|
+
z_factors: Vec<f64>,
|
|
172
|
+
sg: f64,
|
|
173
|
+
degf: f64,
|
|
174
|
+
) -> PyResult<Vec<f64>> {
|
|
175
|
+
let t_degr = degf + DEGF2R;
|
|
176
|
+
let m = MW_AIR * sg;
|
|
177
|
+
|
|
178
|
+
// Precompute temperature-dependent LGE coefficients
|
|
179
|
+
let b = 3.448 + (986.4 / t_degr) + (0.01009 * m);
|
|
180
|
+
let c = 2.447 - (0.2224 * b);
|
|
181
|
+
let a = (9.379 + (0.01607 * m)) * t_degr.powf(1.5) / (209.2 + (19.26 * m) + t_degr);
|
|
182
|
+
|
|
183
|
+
let result: Vec<f64> = pressures.iter().zip(z_factors.iter()).map(|(&p, &z)| {
|
|
184
|
+
let rho = m * p / (t_degr * z * R * 62.37);
|
|
185
|
+
a * 0.0001 * (b * rho.powf(c)).exp()
|
|
186
|
+
}).collect();
|
|
187
|
+
|
|
188
|
+
Ok(result)
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/// LBC viscosity for a batch of (pressure, z-factor) pairs.
|
|
192
|
+
/// Precomputes LBC mixture parameters (u0, eta_mix, rhoc) once.
|
|
193
|
+
#[pyfunction]
|
|
194
|
+
pub fn gas_ug_lbc_batch(
|
|
195
|
+
pressures: Vec<f64>,
|
|
196
|
+
z_factors: Vec<f64>,
|
|
197
|
+
sg: f64,
|
|
198
|
+
degf: f64,
|
|
199
|
+
co2: f64,
|
|
200
|
+
h2s: f64,
|
|
201
|
+
n2: f64,
|
|
202
|
+
h2: f64,
|
|
203
|
+
) -> PyResult<Vec<f64>> {
|
|
204
|
+
let deg_r = degf + DEGF2R;
|
|
205
|
+
let params = lbc_params(degf, sg, co2, h2s, n2, h2);
|
|
206
|
+
|
|
207
|
+
let result: Vec<f64> = pressures.iter().zip(z_factors.iter()).map(|(&p, &z)| {
|
|
208
|
+
lbc_viscosity_with_params(p, deg_r, z, ¶ms)
|
|
209
|
+
}).collect();
|
|
210
|
+
|
|
211
|
+
Ok(result)
|
|
212
|
+
}
|
|
@@ -38,10 +38,19 @@ fn _native(m: &Bound<'_, PyModule>) -> PyResult<()> {
|
|
|
38
38
|
m.add_function(wrap_pyfunction!(zfactor::hall_yarborough_zfactor_full, m)?)?;
|
|
39
39
|
m.add_function(wrap_pyfunction!(zfactor::bns_zfactor_full, m)?)?;
|
|
40
40
|
|
|
41
|
+
// Z-factor batch functions
|
|
42
|
+
m.add_function(wrap_pyfunction!(zfactor::dak_zfactor_batch, m)?)?;
|
|
43
|
+
m.add_function(wrap_pyfunction!(zfactor::hy_zfactor_batch, m)?)?;
|
|
44
|
+
m.add_function(wrap_pyfunction!(zfactor::bns_zfactor_batch, m)?)?;
|
|
45
|
+
|
|
41
46
|
// Gas viscosity
|
|
42
47
|
m.add_function(wrap_pyfunction!(gas_viscosity::gas_ug_lge, m)?)?;
|
|
43
48
|
m.add_function(wrap_pyfunction!(gas_viscosity::gas_ug_lbc, m)?)?;
|
|
44
49
|
|
|
50
|
+
// Gas viscosity batch functions
|
|
51
|
+
m.add_function(wrap_pyfunction!(gas_viscosity::gas_ug_lge_batch, m)?)?;
|
|
52
|
+
m.add_function(wrap_pyfunction!(gas_viscosity::gas_ug_lbc_batch, m)?)?;
|
|
53
|
+
|
|
45
54
|
// Pseudopressure integration
|
|
46
55
|
m.add_function(wrap_pyfunction!(pseudopressure::gas_dmp_rust, m)?)?;
|
|
47
56
|
|
|
@@ -463,6 +463,80 @@ pub fn bns_zfactor_full(
|
|
|
463
463
|
Ok(bns_zfactor_core(p_psia, deg_r, co2_frac, h2s_frac, n2_frac, h2_frac, tpc, ppc))
|
|
464
464
|
}
|
|
465
465
|
|
|
466
|
+
// =========================================================================
|
|
467
|
+
// Batch (vectorized) pipeline functions — precompute once, loop pressures
|
|
468
|
+
// =========================================================================
|
|
469
|
+
|
|
470
|
+
/// DAK Z-factor for a batch of pressures. Precomputes Sutton+WA critical properties once.
|
|
471
|
+
#[pyfunction]
|
|
472
|
+
pub fn dak_zfactor_batch(
|
|
473
|
+
pressures: Vec<f64>,
|
|
474
|
+
t_degf: f64,
|
|
475
|
+
sg: f64,
|
|
476
|
+
co2_frac: f64,
|
|
477
|
+
h2s_frac: f64,
|
|
478
|
+
n2_frac: f64,
|
|
479
|
+
) -> PyResult<Vec<f64>> {
|
|
480
|
+
let (tpc, ppc) = critical_properties::sutton_wa_internal(sg, co2_frac, h2s_frac, n2_frac)
|
|
481
|
+
.map_err(|e| PyValueError::new_err(e))?;
|
|
482
|
+
let t_rankine = t_degf + DEGF2R;
|
|
483
|
+
let tr = t_rankine / tpc;
|
|
484
|
+
|
|
485
|
+
let result: Vec<f64> = pressures.iter().map(|&p| {
|
|
486
|
+
let pr = p / ppc;
|
|
487
|
+
dak_core(pr, tr)
|
|
488
|
+
}).collect();
|
|
489
|
+
|
|
490
|
+
Ok(result)
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
/// Hall-Yarborough Z-factor for a batch of pressures. Precomputes Sutton+WA critical properties once.
|
|
494
|
+
#[pyfunction]
|
|
495
|
+
pub fn hy_zfactor_batch(
|
|
496
|
+
pressures: Vec<f64>,
|
|
497
|
+
t_degf: f64,
|
|
498
|
+
sg: f64,
|
|
499
|
+
co2_frac: f64,
|
|
500
|
+
h2s_frac: f64,
|
|
501
|
+
n2_frac: f64,
|
|
502
|
+
) -> PyResult<Vec<f64>> {
|
|
503
|
+
let (tpc, ppc) = critical_properties::sutton_wa_internal(sg, co2_frac, h2s_frac, n2_frac)
|
|
504
|
+
.map_err(|e| PyValueError::new_err(e))?;
|
|
505
|
+
let t_rankine = t_degf + DEGF2R;
|
|
506
|
+
let tr = t_rankine / tpc;
|
|
507
|
+
|
|
508
|
+
let result: Vec<f64> = pressures.iter().map(|&p| {
|
|
509
|
+
let pr = p / ppc;
|
|
510
|
+
hy_core(pr, tr)
|
|
511
|
+
}).collect();
|
|
512
|
+
|
|
513
|
+
Ok(result)
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
/// BNS Z-factor for a batch of pressures. Precomputes critical properties, BIPs,
|
|
517
|
+
/// alpha, and m once — loops only mixing rules, cubic solve, and fugacity selection.
|
|
518
|
+
#[pyfunction]
|
|
519
|
+
pub fn bns_zfactor_batch(
|
|
520
|
+
pressures: Vec<f64>,
|
|
521
|
+
t_degf: f64,
|
|
522
|
+
sg: f64,
|
|
523
|
+
co2_frac: f64,
|
|
524
|
+
h2s_frac: f64,
|
|
525
|
+
n2_frac: f64,
|
|
526
|
+
h2_frac: f64,
|
|
527
|
+
) -> PyResult<Vec<f64>> {
|
|
528
|
+
let deg_r = t_degf + DEGF2R;
|
|
529
|
+
let (tpc_hc, ppc_hc, _) = critical_properties::bns_pseudocritical_internal(
|
|
530
|
+
sg, co2_frac, h2s_frac, n2_frac, h2_frac
|
|
531
|
+
);
|
|
532
|
+
|
|
533
|
+
let result: Vec<f64> = pressures.iter().map(|&p| {
|
|
534
|
+
bns_zfactor_core(p, deg_r, co2_frac, h2s_frac, n2_frac, h2_frac, tpc_hc, ppc_hc)
|
|
535
|
+
}).collect();
|
|
536
|
+
|
|
537
|
+
Ok(result)
|
|
538
|
+
}
|
|
539
|
+
|
|
466
540
|
// =========================================================================
|
|
467
541
|
// Public wrappers for cross-module access (used by pseudopressure)
|
|
468
542
|
// =========================================================================
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|