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.

Files changed (142) hide show
  1. rock_physics_open/__init__.py +0 -0
  2. rock_physics_open/equinor_utilities/__init__.py +0 -0
  3. rock_physics_open/equinor_utilities/anisotropy.py +162 -0
  4. rock_physics_open/equinor_utilities/classification_functions/__init__.py +17 -0
  5. rock_physics_open/equinor_utilities/classification_functions/class_stats.py +58 -0
  6. rock_physics_open/equinor_utilities/classification_functions/lin_class.py +47 -0
  7. rock_physics_open/equinor_utilities/classification_functions/mahal_class.py +56 -0
  8. rock_physics_open/equinor_utilities/classification_functions/norm_class.py +65 -0
  9. rock_physics_open/equinor_utilities/classification_functions/poly_class.py +40 -0
  10. rock_physics_open/equinor_utilities/classification_functions/post_prob.py +26 -0
  11. rock_physics_open/equinor_utilities/classification_functions/two_step_classification.py +46 -0
  12. rock_physics_open/equinor_utilities/conversions.py +10 -0
  13. rock_physics_open/equinor_utilities/gen_utilities/__init__.py +11 -0
  14. rock_physics_open/equinor_utilities/gen_utilities/dict_to_float.py +33 -0
  15. rock_physics_open/equinor_utilities/gen_utilities/dim_check_vector.py +83 -0
  16. rock_physics_open/equinor_utilities/gen_utilities/filter_input.py +126 -0
  17. rock_physics_open/equinor_utilities/gen_utilities/filter_output.py +78 -0
  18. rock_physics_open/equinor_utilities/machine_learning_utilities/__init__.py +14 -0
  19. rock_physics_open/equinor_utilities/machine_learning_utilities/dummy_vars.py +42 -0
  20. rock_physics_open/equinor_utilities/machine_learning_utilities/exponential_model.py +119 -0
  21. rock_physics_open/equinor_utilities/machine_learning_utilities/import_ml_models.py +61 -0
  22. rock_physics_open/equinor_utilities/machine_learning_utilities/run_regression.py +151 -0
  23. rock_physics_open/equinor_utilities/machine_learning_utilities/sigmoidal_model.py +188 -0
  24. rock_physics_open/equinor_utilities/snapshot_test_utilities/__init__.py +10 -0
  25. rock_physics_open/equinor_utilities/snapshot_test_utilities/compare_snapshots.py +145 -0
  26. rock_physics_open/equinor_utilities/snapshot_test_utilities/snapshots.py +54 -0
  27. rock_physics_open/equinor_utilities/std_functions/__init__.py +43 -0
  28. rock_physics_open/equinor_utilities/std_functions/backus_ave.py +53 -0
  29. rock_physics_open/equinor_utilities/std_functions/dvorkin_nur.py +69 -0
  30. rock_physics_open/equinor_utilities/std_functions/gassmann.py +140 -0
  31. rock_physics_open/equinor_utilities/std_functions/hashin_shtrikman.py +195 -0
  32. rock_physics_open/equinor_utilities/std_functions/hertz_mindlin.py +43 -0
  33. rock_physics_open/equinor_utilities/std_functions/moduli_velocity.py +51 -0
  34. rock_physics_open/equinor_utilities/std_functions/reflection_eq.py +98 -0
  35. rock_physics_open/equinor_utilities/std_functions/rho.py +59 -0
  36. rock_physics_open/equinor_utilities/std_functions/voigt_reuss_hill.py +128 -0
  37. rock_physics_open/equinor_utilities/std_functions/walton.py +38 -0
  38. rock_physics_open/equinor_utilities/std_functions/wood_brie.py +77 -0
  39. rock_physics_open/equinor_utilities/various_utilities/Equinor_logo.gif +0 -0
  40. rock_physics_open/equinor_utilities/various_utilities/Equinor_logo.ico +0 -0
  41. rock_physics_open/equinor_utilities/various_utilities/__init__.py +24 -0
  42. rock_physics_open/equinor_utilities/various_utilities/display_result_statistics.py +83 -0
  43. rock_physics_open/equinor_utilities/various_utilities/gassmann_dry_mod.py +37 -0
  44. rock_physics_open/equinor_utilities/various_utilities/gassmann_mod.py +37 -0
  45. rock_physics_open/equinor_utilities/various_utilities/gassmann_sub_mod.py +53 -0
  46. rock_physics_open/equinor_utilities/various_utilities/hs_average.py +40 -0
  47. rock_physics_open/equinor_utilities/various_utilities/pressure.py +88 -0
  48. rock_physics_open/equinor_utilities/various_utilities/reflectivity.py +85 -0
  49. rock_physics_open/equinor_utilities/various_utilities/timeshift.py +91 -0
  50. rock_physics_open/equinor_utilities/various_utilities/vp_vs_rho_set_statistics.py +154 -0
  51. rock_physics_open/equinor_utilities/various_utilities/vrh_3_min.py +61 -0
  52. rock_physics_open/fluid_models/__init__.py +9 -0
  53. rock_physics_open/fluid_models/brine_model/__init__.py +5 -0
  54. rock_physics_open/fluid_models/brine_model/brine_properties.py +143 -0
  55. rock_physics_open/fluid_models/gas_model/__init__.py +5 -0
  56. rock_physics_open/fluid_models/gas_model/gas_properties.py +277 -0
  57. rock_physics_open/fluid_models/oil_model/__init__.py +5 -0
  58. rock_physics_open/fluid_models/oil_model/dead_oil_density.py +60 -0
  59. rock_physics_open/fluid_models/oil_model/dead_oil_velocity.py +28 -0
  60. rock_physics_open/fluid_models/oil_model/live_oil_density.py +79 -0
  61. rock_physics_open/fluid_models/oil_model/live_oil_velocity.py +24 -0
  62. rock_physics_open/fluid_models/oil_model/oil_bubble_point.py +69 -0
  63. rock_physics_open/fluid_models/oil_model/oil_properties.py +114 -0
  64. rock_physics_open/sandstone_models/__init__.py +57 -0
  65. rock_physics_open/sandstone_models/cemented_shalysand_sandyshale_models.py +304 -0
  66. rock_physics_open/sandstone_models/constant_cement_models.py +204 -0
  67. rock_physics_open/sandstone_models/constant_cement_optimisation.py +122 -0
  68. rock_physics_open/sandstone_models/contact_cement_model.py +138 -0
  69. rock_physics_open/sandstone_models/curvefit_sandstone_models.py +143 -0
  70. rock_physics_open/sandstone_models/friable_models.py +178 -0
  71. rock_physics_open/sandstone_models/friable_optimisation.py +112 -0
  72. rock_physics_open/sandstone_models/friable_shalysand_sandyshale_models.py +235 -0
  73. rock_physics_open/sandstone_models/patchy_cement_fluid_substitution_model.py +477 -0
  74. rock_physics_open/sandstone_models/patchy_cement_model.py +286 -0
  75. rock_physics_open/sandstone_models/patchy_cement_optimisation.py +251 -0
  76. rock_physics_open/sandstone_models/unresolved_cemented_sandshale_models.py +134 -0
  77. rock_physics_open/sandstone_models/unresolved_friable_sandshale_models.py +126 -0
  78. rock_physics_open/shale_models/__init__.py +19 -0
  79. rock_physics_open/shale_models/dem.py +174 -0
  80. rock_physics_open/shale_models/dem_dual_por.py +61 -0
  81. rock_physics_open/shale_models/kus_tok.py +59 -0
  82. rock_physics_open/shale_models/multi_sca.py +133 -0
  83. rock_physics_open/shale_models/pq.py +102 -0
  84. rock_physics_open/shale_models/sca.py +90 -0
  85. rock_physics_open/shale_models/shale4_mineral.py +147 -0
  86. rock_physics_open/shale_models/shale4_mineral_dem_overlay.py +92 -0
  87. rock_physics_open/span_wagner/__init__.py +5 -0
  88. rock_physics_open/span_wagner/co2_properties.py +438 -0
  89. rock_physics_open/span_wagner/coefficients.py +165 -0
  90. rock_physics_open/span_wagner/equations.py +104 -0
  91. rock_physics_open/span_wagner/tables/__init__.py +0 -0
  92. rock_physics_open/span_wagner/tables/carbon_dioxide_density.npz +0 -0
  93. rock_physics_open/span_wagner/tables/lookup_table.py +33 -0
  94. rock_physics_open/t_matrix_models/Equinor_logo.ico +0 -0
  95. rock_physics_open/t_matrix_models/__init__.py +45 -0
  96. rock_physics_open/t_matrix_models/carbonate_pressure_substitution.py +124 -0
  97. rock_physics_open/t_matrix_models/curvefit_t_matrix_exp.py +124 -0
  98. rock_physics_open/t_matrix_models/curvefit_t_matrix_min.py +86 -0
  99. rock_physics_open/t_matrix_models/opt_subst_utilities.py +415 -0
  100. rock_physics_open/t_matrix_models/parse_t_matrix_inputs.py +297 -0
  101. rock_physics_open/t_matrix_models/run_t_matrix.py +243 -0
  102. rock_physics_open/t_matrix_models/t_matrix_C.py +210 -0
  103. rock_physics_open/t_matrix_models/t_matrix_opt_fluid_sub_exp.py +137 -0
  104. rock_physics_open/t_matrix_models/t_matrix_opt_fluid_sub_petec.py +163 -0
  105. rock_physics_open/t_matrix_models/t_matrix_opt_forward_model_exp.py +72 -0
  106. rock_physics_open/t_matrix_models/t_matrix_opt_forward_model_min.py +86 -0
  107. rock_physics_open/t_matrix_models/t_matrix_parameter_optimisation_exp.py +172 -0
  108. rock_physics_open/t_matrix_models/t_matrix_parameter_optimisation_min.py +159 -0
  109. rock_physics_open/t_matrix_models/t_matrix_vector/__init__.py +12 -0
  110. rock_physics_open/t_matrix_models/t_matrix_vector/array_functions.py +75 -0
  111. rock_physics_open/t_matrix_models/t_matrix_vector/calc_c_eff.py +163 -0
  112. rock_physics_open/t_matrix_models/t_matrix_vector/calc_isolated.py +95 -0
  113. rock_physics_open/t_matrix_models/t_matrix_vector/calc_kd.py +40 -0
  114. rock_physics_open/t_matrix_models/t_matrix_vector/calc_kd_eff.py +116 -0
  115. rock_physics_open/t_matrix_models/t_matrix_vector/calc_kd_uuv.py +18 -0
  116. rock_physics_open/t_matrix_models/t_matrix_vector/calc_pressure.py +140 -0
  117. rock_physics_open/t_matrix_models/t_matrix_vector/calc_t.py +71 -0
  118. rock_physics_open/t_matrix_models/t_matrix_vector/calc_td.py +42 -0
  119. rock_physics_open/t_matrix_models/t_matrix_vector/calc_theta.py +43 -0
  120. rock_physics_open/t_matrix_models/t_matrix_vector/calc_x.py +33 -0
  121. rock_physics_open/t_matrix_models/t_matrix_vector/calc_z.py +50 -0
  122. rock_physics_open/t_matrix_models/t_matrix_vector/check_and_tile.py +43 -0
  123. rock_physics_open/t_matrix_models/t_matrix_vector/g_tensor.py +140 -0
  124. rock_physics_open/t_matrix_models/t_matrix_vector/iso_av.py +60 -0
  125. rock_physics_open/t_matrix_models/t_matrix_vector/iso_ave_all.py +55 -0
  126. rock_physics_open/t_matrix_models/t_matrix_vector/pressure_input.py +44 -0
  127. rock_physics_open/t_matrix_models/t_matrix_vector/t_matrix_vec.py +278 -0
  128. rock_physics_open/t_matrix_models/t_matrix_vector/velocity_vti_angles.py +81 -0
  129. rock_physics_open/t_matrix_models/tmatrix_python.dll +0 -0
  130. rock_physics_open/t_matrix_models/tmatrix_python.so +0 -0
  131. rock_physics_open/ternary_plots/__init__.py +3 -0
  132. rock_physics_open/ternary_plots/gen_ternary_plot.py +73 -0
  133. rock_physics_open/ternary_plots/shale_prop_ternary.py +337 -0
  134. rock_physics_open/ternary_plots/ternary_patches.py +277 -0
  135. rock_physics_open/ternary_plots/ternary_plot_utilities.py +197 -0
  136. rock_physics_open/ternary_plots/unconventionals_ternary.py +75 -0
  137. rock_physics_open/version.py +21 -0
  138. rock_physics_open-0.0.dist-info/METADATA +92 -0
  139. rock_physics_open-0.0.dist-info/RECORD +142 -0
  140. rock_physics_open-0.0.dist-info/WHEEL +5 -0
  141. rock_physics_open-0.0.dist-info/licenses/LICENSE +165 -0
  142. 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