Files
ResInsight/ThirdParty/Ert/python/ecl/grid/faults/layer.py
T
Magne Sjaastad 04091ad77d #4266 Update libecl
Use commit 0e1e780fd6f18ce93119061e36a4fca9711bc020

Excluded multibuild folder, as this caused git issues
2019-05-09 08:40:32 +02:00

276 lines
9.2 KiB
Python

# Copyright (C) 2014 Equinor ASA, Norway.
#
# The file 'layer.py' is part of ERT - Ensemble based Reservoir Tool.
#
# ERT is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# ERT is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.
#
# See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
# for more details.
import ctypes
from ecl.grid import EclGrid
from cwrap import BaseCClass
from ecl.util.util import monkey_the_camel
from ecl.util.util import IntVector
from ecl import EclPrototype
class Layer(BaseCClass):
TYPE_NAME = "layer"
_alloc = EclPrototype("void* layer_alloc(int, int)", bind=False)
_copy = EclPrototype("void layer_memcpy(layer, layer)")
_free = EclPrototype("void layer_free(layer)")
_get_nx = EclPrototype("int layer_get_nx(layer)")
_get_ny = EclPrototype("int layer_get_ny(layer)")
_set_cell = EclPrototype("void layer_iset_cell_value(layer, int, int, int)")
_get_cell = EclPrototype("int layer_iget_cell_value(layer, int, int)")
_get_bottom_barrier = EclPrototype("bool layer_iget_bottom_barrier(layer, int, int)")
_get_left_barrier = EclPrototype("bool layer_iget_left_barrier(layer, int, int)")
_cell_contact = EclPrototype("bool layer_cell_contact(layer, int, int, int, int)")
_add_barrier = EclPrototype("void layer_add_barrier(layer, int, int)")
_add_ijbarrier = EclPrototype("void layer_add_ijbarrier(layer, int, int, int, int)")
_add_interp_barrier = EclPrototype("void layer_add_interp_barrier(layer, int, int)")
_clear_cells = EclPrototype("void layer_clear_cells(layer)")
_assign = EclPrototype("void layer_assign(layer, int)")
_cell_sum = EclPrototype("int layer_get_cell_sum(layer)")
_update_connected = EclPrototype("void layer_update_connected_cells(layer,int,int,int,int)")
_cells_equal = EclPrototype("void layer_cells_equal(layer, int,int_vector,int_vector)")
_count_equal = EclPrototype("int layer_count_equal(layer, int)")
_active_cell = EclPrototype("bool layer_iget_active(layer, int,int)")
_update_active = EclPrototype("bool layer_update_active(layer, ecl_grid, int)")
def __init__(self, nx, ny):
c_ptr = self._alloc(nx, ny)
if c_ptr:
super(Layer, self).__init__(c_ptr)
else:
raise ValueError("Invalid input - no Layer object created")
@classmethod
def copy(cls, src):
layer = Layer(src.getNX(), src.getNY())
layer._copy(layer, src)
return layer
def _assert_ij(self, i,j):
if i < 0 or i >= self.getNX():
raise ValueError("Invalid layer i:%d" % i)
if j < 0 or j >= self.getNY():
raise ValueError("Invalid layer j:%d" % j)
def __unpack_index(self, index):
try:
(i,j) = index
except TypeError:
raise ValueError("Index:%s is invalid - must have two integers" % str(index))
self._assert_ij(i,j)
return (i,j)
def __setitem__(self, index, value):
(i,j) = self.__unpack_index(index)
self._set_cell(i, j, value)
def active_cell(self, i,j):
self._assert_ij(i,j)
return self._active_cell(i, j)
def update_active(self, grid, k):
if grid.getNX() != self.getNX():
raise ValueError("NX dimension mismatch. Grid:%d layer:%d" % (grid.getNX(), self.getNX()))
if grid.getNY() != self.getNY():
raise ValueError("NY dimension mismatch. Grid:%d layer:%d" % (grid.getNY(), self.getNY()))
if k >= grid.getNZ():
raise ValueError("K value invalid: Grid range [0,%d)" % grid.getNZ())
self._update_active(grid, k)
def __getitem__(self, index):
(i,j) = self.__unpack_index(index)
return self._get_cell(i, j)
def bottom_barrier(self, i,j):
self._assert_ij(i,j)
return self._get_bottom_barrier(i, j)
def left_barrier(self, i,j):
self._assert_ij(i,j)
return self._get_left_barrier(i, j)
def get_nx(self):
return self._get_nx()
@property
def nx(self):
return self._get_nx()
def get_ny(self):
return self._get_ny()
@property
def ny(self):
return self._get_ny()
def free(self):
self._free()
def cell_contact(self, p1, p2):
i1,j1 = p1
i2,j2 = p2
if not 0 <= i1 < self.getNX():
raise IndexError("Invalid i1:%d" % i1)
if not 0 <= i2 < self.getNX():
raise IndexError("Invalid i2:%d" % i2)
if not 0 <= j1 < self.getNY():
raise IndexError("Invalid i1:%d" % j1)
if not 0 <= j2 < self.getNY():
raise IndexError("Invalid i2:%d" % j2)
return self._cell_contact(i1, j1, i2, j2)
def add_interp_barrier(self, c1, c2):
self._add_interp_barrier(c1, c2)
def add_polyline_barrier(self, polyline, grid, k):
if len(polyline) > 1:
for i in range(len(polyline) - 1):
x1,y1 = polyline[i]
x2,y2 = polyline[i + 1]
c1 = grid.findCellCornerXY(x1, y1, k)
c2 = grid.findCellCornerXY(x2, y2, k)
self.addInterpBarrier(c1, c2)
def add_fault_barrier(self, fault, K, link_segments=True):
fault_layer = fault[K]
num_lines = len(fault_layer)
for index, fault_line in enumerate(fault_layer):
for segment in fault_line:
c1, c2 = segment.getCorners()
self._add_barrier(c1, c2)
if index < num_lines - 1:
next_line = fault_layer[index + 1]
next_segment = next_line[0]
next_c1, next_c2 = next_segment.getCorners()
if link_segments:
self.addInterpBarrier(c2, next_c1)
def add_ij_barrier(self, ij_list):
if len(ij_list) < 2:
raise ValueError("Must have at least two (i,j) points")
nx = self.getNX()
ny = self.getNY()
p1 = ij_list[0]
i1,j1 = p1
for p2 in ij_list[1:]:
i2,j2 = p2
if i1 == i2 or j1 == j2:
if not 0 <= i2 <= nx:
raise ValueError("i value:%d invalid. Valid range: [0,%d] " % (i1, i2))
if not 0 <= j2 <= ny:
raise ValueError("i value:%d invalid. Valid range: [0,%d] " % (j1, j2))
self._add_ijbarrier(i1, j1, i2, j2)
p1 = p2
i1,j1 = p1
else:
raise ValueError("Must have i1 == i2 or j1 == j2")
def cell_sum(self):
return self._cell_sum()
def clear_cells(self):
"""
Will reset all cell and edge values to zero. Barriers will be left
unchanged.
"""
self._clear_cells()
def assign(self, value):
"""
Will set the cell value to @value in all cells. Barriers will not be changed
"""
self._assign(value)
def update_connected(self, ij, new_value, org_value=None):
"""
Will update cell value of all cells in contact with cell ij to the
value @new_value. If org_value is not supplied, the current
value in cell ij is used.
"""
if org_value is None:
org_value = self[ij]
if self[ij] == org_value:
self._update_connected(ij[0], ij[1], org_value, new_value)
else:
raise ValueError("Cell %s is not equal to %d \n" % (ij, org_value))
def cells_equal(self, value):
"""
Will return a list [(i1,j1),(i2,j2), ...(in,jn)] of all cells with value @value.
"""
i_list = IntVector()
j_list = IntVector()
self._cells_equal(value, i_list, j_list)
ij_list= []
for (i,j) in zip(i_list, j_list):
ij_list.append((i,j))
return ij_list
def count_equal(self, value):
return self._count_equal(value)
monkey_the_camel(Layer, 'activeCell', Layer.active_cell)
monkey_the_camel(Layer, 'updateActive', Layer.update_active)
monkey_the_camel(Layer, 'bottomBarrier', Layer.bottom_barrier)
monkey_the_camel(Layer, 'leftBarrier', Layer.left_barrier)
monkey_the_camel(Layer, 'getNX', Layer.get_nx)
monkey_the_camel(Layer, 'getNY', Layer.get_ny)
monkey_the_camel(Layer, 'cellContact', Layer.cell_contact)
monkey_the_camel(Layer, 'addInterpBarrier', Layer.add_interp_barrier)
monkey_the_camel(Layer, 'addPolylineBarrier', Layer.add_polyline_barrier)
monkey_the_camel(Layer, 'addFaultBarrier', Layer.add_fault_barrier)
monkey_the_camel(Layer, 'addIJBarrier', Layer.add_ij_barrier)
monkey_the_camel(Layer, 'cellSum', Layer.cell_sum)
monkey_the_camel(Layer, 'clearCells', Layer.clear_cells)
monkey_the_camel(Layer, 'updateConnected', Layer.update_connected)
monkey_the_camel(Layer, 'cellsEqual', Layer.cells_equal)
monkey_the_camel(Layer, 'countEqual', Layer.count_equal)