rock-physics-open 0.3.2__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.
Files changed (145) 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 +211 -0
  4. rock_physics_open/equinor_utilities/classification_functions/__init__.py +17 -0
  5. rock_physics_open/equinor_utilities/classification_functions/class_stats.py +68 -0
  6. rock_physics_open/equinor_utilities/classification_functions/lin_class.py +53 -0
  7. rock_physics_open/equinor_utilities/classification_functions/mahal_class.py +63 -0
  8. rock_physics_open/equinor_utilities/classification_functions/norm_class.py +73 -0
  9. rock_physics_open/equinor_utilities/classification_functions/poly_class.py +45 -0
  10. rock_physics_open/equinor_utilities/classification_functions/post_prob.py +27 -0
  11. rock_physics_open/equinor_utilities/classification_functions/two_step_classification.py +60 -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 +38 -0
  15. rock_physics_open/equinor_utilities/gen_utilities/dim_check_vector.py +113 -0
  16. rock_physics_open/equinor_utilities/gen_utilities/filter_input.py +131 -0
  17. rock_physics_open/equinor_utilities/gen_utilities/filter_output.py +88 -0
  18. rock_physics_open/equinor_utilities/machine_learning_utilities/__init__.py +15 -0
  19. rock_physics_open/equinor_utilities/machine_learning_utilities/base_pressure_model.py +170 -0
  20. rock_physics_open/equinor_utilities/machine_learning_utilities/dummy_vars.py +53 -0
  21. rock_physics_open/equinor_utilities/machine_learning_utilities/exponential_model.py +137 -0
  22. rock_physics_open/equinor_utilities/machine_learning_utilities/import_ml_models.py +77 -0
  23. rock_physics_open/equinor_utilities/machine_learning_utilities/polynomial_model.py +132 -0
  24. rock_physics_open/equinor_utilities/machine_learning_utilities/run_regression.py +209 -0
  25. rock_physics_open/equinor_utilities/machine_learning_utilities/sigmoidal_model.py +241 -0
  26. rock_physics_open/equinor_utilities/optimisation_utilities/__init__.py +19 -0
  27. rock_physics_open/equinor_utilities/optimisation_utilities/opt_subst_utilities.py +455 -0
  28. rock_physics_open/equinor_utilities/snapshot_test_utilities/__init__.py +10 -0
  29. rock_physics_open/equinor_utilities/snapshot_test_utilities/compare_snapshots.py +184 -0
  30. rock_physics_open/equinor_utilities/snapshot_test_utilities/snapshots.py +97 -0
  31. rock_physics_open/equinor_utilities/std_functions/__init__.py +43 -0
  32. rock_physics_open/equinor_utilities/std_functions/backus_ave.py +68 -0
  33. rock_physics_open/equinor_utilities/std_functions/dvorkin_nur.py +77 -0
  34. rock_physics_open/equinor_utilities/std_functions/gassmann.py +165 -0
  35. rock_physics_open/equinor_utilities/std_functions/hashin_shtrikman.py +224 -0
  36. rock_physics_open/equinor_utilities/std_functions/hertz_mindlin.py +51 -0
  37. rock_physics_open/equinor_utilities/std_functions/moduli_velocity.py +67 -0
  38. rock_physics_open/equinor_utilities/std_functions/reflection_eq.py +120 -0
  39. rock_physics_open/equinor_utilities/std_functions/rho.py +69 -0
  40. rock_physics_open/equinor_utilities/std_functions/voigt_reuss_hill.py +149 -0
  41. rock_physics_open/equinor_utilities/std_functions/walton.py +45 -0
  42. rock_physics_open/equinor_utilities/std_functions/wood_brie.py +94 -0
  43. rock_physics_open/equinor_utilities/various_utilities/Equinor_logo.gif +0 -0
  44. rock_physics_open/equinor_utilities/various_utilities/Equinor_logo.ico +0 -0
  45. rock_physics_open/equinor_utilities/various_utilities/__init__.py +24 -0
  46. rock_physics_open/equinor_utilities/various_utilities/display_result_statistics.py +90 -0
  47. rock_physics_open/equinor_utilities/various_utilities/gassmann_dry_mod.py +56 -0
  48. rock_physics_open/equinor_utilities/various_utilities/gassmann_mod.py +56 -0
  49. rock_physics_open/equinor_utilities/various_utilities/gassmann_sub_mod.py +64 -0
  50. rock_physics_open/equinor_utilities/various_utilities/hs_average.py +59 -0
  51. rock_physics_open/equinor_utilities/various_utilities/pressure.py +96 -0
  52. rock_physics_open/equinor_utilities/various_utilities/reflectivity.py +101 -0
  53. rock_physics_open/equinor_utilities/various_utilities/timeshift.py +104 -0
  54. rock_physics_open/equinor_utilities/various_utilities/vp_vs_rho_set_statistics.py +170 -0
  55. rock_physics_open/equinor_utilities/various_utilities/vrh_3_min.py +83 -0
  56. rock_physics_open/fluid_models/__init__.py +9 -0
  57. rock_physics_open/fluid_models/brine_model/__init__.py +5 -0
  58. rock_physics_open/fluid_models/brine_model/brine_properties.py +178 -0
  59. rock_physics_open/fluid_models/gas_model/__init__.py +5 -0
  60. rock_physics_open/fluid_models/gas_model/gas_properties.py +319 -0
  61. rock_physics_open/fluid_models/oil_model/__init__.py +5 -0
  62. rock_physics_open/fluid_models/oil_model/dead_oil_density.py +65 -0
  63. rock_physics_open/fluid_models/oil_model/dead_oil_velocity.py +30 -0
  64. rock_physics_open/fluid_models/oil_model/live_oil_density.py +82 -0
  65. rock_physics_open/fluid_models/oil_model/live_oil_velocity.py +24 -0
  66. rock_physics_open/fluid_models/oil_model/oil_bubble_point.py +69 -0
  67. rock_physics_open/fluid_models/oil_model/oil_properties.py +146 -0
  68. rock_physics_open/sandstone_models/__init__.py +59 -0
  69. rock_physics_open/sandstone_models/cemented_shalysand_sandyshale_models.py +304 -0
  70. rock_physics_open/sandstone_models/constant_cement_models.py +204 -0
  71. rock_physics_open/sandstone_models/constant_cement_optimisation.py +125 -0
  72. rock_physics_open/sandstone_models/contact_cement_model.py +138 -0
  73. rock_physics_open/sandstone_models/curvefit_sandstone_models.py +143 -0
  74. rock_physics_open/sandstone_models/friable_models.py +177 -0
  75. rock_physics_open/sandstone_models/friable_optimisation.py +115 -0
  76. rock_physics_open/sandstone_models/friable_shalysand_sandyshale_models.py +235 -0
  77. rock_physics_open/sandstone_models/patchy_cement_fluid_substitution_model.py +477 -0
  78. rock_physics_open/sandstone_models/patchy_cement_model.py +384 -0
  79. rock_physics_open/sandstone_models/patchy_cement_optimisation.py +254 -0
  80. rock_physics_open/sandstone_models/unresolved_cemented_sandshale_models.py +134 -0
  81. rock_physics_open/sandstone_models/unresolved_friable_sandshale_models.py +126 -0
  82. rock_physics_open/shale_models/__init__.py +19 -0
  83. rock_physics_open/shale_models/dem.py +174 -0
  84. rock_physics_open/shale_models/dem_dual_por.py +61 -0
  85. rock_physics_open/shale_models/kus_tok.py +59 -0
  86. rock_physics_open/shale_models/multi_sca.py +133 -0
  87. rock_physics_open/shale_models/pq.py +102 -0
  88. rock_physics_open/shale_models/sca.py +90 -0
  89. rock_physics_open/shale_models/shale4_mineral.py +147 -0
  90. rock_physics_open/shale_models/shale4_mineral_dem_overlay.py +92 -0
  91. rock_physics_open/span_wagner/__init__.py +5 -0
  92. rock_physics_open/span_wagner/co2_properties.py +444 -0
  93. rock_physics_open/span_wagner/coefficients.py +165 -0
  94. rock_physics_open/span_wagner/equations.py +104 -0
  95. rock_physics_open/span_wagner/tables/__init__.py +0 -0
  96. rock_physics_open/span_wagner/tables/carbon_dioxide_density.npz +0 -0
  97. rock_physics_open/span_wagner/tables/lookup_table.py +33 -0
  98. rock_physics_open/t_matrix_models/Equinor_logo.ico +0 -0
  99. rock_physics_open/t_matrix_models/__init__.py +35 -0
  100. rock_physics_open/t_matrix_models/carbonate_pressure_substitution.py +124 -0
  101. rock_physics_open/t_matrix_models/curvefit_t_matrix_exp.py +123 -0
  102. rock_physics_open/t_matrix_models/curvefit_t_matrix_min.py +86 -0
  103. rock_physics_open/t_matrix_models/parse_t_matrix_inputs.py +297 -0
  104. rock_physics_open/t_matrix_models/run_t_matrix.py +243 -0
  105. rock_physics_open/t_matrix_models/t_matrix_C.py +210 -0
  106. rock_physics_open/t_matrix_models/t_matrix_opt_fluid_sub_exp.py +137 -0
  107. rock_physics_open/t_matrix_models/t_matrix_opt_fluid_sub_petec.py +167 -0
  108. rock_physics_open/t_matrix_models/t_matrix_opt_forward_model_exp.py +76 -0
  109. rock_physics_open/t_matrix_models/t_matrix_opt_forward_model_min.py +89 -0
  110. rock_physics_open/t_matrix_models/t_matrix_parameter_optimisation_exp.py +176 -0
  111. rock_physics_open/t_matrix_models/t_matrix_parameter_optimisation_min.py +162 -0
  112. rock_physics_open/t_matrix_models/t_matrix_vector/__init__.py +12 -0
  113. rock_physics_open/t_matrix_models/t_matrix_vector/array_functions.py +75 -0
  114. rock_physics_open/t_matrix_models/t_matrix_vector/calc_c_eff.py +163 -0
  115. rock_physics_open/t_matrix_models/t_matrix_vector/calc_isolated.py +95 -0
  116. rock_physics_open/t_matrix_models/t_matrix_vector/calc_kd.py +40 -0
  117. rock_physics_open/t_matrix_models/t_matrix_vector/calc_kd_eff.py +116 -0
  118. rock_physics_open/t_matrix_models/t_matrix_vector/calc_kd_uuv.py +18 -0
  119. rock_physics_open/t_matrix_models/t_matrix_vector/calc_pressure.py +140 -0
  120. rock_physics_open/t_matrix_models/t_matrix_vector/calc_t.py +71 -0
  121. rock_physics_open/t_matrix_models/t_matrix_vector/calc_td.py +42 -0
  122. rock_physics_open/t_matrix_models/t_matrix_vector/calc_theta.py +43 -0
  123. rock_physics_open/t_matrix_models/t_matrix_vector/calc_x.py +33 -0
  124. rock_physics_open/t_matrix_models/t_matrix_vector/calc_z.py +50 -0
  125. rock_physics_open/t_matrix_models/t_matrix_vector/check_and_tile.py +43 -0
  126. rock_physics_open/t_matrix_models/t_matrix_vector/g_tensor.py +140 -0
  127. rock_physics_open/t_matrix_models/t_matrix_vector/iso_av.py +60 -0
  128. rock_physics_open/t_matrix_models/t_matrix_vector/iso_ave_all.py +55 -0
  129. rock_physics_open/t_matrix_models/t_matrix_vector/pressure_input.py +44 -0
  130. rock_physics_open/t_matrix_models/t_matrix_vector/t_matrix_vec.py +278 -0
  131. rock_physics_open/t_matrix_models/t_matrix_vector/velocity_vti_angles.py +81 -0
  132. rock_physics_open/t_matrix_models/tmatrix_python.dll +0 -0
  133. rock_physics_open/t_matrix_models/tmatrix_python.so +0 -0
  134. rock_physics_open/ternary_plots/__init__.py +3 -0
  135. rock_physics_open/ternary_plots/gen_ternary_plot.py +73 -0
  136. rock_physics_open/ternary_plots/shale_prop_ternary.py +337 -0
  137. rock_physics_open/ternary_plots/ternary_patches.py +277 -0
  138. rock_physics_open/ternary_plots/ternary_plot_utilities.py +197 -0
  139. rock_physics_open/ternary_plots/unconventionals_ternary.py +75 -0
  140. rock_physics_open/version.py +34 -0
  141. rock_physics_open-0.3.2.dist-info/METADATA +90 -0
  142. rock_physics_open-0.3.2.dist-info/RECORD +145 -0
  143. rock_physics_open-0.3.2.dist-info/WHEEL +5 -0
  144. rock_physics_open-0.3.2.dist-info/licenses/LICENSE +165 -0
  145. rock_physics_open-0.3.2.dist-info/top_level.txt +1 -0
@@ -0,0 +1,134 @@
1
+ from rock_physics_open import sandstone_models as sm
2
+ from rock_physics_open.equinor_utilities import std_functions
3
+
4
+
5
+ def unresolved_constant_cement_sand_shale_model(
6
+ k_min_sst,
7
+ mu_min_sst,
8
+ rho_min_sst,
9
+ k_cem,
10
+ mu_cem,
11
+ rho_cem,
12
+ k_mud,
13
+ mu_mud,
14
+ rho_mud,
15
+ k_fl_sst,
16
+ rho_fl_sst,
17
+ k_fl_mud,
18
+ rho_fl_mud,
19
+ phi_sst,
20
+ phi_mud,
21
+ p_eff_mud,
22
+ shale_frac,
23
+ frac_cem,
24
+ phi_c_sst,
25
+ phi_c_mud,
26
+ n_sst,
27
+ coord_num_func_mud,
28
+ n_mud,
29
+ shear_red_sst,
30
+ shear_red_mud,
31
+ ):
32
+ """
33
+ Model for silisiclastic rocks with alternating layers of cemented sand and friable shale, and in which the layers
34
+ are not resolved by the investigating signal. Backus average is used to calculate the anisotropic effect of the
35
+ alternating layers.
36
+
37
+ Parameters
38
+ ----------
39
+ k_min_sst : np.ndarray
40
+ Sandstone matrix bulk modulus [Pa].
41
+ mu_min_sst : np.ndarray
42
+ Sandstone matrix shear modulus [Pa].
43
+ rho_min_sst : np.ndarray
44
+ Sandstone matrix bulk density [kg/m^3].
45
+ k_cem : np.ndarray
46
+ Sandstone cement bulk modulus [Pa].
47
+ mu_cem : np.ndarray
48
+ Sandstone cement shear modulus [Pa].
49
+ rho_cem : np.ndarray
50
+ Sandstone cement bulk density [kg/m^3].
51
+ k_mud : np.ndarray
52
+ Shale bulk modulus [Pa].
53
+ mu_mud : np.ndarray
54
+ Shale shear modulus [Pa].
55
+ rho_mud : np.ndarray
56
+ Shale bulk density [kg/m^3].
57
+ k_fl_sst : np.ndarray
58
+ Fluid bulk modulus for sandstone fluid [Pa].
59
+ rho_fl_sst : np.ndarray
60
+ Fluid bulk density for sandstone fluid [kg/m^3].
61
+ k_fl_mud : np.ndarray
62
+ Fluid bulk modulus for shale fluid [Pa].
63
+ rho_fl_mud : np.ndarray
64
+ Fluid bulk density for shale fluid[kg/m^3].
65
+ phi_sst : np.ndarray
66
+ Sandstone porosity [fraction].
67
+ phi_mud : np.ndarray
68
+ Shale porosity [fraction].
69
+ p_eff_mud : np.ndarray
70
+ Effective pressure in mud [Pa].
71
+ shale_frac : np.ndarray
72
+ Shale fraction [fraction].
73
+ frac_cem : float
74
+ Cement volume fraction [fraction].
75
+ phi_c_sst : float
76
+ Critical porosity for sandstone [fraction].
77
+ phi_c_mud : float
78
+ Critical porosity for mud [fraction].
79
+ n_sst : float
80
+ Coordination number for sandstone [unitless].
81
+ n_mud : float
82
+ Coordination number for shale [unitless].
83
+ coord_num_func_mud : str
84
+ Indication if coordination number should be calculated from porosity or kept constant for shale.
85
+ shear_red_sst : float
86
+ Shear reduction factor for sandstone [fraction].
87
+ shear_red_mud : float
88
+ Shear reduction factor for mud [fraction].
89
+
90
+ Returns
91
+ -------
92
+ tuple
93
+ vpv, vsv, vph, vsh, rho : (np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray).
94
+ vertical p-wave velocity, vertical shear-wave velocity, horizontal p-wave velocity, horizontal shear-wave
95
+ velocity (all [m/s]), bulk density [kg/m^3].
96
+ """
97
+ # Estimate the sand end member through the constant cement model
98
+ vp_sst, vs_sst, rho_b_sst = sm.constant_cement_model(
99
+ k_min_sst,
100
+ mu_min_sst,
101
+ rho_min_sst,
102
+ k_cem,
103
+ mu_cem,
104
+ rho_cem,
105
+ k_fl_sst,
106
+ rho_fl_sst,
107
+ phi_sst,
108
+ frac_cem,
109
+ phi_c_sst,
110
+ n_sst,
111
+ shear_red_sst,
112
+ )[0:3]
113
+
114
+ # Estimate the shale end member through the friable model
115
+ vp_mud, vs_mud, rho_b_mud = sm.friable_model(
116
+ k_mud,
117
+ mu_mud,
118
+ rho_mud,
119
+ k_fl_mud,
120
+ rho_fl_mud,
121
+ phi_mud,
122
+ p_eff_mud,
123
+ phi_c_mud,
124
+ coord_num_func_mud,
125
+ n_mud,
126
+ shear_red_mud,
127
+ )[0:3]
128
+
129
+ # Calculate Backus average for the effective medium
130
+ vpv, vsv, vph, vsh, rho = std_functions.backus_average(
131
+ vp_sst, vs_sst, rho_b_sst, vp_mud, vs_mud, rho_b_mud, 1.0 - shale_frac
132
+ )
133
+
134
+ return vpv, vsv, vph, vsh, rho
@@ -0,0 +1,126 @@
1
+ from rock_physics_open import sandstone_models as sm
2
+ from rock_physics_open.equinor_utilities import std_functions
3
+
4
+
5
+ def unresolved_friable_sand_shale_model(
6
+ k_sst,
7
+ mu_sst,
8
+ rho_sst,
9
+ k_mud,
10
+ mu_mud,
11
+ rho_mud,
12
+ k_fl_sst,
13
+ rho_fl_sst,
14
+ k_fl_mud,
15
+ rho_fl_mud,
16
+ phi_sst,
17
+ phi_mud,
18
+ p_eff_sst,
19
+ p_eff_mud,
20
+ shale_frac,
21
+ phi_c_sst,
22
+ phi_c_mud,
23
+ coord_num_func_sst,
24
+ n_sst,
25
+ coord_num_func_mud,
26
+ n_mud,
27
+ shear_red_sst,
28
+ shear_red_mud,
29
+ ):
30
+ """
31
+ Model for siliciclastic rocks with alternating layers of friable sand and shale, and in which the layers are not
32
+ resolved by the investigating signal. Backus average is used to calculate the anisotropic effect of the alternating
33
+ layers.
34
+
35
+ Parameters
36
+ ----------
37
+ k_sst : np.ndarray
38
+ Sandstone bulk modulus [Pa].
39
+ mu_sst : np.ndarray
40
+ Sandstone shear modulus [Pa].
41
+ rho_sst : np.ndarray
42
+ Sandstone bulk density [kg/m^3].
43
+ k_mud : np.ndarray
44
+ Shale bulk modulus [Pa].
45
+ mu_mud : np.ndarray
46
+ Shale shear modulus [Pa].
47
+ rho_mud : np.ndarray
48
+ Shale bulk density [kg/m^3].
49
+ k_fl_sst : np.ndarray
50
+ Fluid bulk modulus for sandstone fluid [Pa].
51
+ rho_fl_sst : np.ndarray
52
+ Fluid bulk density for sandstone fluid [kg/m^3].
53
+ k_fl_mud : np.ndarray
54
+ Fluid bulk modulus for shale fluid [Pa].
55
+ rho_fl_mud : np.ndarray
56
+ Fluid bulk density for shale fluid [kg/m^3].
57
+ phi_sst : np.ndarray
58
+ Sandstone porosity [fraction].
59
+ phi_mud : np.ndarray
60
+ Shale porosity [fraction].
61
+ p_eff_sst : np.ndarray
62
+ Effective pressure in sandstone [Pa].
63
+ p_eff_mud : np.ndarray
64
+ Effective pressure in mud [Pa].
65
+ shale_frac : np.ndarray
66
+ Shale fraction [fraction].
67
+ phi_c_sst : float
68
+ Critical porosity for sandstone [fraction].
69
+ phi_c_mud : float
70
+ Critical porosity for mud [fraction].
71
+ coord_num_func_sst : str
72
+ Indication if coordination number should be calculated from porosity or kept constant for sandstone.
73
+ coord_num_func_mud : str
74
+ Indication if coordination number should be calculated from porosity or kept constant for shale.
75
+ n_sst : float
76
+ Coordination number for sandstone [unitless].
77
+ n_mud : float
78
+ Coordination number for shale [unitless].
79
+ shear_red_sst : float
80
+ Shear reduction factor for sandstone [fraction].
81
+ shear_red_mud : float
82
+ Shear reduction factor for mud [fraction].
83
+
84
+ Returns
85
+ -------
86
+ tuple
87
+ vpv, vsv, vph, vsh, rho : (np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray).
88
+ vertical p-wave velocity, vertical shear-wave velocity, horizontal p-wave velocity, horizontal shear-wave
89
+ velocity (all [m/s]), bulk density [kg/m^3].
90
+ """
91
+
92
+ # Estimate the sand and shale end members through the friable models
93
+ vp_sst, vs_sst, rho_b_sst = sm.friable_model(
94
+ k_sst,
95
+ mu_sst,
96
+ rho_sst,
97
+ k_fl_sst,
98
+ rho_fl_sst,
99
+ phi_sst,
100
+ p_eff_sst,
101
+ phi_c_sst,
102
+ coord_num_func_sst,
103
+ n_sst,
104
+ shear_red_sst,
105
+ )[0:3]
106
+
107
+ vp_mud, vs_mud, rho_b_mud = sm.friable_model(
108
+ k_mud,
109
+ mu_mud,
110
+ rho_mud,
111
+ k_fl_mud,
112
+ rho_fl_mud,
113
+ phi_mud,
114
+ p_eff_mud,
115
+ phi_c_mud,
116
+ coord_num_func_mud,
117
+ n_mud,
118
+ shear_red_mud,
119
+ )[0:3]
120
+
121
+ # Calculate Backus average for the effective medium
122
+ vpv, vsv, vph, vsh, rho = std_functions.backus_average(
123
+ vp_sst, vs_sst, rho_b_sst, vp_mud, vs_mud, rho_b_mud, 1.0 - shale_frac
124
+ )
125
+
126
+ return vpv, vsv, vph, vsh, rho
@@ -0,0 +1,19 @@
1
+ from .dem import dem_model
2
+ from .dem_dual_por import dem_model_dual_por
3
+ from .kus_tok import kuster_toksoz_model
4
+ from .multi_sca import multi_sca
5
+ from .pq import p_q_fcn
6
+ from .sca import self_consistent_approximation_model
7
+ from .shale4_mineral import shale_model_4_mineral_dem
8
+ from .shale4_mineral_dem_overlay import shale_4_min_dem_overlay
9
+
10
+ __all__ = [
11
+ "dem_model",
12
+ "dem_model_dual_por",
13
+ "kuster_toksoz_model",
14
+ "multi_sca",
15
+ "p_q_fcn",
16
+ "self_consistent_approximation_model",
17
+ "shale_model_4_mineral_dem",
18
+ "shale_4_min_dem_overlay",
19
+ ]
@@ -0,0 +1,174 @@
1
+ import sys
2
+
3
+ import numpy as np
4
+ from scipy.integrate import odeint
5
+
6
+ from .pq import p_q_fcn
7
+
8
+
9
+ def dem_model(k1, mu1, rho1, k2, mu2, rho2, frac2, asp2, tol):
10
+ """
11
+ DEM - Effective elastic moduli using Differential Effective Medium formulation.
12
+
13
+ Parameters
14
+ ----------
15
+ k1 : np.ndarray
16
+ Bulk modulus of background matrix [Pa].
17
+ mu1 : np.ndarray
18
+ Shear modulus of background matrix [Pa].
19
+ rho1 : np.ndarray
20
+ Bulk density of background matrix [kg/m^3].
21
+ k2 : np.ndarray
22
+ Bulk modulus of inclusions [Pa].
23
+ mu2 : np.ndarray
24
+ Shear modulus of inclusions [Pa].
25
+ rho2 : np.ndarray
26
+ Bulk density of inclusions [kg/m^3].
27
+ frac2 : np.ndarray
28
+ Fraction of inclusions [fraction].
29
+ asp2 : np.ndarray
30
+ Aspect ratio of inclusions [ratio].
31
+ tol: float
32
+ Desired accuracy in the ODE solver.
33
+
34
+ Returns
35
+ -------
36
+ tuple
37
+ k, mu, rho : (np.ndarray, np.ndarray, np.ndarray).
38
+ k: effective medium bulk modulus [Pa], mu: effective medium shear modulus [Pa], rho: bulk density [kg/m^3].
39
+
40
+ Comments
41
+ --------
42
+ Written by T. Mukerji, SRB, Stanford University.
43
+ Ported to Python by Harald Flesche, Equinor 2015.
44
+ """
45
+
46
+ # Make sure all log inputs are vectors, expand scalars, throw error if uneven
47
+ # length and not scalars
48
+ k = np.ones(k1.shape) * np.nan
49
+ mu = np.ones(k1.shape) * np.nan
50
+ rhob = rho1 * (1 - frac2) + rho2 * frac2
51
+
52
+ # Check for the trivial cases: all inclusions or all matrix
53
+ idx = np.logical_or(frac2 == 1.0, frac2 == 0.0)
54
+ if np.any(idx):
55
+ idx1 = frac2 == 1.0
56
+ idx2 = frac2 == 0.0
57
+ if np.any(idx1):
58
+ k[idx1] = k2[idx1]
59
+ mu[idx1] = mu2[idx1]
60
+ if np.any(idx2):
61
+ k[idx2] = k1[idx2]
62
+ mu[idx2] = mu1[idx2]
63
+ if np.all(idx):
64
+ return k, mu, rhob
65
+
66
+ # Need to run the DEM model for cases that are mixed
67
+ idx1 = ~idx
68
+ frac2 = frac2[idx1]
69
+
70
+ # Only need to run the ODE on different initial conditions
71
+ uni, idx_restore = np.unique(
72
+ np.stack((k1[idx1], mu1[idx1], k2[idx1], mu2[idx1]), axis=1),
73
+ return_inverse=True,
74
+ axis=0,
75
+ )
76
+ k1, mu1, k2, mu2 = np.split(uni, 4, axis=1)
77
+ # Must flatten arrays to avoid problems with dimensions
78
+ k1 = k1.flatten()
79
+ k2 = k2.flatten()
80
+ mu1 = mu1.flatten()
81
+ mu2 = mu2.flatten()
82
+
83
+ k_vec = np.zeros(len(idx_restore))
84
+ mu_vec = np.zeros(len(idx_restore))
85
+
86
+ tot = k1.shape[0]
87
+
88
+ # Must run ODE solver with values in increasing order, and must start at zero value
89
+ i_x = np.argsort(frac2)
90
+ frac2 = frac2[i_x]
91
+ frac2 = np.insert(frac2, 0, 0)
92
+ # Find reverse order
93
+ i_y = np.argsort(i_x)
94
+
95
+ # Too many data points create memory problems for ODE solver, set limit at lim = 1000
96
+ lim = 1000
97
+ runs = 1 if tot <= lim else tot // lim + 1
98
+ for i in range(runs):
99
+ start_i = i * lim
100
+ end_i = min(tot, (i + 1) * lim)
101
+
102
+ # Select part to run, cast to array in case it defaults to single value
103
+ k1_tmp = np.array(k1[start_i:end_i])
104
+ mu1_tmp = np.array(mu1[start_i:end_i])
105
+ k2_tmp = np.array(k2[start_i:end_i])
106
+ mu2_tmp = np.array(mu2[start_i:end_i])
107
+ asp2_tmp = np.array(asp2[start_i:end_i])
108
+
109
+ y0 = np.concatenate((k1_tmp, mu1_tmp))
110
+
111
+ try:
112
+ y_out = odeint(
113
+ _demy_prime, y0, frac2, args=(k2_tmp, mu2_tmp, asp2_tmp), rtol=tol
114
+ )
115
+ except ValueError:
116
+ raise ValueError(sys.exc_info())
117
+
118
+ # Remove inserted zero-value in row 0, split output in k and mu
119
+ # Pycharm reports wrong object type here, checked and found to be OK
120
+ k_out, mu_out = np.split(y_out[1:, :], 2, axis=1)
121
+
122
+ # Reorder rows back to original sequence of fraction values
123
+ k_out = k_out[i_y, :]
124
+ mu_out = mu_out[i_y, :]
125
+
126
+ # Select correct column for the row values
127
+ idx_pres_range = np.logical_and(idx_restore >= start_i, idx_restore < end_i)
128
+ for j in range(len(idx_restore)):
129
+ if idx_pres_range[j]:
130
+ k_vec[j] = k_out[j, idx_restore[j] - start_i]
131
+ mu_vec[j] = mu_out[j, idx_restore[j] - start_i]
132
+
133
+ k[idx1] = k_vec
134
+ mu[idx1] = mu_vec
135
+
136
+ return k, mu, rhob
137
+
138
+
139
+ def _demy_prime(y, t, k2, mu2, asp2):
140
+ """
141
+ Used by DEM model.
142
+
143
+ Parameters
144
+ ----------
145
+ y : np.ndarray
146
+ y array.
147
+ t : float
148
+ t float.
149
+ k2 : np.ndarray
150
+ Bulk modulus of inclusions [Pa].
151
+ mu2 : np.ndarray
152
+ Shear modulus of inclusions [Pa].
153
+ asp2 : np.ndarray
154
+ Aspect ratio of inclusions [ratio].
155
+
156
+ Returns
157
+ -------
158
+ np.ndarray
159
+ k, mu array.
160
+
161
+ Comments
162
+ --------
163
+ Written by T. Mukerji, Stanford University.
164
+ Rewritten in Python by Harald Flesche, Equinor 2015.
165
+ """
166
+ # Input value vector consists of both k and mu values
167
+ k, mu = np.split(y, 2)
168
+
169
+ p, q = p_q_fcn(k, mu, k2, mu2, asp2)
170
+
171
+ k_r_hs = (k2 - k) * p / (1 - t)
172
+ mu_r_hs = (mu2 - mu) * q / (1 - t)
173
+
174
+ return np.concatenate((k_r_hs, mu_r_hs))
@@ -0,0 +1,61 @@
1
+ from .dem import dem_model
2
+
3
+
4
+ def dem_model_dual_por(
5
+ k1, mu1, rho1, k2, mu2, rho2, k3, mu3, rho3, frac_inc, frac_inc_1, asp_1, asp_2, tol
6
+ ):
7
+ """Differential effective media model with two sets of inclusions.
8
+
9
+ Parameters
10
+ ----------
11
+ k1 : np.ndarray
12
+ Matrix bulk modulus [Pa].
13
+ mu1 : np.ndarray
14
+ Matrix shear modulus [Pa].
15
+ rho1 : np.ndarray
16
+ Matrix bulk density [kg/m^3].
17
+ k2 : np.ndarray
18
+ Inclusion 1 bulk modulus [Pa].
19
+ mu2 : np.ndarray
20
+ Inclusion 1 shear modulus [Pa].
21
+ rho2 : np.ndarray
22
+ Inclusion 1 bulk density [kg/m^3]
23
+ k3 : np.ndarray
24
+ Inclusion 2 bulk modulus [Pa].
25
+ mu3 : np.ndarray
26
+ Inclusion 2 shear modulus [Pa].
27
+ rho3 : np.ndarray
28
+ Inclusion 2 bulk density [kg/m^3].
29
+ frac_inc : np.ndarray
30
+ Total fraction of inclusions [fraction].
31
+ frac_inc_1 : np.ndarray
32
+ Fraction of inclusions belonging to type 1 [fraction].
33
+ asp_1 : np.ndarray
34
+ Aspect ratio of inclusion 1 [fraction].
35
+ asp_2 : np.ndarray
36
+ Aspect ratio of inclusion 2 [fraction].
37
+ tol : float
38
+ Tolerance of accuracy [unitless].
39
+
40
+ Returns
41
+ -------
42
+ tuple
43
+ k_dem_dual: bulk modulus [Pa], mu_dem_dual: shear modulus [Pa], rhob_dem_dual: bulk density [kg/m^3].
44
+ """
45
+ # Include the Type 1 inclusions into the matrix first, then run again with inclusions Type 2
46
+ k_dem1, mu_dem1, rhob_dem1 = dem_model(
47
+ k1, mu1, rho1, k2, mu2, rho2, frac_inc * frac_inc_1, asp_1, tol
48
+ )
49
+ k_dem_dual, mu_dem_dual, rhob_dem_dual = dem_model(
50
+ k_dem1,
51
+ mu_dem1,
52
+ rhob_dem1,
53
+ k3,
54
+ mu3,
55
+ rho3,
56
+ frac_inc * (1.0 - frac_inc_1),
57
+ asp_2,
58
+ tol,
59
+ )
60
+
61
+ return k_dem_dual, mu_dem_dual, rhob_dem_dual
@@ -0,0 +1,59 @@
1
+ import warnings
2
+
3
+ import numpy as np
4
+
5
+ from .pq import p_q_fcn
6
+
7
+
8
+ def kuster_toksoz_model(k1, mu1, rho1, k2, mu2, rho2, frac1, asp2):
9
+ """Simplified Kuster-Toksoz model for single mineral inclusion with single aspect ratio.
10
+
11
+ Parameters
12
+ ----------
13
+ k1 : np.ndarray
14
+ Phase 1 bulk modulus [Pa].
15
+ mu1 : np.ndarray
16
+ Phase 1 shear modulus [Pa].
17
+ rho1 : np.ndarray
18
+ Phase 1 bulk density [kg/m^3].
19
+ k2 : np.ndarray
20
+ Phase 2 bulk modulus [Pa].
21
+ mu2 : np.ndarray
22
+ Phase 2 shear modulus [Pa].
23
+ rho2 : np.ndarray
24
+ Phase 2 bulk density [kg/m^3].
25
+ frac1 : np.ndarray
26
+ Fraction of phase 1 [fraction].
27
+ asp2 : np.ndarray
28
+ Aspect ratio for phase 2 inclusions [ratio].
29
+
30
+ Returns
31
+ -------
32
+ tuple
33
+ k_kt, mu_kt, rhob : (np.ndarray, np.ndarray, np.ndarray).
34
+ effective media properties: k_kt: bulk modulus [Pa], mu_kt: shear modulus [Pa], rhob: bulk density [kg/m^3].
35
+ """
36
+ frac2 = 1.0 - frac1
37
+ rhob = rho1 * frac1 + rho2 * frac2
38
+ p, q = p_q_fcn(k1, mu1, k2, mu2, asp2)
39
+ zeta = mu1 / 6.0 * (9.0 * k1 + 8.0 * mu1) / (k1 + 2.0 * mu1)
40
+
41
+ k_kt = (k1 * (k1 + 4.0 / 3.0 * mu1) + 4.0 / 3.0 * mu1 * frac2 * (k2 - k1) * p) / (
42
+ k1 + 4.0 / 3.0 * mu1 - frac2 * (k2 - k1) * p
43
+ )
44
+ mu_kt = (mu1 * (mu1 + zeta) + zeta * frac2 * (mu2 - mu1) * q) / (
45
+ mu1 + zeta - frac2 * (mu2 - mu1) * q
46
+ )
47
+
48
+ # Non-physical situations can arise if there is too high volume fraction of inclusions with
49
+ # low aspect ratio
50
+ idx_neg = np.logical_or(k_kt < 0.0, mu_kt < 0.0)
51
+ if np.any(idx_neg):
52
+ k_kt[idx_neg] = np.nan
53
+ mu_kt[idx_neg] = np.nan
54
+ rhob[idx_neg] = np.nan
55
+ warnings.warn(
56
+ f"{__file__}: {np.sum(idx_neg)} non-physical solutions to Kuster-Toksöz equation"
57
+ )
58
+
59
+ return k_kt, mu_kt, rhob
@@ -0,0 +1,133 @@
1
+ import numpy as np
2
+
3
+ from rock_physics_open.equinor_utilities.gen_utilities import dim_check_vector
4
+
5
+ from .pq import p_q_fcn
6
+
7
+
8
+ def multi_sca(*args, tol):
9
+ """SCA - Effective elastic moduli using Berryman's Self-Consistent
10
+ (Coherent Potential Approximation) method.
11
+
12
+ -----------------------------------------------
13
+
14
+ Inputs for each phase:
15
+
16
+ k: mineral bulk modulus [Pa]
17
+
18
+ mu: mineral shear modulus [Pa]
19
+
20
+ rho: mineral density [kg/m^3]
21
+
22
+ asp: aspect ratio for inclusions [ratio]
23
+
24
+ frac: fraction of matrix that is made up of this mineral [fraction]
25
+
26
+ Additional inputs:
27
+
28
+ tol: tolerance parameter (scalar) [unitless]
29
+
30
+ The sum of all fractions must add to one, and it will be normalised to one if it differs.
31
+
32
+ =======================================================
33
+
34
+ Based on function by T. Mukerji, SRB, Stanford University, 1994.
35
+
36
+ Ported to Python by Harald Flesche, Equinor 2015.
37
+
38
+ Parameters
39
+ ----------
40
+ args : list or tuple
41
+ List or tuple containing multiples of elastic properties as explained above, all numpy arrays.
42
+ tol : float
43
+ Tolerance for the SCA iterations.
44
+
45
+ Returns
46
+ -------
47
+ tuple
48
+ k_sc, mu_sc, rhob : (np.ndarray, np.ndarray, np.ndarray).
49
+ effective medium properties k_sc: bulk modulus [Pa], mu_sc: shear modulus [Pa], rhob: bulk density [kg/m^3].
50
+ """
51
+ if len(args) % 5 != 0:
52
+ raise ValueError(
53
+ "Call function with (k_sc,mu_sc,rhob) = multi_sca((k1,mu1,rho1,asp1,frac1, ...,k_n,mu_n,rho_n,asp_n,"
54
+ "frac_n,tol)). Fractions must add up to 1.0"
55
+ )
56
+
57
+ args = dim_check_vector(args)
58
+
59
+ # Proceed without the parameter, all other inputs should be arrays
60
+
61
+ n_mins = len(args) // 5
62
+
63
+ # Sort inputs
64
+ k_min = []
65
+ mu_min = []
66
+ rho_min = []
67
+ frac = []
68
+ asp = []
69
+
70
+ for i in range(n_mins):
71
+ k_min.append(args[5 * i])
72
+ mu_min.append(args[5 * i + 1])
73
+ rho_min.append(args[5 * i + 2])
74
+ asp.append(args[5 * i + 3])
75
+ frac.append(args[5 * i + 4])
76
+
77
+ # Check and normalise frac
78
+ tot_frac = np.sum(np.vstack(frac[:]), 0)
79
+ if np.any(tot_frac != 1.0):
80
+ for i in range(n_mins):
81
+ frac[i] = frac[i] / tot_frac
82
+
83
+ # Initiate k_sc and mu_sc with weighted sum of phases
84
+ k_sc = np.sum(np.vstack(k_min[:]) * np.vstack(frac[:]), 0)
85
+ mu_sc = np.sum(np.vstack(mu_min[:]) * np.vstack(frac[:]), 0)
86
+ rhob = np.sum(np.vstack(rho_min[:]) * np.vstack(frac[:]), 0)
87
+
88
+ idx = np.any(np.vstack(frac[:]) == 1.0, 0)
89
+ if np.any(idx):
90
+ # If any of the samples contain 100% of one phase - substitute the result
91
+ # with the mineral properties of that phase
92
+ for i in range(n_mins):
93
+ idx1 = frac[i] == 1.0
94
+ if np.any(idx1):
95
+ k_sc[idx1] = k_min[i][idx1]
96
+ mu_sc[idx1] = mu_min[i][idx1]
97
+ # Continue with the real mixtures
98
+ k_min[i] = k_min[i][~idx]
99
+ mu_min[i] = mu_min[i][~idx]
100
+ asp[i] = asp[i][~idx]
101
+ frac[i] = frac[i][~idx]
102
+ if not np.all(idx):
103
+ niter = 0
104
+ # Initiate the delta with a value that makes the while-loop run
105
+ delta = k_sc[~idx]
106
+ # Express tolerance in terms of k0
107
+ tol = tol * k_min[0]
108
+
109
+ # Iterate until delta is less than the tolerance and the loop has run for
110
+ # less than 3000 iterations (normally far less)
111
+ while np.any(np.logical_and(np.greater(delta, tol), np.less(niter, 3000))):
112
+ p = []
113
+ q = []
114
+ for i in range(n_mins):
115
+ p_tmp, q_tmp = p_q_fcn(
116
+ k_sc[~idx], mu_sc[~idx], k_min[i], mu_min[i], asp[i]
117
+ )
118
+ p.append(p_tmp)
119
+ q.append(q_tmp)
120
+ k_new = np.sum(
121
+ np.vstack(frac[:]) * np.vstack(k_min[:]) * np.vstack(p[:]), 0
122
+ ) / np.sum(np.vstack(frac[:]) * np.vstack(p[:]), 0)
123
+ mu_new = np.sum(
124
+ np.vstack(frac[:]) * np.vstack(mu_min[:]) * np.vstack(q[:]), 0
125
+ ) / np.sum(np.vstack(frac[:]) * np.vstack(q[:]), 0)
126
+
127
+ delta = np.absolute(k_sc[~idx] - k_new)
128
+ k_sc[~idx] = k_new
129
+ mu_sc[~idx] = mu_new
130
+
131
+ niter = niter + 1
132
+
133
+ return k_sc, mu_sc, rhob