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,304 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from rock_physics_open import sandstone_models
|
|
4
|
+
from rock_physics_open.equinor_utilities import gen_utilities, std_functions
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def cemented_shaly_sand_sandy_shale_model(
|
|
8
|
+
k_sst,
|
|
9
|
+
mu_sst,
|
|
10
|
+
rho_sst,
|
|
11
|
+
k_cem,
|
|
12
|
+
mu_cem,
|
|
13
|
+
rho_cem,
|
|
14
|
+
k_mud,
|
|
15
|
+
mu_mud,
|
|
16
|
+
rho_mud,
|
|
17
|
+
k_fl_sst,
|
|
18
|
+
rho_fl_sst,
|
|
19
|
+
k_fl_mud,
|
|
20
|
+
rho_fl_mud,
|
|
21
|
+
phi,
|
|
22
|
+
p_eff_mud,
|
|
23
|
+
shale_frac,
|
|
24
|
+
frac_cem,
|
|
25
|
+
phi_c_sst,
|
|
26
|
+
n_sst,
|
|
27
|
+
shear_red_sst,
|
|
28
|
+
phi_c_mud,
|
|
29
|
+
phi_intr_mud,
|
|
30
|
+
coord_num_func_mud,
|
|
31
|
+
n_mud,
|
|
32
|
+
shear_red_mud,
|
|
33
|
+
):
|
|
34
|
+
"""
|
|
35
|
+
Model for mixing of cemented sand and friable shale.
|
|
36
|
+
|
|
37
|
+
It is no point to use this model to calculate the shale response only,
|
|
38
|
+
in that case Friable Model with shale parameters does the job
|
|
39
|
+
|
|
40
|
+
The shale fluid should be brine.
|
|
41
|
+
|
|
42
|
+
Shale fraction shaleFrac is in the range 0 to 1. For shaleFrac = 0 we
|
|
43
|
+
have a pure sand end member with phi =< phi_c for sand. For shaleFrac = 1
|
|
44
|
+
we have pure shale with phi = intrinsic porosity. For shaleFrac < phi_c
|
|
45
|
+
the model is on the shaly sand trend, for shaleFrac > phi_c it is on the
|
|
46
|
+
sandy shale trend.
|
|
47
|
+
|
|
48
|
+
Parameters
|
|
49
|
+
----------
|
|
50
|
+
k_sst : np.ndarray
|
|
51
|
+
Sandstone matrix bulk modulus [Pa].
|
|
52
|
+
mu_sst : np.ndarray
|
|
53
|
+
Sandstone matrix shear modulus [Pa].
|
|
54
|
+
rho_sst : np.ndarray
|
|
55
|
+
Sandstone matrix bulk density [kg/m^3].
|
|
56
|
+
k_cem : np.ndarray
|
|
57
|
+
Sandstone cement bulk modulus [Pa].
|
|
58
|
+
mu_cem : np.ndarray
|
|
59
|
+
Sandstone cement shear modulus [Pa].
|
|
60
|
+
rho_cem : np.ndarray
|
|
61
|
+
Sandstone cement bulk density [kg/m^3].
|
|
62
|
+
k_mud : np.ndarray
|
|
63
|
+
Shale bulk modulus [Pa].
|
|
64
|
+
mu_mud : np.ndarray
|
|
65
|
+
Shale shear modulus [Pa].
|
|
66
|
+
rho_mud : np.ndarray
|
|
67
|
+
Shale bulk density [kg/m^3].
|
|
68
|
+
k_fl_sst : np.ndarray
|
|
69
|
+
Fluid bulk modulus for sandstone fluid [Pa].
|
|
70
|
+
rho_fl_sst : np.ndarray
|
|
71
|
+
Fluid bulk density for sandstone fluid [kg/m^3].
|
|
72
|
+
k_fl_mud : np.ndarray
|
|
73
|
+
Fluid bulk modulus for shale fluid [Pa].
|
|
74
|
+
rho_fl_mud : np.ndarray
|
|
75
|
+
Fluid bulk density for shale fluid[kg/m^3].
|
|
76
|
+
phi : np.ndarray
|
|
77
|
+
Total porosity [fraction].
|
|
78
|
+
p_eff_mud : np.ndarray
|
|
79
|
+
Effective pressure in mud [Pa].
|
|
80
|
+
shale_frac : np.ndarray
|
|
81
|
+
Shale fraction [fraction].
|
|
82
|
+
frac_cem : np.ndarray
|
|
83
|
+
Cement volume fraction [fraction].
|
|
84
|
+
phi_c_sst : float
|
|
85
|
+
Critical porosity for sandstone[fraction].
|
|
86
|
+
phi_c_mud : float
|
|
87
|
+
Critical porosity for mud [fraction].
|
|
88
|
+
phi_intr_mud : float
|
|
89
|
+
Intrinsic porosity for mud [fraction].
|
|
90
|
+
n_sst : float
|
|
91
|
+
Coordination number for sandstone [unitless].
|
|
92
|
+
n_mud : float
|
|
93
|
+
Coordination number for shale [unitless].
|
|
94
|
+
coord_num_func_mud : str
|
|
95
|
+
Indication if coordination number should be calculated from porosity or kept constant for shale.
|
|
96
|
+
shear_red_sst : float
|
|
97
|
+
Shear reduction factor for sandstone [fraction].
|
|
98
|
+
shear_red_mud : float
|
|
99
|
+
Shear reduction factor for mud [fraction].
|
|
100
|
+
|
|
101
|
+
Returns
|
|
102
|
+
-------
|
|
103
|
+
tuple
|
|
104
|
+
vp, vs, rho, ai, vpvs : (np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray)
|
|
105
|
+
vp [m/s] and vs [m/s], bulk density [kg/m^3], ai [m/s x kg/m^3], vpvs [ratio] of saturated rock.
|
|
106
|
+
"""
|
|
107
|
+
|
|
108
|
+
# Valid porosity values must not exceed (phi_c - frac_cem)
|
|
109
|
+
# Assume that this only needs to be considered for the sandstone fraction
|
|
110
|
+
(
|
|
111
|
+
k_sst,
|
|
112
|
+
mu_sst,
|
|
113
|
+
rho_sst,
|
|
114
|
+
k_cem,
|
|
115
|
+
mu_cem,
|
|
116
|
+
rho_cem,
|
|
117
|
+
k_mud,
|
|
118
|
+
mu_mud,
|
|
119
|
+
rho_mud,
|
|
120
|
+
k_fl_sst,
|
|
121
|
+
rho_fl_sst,
|
|
122
|
+
k_fl_mud,
|
|
123
|
+
rho_fl_mud,
|
|
124
|
+
phi,
|
|
125
|
+
p_eff_mud,
|
|
126
|
+
shale_frac,
|
|
127
|
+
frac_cem,
|
|
128
|
+
) = gen_utilities.dim_check_vector(
|
|
129
|
+
(
|
|
130
|
+
k_sst,
|
|
131
|
+
mu_sst,
|
|
132
|
+
rho_sst,
|
|
133
|
+
k_cem,
|
|
134
|
+
mu_cem,
|
|
135
|
+
rho_cem,
|
|
136
|
+
k_mud,
|
|
137
|
+
mu_mud,
|
|
138
|
+
rho_mud,
|
|
139
|
+
k_fl_sst,
|
|
140
|
+
rho_fl_sst,
|
|
141
|
+
k_fl_mud,
|
|
142
|
+
rho_fl_mud,
|
|
143
|
+
phi,
|
|
144
|
+
p_eff_mud,
|
|
145
|
+
shale_frac,
|
|
146
|
+
frac_cem,
|
|
147
|
+
)
|
|
148
|
+
)
|
|
149
|
+
(
|
|
150
|
+
idx_phi,
|
|
151
|
+
(
|
|
152
|
+
k_sst,
|
|
153
|
+
mu_sst,
|
|
154
|
+
rho_sst,
|
|
155
|
+
k_cem,
|
|
156
|
+
mu_cem,
|
|
157
|
+
rho_cem,
|
|
158
|
+
k_mud,
|
|
159
|
+
mu_mud,
|
|
160
|
+
rho_mud,
|
|
161
|
+
k_fl_sst,
|
|
162
|
+
rho_fl_sst,
|
|
163
|
+
k_fl_mud,
|
|
164
|
+
rho_fl_mud,
|
|
165
|
+
phi,
|
|
166
|
+
p_eff_mud,
|
|
167
|
+
shale_frac,
|
|
168
|
+
frac_cem,
|
|
169
|
+
_,
|
|
170
|
+
_,
|
|
171
|
+
),
|
|
172
|
+
) = gen_utilities.filter_input_log(
|
|
173
|
+
(
|
|
174
|
+
k_sst,
|
|
175
|
+
mu_sst,
|
|
176
|
+
rho_sst,
|
|
177
|
+
k_cem,
|
|
178
|
+
mu_cem,
|
|
179
|
+
rho_cem,
|
|
180
|
+
k_mud,
|
|
181
|
+
mu_mud,
|
|
182
|
+
rho_mud,
|
|
183
|
+
k_fl_sst,
|
|
184
|
+
rho_fl_sst,
|
|
185
|
+
k_fl_mud,
|
|
186
|
+
rho_fl_mud,
|
|
187
|
+
phi,
|
|
188
|
+
p_eff_mud,
|
|
189
|
+
shale_frac,
|
|
190
|
+
frac_cem,
|
|
191
|
+
phi_c_sst - frac_cem - phi,
|
|
192
|
+
phi - phi_intr_mud,
|
|
193
|
+
),
|
|
194
|
+
no_zero=False,
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
# Reduce range of porosity by frac_cem
|
|
198
|
+
phi_c = phi_c_sst - frac_cem
|
|
199
|
+
|
|
200
|
+
sandy_shale_idx = shale_frac > phi
|
|
201
|
+
shaly_sand_idx = ~sandy_shale_idx
|
|
202
|
+
|
|
203
|
+
# Fraction of silt in silt - shale trend
|
|
204
|
+
frac_silt = (1 - shale_frac) / (1 - phi)
|
|
205
|
+
# Fraction of sand in sand - silt trend
|
|
206
|
+
frac_sand = 1 - shale_frac / phi
|
|
207
|
+
|
|
208
|
+
# Shale properties for intrinsic porosity point NB! The phi_intr_mud is
|
|
209
|
+
# normally a parameter, but the assumption in Friable model is that it is a
|
|
210
|
+
# log. Make sure that it is of the same length as the other
|
|
211
|
+
|
|
212
|
+
# Expand the needed variables from float to numpy array
|
|
213
|
+
phi, phi_intr_mud = gen_utilities.dim_check_vector((phi, phi_intr_mud))
|
|
214
|
+
|
|
215
|
+
vp_sat_mud, vs_sat_mud, rho_b_mud = sandstone_models.friable_model(
|
|
216
|
+
k_mud,
|
|
217
|
+
mu_mud,
|
|
218
|
+
rho_mud,
|
|
219
|
+
k_fl_mud,
|
|
220
|
+
rho_fl_mud,
|
|
221
|
+
phi_intr_mud,
|
|
222
|
+
p_eff_mud,
|
|
223
|
+
phi_c_mud,
|
|
224
|
+
coord_num_func_mud,
|
|
225
|
+
n_mud,
|
|
226
|
+
shear_red_mud,
|
|
227
|
+
)[0:3]
|
|
228
|
+
k_sat_mud, mu_sat_mud = std_functions.moduli(vp_sat_mud, vs_sat_mud, rho_b_mud)
|
|
229
|
+
|
|
230
|
+
# Calculate cemented zero-porosity sand
|
|
231
|
+
k_zero, mu_zero = std_functions.hashin_shtrikman_walpole(
|
|
232
|
+
k_cem, mu_cem, k_sst, mu_sst, frac_cem, bound="lower"
|
|
233
|
+
)
|
|
234
|
+
rho_zero = rho_cem * frac_cem + (1 - frac_cem) * rho_sst
|
|
235
|
+
|
|
236
|
+
# Silt end member
|
|
237
|
+
k_silt, mu_silt = std_functions.hashin_shtrikman_walpole(
|
|
238
|
+
k_sat_mud, mu_sat_mud, k_zero, mu_zero, phi_c
|
|
239
|
+
)
|
|
240
|
+
rho_silt = rho_b_mud * phi + rho_zero * (1 - phi)
|
|
241
|
+
|
|
242
|
+
# Estimate the sand end member through the constant cement model with phi =
|
|
243
|
+
# phiCSst <= maybe dubious to expand parameter to vector with assumption
|
|
244
|
+
# that kSst has the correct size
|
|
245
|
+
|
|
246
|
+
vp_sat_sst, vs_sat_sst, rho_sat_sst = sandstone_models.constant_cement_model(
|
|
247
|
+
k_sst,
|
|
248
|
+
mu_sst,
|
|
249
|
+
rho_sst,
|
|
250
|
+
k_cem,
|
|
251
|
+
mu_cem,
|
|
252
|
+
rho_cem,
|
|
253
|
+
k_fl_sst,
|
|
254
|
+
rho_fl_sst,
|
|
255
|
+
phi,
|
|
256
|
+
frac_cem,
|
|
257
|
+
phi_c_sst,
|
|
258
|
+
n_sst,
|
|
259
|
+
shear_red_sst,
|
|
260
|
+
)[0:3]
|
|
261
|
+
k_sat_sst, mu_sat_sst = std_functions.moduli(vp_sat_sst, vs_sat_sst, rho_sat_sst)
|
|
262
|
+
|
|
263
|
+
k = np.ones(shale_frac.shape) * np.nan
|
|
264
|
+
mu = np.ones(shale_frac.shape) * np.nan
|
|
265
|
+
rhob = np.ones(shale_frac.shape) * np.nan
|
|
266
|
+
|
|
267
|
+
# Points on sandy shale trend
|
|
268
|
+
k[sandy_shale_idx], mu[sandy_shale_idx] = std_functions.hashin_shtrikman_walpole(
|
|
269
|
+
k_silt[sandy_shale_idx],
|
|
270
|
+
mu_silt[sandy_shale_idx],
|
|
271
|
+
k_sat_mud[sandy_shale_idx],
|
|
272
|
+
mu_sat_mud[sandy_shale_idx],
|
|
273
|
+
frac_silt[sandy_shale_idx],
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
rhob[sandy_shale_idx] = (
|
|
277
|
+
rho_b_mud[sandy_shale_idx] * (1 - frac_silt[sandy_shale_idx])
|
|
278
|
+
+ rho_silt[sandy_shale_idx] * frac_silt[sandy_shale_idx]
|
|
279
|
+
)
|
|
280
|
+
|
|
281
|
+
# Points on shaly sand trend
|
|
282
|
+
k[shaly_sand_idx], mu[shaly_sand_idx] = std_functions.hashin_shtrikman_walpole(
|
|
283
|
+
k_sat_sst[shaly_sand_idx],
|
|
284
|
+
mu_sat_sst[shaly_sand_idx],
|
|
285
|
+
k_silt[shaly_sand_idx],
|
|
286
|
+
mu_silt[shaly_sand_idx],
|
|
287
|
+
frac_sand[shaly_sand_idx],
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
rhob[shaly_sand_idx] = (
|
|
291
|
+
(1 - phi[shaly_sand_idx]) * rho_zero[shaly_sand_idx]
|
|
292
|
+
+ phi[shaly_sand_idx] * rho_fl_sst[shaly_sand_idx]
|
|
293
|
+
) * frac_sand[shaly_sand_idx] + (1 - frac_sand[shaly_sand_idx]) * rho_silt[
|
|
294
|
+
shaly_sand_idx
|
|
295
|
+
]
|
|
296
|
+
|
|
297
|
+
vp, vs, ai, vpvs = std_functions.velocity(k, mu, rhob)
|
|
298
|
+
|
|
299
|
+
# Restore original length
|
|
300
|
+
vp, vs, rhob, ai, vpvs = gen_utilities.filter_output(
|
|
301
|
+
idx_phi, (vp, vs, rhob, ai, vpvs)
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
return vp, vs, rhob, ai, vpvs
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
from scipy.interpolate import interp1d
|
|
3
|
+
|
|
4
|
+
from rock_physics_open.equinor_utilities import gen_utilities, std_functions
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def constant_cement_model(
|
|
8
|
+
k_min,
|
|
9
|
+
mu_min,
|
|
10
|
+
rho_min,
|
|
11
|
+
k_cem,
|
|
12
|
+
mu_cem,
|
|
13
|
+
rho_cem,
|
|
14
|
+
k_fl,
|
|
15
|
+
rho_fl,
|
|
16
|
+
phi,
|
|
17
|
+
frac_cem,
|
|
18
|
+
phi_c,
|
|
19
|
+
n,
|
|
20
|
+
shear_red,
|
|
21
|
+
extrapolate_to_max_phi=False,
|
|
22
|
+
):
|
|
23
|
+
"""
|
|
24
|
+
Constant cement model is a sandstone model that combined a cemented and a friable sand, so that a constant
|
|
25
|
+
proportion of the rock volume is made up of grain-bonding cement. Variation in porosity is due to grain sorting,
|
|
26
|
+
i.e. a well-sorted sand will have high porosity, and a poorly sorted one will have low porosity. In the extreme
|
|
27
|
+
end all porosity is removed and the effective mineral properties is returned.
|
|
28
|
+
|
|
29
|
+
Mineral properties k_min, mu_min, rho_min are effective properties. For mixtures of minerals, effective
|
|
30
|
+
properties are calculated by Hashin-Shtrikman or similar.
|
|
31
|
+
|
|
32
|
+
Cement properties k_cem, mu_cem, rho_cem and cement fraction, the latter as a part of the whole volume.
|
|
33
|
+
|
|
34
|
+
Fluid properties k_fl, rho_fl are in situ properties calculated by fluid models using reservoir properties.
|
|
35
|
+
|
|
36
|
+
Critical porosity phi_c is input to Dvorkin-Nur function. Coordination number n is normally set to a fixed
|
|
37
|
+
value (default 9) but it is possible to override this. Porosity phi is used in Hashin-Shtrikman mixing
|
|
38
|
+
(together with phi_c) and Gassmann saturation.
|
|
39
|
+
|
|
40
|
+
Shear reduction parameter shear_red is used to account for tangential frictionless grain contacts
|
|
41
|
+
|
|
42
|
+
All inputs are assumed to be vectors of the same length
|
|
43
|
+
|
|
44
|
+
Parameters
|
|
45
|
+
----------
|
|
46
|
+
k_min : np.ndarray
|
|
47
|
+
Mineral bulk modulus [Pa].
|
|
48
|
+
mu_min : np.ndarray
|
|
49
|
+
Mineral shear modulus [Pa].
|
|
50
|
+
rho_min : np.ndarray
|
|
51
|
+
Mineral bulk density [kg/m^3].
|
|
52
|
+
k_cem : np.ndarray
|
|
53
|
+
Cement bulk modulus [Pa].
|
|
54
|
+
mu_cem : np.ndarray
|
|
55
|
+
Cement shear modulus [Pa].
|
|
56
|
+
rho_cem : np.ndarray
|
|
57
|
+
Cement bulk density [kg/m^3].
|
|
58
|
+
k_fl : np.ndarray
|
|
59
|
+
Fluid bulk modulus [Pa].
|
|
60
|
+
rho_fl : np.ndarray
|
|
61
|
+
Fluid bulk density [kg/m^3].
|
|
62
|
+
phi : np.ndarray
|
|
63
|
+
Porosity [fraction].
|
|
64
|
+
frac_cem : np.ndarray or float
|
|
65
|
+
Cement fraction [fraction].
|
|
66
|
+
phi_c : float
|
|
67
|
+
Critical porosity [fraction].
|
|
68
|
+
n : float
|
|
69
|
+
Coordination number [unitless].
|
|
70
|
+
shear_red : float
|
|
71
|
+
Shear reduction factor [fraction].
|
|
72
|
+
extrapolate_to_max_phi : bool
|
|
73
|
+
If True, the model will extrapolate to the maximum porosity value (phi_c - frac_cem) if the input porosity
|
|
74
|
+
exceeds this value. If False, the model will return NaN for porosity values exceeding this limit.
|
|
75
|
+
|
|
76
|
+
Returns
|
|
77
|
+
-------
|
|
78
|
+
tuple
|
|
79
|
+
vp, vs, rho, ai, vpvs : (np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray)
|
|
80
|
+
vp [m/s] and vs [m/s], bulk density [kg/m^3], ai [m/s x kg/m^3], vpvs [ratio] of saturated rock.
|
|
81
|
+
"""
|
|
82
|
+
k_zero, k_dry, mu = constant_cement_model_dry(
|
|
83
|
+
k_min,
|
|
84
|
+
mu_min,
|
|
85
|
+
k_cem,
|
|
86
|
+
mu_cem,
|
|
87
|
+
phi,
|
|
88
|
+
frac_cem,
|
|
89
|
+
phi_c,
|
|
90
|
+
n,
|
|
91
|
+
shear_red,
|
|
92
|
+
extrapolate_to_max_phi=extrapolate_to_max_phi,
|
|
93
|
+
return_k_zero=True,
|
|
94
|
+
)
|
|
95
|
+
# Saturated rock incompressibility is calculated with Gassmann
|
|
96
|
+
k = std_functions.gassmann(k_dry, phi, k_fl, k_zero)
|
|
97
|
+
|
|
98
|
+
# Bulk density
|
|
99
|
+
rho = phi * rho_fl + (1 - phi - frac_cem) * rho_min + frac_cem * rho_cem
|
|
100
|
+
# Velocity
|
|
101
|
+
vp, vs, ai, vpvs = std_functions.velocity(k, mu, rho)
|
|
102
|
+
|
|
103
|
+
return vp, vs, rho, ai, vpvs
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def constant_cement_model_dry(
|
|
107
|
+
k_min,
|
|
108
|
+
mu_min,
|
|
109
|
+
k_cem,
|
|
110
|
+
mu_cem,
|
|
111
|
+
phi,
|
|
112
|
+
frac_cem,
|
|
113
|
+
phi_c,
|
|
114
|
+
n,
|
|
115
|
+
shear_red,
|
|
116
|
+
extrapolate_to_max_phi=False,
|
|
117
|
+
return_k_zero=False,
|
|
118
|
+
):
|
|
119
|
+
"""
|
|
120
|
+
Dry rock version of the constant cement model. The method is identical to the constant cement model function,
|
|
121
|
+
except that a saturation step is not performed at the end.
|
|
122
|
+
|
|
123
|
+
Parameters
|
|
124
|
+
----------
|
|
125
|
+
k_min : np.ndarray
|
|
126
|
+
Mineral bulk modulus [Pa].
|
|
127
|
+
mu_min : np.ndarray
|
|
128
|
+
Mineral shear modulus [Pa].
|
|
129
|
+
k_cem : np.ndarray
|
|
130
|
+
Cement bulk modulus [Pa].
|
|
131
|
+
mu_cem : np.ndarray
|
|
132
|
+
Cement shear modulus [Pa].
|
|
133
|
+
phi : np.ndarray
|
|
134
|
+
Porosity [fraction].
|
|
135
|
+
frac_cem : float or np.ndarray
|
|
136
|
+
Cement fraction [fraction].
|
|
137
|
+
phi_c : float
|
|
138
|
+
Critical porosity [fraction].
|
|
139
|
+
n : float
|
|
140
|
+
Coordination number [unitless].
|
|
141
|
+
shear_red : float
|
|
142
|
+
Shear reduction factor [fraction].
|
|
143
|
+
extrapolate_to_max_phi : bool
|
|
144
|
+
If True, the model will extrapolate to the maximum porosity value (phi_c - frac_cem) if the input porosity
|
|
145
|
+
exceeds this value. If False, the model will return NaN for porosity values exceeding this limit.
|
|
146
|
+
return_k_zero : bool
|
|
147
|
+
If True, the model will return the zero-porosity end member bulk modulus k_zero in addition to the dry rock
|
|
148
|
+
bulk modulus k_dry and shear modulus mu.
|
|
149
|
+
|
|
150
|
+
Returns
|
|
151
|
+
-------
|
|
152
|
+
tuple
|
|
153
|
+
k_dry, mu : (np.ndarray, np.ndarray).
|
|
154
|
+
Bulk modulus k [Pa] and shear modulus mu [Pa] of dry rock.
|
|
155
|
+
"""
|
|
156
|
+
# First check if there are input values that are unphysical, i.e. negative values, separate between dry and
|
|
157
|
+
# saturated rock properties. Use the filter_input_log function to identify these values
|
|
158
|
+
idx, (k_min, mu_min, k_cem, mu_cem, phi) = gen_utilities.filter_input_log(
|
|
159
|
+
(k_min, mu_min, k_cem, mu_cem, phi)
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
# Identify porosity values that exceed (phi_c - frac_cem). This is regardless of setting for extrapolate_to_max_phi
|
|
163
|
+
idx_phi = np.where(phi > phi_c - frac_cem)[0]
|
|
164
|
+
|
|
165
|
+
# At the zero-porosity point, all original porosity (critical porosity -
|
|
166
|
+
# cement fraction) is filled with grains. The cement fraction surrounds the
|
|
167
|
+
# original grains, so they will be fraction 1 according to the geometrical
|
|
168
|
+
# interpretation of Hashin-Shtrikman
|
|
169
|
+
k_zero, mu_zero = std_functions.hashin_shtrikman_walpole(
|
|
170
|
+
k_cem, mu_cem, k_min, mu_min, frac_cem, bound="lower"
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
# Dry rock properties of high-porosity end member calculated with
|
|
174
|
+
# Dvorkin-Nur equation. Cement is assumed to be evenly distributed on the
|
|
175
|
+
# grains (scheme 2 in Dvorkin and Nur's original paper)
|
|
176
|
+
|
|
177
|
+
k_cc, mu_cc = std_functions.dvorkin_contact_cement(
|
|
178
|
+
frac_cem, phi_c, mu_min, k_min, mu_cem, k_cem, shear_red, n
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
# Hashin-Shtrikman lower bound describes the dry rock property mixing from
|
|
182
|
+
# mineral properties to high-end porosity.
|
|
183
|
+
|
|
184
|
+
# Fraction of zero-porosity end member
|
|
185
|
+
f1 = 1 - phi / (phi_c - frac_cem)
|
|
186
|
+
|
|
187
|
+
k_dry, mu = std_functions.hashin_shtrikman_walpole(
|
|
188
|
+
k_zero, mu_zero, k_cc, mu_cc, f1, bound="lower"
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
# If extrapolate_to_max_phi is True, create extrapolation functions for k_dry and mu using scipy's interp1d
|
|
192
|
+
if extrapolate_to_max_phi:
|
|
193
|
+
k_dry_func = interp1d(phi, k_dry, fill_value="extrapolate")
|
|
194
|
+
mu_func = interp1d(phi, mu, fill_value="extrapolate")
|
|
195
|
+
k_dry[idx_phi] = k_dry_func(phi[idx_phi])
|
|
196
|
+
mu[idx_phi] = mu_func(phi[idx_phi])
|
|
197
|
+
else:
|
|
198
|
+
k_dry[idx_phi] = np.nan
|
|
199
|
+
mu[idx_phi] = np.nan
|
|
200
|
+
|
|
201
|
+
k_dry, mu = gen_utilities.filter_output(idx, (k_dry, mu))
|
|
202
|
+
if return_k_zero:
|
|
203
|
+
return k_zero, k_dry, mu
|
|
204
|
+
return k_dry, mu
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from rock_physics_open.equinor_utilities import gen_utilities
|
|
4
|
+
from rock_physics_open.t_matrix_models import gen_opt_routine, save_opt_params
|
|
5
|
+
|
|
6
|
+
from .curvefit_sandstone_models import curvefit_constant_cement
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def constant_cement_model_optimisation(
|
|
10
|
+
k_min: np.ndarray,
|
|
11
|
+
mu_min: np.ndarray,
|
|
12
|
+
rho_min: np.ndarray,
|
|
13
|
+
k_cem: np.ndarray,
|
|
14
|
+
mu_cem: np.ndarray,
|
|
15
|
+
rho_cem: np.ndarray,
|
|
16
|
+
k_fl: np.ndarray,
|
|
17
|
+
rho_fl: np.ndarray,
|
|
18
|
+
por: np.ndarray,
|
|
19
|
+
vp: np.ndarray,
|
|
20
|
+
vs: np.ndarray,
|
|
21
|
+
rhob: np.ndarray,
|
|
22
|
+
file_out_str: str = "constant_cement_optimal_params.pkl",
|
|
23
|
+
display_results: bool = False,
|
|
24
|
+
well_name: str = "Unknown well",
|
|
25
|
+
):
|
|
26
|
+
"""Patchy cement model with optimisation for a selection of parameters.
|
|
27
|
+
|
|
28
|
+
Parameters
|
|
29
|
+
----------
|
|
30
|
+
k_min :
|
|
31
|
+
Cement bulk modulus [Pa].
|
|
32
|
+
mu_min :
|
|
33
|
+
Cement shear modulus [Pa].
|
|
34
|
+
rho_min :
|
|
35
|
+
Cement density [kg/m^3].
|
|
36
|
+
k_cem :
|
|
37
|
+
Cement bulk modulus [Pa].
|
|
38
|
+
mu_cem :
|
|
39
|
+
Cement shear modulus [Pa].
|
|
40
|
+
rho_cem :
|
|
41
|
+
Cement density [kg/m^3].
|
|
42
|
+
k_fl :
|
|
43
|
+
Fluid bulk modulus [Pa].
|
|
44
|
+
rho_fl :
|
|
45
|
+
Fluid density [kg/m^3].
|
|
46
|
+
por :
|
|
47
|
+
Inclusion porosity [ratio].
|
|
48
|
+
vp :
|
|
49
|
+
Compressional velocity log [m/s].
|
|
50
|
+
vs :
|
|
51
|
+
Shear velocity log [m/s].
|
|
52
|
+
rhob :
|
|
53
|
+
Bulk density log [kg/m^3].
|
|
54
|
+
file_out_str :
|
|
55
|
+
Output file name (string) to store optimal parameters (pickle format).
|
|
56
|
+
display_results :
|
|
57
|
+
Display optimal parameters in a window after run.
|
|
58
|
+
well_name :
|
|
59
|
+
Name of well to be displayed in info box title.
|
|
60
|
+
|
|
61
|
+
Returns
|
|
62
|
+
-------
|
|
63
|
+
tuple
|
|
64
|
+
vp_mod, vs_mod - modelled logs, vp_res, vs_res - residual logs.
|
|
65
|
+
"""
|
|
66
|
+
|
|
67
|
+
# Skip hardcoded Vp/Vs ratio
|
|
68
|
+
def_vpvs = np.mean(vp / vs)
|
|
69
|
+
# Set weight to vs to give vp and vs similar influence on optimisation
|
|
70
|
+
y_data = np.stack([vp, vs * def_vpvs], axis=1)
|
|
71
|
+
# Optimisation function for selected parameters
|
|
72
|
+
opt_fun = curvefit_constant_cement
|
|
73
|
+
# expand single value parameters to match logs length
|
|
74
|
+
por, def_vpvs = gen_utilities.dim_check_vector((por, def_vpvs))
|
|
75
|
+
x_data = np.stack(
|
|
76
|
+
(k_min, mu_min, rho_min, k_cem, mu_cem, rho_cem, k_fl, rho_fl, por, def_vpvs),
|
|
77
|
+
axis=1,
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
# Params: weight_k, weight_mu, shear_red, frac_cem
|
|
81
|
+
lower_bound = np.array(
|
|
82
|
+
[
|
|
83
|
+
0.35, # phi_c
|
|
84
|
+
0.0, # shear_red
|
|
85
|
+
0.01, # frac_cem
|
|
86
|
+
],
|
|
87
|
+
dtype=float,
|
|
88
|
+
)
|
|
89
|
+
upper_bound = np.array(
|
|
90
|
+
[
|
|
91
|
+
0.45, # phi_c
|
|
92
|
+
1.0, # shear_red
|
|
93
|
+
0.1, # frac_cem
|
|
94
|
+
],
|
|
95
|
+
dtype=float,
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
x0 = (upper_bound + lower_bound) / 2.0
|
|
99
|
+
# Optimisation step without fluid substitution
|
|
100
|
+
vel_mod, vel_res, opt_params = gen_opt_routine(
|
|
101
|
+
opt_fun, x_data, y_data, x0, lower_bound, upper_bound
|
|
102
|
+
)
|
|
103
|
+
frac_cem = opt_params[2]
|
|
104
|
+
|
|
105
|
+
# Reshape outputs and remove weight from vs
|
|
106
|
+
vp_mod, vs_mod = [arr.flatten() for arr in np.split(vel_mod, 2, axis=1)]
|
|
107
|
+
vp_res, vs_res = [arr.flatten() for arr in np.split(vel_res, 2, axis=1)]
|
|
108
|
+
vs_mod = vs_mod / def_vpvs
|
|
109
|
+
vs_res = vs_res / def_vpvs
|
|
110
|
+
vpvs_mod = vp_mod / vs_mod
|
|
111
|
+
# Calculate the modelled density
|
|
112
|
+
rhob_mod = rho_min * (1.0 - por - frac_cem) + frac_cem * rho_cem + por * rho_fl
|
|
113
|
+
ai_mod = vp_mod * rhob_mod
|
|
114
|
+
rhob_res = rhob_mod - rhob
|
|
115
|
+
# Save the optimal parameters
|
|
116
|
+
save_opt_params("const_cem", opt_params, file_out_str, well_name=well_name)
|
|
117
|
+
if display_results:
|
|
118
|
+
from rock_physics_open.t_matrix_models import opt_param_to_ascii
|
|
119
|
+
|
|
120
|
+
opt_param_to_ascii(file_out_str, well_name=well_name)
|
|
121
|
+
|
|
122
|
+
return vp_mod, vs_mod, rhob_mod, ai_mod, vpvs_mod, vp_res, vs_res, rhob_res
|