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.
- rock_physics_open/__init__.py +0 -0
- rock_physics_open/equinor_utilities/__init__.py +0 -0
- rock_physics_open/equinor_utilities/anisotropy.py +211 -0
- rock_physics_open/equinor_utilities/classification_functions/__init__.py +17 -0
- rock_physics_open/equinor_utilities/classification_functions/class_stats.py +68 -0
- rock_physics_open/equinor_utilities/classification_functions/lin_class.py +53 -0
- rock_physics_open/equinor_utilities/classification_functions/mahal_class.py +63 -0
- rock_physics_open/equinor_utilities/classification_functions/norm_class.py +73 -0
- rock_physics_open/equinor_utilities/classification_functions/poly_class.py +45 -0
- rock_physics_open/equinor_utilities/classification_functions/post_prob.py +27 -0
- rock_physics_open/equinor_utilities/classification_functions/two_step_classification.py +60 -0
- rock_physics_open/equinor_utilities/conversions.py +10 -0
- rock_physics_open/equinor_utilities/gen_utilities/__init__.py +11 -0
- rock_physics_open/equinor_utilities/gen_utilities/dict_to_float.py +38 -0
- rock_physics_open/equinor_utilities/gen_utilities/dim_check_vector.py +113 -0
- rock_physics_open/equinor_utilities/gen_utilities/filter_input.py +131 -0
- rock_physics_open/equinor_utilities/gen_utilities/filter_output.py +88 -0
- rock_physics_open/equinor_utilities/machine_learning_utilities/__init__.py +15 -0
- rock_physics_open/equinor_utilities/machine_learning_utilities/base_pressure_model.py +170 -0
- rock_physics_open/equinor_utilities/machine_learning_utilities/dummy_vars.py +53 -0
- rock_physics_open/equinor_utilities/machine_learning_utilities/exponential_model.py +137 -0
- rock_physics_open/equinor_utilities/machine_learning_utilities/import_ml_models.py +77 -0
- rock_physics_open/equinor_utilities/machine_learning_utilities/polynomial_model.py +132 -0
- rock_physics_open/equinor_utilities/machine_learning_utilities/run_regression.py +209 -0
- rock_physics_open/equinor_utilities/machine_learning_utilities/sigmoidal_model.py +241 -0
- rock_physics_open/equinor_utilities/optimisation_utilities/__init__.py +19 -0
- rock_physics_open/equinor_utilities/optimisation_utilities/opt_subst_utilities.py +455 -0
- rock_physics_open/equinor_utilities/snapshot_test_utilities/__init__.py +10 -0
- rock_physics_open/equinor_utilities/snapshot_test_utilities/compare_snapshots.py +184 -0
- rock_physics_open/equinor_utilities/snapshot_test_utilities/snapshots.py +97 -0
- rock_physics_open/equinor_utilities/std_functions/__init__.py +43 -0
- rock_physics_open/equinor_utilities/std_functions/backus_ave.py +68 -0
- rock_physics_open/equinor_utilities/std_functions/dvorkin_nur.py +77 -0
- rock_physics_open/equinor_utilities/std_functions/gassmann.py +165 -0
- rock_physics_open/equinor_utilities/std_functions/hashin_shtrikman.py +224 -0
- rock_physics_open/equinor_utilities/std_functions/hertz_mindlin.py +51 -0
- rock_physics_open/equinor_utilities/std_functions/moduli_velocity.py +67 -0
- rock_physics_open/equinor_utilities/std_functions/reflection_eq.py +120 -0
- rock_physics_open/equinor_utilities/std_functions/rho.py +69 -0
- rock_physics_open/equinor_utilities/std_functions/voigt_reuss_hill.py +149 -0
- rock_physics_open/equinor_utilities/std_functions/walton.py +45 -0
- rock_physics_open/equinor_utilities/std_functions/wood_brie.py +94 -0
- rock_physics_open/equinor_utilities/various_utilities/Equinor_logo.gif +0 -0
- rock_physics_open/equinor_utilities/various_utilities/Equinor_logo.ico +0 -0
- rock_physics_open/equinor_utilities/various_utilities/__init__.py +24 -0
- rock_physics_open/equinor_utilities/various_utilities/display_result_statistics.py +90 -0
- rock_physics_open/equinor_utilities/various_utilities/gassmann_dry_mod.py +56 -0
- rock_physics_open/equinor_utilities/various_utilities/gassmann_mod.py +56 -0
- rock_physics_open/equinor_utilities/various_utilities/gassmann_sub_mod.py +64 -0
- rock_physics_open/equinor_utilities/various_utilities/hs_average.py +59 -0
- rock_physics_open/equinor_utilities/various_utilities/pressure.py +96 -0
- rock_physics_open/equinor_utilities/various_utilities/reflectivity.py +101 -0
- rock_physics_open/equinor_utilities/various_utilities/timeshift.py +104 -0
- rock_physics_open/equinor_utilities/various_utilities/vp_vs_rho_set_statistics.py +170 -0
- rock_physics_open/equinor_utilities/various_utilities/vrh_3_min.py +83 -0
- rock_physics_open/fluid_models/__init__.py +9 -0
- rock_physics_open/fluid_models/brine_model/__init__.py +5 -0
- rock_physics_open/fluid_models/brine_model/brine_properties.py +178 -0
- rock_physics_open/fluid_models/gas_model/__init__.py +5 -0
- rock_physics_open/fluid_models/gas_model/gas_properties.py +319 -0
- rock_physics_open/fluid_models/oil_model/__init__.py +5 -0
- rock_physics_open/fluid_models/oil_model/dead_oil_density.py +65 -0
- rock_physics_open/fluid_models/oil_model/dead_oil_velocity.py +30 -0
- rock_physics_open/fluid_models/oil_model/live_oil_density.py +82 -0
- rock_physics_open/fluid_models/oil_model/live_oil_velocity.py +24 -0
- rock_physics_open/fluid_models/oil_model/oil_bubble_point.py +69 -0
- rock_physics_open/fluid_models/oil_model/oil_properties.py +146 -0
- rock_physics_open/sandstone_models/__init__.py +59 -0
- rock_physics_open/sandstone_models/cemented_shalysand_sandyshale_models.py +304 -0
- rock_physics_open/sandstone_models/constant_cement_models.py +204 -0
- rock_physics_open/sandstone_models/constant_cement_optimisation.py +125 -0
- rock_physics_open/sandstone_models/contact_cement_model.py +138 -0
- rock_physics_open/sandstone_models/curvefit_sandstone_models.py +143 -0
- rock_physics_open/sandstone_models/friable_models.py +177 -0
- rock_physics_open/sandstone_models/friable_optimisation.py +115 -0
- rock_physics_open/sandstone_models/friable_shalysand_sandyshale_models.py +235 -0
- rock_physics_open/sandstone_models/patchy_cement_fluid_substitution_model.py +477 -0
- rock_physics_open/sandstone_models/patchy_cement_model.py +384 -0
- rock_physics_open/sandstone_models/patchy_cement_optimisation.py +254 -0
- rock_physics_open/sandstone_models/unresolved_cemented_sandshale_models.py +134 -0
- rock_physics_open/sandstone_models/unresolved_friable_sandshale_models.py +126 -0
- rock_physics_open/shale_models/__init__.py +19 -0
- rock_physics_open/shale_models/dem.py +174 -0
- rock_physics_open/shale_models/dem_dual_por.py +61 -0
- rock_physics_open/shale_models/kus_tok.py +59 -0
- rock_physics_open/shale_models/multi_sca.py +133 -0
- rock_physics_open/shale_models/pq.py +102 -0
- rock_physics_open/shale_models/sca.py +90 -0
- rock_physics_open/shale_models/shale4_mineral.py +147 -0
- rock_physics_open/shale_models/shale4_mineral_dem_overlay.py +92 -0
- rock_physics_open/span_wagner/__init__.py +5 -0
- rock_physics_open/span_wagner/co2_properties.py +444 -0
- rock_physics_open/span_wagner/coefficients.py +165 -0
- rock_physics_open/span_wagner/equations.py +104 -0
- rock_physics_open/span_wagner/tables/__init__.py +0 -0
- rock_physics_open/span_wagner/tables/carbon_dioxide_density.npz +0 -0
- rock_physics_open/span_wagner/tables/lookup_table.py +33 -0
- rock_physics_open/t_matrix_models/Equinor_logo.ico +0 -0
- rock_physics_open/t_matrix_models/__init__.py +35 -0
- rock_physics_open/t_matrix_models/carbonate_pressure_substitution.py +124 -0
- rock_physics_open/t_matrix_models/curvefit_t_matrix_exp.py +123 -0
- rock_physics_open/t_matrix_models/curvefit_t_matrix_min.py +86 -0
- rock_physics_open/t_matrix_models/parse_t_matrix_inputs.py +297 -0
- rock_physics_open/t_matrix_models/run_t_matrix.py +243 -0
- rock_physics_open/t_matrix_models/t_matrix_C.py +210 -0
- rock_physics_open/t_matrix_models/t_matrix_opt_fluid_sub_exp.py +137 -0
- rock_physics_open/t_matrix_models/t_matrix_opt_fluid_sub_petec.py +167 -0
- rock_physics_open/t_matrix_models/t_matrix_opt_forward_model_exp.py +76 -0
- rock_physics_open/t_matrix_models/t_matrix_opt_forward_model_min.py +89 -0
- rock_physics_open/t_matrix_models/t_matrix_parameter_optimisation_exp.py +176 -0
- rock_physics_open/t_matrix_models/t_matrix_parameter_optimisation_min.py +162 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/__init__.py +12 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/array_functions.py +75 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/calc_c_eff.py +163 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/calc_isolated.py +95 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/calc_kd.py +40 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/calc_kd_eff.py +116 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/calc_kd_uuv.py +18 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/calc_pressure.py +140 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/calc_t.py +71 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/calc_td.py +42 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/calc_theta.py +43 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/calc_x.py +33 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/calc_z.py +50 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/check_and_tile.py +43 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/g_tensor.py +140 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/iso_av.py +60 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/iso_ave_all.py +55 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/pressure_input.py +44 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/t_matrix_vec.py +278 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/velocity_vti_angles.py +81 -0
- rock_physics_open/t_matrix_models/tmatrix_python.dll +0 -0
- rock_physics_open/t_matrix_models/tmatrix_python.so +0 -0
- rock_physics_open/ternary_plots/__init__.py +3 -0
- rock_physics_open/ternary_plots/gen_ternary_plot.py +73 -0
- rock_physics_open/ternary_plots/shale_prop_ternary.py +337 -0
- rock_physics_open/ternary_plots/ternary_patches.py +277 -0
- rock_physics_open/ternary_plots/ternary_plot_utilities.py +197 -0
- rock_physics_open/ternary_plots/unconventionals_ternary.py +75 -0
- rock_physics_open/version.py +34 -0
- rock_physics_open-0.3.2.dist-info/METADATA +90 -0
- rock_physics_open-0.3.2.dist-info/RECORD +145 -0
- rock_physics_open-0.3.2.dist-info/WHEEL +5 -0
- rock_physics_open-0.3.2.dist-info/licenses/LICENSE +165 -0
- rock_physics_open-0.3.2.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
from rock_physics_open import t_matrix_models
|
|
6
|
+
from rock_physics_open.equinor_utilities import gen_utilities
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def parse_t_matrix_inputs(
|
|
10
|
+
k_min,
|
|
11
|
+
mu_min,
|
|
12
|
+
rho_min,
|
|
13
|
+
k_fl,
|
|
14
|
+
rho_fl,
|
|
15
|
+
phi,
|
|
16
|
+
perm,
|
|
17
|
+
visco,
|
|
18
|
+
alpha,
|
|
19
|
+
v,
|
|
20
|
+
tau,
|
|
21
|
+
frequency,
|
|
22
|
+
angle,
|
|
23
|
+
frac_inc_con,
|
|
24
|
+
frac_inc_ani,
|
|
25
|
+
pressure,
|
|
26
|
+
scenario,
|
|
27
|
+
fcn,
|
|
28
|
+
):
|
|
29
|
+
"""Function to do all necessary checking of input type, dimension, reshaping etc. that clutter up the start of T-Matrix
|
|
30
|
+
NB: Setting scenario will override the settings for alpha, v and tau.
|
|
31
|
+
|
|
32
|
+
Parameters
|
|
33
|
+
----------
|
|
34
|
+
k_min : np.ndarray
|
|
35
|
+
N length numpy array, mineral bulk modulus [Pa].
|
|
36
|
+
mu_min : np.ndarray
|
|
37
|
+
N length numpy array, mineral shear modulus [Pa].
|
|
38
|
+
rho_min : np.ndarray
|
|
39
|
+
N length numpy array, mineral density [kg/m^3].
|
|
40
|
+
k_fl : np.ndarray
|
|
41
|
+
N length numpy array, fluid bulk modulus [Pa].
|
|
42
|
+
rho_fl : np.ndarray
|
|
43
|
+
N length numpy array, mineral density [kg/m^3].
|
|
44
|
+
phi : np.ndarray or float
|
|
45
|
+
N length numpy array, total porosity [ratio].
|
|
46
|
+
perm : np.ndarray or float
|
|
47
|
+
float or N length numpy array, permeability [mD].
|
|
48
|
+
visco : np.ndarray or float
|
|
49
|
+
float or N length numpy array, fluid viscosity [cP].
|
|
50
|
+
alpha : np.ndarray
|
|
51
|
+
M or NxM length numpy array, inclusion aspect ratio [ratio].
|
|
52
|
+
v : np.ndarray
|
|
53
|
+
M or NxM length numpy array, inclusion concentration [ratio].
|
|
54
|
+
tau : np.ndarray
|
|
55
|
+
M length numpy array, relaxation time [s].
|
|
56
|
+
frequency : float
|
|
57
|
+
single float, signal frequency [Hz].
|
|
58
|
+
angle : float
|
|
59
|
+
single float, angle of symmetry plane [degree].
|
|
60
|
+
frac_inc_con : np.ndarray or float
|
|
61
|
+
single float or N length numpy array, fraction of connected inclusions [ratio].
|
|
62
|
+
frac_inc_ani : np.ndarray or float
|
|
63
|
+
single float or N length numpy array, fraction of anisotropic inclusions [ratio].
|
|
64
|
+
pressure : list or np.ndarray
|
|
65
|
+
> 1 value list or numpy array in ascending order, effective pressure [Pa].
|
|
66
|
+
scenario : int
|
|
67
|
+
pre-set scenarios for alpha, v and tau
|
|
68
|
+
fcn : callable
|
|
69
|
+
function with which to run the T-Matrix model.
|
|
70
|
+
|
|
71
|
+
Returns
|
|
72
|
+
-------
|
|
73
|
+
tuple
|
|
74
|
+
All inputs in correct dimension and data type plus ctrl_connected, ctrl_anisotropy - control parameters.
|
|
75
|
+
"""
|
|
76
|
+
|
|
77
|
+
def _assert_type(arg, exp_dtype, err_str="check inputs, wrong type encountered"):
|
|
78
|
+
"""Assert type.
|
|
79
|
+
|
|
80
|
+
Parameters
|
|
81
|
+
----------
|
|
82
|
+
arg : any
|
|
83
|
+
To be asserted.
|
|
84
|
+
exp_dtype : type
|
|
85
|
+
Expected data type.
|
|
86
|
+
err_str : str, optional
|
|
87
|
+
Error string, by default 'check inputs, wrong type encountered'.
|
|
88
|
+
|
|
89
|
+
Raises
|
|
90
|
+
------
|
|
91
|
+
ValueError
|
|
92
|
+
Content of err_str.
|
|
93
|
+
"""
|
|
94
|
+
if not isinstance(arg, exp_dtype):
|
|
95
|
+
raise ValueError("t-matrix inputs: " + err_str)
|
|
96
|
+
|
|
97
|
+
# 1: Check all single float values, silently cast int to float
|
|
98
|
+
# Permeability and viscosity: Check that they are floats and convert them to to SI units
|
|
99
|
+
_assert_type(
|
|
100
|
+
perm, (float, int), "expect permeability given as single float in units mD"
|
|
101
|
+
)
|
|
102
|
+
perm = perm * 0.986923e-15
|
|
103
|
+
|
|
104
|
+
_assert_type(
|
|
105
|
+
visco, (float, int), "expect viscosity given as single float in units cP"
|
|
106
|
+
)
|
|
107
|
+
visco = visco * 1.0e-2
|
|
108
|
+
|
|
109
|
+
_assert_type(
|
|
110
|
+
frequency, (float, int), "expect frequency given as single float value in Hz"
|
|
111
|
+
)
|
|
112
|
+
frequency = float(frequency)
|
|
113
|
+
|
|
114
|
+
_assert_type(
|
|
115
|
+
angle, (float, int), "expect angle given as single float value in degrees"
|
|
116
|
+
)
|
|
117
|
+
angle = float(angle)
|
|
118
|
+
|
|
119
|
+
# 2: Determine the T-Matrix function, use the C++ implementation as default in case of None
|
|
120
|
+
# If it given as a string, it must belong to the t_matrix_models module
|
|
121
|
+
if not fcn: # None
|
|
122
|
+
t_matrix_fcn = t_matrix_models.t_matrix_porosity_c_alpha_v
|
|
123
|
+
elif not callable(fcn):
|
|
124
|
+
fcn_err_str = (
|
|
125
|
+
"T-Matrix function should be given as the callable function or a string "
|
|
126
|
+
"to the function name within t_matrix_models "
|
|
127
|
+
)
|
|
128
|
+
_assert_type(fcn, str, fcn_err_str)
|
|
129
|
+
if not hasattr(t_matrix_models, fcn):
|
|
130
|
+
raise ValueError(fcn_err_str)
|
|
131
|
+
t_matrix_fcn = getattr(t_matrix_models, fcn)
|
|
132
|
+
|
|
133
|
+
else: # Function must be recognised
|
|
134
|
+
if not fcn: # check that the function exists
|
|
135
|
+
raise ValueError(
|
|
136
|
+
"t-matrix inputs: function for T-Matrix model is not known"
|
|
137
|
+
)
|
|
138
|
+
t_matrix_fcn = fcn
|
|
139
|
+
|
|
140
|
+
# 3: Check all inputs that should be one value per sample, expand perm and visco to match this.
|
|
141
|
+
# frac_inc_ani and frac_inc_con can be single floats or vectors of the same length as the other vector inputs
|
|
142
|
+
|
|
143
|
+
log_length = len(phi)
|
|
144
|
+
|
|
145
|
+
# Check that the inputs that should have the same length actually do
|
|
146
|
+
# dim_check_vector may throw an error message, modify it to show origin
|
|
147
|
+
try:
|
|
148
|
+
(
|
|
149
|
+
k_min,
|
|
150
|
+
mu_min,
|
|
151
|
+
rho_min,
|
|
152
|
+
k_fl,
|
|
153
|
+
rho_fl,
|
|
154
|
+
phi,
|
|
155
|
+
perm,
|
|
156
|
+
visco,
|
|
157
|
+
frac_inc_con,
|
|
158
|
+
frac_inc_ani,
|
|
159
|
+
) = gen_utilities.dim_check_vector(
|
|
160
|
+
(
|
|
161
|
+
k_min,
|
|
162
|
+
mu_min,
|
|
163
|
+
rho_min,
|
|
164
|
+
k_fl,
|
|
165
|
+
rho_fl,
|
|
166
|
+
phi,
|
|
167
|
+
perm,
|
|
168
|
+
visco,
|
|
169
|
+
frac_inc_con,
|
|
170
|
+
frac_inc_ani,
|
|
171
|
+
),
|
|
172
|
+
force_type=np.dtype(float),
|
|
173
|
+
)
|
|
174
|
+
except ValueError:
|
|
175
|
+
raise ValueError("t-matrix inputs: {}".format(str(sys.exc_info())))
|
|
176
|
+
|
|
177
|
+
# 4: Scenario will override settings for alpha, v and tau
|
|
178
|
+
if scenario:
|
|
179
|
+
scenario = int(scenario)
|
|
180
|
+
if scenario == 1: # Mostly rounded pores
|
|
181
|
+
alpha = np.array([0.9, 0.1])
|
|
182
|
+
v = np.array([0.9, 0.1])
|
|
183
|
+
elif scenario == 2: # Dual porosity with little rounded pores
|
|
184
|
+
alpha = np.array([0.58, 0.027])
|
|
185
|
+
v = np.array([0.85, 0.15])
|
|
186
|
+
elif scenario == 3: # Mixed pores
|
|
187
|
+
alpha = np.array([0.9, 0.1, 0.01])
|
|
188
|
+
v = np.array([0.8, 0.19, 0.01])
|
|
189
|
+
elif scenario == 4: # Flat pores and cracks
|
|
190
|
+
alpha = np.array([0.9, 0.1, 0.01, 0.001])
|
|
191
|
+
v = np.array([0.689, 0.3, 0.01, 0.001])
|
|
192
|
+
tau = np.ones_like(alpha) * 1.0e-7
|
|
193
|
+
|
|
194
|
+
# 4a: Check alpha, v, tau
|
|
195
|
+
# alpha and v is either 1D vector with inclusion aspect ratios and proportions applying to all samples or 2D arrays
|
|
196
|
+
# where the first dimension must coincide with the log_length
|
|
197
|
+
# tau should be a 1D vector with length equal to the number of inclusions per sample
|
|
198
|
+
_assert_type(
|
|
199
|
+
alpha,
|
|
200
|
+
np.ndarray,
|
|
201
|
+
"alpha should be a 1D or 2D numpy array of matching size with v",
|
|
202
|
+
)
|
|
203
|
+
_assert_type(
|
|
204
|
+
v, np.ndarray, "v should be a 1D or 2D numpy array og matching size with alpha"
|
|
205
|
+
)
|
|
206
|
+
_assert_type(
|
|
207
|
+
tau,
|
|
208
|
+
(float, np.ndarray),
|
|
209
|
+
"tau should be a single float or 1D numpy array with length matching "
|
|
210
|
+
"the number of inclusions",
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
alpha_shape = alpha.shape
|
|
214
|
+
# First make sure that alpha and v have the same number of elements
|
|
215
|
+
try:
|
|
216
|
+
alpha, v = gen_utilities.dim_check_vector(
|
|
217
|
+
(alpha, v), force_type=np.dtype(float)
|
|
218
|
+
)
|
|
219
|
+
except ValueError:
|
|
220
|
+
raise ValueError("t-matrix inputs: {}".format(str(sys.exc_info())))
|
|
221
|
+
alpha = alpha.reshape(alpha_shape)
|
|
222
|
+
v = v.reshape(alpha_shape)
|
|
223
|
+
# If they are 2D arrays, the first dimension should match log_length
|
|
224
|
+
if alpha.ndim == 2:
|
|
225
|
+
if not (alpha_shape[0] == log_length or alpha_shape[0] == 1):
|
|
226
|
+
raise ValueError(
|
|
227
|
+
"t-matrix inputs: number of samples in alpha is not matching length of inputs"
|
|
228
|
+
)
|
|
229
|
+
if alpha_shape[0] == 1:
|
|
230
|
+
alpha = np.tile(alpha, (log_length, 1))
|
|
231
|
+
v = np.tile(v, (log_length, 1))
|
|
232
|
+
|
|
233
|
+
elif alpha.ndim == 1:
|
|
234
|
+
alpha = np.tile(alpha.reshape(1, alpha_shape[0]), (log_length, 1))
|
|
235
|
+
v = np.tile(v.reshape(1, alpha_shape[0]), (log_length, 1))
|
|
236
|
+
# Check that the number of elements in tau matches dim 1 of alpha
|
|
237
|
+
if isinstance(tau, float):
|
|
238
|
+
tau = np.ones(alpha_shape) * tau
|
|
239
|
+
else:
|
|
240
|
+
if not tau.ndim == 1 and tau.shape[0] == alpha.shape[1]:
|
|
241
|
+
raise ValueError(
|
|
242
|
+
"t-matrix inputs: number of elements in tau is not matching number of inclusions"
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
# 5: Check pressure
|
|
246
|
+
# Check that pressure either consists of at least two elements in ascending order or is None
|
|
247
|
+
# in the case there is no pressure modelling
|
|
248
|
+
if pressure is not None:
|
|
249
|
+
_assert_type(
|
|
250
|
+
pressure,
|
|
251
|
+
(list, np.ndarray),
|
|
252
|
+
"pressure should be a list or numpy array of at least two "
|
|
253
|
+
"elements in ascending order",
|
|
254
|
+
)
|
|
255
|
+
pressure = np.sort(np.array(pressure).flatten())
|
|
256
|
+
if not pressure.shape[0] > 1:
|
|
257
|
+
raise ValueError(
|
|
258
|
+
"t-matrix inputs: if pressure is given, it should contain two or more values"
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
# 6: Determine case for connected/isolated and isotropic/anisotropic inclusions
|
|
262
|
+
# Assume the most general case: mix of isotropic and anisotropic inclusions and connected and isolated inclusions
|
|
263
|
+
ctrl_anisotropy = 1
|
|
264
|
+
if np.all(frac_inc_ani == 0):
|
|
265
|
+
ctrl_anisotropy = 0 # All isotropic
|
|
266
|
+
angle = 0
|
|
267
|
+
elif np.all(frac_inc_ani == 1):
|
|
268
|
+
ctrl_anisotropy = 2 # All anisotropic
|
|
269
|
+
|
|
270
|
+
ctrl_connected = 1
|
|
271
|
+
# Create case based on amount of connected inclusions
|
|
272
|
+
if np.all(frac_inc_con == 0):
|
|
273
|
+
ctrl_connected = 0 # All isolated
|
|
274
|
+
elif np.all(frac_inc_con == 1):
|
|
275
|
+
ctrl_connected = 2 # All connected
|
|
276
|
+
|
|
277
|
+
return (
|
|
278
|
+
k_min,
|
|
279
|
+
mu_min,
|
|
280
|
+
rho_min,
|
|
281
|
+
k_fl,
|
|
282
|
+
rho_fl,
|
|
283
|
+
phi,
|
|
284
|
+
perm,
|
|
285
|
+
visco,
|
|
286
|
+
alpha,
|
|
287
|
+
v,
|
|
288
|
+
tau,
|
|
289
|
+
frequency,
|
|
290
|
+
angle,
|
|
291
|
+
frac_inc_con,
|
|
292
|
+
frac_inc_ani,
|
|
293
|
+
pressure,
|
|
294
|
+
t_matrix_fcn,
|
|
295
|
+
ctrl_connected,
|
|
296
|
+
ctrl_anisotropy,
|
|
297
|
+
)
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from .parse_t_matrix_inputs import parse_t_matrix_inputs
|
|
4
|
+
from .t_matrix_vector import calc_pressure_vec, pressure_input_utility
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def run_t_matrix(
|
|
8
|
+
k_min,
|
|
9
|
+
mu_min,
|
|
10
|
+
rho_min,
|
|
11
|
+
k_fl,
|
|
12
|
+
rho_fl,
|
|
13
|
+
phi,
|
|
14
|
+
perm,
|
|
15
|
+
visco,
|
|
16
|
+
alpha,
|
|
17
|
+
v,
|
|
18
|
+
tau,
|
|
19
|
+
frequency,
|
|
20
|
+
angle,
|
|
21
|
+
frac_inc_con,
|
|
22
|
+
frac_inc_ani,
|
|
23
|
+
pressure=None,
|
|
24
|
+
scenario=None,
|
|
25
|
+
fcn=None,
|
|
26
|
+
):
|
|
27
|
+
"""Function to run T-Matrix in different flavours, with or without pressure steps included.
|
|
28
|
+
A frontend to running T-Matrix model, including testing of all input parameters in the parse_t_matrix_inputs.
|
|
29
|
+
|
|
30
|
+
Parameters
|
|
31
|
+
----------
|
|
32
|
+
k_min : np.ndarray
|
|
33
|
+
N length numpy array, mineral bulk modulus [Pa].
|
|
34
|
+
mu_min : np.ndarray
|
|
35
|
+
N length numpy array, mineral shear modulus [Pa].
|
|
36
|
+
rho_min : np.ndarray
|
|
37
|
+
N length numpy array, mineral density [kg/m^3].
|
|
38
|
+
k_fl : np.ndarray
|
|
39
|
+
N length numpy array, fluid bulk modulus [Pa].
|
|
40
|
+
rho_fl : np.ndarray
|
|
41
|
+
N length numpy array, mineral density [kg/m^3].
|
|
42
|
+
phi : np.ndarray or float
|
|
43
|
+
N length numpy array, total porosity [ratio].
|
|
44
|
+
perm : np.ndarray or float
|
|
45
|
+
Float or N length numpy array, permeability [mD].
|
|
46
|
+
visco : np.ndarray or float
|
|
47
|
+
Float or N length numpy array, fluid viscosity [cP].
|
|
48
|
+
alpha : np.ndarray
|
|
49
|
+
M or NxM length numpy array, inclusion aspect ratio [ratio].
|
|
50
|
+
v : np.ndarray
|
|
51
|
+
M or NxM length numpy array, inclusion concentration [ratio].
|
|
52
|
+
tau : np.ndarray
|
|
53
|
+
M length numpy array, relaxation time [s].
|
|
54
|
+
frequency : float
|
|
55
|
+
Single float, signal frequency [Hz].
|
|
56
|
+
angle : float
|
|
57
|
+
Single float, angle of symmetry plane [degree].
|
|
58
|
+
frac_inc_con : np.ndarray or float
|
|
59
|
+
Single float or N length numpy array, fraction of connected inclusions [ratio].
|
|
60
|
+
frac_inc_ani : np.ndarray or float
|
|
61
|
+
Single float or N length numpy array, fraction of anisotropic inclusions [ratio].
|
|
62
|
+
pressure : [type], optional
|
|
63
|
+
> 1 value list or numpy array in ascending order, effective pressure [Pa], by default None.
|
|
64
|
+
scenario : int, optional
|
|
65
|
+
Pre-set scenarios for alpha, v and tau, by default None.
|
|
66
|
+
fcn : callable, optional
|
|
67
|
+
Function with which to run the T-Matrix model, by default None.
|
|
68
|
+
|
|
69
|
+
Returns
|
|
70
|
+
-------
|
|
71
|
+
tuple
|
|
72
|
+
vp, vsv, vsh, rho: (np.ndarray, np.ndarray, np.ndarray, np.ndarray).
|
|
73
|
+
"""
|
|
74
|
+
# Check all input parameters and make sure that they are on expected format and shape
|
|
75
|
+
(
|
|
76
|
+
k_min,
|
|
77
|
+
mu_min,
|
|
78
|
+
rho_min,
|
|
79
|
+
k_fl,
|
|
80
|
+
rho_fl,
|
|
81
|
+
phi,
|
|
82
|
+
perm,
|
|
83
|
+
visco,
|
|
84
|
+
alpha,
|
|
85
|
+
v,
|
|
86
|
+
tau,
|
|
87
|
+
frequency,
|
|
88
|
+
angle,
|
|
89
|
+
frac_inc_con,
|
|
90
|
+
frac_inc_ani,
|
|
91
|
+
pressure,
|
|
92
|
+
fcn,
|
|
93
|
+
ctrl_connected,
|
|
94
|
+
ctrl_anisotropy,
|
|
95
|
+
) = parse_t_matrix_inputs(
|
|
96
|
+
k_min,
|
|
97
|
+
mu_min,
|
|
98
|
+
rho_min,
|
|
99
|
+
k_fl,
|
|
100
|
+
rho_fl,
|
|
101
|
+
phi,
|
|
102
|
+
perm,
|
|
103
|
+
visco,
|
|
104
|
+
alpha,
|
|
105
|
+
v,
|
|
106
|
+
tau,
|
|
107
|
+
frequency,
|
|
108
|
+
angle,
|
|
109
|
+
frac_inc_con,
|
|
110
|
+
frac_inc_ani,
|
|
111
|
+
pressure,
|
|
112
|
+
scenario,
|
|
113
|
+
fcn,
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
# If there are no pressure steps to consider the whole task can be assigned to the T-Matrix function
|
|
117
|
+
if pressure is None:
|
|
118
|
+
vp, vsv, vsh, rho = fcn(
|
|
119
|
+
k_min,
|
|
120
|
+
mu_min,
|
|
121
|
+
rho_min,
|
|
122
|
+
k_fl,
|
|
123
|
+
rho_fl,
|
|
124
|
+
phi,
|
|
125
|
+
perm,
|
|
126
|
+
visco,
|
|
127
|
+
alpha,
|
|
128
|
+
v,
|
|
129
|
+
tau,
|
|
130
|
+
frequency,
|
|
131
|
+
angle,
|
|
132
|
+
frac_inc_con,
|
|
133
|
+
frac_inc_ani,
|
|
134
|
+
)
|
|
135
|
+
return vp, vsv, vsh, rho
|
|
136
|
+
|
|
137
|
+
# Pressure steps is mimicking depletion, and inclusion shape parameters can be changed
|
|
138
|
+
# In Remy's implementation it is generally possible to have different alpha's and v's for connected and
|
|
139
|
+
# isolated part, but this is not included directly in Calculo's implementation in C++. For the time being,
|
|
140
|
+
# this possibility is not included here
|
|
141
|
+
|
|
142
|
+
log_length = phi.shape[0]
|
|
143
|
+
pressure_steps = pressure.shape[0]
|
|
144
|
+
# It is the change from initial pressure (first value in the pressure vector) that is input to the function
|
|
145
|
+
# that estimates matrix pressure sensitivity
|
|
146
|
+
delta_pres = np.diff(pressure)
|
|
147
|
+
|
|
148
|
+
# Predefine output vectors
|
|
149
|
+
vp = np.zeros((log_length, pressure_steps))
|
|
150
|
+
vs_v = np.zeros((log_length, pressure_steps))
|
|
151
|
+
vs_h = np.zeros((log_length, pressure_steps))
|
|
152
|
+
rho_b_est = np.zeros((log_length, pressure_steps))
|
|
153
|
+
|
|
154
|
+
# Matrix properties needed as input to calc_pressure_vec
|
|
155
|
+
c0, s0, gd = pressure_input_utility(k_min, mu_min, log_length)
|
|
156
|
+
|
|
157
|
+
for i in range(pressure_steps):
|
|
158
|
+
vp[:, i], vs_v[:, i], vs_h[:, i], rho_b_est[:, i] = fcn(
|
|
159
|
+
k_min,
|
|
160
|
+
mu_min,
|
|
161
|
+
rho_min,
|
|
162
|
+
k_fl,
|
|
163
|
+
rho_fl,
|
|
164
|
+
phi,
|
|
165
|
+
perm,
|
|
166
|
+
visco,
|
|
167
|
+
alpha,
|
|
168
|
+
v,
|
|
169
|
+
tau,
|
|
170
|
+
frequency,
|
|
171
|
+
angle,
|
|
172
|
+
frac_inc_con,
|
|
173
|
+
frac_inc_ani,
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
if i != pressure_steps - 1:
|
|
177
|
+
# Need to check for extreme cases with all connected or all isolated
|
|
178
|
+
if ctrl_connected != 0:
|
|
179
|
+
v_con = v * (phi * frac_inc_con).reshape(log_length, 1)
|
|
180
|
+
else:
|
|
181
|
+
v_con = np.zeros(v.shape)
|
|
182
|
+
if ctrl_connected != 2:
|
|
183
|
+
v_iso = v * (phi * (1 - frac_inc_con)).reshape(log_length, 1)
|
|
184
|
+
else:
|
|
185
|
+
v_iso = np.zeros(v.shape)
|
|
186
|
+
alpha_con, v_con, alpha_iso, v_iso, tau, gamma = calc_pressure_vec(
|
|
187
|
+
alpha,
|
|
188
|
+
alpha,
|
|
189
|
+
v_con,
|
|
190
|
+
v_iso,
|
|
191
|
+
c0,
|
|
192
|
+
s0,
|
|
193
|
+
gd,
|
|
194
|
+
delta_pres[i],
|
|
195
|
+
tau,
|
|
196
|
+
np.zeros_like(tau),
|
|
197
|
+
k_fl,
|
|
198
|
+
ctrl_connected,
|
|
199
|
+
frac_inc_ani,
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
# Post-process outputs from calc_pressure_vec to match required inputs to the T-Matrix function
|
|
203
|
+
# frac_inc_con, v and alpha are inputs that need to be updated
|
|
204
|
+
# As mentioned: assume that there is no distinction between alpha_con and alpha_iso, that could only
|
|
205
|
+
# happen if they differed from the start
|
|
206
|
+
|
|
207
|
+
# v_con, alpha_con or v_iso, alpha_iso can be returned as None from calc_pressure_vec
|
|
208
|
+
if ctrl_connected == 0:
|
|
209
|
+
v_con = np.zeros_like(v_iso)
|
|
210
|
+
alpha = alpha_iso
|
|
211
|
+
elif ctrl_connected == 2:
|
|
212
|
+
alpha = alpha_con
|
|
213
|
+
v_iso = np.zeros_like(v_con)
|
|
214
|
+
else:
|
|
215
|
+
alpha = alpha_con
|
|
216
|
+
# Don't divide by zero
|
|
217
|
+
idx_zero = phi == 0
|
|
218
|
+
if np.any(idx_zero):
|
|
219
|
+
v = v_con + v_iso
|
|
220
|
+
no_zero = np.sum(idx_zero)
|
|
221
|
+
v[~idx_zero, :] = v[~idx_zero, :] / phi[~idx_zero].reshape(
|
|
222
|
+
log_length - no_zero, 1
|
|
223
|
+
)
|
|
224
|
+
else:
|
|
225
|
+
v = (v_con + v_iso) / phi.reshape(log_length, 1)
|
|
226
|
+
|
|
227
|
+
# frac_inc_con is close to a single value, only numerical difference in the range 10^-16, can safely
|
|
228
|
+
# take the average over the alphas to make it match expected input shape
|
|
229
|
+
frac_inc_con = np.mean(v_con / (v_con + v_iso), axis=1)
|
|
230
|
+
|
|
231
|
+
# Return variables for each pressure step
|
|
232
|
+
vp_out = []
|
|
233
|
+
vs_v_out = []
|
|
234
|
+
vs_h_out = []
|
|
235
|
+
|
|
236
|
+
# Only one rho is needed - no change
|
|
237
|
+
rho_out = rho_b_est[:, 0]
|
|
238
|
+
|
|
239
|
+
for i in range(pressure_steps):
|
|
240
|
+
vp_out.append(vp[:, i])
|
|
241
|
+
vs_v_out.append(vs_v[:, i])
|
|
242
|
+
vs_h_out.append(vs_h[:, i])
|
|
243
|
+
return vp_out + vs_v_out + vs_h_out + [rho_out]
|