rock-physics-open 0.3.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. rock_physics_open/__init__.py +0 -0
  2. rock_physics_open/equinor_utilities/__init__.py +0 -0
  3. rock_physics_open/equinor_utilities/anisotropy.py +211 -0
  4. rock_physics_open/equinor_utilities/classification_functions/__init__.py +17 -0
  5. rock_physics_open/equinor_utilities/classification_functions/class_stats.py +68 -0
  6. rock_physics_open/equinor_utilities/classification_functions/lin_class.py +53 -0
  7. rock_physics_open/equinor_utilities/classification_functions/mahal_class.py +63 -0
  8. rock_physics_open/equinor_utilities/classification_functions/norm_class.py +73 -0
  9. rock_physics_open/equinor_utilities/classification_functions/poly_class.py +45 -0
  10. rock_physics_open/equinor_utilities/classification_functions/post_prob.py +27 -0
  11. rock_physics_open/equinor_utilities/classification_functions/two_step_classification.py +60 -0
  12. rock_physics_open/equinor_utilities/conversions.py +10 -0
  13. rock_physics_open/equinor_utilities/gen_utilities/__init__.py +11 -0
  14. rock_physics_open/equinor_utilities/gen_utilities/dict_to_float.py +38 -0
  15. rock_physics_open/equinor_utilities/gen_utilities/dim_check_vector.py +113 -0
  16. rock_physics_open/equinor_utilities/gen_utilities/filter_input.py +131 -0
  17. rock_physics_open/equinor_utilities/gen_utilities/filter_output.py +88 -0
  18. rock_physics_open/equinor_utilities/machine_learning_utilities/__init__.py +15 -0
  19. rock_physics_open/equinor_utilities/machine_learning_utilities/base_pressure_model.py +170 -0
  20. rock_physics_open/equinor_utilities/machine_learning_utilities/dummy_vars.py +53 -0
  21. rock_physics_open/equinor_utilities/machine_learning_utilities/exponential_model.py +137 -0
  22. rock_physics_open/equinor_utilities/machine_learning_utilities/import_ml_models.py +77 -0
  23. rock_physics_open/equinor_utilities/machine_learning_utilities/polynomial_model.py +132 -0
  24. rock_physics_open/equinor_utilities/machine_learning_utilities/run_regression.py +209 -0
  25. rock_physics_open/equinor_utilities/machine_learning_utilities/sigmoidal_model.py +241 -0
  26. rock_physics_open/equinor_utilities/optimisation_utilities/__init__.py +19 -0
  27. rock_physics_open/equinor_utilities/optimisation_utilities/opt_subst_utilities.py +455 -0
  28. rock_physics_open/equinor_utilities/snapshot_test_utilities/__init__.py +10 -0
  29. rock_physics_open/equinor_utilities/snapshot_test_utilities/compare_snapshots.py +184 -0
  30. rock_physics_open/equinor_utilities/snapshot_test_utilities/snapshots.py +97 -0
  31. rock_physics_open/equinor_utilities/std_functions/__init__.py +43 -0
  32. rock_physics_open/equinor_utilities/std_functions/backus_ave.py +68 -0
  33. rock_physics_open/equinor_utilities/std_functions/dvorkin_nur.py +77 -0
  34. rock_physics_open/equinor_utilities/std_functions/gassmann.py +165 -0
  35. rock_physics_open/equinor_utilities/std_functions/hashin_shtrikman.py +224 -0
  36. rock_physics_open/equinor_utilities/std_functions/hertz_mindlin.py +51 -0
  37. rock_physics_open/equinor_utilities/std_functions/moduli_velocity.py +67 -0
  38. rock_physics_open/equinor_utilities/std_functions/reflection_eq.py +120 -0
  39. rock_physics_open/equinor_utilities/std_functions/rho.py +69 -0
  40. rock_physics_open/equinor_utilities/std_functions/voigt_reuss_hill.py +149 -0
  41. rock_physics_open/equinor_utilities/std_functions/walton.py +45 -0
  42. rock_physics_open/equinor_utilities/std_functions/wood_brie.py +94 -0
  43. rock_physics_open/equinor_utilities/various_utilities/Equinor_logo.gif +0 -0
  44. rock_physics_open/equinor_utilities/various_utilities/Equinor_logo.ico +0 -0
  45. rock_physics_open/equinor_utilities/various_utilities/__init__.py +24 -0
  46. rock_physics_open/equinor_utilities/various_utilities/display_result_statistics.py +90 -0
  47. rock_physics_open/equinor_utilities/various_utilities/gassmann_dry_mod.py +56 -0
  48. rock_physics_open/equinor_utilities/various_utilities/gassmann_mod.py +56 -0
  49. rock_physics_open/equinor_utilities/various_utilities/gassmann_sub_mod.py +64 -0
  50. rock_physics_open/equinor_utilities/various_utilities/hs_average.py +59 -0
  51. rock_physics_open/equinor_utilities/various_utilities/pressure.py +96 -0
  52. rock_physics_open/equinor_utilities/various_utilities/reflectivity.py +101 -0
  53. rock_physics_open/equinor_utilities/various_utilities/timeshift.py +104 -0
  54. rock_physics_open/equinor_utilities/various_utilities/vp_vs_rho_set_statistics.py +170 -0
  55. rock_physics_open/equinor_utilities/various_utilities/vrh_3_min.py +83 -0
  56. rock_physics_open/fluid_models/__init__.py +9 -0
  57. rock_physics_open/fluid_models/brine_model/__init__.py +5 -0
  58. rock_physics_open/fluid_models/brine_model/brine_properties.py +178 -0
  59. rock_physics_open/fluid_models/gas_model/__init__.py +5 -0
  60. rock_physics_open/fluid_models/gas_model/gas_properties.py +319 -0
  61. rock_physics_open/fluid_models/oil_model/__init__.py +5 -0
  62. rock_physics_open/fluid_models/oil_model/dead_oil_density.py +65 -0
  63. rock_physics_open/fluid_models/oil_model/dead_oil_velocity.py +30 -0
  64. rock_physics_open/fluid_models/oil_model/live_oil_density.py +82 -0
  65. rock_physics_open/fluid_models/oil_model/live_oil_velocity.py +24 -0
  66. rock_physics_open/fluid_models/oil_model/oil_bubble_point.py +69 -0
  67. rock_physics_open/fluid_models/oil_model/oil_properties.py +146 -0
  68. rock_physics_open/sandstone_models/__init__.py +59 -0
  69. rock_physics_open/sandstone_models/cemented_shalysand_sandyshale_models.py +304 -0
  70. rock_physics_open/sandstone_models/constant_cement_models.py +204 -0
  71. rock_physics_open/sandstone_models/constant_cement_optimisation.py +125 -0
  72. rock_physics_open/sandstone_models/contact_cement_model.py +138 -0
  73. rock_physics_open/sandstone_models/curvefit_sandstone_models.py +143 -0
  74. rock_physics_open/sandstone_models/friable_models.py +177 -0
  75. rock_physics_open/sandstone_models/friable_optimisation.py +115 -0
  76. rock_physics_open/sandstone_models/friable_shalysand_sandyshale_models.py +235 -0
  77. rock_physics_open/sandstone_models/patchy_cement_fluid_substitution_model.py +477 -0
  78. rock_physics_open/sandstone_models/patchy_cement_model.py +384 -0
  79. rock_physics_open/sandstone_models/patchy_cement_optimisation.py +254 -0
  80. rock_physics_open/sandstone_models/unresolved_cemented_sandshale_models.py +134 -0
  81. rock_physics_open/sandstone_models/unresolved_friable_sandshale_models.py +126 -0
  82. rock_physics_open/shale_models/__init__.py +19 -0
  83. rock_physics_open/shale_models/dem.py +174 -0
  84. rock_physics_open/shale_models/dem_dual_por.py +61 -0
  85. rock_physics_open/shale_models/kus_tok.py +59 -0
  86. rock_physics_open/shale_models/multi_sca.py +133 -0
  87. rock_physics_open/shale_models/pq.py +102 -0
  88. rock_physics_open/shale_models/sca.py +90 -0
  89. rock_physics_open/shale_models/shale4_mineral.py +147 -0
  90. rock_physics_open/shale_models/shale4_mineral_dem_overlay.py +92 -0
  91. rock_physics_open/span_wagner/__init__.py +5 -0
  92. rock_physics_open/span_wagner/co2_properties.py +444 -0
  93. rock_physics_open/span_wagner/coefficients.py +165 -0
  94. rock_physics_open/span_wagner/equations.py +104 -0
  95. rock_physics_open/span_wagner/tables/__init__.py +0 -0
  96. rock_physics_open/span_wagner/tables/carbon_dioxide_density.npz +0 -0
  97. rock_physics_open/span_wagner/tables/lookup_table.py +33 -0
  98. rock_physics_open/t_matrix_models/Equinor_logo.ico +0 -0
  99. rock_physics_open/t_matrix_models/__init__.py +35 -0
  100. rock_physics_open/t_matrix_models/carbonate_pressure_substitution.py +124 -0
  101. rock_physics_open/t_matrix_models/curvefit_t_matrix_exp.py +123 -0
  102. rock_physics_open/t_matrix_models/curvefit_t_matrix_min.py +86 -0
  103. rock_physics_open/t_matrix_models/parse_t_matrix_inputs.py +297 -0
  104. rock_physics_open/t_matrix_models/run_t_matrix.py +243 -0
  105. rock_physics_open/t_matrix_models/t_matrix_C.py +210 -0
  106. rock_physics_open/t_matrix_models/t_matrix_opt_fluid_sub_exp.py +137 -0
  107. rock_physics_open/t_matrix_models/t_matrix_opt_fluid_sub_petec.py +167 -0
  108. rock_physics_open/t_matrix_models/t_matrix_opt_forward_model_exp.py +76 -0
  109. rock_physics_open/t_matrix_models/t_matrix_opt_forward_model_min.py +89 -0
  110. rock_physics_open/t_matrix_models/t_matrix_parameter_optimisation_exp.py +176 -0
  111. rock_physics_open/t_matrix_models/t_matrix_parameter_optimisation_min.py +162 -0
  112. rock_physics_open/t_matrix_models/t_matrix_vector/__init__.py +12 -0
  113. rock_physics_open/t_matrix_models/t_matrix_vector/array_functions.py +75 -0
  114. rock_physics_open/t_matrix_models/t_matrix_vector/calc_c_eff.py +163 -0
  115. rock_physics_open/t_matrix_models/t_matrix_vector/calc_isolated.py +95 -0
  116. rock_physics_open/t_matrix_models/t_matrix_vector/calc_kd.py +40 -0
  117. rock_physics_open/t_matrix_models/t_matrix_vector/calc_kd_eff.py +116 -0
  118. rock_physics_open/t_matrix_models/t_matrix_vector/calc_kd_uuv.py +18 -0
  119. rock_physics_open/t_matrix_models/t_matrix_vector/calc_pressure.py +140 -0
  120. rock_physics_open/t_matrix_models/t_matrix_vector/calc_t.py +71 -0
  121. rock_physics_open/t_matrix_models/t_matrix_vector/calc_td.py +42 -0
  122. rock_physics_open/t_matrix_models/t_matrix_vector/calc_theta.py +43 -0
  123. rock_physics_open/t_matrix_models/t_matrix_vector/calc_x.py +33 -0
  124. rock_physics_open/t_matrix_models/t_matrix_vector/calc_z.py +50 -0
  125. rock_physics_open/t_matrix_models/t_matrix_vector/check_and_tile.py +43 -0
  126. rock_physics_open/t_matrix_models/t_matrix_vector/g_tensor.py +140 -0
  127. rock_physics_open/t_matrix_models/t_matrix_vector/iso_av.py +60 -0
  128. rock_physics_open/t_matrix_models/t_matrix_vector/iso_ave_all.py +55 -0
  129. rock_physics_open/t_matrix_models/t_matrix_vector/pressure_input.py +44 -0
  130. rock_physics_open/t_matrix_models/t_matrix_vector/t_matrix_vec.py +278 -0
  131. rock_physics_open/t_matrix_models/t_matrix_vector/velocity_vti_angles.py +81 -0
  132. rock_physics_open/t_matrix_models/tmatrix_python.dll +0 -0
  133. rock_physics_open/t_matrix_models/tmatrix_python.so +0 -0
  134. rock_physics_open/ternary_plots/__init__.py +3 -0
  135. rock_physics_open/ternary_plots/gen_ternary_plot.py +73 -0
  136. rock_physics_open/ternary_plots/shale_prop_ternary.py +337 -0
  137. rock_physics_open/ternary_plots/ternary_patches.py +277 -0
  138. rock_physics_open/ternary_plots/ternary_plot_utilities.py +197 -0
  139. rock_physics_open/ternary_plots/unconventionals_ternary.py +75 -0
  140. rock_physics_open/version.py +34 -0
  141. rock_physics_open-0.3.2.dist-info/METADATA +90 -0
  142. rock_physics_open-0.3.2.dist-info/RECORD +145 -0
  143. rock_physics_open-0.3.2.dist-info/WHEEL +5 -0
  144. rock_physics_open-0.3.2.dist-info/licenses/LICENSE +165 -0
  145. rock_physics_open-0.3.2.dist-info/top_level.txt +1 -0
@@ -0,0 +1,319 @@
1
+ import numpy as np
2
+ from numpy import exp, sqrt
3
+ from scipy.constants import gas_constant
4
+
5
+ from rock_physics_open.equinor_utilities.conversions import celsius_to_kelvin
6
+
7
+ AIR_WEIGHT = 28.8 * 1.0e-3 # kg/mol
8
+
9
+
10
+ def gas_properties(
11
+ temperature: np.ndarray | float,
12
+ pressure: np.ndarray | float,
13
+ gas_gravity: np.ndarray | float,
14
+ model: str | None = None,
15
+ ) -> tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]:
16
+ """
17
+ :param gas_gravity: molar mass of gas relative to air molar mas.
18
+ :param pressure: Confining pressure (Pa)
19
+ :param temperature: Temperature (Celsius).
20
+ :param model: for future use
21
+ :return: vel_gas [m/s], den_gas [kg/m^3], k_gas [Pa], eta_gas [cP]
22
+ """
23
+
24
+ den_gas = gas_density(celsius_to_kelvin(temperature), pressure, gas_gravity)
25
+
26
+ k_gas = gas_bulk_modulus(celsius_to_kelvin(temperature), pressure, gas_gravity)
27
+
28
+ vel_gas = (k_gas / den_gas) ** 0.5
29
+
30
+ eta_gas = lee_gas_viscosity(celsius_to_kelvin(temperature), pressure, gas_gravity)
31
+
32
+ return vel_gas, den_gas, k_gas, eta_gas
33
+
34
+
35
+ def molecular_weight(gas_gravity: np.ndarray | float) -> np.ndarray | float:
36
+ """
37
+ calculates molecular weight of a gas from gas gravity.
38
+ :param gas_gravity: molar mass of gas relative to air molar mas.
39
+ :return: The volume of the gas in kg/mol.
40
+ """
41
+ return gas_gravity * AIR_WEIGHT
42
+
43
+
44
+ def molar_volume(
45
+ absolute_temperature: np.ndarray | float,
46
+ pressure: np.ndarray | float,
47
+ ) -> np.ndarray | float:
48
+ """
49
+ calculates molar volume using the ideal gas law.
50
+ :param absolute_temperature: The absolute temperature of the gas in kelvin.
51
+ :param pressure: Confining pressure in Pa.
52
+ :return: The volume of the gas in m^3/mol.
53
+ """
54
+
55
+ return gas_constant * absolute_temperature / pressure
56
+
57
+
58
+ def ideal_gas_density(
59
+ absolute_temperature: np.ndarray | float,
60
+ pressure: np.ndarray | float,
61
+ gas_gravity: np.ndarray | float,
62
+ ) -> np.ndarray | float:
63
+ """
64
+ calculates molar volume using the ideal gas law.
65
+ :param gas_gravity: molar mass of gas relative to air molar mas.
66
+ :param absolute_temperature: The absolute temperature of the gas in kelvin.
67
+ :param pressure: Confining pressure in Pa.
68
+ :return: The density of the gas in kg/m^3
69
+ """
70
+ return molecular_weight(gas_gravity) / molar_volume(absolute_temperature, pressure)
71
+
72
+
73
+ def ideal_gas_primary_velocity(
74
+ absolute_temperature: np.ndarray | float,
75
+ gas_gravity: np.ndarray | float,
76
+ ) -> np.ndarray | float:
77
+ """
78
+ :param gas_gravity: molar mass of gas relative to air molar mas.
79
+ :param absolute_temperature: The absolute temperature of the gas in kelvin.
80
+ :return: The compressional wave velocity of the gas in m/s.
81
+ """
82
+ return sqrt(gas_constant * absolute_temperature / molecular_weight(gas_gravity))
83
+
84
+
85
+ def ideal_gas(
86
+ absolute_temperature: np.ndarray | float,
87
+ pressure: np.ndarray | float,
88
+ gas_gravity: np.ndarray | float,
89
+ ) -> tuple[np.ndarray | float, np.ndarray | float]:
90
+ """
91
+ :param gas_gravity: molar mass of gas relative to air molar mas.
92
+ :param absolute_temperature: The absolute temperature of the gas in kelvin.
93
+ :param pressure: Confining pressure in Pa.
94
+ :return: ideal_gas_velocity [m/s], ideal_gas_density [kg/m^3],
95
+ """
96
+ ideal_gas_den = ideal_gas_density(absolute_temperature, pressure, gas_gravity)
97
+ ideal_gas_vel = ideal_gas_primary_velocity(absolute_temperature, gas_gravity)
98
+ return ideal_gas_vel, ideal_gas_den
99
+
100
+
101
+ def pseudoreduced_temperature(
102
+ absolute_temperature: np.ndarray | float,
103
+ gas_gravity: np.ndarray | float,
104
+ ) -> np.ndarray | float:
105
+ """
106
+ calculates pseudoreduced temperature, equation 9a from Batzle & Wang [1].
107
+
108
+ Uses relationship from
109
+
110
+ Thomas, L. K., Hankinson, R. W., and Phillips, K. A., 1970,
111
+ Determination of acoustic velocities for natural gas: J. Petr.
112
+ Tech., 22, 889-892.
113
+
114
+ :param gas_gravity: molar mass of gas relative to air molar mas.
115
+ :param absolute_temperature: The absolute temperature of the gas in kelvin.
116
+ :return: Pseudoreduced temperature in kelvin.
117
+ """
118
+ return absolute_temperature / (94.72 + 170.75 * gas_gravity)
119
+
120
+
121
+ def pseudoreduced_pressure(
122
+ pressure: np.ndarray | float,
123
+ gas_gravity: np.ndarray | float,
124
+ ) -> np.ndarray | float:
125
+ """
126
+ calculates pseudoreduced pressure, equation 9a from Batzle & Wang [1].
127
+
128
+ Uses relationship from
129
+
130
+ Thomas, L. K., Hankinson, R. W., and Phillips, K. A., 1970,
131
+ Determination of acoustic velocities for natural gas: J. Petr.
132
+ Tech., 22, 889-892.
133
+
134
+ :param gas_gravity: molar mass of gas relative to air molar mas.
135
+ :param pressure: Confining pressure in Pa.
136
+ :return: Pseudoreduced pressure in Pa.
137
+ """
138
+ return pressure / (4.892 - 0.4048 * gas_gravity)
139
+
140
+
141
+ def compressibility_factor(
142
+ absolute_temperature: np.ndarray | float,
143
+ pressure: np.ndarray | float,
144
+ gas_gravity: np.ndarray | float,
145
+ ) -> np.ndarray | float:
146
+ """
147
+ calculates compressability hydro-carbon gas, equation 10b and 10c from
148
+ Batzle & Wang [1].
149
+
150
+ :param gas_gravity: molar mass of gas relative to air molar mas.
151
+ :param absolute_temperature: The absolute temperature of the gas in kelvin.
152
+ :param pressure: Confining pressure in Pa.
153
+ :return: Gas compressibility - unitless
154
+ """
155
+ tpr = pseudoreduced_temperature(absolute_temperature, gas_gravity)
156
+
157
+ # Pseudoreduced pressure has unit MPa in equation
158
+ ppr = pseudoreduced_pressure(pressure, gas_gravity) * 1.0e-6
159
+
160
+ return (
161
+ (0.03 + 0.00527 * (3.5 - tpr) ** 3) * ppr
162
+ + 0.642 * tpr
163
+ - 0.007 * tpr**4
164
+ - 0.52
165
+ + 0.109
166
+ * (3.85 - tpr) ** 2
167
+ / exp((0.45 + 8.0 * (0.56 - 1 / tpr) ** 2) * ppr**1.2 / tpr)
168
+ )
169
+
170
+
171
+ def gas_density(
172
+ absolute_temperature: np.ndarray | float,
173
+ pressure: np.ndarray | float,
174
+ gas_gravity: np.ndarray | float,
175
+ ) -> np.ndarray | float:
176
+ """
177
+ The density of hydro-carbon gas, using equation 10 from Batzle & Wang [1].
178
+
179
+ :param gas_gravity: molar mass of gas relative to air molar mas.
180
+ :param absolute_temperature: The absolute temperature of the gas in kelvin.
181
+ :param pressure: Confining pressure in Pa.
182
+ :return: The density of the gas in kg/m^3
183
+ """
184
+
185
+ _, ideal_gas_den = ideal_gas(absolute_temperature, pressure, gas_gravity)
186
+ return ideal_gas_den / compressibility_factor(
187
+ absolute_temperature, pressure, gas_gravity
188
+ )
189
+
190
+
191
+ def compressibility_rate_per_pseudoreduced_pressure(
192
+ absolute_temperature: np.ndarray | float,
193
+ pressure: np.ndarray | float,
194
+ gas_gravity: np.ndarray | float,
195
+ ) -> np.ndarray | float:
196
+ """
197
+ Derivate of compressability_factor with respect to pressure.
198
+
199
+ :param gas_gravity: molar mass of gas relative to air molar mas.
200
+ :param absolute_temperature: The absolute temperature of the gas in kelvin.
201
+ :param pressure: Confining pressure in MPa.
202
+ :return: Derivative of the compressibility factor (unitless) with respect to pseudoreduced pressure
203
+ """
204
+ tpr = pseudoreduced_temperature(absolute_temperature, gas_gravity)
205
+
206
+ # Pseudoreduced pressure is expected to be in MPa in the expression
207
+ ppr = pseudoreduced_pressure(pressure, gas_gravity) * 1.0e-6
208
+
209
+ return (
210
+ 0.03
211
+ + 0.00527 * (3.5 - tpr) ** 3
212
+ - (
213
+ 0.1308
214
+ * (0.45 + 8 * (0.56 - tpr ** (-1)) ** 2)
215
+ * (3.85 - tpr) ** 2
216
+ * ppr**0.2
217
+ )
218
+ / (exp(((0.45 + 8 * (0.56 - tpr ** (-1)) ** 2) * ppr**1.2) / tpr) * tpr)
219
+ )
220
+
221
+
222
+ def gas_bulk_modulus(
223
+ absolute_temperature: np.ndarray | float,
224
+ pressure: np.ndarray | float,
225
+ gas_gravity: np.ndarray | float,
226
+ ) -> np.ndarray | float:
227
+ """
228
+ The bulk modulus of hydro-carbon gas, using equation 11 from Batzle & Wang [1].
229
+
230
+ :param gas_gravity: molar mass of gas relative to air molar mas.
231
+ :param absolute_temperature: The absolute temperature of the gas in kelvin.
232
+ :param pressure: Confining pressure in Pa.
233
+ :return: The bulk modulus of the gas in Pa.
234
+ """
235
+ z = compressibility_factor(absolute_temperature, pressure, gas_gravity)
236
+ dz_dppr = compressibility_rate_per_pseudoreduced_pressure(
237
+ absolute_temperature, pressure, gas_gravity
238
+ )
239
+
240
+ # Set ppr in unit MPa in order to use it in calculation of gamma_0
241
+ ppr = pseudoreduced_pressure(pressure, gas_gravity) * 1.0e-6
242
+
243
+ # Equation 11b
244
+ gamma_0 = (
245
+ 0.85
246
+ + 5.6 / (ppr + 2)
247
+ + 27.1 / ((ppr + 3.5) ** 2)
248
+ - 8.7 * exp(-0.65 * (ppr + 1))
249
+ )
250
+
251
+ return gamma_0 * pressure / (1 - dz_dppr * ppr / z)
252
+
253
+
254
+ def gas_viscosity(
255
+ absolute_temperature: np.ndarray | float,
256
+ pressure: np.ndarray | float,
257
+ gas_gravity: np.ndarray | float,
258
+ ) -> np.ndarray | float:
259
+ """
260
+ The gas viscosity of hydrocarbon gas, using equations 12 and 13 of Batzle & Wang [1].
261
+
262
+ :param absolute_temperature: The absolute temperature of the gas in kelvin.
263
+ :param pressure: Confining pressure in Pa.
264
+ :param gas_gravity: molar mass of gas relative to air mas.
265
+ :return: The gas viscosity of the gas in cP.
266
+ """
267
+ temp_pr = pseudoreduced_temperature(absolute_temperature, gas_gravity)
268
+
269
+ # Pseudoreduced pressure should be in unit MPa
270
+ pres_pr = pseudoreduced_pressure(pressure, gas_gravity) * 1.0e-6
271
+
272
+ eta_1 = 0.0001 * (
273
+ temp_pr * (28.0 + 48.0 * gas_gravity - 5.0 * gas_gravity**2)
274
+ - 6.47 * gas_gravity**-2
275
+ + 35.0 * gas_gravity**-1
276
+ + 1.14 * gas_gravity
277
+ - 15.55
278
+ )
279
+ return eta_1 * (
280
+ 0.001
281
+ * pres_pr
282
+ * (
283
+ (1057.0 - 8.08 * temp_pr) / pres_pr
284
+ + (796.0 * pres_pr**0.5 - 704.0)
285
+ / (((temp_pr - 1.0) ** 0.7) * (pres_pr + 1.0))
286
+ - 3.24 * temp_pr
287
+ - 38.0
288
+ )
289
+ )
290
+
291
+
292
+ def lee_gas_viscosity(
293
+ absolute_temperature: np.ndarray | float,
294
+ pressure: np.ndarray | float,
295
+ gas_gravity: np.ndarray | float,
296
+ ) -> np.ndarray:
297
+ """
298
+ :param absolute_temperature: Absolute temperature of the gas in kelvin.
299
+ :param pressure: Confining pressure in Pa.
300
+ :param gas_gravity: specific gravity of gas relative to air.
301
+ :return: gas viscosity in cP
302
+
303
+ Reference
304
+ ---------
305
+ Lee, J. D., et al. (1966). "Viscosity of Natural Gas." In The American Institute of
306
+ Chemical Engineers Journal, Volume 12, Issue 6, pp. 1058-1062.
307
+
308
+ Original equation is given in imperial units. Inputs are transformed to temperature
309
+ in Farenheit and pressure in psi
310
+ """
311
+ temp_far = (absolute_temperature - 273.15) * 9.0 / 5.0 + 32.0
312
+ pres_psi = pressure / 6894.757
313
+ return (
314
+ 0.001
315
+ * (temp_far + 459.67) ** 0.5
316
+ / pres_psi
317
+ * (0.7 + 1.5 * gas_gravity)
318
+ / (gas_gravity + 1) ** 1.5
319
+ )
@@ -0,0 +1,5 @@
1
+ from .oil_properties import oil_properties
2
+
3
+ __all__ = [
4
+ "oil_properties",
5
+ ]
@@ -0,0 +1,65 @@
1
+ import numpy as np
2
+
3
+
4
+ def pressure_adjusted_dead_oil_density(
5
+ pressure: np.ndarray | float,
6
+ reference_density: np.ndarray | float,
7
+ ) -> np.ndarray | float:
8
+ """
9
+ Adjusts density of a dead oil (without dissolved gas) to a given pressure.
10
+
11
+ Uses equation 18 from Batzle & Wang [1].
12
+
13
+ :param reference_density: The density [kg/m^3] of the dead oil at 15.6 degrees Celsius
14
+ and atmospheric pressure.
15
+ :param pressure: Pressure [Pa] to adjust to.
16
+ :return: Density of oil at given pressure and 21 degrees Celsius (~70 degrees
17
+ Farenheit). [kg/m^3]
18
+ """
19
+ pressure_mpa = pressure / 1e6
20
+ density_gcc = reference_density / 1000.0
21
+ return 1000.0 * (
22
+ density_gcc
23
+ + (0.00277 * pressure_mpa - 1.71e-7 * pressure_mpa**3)
24
+ * (density_gcc - 1.15) ** 2
25
+ + 3.49e-4 * pressure_mpa
26
+ )
27
+
28
+
29
+ def temperature_adjusted_dead_oil_density(
30
+ temperature: np.ndarray | float,
31
+ density_at_21c: np.ndarray,
32
+ ) -> np.ndarray | float:
33
+ """
34
+ Adjusts density of a dead oil (without dissolved gas) to a given temperature.
35
+
36
+ Uses equation 19 from Batzle & Wang [1].
37
+
38
+ :param density_at_21c: The density [kg/m^3] of the dead oil at 21 degrees Celsius
39
+ :param temperature: Temperature [°C] of oil.
40
+ :return: Density of oil at given temperature. [kg/m^3]
41
+ """
42
+ density_at_21c_gcc = density_at_21c / 1000.0
43
+ return (
44
+ 1000.0 * density_at_21c_gcc / (0.972 + 3.81e-4 * (temperature + 17.78) ** 1.175)
45
+ )
46
+
47
+
48
+ def dead_oil_density(
49
+ temperature: np.ndarray | float,
50
+ pressure: np.ndarray | float,
51
+ reference_density: np.ndarray | float,
52
+ ) -> np.ndarray | float:
53
+ """
54
+ The density of oil without dissolved gas (dead).
55
+
56
+ Uses equation 18 & 19 from Batzle & Wang [1].
57
+
58
+ :param reference_density: Density of oil at 15.6 degrees Celsius and atmospheric
59
+ pressure [kg/m^3]
60
+ :param pressure: Pressure [Pa] of oil
61
+ :param temperature: Temperature [°C] of oil.
62
+ :return: density of dead oil at given conditions (kg/m^3).
63
+ """
64
+ density_p = pressure_adjusted_dead_oil_density(pressure, reference_density)
65
+ return temperature_adjusted_dead_oil_density(temperature, density_p)
@@ -0,0 +1,30 @@
1
+ import numpy as np
2
+
3
+
4
+ def dead_oil_velocity(
5
+ temperature: np.ndarray | float,
6
+ pressure: np.ndarray | float,
7
+ reference_density: np.ndarray | float,
8
+ ) -> np.ndarray | float:
9
+ """
10
+ The primary wave velocity in oil without dissolved gas (dead).
11
+
12
+ Uses equation 20a from Batzle & Wang [1].
13
+
14
+ :param reference_density: Density of oil at 15.6 degrees Celsius and atmospheric
15
+ pressure [kg/m^3]
16
+ :param pressure: Pressure [Pa] of oil
17
+ :param temperature: Temperature [°C] of oil.
18
+ :return: primary velocity of dead oil in m/s.
19
+ """
20
+ pressure_mpa = pressure * 1e-6
21
+ density_gcc = reference_density / 1000.0
22
+ return (
23
+ 2096 * np.sqrt(density_gcc / (2.6 - density_gcc))
24
+ - 3.7 * temperature
25
+ + 4.64 * pressure_mpa
26
+ + 0.0115
27
+ * (4.12 * np.sqrt(1.08 * density_gcc**-1 - 1) - 1)
28
+ * temperature
29
+ * pressure_mpa
30
+ )
@@ -0,0 +1,82 @@
1
+ import numpy as np
2
+
3
+
4
+ def live_oil_density(
5
+ temperature,
6
+ pressure: np.ndarray | float | None,
7
+ reference_density: np.ndarray | float,
8
+ gas_oil_ratio: np.ndarray | float,
9
+ gas_gravity: np.ndarray | float,
10
+ ) -> np.ndarray | float:
11
+ """
12
+ Density of live oil at saturation.
13
+
14
+ Equation 24 in Batzle & Wang [1].
15
+
16
+ :param reference_density: Density of the oil without dissolved gas
17
+ at 15.6 degrees Celsius and atmospheric pressure. [kg/m^3]
18
+ :param pressure: Pressure [Pa] of oil (for future implementation only)
19
+ :param gas_oil_ratio: The volume ratio of gas to oil [l/l]
20
+ :param temperature: Temperature [°C] of oil.
21
+ :param gas_gravity: molar mass of gas relative to air molar mas.
22
+ :return: Density of live oil [kg/m^3].
23
+ """
24
+ density_gcc = reference_density / 1000.0
25
+ b0 = live_oil_volume_factor(
26
+ temperature, reference_density, gas_oil_ratio, gas_gravity
27
+ )
28
+ return 1000.0 * (density_gcc + 0.0012 * gas_gravity * gas_oil_ratio) / b0
29
+
30
+
31
+ def live_oil_pseudo_density(
32
+ temperature: np.ndarray | float,
33
+ reference_density: np.ndarray | float,
34
+ gas_oil_ratio: np.ndarray | float,
35
+ gas_gravity: np.ndarray | float,
36
+ ) -> np.ndarray | float:
37
+ """
38
+ Pseudo density used to substitute reference density in dead_oil_wave_velocity
39
+ for live oils.
40
+
41
+ Equation 22 in Batzle & Wang [1].
42
+
43
+ :param reference_density: Density of the oil without dissolved gas
44
+ at 15.6 degrees Celsius and atmospheric pressure. [kg/m^3]
45
+ :param gas_oil_ratio: The volume ratio of gas to oil [l/l]
46
+ :param temperature: Temperature [°C] of oil.
47
+ :param gas_gravity: molar mass of gas relative to air molar mas.
48
+ :return: Pseudo-density of live oil [kg/m^3].
49
+ """
50
+ density_gcc = reference_density / 1000.0
51
+ b0 = live_oil_volume_factor(
52
+ temperature, reference_density, gas_oil_ratio, gas_gravity
53
+ )
54
+ return 1000.0 * (density_gcc / b0) / (1 + 0.001 * gas_oil_ratio)
55
+
56
+
57
+ def live_oil_volume_factor(
58
+ temperature: np.ndarray | float,
59
+ reference_density: np.ndarray | float,
60
+ gas_oil_ratio: np.ndarray | float,
61
+ gas_gravity: np.ndarray | float,
62
+ ) -> np.ndarray | float:
63
+ """
64
+ Volume factor derived by Standing (1962), equation 23 in Batzle & Wang [1].
65
+ :param reference_density: Density of the oil without dissolved gas
66
+ at 15.6 degrees Celsius and atmospheric pressure. [kg/m^3]
67
+ :param gas_oil_ratio: The volume ratio of gas to oil [l/l]
68
+ :param temperature: Temperature [°C] of oil.
69
+ :param gas_gravity: molar mass of gas relative to air molar mas.
70
+ :return: A volume factor in calculating pseudo-density of live oil [unitless].
71
+ """
72
+ density_gcc = reference_density / 1000.0
73
+ return (
74
+ 0.972
75
+ + 0.00038
76
+ * (
77
+ 2.4 * gas_oil_ratio * np.sqrt(gas_gravity / density_gcc)
78
+ + temperature
79
+ + 17.8
80
+ )
81
+ ** 1.175
82
+ )
@@ -0,0 +1,24 @@
1
+ from .dead_oil_velocity import dead_oil_velocity
2
+ from .live_oil_density import live_oil_pseudo_density
3
+
4
+
5
+ def live_oil_velocity(
6
+ temperature, pressure, reference_density, gas_oil_ratio, gas_gravity
7
+ ):
8
+ """
9
+ Primary wave velocity of live oil at saturation.
10
+
11
+ Substitute Equation 22 in Equation 20 of Batzle & Wang [1].
12
+
13
+ :param reference_density: Density of the oil without dissolved gas
14
+ at 15.6 degrees Celsius and atmospheric pressure. [kg/m^3]
15
+ :param pressure: Pressure [Pa] of oil
16
+ :param gas_oil_ratio: The volume ratio of gas to oil [l/l]
17
+ :param temperature: Temperature [°C] of oil.
18
+ :param gas_gravity: molar mass of gas relative to air molar mas.
19
+ :return: Primary wave velocity of live oil [m/s].
20
+ """
21
+ rho_marked = live_oil_pseudo_density(
22
+ temperature, reference_density, gas_oil_ratio, gas_gravity
23
+ )
24
+ return dead_oil_velocity(temperature, pressure, rho_marked)
@@ -0,0 +1,69 @@
1
+ import numpy as np
2
+
3
+
4
+ def bp_standing(
5
+ density: np.ndarray | float,
6
+ gas_oil_ratio: np.ndarray | float,
7
+ gas_gravity: np.ndarray | float,
8
+ temperature: np.ndarray | float,
9
+ ) -> np.ndarray | float:
10
+ """
11
+ Reservoir oils include some natural gas in solution. The pressure at which
12
+ this natural gas begins to come out of solution and form bubbles is known
13
+ as the bubble point pressure. See https://petrowiki.org/Oil_bubblepoint_pressure
14
+ Based on the correlation from:
15
+ Standing, M. B. "A pressure-volume-temperature correlation for mixtures of
16
+ California oils and gases." Drilling and Production Practice. American
17
+ Petroleum Institute, 1947.
18
+ Uses refinment described here: https://petrowiki.org/Oil_bubblepoint_pressure
19
+ :param density: density of oil at room conditions [kg/m^3]
20
+ :param gas_oil_ratio: The volume ratio of gas to oil [l/l]
21
+ :param gas_gravity: molar mass of gas relative to air molar mas.
22
+ :param temperature: temperature of oil [°C]
23
+ :return: bubble point pressure [Pa]
24
+ """
25
+
26
+ # Standing, M.B. (1947) uses:
27
+ # * pressure in psi
28
+ # * temperature in F
29
+ # * gas oil ratio in cu ft per bbl
30
+ # * bubble point in in absolute psi
31
+ # * gravity_of_tank_oil in API
32
+ #
33
+ # The paper describes that bubble point is a function of
34
+ # (gor / gr) ** 0.83
35
+ # * (10**(0.00091 * t)/10**(0.0125*gravity_of_tank_oil))
36
+ #
37
+ # and gives the following example:
38
+ # Bubble point pressure at 200° F
39
+ # of a liquid having gas-oil ratio
40
+ # 350 CFB, a gas gravity 0.75, and
41
+ # a tank oil gravity of 30° API.
42
+ # The required pressure is found
43
+ # to be 1930 psia.
44
+ #
45
+ # We could scale to fit this example, however,
46
+ # we use 1896 psia.
47
+ #
48
+ # For density in kg/m^3:
49
+ # 10**(0.0125*gravity_of_tank_oil)=
50
+ # 10**(1770.79/density - 1.64375)=
51
+ # e**(4072.69738323/density - 3.78487)
52
+ # For temperature in Celsius:
53
+ # 10**(0.00091 * Farenheit) =
54
+ # 10**(0.001638*Celsius + 0.02912) =
55
+ # e**(0.00377163*Celsius + 0.0670513)
56
+ #
57
+ # Removing constants factors we get
58
+ # (gor_ratio /
59
+ # gas_gravity)) ** 0.83 / ( np.exp(4072.69738323 / density -
60
+ # 0.00377163438 * temperature_c)
61
+ #
62
+ # The equation occurs in this form as equation 21a in
63
+ # Batzle, Michael, and Zhijing Wang. "Seismic properties of pore fluids."
64
+ # Geophysics 57.11 (1992): 1396-1408.
65
+
66
+ ratio = gas_oil_ratio / gas_gravity
67
+ denominator = np.exp(4072 / density - 0.00377 * temperature)
68
+
69
+ return 24469793.9134 * ratio**0.83 / denominator