Пример #1
0
def _rkwxvec(gfile, kws, name, swap, strict=True):
    """Local function for returning swig pointers to C arrays when reading files.

    If strict is True, a ValueError will be raised if keyword is not
    found. If strict is False, None will be returned
    """

    kwtypedict = {
        "int": 1,
        "float": 2,
        "double": 3,
        "char": 4,
        "bool": 5,
        "byte": 6
    }

    dtype = 0
    reclen = 0
    bytepos = 1
    for items in kws:
        if name in items[0]:
            dtype = kwtypedict.get(items[1])
            reclen = items[2]
            bytepos = items[3]
            break

    if dtype == 0:
        if strict:
            raise ValueError("Cannot find property <{}> in file".format(name))

        return None

    if reclen <= 1:
        raise SystemError("Stuff is rotten here...")

    xvec = None
    cfhandle = gfile.get_cfhandle()
    logger.info("Reading %s from file...", name)

    if dtype == 1:
        xvec = _cxtgeo.new_intarray(reclen)
        _cxtgeo.grd3d_imp_roffbin_ivec(cfhandle, swap, bytepos, xvec, reclen)

    elif dtype == 2:
        xvec = _cxtgeo.new_floatarray(reclen)
        _cxtgeo.grd3d_imp_roffbin_fvec(cfhandle, swap, bytepos, xvec, reclen)

    elif dtype >= 4:
        xvec = _cxtgeo.new_intarray(reclen)  # convert char/byte/bool to int
        _cxtgeo.grd3d_imp_roffbin_bvec(cfhandle, swap, bytepos, xvec, reclen)

    else:
        gfile.cfclose()
        raise ValueError("Unhandled dtype: {}".format(dtype))

    logger.info("Reading %s from file done", name)

    gfile.cfclose()
    return xvec
Пример #2
0
def _export_roff_discrete(self,
                          pfile,
                          name,
                          append=False,
                          last=True,
                          binary=True):

    carray = _gridprop_lowlevel.update_carray(self, undef=-999)

    ptr_idum = _cxtgeo.new_intpointer()
    ptr_ddum = _cxtgeo.new_doublepointer()

    # codes:
    ptr_codes = _cxtgeo.new_intarray(256)
    ncodes = self.ncodes
    codenames = ""
    logger.info("Keys: %s", self.codes.keys())
    for inum, ckey in enumerate(sorted(self.codes.keys())):
        if ckey is not None:
            codenames += str(self.codes[ckey])
            codenames += "|"
            _cxtgeo.intarray_setitem(ptr_codes, inum, int(ckey))
        else:
            logger.warning("For some odd reason, None is a key. Check!")

    mode = 0
    if not binary:
        mode = 1

    if not append:
        _cxtgeo.grd3d_export_roff_pstart(mode, self._ncol, self._nrow,
                                         self._nlay, pfile, XTGDEBUG)

    nsub = 0
    isub_to_export = 0
    _cxtgeo.grd3d_export_roff_prop(
        mode,
        self._ncol,
        self._nrow,
        self._nlay,
        nsub,
        isub_to_export,
        ptr_idum,
        name,
        "int",
        carray,
        ptr_ddum,
        ncodes,
        codenames,
        ptr_codes,
        pfile,
        XTGDEBUG,
    )

    if last:
        _cxtgeo.grd3d_export_roff_end(mode, pfile, XTGDEBUG)

    _gridprop_lowlevel.delete_carray(self, carray)
Пример #3
0
def scan_dates(pfile, maxdates=1000, dataframe=False):
    """Quick scan dates in a simulation restart file.

    Cf. grid_properties.py description
    """

    seq = _cxtgeo.new_intarray(maxdates)
    day = _cxtgeo.new_intarray(maxdates)
    mon = _cxtgeo.new_intarray(maxdates)
    yer = _cxtgeo.new_intarray(maxdates)

    local_fhandle = False
    fhandle = pfile
    if isinstance(pfile, str):
        pfile = xtgeo._XTGeoCFile(pfile)
        fhandle = pfile.fhandle
        local_fhandle = True

    nstat = _cxtgeo.grd3d_ecl_tsteps(fhandle, seq, day, mon, yer, maxdates,
                                     XTGDEBUG)

    if local_fhandle:
        pfile.close(cond=local_fhandle)

    sq = []
    da = []
    for i in range(nstat):
        sq.append(_cxtgeo.intarray_getitem(seq, i))
        dday = _cxtgeo.intarray_getitem(day, i)
        dmon = _cxtgeo.intarray_getitem(mon, i)
        dyer = _cxtgeo.intarray_getitem(yer, i)
        date = "{0:4}{1:02}{2:02}".format(dyer, dmon, dday)
        da.append(int(date))

    for item in [seq, day, mon, yer]:
        _cxtgeo.delete_intarray(item)

    zdates = list(zip(sq, da))  # list for PY3

    if dataframe:
        cols = ["SEQNUM", "DATE"]
        df = pd.DataFrame.from_records(zdates, columns=cols)
        return df

    return zdates
Пример #4
0
def update_carray(self, undef=None, discrete=None, dtype=None, order="F"):
    """Copy (update) values from numpy to SWIG, 1D array, returns a pointer
    to SWIG C array. If discrete is defined as True or False, force
    the SWIG array to be of that kind.

    Note that dtype will "override" current datatype if set. The resulting
    carray will be in Fortran order, unless order is specified as 'C'
    """

    dstatus = self._isdiscrete
    if discrete is not None:
        dstatus = bool(discrete)

    if undef is None:
        undef = xtgeo.UNDEF
        if dstatus:
            undef = xtgeo.UNDEF_INT

    logger.debug("Entering conversion from numpy to C array ...")

    values = self._values.copy()

    if not dtype:
        if dstatus:
            values = values.astype(np.int32)
        else:
            values = values.astype(np.float64)
    else:
        values = values.astype(dtype)

    values = ma.filled(values, undef)

    if order == "F":
        values = np.asfortranarray(values)
        values1d = np.ravel(values, order="K")

    if values1d.dtype == "float64" and dstatus and not dtype:
        values1d = values1d.astype("int32")
        logger.debug("Casting has been done")

    if values1d.dtype == "float64":
        logger.debug("Convert to carray (double)")
        carray = _cxtgeo.new_doublearray(self.ntotal)
        _cxtgeo.swig_numpy_to_carr_1d(values1d, carray)
    elif values1d.dtype == "float32":
        logger.debug("Convert to carray (float)")
        carray = _cxtgeo.new_floatarray(self.ntotal)
        _cxtgeo.swig_numpy_to_carr_f1d(values1d, carray)
    elif values1d.dtype == "int32":
        logger.debug("Convert to carray (int32)")
        carray = _cxtgeo.new_intarray(self.ntotal)
        _cxtgeo.swig_numpy_to_carr_i1d(values1d, carray)
    else:
        raise RuntimeError(
            "Unsupported dtype, probable bug in {}".format(__name__))
    return carray
Пример #5
0
def _export_segy_xtgeo(self, sfile):
    """Export SEGY via XTGeo internal C routine."""

    values1d = self.values.reshape(-1)

    ilinesp = _cxtgeo.new_intarray(len(self._ilines))
    xlinesp = _cxtgeo.new_intarray(len(self._xlines))
    tracidp = _cxtgeo.new_intarray(self.ncol * self.nrow)

    ilns = self._ilines.astype(np.int32)
    xlns = self._xlines.astype(np.int32)
    trid = self._traceidcodes.flatten().astype(np.int32)

    _cxtgeo.swig_numpy_to_carr_i1d(ilns, ilinesp)
    _cxtgeo.swig_numpy_to_carr_i1d(xlns, xlinesp)
    _cxtgeo.swig_numpy_to_carr_i1d(trid, tracidp)

    status = _cxtgeo.cube_export_segy(
        sfile,
        self.ncol,
        self.nrow,
        self.nlay,
        values1d,
        self.xori,
        self.xinc,
        self.yori,
        self.yinc,
        self.zori,
        self.zinc,
        self.rotation,
        self.yflip,
        1,
        ilinesp,
        xlinesp,
        tracidp,
        0,
    )

    if status != 0:
        raise RuntimeError("Error when exporting to SEGY (xtgeo engine)")

    _cxtgeo.delete_intarray(ilinesp)
    _cxtgeo.delete_intarray(xlinesp)
Пример #6
0
def copy(self):
    """Copy a grid instance (C pointers) and other props.

    Returns:
        A new instance (attached grid properties will also be unique)
    """

    other = self.__class__()

    ntot = self.ncol * self.nrow * self.nlay
    ncoord = (self.ncol + 1) * (self.nrow + 1) * 2 * 3
    nzcorn = self.ncol * self.nrow * (self.nlay + 1) * 4

    new_p_coord_v = _cxtgeo.new_doublearray(ncoord)
    new_p_zcorn_v = _cxtgeo.new_doublearray(nzcorn)
    new_p_actnum_v = _cxtgeo.new_intarray(ntot)

    _cxtgeo.grd3d_copy(
        self.ncol,
        self.nrow,
        self.nlay,
        self._p_coord_v,
        self._p_zcorn_v,
        self._p_actnum_v,
        new_p_coord_v,
        new_p_zcorn_v,
        new_p_actnum_v,
        0,
        XTGDEBUG,
    )

    other._p_coord_v = new_p_coord_v
    other._p_zcorn_v = new_p_zcorn_v
    other._p_actnum_v = new_p_actnum_v

    other._ncol = self.ncol
    other._nrow = self.nrow
    other._nlay = self.nlay

    if isinstance(self.subgrids, dict):
        other.subgrids = deepcopy(self.subgrids)

    # copy attached properties
    if self._props:
        other._props = self._props.copy()
        logger.info("Other vs self props %s vs %s", other._props, self._props)

    if self._filesrc is not None and "(copy)" not in self._filesrc:
        other._filesrc = self._filesrc + " (copy)"
    elif self._filesrc is not None:
        other._filesrc = self._filesrc

    return other
Пример #7
0
def get_adjacent_cells(self, prop, val1, val2, activeonly=True):
    """Get adjacents cells"""

    self._xtgformat1()

    if not isinstance(prop, GridProperty):
        raise ValueError("The argument prop is not a xtgeo.GridPropery")

    if prop.isdiscrete is False:
        raise ValueError("The argument prop is not a discrete property")

    result = GridProperty(
        ncol=self._ncol,
        nrow=self._nrow,
        nlay=self._nlay,
        values=np.zeros(self.ntotal, dtype=np.int32),
        name="ADJ_CELLS",
        discrete=True,
    )

    p_prop1 = _gridprop_lowlevel.update_carray(prop)
    p_prop2 = _cxtgeo.new_intarray(self.ntotal)

    iflag1 = 1
    if activeonly:
        iflag1 = 0

    iflag2 = 1

    _cxtgeo.grd3d_adj_cells(
        self._ncol,
        self._nrow,
        self._nlay,
        self._coordsv,
        self._zcornsv,
        self._actnumsv,
        p_prop1,
        self.ntotal,
        val1,
        val2,
        p_prop2,
        self.ntotal,
        iflag1,
        iflag2,
    )

    _gridprop_lowlevel.update_values_from_carray(result,
                                                 p_prop2,
                                                 np.int32,
                                                 delete=True)
    # return the property object
    return result
Пример #8
0
def _scan_ecl_keywords(pfile, maxkeys=100000, dataframe=False):

    ultramax = int(1000000 / 9)  # cf *swig_bnd_char_1m in cxtgeo.i
    if maxkeys > ultramax:
        raise ValueError(
            "maxkeys value is too large, must be < {}".format(ultramax))

    rectypes = _cxtgeo.new_intarray(maxkeys)
    reclens = _cxtgeo.new_longarray(maxkeys)
    recstarts = _cxtgeo.new_longarray(maxkeys)

    cfhandle = pfile.get_cfhandle()

    nkeys, keywords = _cxtgeo.grd3d_scan_eclbinary(cfhandle, rectypes, reclens,
                                                   recstarts, maxkeys)

    pfile.cfclose()

    keywords = keywords.replace(" ", "")
    keywords = keywords.split("|")

    # record types translation (cf: grd3d_scan_eclbinary.c in cxtgeo)
    rct = {
        "1": "INTE",
        "2": "REAL",
        "3": "DOUB",
        "4": "CHAR",
        "5": "LOGI",
        "6": "MESS",
        "-1": "????",
    }

    rc = []
    rl = []
    rs = []
    for i in range(nkeys):
        rc.append(rct[str(_cxtgeo.intarray_getitem(rectypes, i))])
        rl.append(_cxtgeo.longarray_getitem(reclens, i))
        rs.append(_cxtgeo.longarray_getitem(recstarts, i))

    _cxtgeo.delete_intarray(rectypes)
    _cxtgeo.delete_longarray(reclens)
    _cxtgeo.delete_longarray(recstarts)

    result = list(zip(keywords, rc, rl, rs))

    if dataframe:
        cols = ["KEYWORD", "TYPE", "NITEMS", "BYTESTART"]
        df = pd.DataFrame.from_records(result, columns=cols)
        return df

    return result
Пример #9
0
    def _convert_np_carr_int(self, np_array):
        """Convert numpy 1D array to C array, assuming int type.

        The numpy is always a double (float64), so need to convert first
        """

        carr = _cxtgeo.new_intarray(self.nrow)

        np_array = np_array.astype(np.int32)

        _cxtgeo.swig_numpy_to_carr_i1d(np_array, carr)

        return carr
Пример #10
0
def convert_np_carr_int(xyz, np_array):
    """Convert numpy 1D array to C array, assuming int type."""

    # The numpy is always a double (float64), so need to convert first
    # xyz is the general object

    carr = _cxtgeo.new_intarray(xyz.nrow)

    np_array = np_array.astype(np.int32)

    _cxtgeo.swig_numpy_to_carr_i1d(np_array, carr)

    return carr
Пример #11
0
def create_box(
    self,
    dimension=(10, 12, 6),
    origin=(10.0, 20.0, 1000.0),
    oricenter=False,
    increment=(100, 150, 5),
    rotation=30.0,
    flip=1,
):
    """Create a shoebox grid from cubi'sh spec"""

    self._ncol, self._nrow, self._nlay = dimension
    ntot = self.ncol * self.nrow * self.nlay
    ncoord = (self.ncol + 1) * (self.nrow + 1) * 2 * 3
    nzcorn = self.ncol * self.nrow * (self.nlay + 1) * 4

    self._p_actnum_v = _cxtgeo.new_intarray(ntot)
    self._p_coord_v = _cxtgeo.new_doublearray(ncoord)
    self._p_zcorn_v = _cxtgeo.new_doublearray(nzcorn)

    option = 0
    if oricenter:
        option = 1

    _cxtgeo.grd3d_from_cube(
        self.ncol,
        self.nrow,
        self.nlay,
        self._p_coord_v,
        self._p_zcorn_v,
        self._p_actnum_v,
        origin[0],
        origin[1],
        origin[2],
        increment[0],
        increment[1],
        increment[2],
        rotation,
        flip,
        option,
        XTGDEBUG,
    )

    self._actnum_indices = None
    self._filesrc = None
    self._props = None
    self._subgrids = None
    self._roxgrid = None
    self._roxindexer = None
    self._tmp = {}
Пример #12
0
def _scan_roff_keywords(fhandle, maxkeys=100000, dataframe=False):

    # In case fhandle is not a file name but a swig pointer to a file handle,
    # the file must not be closed

    ultramax = int(1000000 / 9)  # cf *swig_bnd_char_1m in cxtgeo.i
    if maxkeys > ultramax:
        raise ValueError(
            "maxkeys value is too large, must be < {}".format(ultramax))

    rectypes = _cxtgeo.new_intarray(maxkeys)
    reclens = _cxtgeo.new_longarray(maxkeys)
    recstarts = _cxtgeo.new_longarray(maxkeys)

    nkeys, _tmp1, keywords = _cxtgeo.grd3d_scan_roffbinary(
        fhandle, rectypes, reclens, recstarts, maxkeys)

    keywords = keywords.replace(" ", "")
    keywords = keywords.split("|")

    # record types translation (cf: grd3d_scan_eclbinary.c in cxtgeo)
    rct = {
        "1": "int",
        "2": "float",
        "3": "double",
        "4": "char",
        "5": "bool",
        "6": "byte",
    }

    rc = []
    rl = []
    rs = []
    for i in range(nkeys):
        rc.append(rct[str(_cxtgeo.intarray_getitem(rectypes, i))])
        rl.append(_cxtgeo.longarray_getitem(reclens, i))
        rs.append(_cxtgeo.longarray_getitem(recstarts, i))

    _cxtgeo.delete_intarray(rectypes)
    _cxtgeo.delete_longarray(reclens)
    _cxtgeo.delete_longarray(recstarts)

    result = list(zip(keywords, rc, rl, rs))

    if dataframe:
        cols = ["KEYWORD", "TYPE", "NITEMS", "BYTESTARTDATA"]
        df = pd.DataFrame.from_records(result, columns=cols)
        return df

    return result
Пример #13
0
def test_grd3d_reduce_onelayer():
    with pytest.raises(
            xtgeo.XTGeoCLibError,
            match="IFLAG other than 0 not implemented",
    ):
        _cxtgeo.grd3d_reduce_onelayer(
            0,
            0,
            0,
            np.array([0.0]),
            np.array([1.0]),
            np.array([1], dtype=np.int32),
            np.array([1], dtype=np.int32),
            _cxtgeo.new_intarray(1),
            1,
        )
Пример #14
0
def reduce_to_one_layer(self):
    """Reduce the grid to one single layer.

    This can be useful for algorithms that need to test if a point is within
    the full grid.

    Example::

        >>> from xtgeo.grid3d import Grid
        >>> gf = Grid('gullfaks2.roff')
        >>> gf.nlay
        47
        >>> gf.reduce_to_one_layer()
        >>> gf.nlay
        1

    """

    # need new pointers in C (not for coord)

    ptr_new_num_act = _cxtgeo.new_intpointer()

    nnum = (1 + 1) * 4
    ptr_new_zcorn_v = _cxtgeo.new_doublearray(self.ncol * self.nrow * nnum)

    ptr_new_actnum_v = _cxtgeo.new_intarray(self.ncol * self.nrow * 1)

    _cxtgeo.grd3d_reduce_onelayer(
        self.ncol,
        self.nrow,
        self.nlay,
        self._p_zcorn_v,
        ptr_new_zcorn_v,
        self._p_actnum_v,
        ptr_new_actnum_v,
        ptr_new_num_act,
        0,
        XTGDEBUG,
    )

    self._nlay = 1
    self._p_zcorn_v = ptr_new_zcorn_v
    self._p_actnum_v = ptr_new_actnum_v
    self._props = None
    self._subgrids = None
Пример #15
0
def _export_roff_v1(self, gfile, option):
    """Export grid to ROFF format (binary)"""

    self._xtgformat1()
    gfile = xtgeo._XTGeoFile(gfile, mode="wb")
    gfile.check_folder(raiseerror=OSError)

    logger.debug("Export to ROFF...")

    nsubs = 0
    if self.subgrids is None:
        logger.debug("Create a pointer for subgrd_v ...")
        subgrd_v = _cxtgeo.new_intpointer()
    else:
        nsubs = len(self.subgrids)
        subgrd_v = _cxtgeo.new_intarray(nsubs)
        for inum, (sname, sarray) in enumerate(self.subgrids.items()):
            logger.info("INUM SUBGRID: %s %s", inum, sname)
            _cxtgeo.intarray_setitem(subgrd_v, inum, len(sarray))

    # get the geometrics list to find the xshift, etc
    gx = self.get_geometrics()

    _cxtgeo.grd3d_export_roff_grid(
        option,
        self._ncol,
        self._nrow,
        self._nlay,
        nsubs,
        0,
        gx[3],
        gx[5],
        gx[7],
        self._coordsv,
        self._zcornsv,
        self._actnumsv,
        subgrd_v,
        gfile.name,
    )

    # end tag
    _cxtgeo.grd3d_export_roff_end(option, gfile.name)
Пример #16
0
def export_roff(self, gfile, option):
    """Export grid to ROFF format (binary)"""

    logger.debug("Export to ROFF...")

    nsubs = 0
    if self.subgrids is None:
        logger.debug("Create a pointer for subgrd_v ...")
        subgrd_v = _cxtgeo.new_intpointer()
    else:
        nsubs = len(self.subgrids)
        subgrd_v = _cxtgeo.new_intarray(nsubs)
        for inum, (sname, sarray) in enumerate(self.subgrids.items()):
            logger.info("INUM SUBGRID: %s %s", inum, sname)
            _cxtgeo.intarray_setitem(subgrd_v, inum, len(sarray))

    # get the geometrics list to find the xshift, etc
    gx = self.get_geometrics()

    _cxtgeo.grd3d_export_roff_grid(
        option,
        self._ncol,
        self._nrow,
        self._nlay,
        nsubs,
        0,
        gx[3],
        gx[5],
        gx[7],
        self._p_coord_v,
        self._p_zcorn_v,
        self._p_actnum_v,
        subgrd_v,
        gfile,
        XTGDEBUG,
    )

    # skip parameters for now (cf Perl code)

    # end tag
    _cxtgeo.grd3d_export_roff_end(option, gfile, XTGDEBUG)
Пример #17
0
def import_ecl_bgrdecl(self, gfile):
    """Import binary files with GRDECL layout"""

    local_fhandle = False
    fhandle = gfile
    if isinstance(gfile, str):
        local_fhandle = True
        gfile = xtgeo._XTGeoCFile(gfile)
        fhandle = gfile.fhandle

    # scan file for properties; these have similar binary format as e.g. EGRID
    logger.info("Make kwlist by scanning")
    kwlist = utils.scan_keywords(fhandle,
                                 fformat="xecl",
                                 maxkeys=1000,
                                 dataframe=False,
                                 dates=False)
    bpos = {}
    needkwlist = ["SPECGRID", "COORD", "ZCORN", "ACTNUM"]
    optkwlist = ["MAPAXES"]
    for name in needkwlist + optkwlist:
        bpos[name] = -1  # initially

    for kwitem in kwlist:
        kwname, kwtype, kwlen, kwbyte = kwitem
        if kwname == "SPECGRID":
            # read grid geometry record:
            specgrid = eclbin_record(fhandle, "SPECGRID", kwlen, kwtype,
                                     kwbyte)
            ncol, nrow, nlay = specgrid[0:3].tolist()
            logger.info("%s %s %s", ncol, nrow, nlay)
        elif kwname in needkwlist:
            bpos[kwname] = kwbyte
        elif kwname == "MAPAXES":  # not always present
            bpos[kwname] = kwbyte

    self._ncol = ncol
    self._nrow = nrow
    self._nlay = nlay

    logger.info("Grid dimensions in binary GRDECL file: %s %s %s", ncol, nrow,
                nlay)

    # allocate dimensions:
    ntot = self._ncol * self._nrow * self._nlay
    ncoord = (self._ncol + 1) * (self._nrow + 1) * 2 * 3
    nzcorn = self._ncol * self._nrow * (self._nlay + 1) * 4

    self._p_coord_v = _cxtgeo.new_doublearray(ncoord)
    self._p_zcorn_v = _cxtgeo.new_doublearray(nzcorn)
    self._p_actnum_v = _cxtgeo.new_intarray(ntot)
    p_nact = _cxtgeo.new_longpointer()

    ier = _cxtgeo.grd3d_imp_ecl_egrid(
        fhandle,
        self._ncol,
        self._nrow,
        self._nlay,
        bpos["MAPAXES"],
        bpos["COORD"],
        bpos["ZCORN"],
        bpos["ACTNUM"],
        self._p_coord_v,
        self._p_zcorn_v,
        self._p_actnum_v,
        p_nact,
        0,
    )

    if ier == -1:
        raise RuntimeError("Error code -1 from _cxtgeo.grd3d_imp_ecl_egrid")

    self._nactive = _cxtgeo.longpointer_value(p_nact)

    if local_fhandle:
        gfile.close(cond=local_fhandle)
Пример #18
0
def import_ecl_egrid(self, gfile):
    """Import, private to this routine."""

    eclfile = xtgeo._XTGeoCFile(gfile)

    # scan file for property
    logger.info("Make kwlist by scanning")
    kwlist = utils.scan_keywords(eclfile.fhandle,
                                 fformat="xecl",
                                 maxkeys=1000,
                                 dataframe=False,
                                 dates=False)
    bpos = {}
    for name in ("COORD", "ZCORN", "ACTNUM", "MAPAXES"):
        bpos[name] = -1  # initially

    self._dualporo = False
    for kwitem in kwlist:
        kwname, kwtype, kwlen, kwbyte = kwitem
        if kwname == "FILEHEAD":
            # read FILEHEAD record:
            filehead = eclbin_record(eclfile.fhandle, "FILEHEAD", kwlen,
                                     kwtype, kwbyte)
            dualp = filehead[5].tolist()
            logger.info("Dual porosity flag is %s", dualp)
            if dualp == 1:
                self._dualporo = True
                self._dualperm = False
            elif dualp == 2:
                self._dualporo = True
                self._dualperm = True
        elif kwname == "GRIDHEAD":
            # read GRIDHEAD record:
            gridhead = eclbin_record(eclfile.fhandle, "GRIDHEAD", kwlen,
                                     kwtype, kwbyte)
            ncol, nrow, nlay = gridhead[1:4].tolist()
            logger.info("%s %s %s", ncol, nrow, nlay)
        elif kwname in ("COORD", "ZCORN", "ACTNUM"):
            bpos[kwname] = kwbyte
        elif kwname == "MAPAXES":  # not always present
            bpos[kwname] = kwbyte

    self._ncol = ncol
    self._nrow = nrow
    self._nlay = nlay

    logger.info("Grid dimensions in EGRID file: %s %s %s", ncol, nrow, nlay)

    # allocate dimensions:
    ntot = self._ncol * self._nrow * self._nlay
    ncoord = (self._ncol + 1) * (self._nrow + 1) * 2 * 3
    nzcorn = self._ncol * self._nrow * (self._nlay + 1) * 4

    self._p_coord_v = _cxtgeo.new_doublearray(ncoord)
    self._p_zcorn_v = _cxtgeo.new_doublearray(nzcorn)
    self._p_actnum_v = _cxtgeo.new_intarray(ntot)
    p_nact = _cxtgeo.new_longpointer()

    option = 0
    if self._dualporo:
        option = 1

    ier = _cxtgeo.grd3d_imp_ecl_egrid(
        eclfile.fhandle,
        self._ncol,
        self._nrow,
        self._nlay,
        bpos["MAPAXES"],
        bpos["COORD"],
        bpos["ZCORN"],
        bpos["ACTNUM"],
        self._p_coord_v,
        self._p_zcorn_v,
        self._p_actnum_v,
        p_nact,
        option,
    )

    if ier == -1:
        raise RuntimeError("Error code -1 from _cxtgeo.grd3d_imp_ecl_egrid")

    self._nactive = _cxtgeo.longpointer_value(p_nact)

    # in case of DUAL PORO/PERM ACTNUM will be 0..3; need to convert
    if self._dualporo:
        self._dualactnum = self.get_actnum(name="DUALACTNUM")
        acttmp = self._dualactnum.copy()
        acttmp.values[acttmp.values >= 1] = 1
        self.set_actnum(acttmp)

    eclfile.close()
Пример #19
0
def _convert_to_xtgeo_grid(self, rox, roxgrid, corners):
    """Convert from RMS API to XTGeo API"""

    # pylint: disable=too-many-statements

    logger.info("Converting to XTGeo internals...")
    logger.info("Call the ROXAPI grid indexer")
    indexer = roxgrid.grid_indexer

    ncol, nrow, nlay = indexer.dimensions
    ntot = ncol * nrow * nlay

    # update other attributes
    self._ncol = ncol
    self._nrow = nrow
    self._nlay = nlay

    if corners is None:
        logger.info("Asked for dimensions_only: No geometry read!")
        return

    logger.info("Get active cells")
    mybuffer = np.ndarray(indexer.dimensions, dtype=np.int32)

    mybuffer.fill(0)

    logger.info("Get cell numbers")
    cellno = indexer.get_cell_numbers_in_range((0, 0, 0), indexer.dimensions)

    logger.info("Reorder...")
    ijk = indexer.get_indices(cellno)

    iind = ijk[:, 0]
    jind = ijk[:, 1]
    kind = ijk[:, 2]

    pvalues = np.ones(len(cellno))
    pvalues[cellno] = 1
    mybuffer[iind, jind, kind] = pvalues[cellno]

    actnum = mybuffer

    if rox.version_required("1.3"):
        logger.info("Handedness (new) %s", indexer.ijk_handedness)
    else:
        logger.info("Handedness (old) %s", indexer.handedness)

    corners = corners.ravel(order="K")
    actnum = actnum.ravel(order="K")

    logger.info("Convert to C pointers...")

    nnum = ncol * nrow * nlay * 24
    ccorners = _cxtgeo.new_doublearray(nnum)
    ntot = ncol * nrow * nlay
    cactnum = _cxtgeo.new_intarray(ntot)
    ncoord = (ncol + 1) * (nrow + 1) * 2 * 3
    nzcorn = ncol * nrow * (nlay + 1) * 4

    self._p_coord_v = _cxtgeo.new_doublearray(ncoord)
    self._p_zcorn_v = _cxtgeo.new_doublearray(nzcorn)
    self._p_actnum_v = _cxtgeo.new_intarray(ntot)

    _cxtgeo.swig_numpy_to_carr_1d(corners, ccorners)
    _cxtgeo.swig_numpy_to_carr_i1d(actnum, cactnum)

    # next task is to convert geometry to cxtgeo internal format
    logger.info("Run XTGeo C code...")
    _cxtgeo.grd3d_conv_roxapi_grid(
        ncol,
        nrow,
        nlay,
        ntot,
        cactnum,
        ccorners,
        self._p_coord_v,
        self._p_zcorn_v,
        self._p_actnum_v,
        XTGDEBUG,
    )
    logger.info("Run XTGeo C code... done")

    _cxtgeo.delete_doublearray(ccorners)
    _cxtgeo.delete_intarray(cactnum)
    logger.info("Converting to XTGeo internals... done")

    # subgrids
    if len(indexer.zonation) > 1:
        logger.debug("Zonation length (N subzones) is %s",
                     len(indexer.zonation))
        subz = OrderedDict()
        for inum, zrange in indexer.zonation.items():
            logger.debug("inum: %s, zrange: %s", inum, zrange)
            zname = roxgrid.zone_names[inum]
            logger.debug("zname is: %s", zname)
            zra = [nn + 1 for ira in zrange for nn in ira]  # nested lists
            subz[zname] = zra

        self.subgrids = subz
Пример #20
0
def import_ecl_grdecl(self, gfile):

    # make a temporary file
    fds, tmpfile = mkstemp(prefix="tmpxtgeo")
    os.close(fds)

    with open(gfile) as oldfile, open(tmpfile, "w") as newfile:
        for line in oldfile:
            if not (re.search(r"^--", line) or re.search(r"^\s+$", line)):
                newfile.write(line)

    newfile.close()
    oldfile.close()

    # find ncol nrow nz
    mylist = []
    found = False
    with open(tmpfile) as xfile:
        for line in xfile:
            if found:
                logger.info(line)
                mylist = line.split()
                break
            if re.search(r"^SPECGRID", line):
                found = True

    if not found:
        logger.error("SPECGRID not found. Nothing imported!")
        return
    xfile.close()

    self._ncol, self._nrow, self._nlay = int(mylist[0]), int(mylist[1]), int(
        mylist[2])

    logger.info("NX NY NZ in grdecl file: %s %s %s", self._ncol, self._nrow,
                self._nlay)

    ntot = self._ncol * self._nrow * self._nlay
    ncoord = (self._ncol + 1) * (self._nrow + 1) * 2 * 3
    nzcorn = self._ncol * self._nrow * (self._nlay + 1) * 4

    logger.info("Reading...")

    ptr_num_act = _cxtgeo.new_intpointer()
    self._p_coord_v = _cxtgeo.new_doublearray(ncoord)
    self._p_zcorn_v = _cxtgeo.new_doublearray(nzcorn)
    self._p_actnum_v = _cxtgeo.new_intarray(ntot)

    _cxtgeo.grd3d_import_grdecl(
        self._ncol,
        self._nrow,
        self._nlay,
        self._p_coord_v,
        self._p_zcorn_v,
        self._p_actnum_v,
        ptr_num_act,
        tmpfile,
        XTGDEBUG,
    )

    # remove tmpfile
    os.remove(tmpfile)

    nact = _cxtgeo.intpointer_value(ptr_num_act)

    logger.info("Number of active cells: %s", nact)
    self._subgrids = None
Пример #21
0
def refine_vertically(self, rfactor, zoneprop=None):
    """Refine vertically, proportionally

    See details in caller.
    """
    rfactord = OrderedDict()

    # case 1 rfactor as scalar value.
    if isinstance(rfactor, int):
        if self.subgrids:
            subgrids = self.get_subgrids()
            for i, _ in enumerate(self.subgrids.keys()):
                rfactord[i + 1] = rfactor
        else:
            rfactord[0] = rfactor
            subgrids = OrderedDict()
            subgrids[1] = self.nlay

    # case 2 rfactor is a dict
    else:
        rfactord = OrderedDict(sorted(rfactor.items()))  # redefined to ordered
        # 2a: zoneprop is present
        if zoneprop is not None:
            oldsubgrids = None
            if self.subgrids:
                oldsubgrids = self.get_subgrids()

            subgrids = self.subgrids_from_zoneprop(zoneprop)

            if oldsubgrids:
                if subgrids.values() != oldsubgrids.values():
                    xtg.warn("ISSUES!!!")

        # 2b: zoneprop is not present
        elif zoneprop is None and self.subgrids:
            subgrids = self.get_subgrids()

        elif zoneprop is None and not self.subgrids:
            raise ValueError("You gave in a dict, but no zoneprops and "
                             "subgrids are not preesent in the grid")
        else:
            raise ValueError("Some major unexpected issue in routine...")

    if len(subgrids) != len(rfactord):
        raise RuntimeError("Subgrids and refinements: different definition!")

    self.set_subgrids(subgrids)

    # Now, based on dict, give a value per subgrid for key, val in rfactor
    newsubgrids = OrderedDict()
    newnlay = 0
    for (_x, rfi), (snam, sran) in zip(rfactord.items(), subgrids.items()):
        newsubgrids[snam] = sran * rfi
        newnlay += newsubgrids[snam]

    logger.debug("New layers: %s", newnlay)

    # rfac is an array with length nlay; has N refinements per single K layer
    rfac = _cxtgeo.new_intarray(self.nlay)

    totvector = []
    for (_tmp1, rfi), (_tmp2, arr) in zip(rfactord.items(),
                                          self.subgrids.items()):
        for _elem in range(len(arr)):
            totvector.append(rfi)
    for inn, rfi in enumerate(totvector):
        _cxtgeo.intarray_setitem(rfac, inn, rfi)

    ref_num_act = _cxtgeo.new_intpointer()
    ref_p_zcorn_v = _cxtgeo.new_doublearray(self.ncol * self.nrow *
                                            (newnlay + 1) * 4)
    ref_p_actnum_v = _cxtgeo.new_intarray(self.ncol * self.nrow * newnlay)

    ier = _cxtgeo.grd3d_refine_vert(
        self.ncol,
        self.nrow,
        self.nlay,
        self._p_coord_v,
        self._p_zcorn_v,
        self._p_actnum_v,
        newnlay,
        ref_p_zcorn_v,
        ref_p_actnum_v,
        ref_num_act,
        rfac,
        0,
        XTGDEBUG,
    )

    if ier != 0:
        raise RuntimeError("An error occured in the C routine "
                           "grd3d_refine_vert, code {}".format(ier))

    # update instance:
    self._nlay = newnlay
    self._p_zcorn_v = ref_p_zcorn_v
    self._p_actnum_v = ref_p_actnum_v
    if self.subgrids is None or len(self.subgrids) <= 1:
        self.subgrids = None
    else:
        self.set_subgrids(newsubgrids)

    return self
Пример #22
0
def crop(self, spec, props=None):  # pylint: disable=too-many-locals
    """Do cropping of geometry (and properties).

    If props is 'all' then all properties assosiated (linked) to then
    grid are also cropped, and the instances are updated.

    Args:
        spec (tuple): A nested tuple on the form ((i1, i2), (j1, j2), (k1, k2))
            where 1 represents start number, and 2 reperesent end. The range
            is inclusive for both ends, and the number start index is 1 based.
        props (list or str): None is default, while properties can be listed.
            If 'all', then all GridProperty objects which are linked to the
            Grid instance are updated.

    Returns:
        The instance is updated (cropped)
    """

    (ic1, ic2), (jc1, jc2), (kc1, kc2) = spec

    if (
        ic1 < 1
        or ic2 > self.ncol
        or jc1 < 1
        or jc2 > self.nrow
        or kc1 < 1
        or kc2 > self.nlay
    ):

        raise ValueError("Boundary for tuples not matching grid" "NCOL, NROW, NLAY")

    oldnlay = self._nlay

    # compute size of new cropped grid
    nncol = ic2 - ic1 + 1
    nnrow = jc2 - jc1 + 1
    nnlay = kc2 - kc1 + 1

    ntot = nncol * nnrow * nnlay
    ncoord = (nncol + 1) * (nnrow + 1) * 2 * 3
    nzcorn = nncol * nnrow * (nnlay + 1) * 4

    new_num_act = _cxtgeo.new_intpointer()
    new_p_coord_v = _cxtgeo.new_doublearray(ncoord)
    new_p_zcorn_v = _cxtgeo.new_doublearray(nzcorn)
    new_p_actnum_v = _cxtgeo.new_intarray(ntot)

    _cxtgeo.grd3d_crop_geometry(
        self.ncol,
        self.nrow,
        self.nlay,
        self._p_coord_v,
        self._p_zcorn_v,
        self._p_actnum_v,
        new_p_coord_v,
        new_p_zcorn_v,
        new_p_actnum_v,
        ic1,
        ic2,
        jc1,
        jc2,
        kc1,
        kc2,
        new_num_act,
        0,
        XTGDEBUG,
    )

    self._p_coord_v = new_p_coord_v
    self._p_zcorn_v = new_p_zcorn_v
    self._p_actnum_v = new_p_actnum_v

    self._ncol = nncol
    self._nrow = nnrow
    self._nlay = nnlay

    if isinstance(self.subgrids, dict):
        newsub = OrderedDict()
        # easier to work with numpies than lists
        newarr = np.array(range(1, oldnlay + 1))
        newarr[newarr < kc1] = 0
        newarr[newarr > kc2] = 0
        newaxx = newarr.copy() - kc1 + 1
        for sub, arr in self.subgrids.items():
            arrx = np.array(arr)
            arrxmap = newaxx[arrx[0] - 1 : arrx[-1]]
            arrxmap = arrxmap[arrxmap > 0]
            if arrxmap.size > 0:
                newsub[sub] = arrxmap.astype(np.int32).tolist()

        self.subgrids = newsub

    # crop properties
    if props is not None:
        if props == "all":
            props = self.props

        for prop in props:
            logger.info("Crop %s", prop.name)
            prop.crop(spec)
Пример #23
0
def _make_ijk_from_grid_v1(self, grid, grid_id=""):
    """
    Getting IJK from a grid and make as well logs.

    This is the first version, using _cxtgeo.grd3d_well_ijk from C

    """
    logger.info("Using algorithm 1 in %s", __name__)

    wxarr = self.get_carray("X_UTME")
    wyarr = self.get_carray("Y_UTMN")
    wzarr = self.get_carray("Z_TVDSS")

    nlen = self.nrow
    wivec = _cxtgeo.new_intarray(nlen)
    wjvec = _cxtgeo.new_intarray(nlen)
    wkvec = _cxtgeo.new_intarray(nlen)

    onelayergrid = grid.copy()
    onelayergrid.reduce_to_one_layer()

    cstatus = _cxtgeo.grd3d_well_ijk(
        grid.ncol,
        grid.nrow,
        grid.nlay,
        grid._coordsv,
        grid._zcornsv,
        grid._actnumsv,
        onelayergrid._zcornsv,
        onelayergrid._actnumsv,
        self.nrow,
        wxarr,
        wyarr,
        wzarr,
        wivec,
        wjvec,
        wkvec,
        0,
    )

    if cstatus != 0:
        raise RuntimeError("Error from C routine, code is {}".format(cstatus))

    indarray = _cxtgeo.swig_carr_to_numpy_i1d(nlen, wivec).astype("float")
    jndarray = _cxtgeo.swig_carr_to_numpy_i1d(nlen, wjvec).astype("float")
    kndarray = _cxtgeo.swig_carr_to_numpy_i1d(nlen, wkvec).astype("float")

    indarray[indarray == 0] = np.nan
    jndarray[jndarray == 0] = np.nan
    kndarray[kndarray == 0] = np.nan

    icellname = "ICELL" + grid_id
    jcellname = "JCELL" + grid_id
    kcellname = "KCELL" + grid_id

    self._df[icellname] = indarray
    self._df[jcellname] = jndarray
    self._df[kcellname] = kndarray

    for cellname in [icellname, jcellname, kcellname]:
        self._wlogtype[cellname] = "DISC"

    self._wlogrecord[icellname] = {
        ncel: str(ncel)
        for ncel in range(1, grid.ncol + 1)
    }
    self._wlogrecord[jcellname] = {
        ncel: str(ncel)
        for ncel in range(1, grid.nrow + 1)
    }
    self._wlogrecord[kcellname] = {
        ncel: str(ncel)
        for ncel in range(1, grid.nlay + 1)
    }

    _cxtgeo.delete_intarray(wivec)
    _cxtgeo.delete_intarray(wjvec)
    _cxtgeo.delete_intarray(wkvec)
    _cxtgeo.delete_doublearray(wxarr)
    _cxtgeo.delete_doublearray(wyarr)
    _cxtgeo.delete_doublearray(wzarr)

    del onelayergrid
Пример #24
0
def _import_roff_v1(self, pfile, name):
    """Import ROFF format, version 1"""
    # pylint: disable=too-many-locals

    # there is a todo here to get it more robust for various cases,
    # e.g. that a ROFF file may contain both a grid an numerous
    # props

    logger.info("Looking for %s in file %s", name, pfile)

    ptr_ncol = _cxtgeo.new_intpointer()
    ptr_nrow = _cxtgeo.new_intpointer()
    ptr_nlay = _cxtgeo.new_intpointer()
    ptr_ncodes = _cxtgeo.new_intpointer()
    ptr_type = _cxtgeo.new_intpointer()

    ptr_idum = _cxtgeo.new_intpointer()
    ptr_ddum = _cxtgeo.new_doublepointer()

    # read with mode 0, to scan for ncol, nrow, nlay and ndcodes, and if
    # property is found...
    ier, _codenames = _cxtgeo.grd3d_imp_prop_roffbin(
        pfile,
        0,
        ptr_type,
        ptr_ncol,
        ptr_nrow,
        ptr_nlay,
        ptr_ncodes,
        name,
        ptr_idum,
        ptr_ddum,
        ptr_idum,
        0,
        XTGDEBUG,
    )

    if ier == -1:
        msg = "Cannot find property name {}".format(name)
        logger.warning(msg)
        raise SystemExit("Error from ROFF import")

    self._ncol = _cxtgeo.intpointer_value(ptr_ncol)
    self._nrow = _cxtgeo.intpointer_value(ptr_nrow)
    self._nlay = _cxtgeo.intpointer_value(ptr_nlay)
    self._ncodes = _cxtgeo.intpointer_value(ptr_ncodes)

    ptype = _cxtgeo.intpointer_value(ptr_type)

    ntot = self._ncol * self._nrow * self._nlay

    if self._ncodes <= 1:
        self._ncodes = 1
        self._codes = {0: "undef"}

    logger.debug("Number of codes: %s", self._ncodes)

    # allocate

    if ptype == 1:  # float, assign to double
        ptr_pval_v = _cxtgeo.new_doublearray(ntot)
        ptr_ival_v = _cxtgeo.new_intarray(1)
        self._isdiscrete = False
        self._dtype = "float64"

    elif ptype > 1:
        ptr_pval_v = _cxtgeo.new_doublearray(1)
        ptr_ival_v = _cxtgeo.new_intarray(ntot)
        self._isdiscrete = True
        self._dtype = "int32"

    # number of codes and names
    ptr_ccodes_v = _cxtgeo.new_intarray(self._ncodes)

    # NB! note the SWIG trick to return modified char values; use cstring.i
    # inn the config and %cstring_bounded_output(char *p_codenames_v, NN);
    # Then the argument for *p_codevalues_v in C is OMITTED here!

    ier, cnames = _cxtgeo.grd3d_imp_prop_roffbin(
        pfile,
        1,
        ptr_type,
        ptr_ncol,
        ptr_nrow,
        ptr_nlay,
        ptr_ncodes,
        name,
        ptr_ival_v,
        ptr_pval_v,
        ptr_ccodes_v,
        0,
        XTGDEBUG,
    )

    if self._isdiscrete:
        _gridprop_lowlevel.update_values_from_carray(self,
                                                     ptr_ival_v,
                                                     np.int32,
                                                     delete=True)
    else:
        _gridprop_lowlevel.update_values_from_carray(self,
                                                     ptr_pval_v,
                                                     np.float64,
                                                     delete=True)

    # now make dictionary of codes
    if self._isdiscrete:
        cnames = cnames.replace(";", "")
        cname_list = cnames.split("|")
        cname_list.pop()  # some rubbish as last entry
        ccodes = []
        for ino in range(0, self._ncodes):
            ccodes.append(_cxtgeo.intarray_getitem(ptr_ccodes_v, ino))

        self._codes = dict(zip(ccodes, cname_list))

    self._name = name
Пример #25
0
def make_hybridgrid(grid, **kwargs):
    """Make hybrid grid.

    It changes the grid geometry status of the object.

    Input:
        grid (object): A grid object
        TODO region (object): A region parameter (property object)
        etc...
    """

    nhdiv = kwargs.get("nhdiv")
    toplevel = kwargs.get("toplevel")
    bottomlevel = kwargs.get("bottomlevel")
    region = kwargs.get("region", None)
    region_number = kwargs.get("region_number", None)

    logger.debug("nhdiv: %s", nhdiv)
    logger.debug("toplevel: %s", toplevel)
    logger.debug("bottomlevel: %s", bottomlevel)
    logger.debug("region: %s", region)
    logger.debug("region_number: %s", region_number)

    xtg_verbose_level = xtg.syslevel

    newnlay = grid.nlay * 2 + nhdiv

    hyb_num_act = _cxtgeo.new_intpointer()
    hyb_p_zcorn_v = _cxtgeo.new_doublearray(grid.ncol * grid.nrow *
                                            (newnlay + 1) * 4)
    hyb_p_actnum_v = _cxtgeo.new_intarray(grid.ncol * grid.nrow * newnlay)

    if region is None:
        _cxtgeo.grd3d_convert_hybrid(
            grid.ncol,
            grid.nrow,
            grid.nlay,
            grid._p_coord_v,
            grid._p_zcorn_v,
            grid._p_actnum_v,
            newnlay,
            hyb_p_zcorn_v,
            hyb_p_actnum_v,
            hyb_num_act,
            toplevel,
            bottomlevel,
            nhdiv,
            xtg_verbose_level,
        )
    else:

        region.discrete_to_continuous()

        carray_reg = _gridprop_lowlevel.update_carray(region)

        _cxtgeo.grd3d_convert_hybrid2(
            grid.ncol,
            grid.nrow,
            grid.nlay,
            grid._p_coord_v,
            grid._p_zcorn_v,
            grid._p_actnum_v,
            newnlay,
            hyb_p_zcorn_v,
            hyb_p_actnum_v,
            hyb_num_act,
            toplevel,
            bottomlevel,
            nhdiv,
            carray_reg,
            region_number,
            xtg_verbose_level,
        )

        _gridprop_lowlevel.delete_carray(region, carray_reg)

    grid._nlay = newnlay
    grid._p_zcorn_v = hyb_p_zcorn_v
    grid._p_actnum_v = hyb_p_actnum_v

    return grid