Skip to content

Commit 23f2b9e

Browse files
authored
Add function to combine multiple petro realizations using facies realization (#266)
Add function to import and export field parameters to and from ERTBOX grid. Added documentation for update_petro_real and the export and import functions. Add test for update_petro_real.py
1 parent 81af438 commit 23f2b9e

6 files changed

Lines changed: 1344 additions & 0 deletions

File tree

docs/export_and_import_fields.rst

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
rms.export_and_import_field_parameters
2+
=======================================
3+
4+
The export and import functions described below supports a workflow where
5+
both facies and petrophysical properties are updated as field parameters in ERT.
6+
The implemented functions in the module *fmu.tools.rms.update_petro_real* are::
7+
8+
export_initial_field_parameters
9+
import_updated_field_parameters
10+
11+
Both the export and import function the same set of petrophysical variables in the
12+
same workflow. Therefore, they both read this information from a configuration file
13+
in YAML format that is also shared with the function *generate_petro_jobs*.
14+
15+
Export petrophysical parameters as field parameters to be used in ERT FIELD keyword
16+
-------------------------------------------------------------------------------------
17+
18+
Example of use of the export function
19+
20+
.. code-block:: python
21+
22+
from fmu.tools.rms import export_initial_field_parameters
23+
from fmu.tools.rms.generate_petro_jobs_for_field_update import read_specification_file
24+
25+
DEBUG_PRINT=True
26+
CONFIG_FILE_NAME_VALYSAR = "../input/config/field_update/generate_petro_jobs_valysar.yml"
27+
CONFIG_FILE_NAME_THERYS = "../input/config/field_update/generate_petro_jobs_therys.yml"
28+
CONFIG_FILE_NAME_VOLON = "../input/config/field_update/generate_petro_jobs_volon.yml"
29+
ERTBOX_GRID = "ERTBOX"
30+
31+
32+
def export_fields():
33+
spec_dict = read_specification_file(CONFIG_FILE_NAME_VALYSAR)
34+
used_petro_dict = spec_dict["used_petro_var"]
35+
export_initial_field_parameters(
36+
project,
37+
used_petro_dict,
38+
grid_model_name=ERTBOX_GRID,
39+
zone_name_for_single_zone_grid="Valysar",
40+
debug_print= DEBUG_PRINT)
41+
42+
spec_dict = read_specification_file(CONFIG_FILE_NAME_THERYS)
43+
used_petro_dict = spec_dict["used_petro_var"]
44+
export_initial_field_parameters(
45+
project,
46+
used_petro_dict,
47+
grid_model_name=ERTBOX_GRID,
48+
zone_name_for_single_zone_grid="Therys",
49+
debug_print= DEBUG_PRINT)
50+
51+
spec_dict = read_specification_file(CONFIG_FILE_NAME_VOLON)
52+
used_petro_dict = spec_dict["used_petro_var"]
53+
export_initial_field_parameters(
54+
project,
55+
used_petro_dict,
56+
grid_model_name=ERTBOX_GRID,
57+
zone_name_for_single_zone_grid="Volon",
58+
debug_print= DEBUG_PRINT)
59+
60+
if __name__ == "__main__":
61+
export_fields()
62+
63+
64+
Import petrophysical parameters used as field parameters to be used in ERT FIELD keyword
65+
------------------------------------------------------------------------------------------
66+
67+
Example of use of the import function
68+
69+
.. code-block:: python
70+
71+
from fmu.tools.rms import import_updated_field_parameters
72+
from fmu.tools.rms.generate_petro_jobs_for_field_update import read_specification_file
73+
74+
75+
DEBUG_PRINT = False
76+
CONFIG_FILE_NAME_VALYSAR = "../input/config/field_update/generate_petro_jobs_valysar.yml"
77+
CONFIG_FILE_NAME_THERYS = "../input/config/field_update/generate_petro_jobs_therys.yml"
78+
CONFIG_FILE_NAME_VOLON = "../input/config/field_update/generate_petro_jobs_volon.yml"
79+
ERTBOX_GRID = "ERTBOX"
80+
81+
def import_fields():
82+
spec_dict = read_specification_file(CONFIG_FILE_NAME_VALYSAR)
83+
used_petro_dict = spec_dict["used_petro_var"]
84+
import_updated_field_parameters(
85+
project,
86+
used_petro_dict,
87+
grid_model_name=ERTBOX_GRID,
88+
zone_name_for_single_zone_grid="Valysar",
89+
debug_print=DEBUG_PRINT)
90+
91+
spec_dict = read_specification_file(CONFIG_FILE_NAME_THERYS)
92+
used_petro_dict = spec_dict["used_petro_var"]
93+
import_updated_field_parameters(
94+
project,
95+
used_petro_dict,
96+
grid_model_name=ERTBOX_GRID,
97+
zone_name_for_single_zone_grid="Therys",
98+
debug_print=DEBUG_PRINT)
99+
100+
spec_dict = read_specification_file(CONFIG_FILE_NAME_VOLON)
101+
used_petro_dict = spec_dict["used_petro_var"]
102+
import_updated_field_parameters(
103+
project,
104+
used_petro_dict,
105+
grid_model_name=ERTBOX_GRID,
106+
zone_name_for_single_zone_grid="Volon",
107+
debug_print=DEBUG_PRINT)
108+
109+
if __name__ == "__main__":
110+
import_fields()
111+

docs/index.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ Contents:
1818
rename_rms_scripts
1919
rms_import_localmodule
2020
generate_bw_per_facies
21+
update_petro_real
22+
export_and_import_fields
2123
utilities
2224
rmsvolumetrics2csv
2325
ensembles

docs/update_petro_real.rst

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
rms.update_petro_parameters
2+
============================
3+
4+
When running FMU project where field parameters for both facies and
5+
petrophysical properties are updated in ERT simultaneously,
6+
some adjustments are needed in the RMS project to support this type
7+
of workflow. It is necessary to have one petrosim job per facies.
8+
9+
The module *update_petro_parameters* will combine values from realization
10+
of a petrophysical property for individual facies into one common
11+
petrophysical realization by using the facies realization as filter.
12+
13+
14+
Example describing the workflow
15+
--------------------------------
16+
17+
The zone Valysar has four different facies::
18+
19+
Floodplain
20+
Channel
21+
Crevasse
22+
Coal
23+
24+
A petrophysical realization is made for PHIT and KLOGH for each of the three
25+
first facies with property names::
26+
27+
Floodplain_PHIT
28+
Floodplain_KLOGH
29+
Channel_PHIT
30+
Channel_KLOGH
31+
Crevasse_PHIT
32+
Crevasse_KLOGH
33+
34+
Neither PHIT nor KLOGH are updated as field parameters for facies
35+
Coal since they have constant (not spatially varying) values and
36+
may even have no uncertainty specified.
37+
The variables VSH and VPHYL are chosen not to be used as field parameters
38+
in ERT in assisted history matching in this example
39+
and therefore not included here,
40+
but still used in the RMS workflow with the prior values.
41+
42+
The original realizations created for PHIT and KLOGH are conditioned
43+
to facies. In a workflow where we want to use both facies by applying
44+
the Adaptive PluriGaussian Simulation method (APS) and PHIT and KLOG
45+
for some selected facies as field parameters to be updated by ERT,
46+
we will need the separate PHIT and KLOGH realizations for the selected
47+
facies.
48+
49+
The steps will be:
50+
51+
* Use original petrophysical job to create initial version of a realization of
52+
PHIT, KLOGH, VSH and VPHYL.
53+
* Use separate petrophysical jobs to create separate version of realizations of
54+
Floodplain_PHIT, Floodplain_KLOGH and so on.
55+
* Use the script *update_petro_parameters* to copy the values for PHIT and KLOGH from
56+
the individual realizations per facies into the initial version of PHIT and KLOG
57+
by overwriting the values in the original version. In this process,
58+
the facies realization is used as a filter to select which grid cell values
59+
to get from the individual PHIT and KLOGH parameters that belongs to the
60+
various facies.
61+
62+
When running ERT iteration 0 which creates the initial ensemble, this looks a bit unnecessary,
63+
since the initial PHIT and KLOGH already has taken facies into account. But, when running
64+
ERT iteration larger than 0 (after ERT has updated the fields Floodplain_PHIT,
65+
Floodplain_KLOGH and so on), then updated versions of the field parameters are imported
66+
and updated version of facies realization is used to update the PHIT and KLOGH parameters
67+
from the imported field parameters (Floodplain_PHIT, Floodplain_KLOGH ...).
68+
69+
Also for iteration 0, to ensure consistency the same procedure
70+
(copy from the field parameters Floodplain_PHIT, Floodplain_KLOG,..) is
71+
applied since this ensure consistent handling of the realizations.
72+
73+
Example of RMS python job running this module to combine the field parameters
74+
-------------------------------------------------------------------------------
75+
76+
The python job below will call the *update_petro_parameters* function that does the
77+
combination of the field parameters into one petrophysical realization.
78+
This job depends on a small config file ( the same config file that is used by the
79+
function *generate_petro_jobs* from fmu.tools.rms module). Here the python job gets
80+
the grid name and which of the petrophysical properties for which facies
81+
to be updated as field parameters in ERT. The script also depends on the facies table
82+
(which facies code and name belongs together).
83+
This can be fetched from the *global_variables.yml* file as shown in the example below.
84+
85+
An alternative is to add a key *USED_PETRO_FIELDS* in global_master_config.yml
86+
and get the petro parameters per facies per zone from this keyword instead.
87+
88+
.. code-block:: python
89+
90+
from fmu.tools.rms import update_petro_parameters
91+
from fmu.config import utilities as ut
92+
93+
DEBUG_PRINT = False
94+
95+
# Choose either to use config file or input from global variable file
96+
USE_CONFIG_FILES = True
97+
98+
CFG = ut.yaml_load("../../fmuconfig/output/global_variables.yml")["global"]
99+
FACIES_ZONE = CFG["FACIES_ZONE"]
100+
101+
# Used if alternative 1 with config file is used
102+
CONFIG_FILES = {
103+
"Valysar": "../input/config/field_update/generate_petro_jobs_valysar.yml",
104+
"Therys": "../input/config/field_update/generate_petro_jobs_therys.yml",
105+
"Volon": "../input/config/field_update/generate_petro_jobs_volon.yml",
106+
}
107+
108+
# Used if alternative 2 without config file is used
109+
# In this case the global master config must be updated
110+
# to define the dictionary with used petro fields per zone per facies
111+
USED_PETRO_FIELDS = CFG["USED_PETRO_FIELDS"]
112+
GRID_NAMES = {
113+
"Valysar": "Geogrid_Valysar",
114+
"Therys": "Geogrid_Therys",
115+
"Volon": "Geogrid_Volon",
116+
}
117+
FACIES_REAL_NAMES = {
118+
"Valysar": "FACIES",
119+
"Therys": "FACIES",
120+
"Volon": "FACIES",
121+
}
122+
123+
# For multi zone grids also zone_param_name and zone_code_names must be specified
124+
# Example:
125+
# ZONE_PARAM_NAME = "Zone"
126+
# ZONE_CODE_NAMES = {
127+
# 1: "Valysar,
128+
# 2: "Therys",
129+
# 3: "Volon",
130+
# }
131+
132+
133+
if __name__ == "__main__":
134+
# Drogon uses 3 different grids and single zone grids
135+
if USE_CONFIG_FILES:
136+
# Alternative 1 using config file common with generate_petro_jobs
137+
for zone_name in ["Valysar", "Therys", "Volon"]:
138+
facies_code_names = FACIES_ZONE[zone_name]
139+
config_file = CONFIG_FILES[zone_name]
140+
update_petro_parameters(
141+
project,
142+
facies_code_names,
143+
zone_name_for_single_zone_grid=zone_name,
144+
config_file=config_file,
145+
debug_print=DEBUG_PRINT)
146+
else:
147+
# Alternative 2 specify input using global_variables file
148+
for zone_name in ["Valysar", "Therys", "Volon"]:
149+
facies_code_names = FACIES_ZONE[zone_name]
150+
grid_name = GRID_NAMES[zone_name]
151+
facies_real_name = FACIES_REAL_NAMES[zone_name]
152+
used_petro_per_facies=USED_PETRO_FIELDS
153+
update_petro_parameters(
154+
project,
155+
facies_code_names,
156+
grid_name=grid_name,
157+
facies_real_name=facies_real_name,
158+
used_petro_dict=used_petro_per_facies,
159+
zone_name_for_single_zone_grid=zone_name,
160+
debug_print=DEBUG_PRINT)
161+
162+
163+
The *global_master_config.yml* file can include a keyword for *USED_PETRO_FIELDS*
164+
165+
.. code-block:: yaml
166+
167+
USED_PETRO_FIELDS:
168+
Valysar:
169+
Floodplain: [ PHIT, KLOGH ]
170+
Channel: [ PHIT, KLOGH ]
171+
Crevasse: [ PHIT, KLOGH ]
172+
Therys:
173+
Offshore: [ PHIT, KLOGH ]
174+
Lowershoreface: [ PHIT, KLOGH ]
175+
Uppershoreface: [ PHIT, KLOGH ]
176+
Volon:
177+
Floodplain: [ PHIT, KLOGH ]
178+
Channel: [ PHIT, KLOGH ]
179+
180+
and optionally also for multizone grid:
181+
182+
.. code-block:: yaml
183+
184+
ZONE_CODE_NAMES:
185+
1: Valysar
186+
2: Therys
187+
3: Volon

src/fmu/tools/rms/__init__.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,19 @@
77
main as generate_petro_jobs,
88
)
99
from .import_localmodules import import_localmodule
10+
from .update_petro_real import (
11+
export_initial_field_parameters,
12+
import_updated_field_parameters,
13+
update_petro_real as update_petro_parameters,
14+
)
1015
from .volumetrics import rmsvolumetrics_txt2df
1116

1217
__all__ = [
1318
"rmsvolumetrics_txt2df",
1419
"import_localmodule",
1520
"generate_petro_jobs",
1621
"create_bw_per_facies",
22+
"update_petro_parameters",
23+
"import_updated_field_parameters",
24+
"export_initial_field_parameters",
1725
]

0 commit comments

Comments
 (0)