Exemple #1
0
def add_grids(model, crs, add_lengths):
    grid_a = grr.RegularGrid(model,
                             extent_kji=(2, 2, 2),
                             crs_uuid=crs.uuid,
                             title='GRID A',
                             set_points_cached=True,
                             as_irregular_grid=True)
    grid_a.write_hdf5()
    grid_a.create_xml(write_active=False,
                      add_cell_length_properties=add_lengths,
                      write_geometry=True)
    grid_b = grr.RegularGrid(model,
                             extent_kji=(3, 3, 3),
                             crs_uuid=crs.uuid,
                             title='GRID B',
                             set_points_cached=True,
                             as_irregular_grid=True)
    grid_b.write_hdf5()
    grid_b.create_xml(write_active=False,
                      add_cell_length_properties=add_lengths,
                      write_geometry=True)
    grid_c = grr.RegularGrid(model,
                             extent_kji=(4, 4, 4),
                             crs_uuid=crs.uuid,
                             title='GRID C',
                             set_points_cached=True,
                             as_irregular_grid=True)
    grid_c.write_hdf5()
    grid_c.create_xml(write_active=False,
                      add_cell_length_properties=add_lengths,
                      write_geometry=True)
    return (grid_a, grid_b, grid_c)
Exemple #2
0
def small_grid_and_surface(
        tmp_model: Model) -> Tuple[grr.RegularGrid, rqs.Surface]:
    """Creates a small RegularGrid and a random triangular surface."""
    crs = Crs(tmp_model)
    crs.create_xml()

    extent = 10
    extent_kji = (extent, extent, extent)
    dxyz = (1.0, 1.0, 1.0)
    crs_uuid = crs.uuid
    title = "small_grid"
    grid = grr.RegularGrid(tmp_model,
                           extent_kji=extent_kji,
                           dxyz=dxyz,
                           crs_uuid=crs_uuid,
                           title=title)
    grid.create_xml()

    n_points = 100
    points = np.random.rand(n_points, 3) * extent
    triangles = tri.dt(points)
    surface = rqs.Surface(tmp_model, crs_uuid=crs_uuid, title="small_surface")
    surface.set_from_triangles_and_points(triangles, points)
    surface.triangles_and_points()
    surface.write_hdf5()
    surface.create_xml()

    tmp_model.store_epc()

    return grid, surface
Exemple #3
0
def test_regular_grid_with_geometry(tmp_path):
    epc = os.path.join(tmp_path, 'concrete.epc')

    model = rq.new_model(epc)

    # create a basic block grid
    dxyz = (55.0, 65.0, 27.0)
    grid = grr.RegularGrid(model,
                           extent_kji=(4, 3, 2),
                           title='concrete',
                           origin=(0.0, 0.0, 1000.0),
                           dxyz=dxyz)
    grid.create_xml(add_cell_length_properties=True)
    grid_uuid = grid.uuid

    # store with constant arrays (no hdf5 data)
    model.store_epc()

    # check that the grid can be read
    model = rq.Model(epc)
    grid = grr.any_grid(model, uuid=grid_uuid)

    # check that the cell size has been preserved
    expected_dxyz_dkji = np.zeros((3, 3))
    for i in range(3):
        expected_dxyz_dkji[2 - i, i] = dxyz[i]
    assert_array_almost_equal(expected_dxyz_dkji, grid.block_dxyz_dkji)
Exemple #4
0
 def try_one_half_t_regular(model,
                            extent_kji=(2, 2, 2),
                            dxyz=(1.0, 1.0, 1.0),
                            perm_kji=(1.0, 1.0, 1.0),
                            ntg=1.0,
                            darcy_constant=1.0,
                            rotate=None,
                            dip=None):
     ones = np.ones(extent_kji)
     grid = grr.RegularGrid(model, extent_kji=extent_kji, dxyz=dxyz)
     if dip is not None:  # dip positive x axis downwards
         r_matrix = vec.rotation_matrix_3d_axial(1, dip)
         p = grid.points_ref(masked=False)
         p[:] = vec.rotate_array(r_matrix, p)
     if rotate is not None:  # rotate anticlockwise in xy plane (viewed from above)
         r_matrix = vec.rotation_matrix_3d_axial(2, rotate)
         p = grid.points_ref(masked=False)
         p[:] = vec.rotate_array(r_matrix, p)
     half_t = rqtr.half_cell_t(grid,
                               perm_k=perm_kji[0] * ones,
                               perm_j=perm_kji[1] * ones,
                               perm_i=perm_kji[2] * ones,
                               ntg=ntg * ones,
                               darcy_constant=darcy_constant)
     expected = 2.0 * darcy_constant * np.array(
         (perm_kji[0] * dxyz[0] * dxyz[1] / dxyz[2],
          ntg * perm_kji[1] * dxyz[0] * dxyz[2] / dxyz[1],
          ntg * perm_kji[2] * dxyz[1] * dxyz[2] / dxyz[0]))
     assert np.all(np.isclose(half_t, expected.reshape(1, 1, 1, 3)))
Exemple #5
0
def test_dtype_size(tmp_path):

    filenames = ['dtype_16', 'dtype_32', 'dtype_64']
    byte_sizes = [2, 4, 8]
    dtypes = [np.float16, np.float32, np.float64]
    hdf5_sizes = []

    extent_kji = (1000, 100, 100)
    a = np.random.random(extent_kji)

    for filename, dtype in zip(filenames, dtypes):
        epc = os.path.join(tmp_path, filename + '.epc')
        h5_file = epc[:-4] + '.h5'
        model = rq.new_model(epc)
        grid = grr.RegularGrid(model, extent_kji=extent_kji)
        grid.create_xml()
        pc = rqp.PropertyCollection()
        pc.set_support(support_uuid=grid.uuid, model=model)
        pc.add_cached_array_to_imported_list(
            cached_array=a,
            source_info='random',
            keyword='NTG',
            property_kind='net to gross ratio',
            indexable_element='cells',
            uom='m3/m3')
        pc.write_hdf5_for_imported_list(dtype=dtype)
        model.store_epc()
        model.h5_release()
        hdf5_sizes.append(os.path.getsize(h5_file))

    assert hdf5_sizes[0] < hdf5_sizes[1] < hdf5_sizes[2]
    for i, (byte_size, hdf5_size) in enumerate(zip(byte_sizes, hdf5_sizes)):
        array_size = byte_size * a.size
        # following may need to be modified if using hdf5 compression
        assert array_size < hdf5_size < array_size + 100000
def test_actual_pillar_shape(tmp_path):

    # --------- Arrange----------
    epc = os.path.join(tmp_path, 'grid.epc')
    model = rq.new_model(epc)

    # create a basic block grid
    dxyz = (10.0, 10.0, 10.0)
    vertical_grid = grr.RegularGrid(model,
                                    extent_kji=(2, 2, 2),
                                    title='vert_grid',
                                    origin=(0.0, 0.0, 0.0),
                                    dxyz=dxyz)
    straight_grid = grr.RegularGrid(model,
                                    extent_kji=(2, 2, 2),
                                    title='straight_grid',
                                    origin=(10.0, 10.0, 0.0),
                                    dxyz=dxyz,
                                    as_irregular_grid=True)
    curved_grid = grr.RegularGrid(model,
                                  extent_kji=(3, 2, 2),
                                  title='curved_grid',
                                  origin=(10.0, 10.0, 0.0),
                                  dxyz=dxyz,
                                  as_irregular_grid=True)

    # shift the corner points of cellkji0 == (0, 0, 0) by - 10 x and -10 y units
    straight_grid.corner_points()[0][0][0][0][0][0] = np.array([0., 0., 0])
    straight_grid.corner_points()[0][0][0][0][0][1] = np.array([10., 0., 0])

    # shift 2 corner points of cellkji0 == (1, 0, 0) by -5 x units
    curved_grid.corner_points()[0][0][0][1][0][0] = np.array([5., 10., 10])
    curved_grid.corner_points()[0][0][0][1][0][1] = np.array([15., 10., 10])

    # --------- Act----------
    pillar_shape_vertical = actual_pillar_shape(
        pillar_points=vertical_grid.corner_points())
    pillar_shape_straight = actual_pillar_shape(
        pillar_points=straight_grid.corner_points())
    pillar_shape_curved = actual_pillar_shape(
        pillar_points=curved_grid.corner_points())

    # --------- Assert----------
    assert pillar_shape_vertical == 'vertical'
    assert pillar_shape_straight == 'straight'
    assert pillar_shape_curved == 'curved'
Exemple #7
0
def make_epc_with_gcs(tmp_path):
    epc = os.path.join(tmp_path, 'two_fault.epc')
    model = rq.new_model(epc)

    # create a grid
    g = grr.RegularGrid(model, extent_kji=(5, 4, 3), dxyz=(100.0, 100.0, 10.0))
    g.create_xml()

    # create an empty grid connection set
    gcs = rqf.GridConnectionSet(model, grid=g)

    # prepare two named faults as a dataframe
    data = {
        'name': ['F1', 'F2'],
        'face': ['I+', 'J-'],
        'i1': [1, 0],
        'i2': [1, 2],
        'j1': [0, 2],
        'j2': [3, 2],
        'k1': [0, 0],
        'k2': [4, 4],
        'mult': [0.1, 0.05]
    }
    df = pd.DataFrame(data)

    # set grid connection set from dataframe
    gcs.set_pairs_from_faces_df(df,
                                create_organizing_objects_where_needed=True,
                                create_mult_prop=True,
                                fault_tmult_dict=None,
                                one_based_indexing=False)

    # save the grid connection set
    gcs.write_hdf5()
    gcs.create_xml(title='two fault gcs')
    model.store_epc()

    # add some basic grid properties
    porosity_uuid = rqdm.add_one_grid_property_array(epc,
                                                     np.full(
                                                         g.extent_kji, 0.27),
                                                     property_kind='porosity',
                                                     title='porosity',
                                                     uom='m3/m3')
    assert porosity_uuid is not None
    perm_uuid = rqdm.add_one_grid_property_array(
        epc,
        np.full(g.extent_kji, 152.0),
        property_kind='rock permeability',
        uom='mD',
        facet_type='direction',
        facet='IJK',
        title='permeability')
    assert perm_uuid is not None

    return epc
Exemple #8
0
def make_epc_with_abutting_grids(tmp_path):
    epc = os.path.join(tmp_path, 'abutting_grids.epc')
    model = rq.new_model(epc)

    # create a grid
    g0 = grr.RegularGrid(model,
                         extent_kji=(5, 4, 3),
                         dxyz=(100.0, 100.0, 10.0))
    g0.create_xml()

    g1 = grr.RegularGrid(model,
                         extent_kji=(5, 4, 3),
                         dxyz=(100.0, 100.0, 10.0),
                         origin=(100.0, 400.0, 20.0))
    g1.create_xml()

    # create an empty grid connection set
    gcs = rqf.GridConnectionSet(model, title='abut')

    # populate the grid connection set at low level due to lack of multi-grid methods
    gcs.grid_list = [g0, g1]
    gcs.count = 6
    gcs.grid_index_pairs = np.zeros((6, 2), dtype=int)
    gcs.grid_index_pairs[:, 1] = 1
    gcs.face_index_pairs = np.empty((6, 2), dtype=int)
    gcs.face_index_pairs[:, 0] = gcs.face_index_map[1, 1]  #  J+
    gcs.face_index_pairs[:, 1] = gcs.face_index_map[1, 0]  #  J-
    gcs.cell_index_pairs = np.empty((6, 2), dtype=int)
    cell = 0
    for k in range(3):
        for i in range(2):
            gcs.cell_index_pairs[cell, 0] = g0.natural_cell_index(
                (k + 2, 3, i + 1))
            gcs.cell_index_pairs[cell, 1] = g1.natural_cell_index((k, 0, i))
            cell += 1
    #  leave optional feature list & indices as None

    # save the grid connection set
    gcs.write_hdf5()
    gcs.create_xml()
    model.store_epc()

    return epc
Exemple #9
0
def example_fine_coarse_model(example_model_and_crs):
    model, crs = example_model_and_crs

    coarse_grid = grr.RegularGrid(parent_model=model,
                                  origin=(0, 0, 0),
                                  extent_kji=(3, 5, 5),
                                  crs_uuid=crs.uuid,
                                  dxyz=(10, 10, 10))
    coarse_grid.cache_all_geometry_arrays()
    coarse_grid.write_hdf5_from_caches(
        file=model.h5_file_name(file_must_exist=False), mode='w')
    coarse_grid.create_xml(ext_uuid=model.h5_uuid(),
                           title='Coarse',
                           write_geometry=True,
                           add_cell_length_properties=True)

    fine_grid = grr.RegularGrid(parent_model=model,
                                origin=(0, 0, 0),
                                extent_kji=(6, 10, 10),
                                crs_uuid=crs.uuid,
                                dxyz=(5, 5, 5))
    fine_grid.cache_all_geometry_arrays()
    fine_grid.write_hdf5_from_caches(
        file=model.h5_file_name(file_must_exist=True), mode='a')
    fine_grid.create_xml(ext_uuid=model.h5_uuid(),
                         title='Fine',
                         write_geometry=True,
                         add_cell_length_properties=True)

    model.store_epc()
    model = Model(model.epc_file)

    coarse = grr.Grid(parent_model=model, uuid=coarse_grid.uuid)
    fine = grr.Grid(parent_model=model, uuid=fine_grid.uuid)

    fc = rqfc.FineCoarse(fine_extent_kji=(6, 10, 10),
                         coarse_extent_kji=(3, 5, 5))
    fc.set_all_ratios_constant()
    fc.set_all_proprtions_equal()

    return model, coarse, fine, fc
Exemple #10
0
def test_random_cell(tmp_path):

    # --------- Arrange----------
    seed(1923877)
    epc = os.path.join(tmp_path, 'grid.epc')
    model = rq.new_model(epc)

    # create a basic block grid
    dxyz = (10.0, 10.0, 100.0)
    grid = grr.RegularGrid(model,
                           extent_kji=(4, 2, 2),
                           title='grid_1',
                           origin=(0.0, 10.0, 1000.0),
                           dxyz=dxyz,
                           as_irregular_grid=True)

    grid_points = grid.points_ref(masked=False)

    # pinch out cells in the k == 2 layer
    grid_points[3] = grid_points[2]

    # collapse cell kji0 == 0,0,0 in the j direction
    grid_points[0:2, 1, 0:2, 1] = 10.  # same as origin y value

    # store grid
    grid.write_hdf5()
    grid.create_xml(add_cell_length_properties=True)
    grid_uuid = grid.uuid
    model.store_epc()

    # check that the grid can be read
    model = rq.Model(epc)
    grid_reloaded = grr.any_grid(model, uuid=grid_uuid)
    corner_points = grid_reloaded.corner_points()

    # --------- Act----------
    # call random_cell function 50 times
    trial_number = 0
    while trial_number < 50:
        (k, j, i) = random_cell(corner_points=corner_points, border=0.0)
        # --------- Assert----------
        assert 0 <= k < 4
        assert 0 <= j < 2
        assert 0 <= i < 2
        # check that none of the k,j,i combinations that correspond to pinched cells are chosen by the random_cell function
        assert (k, j, i) not in [(0, 0, 0), (2, 0, 0), (2, 0, 1), (2, 1, 0),
                                 (2, 1, 1)]
        trial_number += 1

    # reshape corner get the extent of the new grid
    corner_points_reshaped = corner_points.reshape(1, 1, 16, 2, 2, 2, 3)
    new_extent = determine_corp_extent(corner_points=corner_points_reshaped)
    assert np.all(new_extent == np.array([4, 2, 2], dtype=int))
Exemple #11
0
def test_interface_lengths_kji(model_test: Model, dxyz):
    # Arrange
    grid = grr.RegularGrid(model_test,
                           extent_kji=(2, 2, 2),
                           dxyz=dxyz,
                           as_irregular_grid=True)
    cell_kji0 = (1, 1, 1)

    # Act
    interface_length = cp.interface_lengths_kji(grid, cell_kji0=cell_kji0)

    # Assert
    np.testing.assert_array_almost_equal(interface_length, dxyz[::-1])
Exemple #12
0
def test_interface_length(model_test: Model, dxyz):
    # Arrange
    grid = grr.RegularGrid(model_test,
                           extent_kji=(2, 2, 2),
                           dxyz=dxyz,
                           as_irregular_grid=True)
    cell_kji0 = (1, 1, 1)

    # Act & Assert
    for axis in range(3):
        interface_length = cp.interface_length(grid,
                                               cell_kji0=cell_kji0,
                                               axis=axis)
        assert interface_length == dxyz[2 - axis]
Exemple #13
0
def test_regular_grid_no_geometry(tmp_path):
    # issue #222

    epc = os.path.join(tmp_path, 'abstract.epc')

    model = rq.new_model(epc)

    # create a basic block grid
    grid = grr.RegularGrid(model, extent_kji=(4, 3, 2), title='spaced out')
    grid.create_xml(add_cell_length_properties=False)
    grid_uuid = grid.uuid

    model.store_epc()

    # check that the grid can be read
    model = rq.Model(epc)

    grid = grr.any_grid(model, uuid=grid_uuid)
Exemple #14
0
def test_determine_corp_extent(tmp_path):

    # --------- Arrange----------
    epc = os.path.join(tmp_path, 'grid.epc')
    model = rq.new_model(epc)

    # create a basic block grid
    dxyz = (55.0, 65.0, 27.0)
    grid = grr.RegularGrid(model,
                           extent_kji=(4, 3, 2),
                           title='concrete',
                           origin=(0.0, 0.0, 1000.0),
                           dxyz=dxyz)
    grid.create_xml(add_cell_length_properties=True)
    corner_points = grid.corner_points()
    corner_points_reshaped = corner_points.reshape(1, 1, 24, 2, 2, 2, 3)
    # --------- Act----------
    [nk, nj, ni] = determine_corp_extent(corner_points=corner_points_reshaped)

    # --------- Assert----------
    assert [nk, nj, ni] == [4, 3, 2]
Exemple #15
0
def _empty_grid(model, source_grid, is_regular, k0_min, k0_max, zone_count):
    if is_regular:
        dxyz_dkji = source_grid.block_dxyz_dkji.copy()
        dxyz_dkji[0] *= k0_max - k0_min + 1
        grid = grr.RegularGrid(model,
                               extent_kji = (1, source_grid.nj, source_grid.ni),
                               dxyz_dkji = dxyz_dkji,
                               origin = source_grid.block_origin,
                               crs_uuid = source_grid.crs_uuid,
                               set_points_cached = False)
    else:
        grid = grr.Grid(model)
        # inherit attributes from source grid
        grid.grid_representation = 'IjkGrid'
        grid.extent_kji = np.array((zone_count, source_grid.nj, source_grid.ni), dtype = 'int')
        grid.nk, grid.nj, grid.ni = zone_count, source_grid.nj, source_grid.ni
        grid.has_split_coordinate_lines = source_grid.has_split_coordinate_lines
        grid.crs_uuid = source_grid.crs_uuid

    grid.k_direction_is_down = source_grid.k_direction_is_down
    grid.grid_is_right_handed = source_grid.grid_is_right_handed
    grid.pillar_shape = source_grid.pillar_shape
    return grid
Exemple #16
0
def example_model_and_cellio(example_model_and_crs, tmp_path):
    model, crs = example_model_and_crs
    grid = grr.RegularGrid(model,
                           extent_kji=(3, 4, 3),
                           dxyz=(50.0, -50.0, 50.0),
                           origin=(0.0, 0.0, 100.0),
                           crs_uuid=crs.uuid,
                           set_points_cached=True)

    grid.write_hdf5()
    grid.create_xml(write_geometry=True)
    grid_uuid = grid.uuid
    cellio_file = os.path.join(model.epc_directory, 'cellio.dat')
    well_name = 'Banoffee'
    source_df = pd.DataFrame([[2, 2, 1, 25, -25, 125, 26, -26, 126],
                              [2, 2, 2, 26, -26, 126, 27, -27, 127],
                              [2, 2, 3, 27, -27, 127, 28, -28, 128]],
                             columns=[
                                 'i_index', 'j_index', 'k_index', 'x_in',
                                 'y_in', 'z_in', 'x_out', 'y_out', 'z_out'
                             ])

    with open(cellio_file, 'w') as fp:
        fp.write('1.0\n')
        fp.write('Undefined\n')
        fp.write(f'{well_name}\n')
        fp.write('9\n')
        for col in source_df.columns:
            fp.write(f' {col}\n')
        for row_index in range(len(source_df)):
            row = source_df.iloc[row_index]
            for col in source_df.columns:
                fp.write(f' {int(row[col])}')
            fp.write('\n')

    return model, cellio_file, well_name
Exemple #17
0
def example_model_with_prop_ts_rels(tmp_path):
    """Model with a grid (5x5x3) and properties.
   Properties:
   - Zone (discrete)
   - VPC (discrete)
   - Fault block (discrete)
   - Facies (discrete)
   - NTG (continuous)
   - POR (continuous)
   - SW (continuous) (recurrent)
   """
    model_path = str(tmp_path / 'test_model.epc')
    model = Model(create_basics=True,
                  create_hdf5_ext=True,
                  epc_file=model_path,
                  new_epc=True)
    model.store_epc(model.epc_file)

    grid = grr.RegularGrid(parent_model=model,
                           origin=(0, 0, 0),
                           extent_kji=(3, 5, 5),
                           crs_uuid=rqet.uuid_for_part_root(model.crs_root),
                           set_points_cached=True)
    grid.cache_all_geometry_arrays()
    grid.write_hdf5_from_caches(file=model.h5_file_name(file_must_exist=False),
                                mode='w')

    grid.create_xml(ext_uuid=model.h5_uuid(),
                    title='grid',
                    write_geometry=True,
                    add_cell_length_properties=False)
    model.store_epc()

    zone = np.ones(shape=(5, 5), dtype='int')
    zone_array = np.array([zone, zone + 1, zone + 2], dtype='int')

    vpc = np.array([[1, 1, 1, 2, 2], [1, 1, 1, 2, 2], [1, 1, 1, 2, 2],
                    [1, 1, 1, 2, 2], [1, 1, 1, 2, 2]],
                   dtype='int')
    vpc_array = np.array([vpc, vpc, vpc], dtype='int')

    facies = np.array([[1, 1, 1, 2, 2], [1, 1, 2, 2, 2], [1, 2, 2, 2, 3],
                       [2, 2, 2, 3, 3], [2, 2, 3, 3, 3]],
                      dtype='int')
    facies_array = np.array([facies, facies, facies], dtype='int')

    perm = np.array([[1, 1, 1, 10, 10], [1, 1, 1, 10, 10], [1, 1, 1, 10, 10],
                     [1, 1, 1, 10, 10], [1, 1, 1, 10, 10]])
    perm_array = np.array([perm, perm, perm], dtype='float')

    fb = np.array([[1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1],
                   [2, 2, 2, 2, 2], [2, 2, 2, 2, 2]],
                  dtype='int')
    fb_array = np.array([fb, fb, fb], dtype='int')

    ntg = np.array([[0, 0.5, 0, 0.5, 0], [0.5, 0, 0.5, 0, 0.5],
                    [0, 0.5, 0, 0.5, 0], [0.5, 0, 0.5, 0, 0.5],
                    [0, 0.5, 0, 0.5, 0]])
    ntg1_array = np.array([ntg, ntg, ntg])
    ntg2_array = np.array([ntg + 0.1, ntg + 0.1, ntg + 0.1])

    por = np.array([[1, 1, 1, 1, 1], [0.5, 0.5, 0.5, 0.5,
                                      0.5], [1, 1, 1, 1, 1],
                    [0.5, 0.5, 0.5, 0.5, 0.5], [1, 1, 1, 1, 1]])
    por1_array = np.array([por, por, por])
    por2_array = np.array([por - 0.1, por - 0.1, por - 0.1])

    sat = np.array([[1, 0.5, 1, 0.5, 1], [1, 0.5, 1, 0.5, 1],
                    [1, 0.5, 1, 0.5, 1], [1, 0.5, 1, 0.5, 1],
                    [1, 0.5, 1, 0.5, 1]])
    sat1_array = np.array([sat, sat, sat])
    sat2_array = np.array([sat, sat, np.where(sat == 0.5, 0.75, sat)])
    sat3_array = np.array([
        np.where(sat == 0.5, 0.75, sat),
        np.where(sat == 0.5, 0.75, sat),
        np.where(sat == 0.5, 0.75, sat)
    ])

    collection = rqp.GridPropertyCollection()
    collection.set_grid(grid)

    ts = rqts.TimeSeries(parent_model=model, first_timestamp='2000-01-01Z')
    ts.extend_by_days(365)
    ts.extend_by_days(365)

    ts.create_xml()

    lookup = rqp.StringLookup(parent_model=model,
                              int_to_str_dict={
                                  1: 'channel',
                                  2: 'interbedded',
                                  3: 'shale'
                              })
    lookup.create_xml()

    model.store_epc()

    # Add non-varying properties
    for array, name, kind, discrete, facet_type, facet in zip(
        [zone_array, vpc_array, fb_array, perm_array],
        ['Zone', 'VPC', 'Fault block', 'Perm'],
        ['discrete', 'discrete', 'discrete', 'permeability rock'],
        [True, True, True, False], [None, None, None, 'direction'],
        [None, None, None, 'J']):
        collection.add_cached_array_to_imported_list(cached_array=array,
                                                     source_info='',
                                                     keyword=name,
                                                     discrete=discrete,
                                                     uom=None,
                                                     time_index=None,
                                                     null_value=None,
                                                     property_kind=kind,
                                                     facet_type=facet_type,
                                                     facet=facet,
                                                     realization=None)
        collection.write_hdf5_for_imported_list()
        collection.create_xml_for_imported_list_and_add_parts_to_model()

    # Add realisation varying properties
    for array, name, kind, rel in zip(
        [ntg1_array, por1_array, ntg2_array, por2_array],
        ['NTG', 'POR', 'NTG', 'POR'],
        ['net to gross ratio', 'porosity', 'net to gross ratio', 'porosity'],
        [0, 0, 1, 1]):
        collection.add_cached_array_to_imported_list(cached_array=array,
                                                     source_info='',
                                                     keyword=name,
                                                     discrete=False,
                                                     uom=None,
                                                     time_index=None,
                                                     null_value=None,
                                                     property_kind=kind,
                                                     facet_type=None,
                                                     facet=None,
                                                     realization=rel)
        collection.write_hdf5_for_imported_list()
        collection.create_xml_for_imported_list_and_add_parts_to_model()

    # Add categorial property
    collection.add_cached_array_to_imported_list(cached_array=facies_array,
                                                 source_info='',
                                                 keyword='Facies',
                                                 discrete=True,
                                                 uom=None,
                                                 time_index=None,
                                                 null_value=None,
                                                 property_kind='discrete',
                                                 facet_type=None,
                                                 facet=None,
                                                 realization=None)
    collection.write_hdf5_for_imported_list()
    collection.create_xml_for_imported_list_and_add_parts_to_model(
        string_lookup_uuid=lookup.uuid)

    # Add time varying properties
    for array, ts_index in zip([sat1_array, sat2_array, sat3_array],
                               [0, 1, 2]):
        collection.add_cached_array_to_imported_list(
            cached_array=array,
            source_info='',
            keyword='SW',
            discrete=False,
            uom=None,
            time_index=ts_index,
            null_value=None,
            property_kind='saturation',
            facet_type='what',
            facet='water',
            realization=None)
        collection.write_hdf5_for_imported_list()
        collection.create_xml_for_imported_list_and_add_parts_to_model(
            time_series_uuid=ts.uuid)
    model.store_epc()

    return model
Exemple #18
0
def example_model_with_properties(tmp_path):
    """Model with a grid (5x5x3) and properties.
   Properties:
   - Zone (discrete)
   - VPC (discrete)
   - Fault block (discrete)
   - Facies (discrete)
   - NTG (continuous)
   - POR (continuous)
   - SW (continuous)
   """
    model_path = str(tmp_path / 'test_no_rels.epc')
    model = Model(create_basics=True,
                  create_hdf5_ext=True,
                  epc_file=model_path,
                  new_epc=True)
    model.store_epc(model.epc_file)

    grid = grr.RegularGrid(parent_model=model,
                           origin=(0, 0, 0),
                           extent_kji=(3, 5, 5),
                           crs_uuid=rqet.uuid_for_part_root(model.crs_root),
                           set_points_cached=True)
    grid.cache_all_geometry_arrays()
    grid.write_hdf5_from_caches(file=model.h5_file_name(file_must_exist=False),
                                mode='w')

    grid.create_xml(ext_uuid=model.h5_uuid(),
                    title='grid',
                    write_geometry=True,
                    add_cell_length_properties=False)
    model.store_epc()

    zone = np.ones(shape=(5, 5))
    zone_array = np.array([zone, zone + 1, zone + 2], dtype='int')

    vpc = np.array([[1, 1, 1, 2, 2], [1, 1, 1, 2, 2], [1, 1, 1, 2, 2],
                    [1, 1, 1, 2, 2], [1, 1, 1, 2, 2]])
    vpc_array = np.array([vpc, vpc, vpc])

    facies = np.array([[1, 1, 1, 2, 2], [1, 1, 2, 2, 2], [1, 2, 2, 2, 3],
                       [2, 2, 2, 3, 3], [2, 2, 3, 3, 3]])
    facies_array = np.array([facies, facies, facies])

    fb = np.array([[1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1],
                   [2, 2, 2, 2, 2], [2, 2, 2, 2, 2]])
    fb_array = np.array([fb, fb, fb])

    ntg = np.array([[0, 0.5, 0, 0.5, 0], [0.5, 0, 0.5, 0, 0.5],
                    [0, 0.5, 0, 0.5, 0], [0.5, 0, 0.5, 0, 0.5],
                    [0, 0.5, 0, 0.5, 0]])
    ntg_array = np.array([ntg, ntg, ntg])

    por = np.array([[1, 1, 1, 1, 1], [0.5, 0.5, 0.5, 0.5,
                                      0.5], [1, 1, 1, 1, 1],
                    [0.5, 0.5, 0.5, 0.5, 0.5], [1, 1, 1, 1, 1]])
    por_array = np.array([por, por, por])

    sat = np.array([[1, 0.5, 1, 0.5, 1], [1, 0.5, 1, 0.5, 1],
                    [1, 0.5, 1, 0.5, 1], [1, 0.5, 1, 0.5, 1],
                    [1, 0.5, 1, 0.5, 1]])
    sat_array = np.array([sat, sat, sat])

    perm = np.array([[1, 10, 10, 100, 100], [1, 10, 10, 100, 100],
                     [1, 10, 10, 100, 100], [1, 10, 10, 100, 100],
                     [1, 10, 10, 100, 100]])
    perm_array = np.array([perm, perm, perm], dtype='float')
    perm_v_array = perm_array * 0.1

    collection = rqp.GridPropertyCollection()
    collection.set_grid(grid)
    for array, name, kind, discrete, facet_type, facet in zip(
        [
            zone_array, vpc_array, fb_array, facies_array, ntg_array,
            por_array, sat_array, perm_array, perm_v_array
        ], [
            'Zone', 'VPC', 'Fault block', 'Facies', 'NTG', 'POR', 'SW', 'Perm',
            'PERMZ'
        ], [
            'discrete', 'discrete', 'discrete', 'discrete',
            'net to gross ratio', 'porosity', 'saturation',
            'rock permeability', 'permeability rock'
        ], [True, True, True, True, False, False, False, False, False],
        [None, None, None, None, None, None, None, 'direction', 'direction'],
        [None, None, None, None, None, None, None, 'I', 'K']):
        collection.add_cached_array_to_imported_list(cached_array=array,
                                                     source_info='',
                                                     keyword=name,
                                                     discrete=discrete,
                                                     uom=None,
                                                     time_index=None,
                                                     null_value=None,
                                                     property_kind=kind,
                                                     facet_type=facet_type,
                                                     facet=facet,
                                                     realization=None)
        collection.write_hdf5_for_imported_list()
        collection.create_xml_for_imported_list_and_add_parts_to_model()
    model.store_epc()

    return model
Exemple #19
0
def test_gcs_property_inheritance(tmp_path):
    epc = os.path.join(tmp_path, 'gcs_prop_inherit.epc')

    model = rq.Model(epc,
                     new_epc=True,
                     create_basics=True,
                     create_hdf5_ext=True)

    # create a grid
    g = grr.RegularGrid(model, extent_kji=(5, 3, 3), dxyz=(10.0, 10.0, 1.0))
    g.write_hdf5()
    g.create_xml(title='unsplit grid')

    # define an L shaped (in plan view) fault
    j_faces = np.zeros((g.nk, g.nj - 1, g.ni), dtype=bool)
    j_faces[:, 0, 1:] = True
    i_faces = np.zeros((g.nk, g.nj, g.ni - 1), dtype=bool)
    i_faces[:, 1:, 0] = True
    gcs = rqf.GridConnectionSet(
        model,
        grid=g,
        j_faces=j_faces,
        i_faces=i_faces,
        feature_name='L fault',
        create_organizing_objects_where_needed=True,
        create_transmissibility_multiplier_property=False)
    # check that connection set has the right number of cell face pairs
    assert gcs.count == g.nk * ((g.nj - 1) + (g.ni - 1))

    #  create a transmissibility multiplier property
    tm = np.arange(gcs.count).astype(float)
    if gcs.property_collection is None:
        gcs.property_collection = rqp.PropertyCollection()
        gcs.property_collection.set_support(support=gcs)
    pc = gcs.property_collection
    pc.add_cached_array_to_imported_list(
        tm,
        'unit test',
        'TMULT',
        uom='Euc',  # actually a ratio of transmissibilities
        property_kind='transmissibility multiplier',
        local_property_kind_uuid=None,
        realization=None,
        indexable_element='faces')
    # write gcs which should also write property collection and create a local property kind
    gcs.write_hdf5()
    gcs.create_xml(write_new_properties=True)

    # check that a local property kind has materialised
    pk_uuid = model.uuid(obj_type='PropertyKind',
                         title='transmissibility multiplier')
    assert pk_uuid is not None

    # check that we can create a surface object for the gcs
    surf = gcs.surface()
    assert surf is not None
    t, _ = surf.triangles_and_points()
    assert t.shape == (2 * gcs.count, 3)

    # create a derived grid connection set using a layer range
    thin_gcs, thin_indices = gcs.filtered_by_layer_range(min_k0=1,
                                                         max_k0=3,
                                                         return_indices=True)
    assert thin_gcs is not None and thin_indices is not None
    assert thin_gcs.count == 3 * ((g.nj - 1) + (g.ni - 1))
    # inherit the transmissibility multiplier property
    thin_gcs.inherit_properties_for_selected_indices(gcs, thin_indices)
    thin_gcs.write_hdf5()
    thin_gcs.create_xml()  # by default will include write of new properties

    # check that the inheritance has worked
    assert thin_gcs.property_collection is not None and thin_gcs.property_collection.number_of_parts(
    ) > 0
    thin_pc = thin_gcs.property_collection
    tm_part = thin_pc.singleton(property_kind='transmissibility multiplier')
    assert tm_part is not None
    thin_tm = thin_pc.cached_part_array_ref(tm_part)
    assert thin_tm is not None and thin_tm.ndim == 1
    assert thin_tm.size == thin_gcs.count
    assert_array_almost_equal(thin_tm, tm[thin_indices])

    # check that get_combined...() method can execute using property collection
    b_a, i_a, f_a = gcs.get_combined_fault_mask_index_value_arrays(
        min_k=1, max_k=3, property_name='Transmissibility multiplier', ref_k=2)
    assert b_a is not None and i_a is not None and f_a is not None
    # check that transmissibility multiplier values have been sampled correctly from property array
    assert f_a.shape == (g.nj, g.ni, 2, 2)
    assert np.count_nonzero(
        np.isnan(f_a)) == 4 * g.nj * g.ni - 2 * ((g.nj - 1) + (g.ni - 1))
    assert np.nanmax(f_a) > np.nanmin(f_a)
    restore = np.seterr(all='ignore')
    assert np.all(np.logical_or(np.isnan(f_a), f_a >= np.nanmin(thin_tm)))
    assert np.all(np.logical_or(np.isnan(f_a), f_a <= np.nanmax(thin_tm)))
    np.seterr(**restore)
Exemple #20
0
def basic_regular_grid(model_test: Model) -> Grid:
    return grr.RegularGrid(model_test,
                           extent_kji=(2, 2, 2),
                           dxyz=(100.0, 50.0, 20.0),
                           as_irregular_grid=True)
Exemple #21
0
def aligned_regular_grid(model_test: Model) -> Grid:
    return grr.RegularGrid(model_test,
                           extent_kji=(2, 3, 4),
                           dxyz=(100.0, 50.0, 20.0))
Exemple #22
0
def test_pinchout_and_k_gap_gcs(tmp_path):
    epc = os.path.join(tmp_path, 'gcs_pinchout_k_gap.epc')
    model = rq.new_model(epc)

    # create a grid
    g = grr.RegularGrid(model,
                        extent_kji=(5, 5, 5),
                        dxyz=(100.0, 100.0, 10.0),
                        as_irregular_grid=True)
    # patch points to generate a pinchout
    p = g.points_cached
    assert p.shape == (6, 6, 6, 3)
    p[2, :3, :3] = p[1, :3, :3]
    # convert one layer to a K gap with pinchout
    p[4, 3:, 3:] = p[3, 3:, 3:]
    g.nk -= 1
    g.extent_kji = np.array((g.nk, g.nj, g.ni), dtype=int)
    g.k_gaps = 1
    g.k_gap_after_array = np.zeros(g.nk - 1, dtype=bool)
    g.k_gap_after_array[2] = True
    g._set_k_raw_index_array()
    g.write_hdf5()
    g.create_xml(title='pinchout k gap grid')
    model.store_epc()

    # reload the grid
    model = rq.Model(epc)
    grid = model.grid()
    assert grid is not None
    assert grid.k_gaps == 1
    assert tuple(grid.extent_kji) == (4, 5, 5)

    # create a pinchout connection set
    po_gcs = rqf.pinchout_connection_set(grid)
    assert po_gcs is not None
    po_gcs.write_hdf5()
    po_gcs.create_xml()
    po_uuid = po_gcs.uuid

    # create a K gap connection set
    kg_gcs = rqf.k_gap_connection_set(grid)
    assert kg_gcs is not None
    kg_gcs.write_hdf5()
    kg_gcs.create_xml()
    kg_uuid = kg_gcs.uuid

    model.store_epc()

    # re-open the model and load the connection sets
    model = rq.Model(epc)
    po_gcs = rqf.GridConnectionSet(model, uuid=po_uuid)
    assert po_gcs is not None
    po_gcs.cache_arrays()
    kg_gcs = rqf.GridConnectionSet(model, uuid=kg_uuid)
    assert kg_gcs is not None
    kg_gcs.cache_arrays()

    # check face pairs in the pinchout connection set
    assert po_gcs.count == 4
    assert po_gcs.cell_index_pairs.shape == (4, 2)
    assert po_gcs.face_index_pairs.shape == (4, 2)
    assert np.all(
        po_gcs.cell_index_pairs[:, 0] != po_gcs.cell_index_pairs[:, 1])
    assert np.all(
        po_gcs.face_index_pairs[:, 0] != po_gcs.cell_index_pairs[:, 1])
    assert np.all(
        np.logical_or(po_gcs.face_index_pairs == 0,
                      po_gcs.face_index_pairs == 1))
    for cell in po_gcs.cell_index_pairs.flatten():
        assert cell in [0, 1, 5, 6, 50, 51, 55, 56]
    assert np.all(
        np.abs(po_gcs.cell_index_pairs[:, 1] -
               po_gcs.cell_index_pairs[:, 0]) == 50)

    # check face pairs in K gap connection set
    assert kg_gcs.count == 4
    assert kg_gcs.cell_index_pairs.shape == (4, 2)
    assert kg_gcs.face_index_pairs.shape == (4, 2)
    assert np.all(
        kg_gcs.cell_index_pairs[:, 0] != kg_gcs.cell_index_pairs[:, 1])
    assert np.all(
        kg_gcs.face_index_pairs[:, 0] != kg_gcs.cell_index_pairs[:, 1])
    assert np.all(
        np.logical_or(kg_gcs.face_index_pairs == 0,
                      kg_gcs.face_index_pairs == 1))
    for cell in kg_gcs.cell_index_pairs.flatten():
        assert cell in [74, 73, 69, 68, 99, 98, 94, 93]
    assert np.all(
        np.abs(kg_gcs.cell_index_pairs[:, 1] -
               kg_gcs.cell_index_pairs[:, 0]) == 25)

    # test compact indices method
    ci = po_gcs.compact_indices()
    assert ci.shape == (4, 2)
    for cf in ci.flatten():
        assert cf in [1, 7, 31, 37, 300, 306, 330, 336]
    assert np.all(np.abs(ci[:, 1] - ci[:, 0]) == 299)

    # test write simulator method
    files = ('fault_ff.dat', 'fault_tf.dat', 'fault_ft.dat')
    both_sides = (False, True, False)
    minus = (False, False, True)
    for filename, inc_both_sides, use_minus in zip(files, both_sides, minus):
        dat_path = os.path.join(tmp_path, filename)
        po_gcs.write_simulator(dat_path,
                               include_both_sides=inc_both_sides,
                               use_minus=use_minus)
        assert os.path.exists(dat_path)