rock-physics-open 0.2.3__py3-none-any.whl → 0.3.1__py3-none-any.whl
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.
Potentially problematic release.
This version of rock-physics-open might be problematic. Click here for more details.
- rock_physics_open/equinor_utilities/gen_utilities/dict_to_float.py +6 -1
- rock_physics_open/equinor_utilities/gen_utilities/dim_check_vector.py +35 -5
- rock_physics_open/equinor_utilities/gen_utilities/filter_input.py +11 -6
- rock_physics_open/equinor_utilities/gen_utilities/filter_output.py +29 -19
- rock_physics_open/equinor_utilities/machine_learning_utilities/__init__.py +6 -5
- rock_physics_open/equinor_utilities/machine_learning_utilities/base_pressure_model.py +172 -0
- rock_physics_open/equinor_utilities/machine_learning_utilities/exponential_model.py +100 -86
- rock_physics_open/equinor_utilities/machine_learning_utilities/import_ml_models.py +7 -4
- rock_physics_open/equinor_utilities/machine_learning_utilities/polynomial_model.py +128 -0
- rock_physics_open/equinor_utilities/machine_learning_utilities/run_regression.py +6 -4
- rock_physics_open/equinor_utilities/machine_learning_utilities/sigmoidal_model.py +204 -155
- rock_physics_open/equinor_utilities/optimisation_utilities/__init__.py +19 -0
- rock_physics_open/equinor_utilities/snapshot_test_utilities/compare_snapshots.py +1 -2
- rock_physics_open/equinor_utilities/std_functions/backus_ave.py +16 -1
- rock_physics_open/equinor_utilities/std_functions/dvorkin_nur.py +10 -2
- rock_physics_open/equinor_utilities/std_functions/gassmann.py +32 -7
- rock_physics_open/equinor_utilities/std_functions/hashin_shtrikman.py +36 -7
- rock_physics_open/equinor_utilities/std_functions/hertz_mindlin.py +9 -1
- rock_physics_open/equinor_utilities/std_functions/moduli_velocity.py +22 -6
- rock_physics_open/equinor_utilities/std_functions/reflection_eq.py +28 -6
- rock_physics_open/equinor_utilities/std_functions/rho.py +12 -2
- rock_physics_open/equinor_utilities/std_functions/voigt_reuss_hill.py +25 -4
- rock_physics_open/equinor_utilities/std_functions/walton.py +8 -1
- rock_physics_open/equinor_utilities/std_functions/wood_brie.py +20 -3
- rock_physics_open/equinor_utilities/various_utilities/display_result_statistics.py +16 -9
- rock_physics_open/equinor_utilities/various_utilities/gassmann_dry_mod.py +21 -2
- rock_physics_open/equinor_utilities/various_utilities/gassmann_mod.py +21 -2
- rock_physics_open/equinor_utilities/various_utilities/gassmann_sub_mod.py +23 -12
- rock_physics_open/equinor_utilities/various_utilities/hs_average.py +20 -1
- rock_physics_open/equinor_utilities/various_utilities/pressure.py +9 -1
- rock_physics_open/equinor_utilities/various_utilities/reflectivity.py +26 -10
- rock_physics_open/equinor_utilities/various_utilities/timeshift.py +15 -2
- rock_physics_open/equinor_utilities/various_utilities/vp_vs_rho_set_statistics.py +40 -24
- rock_physics_open/equinor_utilities/various_utilities/vrh_3_min.py +24 -2
- rock_physics_open/fluid_models/brine_model/brine_properties.py +70 -35
- rock_physics_open/fluid_models/gas_model/gas_properties.py +79 -37
- rock_physics_open/fluid_models/oil_model/dead_oil_density.py +21 -16
- rock_physics_open/fluid_models/oil_model/dead_oil_velocity.py +9 -7
- rock_physics_open/fluid_models/oil_model/live_oil_density.py +16 -13
- rock_physics_open/fluid_models/oil_model/live_oil_velocity.py +3 -3
- rock_physics_open/fluid_models/oil_model/oil_properties.py +59 -29
- rock_physics_open/sandstone_models/__init__.py +2 -0
- rock_physics_open/sandstone_models/constant_cement_optimisation.py +4 -1
- rock_physics_open/sandstone_models/friable_models.py +6 -7
- rock_physics_open/sandstone_models/friable_optimisation.py +4 -1
- rock_physics_open/sandstone_models/patchy_cement_model.py +103 -5
- rock_physics_open/sandstone_models/patchy_cement_optimisation.py +4 -1
- rock_physics_open/t_matrix_models/__init__.py +0 -10
- rock_physics_open/t_matrix_models/carbonate_pressure_substitution.py +1 -1
- rock_physics_open/t_matrix_models/curvefit_t_matrix_exp.py +1 -2
- rock_physics_open/t_matrix_models/t_matrix_opt_fluid_sub_exp.py +3 -3
- rock_physics_open/t_matrix_models/t_matrix_opt_fluid_sub_petec.py +5 -1
- rock_physics_open/t_matrix_models/t_matrix_opt_forward_model_exp.py +5 -1
- rock_physics_open/t_matrix_models/t_matrix_opt_forward_model_min.py +4 -1
- rock_physics_open/t_matrix_models/t_matrix_parameter_optimisation_exp.py +5 -1
- rock_physics_open/t_matrix_models/t_matrix_parameter_optimisation_min.py +4 -1
- rock_physics_open/ternary_plots/ternary_plot_utilities.py +3 -3
- rock_physics_open/version.py +2 -2
- {rock_physics_open-0.2.3.dist-info → rock_physics_open-0.3.1.dist-info}/METADATA +4 -8
- {rock_physics_open-0.2.3.dist-info → rock_physics_open-0.3.1.dist-info}/RECORD +64 -61
- /rock_physics_open/{t_matrix_models → equinor_utilities/optimisation_utilities}/opt_subst_utilities.py +0 -0
- {rock_physics_open-0.2.3.dist-info → rock_physics_open-0.3.1.dist-info}/WHEEL +0 -0
- {rock_physics_open-0.2.3.dist-info → rock_physics_open-0.3.1.dist-info}/licenses/LICENSE +0 -0
- {rock_physics_open-0.2.3.dist-info → rock_physics_open-0.3.1.dist-info}/top_level.txt +0 -0
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
import warnings
|
|
2
|
+
from typing import cast
|
|
2
3
|
|
|
3
4
|
import numpy as np
|
|
5
|
+
import numpy.typing as npt
|
|
4
6
|
|
|
5
7
|
from rock_physics_open.equinor_utilities.gen_utilities import dim_check_vector
|
|
6
8
|
|
|
7
9
|
|
|
8
|
-
def gassmann(
|
|
10
|
+
def gassmann(
|
|
11
|
+
k_dry: npt.NDArray[np.float64],
|
|
12
|
+
por: npt.NDArray[np.float64],
|
|
13
|
+
k_fl: npt.NDArray[np.float64],
|
|
14
|
+
k_min: npt.NDArray[np.float64],
|
|
15
|
+
) -> npt.NDArray[np.float64]:
|
|
9
16
|
"""
|
|
10
17
|
Fluid substitution according to the Gassmann equation.
|
|
11
18
|
|
|
@@ -25,7 +32,10 @@ def gassmann(k_dry, por, k_fl, k_min):
|
|
|
25
32
|
np.ndarray
|
|
26
33
|
k_sat: bulk modulus for saturated rock [Pa]
|
|
27
34
|
"""
|
|
28
|
-
k_dry, por, k_fl, k_min =
|
|
35
|
+
k_dry, por, k_fl, k_min = cast(
|
|
36
|
+
list[npt.NDArray[np.float64]],
|
|
37
|
+
dim_check_vector((k_dry, por, k_fl, k_min)),
|
|
38
|
+
)
|
|
29
39
|
|
|
30
40
|
idx = np.logical_or(k_dry == k_min, por == 0)
|
|
31
41
|
k_sat = np.ones(k_dry.shape) * np.nan
|
|
@@ -42,7 +52,13 @@ def gassmann(k_dry, por, k_fl, k_min):
|
|
|
42
52
|
return k_sat
|
|
43
53
|
|
|
44
54
|
|
|
45
|
-
def gassmann2(
|
|
55
|
+
def gassmann2(
|
|
56
|
+
k_sat_1: npt.NDArray[np.float64],
|
|
57
|
+
k_fl_1: npt.NDArray[np.float64],
|
|
58
|
+
k_fl_2: npt.NDArray[np.float64],
|
|
59
|
+
por: npt.NDArray[np.float64],
|
|
60
|
+
k_min: npt.NDArray[np.float64],
|
|
61
|
+
) -> npt.NDArray[np.float64]:
|
|
46
62
|
"""
|
|
47
63
|
Fluid substitution by Gassmann method with substitution of one fluid to another
|
|
48
64
|
|
|
@@ -64,8 +80,9 @@ def gassmann2(k_sat_1, k_fl_1, k_fl_2, por, k_min):
|
|
|
64
80
|
np.ndarray
|
|
65
81
|
k_sat_2: bulk modulus of rock saturated with replaced fluid [Pa]
|
|
66
82
|
"""
|
|
67
|
-
k_sat_1, k_fl_1, k_fl_2, por, k_min =
|
|
68
|
-
|
|
83
|
+
k_sat_1, k_fl_1, k_fl_2, por, k_min = cast(
|
|
84
|
+
list[npt.NDArray[np.float64]],
|
|
85
|
+
dim_check_vector((k_sat_1, k_fl_1, k_fl_2, por, k_min)),
|
|
69
86
|
)
|
|
70
87
|
|
|
71
88
|
idx = np.any(
|
|
@@ -96,7 +113,12 @@ def gassmann2(k_sat_1, k_fl_1, k_fl_2, por, k_min):
|
|
|
96
113
|
return k_sat_2
|
|
97
114
|
|
|
98
115
|
|
|
99
|
-
def gassmann_dry(
|
|
116
|
+
def gassmann_dry(
|
|
117
|
+
k_sat: npt.NDArray[np.float64],
|
|
118
|
+
por: npt.NDArray[np.float64],
|
|
119
|
+
k_fl: npt.NDArray[np.float64],
|
|
120
|
+
k_min: npt.NDArray[np.float64],
|
|
121
|
+
) -> npt.NDArray[np.float64]:
|
|
100
122
|
"""
|
|
101
123
|
Dry rock properties of saturated rock by Gassmann equation
|
|
102
124
|
|
|
@@ -116,7 +138,10 @@ def gassmann_dry(k_sat, por, k_fl, k_min):
|
|
|
116
138
|
np.ndarray
|
|
117
139
|
k_dry: dry rock bulk modulus [Pa]
|
|
118
140
|
"""
|
|
119
|
-
k_sat, por, k_fl, k_min =
|
|
141
|
+
k_sat, por, k_fl, k_min = cast(
|
|
142
|
+
list[npt.NDArray[np.float64]],
|
|
143
|
+
dim_check_vector((k_sat, por, k_fl, k_min)),
|
|
144
|
+
)
|
|
120
145
|
|
|
121
146
|
idx = np.any(np.array([k_sat == k_min, por == 0, k_fl == k_min]), axis=0)
|
|
122
147
|
k_dry = np.ones(k_sat.shape)
|
|
@@ -1,9 +1,18 @@
|
|
|
1
|
+
from typing import Literal, cast
|
|
2
|
+
|
|
1
3
|
import numpy as np
|
|
4
|
+
import numpy.typing as npt
|
|
2
5
|
|
|
3
6
|
from rock_physics_open.equinor_utilities.gen_utilities import dim_check_vector
|
|
4
7
|
|
|
5
8
|
|
|
6
|
-
def hashin_shtrikman(
|
|
9
|
+
def hashin_shtrikman(
|
|
10
|
+
k1: npt.NDArray[np.float64],
|
|
11
|
+
mu1: npt.NDArray[np.float64],
|
|
12
|
+
k2: npt.NDArray[np.float64],
|
|
13
|
+
mu2: npt.NDArray[np.float64],
|
|
14
|
+
f: npt.NDArray[np.float64],
|
|
15
|
+
) -> tuple[npt.NDArray[np.float64], npt.NDArray[np.float64]]:
|
|
7
16
|
"""
|
|
8
17
|
Hashin-Sktrikman upper or lower according to ordering of phases.
|
|
9
18
|
|
|
@@ -34,7 +43,13 @@ def hashin_shtrikman(k1, mu1, k2, mu2, f):
|
|
|
34
43
|
return k, mu
|
|
35
44
|
|
|
36
45
|
|
|
37
|
-
def hashin_shtrikman_average(
|
|
46
|
+
def hashin_shtrikman_average(
|
|
47
|
+
k1: npt.NDArray[np.float64],
|
|
48
|
+
mu1: npt.NDArray[np.float64],
|
|
49
|
+
k2: npt.NDArray[np.float64],
|
|
50
|
+
mu2: npt.NDArray[np.float64],
|
|
51
|
+
f: npt.NDArray[np.float64],
|
|
52
|
+
) -> tuple[npt.NDArray[np.float64], npt.NDArray[np.float64]]:
|
|
38
53
|
"""
|
|
39
54
|
Average of Hashin-Shtrikman upper and lower bound.
|
|
40
55
|
|
|
@@ -66,7 +81,14 @@ def hashin_shtrikman_average(k1, mu1, k2, mu2, f):
|
|
|
66
81
|
return k_av, mu_av
|
|
67
82
|
|
|
68
83
|
|
|
69
|
-
def hashin_shtrikman_walpole(
|
|
84
|
+
def hashin_shtrikman_walpole(
|
|
85
|
+
k1: npt.NDArray[np.float64],
|
|
86
|
+
mu1: npt.NDArray[np.float64],
|
|
87
|
+
k2: npt.NDArray[np.float64],
|
|
88
|
+
mu2: npt.NDArray[np.float64],
|
|
89
|
+
f1: npt.NDArray[np.float64],
|
|
90
|
+
bound: Literal["upper", "lower"] = "lower",
|
|
91
|
+
) -> tuple[npt.NDArray[np.float64], npt.NDArray[np.float64]]:
|
|
70
92
|
"""
|
|
71
93
|
Hashin-Shtrikman upper bound is obtained when the stiffest material is
|
|
72
94
|
termed 1 and vice versa for lower bound. Tricky in cases like Quartz -
|
|
@@ -94,7 +116,10 @@ def hashin_shtrikman_walpole(k1, mu1, k2, mu2, f1, bound="lower"):
|
|
|
94
116
|
k, mu : np.ndarray.
|
|
95
117
|
k: effective bulk modulus [Pa], mu: effective shear modulus [Pa].
|
|
96
118
|
"""
|
|
97
|
-
k1, mu1, k2, mu2, f1 =
|
|
119
|
+
k1, mu1, k2, mu2, f1 = cast(
|
|
120
|
+
list[npt.NDArray[np.float64]],
|
|
121
|
+
dim_check_vector((k1, mu1, k2, mu2, f1)),
|
|
122
|
+
)
|
|
98
123
|
if bound.lower() not in ["lower", "upper"]:
|
|
99
124
|
raise ValueError(f'{__file__}: bound must be one of "lower" or "upper"')
|
|
100
125
|
|
|
@@ -138,7 +163,10 @@ def hashin_shtrikman_walpole(k1, mu1, k2, mu2, f1, bound="lower"):
|
|
|
138
163
|
return k, mu
|
|
139
164
|
|
|
140
165
|
|
|
141
|
-
def multi_hashin_shtrikman(
|
|
166
|
+
def multi_hashin_shtrikman(
|
|
167
|
+
*coeffs: npt.NDArray[np.float64],
|
|
168
|
+
mode: Literal["average", "upper", "lower"] = "average",
|
|
169
|
+
) -> tuple[npt.NDArray[np.float64], npt.NDArray[np.float64]]:
|
|
142
170
|
"""
|
|
143
171
|
Hashin-Shtrikman effective medium calculation for multi-mineral case.
|
|
144
172
|
|
|
@@ -163,8 +191,9 @@ def multi_hashin_shtrikman(*coeffs, mode="average"):
|
|
|
163
191
|
k_arr = np.array(coeffs[::3])
|
|
164
192
|
mu_arr = np.array(coeffs[1::3])
|
|
165
193
|
f = np.array(coeffs[2::3])
|
|
166
|
-
|
|
167
|
-
|
|
194
|
+
if not np.all(
|
|
195
|
+
cast(npt.NDArray[np.float64], np.around(np.sum(f, axis=0), decimals=6)) == 1.0
|
|
196
|
+
):
|
|
168
197
|
raise ValueError("multi_hashin_shtrikman: all fractions do not add up to 1.0")
|
|
169
198
|
|
|
170
199
|
if mode.lower() not in ["average", "upper", "lower"]:
|
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
import numpy as np
|
|
2
|
+
import numpy.typing as npt
|
|
2
3
|
|
|
3
4
|
|
|
4
|
-
def hertz_mindlin(
|
|
5
|
+
def hertz_mindlin(
|
|
6
|
+
k: npt.NDArray[np.float64],
|
|
7
|
+
mu: npt.NDArray[np.float64],
|
|
8
|
+
phi_c: npt.NDArray[np.float64],
|
|
9
|
+
p: npt.NDArray[np.float64],
|
|
10
|
+
shear_red: npt.NDArray[np.float64] | float,
|
|
11
|
+
coord: float | None = None,
|
|
12
|
+
) -> tuple[npt.NDArray[np.float64], npt.NDArray[np.float64]]:
|
|
5
13
|
"""
|
|
6
14
|
Hertz-Mindlin Pressure-induced moduli increase at critical porosity.
|
|
7
15
|
|
|
@@ -1,4 +1,16 @@
|
|
|
1
|
-
|
|
1
|
+
from typing import TypeVar, cast
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
import numpy.typing as npt
|
|
5
|
+
|
|
6
|
+
_T = TypeVar("_T", npt.NDArray[np.float64], float)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def moduli(
|
|
10
|
+
vp: _T,
|
|
11
|
+
vs: _T,
|
|
12
|
+
rhob: _T,
|
|
13
|
+
) -> tuple[_T, _T]:
|
|
2
14
|
"""
|
|
3
15
|
Calculate isotropic moduli from velocity and density.
|
|
4
16
|
|
|
@@ -23,7 +35,11 @@ def moduli(vp, vs, rhob):
|
|
|
23
35
|
return k, mu
|
|
24
36
|
|
|
25
37
|
|
|
26
|
-
def velocity(
|
|
38
|
+
def velocity(
|
|
39
|
+
k: _T,
|
|
40
|
+
mu: _T,
|
|
41
|
+
rhob: _T,
|
|
42
|
+
) -> tuple[_T, _T, _T, _T]:
|
|
27
43
|
"""
|
|
28
44
|
Calculate velocity, acoustic impedance and vp/vs ratio from elastic moduli and density.
|
|
29
45
|
|
|
@@ -43,9 +59,9 @@ def velocity(k, mu, rhob):
|
|
|
43
59
|
vp: pressure wave velocity [m/s], vs: shear wave velocity [m/s], ai: acoustic impedance [m/s x kg/m^3],
|
|
44
60
|
vp_vs: velocity ratio [fraction].
|
|
45
61
|
"""
|
|
46
|
-
vs = (mu / rhob) ** 0.5
|
|
47
|
-
vp = ((k + 4 / 3 * mu) / rhob) ** 0.5
|
|
48
|
-
ai = vp * rhob
|
|
49
|
-
vp_vs = vp / vs
|
|
62
|
+
vs = cast(_T, (mu / rhob) ** 0.5)
|
|
63
|
+
vp = cast(_T, ((k + 4 / 3 * mu) / rhob) ** 0.5)
|
|
64
|
+
ai = cast(_T, vp * rhob)
|
|
65
|
+
vp_vs = cast(_T, vp / vs)
|
|
50
66
|
|
|
51
67
|
return vp, vs, ai, vp_vs
|
|
@@ -1,7 +1,17 @@
|
|
|
1
|
+
from typing import Literal
|
|
2
|
+
|
|
1
3
|
import numpy as np
|
|
4
|
+
import numpy.typing as npt
|
|
2
5
|
|
|
3
6
|
|
|
4
|
-
def _refl_models(
|
|
7
|
+
def _refl_models(
|
|
8
|
+
vp: npt.NDArray[np.float64],
|
|
9
|
+
vs: npt.NDArray[np.float64],
|
|
10
|
+
rho: npt.NDArray[np.float64],
|
|
11
|
+
theta: npt.NDArray[np.float64],
|
|
12
|
+
k: npt.NDArray[np.float64] | float = 2.0,
|
|
13
|
+
mod: Literal["aki_richards", "smith_gidlow"] = "aki_richards",
|
|
14
|
+
) -> npt.NDArray[np.float64]:
|
|
5
15
|
"""Calculate reflect coeff.
|
|
6
16
|
|
|
7
17
|
Parameters
|
|
@@ -14,7 +24,7 @@ def _refl_models(vp, vs, rho, theta, k=2.0, mod="aki_richards"):
|
|
|
14
24
|
rho array.
|
|
15
25
|
theta : float, np.ndarray
|
|
16
26
|
Theta value.
|
|
17
|
-
k : float, optional
|
|
27
|
+
k : float, np.ndarray, optional
|
|
18
28
|
By default 2.0.
|
|
19
29
|
mod : str, optional
|
|
20
30
|
By default 'aki_richards'.
|
|
@@ -47,7 +57,13 @@ def _refl_models(vp, vs, rho, theta, k=2.0, mod="aki_richards"):
|
|
|
47
57
|
return reflect_coeff
|
|
48
58
|
|
|
49
59
|
|
|
50
|
-
def aki_richards(
|
|
60
|
+
def aki_richards(
|
|
61
|
+
vp: npt.NDArray[np.float64],
|
|
62
|
+
vs: npt.NDArray[np.float64],
|
|
63
|
+
rho: npt.NDArray[np.float64],
|
|
64
|
+
theta: npt.NDArray[np.float64],
|
|
65
|
+
k: npt.NDArray[np.float64] | float = 2.0,
|
|
66
|
+
) -> npt.NDArray[np.float64]:
|
|
51
67
|
"""
|
|
52
68
|
Linearised Zoeppritz equation according to Aki and Richards.
|
|
53
69
|
|
|
@@ -61,7 +77,7 @@ def aki_richards(vp, vs, rho, theta, k=2.0):
|
|
|
61
77
|
Density [kg/m^3].
|
|
62
78
|
theta : np.ndarray
|
|
63
79
|
Angle of incident ray [radians].
|
|
64
|
-
k : float
|
|
80
|
+
k : float, np.ndarray
|
|
65
81
|
Background vp/vs [unitless].
|
|
66
82
|
|
|
67
83
|
Returns
|
|
@@ -72,7 +88,13 @@ def aki_richards(vp, vs, rho, theta, k=2.0):
|
|
|
72
88
|
return _refl_models(vp, vs, rho, theta, k, mod="aki_richards")
|
|
73
89
|
|
|
74
90
|
|
|
75
|
-
def smith_gidlow(
|
|
91
|
+
def smith_gidlow(
|
|
92
|
+
vp: npt.NDArray[np.float64],
|
|
93
|
+
vs: npt.NDArray[np.float64],
|
|
94
|
+
rho: npt.NDArray[np.float64],
|
|
95
|
+
theta: npt.NDArray[np.float64],
|
|
96
|
+
k: npt.NDArray[np.float64] | float = 2.0,
|
|
97
|
+
) -> npt.NDArray[np.float64]:
|
|
76
98
|
"""
|
|
77
99
|
Linearised Zoeppritz equation according to Smith and Gidlow.
|
|
78
100
|
|
|
@@ -86,7 +108,7 @@ def smith_gidlow(vp, vs, rho, theta, k=2.0):
|
|
|
86
108
|
Density [kg/m^3].
|
|
87
109
|
theta : np.ndarray
|
|
88
110
|
Angle of incident ray [radians].
|
|
89
|
-
k : float
|
|
111
|
+
k : float, np.ndarray
|
|
90
112
|
Background vp/vs [unitless].
|
|
91
113
|
|
|
92
114
|
Returns
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
from warnings import warn
|
|
2
2
|
|
|
3
3
|
import numpy as np
|
|
4
|
+
import numpy.typing as npt
|
|
4
5
|
|
|
5
6
|
|
|
6
|
-
def rho_b(
|
|
7
|
+
def rho_b(
|
|
8
|
+
phi: npt.NDArray[np.float64],
|
|
9
|
+
rho_f: npt.NDArray[np.float64],
|
|
10
|
+
rho_mat: npt.NDArray[np.float64],
|
|
11
|
+
) -> npt.NDArray[np.float64]:
|
|
7
12
|
"""
|
|
8
13
|
Calculate bulk density from porosity, fluid density and matrix density.
|
|
9
14
|
|
|
@@ -24,7 +29,12 @@ def rho_b(phi, rho_f, rho_mat):
|
|
|
24
29
|
return phi * rho_f + (1 - phi) * rho_mat
|
|
25
30
|
|
|
26
31
|
|
|
27
|
-
def rho_m(
|
|
32
|
+
def rho_m(
|
|
33
|
+
frac_cem: npt.NDArray[np.float64],
|
|
34
|
+
phi: npt.NDArray[np.float64],
|
|
35
|
+
rho_cem: npt.NDArray[np.float64],
|
|
36
|
+
rho_min: npt.NDArray[np.float64],
|
|
37
|
+
) -> npt.NDArray[np.float64]:
|
|
28
38
|
"""
|
|
29
39
|
Calculates matrix density as a combination of cement fraction and minerals
|
|
30
40
|
fracCem is defined as cement fraction relative to total volume.
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import numpy as np
|
|
2
|
+
import numpy.typing as npt
|
|
2
3
|
|
|
3
4
|
|
|
4
|
-
def voigt(
|
|
5
|
+
def voigt(
|
|
6
|
+
k1: npt.NDArray[np.float64],
|
|
7
|
+
mu1: npt.NDArray[np.float64],
|
|
8
|
+
k2: npt.NDArray[np.float64],
|
|
9
|
+
mu2: npt.NDArray[np.float64],
|
|
10
|
+
f1: npt.NDArray[np.float64],
|
|
11
|
+
) -> tuple[npt.NDArray[np.float64], npt.NDArray[np.float64]]:
|
|
5
12
|
"""
|
|
6
13
|
Effective media calculation of a mixture of two phases using the Voigt bound.
|
|
7
14
|
|
|
@@ -31,7 +38,13 @@ def voigt(k1, mu1, k2, mu2, f1):
|
|
|
31
38
|
return k_v, mu_v
|
|
32
39
|
|
|
33
40
|
|
|
34
|
-
def voigt_reuss_hill(
|
|
41
|
+
def voigt_reuss_hill(
|
|
42
|
+
k1: npt.NDArray[np.float64],
|
|
43
|
+
mu1: npt.NDArray[np.float64],
|
|
44
|
+
k2: npt.NDArray[np.float64],
|
|
45
|
+
mu2: npt.NDArray[np.float64],
|
|
46
|
+
f1: npt.NDArray[np.float64],
|
|
47
|
+
) -> tuple[npt.NDArray[np.float64], npt.NDArray[np.float64]]:
|
|
35
48
|
"""
|
|
36
49
|
Effective media calculation of a mixture of two phases using the Voigt-Reuss-Hill average.
|
|
37
50
|
|
|
@@ -63,7 +76,9 @@ def voigt_reuss_hill(k1, mu1, k2, mu2, f1):
|
|
|
63
76
|
return k_vrh, mu_vrh
|
|
64
77
|
|
|
65
78
|
|
|
66
|
-
def multi_voigt_reuss_hill(
|
|
79
|
+
def multi_voigt_reuss_hill(
|
|
80
|
+
*varargin: npt.NDArray[np.float64],
|
|
81
|
+
) -> tuple[npt.NDArray[np.float64], npt.NDArray[np.float64]]:
|
|
67
82
|
"""
|
|
68
83
|
Voigt-Reuss-Hill with multiple mineral input.
|
|
69
84
|
|
|
@@ -97,7 +112,13 @@ def multi_voigt_reuss_hill(*varargin):
|
|
|
97
112
|
return k, mu
|
|
98
113
|
|
|
99
114
|
|
|
100
|
-
def reuss(
|
|
115
|
+
def reuss(
|
|
116
|
+
k1: npt.NDArray[np.float64],
|
|
117
|
+
mu1: npt.NDArray[np.float64],
|
|
118
|
+
k2: npt.NDArray[np.float64],
|
|
119
|
+
mu2: npt.NDArray[np.float64],
|
|
120
|
+
f1: npt.NDArray[np.float64],
|
|
121
|
+
) -> tuple[npt.NDArray[np.float64], npt.NDArray[np.float64]]:
|
|
101
122
|
"""
|
|
102
123
|
Effective media calculation of a mixture of two phases using the Reuss bound.
|
|
103
124
|
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import numpy as np
|
|
2
|
+
import numpy.typing as npt
|
|
2
3
|
|
|
3
4
|
|
|
4
|
-
def walton_smooth(
|
|
5
|
+
def walton_smooth(
|
|
6
|
+
k: npt.NDArray[np.float64],
|
|
7
|
+
mu: npt.NDArray[np.float64],
|
|
8
|
+
phi: npt.NDArray[np.float64],
|
|
9
|
+
p_eff: npt.NDArray[np.float64],
|
|
10
|
+
coord: float | npt.NDArray[np.float64] | None = None,
|
|
11
|
+
) -> tuple[npt.NDArray[np.float64], npt.NDArray[np.float64]]:
|
|
5
12
|
"""
|
|
6
13
|
Walton Smooth Pressure-induced moduli increase at critical porosity.
|
|
7
14
|
|
|
@@ -1,7 +1,18 @@
|
|
|
1
|
+
from collections.abc import Sequence
|
|
2
|
+
|
|
1
3
|
import numpy as np
|
|
4
|
+
import numpy.typing as npt
|
|
2
5
|
|
|
3
6
|
|
|
4
|
-
def brie(
|
|
7
|
+
def brie(
|
|
8
|
+
s_gas: npt.NDArray[np.float64],
|
|
9
|
+
k_gas: npt.NDArray[np.float64],
|
|
10
|
+
s_brine: npt.NDArray[np.float64],
|
|
11
|
+
k_brine: npt.NDArray[np.float64],
|
|
12
|
+
s_oil: npt.NDArray[np.float64],
|
|
13
|
+
k_oil: npt.NDArray[np.float64],
|
|
14
|
+
e: float | npt.NDArray[np.float64],
|
|
15
|
+
) -> npt.NDArray[np.float64]:
|
|
5
16
|
"""
|
|
6
17
|
Brie function for effective bulk modulus of a mix of fluids.
|
|
7
18
|
|
|
@@ -36,7 +47,13 @@ def brie(s_gas, k_gas, s_brine, k_brine, s_oil, k_oil, e):
|
|
|
36
47
|
return (k_liquid - k_gas) * (1 - s_gas) ** e + k_gas
|
|
37
48
|
|
|
38
49
|
|
|
39
|
-
def wood(
|
|
50
|
+
def wood(
|
|
51
|
+
s1: npt.NDArray[np.float64],
|
|
52
|
+
k1: npt.NDArray[np.float64],
|
|
53
|
+
rho1: npt.NDArray[np.float64],
|
|
54
|
+
k2: npt.NDArray[np.float64],
|
|
55
|
+
rho2: npt.NDArray[np.float64],
|
|
56
|
+
) -> tuple[npt.NDArray[np.float64], npt.NDArray[np.float64]]:
|
|
40
57
|
"""
|
|
41
58
|
Wood effective fluid properties for a mix of two fluids.
|
|
42
59
|
|
|
@@ -67,7 +84,7 @@ def wood(s1, k1, rho1, k2, rho2):
|
|
|
67
84
|
return k, rho
|
|
68
85
|
|
|
69
86
|
|
|
70
|
-
def multi_wood(fractions, bulk_moduli):
|
|
87
|
+
def multi_wood(fractions: Sequence[float], bulk_moduli: Sequence[float]) -> float:
|
|
71
88
|
assert len(fractions) == len(bulk_moduli)
|
|
72
89
|
sum_fractions = sum(fractions)
|
|
73
90
|
ratio_sum = sum(
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import sys
|
|
3
|
+
from collections.abc import Sequence
|
|
4
|
+
from typing import Any, Literal, cast
|
|
3
5
|
|
|
4
6
|
import numpy as np
|
|
7
|
+
import numpy.typing as npt
|
|
5
8
|
|
|
6
9
|
|
|
7
|
-
def disp_result_stats(
|
|
10
|
+
def disp_result_stats(
|
|
11
|
+
title: str, arr: Sequence[Any], names_arr: list[str], **kwargs: Any
|
|
12
|
+
) -> None:
|
|
8
13
|
"""
|
|
9
14
|
Display results utilizing tkinter.
|
|
10
15
|
|
|
@@ -17,17 +22,19 @@ def disp_result_stats(title: str, arr: list | tuple, names_arr: list, **kwargs):
|
|
|
17
22
|
from tkinter import END, Entry, PhotoImage, Tk
|
|
18
23
|
|
|
19
24
|
class Table:
|
|
20
|
-
def __init__(
|
|
25
|
+
def __init__(
|
|
26
|
+
self, tk_root: Tk, no_rows: int, no_cols: int, info: npt.NDArray[Any]
|
|
27
|
+
):
|
|
21
28
|
# code for creating table
|
|
22
29
|
str_len = np.vectorize(len)
|
|
23
|
-
text_justify = ["center", "left"]
|
|
24
|
-
text_weight = ["bold", "normal"]
|
|
30
|
+
text_justify: list[Literal["center", "left"]] = ["center", "left"]
|
|
31
|
+
text_weight: list[str] = ["bold", "normal"]
|
|
25
32
|
for i in range(no_rows):
|
|
26
|
-
weigh = text_weight[np.sign(i)]
|
|
33
|
+
weigh = text_weight[cast(int, np.sign(i))]
|
|
27
34
|
for j in range(no_cols):
|
|
28
|
-
just = text_justify[np.sign(i)]
|
|
35
|
+
just = text_justify[cast(int, np.sign(i))]
|
|
29
36
|
max_len = np.max(str_len(info[:, j]))
|
|
30
|
-
self.e = Entry(
|
|
37
|
+
self.e: Entry = Entry(
|
|
31
38
|
tk_root,
|
|
32
39
|
width=max_len + 2,
|
|
33
40
|
fg="black",
|
|
@@ -57,7 +64,7 @@ def disp_result_stats(title: str, arr: list | tuple, names_arr: list, **kwargs):
|
|
|
57
64
|
info_array[k + 1, 4] = f"{np.sum(np.isnan(np.asarray(arr[k])))}"
|
|
58
65
|
info_array[k + 1, 5] = f"{np.sum(np.isinf(np.asarray(arr[k])))}"
|
|
59
66
|
|
|
60
|
-
Table(root, info_array.shape[0], info_array.shape[1], info_array)
|
|
67
|
+
_ = Table(root, info_array.shape[0], info_array.shape[1], info_array)
|
|
61
68
|
|
|
62
69
|
root.update_idletasks()
|
|
63
70
|
window_height = root.winfo_height()
|
|
@@ -78,6 +85,6 @@ def disp_result_stats(title: str, arr: list | tuple, names_arr: list, **kwargs):
|
|
|
78
85
|
logo = PhotoImage(
|
|
79
86
|
file=os.path.join(os.path.dirname(__file__), "Equinor_logo.gif")
|
|
80
87
|
)
|
|
81
|
-
root.
|
|
88
|
+
root.wm_iconphoto(True, logo)
|
|
82
89
|
|
|
83
90
|
root.mainloop()
|
|
@@ -1,7 +1,26 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import numpy.typing as npt
|
|
3
|
+
|
|
1
4
|
from rock_physics_open.equinor_utilities import std_functions
|
|
2
5
|
|
|
3
6
|
|
|
4
|
-
def gassmann_dry_model(
|
|
7
|
+
def gassmann_dry_model(
|
|
8
|
+
k_min: npt.NDArray[np.float64],
|
|
9
|
+
k_fl: npt.NDArray[np.float64],
|
|
10
|
+
rho_fl: npt.NDArray[np.float64],
|
|
11
|
+
k_sat: npt.NDArray[np.float64],
|
|
12
|
+
mu: npt.NDArray[np.float64],
|
|
13
|
+
rho_sat: npt.NDArray[np.float64],
|
|
14
|
+
por: npt.NDArray[np.float64],
|
|
15
|
+
) -> tuple[
|
|
16
|
+
npt.NDArray[np.float64],
|
|
17
|
+
npt.NDArray[np.float64],
|
|
18
|
+
npt.NDArray[np.float64],
|
|
19
|
+
npt.NDArray[np.float64],
|
|
20
|
+
npt.NDArray[np.float64],
|
|
21
|
+
npt.NDArray[np.float64],
|
|
22
|
+
npt.NDArray[np.float64],
|
|
23
|
+
]:
|
|
5
24
|
"""
|
|
6
25
|
Gassmann model to go from saturated rock to dry state.
|
|
7
26
|
|
|
@@ -25,7 +44,7 @@ def gassmann_dry_model(k_min, k_fl, rho_fl, k_sat, mu, rho_sat, por):
|
|
|
25
44
|
Returns
|
|
26
45
|
-------
|
|
27
46
|
tuple
|
|
28
|
-
vp_dry, vs_dry, rho_dry, ai_dry, vpvs_dry, k_dry, mu :
|
|
47
|
+
vp_dry, vs_dry, rho_dry, ai_dry, vpvs_dry, k_dry, mu : np.ndarray
|
|
29
48
|
vp_dry, vs_dry: dry velocities [m/s], rho_dry: dry density [kg/m^3], ai_dry: dry acoustic impedance
|
|
30
49
|
[kg/m^3 x m/s], vpvs_dry: dry velocity ratio [unitless], k_dry, mu: dry bulk modulus and shear modulus (the
|
|
31
50
|
latter unchanged from saturated state) [Pa].
|
|
@@ -1,7 +1,26 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import numpy.typing as npt
|
|
3
|
+
|
|
1
4
|
from rock_physics_open.equinor_utilities import std_functions
|
|
2
5
|
|
|
3
6
|
|
|
4
|
-
def gassmann_model(
|
|
7
|
+
def gassmann_model(
|
|
8
|
+
k_min: npt.NDArray[np.float64],
|
|
9
|
+
k_fl: npt.NDArray[np.float64],
|
|
10
|
+
rho_fl: npt.NDArray[np.float64],
|
|
11
|
+
k_dry: npt.NDArray[np.float64],
|
|
12
|
+
mu: npt.NDArray[np.float64],
|
|
13
|
+
rho_dry: npt.NDArray[np.float64],
|
|
14
|
+
por: npt.NDArray[np.float64],
|
|
15
|
+
) -> tuple[
|
|
16
|
+
npt.NDArray[np.float64],
|
|
17
|
+
npt.NDArray[np.float64],
|
|
18
|
+
npt.NDArray[np.float64],
|
|
19
|
+
npt.NDArray[np.float64],
|
|
20
|
+
npt.NDArray[np.float64],
|
|
21
|
+
npt.NDArray[np.float64],
|
|
22
|
+
npt.NDArray[np.float64],
|
|
23
|
+
]:
|
|
5
24
|
"""
|
|
6
25
|
Gassmann model to go from dry rock to saturated state.
|
|
7
26
|
|
|
@@ -25,7 +44,7 @@ def gassmann_model(k_min, k_fl, rho_fl, k_dry, mu, rho_dry, por):
|
|
|
25
44
|
Returns
|
|
26
45
|
-------
|
|
27
46
|
tuple
|
|
28
|
-
vp_sat, vs_sat, rho_sat, ai_sat, vpvs_sat, k_sat, mu :
|
|
47
|
+
vp_sat, vs_sat, rho_sat, ai_sat, vpvs_sat, k_sat, mu : np.ndarray
|
|
29
48
|
vp_sat, vs_sat: saturated velocities [m/s], rho_sat: saturated density [kg/m^3], ai_sat: saturated acoustic
|
|
30
49
|
impedance [kg/m^3 x m/s], vpvs_sat: saturated velocity ratio [unitless], k_sat, mu: saturated bulk modulus and
|
|
31
50
|
shear modulus (the latter unchanged from dry state) [Pa].
|
|
@@ -1,17 +1,28 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import numpy.typing as npt
|
|
3
|
+
|
|
1
4
|
from rock_physics_open.equinor_utilities import std_functions
|
|
2
5
|
|
|
3
6
|
|
|
4
7
|
def gassmann_sub_model(
|
|
5
|
-
k_min,
|
|
6
|
-
k_fl_orig,
|
|
7
|
-
rho_fl_orig,
|
|
8
|
-
k_fl_sub,
|
|
9
|
-
rho_fl_sub,
|
|
10
|
-
k_sat_orig,
|
|
11
|
-
mu,
|
|
12
|
-
rho_sat_orig,
|
|
13
|
-
por,
|
|
14
|
-
)
|
|
8
|
+
k_min: npt.NDArray[np.float64],
|
|
9
|
+
k_fl_orig: npt.NDArray[np.float64],
|
|
10
|
+
rho_fl_orig: npt.NDArray[np.float64],
|
|
11
|
+
k_fl_sub: npt.NDArray[np.float64],
|
|
12
|
+
rho_fl_sub: npt.NDArray[np.float64],
|
|
13
|
+
k_sat_orig: npt.NDArray[np.float64],
|
|
14
|
+
mu: npt.NDArray[np.float64],
|
|
15
|
+
rho_sat_orig: npt.NDArray[np.float64],
|
|
16
|
+
por: npt.NDArray[np.float64],
|
|
17
|
+
) -> tuple[
|
|
18
|
+
npt.NDArray[np.float64],
|
|
19
|
+
npt.NDArray[np.float64],
|
|
20
|
+
npt.NDArray[np.float64],
|
|
21
|
+
npt.NDArray[np.float64],
|
|
22
|
+
npt.NDArray[np.float64],
|
|
23
|
+
npt.NDArray[np.float64],
|
|
24
|
+
npt.NDArray[np.float64],
|
|
25
|
+
]:
|
|
15
26
|
"""
|
|
16
27
|
Gassmann model to go from one saturated state to another.
|
|
17
28
|
|
|
@@ -24,7 +35,7 @@ def gassmann_sub_model(
|
|
|
24
35
|
rho_fl_orig : np.ndarray
|
|
25
36
|
Original fluid density [lg/m^3].
|
|
26
37
|
k_fl_sub : np.ndarray
|
|
27
|
-
|
|
38
|
+
Substituted fluid bulk modulus [Pa].
|
|
28
39
|
rho_fl_sub : np.ndarray
|
|
29
40
|
Substituted fluid density [lg/m^3].
|
|
30
41
|
k_sat_orig : np.ndarray
|
|
@@ -39,7 +50,7 @@ def gassmann_sub_model(
|
|
|
39
50
|
Returns
|
|
40
51
|
-------
|
|
41
52
|
tuple
|
|
42
|
-
vp_sat, vs_sat, rho_sat, ai_sat, vpvs_sat, k_sat, mu :
|
|
53
|
+
vp_sat, vs_sat, rho_sat, ai_sat, vpvs_sat, k_sat, mu : np.ndarray
|
|
43
54
|
vp_sat, vs_sat: saturated velocities [m/s], rho_sat: saturated density [kg/m^3], ai_sat: saturated acoustic
|
|
44
55
|
impedance [kg/m^3 x m/s], vpvs_sat: saturated velocity ratio [unitless], k_sat, mu: saturated bulk modulus and
|
|
45
56
|
shear modulus (the latter unchanged from dry state) [Pa].
|
|
@@ -1,7 +1,26 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import numpy.typing as npt
|
|
3
|
+
|
|
1
4
|
from rock_physics_open.equinor_utilities import std_functions
|
|
2
5
|
|
|
3
6
|
|
|
4
|
-
def hs_average(
|
|
7
|
+
def hs_average(
|
|
8
|
+
k1: npt.NDArray[np.float64],
|
|
9
|
+
mu1: npt.NDArray[np.float64],
|
|
10
|
+
rhob1: npt.NDArray[np.float64],
|
|
11
|
+
k2: npt.NDArray[np.float64],
|
|
12
|
+
mu2: npt.NDArray[np.float64],
|
|
13
|
+
rhob2: npt.NDArray[np.float64],
|
|
14
|
+
f: npt.NDArray[np.float64],
|
|
15
|
+
) -> tuple[
|
|
16
|
+
npt.NDArray[np.float64],
|
|
17
|
+
npt.NDArray[np.float64],
|
|
18
|
+
npt.NDArray[np.float64],
|
|
19
|
+
npt.NDArray[np.float64],
|
|
20
|
+
npt.NDArray[np.float64],
|
|
21
|
+
npt.NDArray[np.float64],
|
|
22
|
+
npt.NDArray[np.float64],
|
|
23
|
+
]:
|
|
5
24
|
"""
|
|
6
25
|
BMix of two phases by Hashin-Shtrikman model. Derived properties are also returned.
|
|
7
26
|
|