pyrestoolbox 3.8.4__tar.gz → 3.8.6__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.8.4 → pyrestoolbox-3.8.6}/Cargo.lock +1 -1
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/Cargo.toml +1 -1
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/PKG-INFO +6 -5
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/README.rst +1 -1
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyproject.toml +5 -4
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/docs/changelist.rst +12 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/docs/nodal.rst +1 -1
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/docs/simtools.rst +2 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/nodal/nodal.py +78 -41
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/simtools/_aquifer.py +11 -3
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/setup.cfg +4 -1
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/setup.py +4 -4
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/src/gwr.rs +83 -59
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/src/pseudopressure.rs +72 -113
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/src/vlp/constants.rs +6 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/src/vlp/march.rs +46 -15
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/src/vlp/mod.rs +12 -12
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/src/vlp/static_column.rs +20 -4
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/.github/complexity-baseline.json +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/.github/scripts/check_complexity.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/.github/workflows/build-wheels.yml +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/.github/workflows/tests.yml +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/.gitignore +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/LICENSE +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/MANIFEST.in +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/ResToolbox/privacy_policy.md +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/build_pure_python.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/clippy.toml +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/mcp/Dockerfile +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/mcp/README.md +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/mcp/pyproject.toml +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/mcp/pyrestoolbox_mcp/__init__.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/mcp/pyrestoolbox_mcp/serialize.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/mcp/pyrestoolbox_mcp/server.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/mcp/tests/test_server.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/__init__.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/_accelerator.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/brine/__init__.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/brine/_lib_dielectric.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/brine/_lib_maoduan_viscosity.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/brine/_lib_pitzer_params.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/brine/_lib_salting_library.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/brine/_lib_vle_engine.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/brine/appelo_volumes.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/brine/brine.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/brine/iapws_viscosity.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/brine/jones_dole_viscosity.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/brine/kestin_nacl_viscosity.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/brine/pr_vphi.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/brine/viscosity_route.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/brine/vphi_route.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/classes/__init__.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/classes/classes.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/constants/__init__.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/constants/constants.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/dca/__init__.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/dca/dca.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/docs/brine.rst +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/docs/dca.rst +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/docs/examples.ipynb +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/docs/gas.rst +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/docs/img/bot.png +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/docs/img/bot_PVTO.png +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/docs/img/bot_img.png +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/docs/img/dry_gas.png +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/docs/img/grid_sat_df.png +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/docs/img/influence.png +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/docs/img/properties_df.png +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/docs/img/sgof.png +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/docs/img/swof.png +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/docs/index.rst +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/docs/layer.rst +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/docs/library.rst +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/docs/matbal.rst +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/docs/nodal_examples.ipynb +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/docs/nodal_hydrate_demo.ipynb +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/docs/oil.rst +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/docs/plyasunov.rst +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/docs/recommend.rst +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/docs/sensitivity.rst +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/gas/__init__.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/gas/_hydrate.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/gas/gas.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/layer/__init__.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/layer/layer.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/library/__init__.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/library/component_library.xlsx +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/library/library.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/matbal/__init__.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/matbal/matbal.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/nodal/__init__.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/oil/__init__.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/oil/_compressibility.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/oil/_constants.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/oil/_correlations.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/oil/_density.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/oil/_harmonize.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/oil/_pvt_class.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/oil/_rate.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/oil/_separator.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/oil/_tables.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/oil/_utils.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/plyasunov/__init__.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/plyasunov/iapws_if97.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/plyasunov/plyasunov_model.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/plyasunov/water_properties.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/recommend/__init__.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/recommend/recommend.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/sensitivity/__init__.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/sensitivity/sensitivity.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/shared_fns/__init__.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/shared_fns/shared_fns.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/simtools/__init__.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/simtools/_decks.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/simtools/_pvt_tables.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/simtools/_relperm.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/simtools/_vfp.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/simtools/simtools.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/validate/__init__.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/pyrestoolbox/validate/validate.py +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/src/bessel.rs +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/src/brine_visc/mod.rs +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/src/brine_visc/salt.rs +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/src/brine_visc/water.rs +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/src/critical_properties/mod.rs +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/src/dca/hyperbolic.rs +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/src/dca/mod.rs +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/src/dca/ransac.rs +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/src/gas_viscosity/mod.rs +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/src/lib.rs +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/src/matbal/mod.rs +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/src/matbal/objective.rs +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/src/oil/density.rs +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/src/oil/mod.rs +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/src/spycher_pruess/mod.rs +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/src/spycher_pruess/solubility.rs +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/src/vle/alpha.rs +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/src/vle/bip.rs +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/src/vle/components.rs +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/src/vle/eos.rs +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/src/vle/flash.rs +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/src/vle/fugacity.rs +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/src/vle/k_init.rs +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/src/vle/mod.rs +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/src/vle/rachford_rice.rs +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/src/vlp/friction.rs +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/src/vlp/holdup_bb.rs +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/src/vlp/holdup_gray.rs +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/src/vlp/holdup_wg.rs +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/src/vlp/ift.rs +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/src/vlp/pvt_helpers.rs +0 -0
- {pyrestoolbox-3.8.4 → pyrestoolbox-3.8.6}/src/zfactor/mod.rs +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyrestoolbox
|
|
3
|
-
Version: 3.8.
|
|
3
|
+
Version: 3.8.6
|
|
4
4
|
Classifier: Programming Language :: Python :: 3
|
|
5
5
|
Classifier: Programming Language :: Rust
|
|
6
6
|
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
|
|
@@ -9,10 +9,11 @@ Requires-Dist: numpy
|
|
|
9
9
|
Requires-Dist: scipy
|
|
10
10
|
Requires-Dist: pandas
|
|
11
11
|
Requires-Dist: tabulate
|
|
12
|
-
Requires-Dist: ilt-inversion
|
|
13
|
-
Requires-Dist: mpmath
|
|
14
|
-
Requires-Dist: gmpy2
|
|
15
12
|
Requires-Dist: openpyxl
|
|
13
|
+
Requires-Dist: ilt-inversion ; extra == 'aquifer'
|
|
14
|
+
Requires-Dist: mpmath ; extra == 'aquifer'
|
|
15
|
+
Requires-Dist: gmpy2 ; extra == 'aquifer'
|
|
16
|
+
Provides-Extra: aquifer
|
|
16
17
|
License-File: LICENSE
|
|
17
18
|
Summary: pyResToolbox - A collection of Reservoir Engineering Utilities
|
|
18
19
|
Keywords: restoolbox,petroleum,reservoir
|
|
@@ -64,7 +65,7 @@ All public PVT, flow rate, and simulation table functions support both oilfield
|
|
|
64
65
|
Rust Acceleration (Optional)
|
|
65
66
|
----------------------------
|
|
66
67
|
|
|
67
|
-
pyResToolbox includes optional Rust-compiled extensions that accelerate computationally intensive algorithms. When the compiled extension is present and loadable, these functions run automatically through Rust with no API changes. When the extension is unavailable, all functions fall back silently to the pure Python implementation.
|
|
68
|
+
pyResToolbox includes optional Rust-compiled extensions that accelerate computationally intensive algorithms. When the compiled extension is present and loadable, these functions run automatically through Rust with no API changes. When the extension is unavailable, all functions fall back silently to the pure Python implementation. The one exception is ``simtools.influence_tables``, whose pure-Python fallback needs the optional ``aquifer`` extra (``pip install 'pyrestoolbox[aquifer]'``).
|
|
68
69
|
|
|
69
70
|
**Accelerated functions:**
|
|
70
71
|
|
|
@@ -39,7 +39,7 @@ All public PVT, flow rate, and simulation table functions support both oilfield
|
|
|
39
39
|
Rust Acceleration (Optional)
|
|
40
40
|
----------------------------
|
|
41
41
|
|
|
42
|
-
pyResToolbox includes optional Rust-compiled extensions that accelerate computationally intensive algorithms. When the compiled extension is present and loadable, these functions run automatically through Rust with no API changes. When the extension is unavailable, all functions fall back silently to the pure Python implementation.
|
|
42
|
+
pyResToolbox includes optional Rust-compiled extensions that accelerate computationally intensive algorithms. When the compiled extension is present and loadable, these functions run automatically through Rust with no API changes. When the extension is unavailable, all functions fall back silently to the pure Python implementation. The one exception is ``simtools.influence_tables``, whose pure-Python fallback needs the optional ``aquifer`` extra (``pip install 'pyrestoolbox[aquifer]'``).
|
|
43
43
|
|
|
44
44
|
**Accelerated functions:**
|
|
45
45
|
|
|
@@ -4,7 +4,7 @@ build-backend = "maturin"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pyrestoolbox"
|
|
7
|
-
version = "3.8.
|
|
7
|
+
version = "3.8.6"
|
|
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"}]
|
|
@@ -21,13 +21,14 @@ dependencies = [
|
|
|
21
21
|
"scipy",
|
|
22
22
|
"pandas",
|
|
23
23
|
"tabulate",
|
|
24
|
-
"ilt-inversion",
|
|
25
|
-
"mpmath",
|
|
26
|
-
"gmpy2",
|
|
27
24
|
"openpyxl",
|
|
28
25
|
]
|
|
29
26
|
readme = "README.rst"
|
|
30
27
|
|
|
28
|
+
[project.optional-dependencies]
|
|
29
|
+
# Pure-Python fallback for simtools.influence_tables (the Rust extension needs none of these)
|
|
30
|
+
aquifer = ["ilt-inversion", "mpmath", "gmpy2"]
|
|
31
|
+
|
|
31
32
|
[project.urls]
|
|
32
33
|
Homepage = "https://github.com/mwburgoyne/pyResToolbox"
|
|
33
34
|
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
Changelist in 3.8.6:
|
|
2
|
+
|
|
3
|
+
- **SIMTOOLS: ``influence_tables`` Rust path now holds the precision the inversion needs (results move).** The Rust Gaver-Wynn-Rho inversion evaluates the Van Everdingen-Hurst transform with its own MPFR Bessel functions, and those carried less precision than GWR needs (about 2.1M digits). The series-to-asymptotic switch was fixed at x = 25, where the asymptotic expansion is good to only about 22 digits; the K-series ran with half the guard bits its cancellation needs; pi in the asymptotic prefactors and Euler's constant in the K0 series were f64 or 50-digit constants; and the I1 asymptotic expansion had a sign error. The switch now depends on the working precision, the guard bits match the cancellation, all constants are MPFR, and the I1 sign is corrected. Against a reference converged to 1e-14, the worst point on a 126-point table (ReD 1.5-20, tD 0.01-200) is now 2.2e-5 at M=7 (was 4.5e-5), 1.4e-8 at M=12 (was 1.6e-4), 3.2e-11 at M=18 (was 6.7e-3) and 2e-16 at M=32 (ReD 1.5 at tD 0.044 returned 20.07 against 0.2175), the same convergence as the pure-Python path. At the default M=7 the README example table (ReD 1.5-1000) moves by up to 4.6e-5 relative (ReD 1.5, tD 0.027: 0.172801 to 0.172809), 6e-7 on average. Run time is unchanged or a little shorter (121 against 138 ms for that table at M=7).
|
|
4
|
+
|
|
5
|
+
- **PACKAGING: ``ilt-inversion``, ``mpmath`` and ``gmpy2`` are now an optional extra (``pip install 'pyrestoolbox[aquifer]'``).** Only ``simtools.influence_tables`` uses them, and only on its pure-Python path; the Rust extension in every prebuilt wheel does the inverse Laplace transform and Bessel functions itself in MPFR. ``import pyrestoolbox.simtools`` no longer loads ``ilt`` or ``mpmath``. Without the Rust extension and without the extra, ``influence_tables`` raises ``ImportError`` naming the extra; every other function is unaffected. Existing environments keep working, since upgrading does not uninstall the three packages.
|
|
6
|
+
|
|
7
|
+
Changelist in 3.8.5:
|
|
8
|
+
|
|
9
|
+
- **NODAL: gas VLP uses the ``gas_pvt`` Z-factor and viscosity methods (results move when a GasPVT is passed).** ``fbhp``, ``fthp``, ``outflow_curve``, ``operating_point`` and the simtools VFP tables took only the gas SG and Sutton/Wichert-Aziz pseudo-criticals from a ``GasPVT``; the march always ran Hall-Yarborough Z with Lee-Gonzalez-Eakin viscosity, so ``zmethod='BNS'`` (or the GasPVT default, DAK with PMC) was silently ignored, as were H2 and He (which raised a warning). The march now evaluates Z and viscosity exactly as ``gas_pvt.z()`` and ``gas_pvt.viscosity()`` do, at every step and in the zero-rate static column, in Python and Rust (the Rust march builds the same Z/viscosity evaluator as ``gas_dmp``, so every method stays accelerated; the two paths agree to 1e-9 relative). Calls without ``gas_pvt`` are bit-identical. Example (THP 1000 psia, 5 MMscf/d, 100 bbl/d water, 5000 ft of 2.441 in tubing, 80-200 degF, SG 0.65), Beggs-Brill BHP: 1475.3 psia before, 1459.3 with ``GasPVT(sg=0.65)`` (DAK/PMC), 1508.2 with ``zmethod='BNS'``; WG 1444.8, 1444.1, 1446.2. Beggs-Brill moves most because the distributed-to-segregated boundary sits mid-well here and the gradient steps 27% across it. The pure-Python fallback is about 15 times slower with a ``gas_pvt`` (about 40 ms per ``fbhp``), since each step calls ``gas_z`` and ``gas_ug``. No documented example passes a ``gas_pvt`` to the VLP functions, so none moves; one nodal test that asserted a sweet ``GasPVT`` equals the ``gsg``-only answer now compares an HY/SUT ``GasPVT`` (within 4e-5).
|
|
10
|
+
|
|
11
|
+
- **NODAL: gas VLP results now approach the dry-gas answer continuously as the liquid rate goes to zero.** With no liquid every method returns the single-phase gas BHP, but a vanishing liquid rate did not: in a 5000 ft, 2.441 in well at 1000 psia THP and 5 MMscf/d (dry gas 1232 psia for all four methods), 1e-6 bbl/d of water gave WG 1294, GRAY 1243 and BB 1429 psia, and BB BHP fell as water rose from 0.001 to 1 bbl/d. The causes are in the correlations' low-liquid limits: the Woldesemayat-Ghajar drift-flux void fraction tends to u_sg/(u_sg + u_gm) because the drift velocity does not depend on the amount of liquid, leaving a stagnant liquid holdup u_gm/(u_sg + u_gm) at any liquid rate; Gray's holdup tends to exp(A); and Beggs-Brill holdup scales as lambda^0.58, so its friction parameter y = lambda/HL^2 grows without bound and the two-phase friction multiplier peaks near lambda = 1e-9. Hagedorn-Brown, whose holdup is floored at lambda, was already continuous. The gas segment march now blends each segment's gradient linearly between the method's own zero-liquid gradient and its two-phase gradient while the no-slip liquid fraction is below 1e-3 (``_LOW_LIQ_LAMBDA``, Rust ``LOW_LIQ_LAMBDA``). At zero liquid and at lambda >= 1e-3 results are unchanged; in between they are continuous and BHP rises monotonically with liquid rate. In the example, 1 bbl/d of water now gives WG 1237.5 (was 1298.5), GRAY 1233.3 (1245.8), BB 1241.2 (1335.7) and HB 1232.0 (1232.3) psia; 10 bbl/d gives WG 1300.8 (1312.7), GRAY 1263.3 (1269.2), BB 1324.9 (1338.9), HB 1234.7 (1235.3). Gas wells with a liquid-to-gas ratio above roughly 3 bbl/MMscf at flowing conditions, and every oil-well march, are unaffected. No frozen baseline or documented example moves.
|
|
12
|
+
|
|
1
13
|
Changelist in 3.8.4:
|
|
2
14
|
|
|
3
15
|
- **GAS: associated-gas hydrocarbon pseudo-criticals for BNS (``ag``).** Burgoyne, Nielsen & Stanko (2025) fitted two hydrocarbon Tc/Pc correlations, for gas condensates and for associated gas; only the condensate one was exposed. Every gas function that takes ``he`` (except ``gas_sg``, ``gas_hydrate`` and the recommenders, which use no critical properties) now also takes ``ag`` (keyword, appended last): ``gas_tc_pc``, ``gas_z``, ``gas_ug``, ``gas_cg``, ``gas_bg``, ``gas_den``, ``gas_thermal``, ``gas_ponz2p``, ``gas_grad2sg``, ``gas_dmp``, ``gas_rate_radial``, ``gas_rate_linear``, ``GasPVT`` and ``gas_matbal``. ``ag=True`` makes ``cmethod='BNS'`` return the associated-gas values (SG 0.75: Tc 397.7 against 401.2 degR, Pc 653.9 against 663.4 psia), and the hydrocarbon-inert BIPs follow the selected Tc, as in the regression. Other cmethods ignore it and a user ``tc``/``pc`` takes precedence. The resolved values reach the Rust paths through the existing hydrocarbon Tc/Pc override, so the Rust code is unchanged. With ``ag=True``, results match the reference BNS implementation (``AG=True``) to 5e-15 in Z and viscosity and 7e-13 Btu/lb-mol in enthalpy; with ``ag=False`` (the default) every result is bit-identical to 3.8.3 on both paths.
|
|
@@ -426,7 +426,7 @@ Returns flowing bottom hole pressure (psia, or barsa if metric=True) using the s
|
|
|
426
426
|
- 'gas' or 'oil'
|
|
427
427
|
* - gas_pvt
|
|
428
428
|
- GasPVT
|
|
429
|
-
- Gas PVT object. If provided,
|
|
429
|
+
- Gas PVT object. If provided, the gas-well VLP march evaluates Z and gas viscosity with its methods and composition (as ``gas_pvt.z()`` and ``gas_pvt.viscosity()``: DAK with PMC by default, or HY or BNS as configured, impurities and H2/He included), and IPR calculations use the same. Without it the march uses Hall-Yarborough Z on Sutton pseudo-criticals of ``gsg`` with Lee-Gonzalez-Eakin viscosity
|
|
430
430
|
* - oil_pvt
|
|
431
431
|
- OilPVT
|
|
432
432
|
- Oil PVT object. If provided for oil wells, extracts api, sgsp, pb, rsb
|
|
@@ -152,6 +152,8 @@ pyrestoolbox.simtools.influence_tables
|
|
|
152
152
|
|
|
153
153
|
Solves Van Everdingin & Hurst Constant Terminal Rate solution via inverse Laplace transform and optionally writes out ECLIPSE styled AQUTAB include file.
|
|
154
154
|
|
|
155
|
+
The Rust extension (in every prebuilt wheel) does the inversion with no extra packages. Without it, the pure-Python fallback needs the optional ``aquifer`` extra (``ilt-inversion``, ``mpmath``, ``gmpy2``): ``pip install 'pyrestoolbox[aquifer]'``. Calling ``influence_tables`` on the pure-Python path without them raises ``ImportError``.
|
|
156
|
+
|
|
155
157
|
Returns a tuple of;
|
|
156
158
|
1. Dimensionless time list
|
|
157
159
|
2. list of lists of dimensionless pressures at each dimensionless time for each dimensionless radius
|
|
@@ -62,6 +62,7 @@ from pyrestoolbox.constants import (BAR_TO_PSI, PSI_TO_BAR, degc_to_degf, degf_t
|
|
|
62
62
|
D_PER_SM3_TO_D_PER_MSCF, D_PER_MSCF_TO_D_PER_SM3,
|
|
63
63
|
STB_TO_SM3, SM3_TO_STB)
|
|
64
64
|
import pyrestoolbox.gas as gas
|
|
65
|
+
from pyrestoolbox.gas.gas import _rust_cmethod
|
|
65
66
|
import pyrestoolbox.oil as oil
|
|
66
67
|
from pyrestoolbox.brine.viscosity_route import brine_viscosity as _brine_viscosity
|
|
67
68
|
from pyrestoolbox._accelerator import RUST_AVAILABLE as _RUST_AVAILABLE, rust_accelerated
|
|
@@ -273,6 +274,12 @@ _GRAY_ND_COEF = 205.0 # Diameter number coefficient in A
|
|
|
273
274
|
_GRAY_ROUGH_K = 28.5 # Effective roughness coefficient
|
|
274
275
|
_GRAY_R_THRESH = 0.007 # R threshold for roughness interpolation
|
|
275
276
|
_GRAY_SP_LIQ_FRAC = 1e-6 # v_sg/v_m below this is single-phase liquid (dry roughness)
|
|
277
|
+
# Below this no-slip liquid fraction the two-phase gradient is blended
|
|
278
|
+
# linearly toward the method's own zero-liquid gradient (weight lambda/_LOW_LIQ_LAMBDA).
|
|
279
|
+
# WG drift-flux and Gray holdup tend to finite values as liquid vanishes and
|
|
280
|
+
# Beggs-Brill's friction parameter y = lambda/HL^2 grows without bound, so
|
|
281
|
+
# without the blend a trace of liquid moved dry-gas BHP by up to 16%.
|
|
282
|
+
_LOW_LIQ_LAMBDA = 1e-3
|
|
276
283
|
_GRAY_ROUGH_FLOOR = 2.77e-5 # Minimum effective roughness (ft)
|
|
277
284
|
|
|
278
285
|
# ============================================================================
|
|
@@ -372,31 +379,25 @@ class _FlowInputs:
|
|
|
372
379
|
gsg: float = 0.65
|
|
373
380
|
vis_frac: float = 1.0
|
|
374
381
|
rsb_frac: float = 1.0
|
|
375
|
-
|
|
376
|
-
|
|
382
|
+
# Gas Z/viscosity spec from GasPVT (_gas_pvt_zspec); None -> Hall-Yarborough
|
|
383
|
+
# on Sutton pseudo-criticals of gsg with Lee-Gonzalez-Eakin viscosity
|
|
384
|
+
zspec: Optional[tuple] = None
|
|
377
385
|
|
|
378
386
|
|
|
379
|
-
def
|
|
380
|
-
"""
|
|
387
|
+
def _gas_pvt_zspec(gas_pvt):
|
|
388
|
+
"""Z-factor and viscosity specification for the VLP march from a GasPVT.
|
|
381
389
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
390
|
+
Returns (zmethod, cmethod, sg, [co2, h2s, n2, h2, he], tc, pc) with the
|
|
391
|
+
object's resolved methods and effective critical properties, so the march
|
|
392
|
+
evaluates Z and viscosity exactly as gas_pvt.z() and gas_pvt.viscosity()
|
|
393
|
+
do (Python via gas_z/gas_ug, Rust via the same GasState as gas_dmp). PMC
|
|
394
|
+
travels as 'SUT' with its already-resolved tc/pc, which gas_z treats as a
|
|
395
|
+
mixture override, as the Rust batch paths do.
|
|
388
396
|
"""
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
"VLP correlations use a Hall-Yarborough Z-factor with Sutton + Wichert-Aziz "
|
|
394
|
-
"pseudo-criticals; the H2 and He fractions on gas_pvt are ignored in the wellbore march.",
|
|
395
|
-
RuntimeWarning, stacklevel=3)
|
|
396
|
-
if gas_pvt.co2 > 0 or gas_pvt.h2s > 0 or gas_pvt.n2 > 0:
|
|
397
|
-
return gas.gas_tc_pc(gas_pvt.sg, co2=gas_pvt.co2, h2s=gas_pvt.h2s,
|
|
398
|
-
n2=gas_pvt.n2, cmethod='SUT')
|
|
399
|
-
return None, None
|
|
397
|
+
return (gas_pvt.zmethod.name, _rust_cmethod(gas_pvt.cmethod), float(gas_pvt.sg),
|
|
398
|
+
[float(gas_pvt.co2), float(gas_pvt.h2s), float(gas_pvt.n2),
|
|
399
|
+
float(gas_pvt.h2), float(getattr(gas_pvt, 'he', 0))],
|
|
400
|
+
float(gas_pvt.tc), float(gas_pvt.pc))
|
|
400
401
|
|
|
401
402
|
|
|
402
403
|
def _prepare_flow_inputs(well_type, metric, gas_pvt=None, oil_pvt=None,
|
|
@@ -435,7 +436,7 @@ def _prepare_flow_inputs(well_type, metric, gas_pvt=None, oil_pvt=None,
|
|
|
435
436
|
if gas_pvt is not None and well_type == 'gas':
|
|
436
437
|
if f.gsg == 0.65:
|
|
437
438
|
f.gsg = gas_pvt.sg
|
|
438
|
-
f.
|
|
439
|
+
f.zspec = _gas_pvt_zspec(gas_pvt)
|
|
439
440
|
|
|
440
441
|
# OilPVT already holds oilfield units
|
|
441
442
|
if oil_pvt is not None and well_type == 'oil':
|
|
@@ -1063,7 +1064,25 @@ def _condensate_vis(pr, cgr_local, gsg, api, temp_f, p_avg, oil_vis):
|
|
|
1063
1064
|
return oil_vis
|
|
1064
1065
|
|
|
1065
1066
|
|
|
1066
|
-
def
|
|
1067
|
+
def _march_gas_z_mu(gsg, temp_f, press_psia, tc, pc, zspec, viscosity=True):
|
|
1068
|
+
"""(Z, gas viscosity cP) for the gas march.
|
|
1069
|
+
|
|
1070
|
+
zspec None: Hall-Yarborough on (tc, pc) and Lee-Gonzalez-Eakin. Otherwise
|
|
1071
|
+
the GasPVT methods carried by zspec (see _gas_pvt_zspec). viscosity=False
|
|
1072
|
+
returns (Z, None).
|
|
1073
|
+
"""
|
|
1074
|
+
if zspec is None:
|
|
1075
|
+
zee = _z_factor(gsg, temp_f, press_psia, tc=tc, pc=pc)
|
|
1076
|
+
mu = _gas_viscosity(gsg, temp_f, press_psia, z=zee, tc=tc, pc=pc) if viscosity else None
|
|
1077
|
+
return zee, mu
|
|
1078
|
+
zmethod, cmethod, sg, (co2, h2s, n2, h2, he), tc_z, pc_z = zspec
|
|
1079
|
+
kw = dict(p=press_psia, sg=sg, degf=temp_f, zmethod=zmethod, cmethod=cmethod,
|
|
1080
|
+
co2=co2, h2s=h2s, n2=n2, h2=h2, he=he, tc=tc_z, pc=pc_z)
|
|
1081
|
+
zee = float(gas.gas_z(**kw))
|
|
1082
|
+
return zee, (float(gas.gas_ug(**kw)) if viscosity else None)
|
|
1083
|
+
|
|
1084
|
+
|
|
1085
|
+
def _static_gas_column_pressure(thp, length, tht, bht, gsg, theta=math.pi / 2.0, zspec=None):
|
|
1067
1086
|
tc, pc = _sutton_tc_pc(gsg)
|
|
1068
1087
|
n_seg = 50
|
|
1069
1088
|
d_len = length / n_seg
|
|
@@ -1073,7 +1092,7 @@ def _static_gas_column_pressure(thp, length, tht, bht, gsg, theta=math.pi / 2.0)
|
|
|
1073
1092
|
frac = (i + 0.5) / n_seg
|
|
1074
1093
|
temp_local = tht + (bht - tht) * frac
|
|
1075
1094
|
temp_r = temp_local + 459.67
|
|
1076
|
-
zee =
|
|
1095
|
+
zee, _ = _march_gas_z_mu(gsg, temp_local, max(p, 14.7), tc, pc, zspec, viscosity=False)
|
|
1077
1096
|
rho_gas = _MW_AIR * gsg * p / (zee * _R_GAS * temp_r)
|
|
1078
1097
|
p += rho_gas / _IN2_PER_FT2 * d_len * sin_theta
|
|
1079
1098
|
return p
|
|
@@ -1186,11 +1205,11 @@ def _hb_gradient_gas(s):
|
|
|
1186
1205
|
def _hb_fbhp_gas(thp, api, gsg, tid, rough, length, tht, bht,
|
|
1187
1206
|
wsg, qg_mmscfd, cgr, qw_bwpd, oil_vis,
|
|
1188
1207
|
injection=False, pr=0.0, theta=math.pi / 2.0,
|
|
1189
|
-
|
|
1208
|
+
zspec=None):
|
|
1190
1209
|
return _segment_march_gas(thp, api, gsg, tid, rough, length, tht, bht,
|
|
1191
1210
|
wsg, qg_mmscfd, cgr, qw_bwpd, oil_vis,
|
|
1192
1211
|
injection, pr, theta, _hb_gradient_gas,
|
|
1193
|
-
|
|
1212
|
+
zspec=zspec)
|
|
1194
1213
|
|
|
1195
1214
|
|
|
1196
1215
|
@rust_accelerated('hb_fbhp_oil_rust')
|
|
@@ -1312,11 +1331,11 @@ def _wg_gradient_gas(s):
|
|
|
1312
1331
|
def _wg_fbhp_gas(thp, api, gsg, tid, rough, length, tht, bht,
|
|
1313
1332
|
wsg, qg_mmscfd, cgr, qw_bwpd, oil_vis,
|
|
1314
1333
|
injection=False, pr=0.0, theta=math.pi / 2.0,
|
|
1315
|
-
|
|
1334
|
+
zspec=None):
|
|
1316
1335
|
return _segment_march_gas(thp, api, gsg, tid, rough, length, tht, bht,
|
|
1317
1336
|
wsg, qg_mmscfd, cgr, qw_bwpd, oil_vis,
|
|
1318
1337
|
injection, pr, theta, _wg_gradient_gas,
|
|
1319
|
-
|
|
1338
|
+
zspec=zspec)
|
|
1320
1339
|
|
|
1321
1340
|
|
|
1322
1341
|
@rust_accelerated('wg_fbhp_oil_rust')
|
|
@@ -1404,16 +1423,16 @@ def _gray_effective_roughness(rough_dry, sigma, rho_ns, v_sl, v_sg):
|
|
|
1404
1423
|
|
|
1405
1424
|
def _segment_march_gas(thp, api, gsg, tid, rough, length, tht, bht,
|
|
1406
1425
|
wsg, qg_mmscfd, cgr, qw_bwpd, oil_vis,
|
|
1407
|
-
injection, pr, theta, gradient_fn,
|
|
1426
|
+
injection, pr, theta, gradient_fn, zspec=None):
|
|
1408
1427
|
"""Shared segment march for all gas VLP methods.
|
|
1409
1428
|
|
|
1410
1429
|
gradient_fn(s) -> dpdz (psi/ft)
|
|
1411
1430
|
Called at each pressure iteration with a dict containing all
|
|
1412
1431
|
computed PVT/flow properties for the current segment step.
|
|
1413
|
-
|
|
1432
|
+
zspec: GasPVT Z/viscosity spec (_gas_pvt_zspec); None -> Hall-Yarborough
|
|
1433
|
+
on Sutton pseudo-criticals of gsg with Lee-Gonzalez-Eakin viscosity.
|
|
1414
1434
|
"""
|
|
1415
|
-
|
|
1416
|
-
tc, pc = _sutton_tc_pc(gsg)
|
|
1435
|
+
tc, pc = _sutton_tc_pc(gsg)
|
|
1417
1436
|
osg = 141.5 / (api + 131.5)
|
|
1418
1437
|
total_mass = (_RHO_AIR_STC * gsg * qg_mmscfd * 1e6 +
|
|
1419
1438
|
osg * _RHO_FW * cgr * qg_mmscfd * _FT3_PER_BBL +
|
|
@@ -1432,7 +1451,7 @@ def _segment_march_gas(thp, api, gsg, tid, rough, length, tht, bht,
|
|
|
1432
1451
|
"the specified liquid rates (liquid loading not modelled).",
|
|
1433
1452
|
RuntimeWarning, stacklevel=3
|
|
1434
1453
|
)
|
|
1435
|
-
return _static_gas_column_pressure(thp, length, tht, bht, gsg, theta=theta)
|
|
1454
|
+
return _static_gas_column_pressure(thp, length, tht, bht, gsg, theta=theta, zspec=zspec)
|
|
1436
1455
|
|
|
1437
1456
|
diam_ft = tid / 12.0
|
|
1438
1457
|
rough_ft = rough / 12.0
|
|
@@ -1466,8 +1485,7 @@ def _segment_march_gas(thp, api, gsg, tid, rough, length, tht, bht,
|
|
|
1466
1485
|
oil_vis_loc = _condensate_vis(pr, cgr_loc, gsg, api,
|
|
1467
1486
|
temp_f, p_avg, oil_vis)
|
|
1468
1487
|
|
|
1469
|
-
zee =
|
|
1470
|
-
mu_g = _gas_viscosity(gsg, temp_f, p_avg, z=zee, tc=tc, pc=pc)
|
|
1488
|
+
zee, mu_g = _march_gas_z_mu(gsg, temp_f, p_avg, tc, pc, zspec)
|
|
1471
1489
|
|
|
1472
1490
|
rho_g = _MW_AIR * gsg * p_avg / (zee * _R_GAS * temp_r)
|
|
1473
1491
|
rho_l = lsg_loc * _RHO_FW
|
|
@@ -1506,7 +1524,7 @@ def _segment_march_gas(thp, api, gsg, tid, rough, length, tht, bht,
|
|
|
1506
1524
|
'qg_mmscfd': qg_mmscfd, 'api': api,
|
|
1507
1525
|
}
|
|
1508
1526
|
|
|
1509
|
-
dpdz = gradient_fn
|
|
1527
|
+
dpdz = _low_liquid_gradient(gradient_fn, s)
|
|
1510
1528
|
p_est = p_psia + dpdz * seg_len
|
|
1511
1529
|
|
|
1512
1530
|
p_psia = p_est
|
|
@@ -1518,6 +1536,25 @@ def _segment_march_gas(thp, api, gsg, tid, rough, length, tht, bht,
|
|
|
1518
1536
|
return p_psia
|
|
1519
1537
|
|
|
1520
1538
|
|
|
1539
|
+
def _low_liquid_gradient(gradient_fn, s):
|
|
1540
|
+
"""Gradient with a continuous approach to the dry-gas limit.
|
|
1541
|
+
|
|
1542
|
+
For 0 < lambda_l < _LOW_LIQ_LAMBDA returns g0 + (lambda_l/_LOW_LIQ_LAMBDA)(g - g0),
|
|
1543
|
+
where g is the method's two-phase gradient and g0 the same method with the
|
|
1544
|
+
liquid removed (its existing lambda_l = 0 path). At lambda_l = 0 and at or
|
|
1545
|
+
above _LOW_LIQ_LAMBDA this is exactly gradient_fn(s).
|
|
1546
|
+
"""
|
|
1547
|
+
g = gradient_fn(s)
|
|
1548
|
+
lam = s['lambda_l']
|
|
1549
|
+
if not 0.0 < lam < _LOW_LIQ_LAMBDA:
|
|
1550
|
+
return g
|
|
1551
|
+
s0 = dict(s, mflow_l=0.0, mflow_o=0.0, mflow_w=0.0, v_sl=0.0,
|
|
1552
|
+
v_m=s['v_sg'], lambda_l=0.0, rho_ns=s['rho_g'],
|
|
1553
|
+
mflow_total=s['mflow_g'], qo_loc=0.0, ql_loc=0.0, qw_bwpd=0.0)
|
|
1554
|
+
g0 = gradient_fn(s0)
|
|
1555
|
+
return g0 + (lam / _LOW_LIQ_LAMBDA) * (g - g0)
|
|
1556
|
+
|
|
1557
|
+
|
|
1521
1558
|
# ============================================================================
|
|
1522
1559
|
# Shared Oil Segment March
|
|
1523
1560
|
# ============================================================================
|
|
@@ -1673,11 +1710,11 @@ def _gray_gradient_gas(s):
|
|
|
1673
1710
|
def _gray_fbhp_gas(thp, api, gsg, tid, rough, length, tht, bht,
|
|
1674
1711
|
wsg, qg_mmscfd, cgr, qw_bwpd, oil_vis,
|
|
1675
1712
|
injection=False, pr=0.0, theta=math.pi / 2.0,
|
|
1676
|
-
|
|
1713
|
+
zspec=None):
|
|
1677
1714
|
return _segment_march_gas(thp, api, gsg, tid, rough, length, tht, bht,
|
|
1678
1715
|
wsg, qg_mmscfd, cgr, qw_bwpd, oil_vis,
|
|
1679
1716
|
injection, pr, theta, _gray_gradient_gas,
|
|
1680
|
-
|
|
1717
|
+
zspec=zspec)
|
|
1681
1718
|
|
|
1682
1719
|
|
|
1683
1720
|
@rust_accelerated('gray_fbhp_oil_rust')
|
|
@@ -1857,12 +1894,12 @@ def _bb_gradient_gas(s):
|
|
|
1857
1894
|
def _bb_core_gas(thp, api, gsg, tid, rough, length, tht, bht,
|
|
1858
1895
|
wsg, qg_mmscfd, cgr, qw_bwpd, oil_vis,
|
|
1859
1896
|
injection=False, pr=0.0, theta=math.pi / 2.0,
|
|
1860
|
-
|
|
1897
|
+
zspec=None):
|
|
1861
1898
|
"""Beggs & Brill core for gas wells."""
|
|
1862
1899
|
return _segment_march_gas(thp, api, gsg, tid, rough, length, tht, bht,
|
|
1863
1900
|
wsg, qg_mmscfd, cgr, qw_bwpd, oil_vis,
|
|
1864
1901
|
injection, pr, theta, _bb_gradient_gas,
|
|
1865
|
-
|
|
1902
|
+
zspec=zspec)
|
|
1866
1903
|
|
|
1867
1904
|
|
|
1868
1905
|
@rust_accelerated('bb_fbhp_oil_rust')
|
|
@@ -1975,7 +2012,7 @@ def fbhp(thp: float, completion: 'Completion', vlpmethod: str = 'WG', well_type:
|
|
|
1975
2012
|
length=length, tht=tht_seg, bht=bht_seg, wsg=wsg,
|
|
1976
2013
|
qg_mmscfd=f.qg_mmscfd, cgr=f.cgr, qw_bwpd=f.qw_bwpd,
|
|
1977
2014
|
oil_vis=oil_vis, injection=injection, pr=f.pr, theta=theta,
|
|
1978
|
-
|
|
2015
|
+
zspec=f.zspec)
|
|
1979
2016
|
else:
|
|
1980
2017
|
return _OIL_METHOD_DIC[vlpmethod.name](
|
|
1981
2018
|
thp=thp_in, api=f.api, gsg=f.gsg, tid=tid, rough=rough,
|
|
@@ -30,8 +30,6 @@ from typing import Union, Tuple
|
|
|
30
30
|
import numpy as np
|
|
31
31
|
import numpy.typing as npt
|
|
32
32
|
from tabulate import tabulate
|
|
33
|
-
from ilt import gwr
|
|
34
|
-
from mpmath import mp
|
|
35
33
|
|
|
36
34
|
from pyrestoolbox._accelerator import RUST_AVAILABLE, _rust_module
|
|
37
35
|
|
|
@@ -74,7 +72,17 @@ def influence_tables(
|
|
|
74
72
|
if RUST_AVAILABLE:
|
|
75
73
|
pDs = _rust_module.influence_tables_rust(tD.tolist(), list(ReDs), M)
|
|
76
74
|
else:
|
|
77
|
-
# Python fallback via ilt library
|
|
75
|
+
# Python fallback via ilt library (optional extra: pyrestoolbox[aquifer])
|
|
76
|
+
try:
|
|
77
|
+
from ilt import gwr
|
|
78
|
+
from mpmath import mp
|
|
79
|
+
except ImportError as e:
|
|
80
|
+
raise ImportError(
|
|
81
|
+
"influence_tables needs the Rust extension or the optional "
|
|
82
|
+
"inverse-Laplace dependencies; install them with "
|
|
83
|
+
"pip install 'pyrestoolbox[aquifer]'"
|
|
84
|
+
) from e
|
|
85
|
+
|
|
78
86
|
def laplace_Ps(s: float, ReD: float):
|
|
79
87
|
x = mp.sqrt(s)
|
|
80
88
|
# pre-calculate duplicated bessel function for greater efficiency
|