fmu-pem 0.0.2__py3-none-any.whl → 0.0.4__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.
- fmu/pem/__init__.py +2 -0
- fmu/pem/__main__.py +72 -19
- fmu/pem/forward_models/pem_model.py +21 -26
- fmu/pem/pem_functions/__init__.py +2 -2
- fmu/pem/pem_functions/density.py +32 -38
- fmu/pem/pem_functions/effective_pressure.py +153 -49
- fmu/pem/pem_functions/estimate_saturated_rock.py +244 -52
- fmu/pem/pem_functions/fluid_properties.py +447 -245
- fmu/pem/pem_functions/mineral_properties.py +77 -74
- fmu/pem/pem_functions/pressure_sensitivity.py +430 -0
- fmu/pem/pem_functions/regression_models.py +129 -97
- fmu/pem/pem_functions/run_friable_model.py +106 -37
- fmu/pem/pem_functions/run_patchy_cement_model.py +107 -45
- fmu/pem/pem_functions/{run_t_matrix_and_pressure.py → run_t_matrix_model.py} +48 -27
- fmu/pem/pem_utilities/__init__.py +30 -10
- fmu/pem/pem_utilities/cumsum_properties.py +29 -37
- fmu/pem/pem_utilities/delta_cumsum_time.py +8 -13
- fmu/pem/pem_utilities/enum_defs.py +65 -8
- fmu/pem/pem_utilities/export_routines.py +84 -72
- fmu/pem/pem_utilities/fipnum_pvtnum_utilities.py +217 -0
- fmu/pem/pem_utilities/import_config.py +76 -50
- fmu/pem/pem_utilities/import_routines.py +57 -69
- fmu/pem/pem_utilities/pem_class_definitions.py +81 -23
- fmu/pem/pem_utilities/pem_config_validation.py +364 -172
- fmu/pem/pem_utilities/rpm_models.py +473 -100
- fmu/pem/pem_utilities/update_grid.py +3 -2
- fmu/pem/pem_utilities/utils.py +90 -38
- fmu/pem/run_pem.py +66 -48
- fmu/pem/version.py +16 -3
- {fmu_pem-0.0.2.dist-info → fmu_pem-0.0.4.dist-info}/METADATA +19 -11
- fmu_pem-0.0.4.dist-info/RECORD +39 -0
- {fmu_pem-0.0.2.dist-info → fmu_pem-0.0.4.dist-info}/WHEEL +1 -1
- fmu_pem-0.0.2.dist-info/RECORD +0 -37
- {fmu_pem-0.0.2.dist-info → fmu_pem-0.0.4.dist-info}/entry_points.txt +0 -0
- {fmu_pem-0.0.2.dist-info → fmu_pem-0.0.4.dist-info}/licenses/LICENSE +0 -0
- {fmu_pem-0.0.2.dist-info → fmu_pem-0.0.4.dist-info}/top_level.txt +0 -0
fmu/pem/pem_utilities/utils.py
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
import os
|
|
2
2
|
from contextlib import contextmanager
|
|
3
3
|
from pathlib import Path
|
|
4
|
-
from typing import
|
|
4
|
+
from typing import Generator
|
|
5
5
|
|
|
6
6
|
import numpy as np
|
|
7
7
|
import xtgeo
|
|
8
8
|
|
|
9
|
-
from .pem_class_definitions import
|
|
10
|
-
from .pem_config_validation import PemConfig
|
|
9
|
+
from .pem_class_definitions import EffectiveMineralProperties, PressureProperties
|
|
11
10
|
|
|
12
11
|
|
|
13
12
|
@contextmanager
|
|
14
|
-
def restore_dir(path: Path) ->
|
|
13
|
+
def restore_dir(path: Path) -> Generator: # type: ignore[return-value]
|
|
15
14
|
"""restore_dir run block of code from a given path, restore original path
|
|
16
15
|
|
|
17
16
|
Args:
|
|
@@ -29,7 +28,7 @@ def restore_dir(path: Path) -> None:
|
|
|
29
28
|
|
|
30
29
|
|
|
31
30
|
def to_masked_array(
|
|
32
|
-
value:
|
|
31
|
+
value: float | int, masked_array: np.ma.MaskedArray
|
|
33
32
|
) -> np.ma.MaskedArray:
|
|
34
33
|
"""Create a masked array with a constant value from an int or float and a template
|
|
35
34
|
masked array
|
|
@@ -44,12 +43,40 @@ def to_masked_array(
|
|
|
44
43
|
return np.ma.MaskedArray(value * np.ones_like(masked_array), mask=masked_array.mask)
|
|
45
44
|
|
|
46
45
|
|
|
46
|
+
def get_masked_array_mask(masked_array: np.ma.MaskedArray) -> np.ndarray:
|
|
47
|
+
"""Extract mask from MaskedArray or create default mask."""
|
|
48
|
+
return (
|
|
49
|
+
masked_array.mask
|
|
50
|
+
if hasattr(masked_array, "mask")
|
|
51
|
+
else np.zeros_like(masked_array.data, dtype=bool)
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def set_mask(
|
|
56
|
+
masked_template: np.ma.MaskedArray,
|
|
57
|
+
prop_array: np.ma.MaskedArray | None,
|
|
58
|
+
) -> np.ma.MaskedArray | None:
|
|
59
|
+
"""Check for existence of mask in masked_template, return prop_array
|
|
60
|
+
with masked values. In case prop_array is None, return None"""
|
|
61
|
+
if prop_array is None:
|
|
62
|
+
return None
|
|
63
|
+
return np.ma.masked_where(
|
|
64
|
+
masked_template.mask
|
|
65
|
+
if hasattr(masked_template, "mask")
|
|
66
|
+
else np.zeros_like(prop_array),
|
|
67
|
+
prop_array,
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
|
|
47
71
|
def filter_and_one_dim(
|
|
48
72
|
*args: np.ma.MaskedArray, return_numpy_array: bool = False
|
|
49
|
-
) -> tuple[np.ma.MaskedArray, ...]:
|
|
73
|
+
) -> tuple[np.ma.MaskedArray | np.ndarray, ...]:
|
|
50
74
|
"""Filters multiple masked arrays by removing masked values and flattens them to 1D.
|
|
51
75
|
|
|
52
|
-
|
|
76
|
+
If no elements are masked (i.e., mask is scalar False), this function will still
|
|
77
|
+
flatten the arrays to 1D by treating all entries as valid. This ensures
|
|
78
|
+
downstream rock physics functions always receive 1D arrays, avoiding shape
|
|
79
|
+
issues (e.g. (1, nx, ny, nz)) when no masking occurs.
|
|
53
80
|
|
|
54
81
|
Args:
|
|
55
82
|
*args: One or more masked arrays of identical shape. Each array contains data
|
|
@@ -59,26 +86,34 @@ def filter_and_one_dim(
|
|
|
59
86
|
|
|
60
87
|
Returns:
|
|
61
88
|
tuple containing:
|
|
62
|
-
- mask: Boolean array of
|
|
63
|
-
|
|
64
|
-
- filtered arrays: One or more 1D arrays containing only the unmasked values
|
|
65
|
-
from each input array, in their original order
|
|
89
|
+
- mask: Boolean array of same shape where True indicates masked positions
|
|
90
|
+
- filtered arrays: 1D arrays containing the unmasked values from each arg
|
|
66
91
|
"""
|
|
67
92
|
if not np.all([isinstance(arg, np.ma.MaskedArray) for arg in args]):
|
|
68
93
|
raise ValueError(f"{__file__}: all inputs should be numpy masked arrays")
|
|
94
|
+
|
|
95
|
+
# Combine masks
|
|
69
96
|
mask = args[0].mask
|
|
70
97
|
for i in range(1, len(args)):
|
|
71
98
|
mask = np.logical_or(mask, args[i].mask)
|
|
99
|
+
|
|
100
|
+
# If mask is scalar (no masked elements), expand to full-shape False array
|
|
101
|
+
if np.isscalar(mask): # covers True/False scalar
|
|
102
|
+
# All values valid -> create explicit False mask array matching input shape
|
|
103
|
+
mask = np.zeros(args[0].shape, dtype=bool)
|
|
104
|
+
|
|
105
|
+
# Extract unmasked (valid) entries and flatten to 1D
|
|
72
106
|
if return_numpy_array:
|
|
73
|
-
out_args = [arg[~mask]
|
|
107
|
+
out_args = [arg.data[~mask] for arg in args]
|
|
74
108
|
else:
|
|
75
109
|
out_args = [arg[~mask] for arg in args]
|
|
76
|
-
|
|
110
|
+
|
|
111
|
+
return mask, *out_args # type: ignore[return-value]
|
|
77
112
|
|
|
78
113
|
|
|
79
114
|
def reverse_filter_and_restore(
|
|
80
115
|
mask: np.ndarray, *args: np.ndarray
|
|
81
|
-
) ->
|
|
116
|
+
) -> tuple[np.ma.MaskedArray, ...]:
|
|
82
117
|
"""Restores 1D filtered arrays back to their original shape with masking.
|
|
83
118
|
|
|
84
119
|
Typically called with results returned from the rock-physics library.
|
|
@@ -152,28 +187,11 @@ def _verify_export_inputs(props, grid, dates, file_format=None):
|
|
|
152
187
|
)
|
|
153
188
|
|
|
154
189
|
|
|
155
|
-
def ntg_to_shale_fraction(
|
|
156
|
-
ntg: np.ma.MaskedArray, por: np.ma.MaskedArray
|
|
157
|
-
) -> np.ma.MaskedArray:
|
|
158
|
-
"""Calculate sand and shale fraction from N/G property
|
|
159
|
-
|
|
160
|
-
Args:
|
|
161
|
-
ntg: net-to-gross property [fraction]
|
|
162
|
-
por: total porosity [fraction]
|
|
163
|
-
|
|
164
|
-
Returns:
|
|
165
|
-
shale fraction
|
|
166
|
-
"""
|
|
167
|
-
clip_ntg: np.ma.MaskedArray = np.ma.clip(np.ma.MaskedArray(ntg), 0.0, 1.0) # type: ignore[assignment]
|
|
168
|
-
vsh: np.ma.MaskedArray = np.ma.MaskedArray(1.0 - clip_ntg)
|
|
169
|
-
return (vsh / (1.0 - por)).clip(0.0, 1.0)
|
|
170
|
-
|
|
171
|
-
|
|
172
190
|
def get_shale_fraction(
|
|
173
|
-
vol_fractions:
|
|
191
|
+
vol_fractions: list[np.ma.MaskedArray],
|
|
174
192
|
fraction_names: list[str],
|
|
175
|
-
shale_fraction_names:
|
|
176
|
-
) ->
|
|
193
|
+
shale_fraction_names: str | list[str] | None = None,
|
|
194
|
+
) -> np.ma.MaskedArray | None:
|
|
177
195
|
"""
|
|
178
196
|
|
|
179
197
|
Args:
|
|
@@ -210,7 +228,7 @@ def estimate_cement(
|
|
|
210
228
|
shear_modulus: float | int,
|
|
211
229
|
density: float | int,
|
|
212
230
|
grid: np.ma.MaskedArray,
|
|
213
|
-
) ->
|
|
231
|
+
) -> EffectiveMineralProperties:
|
|
214
232
|
"""Creates masked arrays filled with constant cement properties, matching the shape
|
|
215
233
|
and mask of the input grid.
|
|
216
234
|
|
|
@@ -226,12 +244,12 @@ def estimate_cement(
|
|
|
226
244
|
cement_k = to_masked_array(bulk_modulus, grid)
|
|
227
245
|
cement_mu = to_masked_array(shear_modulus, grid)
|
|
228
246
|
cement_rho = to_masked_array(density, grid)
|
|
229
|
-
return
|
|
230
|
-
bulk_modulus=cement_k, shear_modulus=cement_mu,
|
|
247
|
+
return EffectiveMineralProperties(
|
|
248
|
+
bulk_modulus=cement_k, shear_modulus=cement_mu, density=cement_rho
|
|
231
249
|
)
|
|
232
250
|
|
|
233
251
|
|
|
234
|
-
def update_dict_list(base_list:
|
|
252
|
+
def update_dict_list(base_list: list[dict], add_list: list[dict]) -> list[dict]:
|
|
235
253
|
"""Update/add new key/value pairs to dicts in list
|
|
236
254
|
|
|
237
255
|
Args:
|
|
@@ -260,3 +278,37 @@ def _verify_update_inputs(base, add_list):
|
|
|
260
278
|
and all(isinstance(item, dict) for item in add_list)
|
|
261
279
|
):
|
|
262
280
|
raise TypeError(f"{__file__}: all items in input lists are not dict")
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
def bar_to_pa(
|
|
284
|
+
pres_bar: float | np.ndarray | np.ma.MaskedArray,
|
|
285
|
+
) -> float | np.ndarray | np.ma.MaskedArray:
|
|
286
|
+
"""
|
|
287
|
+
Pressure unit conversion from bar to Pa
|
|
288
|
+
"""
|
|
289
|
+
return pres_bar * 1.0e5
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
def pa_to_bar(
|
|
293
|
+
pres_pa: float | np.ndarray | np.ma.MaskedArray,
|
|
294
|
+
) -> float | np.ndarray | np.ma.MaskedArray:
|
|
295
|
+
"""
|
|
296
|
+
Pressure unit conversion from Pa to bar
|
|
297
|
+
"""
|
|
298
|
+
return pres_pa * 1.0e-5
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
def convert_single_pressure_to_pa(
|
|
302
|
+
single_press_bar: PressureProperties,
|
|
303
|
+
) -> PressureProperties:
|
|
304
|
+
return PressureProperties(
|
|
305
|
+
effective_pressure=bar_to_pa(single_press_bar.effective_pressure),
|
|
306
|
+
formation_pressure=bar_to_pa(single_press_bar.formation_pressure),
|
|
307
|
+
overburden_pressure=bar_to_pa(single_press_bar.overburden_pressure),
|
|
308
|
+
)
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
def convert_pressures_list_to_pa(
|
|
312
|
+
press_bar: list[PressureProperties],
|
|
313
|
+
) -> list[PressureProperties]:
|
|
314
|
+
return [convert_single_pressure_to_pa(pres) for pres in press_bar]
|
fmu/pem/run_pem.py
CHANGED
|
@@ -6,9 +6,8 @@ from fmu.pem import pem_utilities as pem_utils
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
def pem_fcn(
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
pem_config_file_name: Path,
|
|
9
|
+
config: pem_utils.PemConfig,
|
|
10
|
+
config_dir: Path,
|
|
12
11
|
run_from_rms=False,
|
|
13
12
|
proj=None,
|
|
14
13
|
) -> None:
|
|
@@ -17,82 +16,101 @@ def pem_fcn(
|
|
|
17
16
|
yaml-file control the selections made in the PEM.
|
|
18
17
|
|
|
19
18
|
"""
|
|
20
|
-
# Read and validate all PEM parameters
|
|
21
|
-
config = pem_utils.read_pem_config(
|
|
22
|
-
start_dir.joinpath(rel_path_pem, pem_config_file_name)
|
|
23
|
-
)
|
|
24
|
-
|
|
25
|
-
# Read necessary part of global configurations and parameters
|
|
26
|
-
config.update_with_global(
|
|
27
|
-
pem_utils.get_global_params_and_dates(
|
|
28
|
-
start_dir, config.paths.rel_path_fmu_config
|
|
29
|
-
)
|
|
30
|
-
)
|
|
31
|
-
|
|
32
19
|
# Import Eclipse simulation grid - INIT and RESTART
|
|
33
|
-
egrid_file = start_dir / config.paths.rel_path_simgrid / "ECLIPSE.EGRID"
|
|
34
|
-
init_property_file = start_dir / config.paths.rel_path_simgrid / "ECLIPSE.INIT"
|
|
35
|
-
restart_property_file = start_dir / config.paths.rel_path_simgrid / "ECLIPSE.UNRST"
|
|
36
|
-
|
|
37
20
|
sim_grid, constant_props, time_step_props = pem_utils.read_sim_grid_props(
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
config.
|
|
21
|
+
rel_dir_sim_files=config.eclipse_files.rel_path_simgrid,
|
|
22
|
+
egrid_file=config.eclipse_files.egrid_file,
|
|
23
|
+
init_property_file=config.eclipse_files.init_property_file,
|
|
24
|
+
restart_property_file=config.eclipse_files.restart_property_file,
|
|
25
|
+
seis_dates=config.global_params.mod_dates,
|
|
26
|
+
fipnum_name=config.alternative_fipnum_name,
|
|
42
27
|
)
|
|
43
28
|
|
|
44
29
|
# Calculate rock properties - fluids and minerals
|
|
45
|
-
# Fluid properties calculated for all time-steps
|
|
46
|
-
fluid_properties = pem_fcns.effective_fluid_properties(
|
|
47
|
-
time_step_props, config.fluids
|
|
48
|
-
)
|
|
49
|
-
|
|
50
30
|
# Effective mineral (matrix) properties - one set valid for all time-steps
|
|
51
31
|
vsh, matrix_properties = pem_fcns.effective_mineral_properties(
|
|
52
|
-
|
|
32
|
+
root_dir=config_dir,
|
|
33
|
+
matrix=config.rock_matrix,
|
|
34
|
+
sim_init=constant_props,
|
|
35
|
+
sim_grid=sim_grid,
|
|
53
36
|
)
|
|
54
37
|
# VSH is exported with other constant results, add it to the constant properties
|
|
55
|
-
constant_props.
|
|
38
|
+
constant_props.vsh_pem = vsh
|
|
39
|
+
|
|
40
|
+
# Fluid properties calculated for all time-steps
|
|
41
|
+
fluid_properties, below_bp_grids = pem_fcns.effective_fluid_properties_zoned(
|
|
42
|
+
restart_props=time_step_props,
|
|
43
|
+
fluids=config.fluids,
|
|
44
|
+
pvtnum=constant_props.pvtnum,
|
|
45
|
+
)
|
|
56
46
|
|
|
57
47
|
# Estimate effective pressure
|
|
58
48
|
eff_pres = pem_fcns.estimate_pressure(
|
|
59
|
-
config,
|
|
49
|
+
rock_matrix=config.rock_matrix,
|
|
50
|
+
overburden_pressure=config.pressure,
|
|
51
|
+
sim_init=constant_props,
|
|
52
|
+
sim_rst=time_step_props,
|
|
53
|
+
matrix_props=matrix_properties,
|
|
54
|
+
fluid_props=fluid_properties,
|
|
55
|
+
sim_dates=config.global_params.mod_dates,
|
|
56
|
+
fipnum=constant_props.fipnum,
|
|
60
57
|
)
|
|
61
58
|
|
|
62
59
|
# Estimate saturated rock properties
|
|
63
|
-
sat_rock_props = pem_fcns.estimate_saturated_rock(
|
|
64
|
-
config,
|
|
60
|
+
sat_rock_props, dry_rock = pem_fcns.estimate_saturated_rock(
|
|
61
|
+
rock_matrix=config.rock_matrix,
|
|
62
|
+
sim_init=constant_props,
|
|
63
|
+
press_props=eff_pres,
|
|
64
|
+
matrix_props=matrix_properties,
|
|
65
|
+
fluid_props=fluid_properties,
|
|
66
|
+
model_directory=config.paths.rel_path_pem,
|
|
67
|
+
fipnum_param=constant_props.fipnum,
|
|
65
68
|
)
|
|
66
69
|
|
|
67
70
|
# Delta and cumulative time estimates (only TWT properties are kept)
|
|
68
71
|
sum_delta_time = pem_utils.delta_cumsum_time.estimate_sum_delta_time(
|
|
69
|
-
constant_props,
|
|
72
|
+
constant_props=constant_props,
|
|
73
|
+
sat_rock_props=sat_rock_props,
|
|
70
74
|
)
|
|
71
75
|
|
|
72
76
|
# Calculate difference properties. Possible properties are all that vary with time
|
|
73
77
|
diff_props, diff_date_strs = pem_utils.calculate_diff_properties(
|
|
74
|
-
[time_step_props, eff_pres, sat_rock_props, sum_delta_time],
|
|
78
|
+
props=[time_step_props, eff_pres, sat_rock_props, sum_delta_time],
|
|
79
|
+
diff_dates=config.global_params.mod_diffdates,
|
|
80
|
+
seis_dates=config.global_params.mod_dates,
|
|
81
|
+
diff_calculation=config.diff_calculation,
|
|
75
82
|
)
|
|
76
83
|
|
|
77
84
|
# As a precaution, update the grid mask for inactive cells, based on the saturated
|
|
78
85
|
# rock properties
|
|
79
|
-
sim_grid = pem_utils.update_inactive_grid_cells(
|
|
86
|
+
sim_grid = pem_utils.update_inactive_grid_cells(
|
|
87
|
+
grid=sim_grid,
|
|
88
|
+
props=sat_rock_props,
|
|
89
|
+
)
|
|
80
90
|
|
|
81
91
|
# Save results to disk or RMS project according to settings in the PEM config
|
|
82
92
|
pem_utils.save_results(
|
|
83
|
-
|
|
84
|
-
run_from_rms,
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
93
|
+
config_dir=config_dir,
|
|
94
|
+
run_from_rms_flag=run_from_rms,
|
|
95
|
+
rms_project=proj,
|
|
96
|
+
sim_grid=sim_grid,
|
|
97
|
+
grid_name=config.global_params.grid_model,
|
|
98
|
+
seis_dates=config.global_params.mod_dates,
|
|
99
|
+
save_to_rms=config.results.save_results_to_rms,
|
|
100
|
+
save_to_disk=config.results.save_results_to_disk,
|
|
101
|
+
save_intermediate=config.results.save_intermediate_results,
|
|
102
|
+
mandatory_path=config.paths.rel_path_mandatory_output,
|
|
103
|
+
pem_output_path=config.paths.rel_path_output,
|
|
104
|
+
eff_pres_props=eff_pres,
|
|
105
|
+
sat_rock_props=sat_rock_props,
|
|
106
|
+
difference_props=diff_props,
|
|
107
|
+
difference_date_strs=diff_date_strs,
|
|
108
|
+
matrix_props=matrix_properties,
|
|
109
|
+
fluid_props=fluid_properties,
|
|
110
|
+
bubble_point_grids=below_bp_grids,
|
|
111
|
+
dry_rock_props=dry_rock,
|
|
94
112
|
)
|
|
95
113
|
|
|
96
114
|
# Restore original path
|
|
97
|
-
os.chdir(
|
|
115
|
+
os.chdir(config_dir)
|
|
98
116
|
return
|
fmu/pem/version.py
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
# file generated by setuptools-scm
|
|
2
2
|
# don't change, don't track in version control
|
|
3
3
|
|
|
4
|
-
__all__ = [
|
|
4
|
+
__all__ = [
|
|
5
|
+
"__version__",
|
|
6
|
+
"__version_tuple__",
|
|
7
|
+
"version",
|
|
8
|
+
"version_tuple",
|
|
9
|
+
"__commit_id__",
|
|
10
|
+
"commit_id",
|
|
11
|
+
]
|
|
5
12
|
|
|
6
13
|
TYPE_CHECKING = False
|
|
7
14
|
if TYPE_CHECKING:
|
|
@@ -9,13 +16,19 @@ if TYPE_CHECKING:
|
|
|
9
16
|
from typing import Union
|
|
10
17
|
|
|
11
18
|
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
19
|
+
COMMIT_ID = Union[str, None]
|
|
12
20
|
else:
|
|
13
21
|
VERSION_TUPLE = object
|
|
22
|
+
COMMIT_ID = object
|
|
14
23
|
|
|
15
24
|
version: str
|
|
16
25
|
__version__: str
|
|
17
26
|
__version_tuple__: VERSION_TUPLE
|
|
18
27
|
version_tuple: VERSION_TUPLE
|
|
28
|
+
commit_id: COMMIT_ID
|
|
29
|
+
__commit_id__: COMMIT_ID
|
|
19
30
|
|
|
20
|
-
__version__ = version = '0.0.
|
|
21
|
-
__version_tuple__ = version_tuple = (0, 0,
|
|
31
|
+
__version__ = version = '0.0.4'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 0, 4)
|
|
33
|
+
|
|
34
|
+
__commit_id__ = commit_id = None
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fmu-pem
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.4
|
|
4
4
|
Summary: pem
|
|
5
5
|
License: GNU GENERAL PUBLIC LICENSE
|
|
6
6
|
Version 3, 29 June 2007
|
|
@@ -695,7 +695,8 @@ Requires-Dist: xtgeo>=4.7.1
|
|
|
695
695
|
Requires-Dist: fmu-tools
|
|
696
696
|
Requires-Dist: fmu-config
|
|
697
697
|
Requires-Dist: fmu-dataio
|
|
698
|
-
Requires-Dist:
|
|
698
|
+
Requires-Dist: fmu-datamodels
|
|
699
|
+
Requires-Dist: rock-physics-open>=0.3.3
|
|
699
700
|
Requires-Dist: PyYAML>=6.0.1
|
|
700
701
|
Requires-Dist: pydantic
|
|
701
702
|
Requires-Dist: ert>=14.1.10
|
|
@@ -716,7 +717,8 @@ Requires-Dist: sphinx_rtd_theme; extra == "docs"
|
|
|
716
717
|
Dynamic: license-file
|
|
717
718
|
|
|
718
719
|
> [!WARNING]
|
|
719
|
-
> `fmu-pem` is not yet qualified technology, and as of today only applicable for
|
|
720
|
+
> `fmu-pem` is not yet qualified technology, and as of today only applicable for
|
|
721
|
+
selected pilot test fields.
|
|
720
722
|
|
|
721
723
|
**[📚 User documentation](https://equinor.github.io/fmu-pem/)**
|
|
722
724
|
|
|
@@ -731,25 +733,28 @@ based on the [rock-physics-open](https://github.com/equinor/rock-physics-open) l
|
|
|
731
733
|
|
|
732
734
|
To install `fmu-pem`, first activate a virtual environment, then type:
|
|
733
735
|
|
|
734
|
-
```
|
|
736
|
+
```shell
|
|
735
737
|
pip install fmu-pem
|
|
736
738
|
```
|
|
737
739
|
|
|
738
740
|
The PEM is controlled by parameter settings in a *yaml-file*, given as part of the
|
|
739
|
-
command line arguments, or by the workflow parameter if it is run as an ERT forward
|
|
741
|
+
command line arguments, or by the workflow parameter if it is run as an ERT forward
|
|
742
|
+
model.
|
|
740
743
|
|
|
741
744
|
### Calibration of rock physics models
|
|
742
745
|
|
|
743
746
|
Calibration of the rock physics models is normally carried out in
|
|
744
747
|
[RokDoc](https://www.ikonscience.com/rokdoc-geoprediction-software-platform/)
|
|
745
|
-
prior to running the PEM. Fluid and mineral properties can be found in the RokDoc
|
|
746
|
-
from LFP logs, if they are available.
|
|
748
|
+
prior to running the PEM. Fluid and mineral properties can be found in the RokDoc
|
|
749
|
+
project, or from LFP logs, if they are available.
|
|
747
750
|
|
|
748
|
-
> [!NOTE]
|
|
749
|
-
> The fluid models contained in this module may not cover all possible cases. Gas
|
|
750
|
-
> or reservoir pressure under hydrocarbon bubble point will
|
|
751
|
+
> [!NOTE]
|
|
752
|
+
> The fluid models contained in this module may not cover all possible cases. Gas
|
|
753
|
+
condensate, very heavy oil, > or reservoir pressure under hydrocarbon bubble point will
|
|
754
|
+
need additional proprietary code to run.
|
|
751
755
|
>
|
|
752
756
|
> Equinor users can install additional proprietary models using
|
|
757
|
+
|
|
753
758
|
> ```bash
|
|
754
759
|
> pip install "git+ssh://git@github.com/equinor/rock-physics"`
|
|
755
760
|
> ```
|
|
@@ -757,10 +762,13 @@ from LFP logs, if they are available.
|
|
|
757
762
|
## How to develop fmu-pem?
|
|
758
763
|
|
|
759
764
|
Developing the user interface can be done by:
|
|
765
|
+
|
|
760
766
|
```bash
|
|
761
767
|
cd ./documentation
|
|
762
768
|
npm ci # Install dependencies
|
|
763
769
|
npm run create-json-schema # Extract JSON schema from Python code
|
|
764
770
|
npm run docs:dev # Start local development server
|
|
765
771
|
```
|
|
766
|
-
|
|
772
|
+
|
|
773
|
+
The JSON schema itself (type, title, description etc.) comes from the corresponding
|
|
774
|
+
Pydantic models in the Python code.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
fmu/__init__.py,sha256=YWSE22UTDSocfqQHxEeXrRkdlA63t_aayQVdJkycwYs,83
|
|
2
|
+
fmu/pem/__init__.py,sha256=k-KRNGtW24pTPQv81c5DOYbW9Thy5xv514euStVRYtY,466
|
|
3
|
+
fmu/pem/__main__.py,sha256=43ugEF49aHi33Yv5CSWo8NPfzKsZAhHQrc5_IfnIoEI,3013
|
|
4
|
+
fmu/pem/run_pem.py,sha256=wmGTyQyh8wws5PwouiJf-rtvmrTu3-rzqQSuutEcXx4,4256
|
|
5
|
+
fmu/pem/version.py,sha256=QlXZ5JTjE_pgpDaeHk0GTExkc75xUZFmd0hA7kGYCJ0,704
|
|
6
|
+
fmu/pem/forward_models/__init__.py,sha256=WuN66rmgfqrekCy3Ss9NHqsy-lZ4WGY-4VZa3jYDV2s,117
|
|
7
|
+
fmu/pem/forward_models/pem_model.py,sha256=7aZOmW8IOolQLLIPNWPizciDDDe8QMUsFSyJhmU1G80,2124
|
|
8
|
+
fmu/pem/hook_implementations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
+
fmu/pem/hook_implementations/jobs.py,sha256=IQW5m7oeZ_MiemxXv-UGLCPeo4h3QT9oELPlWAzsN60,388
|
|
10
|
+
fmu/pem/pem_functions/__init__.py,sha256=aGFW0Gmr1rZsmzZhKdll9ofWcgpobzsHxfCNwr2Ypqc,551
|
|
11
|
+
fmu/pem/pem_functions/density.py,sha256=txcG0bp2Fq20A2E6O3-KQtiJm60BXOou-TcgZlnnluw,1605
|
|
12
|
+
fmu/pem/pem_functions/effective_pressure.py,sha256=Qd4selju2qGFWJdWuWFJu8Hyad3e_v3yS3nt5SjKXTQ,10706
|
|
13
|
+
fmu/pem/pem_functions/estimate_saturated_rock.py,sha256=S_uqsX5xDOhndSK7bvMYvdPj_VRwffkm17760T6tZNo,11577
|
|
14
|
+
fmu/pem/pem_functions/fluid_properties.py,sha256=i6iOHGCYC3DI4_Pe54DaMaBhJysdQNhAFQVko6PLnys,18325
|
|
15
|
+
fmu/pem/pem_functions/mineral_properties.py,sha256=1TLs8ZG8Js-k8QpgNNLesruUALQsfqgJawcLLfqZJRY,8068
|
|
16
|
+
fmu/pem/pem_functions/pressure_sensitivity.py,sha256=_IG7nMlalFuBlyrS9YpGZ2F-ClLENS75viDO1_OVaEA,13098
|
|
17
|
+
fmu/pem/pem_functions/regression_models.py,sha256=wUw5yIIeR5sGz7OqAp42K4lxLUOKr-B4_1XkM9k2WXA,10391
|
|
18
|
+
fmu/pem/pem_functions/run_friable_model.py,sha256=R3Nb0nQML6k5QrPwDoB7oMHaTkB-rJjCSPnJ_gsrIIQ,6885
|
|
19
|
+
fmu/pem/pem_functions/run_patchy_cement_model.py,sha256=M561C_4dfPW_Nxm0AgzCUdeQ9UVIrZGGhxBayII1IDQ,6667
|
|
20
|
+
fmu/pem/pem_functions/run_t_matrix_model.py,sha256=Ctl5Lw1HJvNYdqKDUnqrOWRisVV2m1J4gJ6S2u8j-Xw,7875
|
|
21
|
+
fmu/pem/pem_utilities/__init__.py,sha256=p3Fv-wUDH_te9WUHSNj-WS08ly2asRr9iNN6Kw-2f1o,2089
|
|
22
|
+
fmu/pem/pem_utilities/cumsum_properties.py,sha256=s3M0bMs6Dogg8cWzj5M6K5xifdRjhZse3dCWZL0_RCo,3431
|
|
23
|
+
fmu/pem/pem_utilities/delta_cumsum_time.py,sha256=vDc7Hvl50qzUXbK4oKq30zlQ2fqMel9EmBO0lmeoDbo,3035
|
|
24
|
+
fmu/pem/pem_utilities/enum_defs.py,sha256=R6Q0G6TQKe1MM4KTp1t_iCaFuCWEwLvIqV6tH3uxCms,2485
|
|
25
|
+
fmu/pem/pem_utilities/export_routines.py,sha256=hteGM4flK8B7Jy4BNk5bU33-_jcNndFrm9RcnzfTdy4,10108
|
|
26
|
+
fmu/pem/pem_utilities/fipnum_pvtnum_utilities.py,sha256=ypwTsyfqqBJ6d8WHY2HkKAdX9ZjHYLdQq_-3w2xEwVQ,7571
|
|
27
|
+
fmu/pem/pem_utilities/import_config.py,sha256=Ms16Tth0-U28D9VIvExF9y-WVVaJSzY6Kkdh6RHVXOg,3700
|
|
28
|
+
fmu/pem/pem_utilities/import_routines.py,sha256=EVHCS-LaHXKwVgDiE5BDvybJgPi0PjFado2m1O9ezo4,5104
|
|
29
|
+
fmu/pem/pem_utilities/pem_class_definitions.py,sha256=Q_k5s_Zj8q_9TKdnxdJdOeN1UVGZbH997ngs8_5t0Es,5504
|
|
30
|
+
fmu/pem/pem_utilities/pem_config_validation.py,sha256=6SOuNoobSy4y42Z8AAczCVh9nODSorBnHcCTknMy3GQ,27639
|
|
31
|
+
fmu/pem/pem_utilities/rpm_models.py,sha256=S4BDv5aTaMHgk-nSYxBQ1I_SzkSGXVd6HNtoUViElwE,21212
|
|
32
|
+
fmu/pem/pem_utilities/update_grid.py,sha256=Ay0XPGXBl5CtdL5keTGzs0AKp44LgsuqxwBVwmHZV_s,1838
|
|
33
|
+
fmu/pem/pem_utilities/utils.py,sha256=dHfQLDfwG27eC86lHN12PrITuock8M5IH-gD7eWAtCE,10583
|
|
34
|
+
fmu_pem-0.0.4.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
35
|
+
fmu_pem-0.0.4.dist-info/METADATA,sha256=wakrxOg0kE20GH5s5rJ_OxX6bhDNRCiya6JEeSBfFr4,43878
|
|
36
|
+
fmu_pem-0.0.4.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
37
|
+
fmu_pem-0.0.4.dist-info/entry_points.txt,sha256=NSoFnob1PAE6FzRyNJZn5idocnCB1ptNg6R8zYf7Gnc,98
|
|
38
|
+
fmu_pem-0.0.4.dist-info/top_level.txt,sha256=Z-FIY3pxn0UK2Wxi9IJ7fKoLSraaxuNGi1eokiE0ShM,4
|
|
39
|
+
fmu_pem-0.0.4.dist-info/RECORD,,
|
fmu_pem-0.0.2.dist-info/RECORD
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
fmu/__init__.py,sha256=YWSE22UTDSocfqQHxEeXrRkdlA63t_aayQVdJkycwYs,83
|
|
2
|
-
fmu/pem/__init__.py,sha256=FhNaFibcFZEK1Rz7IBRXBgxMHGNlcgrHaD4FtU4pDjs,421
|
|
3
|
-
fmu/pem/__main__.py,sha256=L8HW2P6_AQX70gcgmMdbW0BouCQdI0OVab-U4QkcPOk,1361
|
|
4
|
-
fmu/pem/run_pem.py,sha256=z6UAuEAJlSVcbTeC2q5q8_ToKe0HIgQPHZfjRWSg6PI,3218
|
|
5
|
-
fmu/pem/version.py,sha256=wO7XWlZte1hxA4mMvRc6zhNdGm74Nhhn2bfWRAxaKbI,511
|
|
6
|
-
fmu/pem/forward_models/__init__.py,sha256=WuN66rmgfqrekCy3Ss9NHqsy-lZ4WGY-4VZa3jYDV2s,117
|
|
7
|
-
fmu/pem/forward_models/pem_model.py,sha256=fKDD1-euwLBMr6rAjDYG0o-k7uKYRxG6De6bywF3AXI,2203
|
|
8
|
-
fmu/pem/hook_implementations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
-
fmu/pem/hook_implementations/jobs.py,sha256=IQW5m7oeZ_MiemxXv-UGLCPeo4h3QT9oELPlWAzsN60,388
|
|
10
|
-
fmu/pem/pem_functions/__init__.py,sha256=G2tu5E1PFvlw36fLdmr2A4Xr9ZqbKMf104OU5ydh_3A,539
|
|
11
|
-
fmu/pem/pem_functions/density.py,sha256=eiAvZC7L3LvD0VuJYKSKY_M1WpqnxUS935-kKsT8NyA,1791
|
|
12
|
-
fmu/pem/pem_functions/effective_pressure.py,sha256=AoiMlBkCtERIZ3R0Nct07J7Rj5FaOEeEtS4u738KU-0,6141
|
|
13
|
-
fmu/pem/pem_functions/estimate_saturated_rock.py,sha256=upWTEZ_FCi45FoG4aW5vRdX58VoEDRFlo1ZTyokQpw0,2762
|
|
14
|
-
fmu/pem/pem_functions/fluid_properties.py,sha256=fRS922lwJxca4m12V9XOV5bSa2KaQzt6OQ2WLg0o9EE,10811
|
|
15
|
-
fmu/pem/pem_functions/mineral_properties.py,sha256=ilf1TwE4DDev65TdHEuudxgLj41IRBWgSjXghNrCPak,8394
|
|
16
|
-
fmu/pem/pem_functions/regression_models.py,sha256=fNpeKzVDhFniMTlWlypfcPsEx-ztfueR1Cuo7EspJhk,9091
|
|
17
|
-
fmu/pem/pem_functions/run_friable_model.py,sha256=PzDZjJ3KDGUfwN0nht90lk8yM0RMXS1ZzwEztjdULzk,4274
|
|
18
|
-
fmu/pem/pem_functions/run_patchy_cement_model.py,sha256=A8pIu3fHujoc5U382WK2R_q4GcG8D1F3wHKBRsV7k8Y,4217
|
|
19
|
-
fmu/pem/pem_functions/run_t_matrix_and_pressure.py,sha256=GmGcEq38Oii2mI5tHBaJ7LutE67wKx6MyrtCMpdGWVk,6823
|
|
20
|
-
fmu/pem/pem_utilities/__init__.py,sha256=r9vSDgrY4B2NwBK5PL-4GMD5o1aT2IpR1vaeOCgJ-tI,1687
|
|
21
|
-
fmu/pem/pem_utilities/cumsum_properties.py,sha256=W2FtawYPZzdydGsVoOYCWIgOItNGKCRzhHzI5sUw05M,3769
|
|
22
|
-
fmu/pem/pem_utilities/delta_cumsum_time.py,sha256=J83PSpO2xjxHP5tpDpleVxynt0eytqHLgbGzj79wTQI,3267
|
|
23
|
-
fmu/pem/pem_utilities/enum_defs.py,sha256=SFs_5lru3Br9xHqnUrWJyeJzLvE6JAAsI_MMaA6tjlU,1354
|
|
24
|
-
fmu/pem/pem_utilities/export_routines.py,sha256=gZa3AscefV9h55JQXL7juQg5SpMvhnN5nbBHFU2VtCI,9879
|
|
25
|
-
fmu/pem/pem_utilities/import_config.py,sha256=H6nH_MVnVhuS4q-4KWhoOvQbGzV5Jnw1-KlD1BRccmY,3232
|
|
26
|
-
fmu/pem/pem_utilities/import_routines.py,sha256=nj-yJYFlGno7p0k67SdjjQzUUbA92Bgfv5g7q9Nx8pA,5321
|
|
27
|
-
fmu/pem/pem_utilities/pem_class_definitions.py,sha256=IOwzHfMsoPoGWIs1-I-kI2wVbhgR5TjZHygXOMsECMk,3282
|
|
28
|
-
fmu/pem/pem_utilities/pem_config_validation.py,sha256=8pUDTx0aGGpqBuTJth0adDTvbrODIvKifXqWy0J_WRU,19111
|
|
29
|
-
fmu/pem/pem_utilities/rpm_models.py,sha256=UjqCGy-nbo2uPp-KlRdUmFRG9up2XVTlI8DplDTjIdU,6836
|
|
30
|
-
fmu/pem/pem_utilities/update_grid.py,sha256=InGaWrgIH5G9xyGqazAxQmVHL0nve4B9dAttisBsIpU,1775
|
|
31
|
-
fmu/pem/pem_utilities/utils.py,sha256=Gm_onSB7KuHZ0iKzx5TjHCOBYkatewSyEXgC9J-UA70,8871
|
|
32
|
-
fmu_pem-0.0.2.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
33
|
-
fmu_pem-0.0.2.dist-info/METADATA,sha256=bJh3W1AKoDPrC4-CPet8xAoVpOKRRVkebtW6Rw0wpqM,43839
|
|
34
|
-
fmu_pem-0.0.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
35
|
-
fmu_pem-0.0.2.dist-info/entry_points.txt,sha256=NSoFnob1PAE6FzRyNJZn5idocnCB1ptNg6R8zYf7Gnc,98
|
|
36
|
-
fmu_pem-0.0.2.dist-info/top_level.txt,sha256=Z-FIY3pxn0UK2Wxi9IJ7fKoLSraaxuNGi1eokiE0ShM,4
|
|
37
|
-
fmu_pem-0.0.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|