pyrestoolbox 2.1.4__tar.gz → 2.2.1__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-2.1.4/pyrestoolbox.egg-info → pyrestoolbox-2.2.1}/PKG-INFO +1 -3
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyrestoolbox/brine/brine.py +187 -65
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyrestoolbox/classes/classes.py +2 -0
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyrestoolbox/docs/brine.rst +102 -1
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyrestoolbox/docs/changelist.rst +5 -0
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyrestoolbox/gas/gas.py +310 -276
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyrestoolbox/layer/layer.py +2 -13
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyrestoolbox/library/library.py +3 -2
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyrestoolbox/oil/oil.py +23 -40
- pyrestoolbox-2.2.1/pyrestoolbox/shared_fns/shared_fns.py +163 -0
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyrestoolbox/simtools/simtools.py +20 -43
- pyrestoolbox-2.2.1/pyrestoolbox/tests/__init__.py +0 -0
- pyrestoolbox-2.2.1/pyrestoolbox/tests/run_all_tests.py +92 -0
- pyrestoolbox-2.2.1/pyrestoolbox/tests/test_brine.py +220 -0
- pyrestoolbox-2.2.1/pyrestoolbox/tests/test_gas.py +389 -0
- pyrestoolbox-2.2.1/pyrestoolbox/tests/test_layer.py +115 -0
- pyrestoolbox-2.2.1/pyrestoolbox/tests/test_oil.py +266 -0
- pyrestoolbox-2.2.1/pyrestoolbox/tests/test_simtools.py +175 -0
- pyrestoolbox-2.2.1/pyrestoolbox/validate/validate.py +22 -0
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1/pyrestoolbox.egg-info}/PKG-INFO +1 -3
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyrestoolbox.egg-info/SOURCES.txt +8 -15
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyrestoolbox.egg-info/requires.txt +0 -2
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/setup.cfg +1 -3
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/setup.py +2 -4
- pyrestoolbox-2.1.4/pyrestoolbox/brine/__pycache__/__init__.cpython-39.pyc +0 -0
- pyrestoolbox-2.1.4/pyrestoolbox/brine/__pycache__/brine.cpython-39.pyc +0 -0
- pyrestoolbox-2.1.4/pyrestoolbox/classes/__pycache__/__init__.cpython-39.pyc +0 -0
- pyrestoolbox-2.1.4/pyrestoolbox/classes/__pycache__/classes.cpython-39.pyc +0 -0
- pyrestoolbox-2.1.4/pyrestoolbox/constants/__pycache__/__init__.cpython-39.pyc +0 -0
- pyrestoolbox-2.1.4/pyrestoolbox/constants/__pycache__/constants.cpython-39.pyc +0 -0
- pyrestoolbox-2.1.4/pyrestoolbox/gas/__pycache__/__init__.cpython-39.pyc +0 -0
- pyrestoolbox-2.1.4/pyrestoolbox/gas/__pycache__/gas.cpython-39.pyc +0 -0
- pyrestoolbox-2.1.4/pyrestoolbox/oil/__pycache__/__init__.cpython-39.pyc +0 -0
- pyrestoolbox-2.1.4/pyrestoolbox/oil/__pycache__/oil.cpython-39.pyc +0 -0
- pyrestoolbox-2.1.4/pyrestoolbox/shared_fns/__pycache__/__init__.cpython-39.pyc +0 -0
- pyrestoolbox-2.1.4/pyrestoolbox/shared_fns/__pycache__/shared_fns.cpython-39.pyc +0 -0
- pyrestoolbox-2.1.4/pyrestoolbox/shared_fns/shared_fns.py +0 -92
- pyrestoolbox-2.1.4/pyrestoolbox/validate/__pycache__/__init__.cpython-39.pyc +0 -0
- pyrestoolbox-2.1.4/pyrestoolbox/validate/__pycache__/validate.cpython-39.pyc +0 -0
- pyrestoolbox-2.1.4/pyrestoolbox/validate/validate.py +0 -16
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/LICENSE +0 -0
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/MANIFEST.in +0 -0
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/README.md +0 -0
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/README.rst +0 -0
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyproject.toml +0 -0
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyrestoolbox/__init__.py +0 -0
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyrestoolbox/brine/__init__.py +0 -0
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyrestoolbox/classes/__init__.py +0 -0
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyrestoolbox/constants/__init__.py +0 -0
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyrestoolbox/constants/constants.py +0 -0
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyrestoolbox/docs/gas.rst +0 -0
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyrestoolbox/docs/img/bot.png +0 -0
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyrestoolbox/docs/img/bot_PVTO.png +0 -0
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyrestoolbox/docs/img/bot_img.png +0 -0
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyrestoolbox/docs/img/dry_gas.png +0 -0
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyrestoolbox/docs/img/grid_sat_df.png +0 -0
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyrestoolbox/docs/img/influence.png +0 -0
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyrestoolbox/docs/img/properties_df.png +0 -0
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyrestoolbox/docs/img/sgof.png +0 -0
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyrestoolbox/docs/img/swof.png +0 -0
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyrestoolbox/docs/layer.rst +0 -0
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyrestoolbox/docs/library.rst +0 -0
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyrestoolbox/docs/oil.rst +0 -0
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyrestoolbox/docs/simtools.rst +0 -0
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyrestoolbox/gas/__init__.py +0 -0
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyrestoolbox/layer/__init__.py +0 -0
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyrestoolbox/library/__init__.py +0 -0
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyrestoolbox/library/component_library.xlsx +0 -0
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyrestoolbox/oil/__init__.py +0 -0
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyrestoolbox/shared_fns/__init__.py +0 -0
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyrestoolbox/simtools/__init__.py +0 -0
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyrestoolbox/validate/__init__.py +0 -0
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyrestoolbox.egg-info/dependency_links.txt +0 -0
- {pyrestoolbox-2.1.4 → pyrestoolbox-2.2.1}/pyrestoolbox.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyrestoolbox
|
|
3
|
-
Version: 2.1
|
|
3
|
+
Version: 2.2.1
|
|
4
4
|
Summary: pyResToolbox - A collection of Reservoir Engineering Utilities
|
|
5
5
|
Home-page: https://github.com/mwburgoyne/pyResToolbox
|
|
6
6
|
Author: Mark W. Burgoyne
|
|
@@ -12,7 +12,6 @@ Classifier: License :: OSI Approved :: GNU General Public License v3 or later (G
|
|
|
12
12
|
Classifier: Operating System :: OS Independent
|
|
13
13
|
Description-Content-Type: text/markdown
|
|
14
14
|
License-File: LICENSE
|
|
15
|
-
Requires-Dist: requests
|
|
16
15
|
Requires-Dist: numpy
|
|
17
16
|
Requires-Dist: scipy
|
|
18
17
|
Requires-Dist: pandas
|
|
@@ -20,7 +19,6 @@ Requires-Dist: tabulate
|
|
|
20
19
|
Requires-Dist: gwr_inversion
|
|
21
20
|
Requires-Dist: mpmath
|
|
22
21
|
Requires-Dist: openpyxl
|
|
23
|
-
Requires-Dist: setuptools
|
|
24
22
|
Dynamic: author
|
|
25
23
|
Dynamic: author-email
|
|
26
24
|
Dynamic: description
|
|
@@ -21,25 +21,39 @@
|
|
|
21
21
|
Contact author at mark.w.burgoyne@gmail.com
|
|
22
22
|
"""
|
|
23
23
|
|
|
24
|
-
import sys
|
|
25
|
-
from collections import Counter
|
|
26
|
-
import glob
|
|
27
|
-
from enum import Enum
|
|
28
|
-
import pkg_resources
|
|
29
|
-
|
|
30
24
|
import numpy as np
|
|
31
25
|
import numpy.typing as npt
|
|
32
|
-
|
|
33
26
|
import pandas as pd
|
|
27
|
+
|
|
28
|
+
from typing import Tuple
|
|
34
29
|
from tabulate import tabulate
|
|
35
|
-
from typing import Union, List, Tuple
|
|
36
30
|
|
|
37
31
|
import pyrestoolbox.gas as gas # Needed for Z-Factor
|
|
38
32
|
from pyrestoolbox.classes import z_method, c_method, pb_method, rs_method, bo_method, uo_method, deno_method, co_method, kr_family, kr_table, class_dic
|
|
39
|
-
from pyrestoolbox.shared_fns import convert_to_numpy, process_output
|
|
33
|
+
from pyrestoolbox.shared_fns import convert_to_numpy, process_output, halley_solve_cubic
|
|
40
34
|
from pyrestoolbox.validate import validate_methods
|
|
41
35
|
from pyrestoolbox.constants import R, psc, tsc, degF2R, tscr, scf_per_mol, CUFTperBBL, WDEN, MW_CO2, MW_H2S, MW_N2, MW_AIR, MW_H2
|
|
42
36
|
|
|
37
|
+
def _Eq41(t, input_array):
|
|
38
|
+
"""Eq 4.1 from McCain Petroleum Reservoir Fluid Properties"""
|
|
39
|
+
t2 = t / 100
|
|
40
|
+
return (
|
|
41
|
+
input_array[1] * t2 ** 2 + input_array[2] * t2 + input_array[3]
|
|
42
|
+
) / (input_array[4] * t2 ** 2 + input_array[5] * t2 + 1)
|
|
43
|
+
|
|
44
|
+
# Spivey coefficient tables (shared by brine_props and brine_props_co2)
|
|
45
|
+
_RHOW_T70_ARR = [0, -0.127213, 0.645486, 1.03265, -0.070291, 0.639589]
|
|
46
|
+
_EWT_ARR = [0, 4.221, -3.478, 6.221, 0.5182, -0.4405]
|
|
47
|
+
_FWT_ARR = [0, -11.403, 29.932, 27.952, 0.20684, 0.3768]
|
|
48
|
+
_DM2T_ARR = [0, -0.00011149, 0.000175105, -0.00043766, 0, 0]
|
|
49
|
+
_DM32T_ARR = [0, -0.0008878, -0.0001388, -0.00296318, 0, 0.51103]
|
|
50
|
+
_DM1T_ARR = [0, 0.0021466, 0.012427, 0.042648, -0.081009, 0.525417]
|
|
51
|
+
_DM12T_ARR = [0, 0.0002356, -0.0003636, -0.0002278, 0, 0]
|
|
52
|
+
_EMT_ARR = [0, 0, 0, 0.1249, 0, 0]
|
|
53
|
+
_FM32T_ARR = [0, -0.617, -0.747, -0.4339, 0, 10.26]
|
|
54
|
+
_FM1T_ARR = [0, 0, 9.917, 5.1128, 0, 3.892]
|
|
55
|
+
_FM12T_ARR = [0, 0.0365, -0.0369, 0, 0, 0]
|
|
56
|
+
|
|
43
57
|
def brine_props(p: float, degf: float, wt: float=0, ch4_sat: float=0) -> Tuple:
|
|
44
58
|
""" Calculates Brine properties from modified Spivey Correlation per McCain Petroleum Reservoir Fluid Properties pg 160
|
|
45
59
|
Returns Tuple of (Bw (rb/stb), Density (sg), viscosity (cP), Compressibility (1/psi), Rw GOR (scf/stb))
|
|
@@ -48,12 +62,7 @@ def brine_props(p: float, degf: float, wt: float=0, ch4_sat: float=0) -> Tuple:
|
|
|
48
62
|
wt: Salt wt% (0-100)
|
|
49
63
|
ch4_sat: Degree of methane saturation (0 - 1)
|
|
50
64
|
"""
|
|
51
|
-
|
|
52
|
-
def Eq41(t, input_array): # From McCain Petroleum Reservoir Fluid Properties
|
|
53
|
-
t2 = t / 100
|
|
54
|
-
return (
|
|
55
|
-
input_array[1] * t2 ** 2 + input_array[2] * t2 + input_array[3]
|
|
56
|
-
) / (input_array[4] * t2 ** 2 + input_array[5] * t2 + 1)
|
|
65
|
+
Eq41 = _Eq41
|
|
57
66
|
|
|
58
67
|
Mpa = p * 0.00689476 # Pressure in mPa
|
|
59
68
|
degc = (degf - 32) / 1.8 # Temperature in deg C
|
|
@@ -62,17 +71,17 @@ def brine_props(p: float, degf: float, wt: float=0, ch4_sat: float=0) -> Tuple:
|
|
|
62
71
|
1000 * (wt / 100) / (58.4428 * (1 - (wt / 100)))
|
|
63
72
|
) # Molar concentration of NaCl from wt % in gram mol/kg water
|
|
64
73
|
|
|
65
|
-
rhow_t70_arr =
|
|
66
|
-
Ewt_arr =
|
|
67
|
-
Fwt_arr =
|
|
68
|
-
Dm2t_arr =
|
|
69
|
-
Dm32t_arr =
|
|
70
|
-
Dm1t_arr =
|
|
71
|
-
Dm12t_arr =
|
|
72
|
-
Emt_arr =
|
|
73
|
-
Fm32t_arr =
|
|
74
|
-
Fm1t_arr =
|
|
75
|
-
Fm12t_arr =
|
|
74
|
+
rhow_t70_arr = _RHOW_T70_ARR
|
|
75
|
+
Ewt_arr = _EWT_ARR
|
|
76
|
+
Fwt_arr = _FWT_ARR
|
|
77
|
+
Dm2t_arr = _DM2T_ARR
|
|
78
|
+
Dm32t_arr = _DM32T_ARR
|
|
79
|
+
Dm1t_arr = _DM1T_ARR
|
|
80
|
+
Dm12t_arr = _DM12T_ARR
|
|
81
|
+
Emt_arr = _EMT_ARR
|
|
82
|
+
Fm32t_arr = _FM32T_ARR
|
|
83
|
+
Fm1t_arr = _FM1T_ARR
|
|
84
|
+
Fm12t_arr = _FM12T_ARR
|
|
76
85
|
|
|
77
86
|
rhow_t70 = Eq41(degc, rhow_t70_arr)
|
|
78
87
|
Ewt = Eq41(degc, Ewt_arr)
|
|
@@ -171,7 +180,7 @@ def brine_props(p: float, degf: float, wt: float=0, ch4_sat: float=0) -> Tuple:
|
|
|
171
180
|
|
|
172
181
|
try:
|
|
173
182
|
mch4w = np.exp(A_t * np.power(np.log(Mpa - vap_pressure), 2) + B_t * np.log(Mpa - vap_pressure) + C_t) # Eq 4.15
|
|
174
|
-
except:
|
|
183
|
+
except (ValueError, FloatingPointError):
|
|
175
184
|
mch4w = 0
|
|
176
185
|
|
|
177
186
|
u_arr = [
|
|
@@ -352,9 +361,9 @@ BBL2CUFT = 5.614583333 # cuft in a bbl
|
|
|
352
361
|
|
|
353
362
|
#============================================================================
|
|
354
363
|
# *** Mutual solubilities between CO2 and Brine - Calculated with ***
|
|
355
|
-
# A Phase-Partitioning Model for CO2�Brine Mixtures at Elevated Temperatures
|
|
364
|
+
# A Phase-Partitioning Model for CO2�Brine Mixtures at Elevated Temperatures
|
|
356
365
|
# and Pressures: Application to CO2-Enhanced Geothermal Systems
|
|
357
|
-
# Nicolas Spycher & Karsten Pruess, Transp Porous Med (2010) 82:173�196
|
|
366
|
+
# Nicolas Spycher & Karsten Pruess, Transp Porous Med (2010) 82:173�196
|
|
358
367
|
# DOI 10.1007/s11242-009-9425-y
|
|
359
368
|
#============================================================================
|
|
360
369
|
|
|
@@ -712,31 +721,40 @@ class CO2_Brine_Mixture():
|
|
|
712
721
|
# Cubic Polynomial Solver: f(Z) = Z**3 + E2*Z**2 + E1*Z + E1 = 0
|
|
713
722
|
#=======================================================================
|
|
714
723
|
self.repeat = False
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
724
|
+
|
|
725
|
+
# Try Halley for all roots
|
|
726
|
+
roots = halley_solve_cubic(e2, e1, e0, flag=0)
|
|
727
|
+
|
|
728
|
+
# Fallback to np.roots if Halley returned None
|
|
729
|
+
if roots is None:
|
|
730
|
+
Z = np.roots(np.array([1.0, e2, e1, e0]))
|
|
731
|
+
Z = np.array([x for x in Z if np.isreal(x)]) # Keep only real results
|
|
732
|
+
roots = np.real(Z)
|
|
733
|
+
|
|
734
|
+
if len(roots) > 1: # Evaluate which root to use per Eqs 25 and 26 in Spycher & Pruess (2003)
|
|
735
|
+
vgas, vliq = max(roots), min(roots)
|
|
736
|
+
|
|
720
737
|
w1 = self.pBar*(vgas - vliq)
|
|
721
738
|
w2 = RGASCON * self.tKel * np.log((vgas - self.bMix)/(vliq - self.bMix)) + self.aMix/(self.tKel**0.5 * self.bMix) * np.log((vgas + self.bMix) * vliq / ((vliq + self.bMix) * vgas))
|
|
722
|
-
|
|
739
|
+
|
|
723
740
|
if w2 - w1 > 0:
|
|
724
|
-
|
|
741
|
+
result = max(roots)
|
|
725
742
|
if self.CO2_sat: # CO2 was saturated in previous iteration, but now its not
|
|
726
743
|
self.CO2_sat = False
|
|
727
744
|
self.repeat = True
|
|
728
745
|
else:
|
|
729
|
-
|
|
746
|
+
result = min(roots)
|
|
730
747
|
if not self.CO2_sat:
|
|
731
748
|
self.CO2_sat = True
|
|
732
749
|
self.repeat = True
|
|
733
750
|
else:
|
|
751
|
+
result = roots[0]
|
|
734
752
|
if self.CO2_sat: # CO2 was saturated in previous iteration, but now its not
|
|
735
753
|
self.CO2_sat = False
|
|
736
754
|
self.repeat = True
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
return np.real(
|
|
755
|
+
|
|
756
|
+
|
|
757
|
+
return np.real(result)
|
|
740
758
|
|
|
741
759
|
|
|
742
760
|
def MolarVolume(self):
|
|
@@ -852,9 +870,9 @@ class CO2_Brine_Mixture():
|
|
|
852
870
|
self.Bprime = B
|
|
853
871
|
|
|
854
872
|
#============================================================================
|
|
855
|
-
# A Phase-Partitioning Model for CO2�Brine Mixtures at Elevated Temperatures
|
|
873
|
+
# A Phase-Partitioning Model for CO2�Brine Mixtures at Elevated Temperatures
|
|
856
874
|
# and Pressures: Application to CO2-Enhanced Geothermal Systems
|
|
857
|
-
# Nicolas Spycher & Karsten Pruess, Transp Porous Med (2010) 82:173�196
|
|
875
|
+
# Nicolas Spycher & Karsten Pruess, Transp Porous Med (2010) 82:173�196
|
|
858
876
|
# DOI 10.1007/s11242-009-9425-y
|
|
859
877
|
#============================================================================
|
|
860
878
|
|
|
@@ -1069,26 +1087,18 @@ class CO2_Brine_Mixture():
|
|
|
1069
1087
|
Mpa = pBar * 0.1 # Pressure in mPa
|
|
1070
1088
|
tKel = degc + CEL2KEL # Temperature in deg K
|
|
1071
1089
|
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
Dm1t_arr = [0, 0.0021466, 0.012427, 0.042648, -0.081009, 0.525417]
|
|
1085
|
-
Dm12t_arr = [0, 0.0002356, -0.0003636, -0.0002278, 0, 0]
|
|
1086
|
-
|
|
1087
|
-
# Table 4-8 Coefficients
|
|
1088
|
-
Emt_arr = [0, 0, 0, 0.1249, 0, 0]
|
|
1089
|
-
Fm32t_arr = [0, -0.617, -0.747, -0.4339, 0, 10.26]
|
|
1090
|
-
Fm1t_arr = [0, 0, 9.917, 5.1128, 0, 3.892]
|
|
1091
|
-
Fm12t_arr = [0, 0.0365, -0.0369, 0, 0, 0]
|
|
1090
|
+
Eq41 = _Eq41
|
|
1091
|
+
rhow_t70_arr = _RHOW_T70_ARR
|
|
1092
|
+
Ewt_arr = _EWT_ARR
|
|
1093
|
+
Fwt_arr = _FWT_ARR
|
|
1094
|
+
Dm2t_arr = _DM2T_ARR
|
|
1095
|
+
Dm32t_arr = _DM32T_ARR
|
|
1096
|
+
Dm1t_arr = _DM1T_ARR
|
|
1097
|
+
Dm12t_arr = _DM12T_ARR
|
|
1098
|
+
Emt_arr = _EMT_ARR
|
|
1099
|
+
Fm32t_arr = _FM32T_ARR
|
|
1100
|
+
Fm1t_arr = _FM1T_ARR
|
|
1101
|
+
Fm12t_arr = _FM12T_ARR
|
|
1092
1102
|
|
|
1093
1103
|
# Table 4-14 Mao-Duan Coefficients
|
|
1094
1104
|
d = [0, 2885310, -11072.577, -9.0834095, 0.030925651, -0.0000274071, -1928385.1, 5621.6046, 13.82725, -0.047609523, 0.000035545041]
|
|
@@ -1115,7 +1125,7 @@ class CO2_Brine_Mixture():
|
|
|
1115
1125
|
|
|
1116
1126
|
# -- CO2-Free Brine Density (gm/cm3)
|
|
1117
1127
|
def brine_denw(Mpa):
|
|
1118
|
-
# cw(T, p), in MPa�1, of pure water at temperature T and pressure p,
|
|
1128
|
+
# cw(T, p), in MPa�1, of pure water at temperature T and pressure p,
|
|
1119
1129
|
cwtp = (1 / 70) * (1 / (Ewt * (Mpa / 70) + Fwt)) # Eq 4.2
|
|
1120
1130
|
|
|
1121
1131
|
#Density of pure water at temperature T and pressure p.
|
|
@@ -1168,7 +1178,7 @@ class CO2_Brine_Mixture():
|
|
|
1168
1178
|
return (1.0 + mRat * xRat) / (vPhi * xRat / MwB + 1.0 / rhoBRnoCO2) # --Equation 18 of Garcia paper
|
|
1169
1179
|
|
|
1170
1180
|
# Correct CO2 free brine viscosity for dissolved CO2
|
|
1171
|
-
# Using approach from "Viscosity Models and Effects of Dissolved CO2", Akand W. Islam and Eric S. Carlson (Jul 2012), Energy Fuels 2012, 26, 8, 5330�5336, https://doi.org/10.1021/ef3006228
|
|
1181
|
+
# Using approach from "Viscosity Models and Effects of Dissolved CO2", Akand W. Islam and Eric S. Carlson (Jul 2012), Energy Fuels 2012, 26, 8, 5330�5336, https://doi.org/10.1021/ef3006228
|
|
1172
1182
|
def co2_vis_brine(cP_brine, xCO2):
|
|
1173
1183
|
# Uses CO2 free brine viscosity (cP) and mole fraction CO2 in brine (xCO2), and returns cP
|
|
1174
1184
|
return cP_brine * (1 + 4.65 * xCO2**1.0134)
|
|
@@ -1237,4 +1247,116 @@ class CO2_Brine_Mixture():
|
|
|
1237
1247
|
# Undersaturated compressibility = 1/V dV/dP
|
|
1238
1248
|
c_usat = 1 - sg_CO2_Brine / sg_CO2_Brine_ # 1/Bar
|
|
1239
1249
|
|
|
1240
|
-
return ([sg_CO2_Brine, sg_brine, rhowtp], [cP_CO2_brine, cP_brine, cP_freshwater], viscosblty, [bw, brine_res_vol, bw_freshwater], rs, c_usat)
|
|
1250
|
+
return ([sg_CO2_Brine, sg_brine, rhowtp], [cP_CO2_brine, cP_brine, cP_freshwater], viscosblty, [bw, brine_res_vol, bw_freshwater], rs, c_usat)
|
|
1251
|
+
|
|
1252
|
+
|
|
1253
|
+
def make_pvtw_table(
|
|
1254
|
+
pi: float,
|
|
1255
|
+
degf: float,
|
|
1256
|
+
wt: float = 0,
|
|
1257
|
+
ch4_sat: float = 0,
|
|
1258
|
+
pmin: float = 500,
|
|
1259
|
+
pmax: float = 10000,
|
|
1260
|
+
nrows: int = 20,
|
|
1261
|
+
export: bool = False,
|
|
1262
|
+
) -> dict:
|
|
1263
|
+
""" Generates a PVTW (water PVT) table over a pressure range using brine_props (Spivey correlation).
|
|
1264
|
+
Follows the pattern of make_bot_og from the oil module.
|
|
1265
|
+
|
|
1266
|
+
pi: Initial (reference) pressure (psia)
|
|
1267
|
+
degf: Temperature (deg F)
|
|
1268
|
+
wt: Salt wt% (0-100), default 0
|
|
1269
|
+
ch4_sat: Degree of methane saturation (0 - 1), default 0
|
|
1270
|
+
pmin: Minimum pressure for table (psia), default 500
|
|
1271
|
+
pmax: Maximum pressure for table (psia), default 10000
|
|
1272
|
+
nrows: Number of rows in table, default 20
|
|
1273
|
+
export: If True, writes PVTW.INC (ECLIPSE keyword) and pvtw_table.xlsx
|
|
1274
|
+
|
|
1275
|
+
Returns dict with keys:
|
|
1276
|
+
table: pandas DataFrame with columns Pressure, Bw, Density, Viscosity, Cw, Rsw
|
|
1277
|
+
pref: Reference pressure (psia)
|
|
1278
|
+
bw_ref: Bw at reference pressure (rb/stb)
|
|
1279
|
+
cw_ref: Compressibility at reference pressure (1/psi)
|
|
1280
|
+
visw_ref: Viscosity at reference pressure (cP)
|
|
1281
|
+
rsw_ref: Rsw at reference pressure (scf/stb)
|
|
1282
|
+
den_ref: Density (sg) at reference pressure
|
|
1283
|
+
"""
|
|
1284
|
+
# Build pressure grid, ensuring pi is included
|
|
1285
|
+
pressures = list(np.linspace(pmin, pmax, nrows))
|
|
1286
|
+
if pi not in pressures:
|
|
1287
|
+
pressures.append(pi)
|
|
1288
|
+
pressures = sorted(set(pressures))
|
|
1289
|
+
|
|
1290
|
+
bws, dens, visws, cws, rsws = [], [], [], [], []
|
|
1291
|
+
for p in pressures:
|
|
1292
|
+
bw, lden, visw, cw, rsw = brine_props(p=p, degf=degf, wt=wt, ch4_sat=ch4_sat)
|
|
1293
|
+
bws.append(bw)
|
|
1294
|
+
dens.append(lden)
|
|
1295
|
+
visws.append(visw)
|
|
1296
|
+
cws.append(cw)
|
|
1297
|
+
rsws.append(rsw)
|
|
1298
|
+
|
|
1299
|
+
df = pd.DataFrame()
|
|
1300
|
+
df["Pressure (psia)"] = pressures
|
|
1301
|
+
df["Bw (rb/stb)"] = bws
|
|
1302
|
+
df["Density (sg)"] = dens
|
|
1303
|
+
df["Viscosity (cP)"] = visws
|
|
1304
|
+
df["Cw (1/psi)"] = cws
|
|
1305
|
+
df["Rsw (scf/stb)"] = rsws
|
|
1306
|
+
|
|
1307
|
+
# Reference properties at pi
|
|
1308
|
+
bw_ref, den_ref, visw_ref, cw_ref, rsw_ref = brine_props(
|
|
1309
|
+
p=pi, degf=degf, wt=wt, ch4_sat=ch4_sat
|
|
1310
|
+
)
|
|
1311
|
+
|
|
1312
|
+
if export:
|
|
1313
|
+
# Write ECLIPSE PVTW keyword
|
|
1314
|
+
# PVTW format: Pref Bw Cw Visw Viscosibility
|
|
1315
|
+
# Viscosibility set to 0 (constant viscosity assumption)
|
|
1316
|
+
pvtw_line = f" {pi:.1f} {bw_ref:.6f} {cw_ref:.6e} {visw_ref:.4f} 0.0"
|
|
1317
|
+
fileout = f"-- Generated by pyResToolbox make_pvtw_table\n"
|
|
1318
|
+
fileout += f"-- Temperature: {degf:.1f} deg F, Salt: {wt:.1f} wt%, CH4 sat: {ch4_sat:.2f}\n"
|
|
1319
|
+
fileout += f"PVTW\n{pvtw_line} /\n"
|
|
1320
|
+
with open("PVTW.INC", "w") as f:
|
|
1321
|
+
f.write(fileout)
|
|
1322
|
+
|
|
1323
|
+
# Write full table to Excel
|
|
1324
|
+
df.to_excel("pvtw_table.xlsx", index=False)
|
|
1325
|
+
|
|
1326
|
+
return {
|
|
1327
|
+
"table": df,
|
|
1328
|
+
"pref": pi,
|
|
1329
|
+
"bw_ref": bw_ref,
|
|
1330
|
+
"cw_ref": cw_ref,
|
|
1331
|
+
"visw_ref": visw_ref,
|
|
1332
|
+
"rsw_ref": rsw_ref,
|
|
1333
|
+
"den_ref": den_ref,
|
|
1334
|
+
}
|
|
1335
|
+
|
|
1336
|
+
|
|
1337
|
+
class SoreideWhitson:
|
|
1338
|
+
""" Soreide-Whitson (1992) model for gas solubility in water/brine.
|
|
1339
|
+
|
|
1340
|
+
Planned support for multicomponent gas mixtures containing:
|
|
1341
|
+
C1, C2, C3, nC4, CO2, H2S, N2, H2
|
|
1342
|
+
|
|
1343
|
+
Will calculate:
|
|
1344
|
+
- Mole fraction of dissolved gas components in aqueous phase
|
|
1345
|
+
- Mole fraction of vaporised water in gas phase
|
|
1346
|
+
- Water content of gas (stb/mmscf)
|
|
1347
|
+
- Gas solubility in water (scf/stb)
|
|
1348
|
+
|
|
1349
|
+
Supports fresh and saline water (NaCl equivalent).
|
|
1350
|
+
|
|
1351
|
+
Reference:
|
|
1352
|
+
Soreide, I. and Whitson, C.H., "Peng-Robinson Predictions for Hydrocarbons,
|
|
1353
|
+
CO2, N2, and H2S with Pure Water and NaCl Brine", Fluid Phase Equilibria,
|
|
1354
|
+
77, 217-240, 1992.
|
|
1355
|
+
"""
|
|
1356
|
+
|
|
1357
|
+
def __init__(self, **kwargs):
|
|
1358
|
+
raise NotImplementedError(
|
|
1359
|
+
"SoreideWhitson model is not yet implemented. "
|
|
1360
|
+
"Planned support includes multicomponent gas (C1, C2, C3, nC4, CO2, H2S, N2, H2) "
|
|
1361
|
+
"solubility in fresh/saline water using the Soreide-Whitson (1992) PR-EOS approach."
|
|
1362
|
+
)
|
|
@@ -28,11 +28,13 @@ class z_method(Enum): # Gas Z-Factor calculation model
|
|
|
28
28
|
HY = 1
|
|
29
29
|
WYW = 2
|
|
30
30
|
BUR = 3
|
|
31
|
+
BNS = 3
|
|
31
32
|
|
|
32
33
|
class c_method(Enum): # Gas critical properties calculation method
|
|
33
34
|
PMC = 0
|
|
34
35
|
SUT = 1
|
|
35
36
|
BUR = 2
|
|
37
|
+
BNS = 3
|
|
36
38
|
|
|
37
39
|
class pb_method(Enum): # Bubble point calculation method
|
|
38
40
|
STAN = 0
|
|
@@ -161,5 +161,106 @@ Usage example for 175 Bara x 85 degC and 0% NaCl brine:
|
|
|
161
161
|
|
|
162
162
|
>>> mix = brine.CO2_Brine_Mixture(pres = 175, temp = 85)
|
|
163
163
|
>>> mix.Rs # Returns sm3 dissolved CO2 / sm3 Brine
|
|
164
|
-
24.742923469934272
|
|
164
|
+
24.742923469934272
|
|
165
|
+
|
|
166
|
+
pyrestoolbox.brine.make_pvtw_table
|
|
167
|
+
======================
|
|
168
|
+
|
|
169
|
+
.. code-block:: python
|
|
170
|
+
|
|
171
|
+
make_pvtw_table(pi, degf, wt=0, ch4_sat=0, pmin=500, pmax=10000, nrows=20, export=False) -> dict
|
|
172
|
+
|
|
173
|
+
Generates a PVTW (water PVT) table over a pressure range using the Spivey correlation (brine_props).
|
|
174
|
+
Optionally exports ECLIPSE PVTW keyword file and Excel spreadsheet.
|
|
175
|
+
|
|
176
|
+
.. list-table:: Inputs
|
|
177
|
+
:widths: 10 15 40
|
|
178
|
+
:header-rows: 1
|
|
179
|
+
|
|
180
|
+
* - Parameter
|
|
181
|
+
- Type
|
|
182
|
+
- Description
|
|
183
|
+
* - pi
|
|
184
|
+
- float
|
|
185
|
+
- Initial (reference) pressure (psia)
|
|
186
|
+
* - degf
|
|
187
|
+
- float
|
|
188
|
+
- Temperature (deg F)
|
|
189
|
+
* - wt
|
|
190
|
+
- float
|
|
191
|
+
- Salt weight% in the brine (0 - 100). Default 0
|
|
192
|
+
* - ch4_sat
|
|
193
|
+
- float
|
|
194
|
+
- Degree of methane saturation (0 - 1). Default 0
|
|
195
|
+
* - pmin
|
|
196
|
+
- float
|
|
197
|
+
- Minimum table pressure (psia). Default 500
|
|
198
|
+
* - pmax
|
|
199
|
+
- float
|
|
200
|
+
- Maximum table pressure (psia). Default 10000
|
|
201
|
+
* - nrows
|
|
202
|
+
- int
|
|
203
|
+
- Number of table rows. Default 20
|
|
204
|
+
* - export
|
|
205
|
+
- bool
|
|
206
|
+
- If True, writes PVTW.INC and pvtw_table.xlsx. Default False
|
|
207
|
+
|
|
208
|
+
.. list-table:: Return dict keys
|
|
209
|
+
:widths: 10 15 40
|
|
210
|
+
:header-rows: 1
|
|
211
|
+
|
|
212
|
+
* - Key
|
|
213
|
+
- Type
|
|
214
|
+
- Description
|
|
215
|
+
* - table
|
|
216
|
+
- DataFrame
|
|
217
|
+
- Pressure, Bw, Density, Viscosity, Cw, Rsw
|
|
218
|
+
* - pref
|
|
219
|
+
- float
|
|
220
|
+
- Reference pressure (psia)
|
|
221
|
+
* - bw_ref
|
|
222
|
+
- float
|
|
223
|
+
- Bw at reference pressure (rb/stb)
|
|
224
|
+
* - cw_ref
|
|
225
|
+
- float
|
|
226
|
+
- Compressibility at reference pressure (1/psi)
|
|
227
|
+
* - visw_ref
|
|
228
|
+
- float
|
|
229
|
+
- Viscosity at reference pressure (cP)
|
|
230
|
+
* - rsw_ref
|
|
231
|
+
- float
|
|
232
|
+
- Rsw at reference pressure (scf/stb)
|
|
233
|
+
* - den_ref
|
|
234
|
+
- float
|
|
235
|
+
- Density (sg) at reference pressure
|
|
236
|
+
|
|
237
|
+
Examples:
|
|
238
|
+
|
|
239
|
+
.. code-block:: python
|
|
240
|
+
|
|
241
|
+
>>> from pyrestoolbox import brine
|
|
242
|
+
>>> result = brine.make_pvtw_table(pi=3000, degf=200, wt=0, ch4_sat=0)
|
|
243
|
+
>>> print(result['bw_ref'])
|
|
244
|
+
>>> print(result['table'].head())
|
|
245
|
+
|
|
246
|
+
pyrestoolbox.brine.SoreideWhitson
|
|
247
|
+
======================
|
|
248
|
+
|
|
249
|
+
.. code-block:: python
|
|
250
|
+
|
|
251
|
+
SoreideWhitson(**kwargs) -> raises NotImplementedError
|
|
252
|
+
|
|
253
|
+
Placeholder for the Soreide-Whitson (1992) PR-EOS model for gas solubility in water/brine.
|
|
254
|
+
|
|
255
|
+
Planned support includes multicomponent gas mixtures (C1, C2, C3, nC4, CO2, H2S, N2, H2)
|
|
256
|
+
solubility in fresh and saline water.
|
|
257
|
+
|
|
258
|
+
Planned return values:
|
|
259
|
+
- Mole fraction of dissolved gas components in aqueous phase
|
|
260
|
+
- Mole fraction of vaporised water in gas phase
|
|
261
|
+
- Water content of gas (stb/mmscf)
|
|
262
|
+
- Gas solubility in water (scf/stb)
|
|
263
|
+
|
|
264
|
+
Reference: Soreide, I. and Whitson, C.H., "Peng-Robinson Predictions for Hydrocarbons,
|
|
265
|
+
CO2, N2, and H2S with Pure Water and NaCl Brine", Fluid Phase Equilibria, 77, 217-240, 1992.
|
|
165
266
|
|