def test_ecl_run(): """Test import an eclrun with dates and export to roff after a diff""" dates = [19991201, 20030101] rprops = ["PRESSURE", "SWAT"] gg = Grid(REEKROOT, fformat="eclipserun", restartdates=dates, restartprops=rprops) # get the property object: pres1 = gg.get_prop_by_name("PRESSURE_20030101") tsetup.assert_almostequal(pres1.values.mean(), 308.45, 0.001) pres1.to_file(os.path.join(TMPDIR, "pres1.roff")) pres2 = gg.get_prop_by_name("PRESSURE_19991201") if isinstance(pres2, GridProperty): pass logger.debug(pres1.values) logger.debug(pres2.values) pres1.values = pres1.values - pres2.values # logger.debug(pres1.values) # logger.debug(pres1) avg = pres1.values.mean() # ok checked in RMS: tsetup.assert_almostequal(avg, -26.073, 0.001) pres1.to_file(os.path.join(TMPDIR, "pressurediff.roff"), name="PRESSUREDIFF")
def test_refine_vertically_per_zone(tmpdir): """Do a grid refinement vertically, via a dict per zone.""" logger.info("Read grid...") grd_orig = Grid(EMEGFILE2) grd = grd_orig.copy() logger.info("Read grid... done, NLAY is {}".format(grd.nlay)) grd.to_file(join(tmpdir, "test_refined_by_dict_initial.roff")) logger.info("Subgrids before: %s", grd.get_subgrids()) zone = GridProperty(EMEZFILE2, grid=grd, name="Zone") logger.info("Zone values min max: %s %s", zone.values.min(), zone.values.max()) logger.info("Subgrids list: %s", grd.subgrids) refinement = {1: 4, 2: 2} grd.refine_vertically(refinement, zoneprop=zone) grd1s = grd.get_subgrids() logger.info("Subgrids after: %s", grd1s) grd.to_file(join(tmpdir, "test_refined_by_dict.roff")) grd = grd_orig.copy() grd.refine_vertically(refinement) # no zoneprop grd2s = grd.get_subgrids() logger.info("Subgrids after: %s", grd2s) assert list(grd1s.values()) == list(grd2s.values())
def test_import_restart(): """Import Restart""" g = Grid() g.from_file(GFILE1, fformat="egrid") x = GridProperties() names = ["PRESSURE", "SWAT"] dates = [19991201, 20010101] x.from_file(RFILE1, fformat="unrst", names=names, dates=dates, grid=g) # get the object pr = x.get_prop_by_name("PRESSURE_19991201") swat = x.get_prop_by_name("SWAT_19991201") logger.info(x.names) logger.info(swat.values3d.mean()) logger.info(pr.values3d.mean()) txt = "Average PRESSURE_19991201" assert pr.values.mean() == pytest.approx(334.52327, abs=0.0001), txt txt = "Average SWAT_19991201" assert swat.values.mean() == pytest.approx(0.87, abs=0.01), txt pr = x.get_prop_by_name("PRESSURE_20010101") logger.info(pr.values3d.mean()) txt = "Average PRESSURE_20010101" assert pr.values.mean() == pytest.approx(304.897, abs=0.01), txt
def test_get_adjacent_cells(tmp_path): """Get the cell indices for discrete value X vs Y, if connected.""" grid = Grid(EMEGFILE) actnum = grid.get_actnum() actnum.to_file(tmp_path / "emerald_actnum.roff") result = grid.get_adjacent_cells(actnum, 0, 1, activeonly=False) result.to_file(tmp_path / "emerald_adj_cells.roff")
def test_import_should_fail(): """Import INIT and UNRST Reek but ask for wrong name or date""" g = Grid() g.from_file(GFILE1, fformat="egrid") x = GridProperties() names = ["PORO", "NOSUCHNAME"] with pytest.raises(ValueError) as e_info: logger.warning(e_info) x.from_file(IFILE1, fformat="init", names=names, grid=g) rx = GridProperties() names = ["PRESSURE"] dates = [19991201, 19991212] # last date does not exist rx.from_file( RFILE1, fformat="unrst", names=names, dates=dates, grid=g, strict=(True, False) ) with pytest.raises(ValueError) as e_info: rx.from_file( RFILE1, fformat="unrst", names=names, dates=dates, grid=g, strict=(True, True), )
def test_banal7(xtgshow): """Create a simple property in a small grid box""" grd = Grid(BANAL7) assert grd.dimensions == (4, 2, 3) disc = GridProperty(BANAL7, name="DISC") assert disc.dimensions == (4, 2, 3) assert disc.values.mean() == pytest.approx(0.59091, abs=0.001) gprops = grd.get_gridquality_properties() mix = gprops.get_prop_by_name("minangle_sides") assert mix.values.mean() == pytest.approx(81.31036, abs=0.001) if xtgshow: lay = 2 layslice = xtgeo.plot.Grid3DSlice() layslice.canvas(title=f"Layer {lay}") layslice.plot_gridslice( grd, prop=mix, mode="layer", index=lay, window=None, linecolor="black", ) layslice.show()
def load_grid_to_dataframe(grid_path): """Get field grid characteristics/coordinates""" grid_path = Path(grid_path).with_suffix("") try: grid = Grid(grid_path, fformat="eclipserun") return grid.dataframe(activeonly=False) except OSError as err: raise OSError("A grid with .EGRID format is expected.") from err
def test_xyz_cell_corners(): """Test xyz variations.""" grd = Grid(DUALFIL1) allcorners = grd.get_xyz_corners() assert len(allcorners) == 24 assert allcorners[0].get_npvalues1d()[0] == 0.0 assert allcorners[23].get_npvalues1d()[-1] == 1001.0
def test_roffbin_import_v2stress(): """Test roff binary import ROFF using new API, comapre timing etc.""" t0 = xtg.timer() for _ino in range(100): grd1 = Grid() grd1.from_file(REEKFIL4) t1 = xtg.timer(t0) print("100 loops with ROXAPIV 2 took: ", t1)
def test_get_cell_corners(): """Get X Y Z for one cell as tuple""" grid = Grid(TESTFILE8A) clist = grid.get_xyz_cell_corners(ijk=(4, 4, 1)) logger.debug(clist) tsetup.assert_almostequal(clist[0], 457168.358886, 0.1)
def test_copy_grid(): """Copy a grid.""" grd = Grid(EMEGFILE2) grd2 = grd.copy() grd.to_file(join("TMP", "gcp1.roff")) grd2.to_file(join("TMP", "gcp2.roff")) assert cmp(join("TMP", "gcp1.roff"), join("TMP", "gcp2.roff")) is True
def test_copy_grid(): """Crop a grid.""" grd = Grid(EMEGFILE2) grd2 = grd.copy() grd.to_file(join('TMP', 'gcp1.roff')) grd2.to_file(join('TMP', 'gcp2.roff')) assert cmp(join('TMP', 'gcp1.roff'), join('TMP', 'gcp2.roff')) is True
def test_reduce_to_one_layer(): """Reduce grid to one layer""" logger.info("Read grid...") grd1 = Grid(EMEGFILE2) grd1.reduce_to_one_layer() assert grd1.nlay == 1
def test_import_should_warn(): """Import INIT and UNRST Reek but ask for wrong name or date""" g = Grid() g.from_file(GFILE1, fformat="egrid") rx = GridProperties() names = ['PRESSURE'] dates = [19991201, 19991212] # last date does not exist rx.from_file(RFILE1, fformat='unrst', names=names, dates=dates, grid=g)
def test_bulkvol(): """Test cell bulk volume calculation.""" grd = Grid(GRIDQC1) cellvol_rms = GridProperty(GRIDQC1_CELLVOL) bulk = grd.get_bulk_volume() logger.info("Sum this: %s", bulk.values.sum()) logger.info("Sum RMS: %s", cellvol_rms.values.sum()) assert bulk.values.sum() == pytest.approx(cellvol_rms.values.sum(), rel=0.001)
def test_ecl_run_all(): """Test import an eclrun with all dates and props.""" gg = Grid() gg.from_file( REEKROOT, fformat="eclipserun", initprops="all", restartdates="all", restartprops="all", ) assert len(gg.gridprops.names) == 287
def test_grid_to_from_grdecl_file_is_identity(tmp_path, grid): filepath = tmp_path / "grid.grdecl" grid.to_file(filepath, fformat="grdecl") grid_from_file = Grid().from_file(filepath, fformat="grdecl") assert grid.dimensions == grid_from_file.dimensions assert np.array_equal(grid.actnum_array, grid_from_file.actnum_array) for prop1, prop_from_file in zip(grid.get_xyz_corners(), grid_from_file.get_xyz_corners()): assert_allclose(prop1.get_npvalues1d(), prop_from_file.get_npvalues1d(), atol=1e-3)
def test_reverse_row_axis_dual(tmpdir): """Reverse axis for distorted but small grid""" grd = Grid(DUAL) assert grd.ijk_handedness == "left" grd.to_file(join(tmpdir, "dual_left.grdecl"), fformat="grdecl") cellcorners1 = grd.get_xyz_cell_corners((5, 1, 1)) grd.reverse_row_axis() assert grd.ijk_handedness == "right" grd.to_file(join(tmpdir, "dual_right.grdecl"), fformat="grdecl") cellcorners2 = grd.get_xyz_cell_corners((5, 3, 1)) assert cellcorners1[7] == cellcorners2[1]
def test_crop_grid_after_copy(): """Copy a grid, then crop and check number of active cells.""" logger.info("Read grid...") grd = Grid(EMEGFILE2) grd.describe() zprop = GridProperty(EMEZFILE2, name="Zone", grid=grd) grd.describe(details=True) logger.info(grd.dimensions) grd2 = grd.copy() grd2.describe(details=True) logger.info("GRD2 props: %s", grd2.props) assert grd.propnames == grd2.propnames logger.info("GRD2 number of active cells: %s", grd2.nactive) act = grd.get_actnum() logger.info(act.values.shape) logger.info("ZPROP: %s", zprop.values.shape) grd2.crop((1, 30), (40, 80), (23, 46)) grd2.describe(details=True)
def test_reverse_row_axis_box(tmpdir): """Crop a grid.""" grd = Grid() grd.create_box( origin=(1000, 4000, 300), increment=(100, 100, 2), dimension=(2, 3, 1), rotation=0, ) assert grd.ijk_handedness == "left" grd.to_file(join(tmpdir, "reverse_left.grdecl"), fformat="grdecl") grd.reverse_row_axis() assert grd.ijk_handedness == "right" grd.to_file(join(tmpdir, "reverse_right.grdecl"), fformat="grdecl")
def test_values_in_polygon(): """Test replace values in polygons""" xprop = GridProperty() logger.info("Import roff...") grid = Grid(TESTFILE5) xprop.from_file(TESTFILE1, fformat="roff", name="PORO", grid=grid) poly = Polygons(POLYFILE) xprop.geometry = grid xorig = xprop.copy() xprop.operation_polygons(poly, 99, inside=True) tsetup.assert_almostequal(xprop.values.mean(), 25.1788, 0.01) xp2 = xorig.copy() xp2.values *= 100 xp2.continuous_to_discrete() xp2.set_inside(poly, 44) xp2.dtype = np.uint8 xp2.set_inside(poly, 44) print(xp2.values) xp2.dtype = np.uint16 xp2.set_inside(poly, 44) print(xp2.values) xp3 = xorig.copy() xp3.values *= 100 print(xp3.values.mean()) xp3.dtype = np.float32 xp3.set_inside(poly, 44) print(xp3.values.mean()) tsetup.assert_almostequal(xp3.values.mean(), 23.40642788381048, 0.001)
def test_slice_plot_many_grid_layers(): """Loop over layers and produce both SVG and PNG files to file""" mygrid = Grid(USEFILE1) myprop = GridProperty(USEFILE2, grid=mygrid, name="PORO") nlayers = mygrid.nlay + 1 layslice2 = Grid3DSlice() for k in range(1, nlayers, 4): print("Layer {} ...".format(k)) layslice2.canvas(title="Porosity for layer " + str(k)) layslice2.plot_gridslice(mygrid, myprop, colormap=USEFILE3, index=k, minvalue=0.18, maxvalue=0.36) layslice2.savefig( os.path.join(TMPDIR, "layerslice2_" + str(k) + ".svg"), fformat="svg", last=False, ) layslice2.savefig( os.path.join(TMPDIR, "layerslice2_" + str(k) + ".png"))
def test_grdecl_import_reek(): """Property GRDECL import from Eclipse. Reek""" rgrid = Grid(TESTFILE12A, fformat="grdecl") assert rgrid.dimensions == (40, 64, 14) poro = GridProperty(TESTFILE12B, name="PORO", fformat="grdecl", grid=rgrid) poro2 = GridProperty(TESTFILE1, name="PORO", fformat="roff", grid=rgrid) tsetup.assert_almostequal(poro.values.mean(), poro2.values.mean(), 0.001) tsetup.assert_almostequal(poro.values.std(), poro2.values.std(), 0.001) with pytest.raises(KeywordNotFoundError): poro3 = GridProperty(TESTFILE12B, name="XPORO", fformat="grdecl", grid=rgrid) logger.debug("Keyword failed as expected for instance %s", poro3) # Export to ascii grdecl and import that again... exportfile = os.path.join(TMPDIR, "reekporo.grdecl") poro.to_file(exportfile, fformat="grdecl") porox = GridProperty(exportfile, name="PORO", fformat="grdecl", grid=rgrid) tsetup.assert_almostequal(poro.values.mean(), porox.values.mean(), 0.001) # Export to binary grdecl and import that again... exportfile = os.path.join(TMPDIR, "reekporo.bgrdecl") poro.to_file(exportfile, fformat="bgrdecl") porox = GridProperty(exportfile, name="PORO", fformat="bgrdecl", grid=rgrid) tsetup.assert_almostequal(poro.values.mean(), porox.values.mean(), 0.001)
def test_eclunrst_import_soil_reek(): """Property UNRST import from Eclipse, computing SOIL. Reek""" gg = Grid(TESTFILE5, fformat="egrid") logger.info("Import RESTART (UNIFIED) ...") swat = GridProperty(TESTFILE7, name="SWAT", fformat="unrst", date=19991201, grid=gg) tsetup.assert_almostequal(swat.values.mean(), 0.8780, 0.001) sgas = GridProperty(TESTFILE7, name="SGAS", fformat="unrst", date=19991201, grid=gg) tsetup.assert_almostequal(sgas.values.mean(), 0.000, 0.001) soil = GridProperty(TESTFILE7, name="SOIL", fformat="unrst", date=19991201, grid=gg) tsetup.assert_almostequal(soil.values.mean(), 1.0 - 0.8780, 0.001)
def test_import_should_pass(): """Import INIT and UNRST but ask for wrong name or date , using strict=False""" g = Grid() g.from_file(GFILE1, fformat="egrid") rx = GridProperties() names = ["PRESSURE", "DUMMY"] # dummy should exist dates = [19991201, 19991212] # last date does not exist rx.from_file( RFILE1, fformat="unrst", names=names, dates=dates, grid=g, strict=(False, False) ) assert "PRESSURE_19991201" in rx assert "PRESSURE_19991212" not in rx assert "DUMMY_19991201" not in rx
def test_roffbin_import_v2_emerald(): """Test roff binary import ROFF using new API, emerald""" t0 = xtg.timer() grd1 = Grid(EMEGFILE) tsetup.assert_equal(grd1.ncol, 70) print("V2: ", xtg.timer(t0))
def test_geometrics_reek(): """Import Reek and test geometrics.""" grd = Grid(REEKFILE, fformat="egrid") geom = grd.get_geometrics(return_dict=True, cellcenter=False) for key, val in geom.items(): logger.info("%s is %s", key, val) # compared with RMS info: tsetup.assert_almostequal(geom["xmin"], 456510.6, 0.1, "Xmin") tsetup.assert_almostequal(geom["ymax"], 5938935.5, 0.1, "Ymax") # cellcenter True: geom = grd.get_geometrics(return_dict=True, cellcenter=True) tsetup.assert_almostequal(geom["xmin"], 456620, 1, "Xmin cell center")
def test_slice_simple_layer(tmpdir, show_plot, generate_plot): """Trigger XSection class, and do some simple things basically.""" layslice = Grid3DSlice() mygrid = Grid(USEFILE1) myprop = GridProperty(USEFILE2, grid=mygrid, name="PORO") assert myprop.values.mean() == pytest.approx(0.1677, abs=0.001) wd = None # [457000, 464000, 1650, 1800] for lay in range(1, mygrid.nlay + 1): layslice.canvas(title="My Grid Layer plot for layer {}".format(lay)) layslice.plot_gridslice( mygrid, prop=myprop, mode="layer", index=lay, window=wd, linecolor="black", ) if show_plot: layslice.show() if generate_plot: layslice.savefig( os.path.join(tmpdir, "layerslice_" + str(lay) + ".png"))
def test_grdecl_import_reek(): """Property GRDECL import from Eclipse. Reek""" rgrid = Grid(testfile12a, fformat='grdecl') assert rgrid.dimensions == (40, 64, 14) poro = GridProperty(testfile12b, name='PORO', fformat='grdecl', grid=rgrid) poro2 = GridProperty(testfile1, name='PORO', fformat='roff', grid=rgrid) tsetup.assert_almostequal(poro.values.mean(), poro2.values.mean(), 0.001) tsetup.assert_almostequal(poro.values.std(), poro2.values.std(), 0.001) with pytest.raises(KeywordNotFoundError): poro3 = GridProperty(testfile12b, name='XPORO', fformat='grdecl', grid=rgrid) logger.debug('Keyword failed as expected for instance %s', poro3) # Export to ascii grdecl and import that again... exportfile = os.path.join(td, 'reekporo.grdecl') poro.to_file(exportfile, fformat='grdecl') porox = GridProperty(exportfile, name='PORO', fformat='grdecl', grid=rgrid) tsetup.assert_almostequal(poro.values.mean(), porox.values.mean(), 0.001) # Export to binary grdecl and import that again... exportfile = os.path.join(td, 'reekporo.bgrdecl') poro.to_file(exportfile, fformat='bgrdecl') porox = GridProperty(exportfile, name='PORO', fformat='bgrdecl', grid=rgrid) tsetup.assert_almostequal(poro.values.mean(), porox.values.mean(), 0.001)
def test_slice_simple_layer(): """Trigger XSection class, and do some simple things basically.""" layslice = Grid3DSlice() mygrid = Grid(USEFILE1) myprop = GridProperty(USEFILE2, grid=mygrid, name="PORO") assert myprop.values.mean() == pytest.approx(0.1677, abs=0.001) wd = None # [457000, 464000, 1650, 1800] for lay in range(1, mygrid.nlay + 1): layslice.canvas(title="My Grid Layer plot for layer {}".format(lay)) layslice.plot_gridslice(mygrid, prop=myprop, mode="layer", index=lay, window=wd) if XTGSHOW: layslice.show() else: print("Output to screen disabled (will plot to screen); " "use XTG_SHOW env variable") layslice.savefig( os.path.join(TMPDIR, "layerslice_" + str(lay) + ".png"))