pyrestoolbox 3.0.4__tar.gz → 3.0.5__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.0.5/MANIFEST.in +8 -0
- {pyrestoolbox-3.0.4/pyrestoolbox.egg-info → pyrestoolbox-3.0.5}/PKG-INFO +1 -1
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/brine/brine.py +8 -5
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/docs/brine.rst +14 -12
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/docs/changelist.rst +12 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/docs/matbal.rst +20 -1
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/docs/oil.rst +121 -13
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/docs/simtools.rst +1 -1
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/matbal/matbal.py +19 -1
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/oil/oil.py +201 -61
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/simtools/simtools.py +16 -10
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5/pyrestoolbox.egg-info}/PKG-INFO +1 -1
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox.egg-info/SOURCES.txt +0 -18
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/setup.cfg +5 -2
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/setup.py +2 -2
- pyrestoolbox-3.0.4/MANIFEST.in +0 -6
- pyrestoolbox-3.0.4/pyrestoolbox/docs/.ipynb_checkpoints/examples-checkpoint.ipynb +0 -1458
- pyrestoolbox-3.0.4/pyrestoolbox/docs/.ipynb_checkpoints/nodal_examples-checkpoint.ipynb +0 -825
- pyrestoolbox-3.0.4/pyrestoolbox/docs/.ipynb_checkpoints/nodal_hydrate_demo-checkpoint.ipynb +0 -1345
- pyrestoolbox-3.0.4/pyrestoolbox/tests/__init__.py +0 -0
- pyrestoolbox-3.0.4/pyrestoolbox/tests/run_all_tests.py +0 -98
- pyrestoolbox-3.0.4/pyrestoolbox/tests/test_brine.py +0 -266
- pyrestoolbox-3.0.4/pyrestoolbox/tests/test_dca.py +0 -675
- pyrestoolbox-3.0.4/pyrestoolbox/tests/test_doc_examples.py +0 -1394
- pyrestoolbox-3.0.4/pyrestoolbox/tests/test_gas.py +0 -849
- pyrestoolbox-3.0.4/pyrestoolbox/tests/test_layer.py +0 -115
- pyrestoolbox-3.0.4/pyrestoolbox/tests/test_matbal.py +0 -724
- pyrestoolbox-3.0.4/pyrestoolbox/tests/test_nodal.py +0 -836
- pyrestoolbox-3.0.4/pyrestoolbox/tests/test_oil.py +0 -499
- pyrestoolbox-3.0.4/pyrestoolbox/tests/test_recommend.py +0 -104
- pyrestoolbox-3.0.4/pyrestoolbox/tests/test_sensitivity.py +0 -122
- pyrestoolbox-3.0.4/pyrestoolbox/tests/test_simtools.py +0 -405
- pyrestoolbox-3.0.4/pyrestoolbox/tests/test_unified_brine_design.py +0 -351
- pyrestoolbox-3.0.4/pyrestoolbox/tests/test_viscosity_scaling.py +0 -464
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/LICENSE +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/README.rst +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyproject.toml +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/__init__.py +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/brine/__init__.py +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/brine/_lib_salting_library.py +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/brine/_lib_vle_engine.py +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/classes/__init__.py +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/classes/classes.py +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/constants/__init__.py +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/constants/constants.py +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/dca/__init__.py +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/dca/dca.py +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/docs/dca.rst +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/docs/examples.ipynb +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/docs/gas.rst +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/docs/img/bot.png +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/docs/img/bot_PVTO.png +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/docs/img/bot_img.png +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/docs/img/dry_gas.png +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/docs/img/grid_sat_df.png +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/docs/img/influence.png +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/docs/img/properties_df.png +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/docs/img/sgof.png +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/docs/img/swof.png +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/docs/layer.rst +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/docs/library.rst +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/docs/nodal.rst +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/docs/nodal_examples.ipynb +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/docs/nodal_hydrate_demo.ipynb +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/docs/recommend.rst +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/docs/sensitivity.rst +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/gas/__init__.py +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/gas/gas.py +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/layer/__init__.py +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/layer/layer.py +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/library/__init__.py +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/library/component_library.xlsx +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/library/library.py +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/matbal/__init__.py +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/nodal/__init__.py +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/nodal/nodal.py +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/oil/__init__.py +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/plyasunov/__init__.py +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/plyasunov/iapws_if97.py +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/plyasunov/plyasunov_model.py +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/plyasunov/water_properties.py +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/recommend/__init__.py +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/recommend/recommend.py +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/sensitivity/__init__.py +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/sensitivity/sensitivity.py +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/shared_fns/__init__.py +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/shared_fns/shared_fns.py +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/simtools/__init__.py +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/validate/__init__.py +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox/validate/validate.py +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox.egg-info/dependency_links.txt +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox.egg-info/requires.txt +0 -0
- {pyrestoolbox-3.0.4 → pyrestoolbox-3.0.5}/pyrestoolbox.egg-info/top_level.txt +0 -0
|
@@ -24,7 +24,7 @@ Brine property calculations with three models.
|
|
|
24
24
|
|
|
25
25
|
Functions
|
|
26
26
|
---------
|
|
27
|
-
brine_props Methane-saturated brine properties (Bw, density, viscosity,
|
|
27
|
+
brine_props Methane-saturated brine properties (Bw, density, viscosity, [Cw_usat, Cw_sat], Rs)
|
|
28
28
|
make_pvtw_table Water PVT table generation (backward-compatible wrapper)
|
|
29
29
|
|
|
30
30
|
Classes
|
|
@@ -361,12 +361,15 @@ def brine_props(p: float, degf: float, wt: float=0, ch4_sat: float=0, metric: bo
|
|
|
361
361
|
bw = Bw # rb/stb (dimensionless ratio, same in both unit systems)
|
|
362
362
|
lden = rhobtpbch4 # sg (g/cm3)
|
|
363
363
|
visw = ub_tpm # cP
|
|
364
|
-
|
|
364
|
+
cwu_psi = 1 / (145.038 * (1 / cwu)) # Undersaturated compressibility in psi-1
|
|
365
|
+
cws_psi = cw_new # Saturated compressibility in psi-1
|
|
365
366
|
rsw = rsw_new_oilfield # scf/stb
|
|
366
367
|
|
|
367
368
|
if metric:
|
|
368
|
-
cw =
|
|
369
|
+
cw = [cwu_psi * INVPSI_TO_INVBAR, cws_psi * INVPSI_TO_INVBAR] # 1/bar
|
|
369
370
|
rsw = rsw * SCF_PER_STB_TO_SM3_PER_SM3 # scf/stb -> sm3/sm3
|
|
371
|
+
else:
|
|
372
|
+
cw = [cwu_psi, cws_psi] # 1/psi
|
|
370
373
|
|
|
371
374
|
return (bw, lden, visw, cw, rsw)
|
|
372
375
|
|
|
@@ -1686,10 +1689,10 @@ class SoreideWhitson:
|
|
|
1686
1689
|
# Viscosity: Mao-Duan (2009) via brine_props
|
|
1687
1690
|
# ================================================================
|
|
1688
1691
|
# brine_props still needed for viscosity, compressibility, Bw, Rsw
|
|
1689
|
-
bw_base, den_base_sg, vis_base_cP,
|
|
1692
|
+
bw_base, den_base_sg, vis_base_cP, _, rsw_base = brine_props(
|
|
1690
1693
|
p=psia, degf=degf, wt=wt, ch4_sat=0
|
|
1691
1694
|
)
|
|
1692
|
-
bw_fw, den_fw_sg, vis_fw_cP,
|
|
1695
|
+
bw_fw, den_fw_sg, vis_fw_cP, _, rsw_fw = brine_props(
|
|
1693
1696
|
p=psia, degf=degf, wt=0, ch4_sat=0
|
|
1694
1697
|
)
|
|
1695
1698
|
|
|
@@ -91,8 +91,8 @@ pyrestoolbox.brine.brine_props
|
|
|
91
91
|
- float
|
|
92
92
|
- Viscosity (cP)
|
|
93
93
|
* - [3]
|
|
94
|
-
-
|
|
95
|
-
- Compressibility (1/psi, or 1/barsa if metric=True)
|
|
94
|
+
- list
|
|
95
|
+
- Compressibility [undersaturated, saturated] (1/psi, or 1/barsa if metric=True). The undersaturated value (Cw[0]) is the isothermal compressibility of the brine at constant dissolved gas content. The saturated value (Cw[1]) is a pseudo-compressibility representing the average compressibility of the brine and differentially evolved gas system, accounting for both liquid compression and gas exsolution volume changes
|
|
96
96
|
* - [4]
|
|
97
97
|
- float
|
|
98
98
|
- Rsw — solution gas-water ratio (scf/stb, or sm3/sm3 if metric=True)
|
|
@@ -106,17 +106,19 @@ Examples:
|
|
|
106
106
|
>>> print('Bw:', bw)
|
|
107
107
|
>>> print('SGw:', lsg)
|
|
108
108
|
>>> print('Visw:', visw)
|
|
109
|
-
>>> print('
|
|
109
|
+
>>> print('Cw_usat:', cw[0])
|
|
110
|
+
>>> print('Cw_sat:', cw[1])
|
|
110
111
|
>>> print('Rsw:', rsw)
|
|
111
112
|
Bw: 1.0152007040056148
|
|
112
113
|
SGw: 0.9950108179684295
|
|
113
114
|
Visw: 0.4994004662758671
|
|
114
|
-
|
|
115
|
+
Cw_usat: 2.969627494768876e-06
|
|
116
|
+
Cw_sat: 0.0001539690974662865
|
|
115
117
|
Rsw: 1.2540982731813703
|
|
116
118
|
|
|
117
119
|
.. note::
|
|
118
120
|
|
|
119
|
-
When ``metric=True``, Cw
|
|
121
|
+
When ``metric=True``, Cw values are returned in 1/barsa (instead of 1/psi) and Rsw in sm3/sm3 (instead of scf/stb).
|
|
120
122
|
Bw (rb/stb), density (SG), and viscosity (cP) are unchanged by the unit system.
|
|
121
123
|
|
|
122
124
|
pyrestoolbox.brine.CO2_Brine_Mixture
|
|
@@ -187,9 +189,9 @@ pyrestoolbox.brine.CO2_Brine_Mixture
|
|
|
187
189
|
* - .Cf_usat
|
|
188
190
|
- float
|
|
189
191
|
- Brine undersaturated compressibility (1/Bar or 1/psi)
|
|
190
|
-
* - .
|
|
192
|
+
* - .Cf_sat
|
|
191
193
|
- float
|
|
192
|
-
- Brine saturated compressibility (1/Bar or 1/psi). Requires cw_sat input to be set True to calculate
|
|
194
|
+
- Brine saturated pseudo-compressibility (1/Bar or 1/psi). Represents the average compressibility of the brine and differentially evolved gas system, accounting for both liquid compression and gas exsolution. Requires cw_sat input to be set True to calculate
|
|
193
195
|
|
|
194
196
|
|
|
195
197
|
Examples:
|
|
@@ -272,7 +274,7 @@ Optionally exports ECLIPSE PVTW keyword file and Excel spreadsheet.
|
|
|
272
274
|
- Description
|
|
273
275
|
* - table
|
|
274
276
|
- DataFrame
|
|
275
|
-
- Pressure, Bw, Density, Viscosity,
|
|
277
|
+
- Pressure, Bw, Density, Viscosity, Cw_usat, Cw_sat, Rsw
|
|
276
278
|
* - pref
|
|
277
279
|
- float
|
|
278
280
|
- Reference pressure (psia, or barsa if metric=True)
|
|
@@ -280,8 +282,8 @@ Optionally exports ECLIPSE PVTW keyword file and Excel spreadsheet.
|
|
|
280
282
|
- float
|
|
281
283
|
- Bw at reference pressure (rb/stb)
|
|
282
284
|
* - cw_ref
|
|
283
|
-
-
|
|
284
|
-
- Compressibility at reference pressure (1/psi, or 1/bar if metric=True)
|
|
285
|
+
- list
|
|
286
|
+
- Compressibility [undersaturated, saturated] at reference pressure (1/psi, or 1/bar if metric=True)
|
|
285
287
|
* - visw_ref
|
|
286
288
|
- float
|
|
287
289
|
- Viscosity at reference pressure (cP)
|
|
@@ -301,7 +303,7 @@ Examples:
|
|
|
301
303
|
>>> result['bw_ref']
|
|
302
304
|
1.027589195773527
|
|
303
305
|
>>> result['cw_ref']
|
|
304
|
-
3.0887176266534516e-06
|
|
306
|
+
[3.0887176266534516e-06, 3.0887176266534516e-06]
|
|
305
307
|
>>> result['visw_ref']
|
|
306
308
|
0.3083544960904146
|
|
307
309
|
|
|
@@ -421,7 +423,7 @@ based on the gas specific gravity using constrained exponential decay to match t
|
|
|
421
423
|
- Brine undersaturated compressibility (1/Bar or 1/psi)
|
|
422
424
|
* - .Cf_sat
|
|
423
425
|
- float
|
|
424
|
-
- Brine saturated compressibility (1/Bar or 1/psi). Requires cw_sat input to be set True to calculate
|
|
426
|
+
- Brine saturated pseudo-compressibility (1/Bar or 1/psi). Represents the average compressibility of the brine and differentially evolved gas system, accounting for both liquid compression and gas exsolution. Requires cw_sat input to be set True to calculate
|
|
425
427
|
* - .gas_comp
|
|
426
428
|
- dict
|
|
427
429
|
- Normalized gas composition used (including estimated HC split from SG)
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
Changelist in 3.0.5:
|
|
2
|
+
|
|
3
|
+
- **brine_props()**: Compressibility return changed from a scalar (saturated only) to a ``[cw_usat, cw_sat]`` list. The undersaturated value (Spivey Eq 4.32) is the isothermal compressibility at constant dissolved gas content. The saturated value (Spivey Eq 4.35) is a pseudo-compressibility of the brine and differentially evolved gas system. Previously only the saturated value was returned.
|
|
4
|
+
- **oil_co()**: Changed from saturated pseudo-compressibility (``Co = -1/Bo * (dBo/dp - Bg * dRs/dp)``) to undersaturated compressibility (``Co = -1/Bo * dBo/dp`` at constant Rs). Rs is held at the equilibrium value for the specified pressure, yielding the isothermal liquid-phase compressibility without mixing in differentially evolved gas volume. Values below Pb are now smaller and physically consistent with above-Pb values.
|
|
5
|
+
- **oil_co() co_sat parameter**: New ``co_sat=False`` parameter. When ``True``, returns ``[co_usat, co_sat]`` list. Saturated compressibility uses Perrine's definition: ``co_sat = -(1/Bo)*dBo/dp + (Bg/Bo)*dRs/dp``, a pseudo-compressibility including gas evolution effects. Above Pb, both values are equal. Backward compatible — default returns a float.
|
|
6
|
+
- **oil_bt()**: New function returning total two-phase oil FVF: ``Bt = Bo + (Rsi - Rs) * Bg``. Above Pb returns Bo. Useful for material balance and reservoir voidage calculations.
|
|
7
|
+
- **oil_matbal() metric cw/cf fix**: Fixed bug where ``cw`` and ``cf`` in 1/bar were not converted to 1/psi when ``metric=True``, causing the Efw term to be off by ~14.5x. Regression bounds for ``cw``/``cf`` are also now correctly unit-converted.
|
|
8
|
+
- **CO2_Brine_Mixture.Cf_sat** and **SoreideWhitson.Cf_sat**: Documentation clarified that these are pseudo-compressibilities representing the average compressibility of the brine and differentially evolved gas system.
|
|
9
|
+
- **make_pvtw_table()**: Table now includes both ``Cw_usat`` and ``Cw_sat`` columns. ``cw_ref`` is now a ``[usat, sat]`` list. PVTW keyword export uses undersaturated compressibility.
|
|
10
|
+
- **make_bot_og()**: Water compressibility (``cw`` key) now uses undersaturated value from ``brine_props()``.
|
|
11
|
+
- 603 validation tests (up from 588 in 3.0.4).
|
|
12
|
+
|
|
1
13
|
Changelist in 3.0.4:
|
|
2
14
|
|
|
3
15
|
- **VLP performance**: Eliminated duplicate Z-factor calculations in all 8 VLP method functions. ``_gas_viscosity()`` now accepts a pre-computed Z-factor, avoiding a redundant Hall-Yarborough solve on every segment iteration. Combined with pre-computing Sutton critical properties (Tc/Pc) once per VLP function call instead of recalculating on every segment step. Delivers ~11% speedup on ``operating_point()`` and ``outflow_curve()`` calls.
|
|
@@ -257,7 +257,7 @@ Havlena-Odeh oil material balance for OOIP estimation. Computes underground with
|
|
|
257
257
|
- Initial water saturation (fraction, default 0)
|
|
258
258
|
* - cw
|
|
259
259
|
- float
|
|
260
|
-
- Water compressibility (1/psi | 1/bar, default 0)
|
|
260
|
+
- Water compressibility (1/psi | 1/bar, default 0). See compressibility guidance below
|
|
261
261
|
* - rsmethod
|
|
262
262
|
- str
|
|
263
263
|
- Solution GOR method (default 'VELAR')
|
|
@@ -370,6 +370,25 @@ Tabulated PVT Example:
|
|
|
370
370
|
82793519.84914012
|
|
371
371
|
|
|
372
372
|
|
|
373
|
+
.. note:: **Compressibility Guidance**
|
|
374
|
+
|
|
375
|
+
The ``cw`` parameter controls how water compressibility is treated in the formation/water expansion term (Efw). Two approaches are common:
|
|
376
|
+
|
|
377
|
+
- **Undersaturated (liquid-phase) compressibility**: Use ``cw_usat`` from ``brine.brine_props()``, which is the isothermal compressibility of brine at constant dissolved gas content. Appropriate when the material balance tracks free gas volumes separately, or when the water does not evolve dissolved gas over the depletion range.
|
|
378
|
+
|
|
379
|
+
- **Saturated (pseudo) compressibility**: Use ``cw_sat`` from ``brine.brine_props()``, which includes the volume of differentially evolved gas. Appropriate when no separate water-gas tracking is performed. Dissolved gas in water can contribute compressibility as large as or larger than the liquid-phase value alone (Ramey, 1964).
|
|
380
|
+
|
|
381
|
+
To compute ``cw`` from brine properties:
|
|
382
|
+
|
|
383
|
+
.. code-block:: python
|
|
384
|
+
|
|
385
|
+
>>> from pyrestoolbox import brine
|
|
386
|
+
>>> props = brine.brine_props(p=4000, degf=220, wt=3)
|
|
387
|
+
>>> cw_usat, cw_sat = props['cw'] # [undersaturated, saturated]
|
|
388
|
+
|
|
389
|
+
Similarly, ``oil.oil_co(co_sat=True)`` returns ``[co_usat, co_sat]`` — the undersaturated value is the liquid-phase compressibility, while the saturated value includes gas evolution effects (Perrine's definition).
|
|
390
|
+
|
|
391
|
+
|
|
373
392
|
Class Objects
|
|
374
393
|
======================
|
|
375
394
|
|
|
@@ -46,9 +46,9 @@ pyResToolBox uses class objects to track calculation options through the functio
|
|
|
46
46
|
+ 'VALMC': Valko-McCain Correlation (2003) - Only for oil_rs_bub (Rs at Pb)
|
|
47
47
|
* - comethod
|
|
48
48
|
- co_method
|
|
49
|
-
- Method for calculating oil compressibility. Defaults to 'EXPLT'.
|
|
49
|
+
- Method for calculating undersaturated oil compressibility. Defaults to 'EXPLT'.
|
|
50
50
|
Options are:
|
|
51
|
-
+ 'EXPLT': Explicit calculation with numerical derivatives
|
|
51
|
+
+ 'EXPLT': Explicit calculation with numerical derivatives via co = -1/bo*dBo/dp at constant Rs.
|
|
52
52
|
* - denomethod
|
|
53
53
|
- deno_method
|
|
54
54
|
- Method for calculating oil density. Defaults to 'SWMH'
|
|
@@ -152,7 +152,9 @@ Function List
|
|
|
152
152
|
* - Oil GOR at P
|
|
153
153
|
- `pyrestoolbox.oil.oil_rs`_
|
|
154
154
|
* - Oil Compressibility
|
|
155
|
-
- `pyrestoolbox.oil.oil_co`_
|
|
155
|
+
- `pyrestoolbox.oil.oil_co`_
|
|
156
|
+
* - Total Two-Phase Oil FVF
|
|
157
|
+
- `pyrestoolbox.oil.oil_bt`_
|
|
156
158
|
* - Oil Density
|
|
157
159
|
- `pyrestoolbox.oil.oil_deno`_
|
|
158
160
|
* - Oil Formation Volume Factor
|
|
@@ -546,9 +548,14 @@ pyrestoolbox.oil.oil_co
|
|
|
546
548
|
|
|
547
549
|
.. code-block:: python
|
|
548
550
|
|
|
549
|
-
oil_co(p, api,
|
|
551
|
+
oil_co(p, api, degf, sg_sp=0, sg_g=0, pb=0, rsb=0, co_sat=False, comethod='EXPLT', zmethod='DAK', rsmethod='VELAR', cmethod='PMC', denomethod='SWMH', bomethod='MCAIN', pbmethod='VALMC', metric=False) -> float or list
|
|
552
|
+
|
|
553
|
+
Returns oil compressibility (1/psi, or 1/barsa if metric=True).
|
|
554
|
+
|
|
555
|
+
By default (``co_sat=False``) returns **undersaturated** compressibility calculated with ``Co = -1/Bo * dBo/dp`` at constant Rs, using correlation values and their numerical derivatives. Rs is held at the equilibrium value for the specified pressure — rsb when above Pb, or the correlation value at p when below Pb. This yields the isothermal compressibility of the liquid oil phase at its current dissolved gas content, without mixing in the volume of differentially evolved gas.
|
|
556
|
+
|
|
557
|
+
When ``co_sat=True``, returns a ``[co_usat, co_sat]`` list. The **saturated** compressibility uses Perrine's definition: ``co_sat = -(1/Bo)*dBo/dp + (Bg/Bo)*dRs/dp``, where both Bo and Rs vary with pressure. This is a pseudo-compressibility representing the average compressibility of the oil and its differentially evolved gas. Above Pb, ``co_sat`` equals ``co_usat`` (no gas evolution).
|
|
550
558
|
|
|
551
|
-
Returns oil compressibility (1/psi, or 1/barsa if metric=True) calculated with Co = -1/Bo *[dBodp - Bg*dRsdp], using correlation values and their numerical derivatives.
|
|
552
559
|
At least one of sg_g and sg_sp must be supplied. This function will make simple assumption to estimate missing gas sg if only one is provided.
|
|
553
560
|
Either pb, rsb or both need to be specified. If one is missing, the other will be calculated from correlation
|
|
554
561
|
|
|
@@ -581,6 +588,9 @@ Either pb, rsb or both need to be specified. If one is missing, the other will b
|
|
|
581
588
|
* - rsb
|
|
582
589
|
- float
|
|
583
590
|
- Original solution GOR at original bubble point pressure (scf/stb, or sm3/sm3 if metric=True)
|
|
591
|
+
* - co_sat
|
|
592
|
+
- bool
|
|
593
|
+
- If True, return ``[co_usat, co_sat]`` list. Default False (returns float)
|
|
584
594
|
* - comethod
|
|
585
595
|
- string or co_method
|
|
586
596
|
- The method of Compressibility calculation to be employed. `Calculation Methods and Class Objects`_.
|
|
@@ -613,21 +623,119 @@ Either pb, rsb or both need to be specified. If one is missing, the other will b
|
|
|
613
623
|
* - Name
|
|
614
624
|
- Type
|
|
615
625
|
- Description
|
|
616
|
-
* -
|
|
626
|
+
* - co (co_sat=False)
|
|
617
627
|
- float
|
|
618
|
-
-
|
|
628
|
+
- Undersaturated oil compressibility (1/psi, or 1/barsa if metric=True)
|
|
629
|
+
* - [co_usat, co_sat] (co_sat=True)
|
|
630
|
+
- list
|
|
631
|
+
- ``[undersaturated, saturated]`` compressibility (1/psi, or 1/barsa if metric=True)
|
|
619
632
|
|
|
620
633
|
|
|
621
634
|
Examples:
|
|
622
635
|
|
|
623
636
|
.. code-block:: python
|
|
624
637
|
|
|
625
|
-
>>> oil.oil_co(p
|
|
626
|
-
|
|
638
|
+
>>> oil.oil_co(p=6000, api=47, degf=180, sg_sp=0.72, rsb=2750, pb=4945)
|
|
639
|
+
3.63915926110187e-05
|
|
640
|
+
|
|
641
|
+
>>> oil.oil_co(p=2000, api=47, degf=180, sg_sp=0.72, rsb=2750, pb=4945)
|
|
642
|
+
1.0122640715155418e-05
|
|
643
|
+
|
|
644
|
+
>>> oil.oil_co(p=2000, api=47, degf=180, sg_sp=0.72, rsb=2750, pb=4945, co_sat=True)
|
|
645
|
+
[1.0122640715155418e-05, 0.0002315283893081275]
|
|
646
|
+
|
|
647
|
+
|
|
648
|
+
pyrestoolbox.oil.oil_bt
|
|
649
|
+
=====================
|
|
650
|
+
|
|
651
|
+
.. code-block:: python
|
|
652
|
+
|
|
653
|
+
oil_bt(p, api, degf, sg_sp=0, sg_g=0, pb=0, rsb=0, rsi=0, zmethod='DAK', rsmethod='VELAR', cmethod='PMC', denomethod='SWMH', bomethod='MCAIN', pbmethod='VALMC', metric=False) -> float
|
|
654
|
+
|
|
655
|
+
Returns total two-phase oil formation volume factor Bt (rb/stb, or rm3/sm3 if metric=True).
|
|
656
|
+
|
|
657
|
+
``Bt = Bo + (Rsi - Rs) * Bg``
|
|
658
|
+
|
|
659
|
+
Above Pb, Rs = Rsi so Bt = Bo. Below Pb, Bt accounts for the reservoir volume of both the liquid oil and the gas that has evolved from it relative to the original solution GOR.
|
|
660
|
+
|
|
661
|
+
At least one of sg_g and sg_sp must be supplied.
|
|
662
|
+
Either pb, rsb or both need to be specified.
|
|
663
|
+
|
|
664
|
+
|
|
665
|
+
.. list-table:: Inputs
|
|
666
|
+
:widths: 10 15 40
|
|
667
|
+
:header-rows: 1
|
|
668
|
+
|
|
669
|
+
* - Parameter
|
|
670
|
+
- Type
|
|
671
|
+
- Description
|
|
672
|
+
* - p
|
|
673
|
+
- float
|
|
674
|
+
- Pressure (psia, or barsa if metric=True)
|
|
675
|
+
* - api
|
|
676
|
+
- float
|
|
677
|
+
- Density of stock tank liquid (API)
|
|
678
|
+
* - degf
|
|
679
|
+
- float
|
|
680
|
+
- Oil Temperature (deg F, or deg C if metric=True)
|
|
681
|
+
* - sg_sp
|
|
682
|
+
- float
|
|
683
|
+
- Separator gas gravity (relative to air)
|
|
684
|
+
* - sg_g
|
|
685
|
+
- float
|
|
686
|
+
- Weighted average specific gravity of surface gas (relative to air)
|
|
687
|
+
* - pb
|
|
688
|
+
- float
|
|
689
|
+
- Bubble point pressure (psia, or barsa if metric=True)
|
|
690
|
+
* - rsb
|
|
691
|
+
- float
|
|
692
|
+
- Solution GOR at bubble point (scf/stb, or sm3/sm3 if metric=True)
|
|
693
|
+
* - rsi
|
|
694
|
+
- float
|
|
695
|
+
- Initial solution GOR (scf/stb, or sm3/sm3 if metric=True). Default 0 = use rsb
|
|
696
|
+
* - zmethod
|
|
697
|
+
- string or z_method
|
|
698
|
+
- The method of gas z-factor calculation. `Calculation Methods and Class Objects`_.
|
|
699
|
+
* - rsmethod
|
|
700
|
+
- string or rs_method
|
|
701
|
+
- The method of Rs calculation. `Calculation Methods and Class Objects`_.
|
|
702
|
+
* - cmethod
|
|
703
|
+
- string or c_method
|
|
704
|
+
- The method of critical gas property calculation. `Calculation Methods and Class Objects`_.
|
|
705
|
+
* - denomethod
|
|
706
|
+
- string or deno_method
|
|
707
|
+
- The method of live oil density calculation. `Calculation Methods and Class Objects`_.
|
|
708
|
+
* - bomethod
|
|
709
|
+
- string or bo_method
|
|
710
|
+
- The method of Bo calculation. `Calculation Methods and Class Objects`_.
|
|
711
|
+
* - pbmethod
|
|
712
|
+
- string or pb_method
|
|
713
|
+
- The method of Pb calculation. `Calculation Methods and Class Objects`_.
|
|
714
|
+
* - metric
|
|
715
|
+
- bool
|
|
716
|
+
- Use Eclipse METRIC units for inputs/outputs. Default False
|
|
717
|
+
|
|
718
|
+
.. list-table:: Returns
|
|
719
|
+
:widths: 10 15 40
|
|
720
|
+
:header-rows: 1
|
|
721
|
+
|
|
722
|
+
* - Name
|
|
723
|
+
- Type
|
|
724
|
+
- Description
|
|
725
|
+
* -
|
|
726
|
+
- float
|
|
727
|
+
- Total two-phase oil FVF (rb/stb, or rm3/sm3 if metric=True)
|
|
728
|
+
|
|
729
|
+
Examples:
|
|
730
|
+
|
|
731
|
+
.. code-block:: python
|
|
732
|
+
|
|
733
|
+
>>> oil.oil_bt(p=2000, api=47, degf=180, sg_sp=0.72, rsb=2750, pb=4945)
|
|
734
|
+
4.162163176179142
|
|
735
|
+
|
|
736
|
+
>>> oil.oil_bt(p=6000, api=47, degf=180, sg_sp=0.72, rsb=2750, pb=4945)
|
|
737
|
+
2.291191400872878
|
|
627
738
|
|
|
628
|
-
>>> oil.oil_co(p=2000, api=47, degf=180, sg_sp =0.72, rsb =2750, pb=4945)
|
|
629
|
-
0.0002311385007013396
|
|
630
|
-
|
|
631
739
|
|
|
632
740
|
pyrestoolbox.oil.oil_deno
|
|
633
741
|
==============================
|
|
@@ -1036,7 +1144,7 @@ If user species Pb or Rsb only, the corresponding property will be calculated. I
|
|
|
1036
1144
|
- Water density at Pi (lb/cuft)
|
|
1037
1145
|
* - 'cw'
|
|
1038
1146
|
- float
|
|
1039
|
-
- Water compressibility at Pi (1/psi)
|
|
1147
|
+
- Water undersaturated compressibility at Pi (1/psi)
|
|
1040
1148
|
* - 'uw'
|
|
1041
1149
|
- float
|
|
1042
1150
|
- Water viscosity at Pi (cP)
|
|
@@ -1210,7 +1210,7 @@ Creates data required for Oil-Gas-Water black oil tables (PVDO, PVDG, optionally
|
|
|
1210
1210
|
- Water density at Pi (lb/cuft, or kg/m3 if metric)
|
|
1211
1211
|
* - 'cw'
|
|
1212
1212
|
- float
|
|
1213
|
-
- Water compressibility at Pi (1/psi, or 1/bar if metric)
|
|
1213
|
+
- Water undersaturated compressibility at Pi (1/psi, or 1/bar if metric)
|
|
1214
1214
|
* - 'uw'
|
|
1215
1215
|
- float
|
|
1216
1216
|
- Water viscosity at Pi (cP)
|
|
@@ -451,6 +451,9 @@ def oil_matbal(p, Np, degf, api=0, sg_sp=0, sg_g=0, pb=0, rsb=0,
|
|
|
451
451
|
degf_field = degc_to_degf(degf)
|
|
452
452
|
pb_field = pb * BAR_TO_PSI if pb > 0 else 0
|
|
453
453
|
rsb_field = rsb * SM3_PER_SM3_TO_SCF_PER_STB if rsb > 0 else 0
|
|
454
|
+
# Convert compressibilities from 1/bar to 1/psi
|
|
455
|
+
cw = cw / BAR_TO_PSI # 1/bar → 1/psi
|
|
456
|
+
cf = cf / BAR_TO_PSI # 1/bar → 1/psi
|
|
454
457
|
else:
|
|
455
458
|
p_field = p
|
|
456
459
|
degf_field = degf
|
|
@@ -567,6 +570,14 @@ def oil_matbal(p, Np, degf, api=0, sg_sp=0, sg_g=0, pb=0, rsb=0,
|
|
|
567
570
|
|
|
568
571
|
param_names = list(regress.keys())
|
|
569
572
|
bounds = [regress[k] for k in param_names]
|
|
573
|
+
|
|
574
|
+
# Convert compressibility regression bounds from 1/bar to 1/psi when metric
|
|
575
|
+
if metric:
|
|
576
|
+
bounds = [
|
|
577
|
+
(lo / BAR_TO_PSI, hi / BAR_TO_PSI) if k in ('cw', 'cf') else (lo, hi)
|
|
578
|
+
for k, (lo, hi) in zip(param_names, bounds)
|
|
579
|
+
]
|
|
580
|
+
|
|
570
581
|
base_vals = {'m': m, 'cf': cf, 'cw': cw, 'sw_i': sw_i}
|
|
571
582
|
|
|
572
583
|
# Initial guess: use passed value if within bounds, else midpoint
|
|
@@ -605,7 +616,14 @@ def oil_matbal(p, Np, degf, api=0, sg_sp=0, sg_g=0, pb=0, rsb=0,
|
|
|
605
616
|
cf = base_vals['cf']
|
|
606
617
|
cw = base_vals['cw']
|
|
607
618
|
sw_i = base_vals['sw_i']
|
|
608
|
-
|
|
619
|
+
|
|
620
|
+
# Report regressed values back in user's unit system
|
|
621
|
+
regressed_result = {}
|
|
622
|
+
for k, v in zip(param_names, opt_result.x):
|
|
623
|
+
if metric and k in ('cw', 'cf'):
|
|
624
|
+
regressed_result[k] = float(v * BAR_TO_PSI) # 1/psi → 1/bar
|
|
625
|
+
else:
|
|
626
|
+
regressed_result[k] = float(v)
|
|
609
627
|
|
|
610
628
|
# Final computation with (possibly regressed) params
|
|
611
629
|
ooip, Efw, denom, valid = _compute_result(m, cf, cw, sw_i)
|