Nested Hybrid Grids
Overview
The nestedhybridgrid module creates nested hybrid grids where a
selected region of a coarse grid is replaced by a refined (subdivided)
sub-grid. The two grids are merged into a single grid and connected
through Non-Neighbour Connections (NNCs).
The typical workflow is:
Define a coarse grid and a region property that marks which cells to refine.
Call
create_nested_hybrid_grid()to produce the merged grid and an NNC table. You may need to export the NNC file to csv at this stage.Do rescaling from the original gridmodel (e.g. a finer geogrid) to the merged grid, e.g. by using software like RMS.
Make another script, that computes transmissibilities with
xtgeo.Grid.get_transmissibilities()passing the NNC table.Export the NNC transmissibilities for the flow simulator.
Quick-start example
The example here runs within RMS, but similar workflows can be created for file i/o.
import xtgeo
from fmu.tools.nestedhybridgrid import (
create_nested_hybrid_grid,
)
# Load grid and region property
grid = xtgeo.grid_from_roxar(project, "Simgrid")
region = xtgeo.gridproperty_from_roxar(project, "Simgrid", "REGION")
# Create nested hybrid grid (e.g. refine region 2 by 2×2×1)
merged, nnc_table = create_nested_hybrid_grid(
grid, region, target_region_id=2, refinement=(2, 2, 1)
)
# store merged grid in RMS (or file)
merged.to_roxar(project, "NestedHybrid")
merged.get_prop_by_name("NEST_ID")
nest_id.to_roxar(project, "NestedHybrid", nest_id.name)
# write the NNC pandas to disk; this will be applied for computing NNC's in the next script
nnc_table.write_csv("path_to_some_csv_file.csv", index=False)
The next step is to do a rescaling from the original geogrid to the merged grid using e.g. the RMS tool.
Further, we need to create NNC transmissibilities and generate file for flow simulator:
import xtgeo
from fmu.tools.nestedhybridgrid import (
nnc_to_flowsimulator_input,
nnc_to_gridproperty,
)
GNAME = "NestedHybrid"
# Load grid and region property which may be stored in RMS
nested = xtgeo.grid_from_roxar(project, GNAME)
region = nested.get_prop_by_name("NEST_ID") # if needed for QC
# load the NNC table
nnc_table = pd.read_csv("path_to_some_nnc_file.csv")
# Load rescaled property input for transmissibilities and compute
permx = xtgeo.gridproperty_from_roxar(project, GNAME,"PERMX")
permy = xtgeo.gridproperty_from_roxar(project, GNAME,"PERMY")
permz = xtgeo.gridproperty_from_roxar(project, GNAME,"PERMZ")
ntg = xtgeo.gridproperty_from_roxar(project, GNAME,"NTG") # defaults to 1 if no NTG
# compute transmissibilities. Note that flow simulators do this for the normal cells/faults
# so strictly speaking, only nnc_hybrid is needed here.
tranx, trany, tranz, nnc_fault, nnc_hybrid, rbnd = merged.get_transmissibilities(
permx, permy, permz, ntg, nnc_table=nnc_table
)
# Export NNC keyword for Eclipse / OPM Flow
nnc_to_flowsimulator_input(nnc_hybrid, "some_path/NNC_HYBRID.INC")
# Or map NNCs onto grid properties for visualisation
tx_nnc, ty_nnc, tz_nnc = nnc_to_gridproperty(merged, nnc_hybrid)
tx_nnc.to_roxar(project, GNAME, "TRANX_NNC_QC") # etc
Concepts
NNC table
The NNC table is a DataFrame returned by
create_nested_hybrid_grid with columns:
Column |
Description |
|---|---|
|
Mother cell indices (1-based) |
|
Refined cell indices (1-based) |
|
Face direction from the mother cell toward the refined cell
( |
This table is passed to xtgeo.Grid.get_transmissibilities() via the
nnc_table parameter. The transmissibility computation uses geometric
face-overlap calculations (Sutherland–Hodgman algorithm) and two-point flux
approximation (TPFA).
NEST_ID property
The merged grid carries a discrete property called NEST_ID:
0 — inactive hole cells (carved out to make room for the refined region)
1 — mother (coarse) cells
2 — refined cells
Eclipse / OPM Flow export
nnc_to_flowsimulator_input() writes the
NNC keyword in Eclipse format. The output file can be included in the
simulator deck:
INCLUDE
'NNC_HYBRID.INC' /