rock-physics-open 0.0__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/__init__.py +0 -0
- rock_physics_open/equinor_utilities/__init__.py +0 -0
- rock_physics_open/equinor_utilities/anisotropy.py +162 -0
- rock_physics_open/equinor_utilities/classification_functions/__init__.py +17 -0
- rock_physics_open/equinor_utilities/classification_functions/class_stats.py +58 -0
- rock_physics_open/equinor_utilities/classification_functions/lin_class.py +47 -0
- rock_physics_open/equinor_utilities/classification_functions/mahal_class.py +56 -0
- rock_physics_open/equinor_utilities/classification_functions/norm_class.py +65 -0
- rock_physics_open/equinor_utilities/classification_functions/poly_class.py +40 -0
- rock_physics_open/equinor_utilities/classification_functions/post_prob.py +26 -0
- rock_physics_open/equinor_utilities/classification_functions/two_step_classification.py +46 -0
- rock_physics_open/equinor_utilities/conversions.py +10 -0
- rock_physics_open/equinor_utilities/gen_utilities/__init__.py +11 -0
- rock_physics_open/equinor_utilities/gen_utilities/dict_to_float.py +33 -0
- rock_physics_open/equinor_utilities/gen_utilities/dim_check_vector.py +83 -0
- rock_physics_open/equinor_utilities/gen_utilities/filter_input.py +126 -0
- rock_physics_open/equinor_utilities/gen_utilities/filter_output.py +78 -0
- rock_physics_open/equinor_utilities/machine_learning_utilities/__init__.py +14 -0
- rock_physics_open/equinor_utilities/machine_learning_utilities/dummy_vars.py +42 -0
- rock_physics_open/equinor_utilities/machine_learning_utilities/exponential_model.py +119 -0
- rock_physics_open/equinor_utilities/machine_learning_utilities/import_ml_models.py +61 -0
- rock_physics_open/equinor_utilities/machine_learning_utilities/run_regression.py +151 -0
- rock_physics_open/equinor_utilities/machine_learning_utilities/sigmoidal_model.py +188 -0
- rock_physics_open/equinor_utilities/snapshot_test_utilities/__init__.py +10 -0
- rock_physics_open/equinor_utilities/snapshot_test_utilities/compare_snapshots.py +145 -0
- rock_physics_open/equinor_utilities/snapshot_test_utilities/snapshots.py +54 -0
- rock_physics_open/equinor_utilities/std_functions/__init__.py +43 -0
- rock_physics_open/equinor_utilities/std_functions/backus_ave.py +53 -0
- rock_physics_open/equinor_utilities/std_functions/dvorkin_nur.py +69 -0
- rock_physics_open/equinor_utilities/std_functions/gassmann.py +140 -0
- rock_physics_open/equinor_utilities/std_functions/hashin_shtrikman.py +195 -0
- rock_physics_open/equinor_utilities/std_functions/hertz_mindlin.py +43 -0
- rock_physics_open/equinor_utilities/std_functions/moduli_velocity.py +51 -0
- rock_physics_open/equinor_utilities/std_functions/reflection_eq.py +98 -0
- rock_physics_open/equinor_utilities/std_functions/rho.py +59 -0
- rock_physics_open/equinor_utilities/std_functions/voigt_reuss_hill.py +128 -0
- rock_physics_open/equinor_utilities/std_functions/walton.py +38 -0
- rock_physics_open/equinor_utilities/std_functions/wood_brie.py +77 -0
- rock_physics_open/equinor_utilities/various_utilities/Equinor_logo.gif +0 -0
- rock_physics_open/equinor_utilities/various_utilities/Equinor_logo.ico +0 -0
- rock_physics_open/equinor_utilities/various_utilities/__init__.py +24 -0
- rock_physics_open/equinor_utilities/various_utilities/display_result_statistics.py +83 -0
- rock_physics_open/equinor_utilities/various_utilities/gassmann_dry_mod.py +37 -0
- rock_physics_open/equinor_utilities/various_utilities/gassmann_mod.py +37 -0
- rock_physics_open/equinor_utilities/various_utilities/gassmann_sub_mod.py +53 -0
- rock_physics_open/equinor_utilities/various_utilities/hs_average.py +40 -0
- rock_physics_open/equinor_utilities/various_utilities/pressure.py +88 -0
- rock_physics_open/equinor_utilities/various_utilities/reflectivity.py +85 -0
- rock_physics_open/equinor_utilities/various_utilities/timeshift.py +91 -0
- rock_physics_open/equinor_utilities/various_utilities/vp_vs_rho_set_statistics.py +154 -0
- rock_physics_open/equinor_utilities/various_utilities/vrh_3_min.py +61 -0
- rock_physics_open/fluid_models/__init__.py +9 -0
- rock_physics_open/fluid_models/brine_model/__init__.py +5 -0
- rock_physics_open/fluid_models/brine_model/brine_properties.py +143 -0
- rock_physics_open/fluid_models/gas_model/__init__.py +5 -0
- rock_physics_open/fluid_models/gas_model/gas_properties.py +277 -0
- rock_physics_open/fluid_models/oil_model/__init__.py +5 -0
- rock_physics_open/fluid_models/oil_model/dead_oil_density.py +60 -0
- rock_physics_open/fluid_models/oil_model/dead_oil_velocity.py +28 -0
- rock_physics_open/fluid_models/oil_model/live_oil_density.py +79 -0
- rock_physics_open/fluid_models/oil_model/live_oil_velocity.py +24 -0
- rock_physics_open/fluid_models/oil_model/oil_bubble_point.py +69 -0
- rock_physics_open/fluid_models/oil_model/oil_properties.py +114 -0
- rock_physics_open/sandstone_models/__init__.py +57 -0
- rock_physics_open/sandstone_models/cemented_shalysand_sandyshale_models.py +304 -0
- rock_physics_open/sandstone_models/constant_cement_models.py +204 -0
- rock_physics_open/sandstone_models/constant_cement_optimisation.py +122 -0
- rock_physics_open/sandstone_models/contact_cement_model.py +138 -0
- rock_physics_open/sandstone_models/curvefit_sandstone_models.py +143 -0
- rock_physics_open/sandstone_models/friable_models.py +178 -0
- rock_physics_open/sandstone_models/friable_optimisation.py +112 -0
- rock_physics_open/sandstone_models/friable_shalysand_sandyshale_models.py +235 -0
- rock_physics_open/sandstone_models/patchy_cement_fluid_substitution_model.py +477 -0
- rock_physics_open/sandstone_models/patchy_cement_model.py +286 -0
- rock_physics_open/sandstone_models/patchy_cement_optimisation.py +251 -0
- rock_physics_open/sandstone_models/unresolved_cemented_sandshale_models.py +134 -0
- rock_physics_open/sandstone_models/unresolved_friable_sandshale_models.py +126 -0
- rock_physics_open/shale_models/__init__.py +19 -0
- rock_physics_open/shale_models/dem.py +174 -0
- rock_physics_open/shale_models/dem_dual_por.py +61 -0
- rock_physics_open/shale_models/kus_tok.py +59 -0
- rock_physics_open/shale_models/multi_sca.py +133 -0
- rock_physics_open/shale_models/pq.py +102 -0
- rock_physics_open/shale_models/sca.py +90 -0
- rock_physics_open/shale_models/shale4_mineral.py +147 -0
- rock_physics_open/shale_models/shale4_mineral_dem_overlay.py +92 -0
- rock_physics_open/span_wagner/__init__.py +5 -0
- rock_physics_open/span_wagner/co2_properties.py +438 -0
- rock_physics_open/span_wagner/coefficients.py +165 -0
- rock_physics_open/span_wagner/equations.py +104 -0
- rock_physics_open/span_wagner/tables/__init__.py +0 -0
- rock_physics_open/span_wagner/tables/carbon_dioxide_density.npz +0 -0
- rock_physics_open/span_wagner/tables/lookup_table.py +33 -0
- rock_physics_open/t_matrix_models/Equinor_logo.ico +0 -0
- rock_physics_open/t_matrix_models/__init__.py +45 -0
- rock_physics_open/t_matrix_models/carbonate_pressure_substitution.py +124 -0
- rock_physics_open/t_matrix_models/curvefit_t_matrix_exp.py +124 -0
- rock_physics_open/t_matrix_models/curvefit_t_matrix_min.py +86 -0
- rock_physics_open/t_matrix_models/opt_subst_utilities.py +415 -0
- rock_physics_open/t_matrix_models/parse_t_matrix_inputs.py +297 -0
- rock_physics_open/t_matrix_models/run_t_matrix.py +243 -0
- rock_physics_open/t_matrix_models/t_matrix_C.py +210 -0
- rock_physics_open/t_matrix_models/t_matrix_opt_fluid_sub_exp.py +137 -0
- rock_physics_open/t_matrix_models/t_matrix_opt_fluid_sub_petec.py +163 -0
- rock_physics_open/t_matrix_models/t_matrix_opt_forward_model_exp.py +72 -0
- rock_physics_open/t_matrix_models/t_matrix_opt_forward_model_min.py +86 -0
- rock_physics_open/t_matrix_models/t_matrix_parameter_optimisation_exp.py +172 -0
- rock_physics_open/t_matrix_models/t_matrix_parameter_optimisation_min.py +159 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/__init__.py +12 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/array_functions.py +75 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/calc_c_eff.py +163 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/calc_isolated.py +95 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/calc_kd.py +40 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/calc_kd_eff.py +116 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/calc_kd_uuv.py +18 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/calc_pressure.py +140 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/calc_t.py +71 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/calc_td.py +42 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/calc_theta.py +43 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/calc_x.py +33 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/calc_z.py +50 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/check_and_tile.py +43 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/g_tensor.py +140 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/iso_av.py +60 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/iso_ave_all.py +55 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/pressure_input.py +44 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/t_matrix_vec.py +278 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/velocity_vti_angles.py +81 -0
- rock_physics_open/t_matrix_models/tmatrix_python.dll +0 -0
- rock_physics_open/t_matrix_models/tmatrix_python.so +0 -0
- rock_physics_open/ternary_plots/__init__.py +3 -0
- rock_physics_open/ternary_plots/gen_ternary_plot.py +73 -0
- rock_physics_open/ternary_plots/shale_prop_ternary.py +337 -0
- rock_physics_open/ternary_plots/ternary_patches.py +277 -0
- rock_physics_open/ternary_plots/ternary_plot_utilities.py +197 -0
- rock_physics_open/ternary_plots/unconventionals_ternary.py +75 -0
- rock_physics_open/version.py +21 -0
- rock_physics_open-0.0.dist-info/METADATA +92 -0
- rock_physics_open-0.0.dist-info/RECORD +142 -0
- rock_physics_open-0.0.dist-info/WHEEL +5 -0
- rock_physics_open-0.0.dist-info/licenses/LICENSE +165 -0
- rock_physics_open-0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from rock_physics_open.equinor_utilities.gen_utilities import dim_check_vector
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def hashin_shtrikman(k1, mu1, k2, mu2, f):
|
|
7
|
+
"""
|
|
8
|
+
Hashin-Sktrikman upper or lower according to ordering of phases.
|
|
9
|
+
|
|
10
|
+
Parameters
|
|
11
|
+
----------
|
|
12
|
+
k1 : np.ndarray
|
|
13
|
+
Bulk modulus of phase 1 [Pa].
|
|
14
|
+
mu1 : np.ndarray
|
|
15
|
+
Shear modulus of phase 1 [Pa].
|
|
16
|
+
k2 : np.ndarray
|
|
17
|
+
Bulk modulus of phase 2 [Pa].
|
|
18
|
+
mu2 : np.ndarray
|
|
19
|
+
Shear modulus of phase 2 [Pa].
|
|
20
|
+
f : np.ndarray
|
|
21
|
+
Fraction of phase 1 [fraction].
|
|
22
|
+
|
|
23
|
+
Returns
|
|
24
|
+
-------
|
|
25
|
+
tuple
|
|
26
|
+
k, mu : np.ndarray.
|
|
27
|
+
k: effective bulk modulus [Pa], mu: effective shear modulus [Pa].
|
|
28
|
+
"""
|
|
29
|
+
k = k1 + (1 - f) * (k2 - k1) / (1 + (k2 - k1) * f * (k1 + 4 / 3 * mu1) ** -1)
|
|
30
|
+
mu = mu1 + (1 - f) * (mu2 - mu1) / (
|
|
31
|
+
1 + 2 * (mu2 - mu1) * f * (k1 + 2 * mu1) / (5 * mu1 * (k1 + 4 / 3 * mu1))
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
return k, mu
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def hashin_shtrikman_average(k1, mu1, k2, mu2, f):
|
|
38
|
+
"""
|
|
39
|
+
Average of Hashin-Shtrikman upper and lower bound.
|
|
40
|
+
|
|
41
|
+
Parameters
|
|
42
|
+
----------
|
|
43
|
+
k1 : np.ndarray
|
|
44
|
+
Bulk modulus of phase 1 [Pa].
|
|
45
|
+
mu1 : np.ndarray
|
|
46
|
+
Shear modulus of phase 1 [Pa].
|
|
47
|
+
k2 : np.ndarray
|
|
48
|
+
Bulk modulus of phase 2 [Pa].
|
|
49
|
+
mu2 : np.ndarray
|
|
50
|
+
Shear modulus of phase 2 [Pa].
|
|
51
|
+
f : np.ndarray
|
|
52
|
+
Fraction of phase 1 [fraction].
|
|
53
|
+
|
|
54
|
+
Returns
|
|
55
|
+
-------
|
|
56
|
+
tuple
|
|
57
|
+
k_av, mu_av : np.ndarray.
|
|
58
|
+
k_av: effective bulk modulus [Pa], mu_av: effective shear modulus [Pa]
|
|
59
|
+
"""
|
|
60
|
+
k_hs1, mu_hs1 = hashin_shtrikman(k1, mu1, k2, mu2, f)
|
|
61
|
+
k_hs2, mu_hs2 = hashin_shtrikman(k2, mu2, k1, mu1, 1 - f)
|
|
62
|
+
|
|
63
|
+
k_av = (k_hs1 + k_hs2) / 2
|
|
64
|
+
mu_av = (mu_hs1 + mu_hs2) / 2
|
|
65
|
+
|
|
66
|
+
return k_av, mu_av
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def hashin_shtrikman_walpole(k1, mu1, k2, mu2, f1, bound="lower"):
|
|
70
|
+
"""
|
|
71
|
+
Hashin-Shtrikman upper bound is obtained when the stiffest material is
|
|
72
|
+
termed 1 and vice versa for lower bound. Tricky in cases like Quartz -
|
|
73
|
+
Calcite where the K and Mu have opposed values. HS - Walpole is
|
|
74
|
+
generalised to regard highest and lowest values in each case. The default
|
|
75
|
+
is to generate lower bound.
|
|
76
|
+
|
|
77
|
+
Parameters
|
|
78
|
+
----------
|
|
79
|
+
k1 : np.ndarray
|
|
80
|
+
Bulk modulus of phase 1 [Pa].
|
|
81
|
+
mu1 : np.ndarray
|
|
82
|
+
Shear modulus of phase 1 [Pa].
|
|
83
|
+
k2 : np.ndarray
|
|
84
|
+
Bulk modulus of phase 2 [Pa].
|
|
85
|
+
mu2 : np.ndarray
|
|
86
|
+
Shear modulus of phase 2 [Pa].
|
|
87
|
+
f1 : np.ndarray or float
|
|
88
|
+
Fraction of phase 1 [fraction].
|
|
89
|
+
bound: str
|
|
90
|
+
'upper' or 'lower' selection of upper of lower bound of effective medium.
|
|
91
|
+
Returns
|
|
92
|
+
-------
|
|
93
|
+
tuple
|
|
94
|
+
k, mu : np.ndarray.
|
|
95
|
+
k: effective bulk modulus [Pa], mu: effective shear modulus [Pa].
|
|
96
|
+
"""
|
|
97
|
+
k1, mu1, k2, mu2, f1 = dim_check_vector((k1, mu1, k2, mu2, f1))
|
|
98
|
+
if bound.lower() not in ["lower", "upper"]:
|
|
99
|
+
raise ValueError(f'{__file__}: bound must be one of "lower" or "upper"')
|
|
100
|
+
|
|
101
|
+
idx_k = k1 == k2
|
|
102
|
+
idx_mu = mu1 == mu2
|
|
103
|
+
f2 = 1 - f1
|
|
104
|
+
|
|
105
|
+
if bound.lower() == "lower":
|
|
106
|
+
k_m = np.minimum(k1, k2)
|
|
107
|
+
mu_m = np.minimum(mu1, mu2)
|
|
108
|
+
else:
|
|
109
|
+
k_m = np.maximum(k1, k2)
|
|
110
|
+
mu_m = np.maximum(mu1, mu2)
|
|
111
|
+
|
|
112
|
+
k = np.zeros(k1.shape)
|
|
113
|
+
mu = np.zeros(k1.shape)
|
|
114
|
+
|
|
115
|
+
if np.any(idx_k):
|
|
116
|
+
k[idx_k] = k1[idx_k]
|
|
117
|
+
if np.any(~idx_k):
|
|
118
|
+
k[~idx_k] = k1[~idx_k] + f2[~idx_k] / (
|
|
119
|
+
(k2[~idx_k] - k1[~idx_k]) ** -1
|
|
120
|
+
+ f1[~idx_k] * (k1[~idx_k] + 4 / 3 * mu_m[~idx_k]) ** -1
|
|
121
|
+
)
|
|
122
|
+
if np.any(idx_mu):
|
|
123
|
+
mu[idx_mu] = mu1[idx_mu]
|
|
124
|
+
if np.any(~idx_mu):
|
|
125
|
+
mu[~idx_mu] = mu1[~idx_mu] + f2[~idx_mu] / (
|
|
126
|
+
(mu2[~idx_mu] - mu1[~idx_mu]) ** -1
|
|
127
|
+
+ f1[~idx_mu]
|
|
128
|
+
* (
|
|
129
|
+
mu1[~idx_mu]
|
|
130
|
+
+ mu_m[~idx_mu]
|
|
131
|
+
/ 6
|
|
132
|
+
* (9 * k_m[~idx_mu] + 8 * mu_m[~idx_mu])
|
|
133
|
+
/ (k_m[~idx_mu] + 2 * mu_m[~idx_mu])
|
|
134
|
+
)
|
|
135
|
+
** -1
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
return k, mu
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def multi_hashin_shtrikman(*coeffs, mode="average"):
|
|
142
|
+
"""
|
|
143
|
+
Hashin-Shtrikman effective medium calculation for multi-mineral case.
|
|
144
|
+
|
|
145
|
+
Parameters
|
|
146
|
+
----------
|
|
147
|
+
coeffs : np.ndarray
|
|
148
|
+
Triplets of vectors with k (bulk modulus [Pa]), mu (shear modulus [Pa]) and fraction for each mineral.
|
|
149
|
+
mode : str
|
|
150
|
+
'average', 'upper' or 'lower'.
|
|
151
|
+
|
|
152
|
+
Returns
|
|
153
|
+
-------
|
|
154
|
+
tuple
|
|
155
|
+
k_hs, mu_hs : np.ndarray.
|
|
156
|
+
k_hs, mu_hs - bulk modulus and shear modulus for effective medium [Pa].
|
|
157
|
+
"""
|
|
158
|
+
if not len(coeffs) % 3 == 0:
|
|
159
|
+
raise ValueError(
|
|
160
|
+
"multi_hashin_shtrikman: inputs not vectors of k, mu and fraction for each mineral"
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
k_arr = np.array(coeffs[::3])
|
|
164
|
+
mu_arr = np.array(coeffs[1::3])
|
|
165
|
+
f = np.array(coeffs[2::3])
|
|
166
|
+
|
|
167
|
+
if not np.all(np.around(np.sum(f, axis=0), decimals=6) == 1.0):
|
|
168
|
+
raise ValueError("multi_hashin_shtrikman: all fractions do not add up to 1.0")
|
|
169
|
+
|
|
170
|
+
if mode.lower() not in ["average", "upper", "lower"]:
|
|
171
|
+
raise ValueError(
|
|
172
|
+
'multi_hashin_shtrikman: mode is not one of "average", "upper" or "lower"'
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
k_min = np.min(k_arr, axis=0)
|
|
176
|
+
k_max = np.max(k_arr, axis=0)
|
|
177
|
+
mu_min = np.min(mu_arr, axis=0)
|
|
178
|
+
mu_max = np.max(mu_arr, axis=0)
|
|
179
|
+
|
|
180
|
+
k_hs_upper = np.sum(f / (k_arr + 4 / 3 * mu_max), axis=0) ** -1 - 4 / 3 * mu_max
|
|
181
|
+
k_hs_lower = np.sum(f / (k_arr + 4 / 3 * mu_min), axis=0) ** -1 - 4 / 3 * mu_min
|
|
182
|
+
|
|
183
|
+
zeta_max = mu_max / 6 * (9 * k_max + 8 * mu_max) / (k_max + 2 * mu_max)
|
|
184
|
+
zeta_min = mu_min / 6 * (9 * k_min + 8 * mu_min) / (k_min + 2 * mu_min)
|
|
185
|
+
|
|
186
|
+
mu_hs_upper = np.sum(f / (mu_arr + zeta_max), axis=0) ** -1 - zeta_max
|
|
187
|
+
mu_hs_lower = np.sum(f / (mu_arr + zeta_min), axis=0) ** -1 - zeta_min
|
|
188
|
+
|
|
189
|
+
if mode == "lower":
|
|
190
|
+
return k_hs_lower, mu_hs_lower
|
|
191
|
+
if mode == "upper":
|
|
192
|
+
return k_hs_upper, mu_hs_upper
|
|
193
|
+
k_hs = 0.5 * (k_hs_upper + k_hs_lower)
|
|
194
|
+
mu_hs = 0.5 * (mu_hs_upper + mu_hs_lower)
|
|
195
|
+
return k_hs, mu_hs
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def hertz_mindlin(k, mu, phi_c, p, shear_red, coord=None):
|
|
5
|
+
"""
|
|
6
|
+
Hertz-Mindlin Pressure-induced moduli increase at critical porosity.
|
|
7
|
+
|
|
8
|
+
Parameters
|
|
9
|
+
----------
|
|
10
|
+
k : np.ndarray
|
|
11
|
+
Bulk modulus of grain mineral [Pa].
|
|
12
|
+
mu : np.ndarray
|
|
13
|
+
Shear modulus of grain mineral [Pa].
|
|
14
|
+
phi_c : np.ndarray
|
|
15
|
+
Critical porosity [fraction].
|
|
16
|
+
p : np.ndarray
|
|
17
|
+
Effective pressure = lithostatic pressure - hydrostatic pressure [Pa].
|
|
18
|
+
shear_red : float or np.ndarray
|
|
19
|
+
Reduced shear factor, if set to 1.0, calculation reduces to standard Hertz-Mindlin equation.
|
|
20
|
+
coord
|
|
21
|
+
coordination number, i.e. the number of grain contacts per grain. If not provided a porosity based
|
|
22
|
+
estimate is used.
|
|
23
|
+
|
|
24
|
+
Returns
|
|
25
|
+
-------
|
|
26
|
+
tuple
|
|
27
|
+
k_dry, mu_dry : np.ndarray.
|
|
28
|
+
k_dry: Bulk modulus [Pa] at effective pressure p,
|
|
29
|
+
mu_dry: Shear modulus [Pa] at effective pressure p.
|
|
30
|
+
"""
|
|
31
|
+
n = 25.98805 * phi_c**2 - 43.7622 * phi_c + 21.6719 if coord is None else coord
|
|
32
|
+
|
|
33
|
+
poiss = (3 * k - 2 * mu) / (2 * (3 * k + mu))
|
|
34
|
+
|
|
35
|
+
a = ((3 * np.pi * (1 - poiss) * p) / (2 * n * (1 - phi_c) * mu)) ** (1 / 3)
|
|
36
|
+
|
|
37
|
+
s_n = (4 * a * mu) / (1 - poiss)
|
|
38
|
+
s_t = (8 * a * mu) / (2 - poiss)
|
|
39
|
+
|
|
40
|
+
k_dry = (n * (1 - phi_c) / (12 * np.pi)) * s_n
|
|
41
|
+
mu_dry = (n * (1 - phi_c) / (20 * np.pi)) * (s_n + 1.5 * s_t * shear_red)
|
|
42
|
+
|
|
43
|
+
return k_dry, mu_dry
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
def moduli(vp, vs, rhob):
|
|
2
|
+
"""
|
|
3
|
+
Calculate isotropic moduli from velocity and density.
|
|
4
|
+
|
|
5
|
+
Parameters
|
|
6
|
+
----------
|
|
7
|
+
vp : np.ndarray or float
|
|
8
|
+
Pressure wave velocity [m/s].
|
|
9
|
+
vs : np.ndarray or float
|
|
10
|
+
Shear wave velocity [m/s].
|
|
11
|
+
rhob : np.ndarray or float
|
|
12
|
+
Bulk density [kg/m^3].
|
|
13
|
+
|
|
14
|
+
Returns
|
|
15
|
+
-------
|
|
16
|
+
tuple
|
|
17
|
+
k, mu : (np.ndarray, np.ndarray) or (float, float).
|
|
18
|
+
k: bulk modulus [Pa], mu: shear modulus [Pa].
|
|
19
|
+
"""
|
|
20
|
+
mu = vs**2 * rhob
|
|
21
|
+
k = vp**2 * rhob - 4 / 3 * mu
|
|
22
|
+
|
|
23
|
+
return k, mu
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def velocity(k, mu, rhob):
|
|
27
|
+
"""
|
|
28
|
+
Calculate velocity, acoustic impedance and vp/vs ratio from elastic moduli and density.
|
|
29
|
+
|
|
30
|
+
Parameters
|
|
31
|
+
----------
|
|
32
|
+
k : np.ndarray, float
|
|
33
|
+
Bulk modulus [Pa].
|
|
34
|
+
mu : np.ndarray, float
|
|
35
|
+
Shear modulus [Pa].
|
|
36
|
+
rhob : np.ndarray, float
|
|
37
|
+
Bulk density [kg/m^3].
|
|
38
|
+
|
|
39
|
+
Returns
|
|
40
|
+
-------
|
|
41
|
+
tuple
|
|
42
|
+
vp, vs, ai, vp_vs : np.ndarray.
|
|
43
|
+
vp: pressure wave velocity [m/s], vs: shear wave velocity [m/s], ai: acoustic impedance [m/s x kg/m^3],
|
|
44
|
+
vp_vs: velocity ratio [fraction].
|
|
45
|
+
"""
|
|
46
|
+
vs = (mu / rhob) ** 0.5
|
|
47
|
+
vp = ((k + 4 / 3 * mu) / rhob) ** 0.5
|
|
48
|
+
ai = vp * rhob
|
|
49
|
+
vp_vs = vp / vs
|
|
50
|
+
|
|
51
|
+
return vp, vs, ai, vp_vs
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def _refl_models(vp, vs, rho, theta, k=2.0, mod="aki_richards"):
|
|
5
|
+
"""Calculate reflect coeff.
|
|
6
|
+
|
|
7
|
+
Parameters
|
|
8
|
+
----------
|
|
9
|
+
vp : np.ndarray
|
|
10
|
+
vp array.
|
|
11
|
+
vs : np.ndarray
|
|
12
|
+
vs array.
|
|
13
|
+
rho : np.ndarray
|
|
14
|
+
rho array.
|
|
15
|
+
theta : float, np.ndarray
|
|
16
|
+
Theta value.
|
|
17
|
+
k : float, optional
|
|
18
|
+
By default 2.0.
|
|
19
|
+
mod : str, optional
|
|
20
|
+
By default 'aki_richards'.
|
|
21
|
+
|
|
22
|
+
Returns
|
|
23
|
+
-------
|
|
24
|
+
np.ndarray
|
|
25
|
+
Reflect coeff.
|
|
26
|
+
"""
|
|
27
|
+
theta = theta / 180 * np.pi
|
|
28
|
+
r_vp = (vp[1:] - vp[0:-1]) / (vp[0:-1] + vp[1:])
|
|
29
|
+
r_vs = (vs[1:] - vs[0:-1]) / (vs[0:-1] + vs[1:])
|
|
30
|
+
r_rho = (rho[1:] - rho[0:-1]) / (rho[0:-1] + rho[1:])
|
|
31
|
+
# Need to append one sample to make returned array of the same size - repeat the last value
|
|
32
|
+
r_vp = np.append(r_vp, r_vp[-1])
|
|
33
|
+
r_vs = np.append(r_vs, r_vs[-1])
|
|
34
|
+
r_rho = np.append(r_rho, r_rho[-1])
|
|
35
|
+
|
|
36
|
+
if mod == "aki_richards":
|
|
37
|
+
reflect_coeff = (
|
|
38
|
+
0.5 * (r_vp + r_rho)
|
|
39
|
+
+ (0.5 * r_vp - 2 * k**-2 * (2 * r_vs + r_rho)) * np.sin(theta) ** 2
|
|
40
|
+
+ 0.5 * r_vp * (np.tan(theta) ** 2 - np.sin(theta) ** 2)
|
|
41
|
+
)
|
|
42
|
+
else:
|
|
43
|
+
reflect_coeff = (
|
|
44
|
+
5 / 8 - 0.5 * k**-2 * np.sin(theta) ** 2 + 0.5 * np.tan(theta) ** 2
|
|
45
|
+
) * r_vp - 4 * k**-2 * np.sin(theta) ** 2 * r_vs
|
|
46
|
+
|
|
47
|
+
return reflect_coeff
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def aki_richards(vp, vs, rho, theta, k=2.0):
|
|
51
|
+
"""
|
|
52
|
+
Linearised Zoeppritz equation according to Aki and Richards.
|
|
53
|
+
|
|
54
|
+
Parameters
|
|
55
|
+
----------
|
|
56
|
+
vp : np.ndarray
|
|
57
|
+
Pressure wave velocity [m/s].
|
|
58
|
+
vs : np.ndarray
|
|
59
|
+
Shear wave velocity [m/s].
|
|
60
|
+
rho : np.ndarray
|
|
61
|
+
Density [kg/m^3].
|
|
62
|
+
theta : np.ndarray
|
|
63
|
+
Angle of incident ray [radians].
|
|
64
|
+
k : float
|
|
65
|
+
Background vp/vs [unitless].
|
|
66
|
+
|
|
67
|
+
Returns
|
|
68
|
+
-------
|
|
69
|
+
refl_coeff : np.ndarray
|
|
70
|
+
Reflection coefficient [unitless].
|
|
71
|
+
"""
|
|
72
|
+
return _refl_models(vp, vs, rho, theta, k, mod="aki_richards")
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def smith_gidlow(vp, vs, rho, theta, k=2.0):
|
|
76
|
+
"""
|
|
77
|
+
Linearised Zoeppritz equation according to Smith and Gidlow.
|
|
78
|
+
|
|
79
|
+
Parameters
|
|
80
|
+
----------
|
|
81
|
+
vp : np.ndarray
|
|
82
|
+
Pressure wave velocity [m/s].
|
|
83
|
+
vs : np.ndarray
|
|
84
|
+
Shear wave velocity [m/s].
|
|
85
|
+
rho : np.ndarray
|
|
86
|
+
Density [kg/m^3].
|
|
87
|
+
theta : np.ndarray
|
|
88
|
+
Angle of incident ray [radians].
|
|
89
|
+
k : float
|
|
90
|
+
Background vp/vs [unitless].
|
|
91
|
+
|
|
92
|
+
Returns
|
|
93
|
+
-------
|
|
94
|
+
refl_coeff : np.ndarray
|
|
95
|
+
Reflection coefficient [unitless].
|
|
96
|
+
"""
|
|
97
|
+
|
|
98
|
+
return _refl_models(vp, vs, rho, theta, k, mod="smith_gidlow")
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
from warnings import warn
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def rho_b(phi, rho_f, rho_mat):
|
|
7
|
+
"""
|
|
8
|
+
Calculate bulk density from porosity, fluid density and matrix density.
|
|
9
|
+
|
|
10
|
+
Parameters
|
|
11
|
+
----------
|
|
12
|
+
phi: np.ndarray
|
|
13
|
+
Porosity [fraction].
|
|
14
|
+
rho_f: np.ndarray
|
|
15
|
+
Fluid bulk density [kg/m^3].
|
|
16
|
+
rho_mat: np.ndarray
|
|
17
|
+
Matrix bulk density [kg/m^3].
|
|
18
|
+
|
|
19
|
+
Returns
|
|
20
|
+
-------
|
|
21
|
+
np.ndarray
|
|
22
|
+
rhob: bulk density [kg/m^3].
|
|
23
|
+
"""
|
|
24
|
+
return phi * rho_f + (1 - phi) * rho_mat
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def rho_m(frac_cem, phi, rho_cem, rho_min):
|
|
28
|
+
"""
|
|
29
|
+
Calculates matrix density as a combination of cement fraction and minerals
|
|
30
|
+
fracCem is defined as cement fraction relative to total volume.
|
|
31
|
+
|
|
32
|
+
Parameters
|
|
33
|
+
----------
|
|
34
|
+
frac_cem : np.ndarray
|
|
35
|
+
Cement fraction [fraction].
|
|
36
|
+
phi : np.ndarray
|
|
37
|
+
Porosity [fraction].
|
|
38
|
+
rho_cem : np.ndarray
|
|
39
|
+
Cement density [kg/m^3].
|
|
40
|
+
rho_min : np.ndarray
|
|
41
|
+
Mineral density [kg/m^3].
|
|
42
|
+
|
|
43
|
+
Returns
|
|
44
|
+
-------
|
|
45
|
+
np.ndarray
|
|
46
|
+
rho_mat: matrix density [kg/m^3]
|
|
47
|
+
"""
|
|
48
|
+
idx = np.logical_and(phi >= 0.0, phi < 1.0)
|
|
49
|
+
if np.sum(idx) != len(phi):
|
|
50
|
+
warn(
|
|
51
|
+
f"{__file__}: phi out of range in {len(phi) - np.sum(idx)} sample",
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
rho_mat = np.ones_like(phi) * np.nan
|
|
55
|
+
f_cem = frac_cem[idx] / (1 - phi[idx])
|
|
56
|
+
|
|
57
|
+
rho_mat[idx] = f_cem * rho_cem[idx] + (1 - f_cem) * rho_min[idx]
|
|
58
|
+
|
|
59
|
+
return rho_mat
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def voigt(k1, mu1, k2, mu2, f1):
|
|
5
|
+
"""
|
|
6
|
+
Effective media calculation of a mixture of two phases using the Voigt bound.
|
|
7
|
+
|
|
8
|
+
Parameters
|
|
9
|
+
----------
|
|
10
|
+
k1 : np.ndarray
|
|
11
|
+
Bulk modulus of phase 1 [Pa].
|
|
12
|
+
mu1 : np.ndarray
|
|
13
|
+
Shear modulus of phase 1 [Pa].
|
|
14
|
+
k2 : np.ndarray
|
|
15
|
+
Bulk modulus of phase 2 [Pa].
|
|
16
|
+
mu2 : np.ndarray
|
|
17
|
+
Shear modulus of phase 2 [Pa].
|
|
18
|
+
f1 : np.ndarray
|
|
19
|
+
Fraction of phase 1 [fraction].
|
|
20
|
+
|
|
21
|
+
Returns
|
|
22
|
+
-------
|
|
23
|
+
tuple
|
|
24
|
+
k, mu : np.ndarray.
|
|
25
|
+
k: effective bulk modulus [Pa], mu: effective shear modulus [Pa]
|
|
26
|
+
"""
|
|
27
|
+
f2 = 1 - f1
|
|
28
|
+
k_v = f1 * k1 + f2 * k2
|
|
29
|
+
mu_v = f1 * mu1 + f2 * mu2
|
|
30
|
+
|
|
31
|
+
return k_v, mu_v
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def voigt_reuss_hill(k1, mu1, k2, mu2, f1):
|
|
35
|
+
"""
|
|
36
|
+
Effective media calculation of a mixture of two phases using the Voigt-Reuss-Hill average.
|
|
37
|
+
|
|
38
|
+
Parameters
|
|
39
|
+
----------
|
|
40
|
+
k1 : np.ndarray
|
|
41
|
+
Bulk modulus of phase 1 [Pa].
|
|
42
|
+
mu1 : np.ndarray
|
|
43
|
+
Shear modulus of phase 1 [Pa].
|
|
44
|
+
k2 : np.ndarray
|
|
45
|
+
Bulk modulus of phase 2 [Pa].
|
|
46
|
+
mu2 : np.ndarray
|
|
47
|
+
Shear modulus of phase 2 [Pa].
|
|
48
|
+
f1 : np.ndarray
|
|
49
|
+
Fraction of phase 1 [fraction].
|
|
50
|
+
|
|
51
|
+
Returns
|
|
52
|
+
-------
|
|
53
|
+
tuple
|
|
54
|
+
k, mu : np.ndarray
|
|
55
|
+
k: effective bulk modulus [Pa], mu: effective shear modulus [Pa]
|
|
56
|
+
"""
|
|
57
|
+
k_v, mu_v = voigt(k1, mu1, k2, mu2, f1)
|
|
58
|
+
k_r, mu_r = reuss(k1, mu1, k2, mu2, f1)
|
|
59
|
+
|
|
60
|
+
k_vrh = (k_r + k_v) / 2
|
|
61
|
+
mu_vrh = (mu_r + mu_v) / 2
|
|
62
|
+
|
|
63
|
+
return k_vrh, mu_vrh
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def multi_voigt_reuss_hill(*varargin):
|
|
67
|
+
"""
|
|
68
|
+
Voigt-Reuss-Hill with multiple mineral input.
|
|
69
|
+
|
|
70
|
+
Call function with [k, mu] = multi_voigt_reuss_hill(k1, mu1, f2, ....kn,
|
|
71
|
+
mun, fn). Fractions must add up to 1.0. All inputs are assumed to be
|
|
72
|
+
vectors with the same length.
|
|
73
|
+
|
|
74
|
+
Parameters
|
|
75
|
+
----------
|
|
76
|
+
varargin : np.ndarray
|
|
77
|
+
|
|
78
|
+
Returns
|
|
79
|
+
-------
|
|
80
|
+
tuple
|
|
81
|
+
k, mu : np.ndarray
|
|
82
|
+
k: effective bulk modulus [Pa], mu: effective shear modulus [Pa].
|
|
83
|
+
"""
|
|
84
|
+
k_min = np.array(varargin[::3])
|
|
85
|
+
mu_min = np.array(varargin[1::3])
|
|
86
|
+
f = np.array(varargin[2::3])
|
|
87
|
+
|
|
88
|
+
k_voigt = np.sum(k_min * f, axis=0)
|
|
89
|
+
mu_voigt = np.sum(mu_min * f, axis=0)
|
|
90
|
+
|
|
91
|
+
k_reuss = 1 / np.sum(f / k_min, axis=0)
|
|
92
|
+
mu_reuss = 1 / np.sum(f / mu_min, axis=0)
|
|
93
|
+
|
|
94
|
+
k = (k_voigt + k_reuss) / 2
|
|
95
|
+
mu = (mu_voigt + mu_reuss) / 2
|
|
96
|
+
|
|
97
|
+
return k, mu
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def reuss(k1, mu1, k2, mu2, f1):
|
|
101
|
+
"""
|
|
102
|
+
Effective media calculation of a mixture of two phases using the Reuss bound.
|
|
103
|
+
|
|
104
|
+
Parameters
|
|
105
|
+
----------
|
|
106
|
+
k1 : np.ndarray
|
|
107
|
+
Bulk modulus of phase 1 [Pa].
|
|
108
|
+
mu1 : np.ndarray
|
|
109
|
+
Shear modulus of phase 1 [Pa].
|
|
110
|
+
k2 : np.ndarray
|
|
111
|
+
Bulk modulus of phase 2 [Pa].
|
|
112
|
+
mu2 : np.ndarray
|
|
113
|
+
Shear modulus of phase 2 [Pa].
|
|
114
|
+
f1 : np.ndarray
|
|
115
|
+
Fraction of phase 1 [fraction].
|
|
116
|
+
|
|
117
|
+
Returns
|
|
118
|
+
-------
|
|
119
|
+
tuple
|
|
120
|
+
k, mu : np.ndarray.
|
|
121
|
+
k: effective bulk modulus [Pa], mu: effective shear modulus [Pa].
|
|
122
|
+
"""
|
|
123
|
+
f2 = 1 - f1
|
|
124
|
+
|
|
125
|
+
k_r = 1 / (f1 / k1 + f2 / k2)
|
|
126
|
+
mu_r = 1 / (f1 / mu1 + f2 / mu2)
|
|
127
|
+
|
|
128
|
+
return k_r, mu_r
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def walton_smooth(k, mu, phi, p_eff, coord=None):
|
|
5
|
+
"""
|
|
6
|
+
Walton Smooth Pressure-induced moduli increase at critical porosity.
|
|
7
|
+
|
|
8
|
+
Parameters
|
|
9
|
+
----------
|
|
10
|
+
k : np.ndarray
|
|
11
|
+
Bulk modulus of grain mineral [Pa].
|
|
12
|
+
mu : np.ndarray
|
|
13
|
+
Shear modulus of grain mineral [Pa].
|
|
14
|
+
phi : np.ndarray
|
|
15
|
+
Critical porosity [fraction].
|
|
16
|
+
p_eff : np.ndarray
|
|
17
|
+
Effective Pressure = (Lithostatic - Hydrostatic) pressure [Pa].
|
|
18
|
+
coord : float or np.ndarray
|
|
19
|
+
Coordination number, i.e. number of grain contract per grain. If not provided a porosity based estimate is
|
|
20
|
+
used [unitless].
|
|
21
|
+
|
|
22
|
+
Returns
|
|
23
|
+
-------
|
|
24
|
+
tuple
|
|
25
|
+
k_dry , mu_dry : np.ndarray.
|
|
26
|
+
k_dry Bulk modulus at effective pressure p,
|
|
27
|
+
mu_dry Shear modulus at effective pressure p.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
n = 25.98805 * phi**2 - 43.7622 * phi + 21.6719 if coord is None else coord
|
|
31
|
+
|
|
32
|
+
pr_min = (3 * k - 2 * mu) / (2 * (3 * k + mu))
|
|
33
|
+
k_dry_num = n**2 * (1 - phi) ** 2 * mu**2 * p_eff # Numerator in walton expression
|
|
34
|
+
k_dry_denom = 18 * np.pi**2 * (1 - pr_min) ** 2 # Denominator in Walton expression
|
|
35
|
+
k_dry = (k_dry_num / k_dry_denom) ** (1 / 3) # Bulk modulus
|
|
36
|
+
mu_dry = 3 / 5 * k_dry
|
|
37
|
+
|
|
38
|
+
return k_dry, mu_dry
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def brie(s_gas, k_gas, s_brine, k_brine, s_oil, k_oil, e):
|
|
5
|
+
"""
|
|
6
|
+
Brie function for effective bulk modulus of a mix of fluids.
|
|
7
|
+
|
|
8
|
+
Parameters
|
|
9
|
+
----------
|
|
10
|
+
s_gas : np.ndarray
|
|
11
|
+
Gas saturation [ratio].
|
|
12
|
+
k_gas : np.ndarray
|
|
13
|
+
Gas bulk modulus [Pa].
|
|
14
|
+
s_brine : np.ndarray
|
|
15
|
+
Brine saturation [ratio].
|
|
16
|
+
k_brine : np.ndarray
|
|
17
|
+
Brine bulk modulus [Pa].
|
|
18
|
+
s_oil : np.ndarray
|
|
19
|
+
Oil saturation [ratio].
|
|
20
|
+
k_oil : np.ndarray
|
|
21
|
+
Oil bulk modulus [Pa].
|
|
22
|
+
e : float or np.ndarray
|
|
23
|
+
Exponent in Brie function [unitless].
|
|
24
|
+
|
|
25
|
+
Returns
|
|
26
|
+
-------
|
|
27
|
+
np.ndarray
|
|
28
|
+
k: effective bulk modulus [Pa].
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
# Reuss average for fluids, catch zero fluid saturations
|
|
32
|
+
idx = s_brine + s_oil > 0
|
|
33
|
+
k_liquid = np.zeros(k_brine.shape)
|
|
34
|
+
k_liquid[idx] = (s_brine[idx] / k_brine[idx] + s_oil[idx] / k_oil[idx]) ** -1
|
|
35
|
+
|
|
36
|
+
return (k_liquid - k_gas) * (1 - s_gas) ** e + k_gas
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def wood(s1, k1, rho1, k2, rho2):
|
|
40
|
+
"""
|
|
41
|
+
Wood effective fluid properties for a mix of two fluids.
|
|
42
|
+
|
|
43
|
+
Parameters
|
|
44
|
+
----------
|
|
45
|
+
s1 : np.ndarray
|
|
46
|
+
Saturation of phase 1 [ratio].
|
|
47
|
+
k1 : np.ndarray
|
|
48
|
+
Bulk modulus of phase 1 [Pa].
|
|
49
|
+
rho1 : np.ndarray
|
|
50
|
+
Density of phase 1 [kg/m^3].
|
|
51
|
+
k2 : np.ndarray
|
|
52
|
+
Bulk modulus of phase 2 [Pa].
|
|
53
|
+
rho2 : np.ndarray
|
|
54
|
+
Density of phase 2 [kg/m^3].
|
|
55
|
+
|
|
56
|
+
Returns
|
|
57
|
+
-------
|
|
58
|
+
tuple
|
|
59
|
+
k, rho : np.ndarray.
|
|
60
|
+
k: effective fluid bulk modulus [Pa], rho: effective fluid density [kg/m^3].
|
|
61
|
+
"""
|
|
62
|
+
s2 = 1 - s1
|
|
63
|
+
|
|
64
|
+
k = 1 / (s1 / k1 + s2 / k2)
|
|
65
|
+
rho = s1 * rho1 + s2 * rho2
|
|
66
|
+
|
|
67
|
+
return k, rho
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def multi_wood(fractions, bulk_moduli):
|
|
71
|
+
assert len(fractions) == len(bulk_moduli)
|
|
72
|
+
sum_fractions = sum(fractions)
|
|
73
|
+
ratio_sum = sum(
|
|
74
|
+
saturation / bulk_modulus
|
|
75
|
+
for (saturation, bulk_modulus) in zip(fractions, bulk_moduli)
|
|
76
|
+
)
|
|
77
|
+
return sum_fractions / ratio_sum
|
|
Binary file
|
|
Binary file
|