rock-physics-open 0.3.0__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/machine_learning_utilities/__init__.py +0 -12
- rock_physics_open/equinor_utilities/machine_learning_utilities/import_ml_models.py +0 -16
- rock_physics_open/equinor_utilities/machine_learning_utilities/run_regression.py +6 -4
- 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/sandstone_models/friable_models.py +6 -7
- rock_physics_open/sandstone_models/patchy_cement_model.py +15 -0
- rock_physics_open/ternary_plots/ternary_plot_utilities.py +3 -3
- rock_physics_open/version.py +2 -2
- {rock_physics_open-0.3.0.dist-info → rock_physics_open-0.3.1.dist-info}/METADATA +2 -2
- {rock_physics_open-0.3.0.dist-info → rock_physics_open-0.3.1.dist-info}/RECORD +33 -35
- rock_physics_open/equinor_utilities/machine_learning_utilities/friable_pressure_models.py +0 -230
- rock_physics_open/equinor_utilities/machine_learning_utilities/patchy_cement_pressure_models.py +0 -280
- {rock_physics_open-0.3.0.dist-info → rock_physics_open-0.3.1.dist-info}/WHEEL +0 -0
- {rock_physics_open-0.3.0.dist-info → rock_physics_open-0.3.1.dist-info}/licenses/LICENSE +0 -0
- {rock_physics_open-0.3.0.dist-info → rock_physics_open-0.3.1.dist-info}/top_level.txt +0 -0
|
@@ -1,14 +1,6 @@
|
|
|
1
1
|
from .dummy_vars import generate_dummy_vars
|
|
2
2
|
from .exponential_model import ExponentialPressureModel
|
|
3
|
-
from .friable_pressure_models import (
|
|
4
|
-
FriableDryBulkModulusPressureModel,
|
|
5
|
-
FriableDryShearModulusPressureModel,
|
|
6
|
-
)
|
|
7
3
|
from .import_ml_models import import_model
|
|
8
|
-
from .patchy_cement_pressure_models import (
|
|
9
|
-
PatchyCementDryBulkModulusPressureModel,
|
|
10
|
-
PatchyCementDryShearModulusPressureModel,
|
|
11
|
-
)
|
|
12
4
|
from .polynomial_model import PolynomialPressureModel
|
|
13
5
|
from .run_regression import run_regression
|
|
14
6
|
from .sigmoidal_model import SigmoidalPressureModel
|
|
@@ -20,8 +12,4 @@ __all__ = [
|
|
|
20
12
|
"ExponentialPressureModel",
|
|
21
13
|
"PolynomialPressureModel",
|
|
22
14
|
"SigmoidalPressureModel",
|
|
23
|
-
"FriableDryBulkModulusPressureModel",
|
|
24
|
-
"FriableDryShearModulusPressureModel",
|
|
25
|
-
"PatchyCementDryShearModulusPressureModel",
|
|
26
|
-
"PatchyCementDryBulkModulusPressureModel",
|
|
27
15
|
]
|
|
@@ -1,12 +1,4 @@
|
|
|
1
1
|
from .exponential_model import ExponentialPressureModel
|
|
2
|
-
from .friable_pressure_models import (
|
|
3
|
-
FriableDryBulkModulusPressureModel,
|
|
4
|
-
FriableDryShearModulusPressureModel,
|
|
5
|
-
)
|
|
6
|
-
from .patchy_cement_pressure_models import (
|
|
7
|
-
PatchyCementDryBulkModulusPressureModel,
|
|
8
|
-
PatchyCementDryShearModulusPressureModel,
|
|
9
|
-
)
|
|
10
2
|
from .polynomial_model import PolynomialPressureModel
|
|
11
3
|
from .sigmoidal_model import SigmoidalPressureModel
|
|
12
4
|
|
|
@@ -47,14 +39,6 @@ def import_model(model_file_name):
|
|
|
47
39
|
models = ExponentialPressureModel.load(mod_dict["nn_mod"])
|
|
48
40
|
elif mod_dict["model_type"] == "Polynomial":
|
|
49
41
|
models = PolynomialPressureModel.load(mod_dict["nn_mod"])
|
|
50
|
-
elif mod_dict["model_type"] == "FriableDryBulk":
|
|
51
|
-
models = FriableDryBulkModulusPressureModel.load(mod_dict["nn_mod"])
|
|
52
|
-
elif mod_dict["model_type"] == "FriableDryShear":
|
|
53
|
-
models = FriableDryShearModulusPressureModel.load(mod_dict["nn_mod"])
|
|
54
|
-
elif mod_dict["model_type"] == "PatchyCementDryBulk":
|
|
55
|
-
models = PatchyCementDryBulkModulusPressureModel.load(mod_dict["nn_mod"])
|
|
56
|
-
elif mod_dict["model_type"] == "PatchyCementDryShear":
|
|
57
|
-
models = PatchyCementDryShearModulusPressureModel.load(mod_dict["nn_mod"])
|
|
58
42
|
else:
|
|
59
43
|
raise ValueError("unknown model type {}".format(mod_dict["model_type"]))
|
|
60
44
|
|
|
@@ -108,7 +108,9 @@ def _perform_regression(
|
|
|
108
108
|
return res_frame
|
|
109
109
|
|
|
110
110
|
|
|
111
|
-
def run_regression(
|
|
111
|
+
def run_regression(
|
|
112
|
+
inp_df, first_model_file_name, second_model_file_name, model_dir=None
|
|
113
|
+
):
|
|
112
114
|
"""
|
|
113
115
|
Estimate Vp and Vs by neural network regression with multiple inputs.
|
|
114
116
|
|
|
@@ -116,9 +118,9 @@ def run_regression(inp_df, vp_model_file_name, vs_model_file_name, model_dir=Non
|
|
|
116
118
|
----------
|
|
117
119
|
inp_df : pd.DataFrame
|
|
118
120
|
Input logs required for the regression.
|
|
119
|
-
|
|
121
|
+
first_model_file_name : str
|
|
120
122
|
Full file name for vp model.
|
|
121
|
-
|
|
123
|
+
second_model_file_name : str
|
|
122
124
|
Full file name for vs model.
|
|
123
125
|
model_dir : str
|
|
124
126
|
Directory.
|
|
@@ -139,7 +141,7 @@ def run_regression(inp_df, vp_model_file_name, vs_model_file_name, model_dir=Non
|
|
|
139
141
|
category_var,
|
|
140
142
|
column_names,
|
|
141
143
|
column_units,
|
|
142
|
-
) = _read_models(
|
|
144
|
+
) = _read_models(first_model_file_name, second_model_file_name, model_dir=model_dir)
|
|
143
145
|
return _perform_regression(
|
|
144
146
|
inp_df,
|
|
145
147
|
column_names,
|
|
@@ -1,7 +1,22 @@
|
|
|
1
1
|
import numpy as np
|
|
2
|
+
import numpy.typing as npt
|
|
2
3
|
|
|
3
4
|
|
|
4
|
-
def backus_average(
|
|
5
|
+
def backus_average(
|
|
6
|
+
vp1: npt.NDArray[np.float64],
|
|
7
|
+
vs1: npt.NDArray[np.float64],
|
|
8
|
+
rho1: npt.NDArray[np.float64],
|
|
9
|
+
vp2: npt.NDArray[np.float64],
|
|
10
|
+
vs2: npt.NDArray[np.float64],
|
|
11
|
+
rho2: npt.NDArray[np.float64],
|
|
12
|
+
f1: npt.NDArray[np.float64],
|
|
13
|
+
) -> tuple[
|
|
14
|
+
npt.NDArray[np.float64],
|
|
15
|
+
npt.NDArray[np.float64],
|
|
16
|
+
npt.NDArray[np.float64],
|
|
17
|
+
npt.NDArray[np.float64],
|
|
18
|
+
npt.NDArray[np.float64],
|
|
19
|
+
]:
|
|
5
20
|
"""
|
|
6
21
|
Backus average for a combination of two phases. The individual phases are isotropic
|
|
7
22
|
but the resulting effective medium is not.
|
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
import numpy as np
|
|
2
|
+
import numpy.typing as npt
|
|
2
3
|
|
|
3
4
|
|
|
4
5
|
def dvorkin_contact_cement(
|
|
5
|
-
frac_cem
|
|
6
|
-
|
|
6
|
+
frac_cem: npt.NDArray[np.float64],
|
|
7
|
+
por0_sst: npt.NDArray[np.float64],
|
|
8
|
+
mu0_sst: npt.NDArray[np.float64],
|
|
9
|
+
k0_sst: npt.NDArray[np.float64],
|
|
10
|
+
mu0_cem: npt.NDArray[np.float64],
|
|
11
|
+
k0_cem: npt.NDArray[np.float64],
|
|
12
|
+
vs_red: npt.NDArray[np.float64],
|
|
13
|
+
c: float,
|
|
14
|
+
) -> tuple[npt.NDArray[np.float64], npt.NDArray[np.float64]]:
|
|
7
15
|
"""
|
|
8
16
|
Dvorkin-Nur contact cement model for estimation of elastic moduli.
|
|
9
17
|
|
|
@@ -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].
|