pycopm.utils.coarsening module

Coarsen corner-point grids and aggregate reservoir properties.

The module supports deck-based coarsening and the TOML workflows used to generate reduced Norne and Drogon models.

class pycopm.utils.coarsening.CoarseningMaps(x: NDArray, y: NDArray, z: NDArray, cell_groups: NDArray, coarsened_axes: str, matrix_mask: NDArray, vertical_transfer_enabled: bool, reference_to_coarse: list[int] = <factory>, nnc_text: str = 'NNC\n', coarse_tranx: NDArray = <factory>, coarse_trany: NDArray = <factory>, dual_tranx: NDArray = <factory>, dual_trany: NDArray = <factory>, dual_defaults: dict[str, float]=<factory>)

Bases: object

Store mappings and intermediate values used during coarsening.

cell_groups: NDArray

One-based coarse-cell identifier for each original cell, flattened in (z, y, x) order.

coarse_tranx: NDArray

Horizontal x-direction transmissibilities for the matrix or single-porosity coarse grid.

coarse_trany: NDArray

Horizontal y-direction transmissibilities for the matrix or single-porosity coarse grid.

coarsened_axes: str

Concatenated names of the coarsened axes, for example "xz".

dual_defaults: dict[str, float]

Default property values inserted into separator rows of the extended dual-porosity grid.

dual_tranx: NDArray

Horizontal x-direction transmissibilities for the fracture continuum of a dual-porosity grid.

dual_trany: NDArray

Horizontal y-direction transmissibilities for the fracture continuum of a dual-porosity grid.

matrix_mask: NDArray

Per-cell mask separating matrix cells (one) from fracture or non-net cells (zero) in dual-porosity models.

nnc_text: str

NNC include-file content accumulated while mapping non-neighbouring and matrix-fracture connections.

reference_to_coarse: list[int]

Coarse-cell identifier for each reference-grid cell, populated while properties are coarsened.

vertical_transfer_enabled: bool

Whether vertical matrix-fracture transfer connections are retained.

x: NDArray

Axis array marking boundaries removed by coarsening in the x direction. Values greater than one identify intervals merged with the preceding interval.

y: NDArray

Axis array marking boundaries removed by coarsening in the y direction. Values greater than one identify intervals merged with the preceding interval.

z: NDArray

Axis array marking boundaries removed by coarsening in the z direction. Values greater than one identify intervals merged with the preceding interval.

pycopm.utils.coarsening._collect_removed_zcorn_indices(dck: ConfigViaDeck, coa_z: NDArray, removal_indices: list[int]) list[int]

Add the ZCORN indices removed by vertical coarsening.

pycopm.utils.coarsening._compact_permeability_properties(dck: ConfigViaDeck, permx: NDArray, permy: NDArray, permz: NDArray, modified_deck: list[str]) None

Use COPY and MULTIPLY if PERMY and PERMZ can be generated from PERMX.

pycopm.utils.coarsening._find_active_neighbors(dck: ConfigViaDeck, neighbor_indices: list[int], cluster_id: int, distance: int, offset: int, ijk: list) list[int]

Find active neighbouring cells for pore-volume redistribution.

pycopm.utils.coarsening._find_include_statement(modified_deck: list[str], include_line: str) tuple[int, int]

Return the list interval containing an INCLUDE statement.

pycopm.utils.coarsening._global_index_to_ijk(dck: ConfigViaDeck, global_index: int) tuple[int, int, int]

Return the i, j, and k indices from a zero-based global cell index.

pycopm.utils.coarsening._group_maximum_zero_based(values: NDArray, groups: NDArray, number_groups: int) NDArray
pycopm.utils.coarsening._group_minimum_zero_based(values: NDArray, groups: NDArray, number_groups: int) NDArray
pycopm.utils.coarsening._group_sum_zero_based(values: NDArray, groups: NDArray, number_groups: int) NDArray
pycopm.utils.coarsening._grouped_count(values: NDArray, groups: NDArray, size: int | None = None) NDArray

Return the number of non-NaN values for each one-based group.

pycopm.utils.coarsening._grouped_first(values: NDArray, groups: NDArray, size: int | None = None) NDArray

Return the first non-NaN value for each one-based group.

pycopm.utils.coarsening._grouped_last(values: NDArray, groups: NDArray, size: int | None = None) NDArray

Return the last non-NaN value for each one-based group.

pycopm.utils.coarsening._grouped_max(values: NDArray, groups: NDArray, size: int | None = None) NDArray

Return the maximum value for each one-based group, ignoring NaNs.

pycopm.utils.coarsening._grouped_mean(values: NDArray, groups: NDArray, size: int | None = None) NDArray

Return the mean value for each one-based group, ignoring NaNs.

pycopm.utils.coarsening._grouped_min(values: NDArray, groups: NDArray, size: int | None = None) NDArray

Return the minimum value for each one-based group, ignoring NaNs.

pycopm.utils.coarsening._grouped_mode(values: NDArray, group_codes: NDArray, number_groups: int) NDArray

Return the smallest mode for each zero-based group, ignoring NaNs.

pycopm.utils.coarsening._grouped_sum(values: NDArray, groups: NDArray, size: int | None = None) NDArray

Return the sum of values for each one-based group.

pycopm.utils.coarsening._interleave_dual_property(property_values: NDArray, dual_values: NDArray, nx: int, nz: int, default_value: float = 0) NDArray

Interleave property and dual-property layers with separator rows.

pycopm.utils.coarsening._read_satnum(cfg: ConfigViaTOML, actnum: NDArray, nxyz: int, satnum_opm: NDArray) NDArray

Read or generate fine-grid SATNUM values.

Parameters:
  • cfg – TOML configuration controlling the SATNUM source.

  • actnum – Fine-grid active-cell mask.

  • nxyz – Number of fine-grid cells.

  • satnum_opm – SATNUM values read from the reference INIT file.

Returns:

SATNUM value for every fine-grid cell.

Return type:

NDArray

pycopm.utils.coarsening.build_dual_porosity_grid(dck: ConfigViaDeck, coarsening: CoarseningMaps, cr: NDArray, zc: NDArray) tuple[NDArray, NDArray]

Extend a coarsened grid with a second porosity continuum.

The matrix and fracture grids are separated in the j direction, and their connections are added to coarsening.nnc_text.

Parameters:
  • dck – Deck configuration for the coarsened model.

  • coarsening – Coarsening data containing continuum masks and transmissibilities.

  • cr – Coarsened COORD and ZCORN arrays.

  • zc – Coarsened COORD and ZCORN arrays.

Returns:

Extended dual-porosity grid arrays.

Return type:

coord, zcorn

pycopm.utils.coarsening.coarsen_and_write_properties(cfg: ConfigViaTOML, coa_map: NDArray) int

Aggregate and write properties for a TOML-generated model.

Parameters:
  • cfg – TOML configuration and reference-case settings.

  • coa_map – One-based fine-to-coarse cell mapping.

Returns:

Highest generated SATNUM value, used as the number of saturation tables.

Return type:

int

pycopm.utils.coarsening.coarsen_corner_point_grid(dck: ConfigViaDeck, coarsening: CoarseningMaps) tuple[NDArray, NDArray]

Remove selected pillars and ZCORN surfaces from the grid.

Parameters:
  • dck – Deck configuration containing the original corner-point grid.

  • coarsening – Axis mappings defining the removed rows, columns, and layers.

Returns:

Coarsened arrays when dual porosity is enabled; otherwise empty arrays.

Return type:

coord, zcorn

pycopm.utils.coarsening.coarsen_properties(dck: ConfigViaDeck, coarsening: CoarseningMaps, modified_deck: list[str], wellcind: list[int]) tuple[NDArray, NDArray, NDArray]

Aggregate reservoir properties onto the coarsened grid.

Continuous properties use their configured or property-specific aggregation; discrete properties use min, max, or mode. The function writes property include files and updates output pore volume and active cells.

Parameters:
  • dck – Deck configuration and source INIT or restart properties.

  • coarsening – Cell groups and masks created by create_coarsening_maps().

  • modified_deck – Deck lines updated with generated property includes.

  • wellcind – Coarse-cell indices containing well completions.

Returns:

Activity summaries and the mask used to remove depth-jump cells.

Return type:

cluster_minimum, cluster_maximum, removal_mask

pycopm.utils.coarsening.create_coarsening_map(cfg: ConfigViaTOML) NDArray

Map each fine-grid cell to a one-based coarse-cell identifier.

The output dimensions and original-to-output axis mappings in cfg are also updated.

Parameters:

cfg – TOML configuration containing the axis coarsening arrays.

Returns:

One-based coarse-cell identifier for every fine-grid cell.

Return type:

NDArray

pycopm.utils.coarsening.create_coarsening_maps(dck: ConfigViaDeck, cmdargs) CoarseningMaps

Create axis mappings and assign original cells to coarse cells.

Parameters:
  • dck – Deck configuration whose output dimensions are updated.

  • cmdargs – Command arguments containing coarsening, x_coarsening, y_coarsening, and z_coarsening.

Returns:

Axis mappings, cell groups, and dual-porosity masks.

Return type:

CoarseningMaps

pycopm.utils.coarsening.map_nnc_transmissibilities(dck: ConfigViaDeck, coarsening: CoarseningMaps) None

Map original non-neighbouring transmissibilities to the coarse grid.

Connections that become Cartesian neighbours are accumulated in TRANX or TRANY; remaining connections are written as NNC records.

Parameters:
  • dck – Deck configuration and source NNC data.

  • coarsening – Coarse mapping updated with transmissibilities and NNC text.

pycopm.utils.coarsening.redistribute_removed_pore_volume(dck: ConfigViaDeck, con: NDArray, cluster_minimum: NDArray, cluster_maximum: NDArray, removal_mask: NDArray) None

Redistribute pore volume from removed coarse cells.

Pore volume is divided among the nearest active neighbours without changing the total pore volume.

Parameters:
  • dck – Deck configuration whose output_porv is updated.

  • con – One-based coarse-cell identifier for each original cell.

  • cluster_minimum – Aggregated activity values used to identify changed clusters.

  • cluster_maximum – Aggregated activity values used to identify changed clusters.

  • removal_mask – Mask identifying retained coarse cells.