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,75 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def array_inverse(a: np.ndarray) -> np.ndarray:
|
|
5
|
+
"""Inverse of higher order array (3 dim) using linalg inv routine.
|
|
6
|
+
|
|
7
|
+
Parameters
|
|
8
|
+
----------
|
|
9
|
+
a : np.ndarray
|
|
10
|
+
An nxmxm numpy array.
|
|
11
|
+
|
|
12
|
+
Returns
|
|
13
|
+
-------
|
|
14
|
+
np.ndarray
|
|
15
|
+
An nxmxm array where [i, :, :] contains the inverse of A[i, :, :].
|
|
16
|
+
|
|
17
|
+
Raises
|
|
18
|
+
------
|
|
19
|
+
ValueError
|
|
20
|
+
If input of wrong shape.
|
|
21
|
+
"""
|
|
22
|
+
if not (a.ndim == 3 and a.shape[1] == a.shape[2]):
|
|
23
|
+
raise ValueError(f"{__name__}: mismatch in inputs variables dimension/shape")
|
|
24
|
+
|
|
25
|
+
return np.array([np.linalg.inv(x) for x in a])
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def array_matrix_mult(*args: np.ndarray) -> np.ndarray:
|
|
29
|
+
"""3-dim arrays are matrix multiplied args[j][i, :, :] @ args[j+1][i, :, :].
|
|
30
|
+
Input args should all be numpy arrays of shape nxmxm.
|
|
31
|
+
|
|
32
|
+
Returns
|
|
33
|
+
-------
|
|
34
|
+
np.ndarray
|
|
35
|
+
An nxmxm array with n args[i] @ args[i+1] @ ....
|
|
36
|
+
|
|
37
|
+
Raises
|
|
38
|
+
------
|
|
39
|
+
ValueError
|
|
40
|
+
If input is not a list or tuple.
|
|
41
|
+
ValueError
|
|
42
|
+
If mismatch in input shape/dimension.
|
|
43
|
+
ValueError
|
|
44
|
+
If mismatch in input shape/dimension.
|
|
45
|
+
"""
|
|
46
|
+
if not isinstance(args, (list, tuple)):
|
|
47
|
+
raise ValueError(f"{__name__}: inputs must be list or tuple")
|
|
48
|
+
if not len(args) > 1:
|
|
49
|
+
return args[0]
|
|
50
|
+
|
|
51
|
+
arg_shape = []
|
|
52
|
+
arg_type = []
|
|
53
|
+
for i in range(len(args)):
|
|
54
|
+
if not (
|
|
55
|
+
isinstance(args[i], np.ndarray)
|
|
56
|
+
and args[i].ndim == 3
|
|
57
|
+
and args[i].shape[1] == args[i].shape[2]
|
|
58
|
+
):
|
|
59
|
+
raise ValueError(
|
|
60
|
+
f"{__name__}: mismatch in inputs variables dimension/shape"
|
|
61
|
+
)
|
|
62
|
+
arg_shape.append(args[i].shape)
|
|
63
|
+
arg_type.append(args[i].dtype)
|
|
64
|
+
arg_shape = np.array(arg_shape)
|
|
65
|
+
arg_type = np.array(arg_type)
|
|
66
|
+
if not np.all(arg_shape[:, 0] == arg_shape[0, 0]):
|
|
67
|
+
raise ValueError(f"{__name__}: mismatch in inputs variables dimension/shape")
|
|
68
|
+
out_type = "complex128" if np.any(arg_type == np.dtype("complex128")) else "float64"
|
|
69
|
+
|
|
70
|
+
x = args[0]
|
|
71
|
+
|
|
72
|
+
for i in range(1, len(args)):
|
|
73
|
+
x = np.einsum("...ij,...jk->...ik", x, args[i], dtype=out_type)
|
|
74
|
+
|
|
75
|
+
return x
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from .array_functions import array_inverse, array_matrix_mult
|
|
4
|
+
from .calc_t import calc_t_vec
|
|
5
|
+
from .calc_theta import calc_theta_vec
|
|
6
|
+
from .calc_z import calc_z_vec
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def calc_c_eff_vec(c0, c1, gd, t, t_bar, v, frac_aniso):
|
|
10
|
+
"""
|
|
11
|
+
Equation 4 (page 222) Jakobsen et al. 2003 (The acoustic signature of fluid flow in complex
|
|
12
|
+
porous media).
|
|
13
|
+
Returns the effective stiffness tensor C* (nx6x6 matrix) calculated from the t-matrices t(r) (Eq. 1).
|
|
14
|
+
|
|
15
|
+
Parameters
|
|
16
|
+
----------
|
|
17
|
+
c0 : np.ndarray
|
|
18
|
+
Stiffness tensor of the host of the inclusion (nx6x6 matrix).
|
|
19
|
+
c1 : np.ndarray
|
|
20
|
+
Sum of the concentration and t-matrices (nx6x6 matrix).
|
|
21
|
+
gd : np.ndarray
|
|
22
|
+
Correlation function (nx6x6 matrix).
|
|
23
|
+
t : np.ndarray
|
|
24
|
+
t-matrices of the different inclusions (nx6x6xr matrix) (anisotropic).
|
|
25
|
+
t_bar: np.ndarray
|
|
26
|
+
t-matrices of the different inclusions (nx6x6xr matrix) (isotropic).
|
|
27
|
+
v : np.ndarray
|
|
28
|
+
Concentration of the inclusions (nxr vector).
|
|
29
|
+
frac_aniso: np.ndarray
|
|
30
|
+
Fraction of anisotropic.
|
|
31
|
+
|
|
32
|
+
Returns
|
|
33
|
+
-------
|
|
34
|
+
tuple
|
|
35
|
+
c_eff: np.ndarray.
|
|
36
|
+
c_eff: effective stiffness tensor C.
|
|
37
|
+
"""
|
|
38
|
+
if not (
|
|
39
|
+
c0.ndim == 3
|
|
40
|
+
and c1.ndim == 3
|
|
41
|
+
and gd.ndim == 3
|
|
42
|
+
and t.ndim == 4
|
|
43
|
+
and t_bar.ndim == 4
|
|
44
|
+
and v.ndim == 2
|
|
45
|
+
and np.all(
|
|
46
|
+
np.array(
|
|
47
|
+
[
|
|
48
|
+
c0.shape[1:2],
|
|
49
|
+
c1.shape[1:2],
|
|
50
|
+
gd.shape[1:2],
|
|
51
|
+
t.shape[1:2],
|
|
52
|
+
t_bar.shape[1:2],
|
|
53
|
+
]
|
|
54
|
+
)
|
|
55
|
+
== c0.shape[1]
|
|
56
|
+
)
|
|
57
|
+
and np.all(
|
|
58
|
+
np.array(
|
|
59
|
+
[
|
|
60
|
+
c0.shape[0],
|
|
61
|
+
c1.shape[0],
|
|
62
|
+
gd.shape[0],
|
|
63
|
+
t.shape[0],
|
|
64
|
+
t_bar.shape[0],
|
|
65
|
+
v.shape[0],
|
|
66
|
+
]
|
|
67
|
+
)
|
|
68
|
+
== c0.shape[0]
|
|
69
|
+
)
|
|
70
|
+
):
|
|
71
|
+
raise ValueError("calc_c_eff_vec: inconsistencies in input shapes")
|
|
72
|
+
|
|
73
|
+
log_length = c0.shape[0]
|
|
74
|
+
alpha_len = v.shape[1]
|
|
75
|
+
v = v.reshape((log_length, 1, 1, alpha_len))
|
|
76
|
+
i4 = np.eye(6)
|
|
77
|
+
|
|
78
|
+
c1 = c1 + np.sum(frac_aniso * v * t + (1.0 - frac_aniso) * v * t_bar, axis=3)
|
|
79
|
+
|
|
80
|
+
return c0 + array_matrix_mult(c1, array_inverse(i4 + array_matrix_mult(gd, c1)))
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def calc_c_eff_visco_vec(
|
|
84
|
+
vs,
|
|
85
|
+
k_r,
|
|
86
|
+
eta_f,
|
|
87
|
+
v,
|
|
88
|
+
gamma,
|
|
89
|
+
tau,
|
|
90
|
+
kd_uuvv,
|
|
91
|
+
kappa,
|
|
92
|
+
kappa_f,
|
|
93
|
+
c0,
|
|
94
|
+
s0,
|
|
95
|
+
c1,
|
|
96
|
+
td,
|
|
97
|
+
td_bar,
|
|
98
|
+
x,
|
|
99
|
+
x_bar,
|
|
100
|
+
gd,
|
|
101
|
+
frequency,
|
|
102
|
+
frac_ani,
|
|
103
|
+
):
|
|
104
|
+
"""
|
|
105
|
+
Returns the effective stiffness tensor C* for a visco-elastic system (6x6xnumber of frequencies).
|
|
106
|
+
|
|
107
|
+
Parameters
|
|
108
|
+
----------
|
|
109
|
+
vs : np.ndarray
|
|
110
|
+
The velocity used to calculate the wave number.
|
|
111
|
+
k_r : np.ndarray
|
|
112
|
+
Klinkenberg permability.
|
|
113
|
+
eta_f : np.ndarray
|
|
114
|
+
Viscosity (P).
|
|
115
|
+
v : np.ndarray
|
|
116
|
+
Concentration of the inclusions which are connected with respect to fluid flow.
|
|
117
|
+
gamma : np.ndarray
|
|
118
|
+
Gamma factor for each inclusion (1x(number of connected inclusions) vector).
|
|
119
|
+
tau : float or np.ndarray
|
|
120
|
+
Relaxation time constant.
|
|
121
|
+
kd_uuvv : np.ndarray
|
|
122
|
+
Kd_uuvv for each connected inclusion (1x(number of connected inclusions) vector.
|
|
123
|
+
kappa : np.ndarray
|
|
124
|
+
Bulk modulus of host material.
|
|
125
|
+
kappa_f : np.ndarray
|
|
126
|
+
Bulk modulus of the fluid.
|
|
127
|
+
c0 : np.ndarray
|
|
128
|
+
The stiffness tensor of host material (6x6 matrix).
|
|
129
|
+
s0 : np.ndarray
|
|
130
|
+
Inverse of C0.
|
|
131
|
+
c1 : np.ndarray
|
|
132
|
+
First order correction matrix(6x6 matrix). If there are isolated inclusions, C1 is sum of concentration and
|
|
133
|
+
t-matrices of the isolated part of the porosity.
|
|
134
|
+
td : np.ndarray
|
|
135
|
+
t-matrix tensors.
|
|
136
|
+
td_bar : np.ndarray
|
|
137
|
+
t-matrices of the connected inclusions(6x6x(numbers of inclusions) matrix).
|
|
138
|
+
x : np.ndarray
|
|
139
|
+
X-tensor.
|
|
140
|
+
x_bar : np.ndarray
|
|
141
|
+
X-tensor of the connected inclusions (6x6x(numbers of inclusions) matrix).
|
|
142
|
+
gd : np.ndarray
|
|
143
|
+
Correlation function (6x6 matrix).
|
|
144
|
+
frequency : float
|
|
145
|
+
Frequency under consideration.
|
|
146
|
+
frac_ani : np.ndarray
|
|
147
|
+
Fraction of anisotropic inclusions.
|
|
148
|
+
|
|
149
|
+
Returns
|
|
150
|
+
-------
|
|
151
|
+
np.ndarray
|
|
152
|
+
Effective stiffness tensor.
|
|
153
|
+
"""
|
|
154
|
+
dr = k_r / eta_f
|
|
155
|
+
|
|
156
|
+
omega = 2 * np.pi * frequency
|
|
157
|
+
k = omega / vs
|
|
158
|
+
theta = calc_theta_vec(v, omega, gamma, tau, kd_uuvv, dr, k, kappa, kappa_f)
|
|
159
|
+
z, z_bar = calc_z_vec(s0, td, td_bar, omega, gamma, v * frac_ani, tau)
|
|
160
|
+
t = calc_t_vec(td, theta, x, z, omega, gamma, tau, kappa_f)
|
|
161
|
+
t_bar = calc_t_vec(td_bar, theta, x_bar, z_bar, omega, gamma, tau, kappa_f)
|
|
162
|
+
|
|
163
|
+
return calc_c_eff_vec(c0, c1, gd, t, t_bar, v, frac_ani)
|
|
@@ -0,0 +1,95 @@
|
|
|
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
|
+
from .iso_av import iso_av_vec
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def calc_isolated_part_vec(c0, s_0, kappa_f, alpha, v, case_iso, frac_ani):
|
|
9
|
+
"""
|
|
10
|
+
Returns the first order correction tensor: sum of the concentrations and
|
|
11
|
+
t-matrices of the isolated porosity (6x6 matrix).
|
|
12
|
+
case_iso = 0 : 100% isotropic,
|
|
13
|
+
case_iso = 1 : mixed isotropic and anisotropic porosity,
|
|
14
|
+
case_iso = 2 : 100% anisotropic porosity.
|
|
15
|
+
|
|
16
|
+
Parameters
|
|
17
|
+
----------
|
|
18
|
+
c0 : np.ndarray
|
|
19
|
+
Stiffness tensor of the host material (6x6xn).
|
|
20
|
+
s_0 : np.ndarray
|
|
21
|
+
Inverse of stiffness tensor.
|
|
22
|
+
kappa_f : np.ndarray
|
|
23
|
+
Bulk modulus of the fluid (n length vector).
|
|
24
|
+
alpha : np.ndarray
|
|
25
|
+
Aspect ratios of all the inclusions (1xnumber of inclusions) vector).
|
|
26
|
+
v : np.ndarray
|
|
27
|
+
Concentration of all the inclusions (1xnumber of inclusions) vector).
|
|
28
|
+
case_iso : int
|
|
29
|
+
Control parameter.
|
|
30
|
+
frac_ani : float
|
|
31
|
+
Fraction of anisotropic inclusions.
|
|
32
|
+
|
|
33
|
+
Returns
|
|
34
|
+
-------
|
|
35
|
+
np.ndarray
|
|
36
|
+
c1: correction tensor.
|
|
37
|
+
|
|
38
|
+
Notes
|
|
39
|
+
-----
|
|
40
|
+
29.10.2020 HFLE: Simplification: alpha for isotropic and anisotropic part are the same. This has been default in
|
|
41
|
+
Remy's code, but this function had assumption that half of the inclusions could have different aspect ratio
|
|
42
|
+
13.11.2020 HFLE: In case of zero porosity, this routine returns a zero tensor, whereas the correct should have
|
|
43
|
+
been to return the host material tensor - corrected.
|
|
44
|
+
|
|
45
|
+
"""
|
|
46
|
+
if not (c0.ndim == 3 and s_0.ndim == 3):
|
|
47
|
+
raise ValueError(f"{__name__}: mismatch in inputs variables dimension/shape")
|
|
48
|
+
|
|
49
|
+
log_length = c0.shape[0]
|
|
50
|
+
if v.ndim != 2:
|
|
51
|
+
v = np.tile(v.reshape(1, v.shape[0]), (log_length, 1))
|
|
52
|
+
|
|
53
|
+
if alpha.ndim == 1 and alpha.shape[0] != c0.shape[0]:
|
|
54
|
+
alpha = np.tile(alpha.reshape(1, alpha.shape[0]), (log_length, 1))
|
|
55
|
+
alpha_len = alpha.shape[1]
|
|
56
|
+
|
|
57
|
+
cn = np.zeros_like(c0)
|
|
58
|
+
cn[:, 0:3, 0:3] = np.tile(kappa_f.reshape((log_length, 1, 1)), (1, 3, 3))
|
|
59
|
+
cn_d = cn - c0
|
|
60
|
+
i4 = np.tile(np.eye(6).reshape(1, 6, 6), (log_length, 1, 1))
|
|
61
|
+
c1 = np.zeros_like(c0)
|
|
62
|
+
|
|
63
|
+
# Will need G tensor for each alpha
|
|
64
|
+
g_arr = []
|
|
65
|
+
for i in range(alpha_len):
|
|
66
|
+
g_arr.append(g_tensor_vec(c0, s_0, alpha[:, i]))
|
|
67
|
+
|
|
68
|
+
if case_iso != 1:
|
|
69
|
+
# if there is only isotropic or anisotropic inclusions
|
|
70
|
+
for j in range(alpha_len):
|
|
71
|
+
t = array_matrix_mult(
|
|
72
|
+
cn_d, array_inverse(i4 - array_matrix_mult(g_arr[j], cn_d))
|
|
73
|
+
)
|
|
74
|
+
if case_iso != 2:
|
|
75
|
+
t = iso_av_vec(t)
|
|
76
|
+
c1 = c1 + v[:, j].reshape(log_length, 1, 1) * t
|
|
77
|
+
else:
|
|
78
|
+
# Isotropic and anisotropic part
|
|
79
|
+
for j in range(alpha_len):
|
|
80
|
+
t = array_matrix_mult(
|
|
81
|
+
cn_d, array_inverse(i4 - array_matrix_mult(g_arr[j], cn_d))
|
|
82
|
+
)
|
|
83
|
+
t = iso_av_vec(t)
|
|
84
|
+
c1 = c1 + ((1 - frac_ani) * v[:, j]).reshape(log_length, 1, 1) * t
|
|
85
|
+
for j in range(alpha_len):
|
|
86
|
+
t = array_matrix_mult(
|
|
87
|
+
cn_d, array_inverse(i4 - array_matrix_mult(g_arr[j], cn_d))
|
|
88
|
+
)
|
|
89
|
+
c1 = c1 + (frac_ani * v[:, j]).reshape(log_length, 1, 1) * t
|
|
90
|
+
|
|
91
|
+
idx_zero = np.sum(v, axis=1) == 0.0
|
|
92
|
+
if np.any(idx_zero):
|
|
93
|
+
c1[idx_zero] = c0[idx_zero]
|
|
94
|
+
|
|
95
|
+
return c1
|
|
@@ -0,0 +1,40 @@
|
|
|
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 calc_kd_vec(c0, i4, s_0, alpha):
|
|
8
|
+
"""
|
|
9
|
+
kd is a (nx6x6x(number of alphas)) matrix.
|
|
10
|
+
|
|
11
|
+
Parameters
|
|
12
|
+
----------
|
|
13
|
+
c0 : np.ndarray
|
|
14
|
+
Stiffness tensor of the host material (nx6x6 matrix).
|
|
15
|
+
i4 : np.ndarray
|
|
16
|
+
Array of 6x6 identity matrices.
|
|
17
|
+
s_0: np.ndarray
|
|
18
|
+
Inverse of stiffness tensor.
|
|
19
|
+
alpha : np.ndarray
|
|
20
|
+
Vector of aspect ratios (1x (number of aspect ratios) vector) or nx(number of (number of alphas)).
|
|
21
|
+
|
|
22
|
+
Returns
|
|
23
|
+
-------
|
|
24
|
+
np.ndarray
|
|
25
|
+
kd: stiffness tensor.
|
|
26
|
+
"""
|
|
27
|
+
log_length = c0.shape[0]
|
|
28
|
+
|
|
29
|
+
if alpha.ndim == 1 and alpha.shape[0] != c0.shape[0]:
|
|
30
|
+
alpha = np.tile(alpha.reshape(1, alpha.shape[0]), (log_length, 1))
|
|
31
|
+
L = alpha.shape[1]
|
|
32
|
+
kd = np.zeros((log_length, 6, 6, L))
|
|
33
|
+
|
|
34
|
+
for nc in range(L):
|
|
35
|
+
g = g_tensor_vec(c0, s_0, alpha[:, nc])
|
|
36
|
+
kd[:, :, :, nc] = array_matrix_mult(
|
|
37
|
+
array_inverse(i4 + array_matrix_mult(g, c0)), s_0
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
return kd
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from .array_functions import array_inverse, array_matrix_mult
|
|
4
|
+
from .calc_isolated import calc_isolated_part_vec
|
|
5
|
+
from .g_tensor import g_tensor_vec
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def calc_kd_eff_vec(
|
|
9
|
+
c0, s_0, k_fl, alpha_con, alpha_iso, v_con, v_iso, gd, ctrl, frac_ani
|
|
10
|
+
):
|
|
11
|
+
"""Returns the effective dry K-tensor (6x6x(numbers of inclusions) matrix.
|
|
12
|
+
If there is no connected or no isolated pores, the function returns a NaN for
|
|
13
|
+
the case which is not considered. E.g. if only isolated pores, the kd_eff_connected = NaN.
|
|
14
|
+
|
|
15
|
+
Note: When isolated pores, the pores are considered as filled when
|
|
16
|
+
calculating the dry effective K-tensor.
|
|
17
|
+
|
|
18
|
+
Parameters
|
|
19
|
+
----------
|
|
20
|
+
c0 : np.ndarray
|
|
21
|
+
Stiffness tensor of the host material (nx6x6 matrix).
|
|
22
|
+
s_0 : np.ndarray
|
|
23
|
+
Inverse of the stiffness tensor.
|
|
24
|
+
k_fl : np.ndarray
|
|
25
|
+
Bulk modulus of the fluid (n length vector).
|
|
26
|
+
alpha_con : np.ndarray
|
|
27
|
+
Aspect ratio of connected inclusions.
|
|
28
|
+
alpha_iso : np.ndarray
|
|
29
|
+
Aspect ratio of isolated inclusions.
|
|
30
|
+
v_con : np.ndarray
|
|
31
|
+
Concentration of connected pores.
|
|
32
|
+
v_iso : np.ndarray
|
|
33
|
+
Concentration of isolated pores.
|
|
34
|
+
gd : np.ndarray
|
|
35
|
+
Correlation function (nx6x6 matrix).
|
|
36
|
+
ctrl : int
|
|
37
|
+
0 :only isolated pores, 1 :both isolated and connected pores, 2 :only connected pores.
|
|
38
|
+
frac_ani : float
|
|
39
|
+
Fraction of anisotropic inclusions.
|
|
40
|
+
|
|
41
|
+
Returns
|
|
42
|
+
-------
|
|
43
|
+
tuple
|
|
44
|
+
kd_eff_isolated, kd_eff_connected: (np.ndarray, np.ndarray).
|
|
45
|
+
|
|
46
|
+
Notes
|
|
47
|
+
-----
|
|
48
|
+
Equations used can be found in:
|
|
49
|
+
Agersborg (2007), phd thesis:
|
|
50
|
+
https://bora.uib.no/handle/1956/2422
|
|
51
|
+
|
|
52
|
+
09.03.2012
|
|
53
|
+
Remy Agersborg
|
|
54
|
+
email: remy@agersborg.com
|
|
55
|
+
|
|
56
|
+
Translated to Python and vectorised by Harald Flesche, hfle@equinor.com 2020.
|
|
57
|
+
"""
|
|
58
|
+
log_len = c0.shape[0]
|
|
59
|
+
c1dry = np.zeros((log_len, 6, 6))
|
|
60
|
+
c2dry = np.zeros((log_len, 6, 6))
|
|
61
|
+
|
|
62
|
+
kd_eff_isolated = None
|
|
63
|
+
kd_eff_connected = None
|
|
64
|
+
|
|
65
|
+
c1_isolated = None
|
|
66
|
+
if ctrl != 2:
|
|
67
|
+
c1_isolated = calc_isolated_part_vec(
|
|
68
|
+
c0, s_0, k_fl, alpha_iso, v_iso, ctrl, frac_ani
|
|
69
|
+
)
|
|
70
|
+
c1dry = c1dry + c1_isolated
|
|
71
|
+
if alpha_iso.ndim == 1 and alpha_iso.shape[0] != c0.shape[0]:
|
|
72
|
+
alpha_iso = np.tile(alpha_iso.reshape(1, alpha_iso.shape[0]), (log_len, 1))
|
|
73
|
+
c2dry = c2dry + array_matrix_mult(c1_isolated, gd, c1_isolated)
|
|
74
|
+
if ctrl != 0:
|
|
75
|
+
c1_connected = calc_isolated_part_vec(
|
|
76
|
+
c0, s_0, np.zeros_like(k_fl), alpha_con, v_con, ctrl, frac_ani
|
|
77
|
+
)
|
|
78
|
+
c1dry = c1dry + c1_connected
|
|
79
|
+
if alpha_con.ndim == 1 and alpha_con.shape[0] != c0.shape[0]:
|
|
80
|
+
alpha_con = np.tile(alpha_con.reshape(1, alpha_con.shape[0]), (log_len, 1))
|
|
81
|
+
c2dry = c2dry + array_matrix_mult(c1_connected, gd, c1_connected)
|
|
82
|
+
if c1_isolated is not None:
|
|
83
|
+
c2dry = (
|
|
84
|
+
c2dry
|
|
85
|
+
+ array_matrix_mult(c1_connected, gd, c1_isolated)
|
|
86
|
+
+ array_matrix_mult(c1_isolated, gd, c1_connected)
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
i4 = np.tile(np.eye(6).reshape(1, 6, 6), (log_len, 1, 1))
|
|
90
|
+
c_eff_dry = c0 + array_matrix_mult(
|
|
91
|
+
c1dry, array_inverse(i4 + array_matrix_mult(array_inverse(c1dry), c2dry))
|
|
92
|
+
)
|
|
93
|
+
temp = array_matrix_mult(
|
|
94
|
+
i4,
|
|
95
|
+
array_inverse(i4 + array_matrix_mult(array_inverse(c1dry), c2dry)),
|
|
96
|
+
array_inverse(c_eff_dry),
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
# if only connected or mixed connected and isolated
|
|
100
|
+
if ctrl != 0:
|
|
101
|
+
kd_eff_connected = np.zeros((log_len, 6, 6, alpha_con.shape[1]))
|
|
102
|
+
for j in range(alpha_con.shape[1]):
|
|
103
|
+
g = g_tensor_vec(c0, s_0, alpha_con[:, j])
|
|
104
|
+
kd_eff_connected[:, :, :, j] = array_matrix_mult(
|
|
105
|
+
array_inverse(i4 + array_matrix_mult(g, c0)), temp
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
if ctrl != 2:
|
|
109
|
+
kd_eff_isolated = np.zeros((log_len, 6, 6, alpha_iso.shape[1]))
|
|
110
|
+
for j in range(alpha_iso.shape[1]):
|
|
111
|
+
g = g_tensor_vec(c0, s_0, alpha_iso[:, j])
|
|
112
|
+
kd_eff_isolated[:, :, :, j] = array_matrix_mult(
|
|
113
|
+
array_inverse(i4 + array_matrix_mult(g, c0)), temp
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
return kd_eff_isolated, kd_eff_connected
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def calc_kd_uuvv_vec(kd):
|
|
5
|
+
"""Returns the sum of dry k_uuvv.
|
|
6
|
+
|
|
7
|
+
Parameters
|
|
8
|
+
----------
|
|
9
|
+
kd : np.ndarray
|
|
10
|
+
The dry K-tensor (n, 6,6,(numbers of inclusions)) matrix.
|
|
11
|
+
|
|
12
|
+
Returns
|
|
13
|
+
-------
|
|
14
|
+
np.ndarray
|
|
15
|
+
Summed elements.
|
|
16
|
+
|
|
17
|
+
"""
|
|
18
|
+
return np.sum(kd[:, :3, :3, :], axis=(1, 2))
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from .calc_kd_eff import calc_kd_eff_vec
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def calc_pressure_vec(
|
|
7
|
+
alpha_con,
|
|
8
|
+
alpha_iso,
|
|
9
|
+
v_con,
|
|
10
|
+
v_iso,
|
|
11
|
+
c0,
|
|
12
|
+
s_0,
|
|
13
|
+
gd,
|
|
14
|
+
d_p,
|
|
15
|
+
tau,
|
|
16
|
+
gamma,
|
|
17
|
+
k_fl,
|
|
18
|
+
ctrl,
|
|
19
|
+
frac_ani,
|
|
20
|
+
):
|
|
21
|
+
"""Calculate the effect of depletion on aspect ratios.
|
|
22
|
+
|
|
23
|
+
Parameters
|
|
24
|
+
----------
|
|
25
|
+
alpha_con : np.ndarray
|
|
26
|
+
Aspect ratio for connected inclusions (r length vector).
|
|
27
|
+
alpha_iso : np.ndarray
|
|
28
|
+
Aspect ratio for connected inclusions (s length vector).
|
|
29
|
+
v_con : np.ndarray
|
|
30
|
+
Volume of connected inclusions (r length vector).
|
|
31
|
+
v_iso : np.ndarray
|
|
32
|
+
Volume of connected inclusions (s length vector).
|
|
33
|
+
c0 : np.ndarray
|
|
34
|
+
Stiffness tensor of host material (nx6x6 array).
|
|
35
|
+
s_0 : np.ndarray
|
|
36
|
+
Inverse of stiffness tensor (nx6x6 array).
|
|
37
|
+
gd : np.ndarray
|
|
38
|
+
The correlation function (green's tensor nx6x6 matrix).
|
|
39
|
+
d_p : float
|
|
40
|
+
Change in effective pressure.
|
|
41
|
+
tau : np.ndarray
|
|
42
|
+
Relaxation time constant ((numbers of connected pores) vector).
|
|
43
|
+
gamma : np.ndarray
|
|
44
|
+
Gamma factor ((numbers of connected pores) vector).
|
|
45
|
+
k_fl : np.ndarray
|
|
46
|
+
Fluid bulk modulus (n length vector).
|
|
47
|
+
ctrl : int
|
|
48
|
+
Control parameter.
|
|
49
|
+
frac_ani : float
|
|
50
|
+
Fraction of anisotropic inclusions.
|
|
51
|
+
|
|
52
|
+
Returns
|
|
53
|
+
-------
|
|
54
|
+
tuple
|
|
55
|
+
alpha_n_connected, v_n_connected, alpha_n_isolated, v_n_isolated, tau_n_out, gamma_n_out -
|
|
56
|
+
modified alphas, volumes, relaxation times and gamma factors.
|
|
57
|
+
|
|
58
|
+
Notes
|
|
59
|
+
-----
|
|
60
|
+
Equations used can be found in:
|
|
61
|
+
Agersborg (2007), phd thesis:
|
|
62
|
+
https://bora.uib.no/handle/1956/2422
|
|
63
|
+
|
|
64
|
+
09.03.2012
|
|
65
|
+
Remy Agersborg
|
|
66
|
+
email: remy@agersborg.com
|
|
67
|
+
|
|
68
|
+
Translated to Python and vectorised by Harald Flesche, hfle@equinor.com 2020
|
|
69
|
+
"""
|
|
70
|
+
|
|
71
|
+
def _new_values(k, sum_k, a, v, d_p, t, g):
|
|
72
|
+
# Local helper function to avoid code duplication
|
|
73
|
+
len_alpha = a.shape[1]
|
|
74
|
+
len_log = k.shape[0]
|
|
75
|
+
|
|
76
|
+
v_new = v * (
|
|
77
|
+
1
|
|
78
|
+
- (np.sum(k[:, 0:3, 0:3, :], axis=(1, 2)) - sum_k.reshape(len_log, 1)) * d_p
|
|
79
|
+
)
|
|
80
|
+
alpha_new = a * (
|
|
81
|
+
1
|
|
82
|
+
- (np.sum(k[:, 2, 0:3, :], axis=1) - np.sum(k[:, 0, 0:3, :], axis=1)) * d_p
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
idx_neg = (alpha_new < 0.0) | (v_new < 0.0)
|
|
86
|
+
idx_high = (alpha_new > 1.0) | (v_new > 1.0)
|
|
87
|
+
idx_inval = np.logical_or(idx_neg, idx_high)
|
|
88
|
+
|
|
89
|
+
for i in range(len_alpha):
|
|
90
|
+
# Maybe best to set undefined, but for now keep old values
|
|
91
|
+
# alpha_new[idx_inval] = np.nan
|
|
92
|
+
# v_new[idx_inval] = np.nan
|
|
93
|
+
alpha_new[idx_inval[:, i], i] = a[idx_inval[:, i], i]
|
|
94
|
+
v_new[idx_inval[:, i], i] = v[idx_inval[:, i], i]
|
|
95
|
+
tau_n = np.array(t)
|
|
96
|
+
gamma_n = np.array(g)
|
|
97
|
+
|
|
98
|
+
return v_new, alpha_new, tau_n, gamma_n
|
|
99
|
+
|
|
100
|
+
kd_eff_isolated, kd_eff_connected = calc_kd_eff_vec(
|
|
101
|
+
c0, s_0, k_fl, alpha_con, alpha_iso, v_con, v_iso, gd, ctrl, frac_ani
|
|
102
|
+
)
|
|
103
|
+
# Find the sum in the eq. 21 Jakobsen and Johansen 2005
|
|
104
|
+
sum_kd = 0.0
|
|
105
|
+
if ctrl != 2 and kd_eff_isolated is not None:
|
|
106
|
+
count_isolated = kd_eff_isolated.shape[3]
|
|
107
|
+
for j in range(count_isolated):
|
|
108
|
+
sum_kd = sum_kd + v_iso[:, j] * np.sum(
|
|
109
|
+
kd_eff_isolated[:, 0:3, 0:3, j], axis=(1, 2)
|
|
110
|
+
)
|
|
111
|
+
if ctrl != 0 and kd_eff_connected is not None:
|
|
112
|
+
count_connected = kd_eff_connected.shape[3]
|
|
113
|
+
for j in range(count_connected):
|
|
114
|
+
sum_kd = sum_kd + v_con[:, j] * np.sum(
|
|
115
|
+
kd_eff_connected[:, 0:3, 0:3, j], axis=(1, 2)
|
|
116
|
+
)
|
|
117
|
+
# Find the new concentration of inclusion
|
|
118
|
+
alpha_n_isolated = None
|
|
119
|
+
alpha_n_connected = None
|
|
120
|
+
v_n_isolated = None
|
|
121
|
+
v_n_connected = None
|
|
122
|
+
gamma_n_out = []
|
|
123
|
+
tau_n_out = []
|
|
124
|
+
if ctrl != 2:
|
|
125
|
+
v_n_isolated, alpha_n_isolated, _, _ = _new_values(
|
|
126
|
+
kd_eff_isolated, sum_kd, alpha_iso, v_iso, d_p, tau, gamma
|
|
127
|
+
)
|
|
128
|
+
if ctrl != 0:
|
|
129
|
+
v_n_connected, alpha_n_connected, tau_n_out, gamma_n_out = _new_values(
|
|
130
|
+
kd_eff_connected, sum_kd, alpha_con, v_con, d_p, tau, gamma
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
return (
|
|
134
|
+
alpha_n_connected,
|
|
135
|
+
v_n_connected,
|
|
136
|
+
alpha_n_isolated,
|
|
137
|
+
v_n_isolated,
|
|
138
|
+
tau_n_out,
|
|
139
|
+
gamma_n_out,
|
|
140
|
+
)
|