rock-physics-open 0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of rock-physics-open might be problematic. Click here for more details.
- rock_physics_open/__init__.py +0 -0
- rock_physics_open/equinor_utilities/__init__.py +0 -0
- rock_physics_open/equinor_utilities/anisotropy.py +162 -0
- rock_physics_open/equinor_utilities/classification_functions/__init__.py +17 -0
- rock_physics_open/equinor_utilities/classification_functions/class_stats.py +58 -0
- rock_physics_open/equinor_utilities/classification_functions/lin_class.py +47 -0
- rock_physics_open/equinor_utilities/classification_functions/mahal_class.py +56 -0
- rock_physics_open/equinor_utilities/classification_functions/norm_class.py +65 -0
- rock_physics_open/equinor_utilities/classification_functions/poly_class.py +40 -0
- rock_physics_open/equinor_utilities/classification_functions/post_prob.py +26 -0
- rock_physics_open/equinor_utilities/classification_functions/two_step_classification.py +46 -0
- rock_physics_open/equinor_utilities/conversions.py +10 -0
- rock_physics_open/equinor_utilities/gen_utilities/__init__.py +11 -0
- rock_physics_open/equinor_utilities/gen_utilities/dict_to_float.py +33 -0
- rock_physics_open/equinor_utilities/gen_utilities/dim_check_vector.py +83 -0
- rock_physics_open/equinor_utilities/gen_utilities/filter_input.py +126 -0
- rock_physics_open/equinor_utilities/gen_utilities/filter_output.py +78 -0
- rock_physics_open/equinor_utilities/machine_learning_utilities/__init__.py +14 -0
- rock_physics_open/equinor_utilities/machine_learning_utilities/dummy_vars.py +42 -0
- rock_physics_open/equinor_utilities/machine_learning_utilities/exponential_model.py +119 -0
- rock_physics_open/equinor_utilities/machine_learning_utilities/import_ml_models.py +61 -0
- rock_physics_open/equinor_utilities/machine_learning_utilities/run_regression.py +151 -0
- rock_physics_open/equinor_utilities/machine_learning_utilities/sigmoidal_model.py +188 -0
- rock_physics_open/equinor_utilities/snapshot_test_utilities/__init__.py +10 -0
- rock_physics_open/equinor_utilities/snapshot_test_utilities/compare_snapshots.py +145 -0
- rock_physics_open/equinor_utilities/snapshot_test_utilities/snapshots.py +54 -0
- rock_physics_open/equinor_utilities/std_functions/__init__.py +43 -0
- rock_physics_open/equinor_utilities/std_functions/backus_ave.py +53 -0
- rock_physics_open/equinor_utilities/std_functions/dvorkin_nur.py +69 -0
- rock_physics_open/equinor_utilities/std_functions/gassmann.py +140 -0
- rock_physics_open/equinor_utilities/std_functions/hashin_shtrikman.py +195 -0
- rock_physics_open/equinor_utilities/std_functions/hertz_mindlin.py +43 -0
- rock_physics_open/equinor_utilities/std_functions/moduli_velocity.py +51 -0
- rock_physics_open/equinor_utilities/std_functions/reflection_eq.py +98 -0
- rock_physics_open/equinor_utilities/std_functions/rho.py +59 -0
- rock_physics_open/equinor_utilities/std_functions/voigt_reuss_hill.py +128 -0
- rock_physics_open/equinor_utilities/std_functions/walton.py +38 -0
- rock_physics_open/equinor_utilities/std_functions/wood_brie.py +77 -0
- rock_physics_open/equinor_utilities/various_utilities/Equinor_logo.gif +0 -0
- rock_physics_open/equinor_utilities/various_utilities/Equinor_logo.ico +0 -0
- rock_physics_open/equinor_utilities/various_utilities/__init__.py +24 -0
- rock_physics_open/equinor_utilities/various_utilities/display_result_statistics.py +83 -0
- rock_physics_open/equinor_utilities/various_utilities/gassmann_dry_mod.py +37 -0
- rock_physics_open/equinor_utilities/various_utilities/gassmann_mod.py +37 -0
- rock_physics_open/equinor_utilities/various_utilities/gassmann_sub_mod.py +53 -0
- rock_physics_open/equinor_utilities/various_utilities/hs_average.py +40 -0
- rock_physics_open/equinor_utilities/various_utilities/pressure.py +88 -0
- rock_physics_open/equinor_utilities/various_utilities/reflectivity.py +85 -0
- rock_physics_open/equinor_utilities/various_utilities/timeshift.py +91 -0
- rock_physics_open/equinor_utilities/various_utilities/vp_vs_rho_set_statistics.py +154 -0
- rock_physics_open/equinor_utilities/various_utilities/vrh_3_min.py +61 -0
- rock_physics_open/fluid_models/__init__.py +9 -0
- rock_physics_open/fluid_models/brine_model/__init__.py +5 -0
- rock_physics_open/fluid_models/brine_model/brine_properties.py +143 -0
- rock_physics_open/fluid_models/gas_model/__init__.py +5 -0
- rock_physics_open/fluid_models/gas_model/gas_properties.py +277 -0
- rock_physics_open/fluid_models/oil_model/__init__.py +5 -0
- rock_physics_open/fluid_models/oil_model/dead_oil_density.py +60 -0
- rock_physics_open/fluid_models/oil_model/dead_oil_velocity.py +28 -0
- rock_physics_open/fluid_models/oil_model/live_oil_density.py +79 -0
- rock_physics_open/fluid_models/oil_model/live_oil_velocity.py +24 -0
- rock_physics_open/fluid_models/oil_model/oil_bubble_point.py +69 -0
- rock_physics_open/fluid_models/oil_model/oil_properties.py +114 -0
- rock_physics_open/sandstone_models/__init__.py +57 -0
- rock_physics_open/sandstone_models/cemented_shalysand_sandyshale_models.py +304 -0
- rock_physics_open/sandstone_models/constant_cement_models.py +204 -0
- rock_physics_open/sandstone_models/constant_cement_optimisation.py +122 -0
- rock_physics_open/sandstone_models/contact_cement_model.py +138 -0
- rock_physics_open/sandstone_models/curvefit_sandstone_models.py +143 -0
- rock_physics_open/sandstone_models/friable_models.py +178 -0
- rock_physics_open/sandstone_models/friable_optimisation.py +112 -0
- rock_physics_open/sandstone_models/friable_shalysand_sandyshale_models.py +235 -0
- rock_physics_open/sandstone_models/patchy_cement_fluid_substitution_model.py +477 -0
- rock_physics_open/sandstone_models/patchy_cement_model.py +286 -0
- rock_physics_open/sandstone_models/patchy_cement_optimisation.py +251 -0
- rock_physics_open/sandstone_models/unresolved_cemented_sandshale_models.py +134 -0
- rock_physics_open/sandstone_models/unresolved_friable_sandshale_models.py +126 -0
- rock_physics_open/shale_models/__init__.py +19 -0
- rock_physics_open/shale_models/dem.py +174 -0
- rock_physics_open/shale_models/dem_dual_por.py +61 -0
- rock_physics_open/shale_models/kus_tok.py +59 -0
- rock_physics_open/shale_models/multi_sca.py +133 -0
- rock_physics_open/shale_models/pq.py +102 -0
- rock_physics_open/shale_models/sca.py +90 -0
- rock_physics_open/shale_models/shale4_mineral.py +147 -0
- rock_physics_open/shale_models/shale4_mineral_dem_overlay.py +92 -0
- rock_physics_open/span_wagner/__init__.py +5 -0
- rock_physics_open/span_wagner/co2_properties.py +438 -0
- rock_physics_open/span_wagner/coefficients.py +165 -0
- rock_physics_open/span_wagner/equations.py +104 -0
- rock_physics_open/span_wagner/tables/__init__.py +0 -0
- rock_physics_open/span_wagner/tables/carbon_dioxide_density.npz +0 -0
- rock_physics_open/span_wagner/tables/lookup_table.py +33 -0
- rock_physics_open/t_matrix_models/Equinor_logo.ico +0 -0
- rock_physics_open/t_matrix_models/__init__.py +45 -0
- rock_physics_open/t_matrix_models/carbonate_pressure_substitution.py +124 -0
- rock_physics_open/t_matrix_models/curvefit_t_matrix_exp.py +124 -0
- rock_physics_open/t_matrix_models/curvefit_t_matrix_min.py +86 -0
- rock_physics_open/t_matrix_models/opt_subst_utilities.py +415 -0
- rock_physics_open/t_matrix_models/parse_t_matrix_inputs.py +297 -0
- rock_physics_open/t_matrix_models/run_t_matrix.py +243 -0
- rock_physics_open/t_matrix_models/t_matrix_C.py +210 -0
- rock_physics_open/t_matrix_models/t_matrix_opt_fluid_sub_exp.py +137 -0
- rock_physics_open/t_matrix_models/t_matrix_opt_fluid_sub_petec.py +163 -0
- rock_physics_open/t_matrix_models/t_matrix_opt_forward_model_exp.py +72 -0
- rock_physics_open/t_matrix_models/t_matrix_opt_forward_model_min.py +86 -0
- rock_physics_open/t_matrix_models/t_matrix_parameter_optimisation_exp.py +172 -0
- rock_physics_open/t_matrix_models/t_matrix_parameter_optimisation_min.py +159 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/__init__.py +12 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/array_functions.py +75 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/calc_c_eff.py +163 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/calc_isolated.py +95 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/calc_kd.py +40 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/calc_kd_eff.py +116 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/calc_kd_uuv.py +18 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/calc_pressure.py +140 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/calc_t.py +71 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/calc_td.py +42 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/calc_theta.py +43 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/calc_x.py +33 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/calc_z.py +50 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/check_and_tile.py +43 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/g_tensor.py +140 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/iso_av.py +60 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/iso_ave_all.py +55 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/pressure_input.py +44 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/t_matrix_vec.py +278 -0
- rock_physics_open/t_matrix_models/t_matrix_vector/velocity_vti_angles.py +81 -0
- rock_physics_open/t_matrix_models/tmatrix_python.dll +0 -0
- rock_physics_open/t_matrix_models/tmatrix_python.so +0 -0
- rock_physics_open/ternary_plots/__init__.py +3 -0
- rock_physics_open/ternary_plots/gen_ternary_plot.py +73 -0
- rock_physics_open/ternary_plots/shale_prop_ternary.py +337 -0
- rock_physics_open/ternary_plots/ternary_patches.py +277 -0
- rock_physics_open/ternary_plots/ternary_plot_utilities.py +197 -0
- rock_physics_open/ternary_plots/unconventionals_ternary.py +75 -0
- rock_physics_open/version.py +21 -0
- rock_physics_open-0.0.dist-info/METADATA +92 -0
- rock_physics_open-0.0.dist-info/RECORD +142 -0
- rock_physics_open-0.0.dist-info/WHEEL +5 -0
- rock_physics_open-0.0.dist-info/licenses/LICENSE +165 -0
- rock_physics_open-0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import pickle
|
|
3
|
+
|
|
4
|
+
# from scipy.optimize import minimize, Bounds
|
|
5
|
+
import sys
|
|
6
|
+
|
|
7
|
+
import numpy as np
|
|
8
|
+
from scipy.optimize import curve_fit
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def curve_fit_wrapper(x_init, opt_func, x_data, y_data, *args, **opt_kwargs):
|
|
12
|
+
"""Use in tests with scipy.optimize.minimize instead of curve_fit.
|
|
13
|
+
|
|
14
|
+
Parameters
|
|
15
|
+
----------
|
|
16
|
+
x_init : np.ndarray
|
|
17
|
+
Initial guess for parameters.
|
|
18
|
+
opt_func : callable
|
|
19
|
+
Function to optimize.
|
|
20
|
+
x_data : np.ndarray
|
|
21
|
+
Input data to opt_func.
|
|
22
|
+
y_data : np.ndarray
|
|
23
|
+
Results that the optimisation should match.
|
|
24
|
+
args :
|
|
25
|
+
args opt_func.
|
|
26
|
+
opt_kwargs :
|
|
27
|
+
kwargs opt_func.
|
|
28
|
+
|
|
29
|
+
Returns
|
|
30
|
+
-------
|
|
31
|
+
np.ndarray
|
|
32
|
+
res values.
|
|
33
|
+
"""
|
|
34
|
+
y_pred = opt_func(x_data, *x_init, *args, **opt_kwargs)
|
|
35
|
+
return np.sum(np.sqrt((y_data - y_pred) ** 2))
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def gen_opt_routine(
|
|
39
|
+
opt_function, x_data_orig, y_data, x_init, low_bound, high_bound, **opt_kwargs
|
|
40
|
+
):
|
|
41
|
+
"""
|
|
42
|
+
This function is a lean method for running optimisation with the given opt_function in curve_fit. Predicted values,
|
|
43
|
+
residuals to the observed values and optimal parameters are returned.
|
|
44
|
+
|
|
45
|
+
Parameters
|
|
46
|
+
----------
|
|
47
|
+
opt_function : callable
|
|
48
|
+
function to optimise
|
|
49
|
+
x_data_orig : np.ndarray
|
|
50
|
+
input data to the function - independent variables
|
|
51
|
+
y_data : np.ndarray
|
|
52
|
+
results that the optimisation should match - dependent variables
|
|
53
|
+
x_init : np.ndarray
|
|
54
|
+
initial guess for parameters
|
|
55
|
+
low_bound : np.ndarray
|
|
56
|
+
parameter low bound
|
|
57
|
+
high_bound : np.ndarray
|
|
58
|
+
parameter high bound
|
|
59
|
+
opt_kwargs : dict
|
|
60
|
+
optional meta-parameters to the optimisation function
|
|
61
|
+
|
|
62
|
+
Returns
|
|
63
|
+
-------
|
|
64
|
+
tuple
|
|
65
|
+
y_pred, y_res, opt_params : (np.ndarray, np.ndarray, np.ndarray).
|
|
66
|
+
y_pred : predicted values,
|
|
67
|
+
y_res : residual values,
|
|
68
|
+
opt_params : optimal model parameters.
|
|
69
|
+
"""
|
|
70
|
+
try:
|
|
71
|
+
opt_params, param_cov = curve_fit(
|
|
72
|
+
opt_function,
|
|
73
|
+
x_data_orig,
|
|
74
|
+
y_data.flatten("F"),
|
|
75
|
+
x_init,
|
|
76
|
+
bounds=(low_bound, high_bound),
|
|
77
|
+
method="trf",
|
|
78
|
+
loss="soft_l1",
|
|
79
|
+
**opt_kwargs,
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
except ValueError:
|
|
83
|
+
raise ValueError(
|
|
84
|
+
"gen_opt_routine: failed in optimisation step: {}".format(
|
|
85
|
+
str(sys.exc_info())
|
|
86
|
+
)
|
|
87
|
+
)
|
|
88
|
+
else:
|
|
89
|
+
y_pred = np.reshape(
|
|
90
|
+
opt_function(x_data_orig, *opt_params), y_data.shape, order="F"
|
|
91
|
+
)
|
|
92
|
+
y_res = y_pred - y_data
|
|
93
|
+
|
|
94
|
+
# Alternative implementation, not shown to improve results
|
|
95
|
+
# alt_opt_params = minimize(curve_fit_wrapper, x_init, args=(opt_function, x_data_orig, y_data.flatten('F')),
|
|
96
|
+
# bounds=Bounds(low_bound, high_bound), method='SLSQP', options={'maxiter': 10000})
|
|
97
|
+
# y_pred_1 = np.reshape(opt_function(x_data_orig, *alt_opt_params['x'], **opt_kwargs), y_data.shape, order='F')
|
|
98
|
+
# y_res_1 = y_pred_1 - y_data
|
|
99
|
+
# return y_pred_1, y_res_1, alt_opt_params['x']
|
|
100
|
+
|
|
101
|
+
return y_pred, y_res, opt_params
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def gen_mod_routine(opt_function, xdata_orig, ydata_shape, opt_params):
|
|
105
|
+
"""Predict modelled values based on an earlier optimisation run for optimal model parameters.
|
|
106
|
+
|
|
107
|
+
Parameters
|
|
108
|
+
----------
|
|
109
|
+
opt_function : callable
|
|
110
|
+
Function to optimise.
|
|
111
|
+
xdata_orig : np.ndarray
|
|
112
|
+
Input data to the function - independent variables.
|
|
113
|
+
ydata_shape : (int, int)
|
|
114
|
+
Shape of y_data.
|
|
115
|
+
opt_params : np.ndarray
|
|
116
|
+
Optimal model parameters.
|
|
117
|
+
|
|
118
|
+
Returns
|
|
119
|
+
-------
|
|
120
|
+
np.ndarray
|
|
121
|
+
Predicted values.
|
|
122
|
+
"""
|
|
123
|
+
# Estimation of values
|
|
124
|
+
return np.reshape(opt_function(xdata_orig, *opt_params), ydata_shape, order="F")
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def gen_sub_routine(opt_function, xdata_orig, xdata_new, ydata, opt_params):
|
|
128
|
+
"""General substitution function based on a calibrated/optimised model and with two sets of input parameters.
|
|
129
|
+
The substituted values are calculated as the original observations plus the difference of the two modelling
|
|
130
|
+
steps.
|
|
131
|
+
|
|
132
|
+
Parameters
|
|
133
|
+
----------
|
|
134
|
+
opt_function : callable
|
|
135
|
+
Function to optimise.
|
|
136
|
+
xdata_orig : np.ndarray
|
|
137
|
+
Input data to the function step 1 - independent variables.
|
|
138
|
+
xdata_new : np.ndarray
|
|
139
|
+
Input data to the function step 2 - independent variables.
|
|
140
|
+
ydata : np.ndarray
|
|
141
|
+
Original observed values step 1.
|
|
142
|
+
opt_params : np.ndarray
|
|
143
|
+
Set of optimal parameters to model.
|
|
144
|
+
|
|
145
|
+
Returns
|
|
146
|
+
-------
|
|
147
|
+
tuple
|
|
148
|
+
y_final, y_pred, y_res : (np.ndarray, np.ndarray, np.ndarray).
|
|
149
|
+
Original observed data + difference in estimation between steps 0 and 1, y_pred - modelled data,
|
|
150
|
+
y_res - residuals, opt_params - best parameter setting.
|
|
151
|
+
"""
|
|
152
|
+
# Estimation of initial values
|
|
153
|
+
y_pred = np.reshape(opt_function(xdata_orig, *opt_params), ydata.shape, order="F")
|
|
154
|
+
# Estimation step for substituted fluid properties
|
|
155
|
+
y_subst = np.reshape(opt_function(xdata_new, *opt_params), ydata.shape, "F")
|
|
156
|
+
|
|
157
|
+
y_res = y_pred - ydata
|
|
158
|
+
y_diff = y_subst - y_pred
|
|
159
|
+
y_final = ydata + y_diff
|
|
160
|
+
|
|
161
|
+
return y_final, y_pred, y_res
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def save_opt_params(
|
|
165
|
+
opt_type: str,
|
|
166
|
+
opt_params: np.ndarray,
|
|
167
|
+
file_name: str = "opt_params.pkl",
|
|
168
|
+
well_name: str = "Unknown well",
|
|
169
|
+
):
|
|
170
|
+
"""
|
|
171
|
+
Utility to save optimal parameters as a pickle file in a more readable format so that the optimisation method can be
|
|
172
|
+
recognised.
|
|
173
|
+
|
|
174
|
+
Parameters
|
|
175
|
+
----------
|
|
176
|
+
opt_type : str
|
|
177
|
+
String defining optimisation type.
|
|
178
|
+
opt_params : np.ndarray
|
|
179
|
+
Numpy array with parameters from optimisation.
|
|
180
|
+
file_name : str, optional
|
|
181
|
+
File to save results to, by default 'opt_params.pkl'.
|
|
182
|
+
well_name : str, optional
|
|
183
|
+
Name of the well which is used in optimisation, by default 'Unknown well'.
|
|
184
|
+
|
|
185
|
+
Raises
|
|
186
|
+
------
|
|
187
|
+
ValueError
|
|
188
|
+
If unknown optimisation opt_type.
|
|
189
|
+
"""
|
|
190
|
+
# Save the optimal parameters with info
|
|
191
|
+
if opt_type == "min": # optimisation with mineral input from well
|
|
192
|
+
opt_param_dict = {
|
|
193
|
+
"well_name": well_name,
|
|
194
|
+
"opt_ver": opt_type,
|
|
195
|
+
"f_ani": opt_params[0],
|
|
196
|
+
"f_con": opt_params[1],
|
|
197
|
+
"alpha_opt": opt_params[2:4],
|
|
198
|
+
"v_opt": opt_params[4],
|
|
199
|
+
"opt_vec": opt_params,
|
|
200
|
+
}
|
|
201
|
+
elif opt_type == "exp":
|
|
202
|
+
opt_param_dict = {
|
|
203
|
+
"well_name": well_name,
|
|
204
|
+
"opt_ver": opt_type,
|
|
205
|
+
"f_ani": opt_params[0],
|
|
206
|
+
"f_con": opt_params[1],
|
|
207
|
+
"alpha_opt": opt_params[2:4],
|
|
208
|
+
"v_opt": opt_params[4],
|
|
209
|
+
"k_carb": opt_params[5],
|
|
210
|
+
"mu_carb": opt_params[6],
|
|
211
|
+
"rho_carb": opt_params[7],
|
|
212
|
+
"k_sh": opt_params[8],
|
|
213
|
+
"mu_sh": opt_params[9],
|
|
214
|
+
"rho_sh": opt_params[10],
|
|
215
|
+
"opt_vec": opt_params,
|
|
216
|
+
}
|
|
217
|
+
elif opt_type == "pat_cem":
|
|
218
|
+
opt_param_dict = {
|
|
219
|
+
"well_name": well_name,
|
|
220
|
+
"opt_ver": opt_type,
|
|
221
|
+
"weight_k": opt_params[0],
|
|
222
|
+
"weight_mu": opt_params[1],
|
|
223
|
+
"shear_red": opt_params[2],
|
|
224
|
+
"frac_cem": opt_params[3],
|
|
225
|
+
"opt_vec": opt_params,
|
|
226
|
+
}
|
|
227
|
+
elif opt_type == "const_cem":
|
|
228
|
+
opt_param_dict = {
|
|
229
|
+
"well_name": well_name,
|
|
230
|
+
"opt_ver": opt_type,
|
|
231
|
+
"phi_c": opt_params[0],
|
|
232
|
+
"shear_red": opt_params[1],
|
|
233
|
+
"frac_cem": opt_params[2],
|
|
234
|
+
"opt_vec": opt_params,
|
|
235
|
+
}
|
|
236
|
+
elif opt_type == "friable":
|
|
237
|
+
opt_param_dict = {
|
|
238
|
+
"well_name": well_name,
|
|
239
|
+
"opt_ver": opt_type,
|
|
240
|
+
"phi_c": opt_params[0],
|
|
241
|
+
"shear_red": opt_params[1],
|
|
242
|
+
"opt_vec": opt_params,
|
|
243
|
+
}
|
|
244
|
+
else:
|
|
245
|
+
raise ValueError(
|
|
246
|
+
"save_opt_params: unknown optimisation opt_type: {}".format(opt_type)
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
with open(file_name, "wb") as file_out:
|
|
250
|
+
pickle.dump(opt_param_dict, file_out)
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
def opt_param_info():
|
|
254
|
+
"""Hard coded dictionaries returned.
|
|
255
|
+
Returns
|
|
256
|
+
-------
|
|
257
|
+
tuple
|
|
258
|
+
parameter_translation_dict, value_translation_dict, type_translation_dict.
|
|
259
|
+
"""
|
|
260
|
+
parameter_translation_dict = {
|
|
261
|
+
"opt_ver": "Optimisation version",
|
|
262
|
+
"no_incl_sets": "Number of inclusion sets",
|
|
263
|
+
"ang_sym": "Angle of symmetry plane [°]",
|
|
264
|
+
"f_ani": "Fraction of anisotropic inclusions",
|
|
265
|
+
"f_con": "Fraction of connected inclusions",
|
|
266
|
+
"alpha_opt": "Optimal aspect ratios for inclusion sets",
|
|
267
|
+
"v_opt": "Ratio of volume for inclusion sets",
|
|
268
|
+
"k_carb": "Matrix (carbonate) bulk modulus [Pa]",
|
|
269
|
+
"mu_carb": "Matrix (carbonate) shear modulus [Pa]",
|
|
270
|
+
"rho_carb": "Matrix (carbonate) density [kg/m^3]",
|
|
271
|
+
"k_sh": "Mud/shale bulk modulus [Pa]",
|
|
272
|
+
"mu_sh": "Mud/shale shear modulus [Pa]",
|
|
273
|
+
"rho_sh": "Mud/shale density [kg/m^3]",
|
|
274
|
+
"k_sst": "Sst bulk modulus [Pa]",
|
|
275
|
+
"mu_sst": "Sst shear modulus [Pa]",
|
|
276
|
+
"rho_sst": "Sst density [kg/m^3]",
|
|
277
|
+
"frac_cem": "Cement fraction [fraction]",
|
|
278
|
+
"phi_c": "Critical porosity [fraction]",
|
|
279
|
+
"shear_red": "Reduction in tangential friction [fraction]",
|
|
280
|
+
"weight_k": "Bulk modulus weight for constant cement model",
|
|
281
|
+
"weight_mu": "Shear modulus weight for constant cement model",
|
|
282
|
+
}
|
|
283
|
+
value_translation_dict = {
|
|
284
|
+
"ang_sym": 90.0,
|
|
285
|
+
"k_carb": 95.0e9,
|
|
286
|
+
"mu_carb": 45.0e9,
|
|
287
|
+
"rho_carb": 2950.0,
|
|
288
|
+
"k_sh": 35.0e9,
|
|
289
|
+
"mu_sh": 20.0e9,
|
|
290
|
+
"rho_sh": 2750.0,
|
|
291
|
+
"k_sst": 45.0e9,
|
|
292
|
+
"mu_sst": 50.0e9,
|
|
293
|
+
"rho_sst": 2750.0,
|
|
294
|
+
}
|
|
295
|
+
type_translation_dict = {
|
|
296
|
+
"min": "PETEC (Mineral input) optimisation",
|
|
297
|
+
"exp": "Exploration type optimisation",
|
|
298
|
+
"pat_cem": "Patchy cement model",
|
|
299
|
+
"const_cem": "Constant cement model",
|
|
300
|
+
"friable": "Friable sand model",
|
|
301
|
+
}
|
|
302
|
+
return parameter_translation_dict, value_translation_dict, type_translation_dict
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
def load_opt_params(file_name: str):
|
|
306
|
+
"""Utility to load parameter file from optimisation run.
|
|
307
|
+
|
|
308
|
+
Parameters
|
|
309
|
+
----------
|
|
310
|
+
file_name : str
|
|
311
|
+
Input file name including path.
|
|
312
|
+
|
|
313
|
+
Returns
|
|
314
|
+
-------
|
|
315
|
+
tuple
|
|
316
|
+
opt_type: model type, no_sets: number of inclusion sets, opt_param: with all parameters for model.
|
|
317
|
+
"""
|
|
318
|
+
with open(file_name, "rb") as fin:
|
|
319
|
+
param_dict = pickle.load(fin)
|
|
320
|
+
opt_type = param_dict["opt_ver"]
|
|
321
|
+
opt_param = param_dict["opt_vec"]
|
|
322
|
+
opt_dict = param_dict
|
|
323
|
+
|
|
324
|
+
return opt_type, opt_param, opt_dict
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
def opt_param_to_ascii(
|
|
328
|
+
in_file, display_results=True, out_file=None, well_name="Unknown well", **kwargs
|
|
329
|
+
):
|
|
330
|
+
"""Utility to convert stored optimised parameters to ascii and display results or save to file.
|
|
331
|
+
|
|
332
|
+
Parameters
|
|
333
|
+
----------
|
|
334
|
+
in_file : str
|
|
335
|
+
File name for stored optimised parameters.
|
|
336
|
+
display_results : bool
|
|
337
|
+
Display results on screen, default True.
|
|
338
|
+
out_file : str or None
|
|
339
|
+
Optional store optimised parameters in ascii file.
|
|
340
|
+
well_name : str
|
|
341
|
+
Optional name of the well that is used in optimisation.
|
|
342
|
+
"""
|
|
343
|
+
with open(in_file, "rb") as f_in:
|
|
344
|
+
param_dict = pickle.load(f_in)
|
|
345
|
+
if well_name.lower() == "unknown well":
|
|
346
|
+
well_name = param_dict.pop("well_name", "Unknown Well")
|
|
347
|
+
|
|
348
|
+
(
|
|
349
|
+
parameter_translation_dict,
|
|
350
|
+
value_translation_dict,
|
|
351
|
+
type_translation_dict,
|
|
352
|
+
) = opt_param_info()
|
|
353
|
+
|
|
354
|
+
item = []
|
|
355
|
+
value = []
|
|
356
|
+
disp_string = ""
|
|
357
|
+
for opt_key, opt_value in param_dict.items():
|
|
358
|
+
if opt_key in parameter_translation_dict:
|
|
359
|
+
if opt_key in value_translation_dict:
|
|
360
|
+
opt_value = opt_value * value_translation_dict[opt_key]
|
|
361
|
+
opt_str = f" {opt_value:.4f}"
|
|
362
|
+
elif opt_key == "opt_ver":
|
|
363
|
+
opt_str = type_translation_dict[opt_value]
|
|
364
|
+
elif opt_key == "v_opt":
|
|
365
|
+
opt_value = np.append(opt_value, 1.0 - np.sum(opt_value))
|
|
366
|
+
opt_str = f" {opt_value:}"
|
|
367
|
+
else:
|
|
368
|
+
if isinstance(opt_value, float):
|
|
369
|
+
opt_str = f" {opt_value:.4f}"
|
|
370
|
+
else:
|
|
371
|
+
opt_str = f" {opt_value:}"
|
|
372
|
+
item.append(f"{parameter_translation_dict[opt_key]}: ")
|
|
373
|
+
value.append(opt_str)
|
|
374
|
+
disp_string += f"{parameter_translation_dict[opt_key]}: {opt_str}\n"
|
|
375
|
+
info_array = np.stack((item, value), axis=1)
|
|
376
|
+
|
|
377
|
+
if display_results:
|
|
378
|
+
from tkinter import END, Entry, Tk
|
|
379
|
+
|
|
380
|
+
class Table:
|
|
381
|
+
def __init__(self, tk_root, no_rows, no_cols, info):
|
|
382
|
+
# code for creating table
|
|
383
|
+
str_len = np.vectorize(len)
|
|
384
|
+
text_justify = ["right", "left"]
|
|
385
|
+
for i in range(no_rows):
|
|
386
|
+
for j in range(no_cols):
|
|
387
|
+
just = text_justify[0] if j == 0 else text_justify[1]
|
|
388
|
+
max_len = np.max(str_len(info[:, j]))
|
|
389
|
+
self.e = Entry(
|
|
390
|
+
root,
|
|
391
|
+
width=max_len + 2,
|
|
392
|
+
fg="black",
|
|
393
|
+
font=("Consolas", 11, "normal"),
|
|
394
|
+
justify=just,
|
|
395
|
+
)
|
|
396
|
+
self.e.grid(row=i, column=j)
|
|
397
|
+
self.e.insert(END, info[i][j])
|
|
398
|
+
|
|
399
|
+
root = Tk(**kwargs)
|
|
400
|
+
if well_name.lower() == "unknown well":
|
|
401
|
+
root.title("T Matrix Optimised Parameters")
|
|
402
|
+
else:
|
|
403
|
+
root.title(well_name)
|
|
404
|
+
if sys.platform.startswith("win"):
|
|
405
|
+
ico_file = os.path.join(os.path.dirname(__file__), "Equinor_logo.ico")
|
|
406
|
+
root.iconbitmap(ico_file)
|
|
407
|
+
Table(root, info_array.shape[0], info_array.shape[1], info_array)
|
|
408
|
+
root.attributes("-topmost", True)
|
|
409
|
+
root.mainloop()
|
|
410
|
+
|
|
411
|
+
if out_file is not None:
|
|
412
|
+
with open(out_file, "w") as f_out:
|
|
413
|
+
f_out.write(disp_string)
|
|
414
|
+
|
|
415
|
+
return
|
|
@@ -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
|
+
)
|