Skip to content

Commit b8e19c8

Browse files
committed
ENH: Add to_rms()/from_rms() methods in NestedHybridGrid
1 parent 31d6706 commit b8e19c8

4 files changed

Lines changed: 982 additions & 677 deletions

File tree

docs/nestedhybridgrid.rst

Lines changed: 19 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@ Overview
1616

1717
The ``nestedhybridgrid`` module creates **nested hybrid grids** where a
1818
selected region of a coarse grid is replaced by a refined (subdivided)
19-
sub-grid. The two grids are merged into a single grid and connected
19+
sub-grid. The two grids are merged into a single grid and connected
2020
through Non-Neighbour Connections (NNCs).
2121

2222
The typical workflow is:
2323

24-
1. Define a coarse grid and a region property that marks which cells to
25-
refine.
26-
2. Call :func:`~fmu.tools.nestedhybridgrid.create_nested_hybrid_grid` to
24+
1. Define a coarse grid and a region property that marks cells to
25+
refine with value 1.
26+
2. Use the :class:`~fmu.tools.nestedhybridgrid.NestedHybridGrid` to
2727
produce the merged grid and an NNC table. You may need to export the NNC file to csv
2828
at this stage.
2929
3. Do rescaling from the original gridmodel (e.g. a finer geogrid) to the merged grid,
@@ -39,33 +39,22 @@ The example here runs within RMS, but similar workflows can be created for file
3939

4040
.. code-block:: python
4141
42-
import xtgeo
43-
from fmu.tools.nestedhybridgrid import (
44-
create_nested_hybrid_grid,
45-
)
42+
from fmu.tools.nestedhybridgrid import NestedHybridGrid
4643
47-
# Load grid and region property
48-
grid = xtgeo.grid_from_roxar(project, "Simgrid")
49-
region = xtgeo.gridproperty_from_roxar(project, "Simgrid", "REGION")
50-
51-
# Optionally load any other parameter you wish to preserve on grid
52-
#zone = xtgeo.gridproperty_from_roxar(project, "Simgrid", "Zone")
53-
#grid.append_prop(zone)
54-
55-
# Create nested hybrid grid (e.g. refine region 2 by 2×2×1)
56-
merged, nnc_table = create_nested_hybrid_grid(
57-
grid, region, target_region_id=2, refinement=(2, 2, 1)
44+
# Create nested hybrid grid (refine region 1 by 2×2×1)
45+
nhg = NestedHybridGrid.from_rms(
46+
project,
47+
grid_name="Simgrid",
48+
region_name="Refinement_region",
49+
refinement=(2, 2, 1),
50+
properties=["Zone"], # Optional list of properties to transfer to the output grid
5851
)
5952
60-
# store merged grid in RMS (or file)
61-
merged.to_roxar(project, "NestedHybrid")
62-
63-
# Optionally extract and store any necessary parameters from grid
64-
region2 = merged.get_prop_by_name("REGION")
65-
region2.to_roxar(project, "NestedHybrid", region2.name)
53+
# store nested grid with properties in RMS
54+
nhg.to_rms(project, "NestedHybrid")
6655
6756
# write the NNC pandas to disk; this will be applied for computing NNC's in the next script
68-
nnc_table.to_csv("path_to_some_csv_file.csv", index=False)
57+
nhg.nnc_table.to_csv("path_to_some_csv_file.csv", index=False)
6958
7059
7160
The next step is to do a rescaling from the original geogrid to the merged grid
@@ -116,8 +105,10 @@ Concepts
116105
NNC table
117106
^^^^^^^^^
118107

119-
The NNC table is a :class:`~pandas.DataFrame` returned by
120-
``create_nested_hybrid_grid`` with columns:
108+
The NNC table captures which coarse (mother) cells connect to which refined cells — information that
109+
xtgeo needs to compute transmissibilities across the refinement boundary. It is accessed via the property
110+
``nnc_table`` on the :class:`~fmu.tools.nestedhybridgrid.NestedHybridGrid` instance and is of type
111+
:class:`~pandas.DataFrame` with columns:
121112

122113
.. list-table::
123114
:header-rows: 1

src/fmu/tools/nestedhybridgrid/nestedhybrid.py

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
import logging
2020
import warnings
21-
from typing import TYPE_CHECKING, Literal, Self, TypeAlias
21+
from typing import TYPE_CHECKING, Any, Literal, Self, TypeAlias
2222

2323
import numpy as np
2424
import pandas as pd
@@ -324,6 +324,33 @@ def __init__(
324324
self._layer_map_coarse = self._generate_layer_map_coarse()
325325
self._layer_map_refined = self._generate_layer_map_refined()
326326

327+
@classmethod
328+
def from_rms(
329+
cls,
330+
project: Any,
331+
grid_name: str,
332+
region_name: str,
333+
refinement: tuple[int, int, int],
334+
properties: list[str] | None = None,
335+
) -> Self:
336+
"""Create a NestedHybridGrid instance from an RMS project."""
337+
338+
coarse_grid = xtgeo.grid_from_roxar(project, grid_name)
339+
region = xtgeo.gridproperty_from_roxar(project, grid_name, region_name)
340+
341+
for propname in properties or []:
342+
prop = xtgeo.gridproperty_from_roxar(project, grid_name, propname)
343+
coarse_grid.append_prop(prop)
344+
345+
return cls(coarse_grid, region, refinement)
346+
347+
def to_rms(self, project: Any, grid_name: str) -> None:
348+
"""Write the nested hybrid grid and its properties to an RMS project."""
349+
self.grid.to_roxar(project, grid_name)
350+
351+
for prop in self.properties:
352+
prop.to_roxar(project, grid_name, prop.name)
353+
327354
@staticmethod
328355
def _validate_inputs(
329356
coarse_grid: xtgeo.Grid,
@@ -351,11 +378,11 @@ def _validate_inputs(
351378

352379
def _build_nested_hybrid_grid(self) -> xtgeo.Grid:
353380
"""Build the nested hybrid grid."""
354-
355381
coarse_grid = self._original_grid.copy()
356-
coarse_grid.append_prop(self._original_region)
357382

358383
region_name = self._original_region.name
384+
if region_name not in coarse_grid.propnames:
385+
coarse_grid.append_prop(self._original_region)
359386

360387
# Create the refined grid, i.e. crop and refine.
361388
refined_grid = _crop_for_region(coarse_grid, self._refined_bbox)

0 commit comments

Comments
 (0)