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,140 @@
1
+ import numpy as np
2
+
3
+ from .array_functions import array_matrix_mult
4
+
5
+
6
+ def g_tensor_vec(c0, s_0, alpha):
7
+ """Returns the Eshelby green's tensor (nx6x6 array).
8
+
9
+ Parameters
10
+ ----------
11
+ c0 : np.ndarray
12
+ n stiffness tensors of the host material (nx6x6 array).
13
+ s_0 : np.ndarray
14
+ Inverse of stiffness tensor.
15
+ alpha : float
16
+ Aspect ratio for single inclusion.
17
+
18
+ Returns
19
+ -------
20
+ np.ndarray
21
+ g-tensor.
22
+
23
+ Raises
24
+ ------
25
+ ValueError
26
+ If mismatch in input dimension/shape.
27
+ """
28
+ if not (
29
+ c0.ndim == 3
30
+ and c0.shape[1] == c0.shape[2]
31
+ and s_0.ndim == 3
32
+ and s_0.shape[1] == s_0.shape[2]
33
+ ):
34
+ raise ValueError(f"{__name__}: mismatch in inputs variables dimension/shape")
35
+
36
+ log_len = c0.shape[0]
37
+ mu = c0[:, 3, 3] / 2
38
+ kappa = c0[:, 0, 0] - (4 / 3) * mu
39
+ pois_ratio = (3 * kappa - 2 * mu) / (2 * (3 * kappa + mu))
40
+
41
+ s_r = np.zeros(c0.shape)
42
+
43
+ s_11 = np.zeros(log_len)
44
+ s_12 = np.zeros(log_len)
45
+ s_13 = np.zeros(log_len)
46
+ s_21 = np.zeros(log_len)
47
+ s_22 = np.zeros(log_len)
48
+ s_23 = np.zeros(log_len)
49
+ s_31 = np.zeros(log_len)
50
+ s_32 = np.zeros(log_len)
51
+ s_33 = np.zeros(log_len)
52
+ s_44 = np.zeros(log_len)
53
+ s_55 = np.zeros(log_len)
54
+ s_66 = np.zeros(log_len)
55
+
56
+ if isinstance(alpha, float):
57
+ alpha = np.ones(log_len) * alpha
58
+ # Check for valid range of alpha - those outside are returned with zero matrices
59
+ idx_in = (alpha >= 0) & (alpha < 1)
60
+ idx_one = alpha == 1
61
+ alpha_in = alpha[idx_in]
62
+ pois_ratio_in = pois_ratio[idx_in]
63
+ pois_ratio_one = pois_ratio[idx_one]
64
+
65
+ if np.any(idx_in):
66
+ q = (alpha_in / (1 - alpha_in**2) ** (3 / 2)) * (
67
+ np.arccos(alpha_in) - alpha_in * (1 - alpha_in**2) ** (1 / 2)
68
+ )
69
+ s_11[idx_in] = (3 / (8 * (1 - pois_ratio_in))) * (
70
+ alpha_in**2 / (alpha_in**2 - 1)
71
+ ) + (1 / (4 * (1 - pois_ratio_in))) * (
72
+ 1 - 2 * pois_ratio_in - 9 / (4 * (alpha_in**2 - 1))
73
+ ) * q
74
+ s_33[idx_in] = (1 / (2 * (1 - pois_ratio_in))) * (
75
+ 1
76
+ - 2 * pois_ratio_in
77
+ + (3 * alpha_in**2 - 1) / (alpha_in**2 - 1)
78
+ - (1 - 2 * pois_ratio_in + 3 * alpha_in**2 / (alpha_in**2 - 1)) * q
79
+ )
80
+ s_12[idx_in] = (1 / (4 * (1 - pois_ratio_in))) * (
81
+ alpha_in**2 / (2 * (alpha_in**2 - 1))
82
+ - (1 - 2 * pois_ratio_in + 3 / (4 * (alpha_in**2 - 1))) * q
83
+ )
84
+ s_13[idx_in] = (1 / (2 * (1 - pois_ratio_in))) * (
85
+ -(alpha_in**2) / (alpha_in**2 - 1)
86
+ + 0.5 * (3 * alpha_in**2 / (alpha_in**2 - 1) - (1 - 2 * pois_ratio_in)) * q
87
+ )
88
+ s_31[idx_in] = (1 / (2 * (1 - pois_ratio_in))) * (
89
+ 2 * pois_ratio_in
90
+ - 1
91
+ - 1 / (alpha_in**2 - 1)
92
+ + (1 - 2 * pois_ratio_in + 3 / (2 * (alpha_in**2 - 1))) * q
93
+ )
94
+ s_66[idx_in] = (1 / (4 * (1 - pois_ratio_in))) * (
95
+ alpha_in**2 / (2 * (alpha_in**2 - 1))
96
+ + (1 - 2 * pois_ratio_in - 3 / (4 * (alpha_in**2 - 1))) * q
97
+ )
98
+ s_44[idx_in] = (1 / (4 * (1 - pois_ratio_in))) * (
99
+ 1
100
+ - 2 * pois_ratio_in
101
+ - (alpha_in**2 + 1) / (alpha_in**2 - 1)
102
+ - 0.5
103
+ * (1 - 2 * pois_ratio_in - (3 * (alpha_in**2 + 1)) / (alpha_in**2 - 1))
104
+ * q
105
+ )
106
+ s_22[idx_in] = s_11[idx_in]
107
+ s_21[idx_in] = s_12[idx_in]
108
+ s_23[idx_in] = s_13[idx_in]
109
+ s_32[idx_in] = s_31[idx_in]
110
+ s_55[idx_in] = s_44[idx_in]
111
+ if np.any(idx_one):
112
+ s_11[idx_one] = (5 * pois_ratio_one - 1) / (15 * (1 - pois_ratio_one)) + (
113
+ 2 * (4 - 5 * pois_ratio_one)
114
+ ) / (15 * (1 - pois_ratio_one))
115
+ s_12[idx_one] = (5 * pois_ratio_one - 1) / (15 * (1 - pois_ratio_one))
116
+ s_13[idx_one] = (5 * pois_ratio_one - 1) / (15 * (1 - pois_ratio_one))
117
+ s_31[idx_one] = (5 * pois_ratio_one - 1) / (15 * (1 - pois_ratio_one))
118
+ s_44[idx_one] = (4 - 5 * pois_ratio_one) / (15 * (1 - pois_ratio_one))
119
+ s_22[idx_one] = s_11[idx_one]
120
+ s_33[idx_one] = s_11[idx_one]
121
+ s_21[idx_one] = s_12[idx_one]
122
+ s_32[idx_one] = s_31[idx_one]
123
+ s_23[idx_one] = s_13[idx_one]
124
+ s_55[idx_one] = s_44[idx_one]
125
+ s_66[idx_one] = s_44[idx_one]
126
+
127
+ s_r[:, 0, 0] = s_11
128
+ s_r[:, 1, 1] = s_22
129
+ s_r[:, 2, 2] = s_33
130
+ s_r[:, 3, 3] = 2 * s_44
131
+ s_r[:, 4, 4] = 2 * s_55
132
+ s_r[:, 5, 5] = 2 * s_66
133
+ s_r[:, 0, 1] = s_12
134
+ s_r[:, 0, 2] = s_13
135
+ s_r[:, 1, 0] = s_21
136
+ s_r[:, 1, 2] = s_23
137
+ s_r[:, 2, 0] = s_31
138
+ s_r[:, 2, 1] = s_32
139
+
140
+ return array_matrix_mult(-s_r, s_0)
@@ -0,0 +1,60 @@
1
+ import numpy as np
2
+
3
+
4
+ def iso_av_vec(t):
5
+ """Returns a (nx6x6) matrix t_bar averaged over all the orientations (isotropy).
6
+
7
+
8
+ t_bar = np.array([
9
+
10
+ [c11, c12, c12, 0, 0, 0],
11
+
12
+ [c12, c11, c12, 0, 0, 0],
13
+
14
+ [c12, c12, c11, 0, 0, 0],
15
+
16
+ [0, 0, 0, 2 * c44, 0, 0],
17
+
18
+ [0, 0, 0, 0, 2 * c44, 0],
19
+
20
+ [0, 0, 0, 0, 0, 2 * c44]
21
+
22
+ ])
23
+
24
+
25
+ Parameters
26
+ ----------
27
+ t : np.ndarray
28
+ An nx6x6 matrix which has a HTI symmetry.
29
+
30
+
31
+ Returns
32
+ -------
33
+ np.ndarray
34
+ Averaged value.
35
+ """
36
+ t_bar = np.zeros(t.shape)
37
+
38
+ lambda_var = (
39
+ t[:, 0, 0] + t[:, 2, 2] + 5 * t[:, 0, 1] + 8 * t[:, 0, 2] - 2 * t[:, 3, 3]
40
+ ) / 15
41
+ mu = (
42
+ 7 * t[:, 0, 0]
43
+ + 2 * t[:, 2, 2]
44
+ - 5 * t[:, 0, 1]
45
+ - 4 * t[:, 0, 2]
46
+ + 6 * t[:, 3, 3]
47
+ ) / 30
48
+ c11 = lambda_var + 2 * mu
49
+ c12 = lambda_var
50
+ c44 = mu
51
+
52
+ for i in range(3):
53
+ t_bar[:, i, i] = c11
54
+ t_bar[:, i + 3, i + 3] = 2 * c44
55
+ for i in range(2):
56
+ t_bar[:, 0, i + 1] = c12
57
+ t_bar[:, 1, 2 * i] = c12
58
+ t_bar[:, 2, i] = c12
59
+
60
+ return t_bar
@@ -0,0 +1,55 @@
1
+ import numpy as np
2
+
3
+ from .iso_av import iso_av_vec
4
+
5
+
6
+ def iso_av_all_vec(x, case_iso):
7
+ """Returns an multi dimensional matrix with isotropic elements. (nx6x6x(numbers of inclusions) matrix).
8
+ Not used in the present implementation - direct call to iso_av_vec from main function instead
9
+
10
+
11
+ Parameters
12
+ ----------
13
+ x : np.ndarray
14
+ An nx6x6x(numbers of inclusions) matrix.
15
+ case_iso : int
16
+ Control parameter.
17
+
18
+ Returns
19
+ -------
20
+ np.ndarray,
21
+ Isotropic values.
22
+
23
+ Examples
24
+ --------
25
+ caseIso : control parameter
26
+ if caseIso = 0 then all the pore types are isotropic,
27
+ if caseIso = 1 then there is a mix of isotropic and anisotropic pores,
28
+ if caseIso = 2 then all the pore types are anisotropic.
29
+
30
+ Notes
31
+ -----
32
+ HFLE 01.11.2020: Anisotropic inclusions are set to have the same aspect ratio as the isotropic ones.
33
+ """
34
+ if not (x.ndim == 4 and x.shape[1] == x.shape[2]):
35
+ raise ValueError(f"{__name__}: mismatch in inputs variables dimension/shape")
36
+
37
+ no_inclusions = x.shape[3]
38
+ x_iso = np.zeros(x.shape)
39
+
40
+ # if caseIso = 0 then all the pore types are isotropic
41
+ if case_iso == 0:
42
+ for j in range(no_inclusions):
43
+ x_iso[:, :, j] = iso_av_vec(x[:, :, j])
44
+ # if caseIso = 1 then all the pore types are isotropic
45
+ elif case_iso == 1:
46
+ for j in range(no_inclusions):
47
+ x_iso[:, :, j] = iso_av_vec(x[:, :, j])
48
+
49
+ x_iso[:, :, (no_inclusions // 2) : no_inclusions] = x[
50
+ :, :, (no_inclusions // 2) : no_inclusions
51
+ ]
52
+ elif case_iso == 2:
53
+ x_iso = x
54
+
55
+ return x_iso
@@ -0,0 +1,44 @@
1
+ import numpy as np
2
+
3
+ from .array_functions import array_inverse, array_matrix_mult
4
+ from .g_tensor import g_tensor_vec
5
+
6
+
7
+ def pressure_input_utility(k_min, mu_min, log_length):
8
+ """Utility that calculates some of the elastic properties needed for T-Matrix pressure estimation.
9
+
10
+ Parameters
11
+ ----------
12
+ k_min : np.ndarray
13
+ Effective mineral bulk modulus [Pa].
14
+ mu_min : np.ndarray
15
+ Effective mineral shear modulus [Pa].
16
+ log_length : int
17
+ Number of samples in logs.
18
+
19
+ Returns
20
+ -------
21
+ tuple
22
+ c0 (background stiffness), s0 (inverse of background stiffness), gd (G tensor for inclusions with aspect
23
+ ratio 1.0).
24
+ """
25
+ # Calculate elastic parameters
26
+ c11 = k_min + 4 / 3 * mu_min
27
+ c44 = mu_min
28
+ c12 = c11 - 2 * c44
29
+
30
+ i4 = np.tile(np.eye(6).reshape(1, 6, 6), (log_length, 1, 1))
31
+ c0 = np.zeros((log_length, 6, 6))
32
+
33
+ for i in range(3):
34
+ c0[:, i, i] = c11
35
+ c0[:, i + 3, i + 3] = 2 * c44
36
+ for i in range(2):
37
+ c0[:, 0, i + 1] = c12
38
+ c0[:, 1, 2 * i] = c12
39
+ c0[:, 2, i] = c12
40
+
41
+ s0 = array_matrix_mult(i4, array_inverse(c0))
42
+ gd = g_tensor_vec(c0, s0, 1.0)
43
+
44
+ return c0, s0, gd
@@ -0,0 +1,278 @@
1
+ import warnings
2
+
3
+ import numpy as np
4
+
5
+ from rock_physics_open.equinor_utilities import gen_utilities
6
+
7
+ from .array_functions import array_inverse, array_matrix_mult
8
+ from .calc_c_eff import calc_c_eff_visco_vec
9
+ from .calc_isolated import calc_isolated_part_vec
10
+ from .calc_kd import calc_kd_vec
11
+ from .calc_kd_uuv import calc_kd_uuvv_vec
12
+ from .calc_pressure import calc_pressure_vec
13
+ from .calc_td import calc_td_vec
14
+ from .calc_x import calc_x_vec
15
+ from .iso_av import iso_av_vec
16
+ from .pressure_input import pressure_input_utility
17
+ from .velocity_vti_angles import velocity_vti_angles_vec
18
+
19
+
20
+ def t_matrix_porosity_vectorised(
21
+ k_min,
22
+ mu_min,
23
+ rho_min,
24
+ k_fl,
25
+ rho_fl,
26
+ phi,
27
+ perm,
28
+ visco,
29
+ alpha,
30
+ v,
31
+ tau,
32
+ frequency,
33
+ angle,
34
+ frac_inc_con,
35
+ frac_inc_ani,
36
+ pressure=None,
37
+ ):
38
+ """Vectorised version of T-Matrix, pure Python version - mainly intended for cases where it is wished to follow
39
+ the entire process through and study intermediate results. The C++ implementation is significantly faster.
40
+
41
+ Description of inputs:
42
+ Mineral propeties (effective properties, assumed mixed).
43
+ Fluid properties (effective properties, assume mixed).
44
+
45
+ Parameters
46
+ ----------
47
+ k_min : np.ndarray
48
+ N length array, bulk modulus of matrix/mineral [Pa].
49
+ mu_min : np.ndarray
50
+ N length array, shear modulus of matrix/mineral [Pa].
51
+ rho_min : np.ndarray
52
+ N length array, density of matrix/mineral [kg/m^3].
53
+ k_fl : np.ndarray
54
+ N length array, bulk modulus of fluid [Pa].
55
+ rho_fl : np.ndarray
56
+ N length array, density of fluid [kg/m^3].
57
+ phi : np.ndarray
58
+ N length array, porosity [fraction].
59
+ perm : np.ndarray
60
+ Single float or N length array, permeability [mD].
61
+ visco : np.ndarray
62
+ Single float or N length array, fluid viscosity [cP].
63
+ alpha : np.ndarray
64
+ M length vector, aspect ratio for inclusion sets [ratio].
65
+ v : np.ndarray
66
+ M length vector, fraction of porosity belonging to each inclusion set [fraction].
67
+ tau : np.ndarray
68
+ M length vector, relaxation time constant [s].
69
+ frequency : float
70
+ Single float, measurement frequency (seismic, sonic, ultrasonic range) [Hz].
71
+ angle : float
72
+ Single float, angle of symmetry plane (0 = HTI, 90 = VTI medium).
73
+ frac_inc_con : float or np.ndarray
74
+ Single float or N length array, fraction of inclusions that are connected.
75
+ frac_inc_ani : float or np.ndaray
76
+ Single float or N length array, fraction of inclusions that are anisotropic.
77
+ pressure : np.ndarray, optional
78
+ L length array (normally 2), by default None.
79
+
80
+ Returns
81
+ -------
82
+ tuple
83
+ Of type (np.ndarray, np.ndarray, np.ndarray, np.ndarray). Vertical P-wave velocity [m/s], Vsv: Vertical polarity S-wave velocity [m/s],
84
+ Vsh: Horizontal polarity S-wave velocity [m/s], rho_b: bulk density [kg/m^3].
85
+ """
86
+ log_length = len(phi)
87
+ # Check that the inputs that should have the same length actually do
88
+ (
89
+ k_min,
90
+ mu_min,
91
+ rho_min,
92
+ k_fl,
93
+ rho_fl,
94
+ phi,
95
+ perm,
96
+ visco,
97
+ ) = gen_utilities.dim_check_vector(
98
+ (k_min, mu_min, rho_min, k_fl, rho_fl, phi, perm, visco)
99
+ )
100
+
101
+ # Conversion to SI units
102
+ perm = perm * 0.986923e-15
103
+ visco = visco * 1.0e-2
104
+
105
+ # Alpha, v and tau should be of the same length
106
+ (alpha, v, tau) = gen_utilities.dim_check_vector((alpha, v, tau))
107
+ shape_len = alpha.shape[0]
108
+
109
+ # Shape parameters go into a dict, duplicate here, can be changed with pressure effect
110
+ shape_params = {
111
+ "alpha_con": alpha,
112
+ "alpha_iso": alpha,
113
+ "v_con": v * frac_inc_con,
114
+ "v_iso": v * (1 - frac_inc_con),
115
+ "tau_con": tau,
116
+ "tau_iso": tau,
117
+ }
118
+ # Create case based on amount of anisotropic inclusions
119
+ if frac_inc_ani == 0:
120
+ case = {"iso": 0} # All isotropic
121
+ angle = 0
122
+ elif frac_inc_ani == 1:
123
+ case = {"iso": 2} # All anisotropic
124
+ else:
125
+ case = {"iso": 1} # Mixed case
126
+
127
+ # Create case based on amount of connected inclusions
128
+ if frac_inc_con == 0:
129
+ case["con"] = 0
130
+ elif frac_inc_con == 1:
131
+ # All connected
132
+ case["con"] = 2
133
+ else:
134
+ # Mixed case
135
+ case["con"] = 1
136
+
137
+ pressure_steps = 1
138
+ delta_pres = 0.0
139
+ if pressure is not None:
140
+ try:
141
+ # Pressure should be an object with __len__ attribute, cast to np.array
142
+ pressure = np.array(pressure)
143
+ pressure_steps = len(pressure)
144
+ except TypeError:
145
+ w_str = "pressure input must be a vector of length > 1 with increasing effective pressures"
146
+ warnings.warn(w_str)
147
+ else:
148
+ delta_pres = np.diff(pressure)
149
+
150
+ # Predefine output vectors
151
+ vp = np.zeros((log_length, pressure_steps))
152
+ vs_v = np.zeros((log_length, pressure_steps))
153
+ vs_h = np.zeros((log_length, pressure_steps))
154
+ rho_b_est = np.zeros((log_length, pressure_steps))
155
+
156
+ # Matrix properties needed
157
+ c0, s0, gd = pressure_input_utility(k_min, mu_min, log_length)
158
+
159
+ i4 = np.tile(np.eye(6).reshape(1, 6, 6), (log_length, 1, 1))
160
+
161
+ # Vectorise v and alpha
162
+ v_con = None
163
+ alpha_con = None
164
+ v_iso = None
165
+ alpha_iso = None
166
+ if case["con"] != 0:
167
+ v_con = phi.reshape(log_length, 1) * shape_params["v_con"].reshape(1, shape_len)
168
+ alpha_con = np.ones(v_con.shape) * shape_params["alpha_con"].reshape(
169
+ 1, shape_len
170
+ )
171
+
172
+ if case["con"] != 2:
173
+ v_iso = phi.reshape(log_length, 1) * shape_params["v_iso"].reshape(1, shape_len)
174
+ alpha_iso = np.ones(v_iso.shape) * shape_params["alpha_iso"].reshape(
175
+ 1, shape_len
176
+ )
177
+
178
+ for i in range(pressure_steps):
179
+ # Check if v(j) > alpha(j)for maximum porosity. If true, set v(j) = alpha(j)/2 to make sure
180
+ # the numbers of inclusions in the system is not violating the
181
+ # approximations for effective medium theories.
182
+ phi_con = 0.0
183
+ phi_iso = 0.0
184
+ if case["con"] != 0:
185
+ idx_v_con = v_con * phi.reshape(log_length, 1) > alpha_con
186
+ if np.any(idx_v_con):
187
+ v_con[idx_v_con] = alpha_con[idx_v_con] / 2
188
+ phi_con = np.sum(v_con, axis=1)
189
+ if case["con"] != 2:
190
+ idx_v_iso = v_iso * phi.reshape(log_length, 1) > alpha_iso
191
+ if np.any(idx_v_iso):
192
+ v_iso[idx_v_iso] = alpha_iso[idx_v_iso] / 2
193
+ phi_iso = np.sum(v_iso, axis=1)
194
+ # May seem unnecessary, but V-vectors can change with changing pressure
195
+ phi_out = phi_con + phi_iso
196
+
197
+ # Creating reference matrix
198
+ vs_min = np.sqrt(mu_min / rho_min)
199
+
200
+ if case["con"] == 0:
201
+ # All isolated
202
+ # Isolated part: calculated c1 tensor (sum over all the isolated t-matrices and concentrations
203
+ c1 = calc_isolated_part_vec(
204
+ c0, s0, k_fl, alpha_iso, v_iso, case["iso"], frac_inc_ani
205
+ )
206
+ c_eff = c0 + array_matrix_mult(
207
+ c1, array_inverse(i4 + array_matrix_mult(gd, c1))
208
+ )
209
+ gamma = np.zeros_like(tau)
210
+ else:
211
+ kd = calc_kd_vec(c0, i4, s0, alpha_con)
212
+ kd_uuvv = calc_kd_uuvv_vec(kd)
213
+ gamma = (1 - k_fl / k_min).reshape(log_length, 1) + k_fl.reshape(
214
+ log_length, 1
215
+ ) * kd_uuvv
216
+ if case["con"] == 1:
217
+ # Mix
218
+ # Isolated part: calculated c1 tensor (sum over all the isolated t-matrices and concentrations
219
+ c1 = calc_isolated_part_vec(
220
+ c0, s0, k_fl, alpha_iso, v_iso, case["iso"], frac_inc_ani
221
+ )
222
+ else: # case['con'] == 2
223
+ # All connected - only c1 differs from the most general case
224
+ c1 = np.zeros((log_length, 6, 6))
225
+ # Connected part Calculate dry properties:
226
+ td = calc_td_vec(c0, i4, s0, kd, alpha_con)
227
+ # iso averaging the isotropic porosity
228
+ td_bar = iso_av_vec(td)
229
+ # Calculate the fluid effect
230
+ x = calc_x_vec(s0, td)
231
+ # iso averaging the isotropic porosity
232
+ x_bar = iso_av_vec(x)
233
+ # Frequency dependent stiffness
234
+ c_eff = calc_c_eff_visco_vec(
235
+ vs_min,
236
+ perm,
237
+ visco,
238
+ v_con,
239
+ gamma,
240
+ tau,
241
+ kd_uuvv,
242
+ k_min,
243
+ k_fl,
244
+ c0,
245
+ s0,
246
+ c1,
247
+ td,
248
+ td_bar,
249
+ x,
250
+ x_bar,
251
+ gd,
252
+ frequency,
253
+ frac_inc_ani,
254
+ )
255
+ # Effective density
256
+ rho_b_est[:, i] = phi_out * rho_fl + (1 - phi_out) * rho_min
257
+ vp[:, i], vs_v[:, i], vs_h[:, i] = velocity_vti_angles_vec(
258
+ c_eff, rho_b_est[:, i], angle
259
+ )
260
+
261
+ if i != pressure_steps - 1:
262
+ alpha_con, v_con, alpha_iso, v_iso, tau, gamma = calc_pressure_vec(
263
+ alpha_con,
264
+ alpha_iso,
265
+ v_con,
266
+ v_iso,
267
+ c0,
268
+ s0,
269
+ gd,
270
+ delta_pres[i],
271
+ tau,
272
+ gamma,
273
+ k_fl,
274
+ case["con"],
275
+ frac_inc_ani,
276
+ )
277
+
278
+ return vp, vs_v, vs_h, rho_b_est
@@ -0,0 +1,81 @@
1
+ import numpy as np
2
+
3
+
4
+ def velocity_vti_angles_vec(c_eff, rho_eff, angle):
5
+ """Returns the P-velocity and S-velocities.
6
+
7
+ Parameters
8
+ ----------
9
+ c_eff : np.ndarray
10
+ Effective stiffness tensor (nx6x6 matrix).
11
+ rho_eff : np.ndarray
12
+ Effective density.
13
+ angle : np.ndarray or float
14
+ The angle between the wave vector and the axis of symmetry.
15
+
16
+ Returns
17
+ -------
18
+ tuple
19
+ vp_out, vsv_out, vsh_out : (np.ndarray, np.ndarray, np.ndarray).
20
+ vp_out, vsv_out, vsh_out : p-velocity, vertical polarisation s-velocity, horizontal polarisation s-velocity.
21
+ """
22
+ if not (
23
+ c_eff.ndim == 3
24
+ and rho_eff.ndim == 1
25
+ and isinstance(angle, (float, int))
26
+ and (c_eff.shape[0] == rho_eff.shape[0] and c_eff.shape[1] == c_eff.shape[2])
27
+ ):
28
+ raise ValueError("velocity_vti_angles: inconsistencies in input shapes")
29
+
30
+ # vp45
31
+ m45 = (
32
+ (c_eff[:, 0, 0] - c_eff[:, 3, 3] / 2.0) * 0.5
33
+ - (c_eff[:, 2, 2] - c_eff[:, 3, 3] / 2.0) * 0.5
34
+ ) ** 2 + (c_eff[:, 0, 0] - c_eff[:, 3, 3] / 2.0) ** 2
35
+ m45 = np.sqrt(m45)
36
+ v2p = ((c_eff[:, 0, 0] + c_eff[:, 2, 2] + c_eff[:, 3, 3]) / 2.0 + m45) / (
37
+ 2.0 * rho_eff
38
+ )
39
+ sp = np.real(1.0 / (np.sqrt(v2p)))
40
+ vp45 = 1.0 / sp
41
+
42
+ # c11 = rho_eff * Vp90 ** 2
43
+ c11 = np.real(c_eff[:, 0, 0])
44
+ # c33 = rho_eff * Vp0 ** 2
45
+ c33 = np.real(c_eff[:, 2, 2])
46
+ # c44 = rho_eff * Vs0 ** 2
47
+ c44 = np.real(c_eff[:, 3, 3] / 2.0)
48
+ # c66 = rho_eff * Vs90 ** 2
49
+ c66 = np.real(c_eff[:, 5, 5] / 2.0)
50
+
51
+ c13 = -c44 + np.sqrt(
52
+ 4 * (rho_eff**2) * (vp45**4)
53
+ - 2.0 * rho_eff * (vp45**2) * (c11 + c33 + 2.0 * c44)
54
+ + (c11 + c44) * (c33 + c44)
55
+ )
56
+
57
+ rad_angle = (angle * np.pi) / 180.0
58
+
59
+ m_real = (
60
+ (c11 - c44) * (np.sin(rad_angle) ** 2) - (c33 - c44) * (np.cos(rad_angle) ** 2)
61
+ ) ** 2 + ((c13 + c44) ** 2) * (np.sin(2.0 * rad_angle) ** 2)
62
+
63
+ vp_out = np.sqrt(
64
+ c11 * (np.sin(rad_angle) ** 2)
65
+ + c33 * (np.cos(rad_angle) ** 2)
66
+ + c44
67
+ + np.sqrt(m_real)
68
+ ) * np.sqrt(1.0 / (2.0 * rho_eff))
69
+
70
+ vsv_out = np.sqrt(
71
+ c11 * (np.sin(rad_angle) ** 2)
72
+ + c33 * (np.cos(rad_angle) ** 2)
73
+ + c44
74
+ - np.sqrt(m_real)
75
+ ) * np.sqrt(1.0 / (2.0 * rho_eff))
76
+
77
+ vsh_out = np.sqrt(
78
+ (c66 * (np.sin(rad_angle) ** 2) + c44 * (np.cos(rad_angle) ** 2)) / rho_eff
79
+ )
80
+
81
+ return vp_out, vsv_out, vsh_out
@@ -0,0 +1,3 @@
1
+ from .unconventionals_ternary import run_ternary
2
+
3
+ __all__ = ["run_ternary"]