diff --git a/python/tests/geometry_tests/test_cpolyline.py b/python/tests/geometry_tests/test_cpolyline.py index 9868ac91d..cdf737f71 100644 --- a/python/tests/geometry_tests/test_cpolyline.py +++ b/python/tests/geometry_tests/test_cpolyline.py @@ -144,6 +144,9 @@ def test_name(self): p2 = CPolyline(name="Poly2") self.assertEqual(p2.getName(), "Poly2") + p1 = CPolyline.createFromXYZFile(self.polyline1, name="poly") + self.assertEqual(p1.getName(), "poly") + def test_unzip(self): pl = CPolyline(init_points=[(0, 3), (1, 4), (2, 5)]) x, y = pl.unzip() diff --git a/python/tests/geometry_tests/test_geo_pointset.py b/python/tests/geometry_tests/test_geo_pointset.py index de0c4a6d4..49da25663 100644 --- a/python/tests/geometry_tests/test_geo_pointset.py +++ b/python/tests/geometry_tests/test_geo_pointset.py @@ -25,3 +25,10 @@ def test_getitem(self): gp = GeoPointset.fromSurface(srf) for i in (561, 1105, 1729, 2465, 2821): self.assertEqual(gp[i], srf[i]) + + def test_equal(self): + srf_path = self.createTestPath("local/geometry/surface/valid_ascii.irap") + srf = Surface(srf_path) + gp = GeoPointset.fromSurface(srf) + gp2 = GeoPointset.fromSurface(srf) + self.assertEqual(gp, gp2) diff --git a/python/tests/rd_tests/test_fault_blocks.py b/python/tests/rd_tests/test_fault_blocks.py index 44f1bebef..0fc5734c9 100644 --- a/python/tests/rd_tests/test_fault_blocks.py +++ b/python/tests/rd_tests/test_fault_blocks.py @@ -265,8 +265,11 @@ def test_fault_block_layer(self): l0 = layer[0] l1 = layer[1] self.assertTrue(isinstance(l1, FaultBlock)) + assert l1[0].i == 7 + assert l1[0].j == 0 l0.getCentroid() l1.getBlockID() + assert list(l1.get_region_list()) == [] with self.assertRaises(IndexError): l2 = layer[2] @@ -278,6 +281,10 @@ def test_fault_block_layer(self): l1 = layer.getBlock(1) self.assertTrue(isinstance(l1, FaultBlock)) + l1.add_cell(9, 9) + assert len(l1.get_global_index_list()) == len(l1) + polyline = Polyline(init_points=[(1.0, 0.0), (2.0, 1.0)]) + assert l1.contains_polyline(polyline) with self.assertRaises(KeyError): l = layer.getBlock(66) diff --git a/python/tests/rd_tests/test_geertsma.py b/python/tests/rd_tests/test_geertsma.py index 0485721cc..ce0846f70 100644 --- a/python/tests/rd_tests/test_geertsma.py +++ b/python/tests/rd_tests/test_geertsma.py @@ -1,4 +1,5 @@ import datetime +import pytest from resdata import ResDataType from resdata.resfile import ResdataKW, openFortIO, FortIO, ResdataFile from resdata.grid import Grid @@ -80,6 +81,7 @@ def test_geertsma_kernel(): subsidence = ResdataSubsidence(grid, init) subsidence.add_survey_PRESSURE("S1", restart_view1) + subsidence.add_survey_PRESSURE("S2", restart_view1) youngs_modulus = 5e8 poisson_ratio = 0.3 @@ -100,6 +102,10 @@ def test_geertsma_kernel(): ) np.testing.assert_almost_equal(dz, 5.8160298201497136e-08) + assert subsidence.eval( + "S1", "S2", receiver, youngs_modulus, poisson_ratio + ) == pytest.approx(0.0) + @staticmethod def test_geertsma_kernel_2_source_points_2_vintages(): grid = Grid.createRectangular(dims=(2, 1, 1), dV=(100, 100, 100)) diff --git a/python/tests/rd_tests/test_grav.py b/python/tests/rd_tests/test_grav.py index 149a64731..950cae643 100644 --- a/python/tests/rd_tests/test_grav.py +++ b/python/tests/rd_tests/test_grav.py @@ -1,10 +1,11 @@ -import time +import datetime from resdata import ResDataType from resdata.resfile import ResdataKW, ResdataFile, openFortIO, FortIO from resdata.grid import Grid from resdata.gravimetry import ResdataGrav from resdata.util.test import TestAreaContext from tests import ResdataTest +from resdata.rd_util import Phase class ResdataGravTest(ResdataTest): @@ -12,13 +13,89 @@ def setUp(self): self.grid = Grid.createRectangular((10, 10, 10), (1, 1, 1)) def test_create(self): - # The init file created here only contains a PORO field. More - # properties must be added to this before it can be used for - # any usefull gravity calculations. - poro = ResdataKW("PORO", self.grid.getGlobalSize(), ResDataType.RD_FLOAT) + + kws = [ + ResdataKW(kw, self.grid.getGlobalSize(), ResDataType.RD_FLOAT) + for kw in [ + "PORO", + "PORV", + "PRESSURE", + "SWAT", + "OIL_DEN", + "RPORV", + "PORV_MOD", + "FIPOIL", + "RFIPOIL", + ] + ] + int_kws = [ + ResdataKW(kw, self.grid.getGlobalSize(), ResDataType.RD_INT) + for kw in ["FIP_NUM", "PVTNUM"] + ] + + for kw in kws: + for i in range(self.grid.getGlobalSize()): + kw[i] = 0.5 + for kw in int_kws: + for i in range(self.grid.getGlobalSize()): + kw[i] = 0 + + kws += int_kws + with TestAreaContext("grav_init"): + with openFortIO("TEST.UNRST", mode=FortIO.WRITE_MODE) as f: + seq_hdr = ResdataKW("SEQNUM", 1, ResDataType.RD_FLOAT) + seq_hdr[0] = 10 + + header = ResdataKW("INTEHEAD", 67, ResDataType.RD_INT) + header[64] = 1 + header[65] = 1 + header[66] = 2000 + + seq_hdr.fwrite(f) + header.fwrite(f) + for kw in kws: + kw.fwrite(f) + + seq_hdr[0] = 20 + header[66] = 2009 + + seq_hdr.fwrite(f) + header.fwrite(f) + for kw in kws: + kw.fwrite(f) + + seq_hdr[0] = 20 + header[66] = 2010 + + seq_hdr.fwrite(f) + header.fwrite(f) + for kw in kws: + kw.fwrite(f) + + # The init file created here only contains a PORO field. More + # properties must be added to this before it can be used for + # any usefull gravity calculations. + header = ResdataKW("INTEHEAD", 95, ResDataType.RD_INT) + header[14] = 1 # sets phase to oil + header[94] = 100 # E100 with openFortIO("TEST.INIT", mode=FortIO.WRITE_MODE) as f: - poro.fwrite(f) + header.fwrite(f) + for kw in kws: + kw.fwrite(f) self.init = ResdataFile("TEST.INIT") grav = ResdataGrav(self.grid, self.init) + + restart_file = ResdataFile("TEST.UNRST") + restart_view = restart_file.restartView(sim_time=datetime.date(2000, 1, 1)) + + grav.new_std_density(1, 0.5) + grav.add_std_density(1, 0, 0.5) + + grav.add_survey_RPORV("rporv", restart_view) + grav.add_survey_PORMOD("pormod", restart_view) + grav.add_survey_FIP("fip", restart_view) + grav.add_survey_RFIP("fip", restart_view) + + grav.eval("rporv", "pormod", (0, 0, 0), phase_mask=1) diff --git a/python/tests/rd_tests/test_grid.py b/python/tests/rd_tests/test_grid.py index 7b20b9045..5dbb14f17 100644 --- a/python/tests/rd_tests/test_grid.py +++ b/python/tests/rd_tests/test_grid.py @@ -5,8 +5,9 @@ import six from numpy import linspace, allclose +import cwrap -from resdata.util.util import IntVector +from resdata.util.util import IntVector, DoubleVector from resdata import ResDataType, UnitSystem from resdata.resfile import ResdataKW, ResdataFile from resdata.grid import Grid @@ -222,13 +223,54 @@ def test_posXYEdge(self): def test_dims(self): grid = GridGen.createRectangular((10, 20, 30), (1, 1, 1)) + + self.assertTrue(grid.equal(grid)) + self.assertFalse(grid.dual_grid()) + self.assertEqual(grid.get_num_active_fracture(), 0) + self.assertEqual(grid.get_active_fracture_index(global_index=0), -1) + self.assertEqual( + grid.get_bounding_box_2d(), + ((0.0, 0.0), (10.0, 0.0), (10.0, 20.0), (0.0, 20.0)), + ) + self.assertEqual(grid.depth(ijk=(0, 0, 0)), 0.5) + self.assertEqual(grid.top(0, 0), 0.0) + self.assertEqual(grid.top_active(0, 0), 0.0) + self.assertEqual(grid.bottom(0, 0), 30.0) + self.assertEqual(grid.locate_depth(1.0, 0, 0), 1) + self.assertEqual(grid.find_cell(1.1, 0.0, 0.0), (1, 0, 0)) + self.assertTrue(grid.cell_regular(ijk=(1, 0, 0))) + self.assertEqual(grid.get_layer_xyz(1, 0), (1.0, 0.0, 0.0)) + self.assertEqual(grid.distance(0, 1), (-1.0, 0.0, 0.0)) + self.assertEqual(grid.get_num_lgr(), 0) + self.assertFalse(grid.has_lgr("lgr")) + self.assertEqual(grid.coarse_groups(), 0) + self.assertFalse(grid.in_coarse_group(ijk=(0, 0, 0))) + + with self.assertRaises(KeyError): + grid.get_lgr("lgr") + with self.assertRaises(KeyError): + grid.get_lgr(0) + with self.assertRaises(IndexError): + grid.get_cell_lgr(ijk=(0, 0, 0)) + self.assertEqual(grid.getNX(), 10) self.assertEqual(grid.getNY(), 20) self.assertEqual(grid.getNZ(), 30) + self.assertEqual(grid.nx, 10) + self.assertEqual(grid.ny, 20) + self.assertEqual(grid.nz, 30) self.assertEqual(grid.getGlobalSize(), 30 * 10 * 20) self.assertEqual(grid.getDims(), (10, 20, 30, 6000)) + def test_load_column(self): + column = DoubleVector(2 * 3 * 4) + grid = GridGen.createRectangular((2, 3, 4), (1, 1, 1)) + kw = ResdataKW("KW", 2 * 3 * 4, ResDataType.RD_DOUBLE) + kw[0] = 1.0 + grid.load_column(kw, 0, 0, column) + assert list(column) == [1.0, 0.0, 0.0, 0.0] + def test_create(self): with self.assertRaises(ValueError): grid = GridGen.createRectangular( @@ -683,3 +725,37 @@ def test_concvex_cell_containment(self): middle_point[2] = 30 for p in points[4:8:]: assertNotPoint(average(20 * [p] + [middle_point])) + + +def test_save_grdecl(tmpdir): + grid = GridGen.createRectangular((2, 3, 4), (1, 1, 1)) + with tmpdir.as_cwd(): + with cwrap.open("grid.grdecl", "w") as f: + grid.save_grdecl(f) + assert grid.equal(Grid.load_from_grdecl("grid.grdecl")) + assert grid.equal(Grid.load_from_file("grid.grdecl")) + + +def test_save_grid(tmpdir): + grid = GridGen.create_rectangular((2, 3, 4), (1, 1, 1)) + with tmpdir.as_cwd(): + grid.save_GRID("grid.GRID") + assert grid.equal(Grid("grid.GRID")) + + +def test_write_grdecl(tmpdir): + kw = ResdataKW("KW", 2 * 3 * 4, ResDataType.RD_DOUBLE) + grid = GridGen.create_rectangular((2, 3, 4), (1, 1, 1)) + + with tmpdir.as_cwd(): + with cwrap.open("kw.grdecl", "w") as f: + grid.write_grdecl(kw, f) + with cwrap.open("kw.grdecl", "r") as f: + kw2 = ResdataKW.read_grdecl(f, "KW") + + assert list(kw) == list(kw2) + + +def test_create_volume_keyword(): + grid = GridGen.create_rectangular((2, 3, 4), (1, 1, 1)) + assert list(grid.create_volume_keyword()) == [1.0] * (2 * 3 * 4) diff --git a/python/tests/rd_tests/test_region.py b/python/tests/rd_tests/test_region.py index 540bd17b0..23cdd0856 100644 --- a/python/tests/rd_tests/test_region.py +++ b/python/tests/rd_tests/test_region.py @@ -1,7 +1,8 @@ from resdata import ResDataType +import numpy as np +import pytest from resdata.resfile import ResdataKW from resdata.grid import Grid, ResdataRegion -from resdata.grid.faults import Layer from resdata.util.util import IntVector from tests import ResdataTest @@ -47,28 +48,206 @@ def test_sum(self): self.assertEqual(float_value.sum(mask=region), 1.0 * 49 * 50 / 2) self.assertEqual(bool_value.sum(mask=region), 50) - def test_truth_and_size(self): - actnum = IntVector(initial_size=100, default_value=0) - actnum[0:50] = 1 - grid = Grid.createRectangular((10, 10, 1), (1, 1, 1), actnum=actnum) - region = ResdataRegion(grid, False) - self.assertFalse(region) - self.assertEqual(0, region.active_size()) - self.assertEqual(0, region.global_size()) +@pytest.fixture +def actnum(): + actnum = IntVector(initial_size=100, default_value=0) + actnum[0:50] = 1 + return actnum - region.select_all() - self.assertTrue(region) - self.assertEqual(50, region.active_size()) - self.assertEqual(100, region.global_size()) - region.deselect_all() - self.assertFalse(region) - self.assertEqual(0, region.active_size()) - self.assertEqual(0, region.global_size()) +@pytest.fixture +def grid(actnum): + return Grid.create_rectangular((10, 10, 1), (1, 1, 1), actnum=actnum) - region = ResdataRegion(grid, False) - region.select_inactive() - self.assertTrue(region) - self.assertEqual(0, region.active_size()) - self.assertEqual(50, region.global_size()) + +@pytest.fixture +def empty_region(grid): + return ResdataRegion(grid, False) + + +def test_empty_region_has_size_zero(empty_region): + assert not empty_region + assert empty_region.active_size() == 0 + assert empty_region.global_size() == 0 + + +@pytest.fixture +def full_region(grid): + return ResdataRegion(grid, True) + + +def test_full_region_has_total_size(grid, full_region): + assert full_region + assert full_region.active_size() == grid.get_num_active() + assert full_region.global_size() == grid.get_global_size() + + +def test_full_region_has_selected_all(empty_region, full_region): + empty_region.select_all() + assert empty_region == full_region + + +def test_empty_region_has_deselected_all(empty_region, full_region): + full_region.deselect_all() + assert empty_region == full_region + + +@pytest.fixture +def inactive_region(empty_region): + inactive_region = empty_region.copy() + inactive_region.select_inactive() + return inactive_region + + +def test_inactive_region_size_agrees_with_grid(inactive_region, grid): + assert inactive_region.active_size() == 0 + assert inactive_region.global_size() == len(grid) - grid.get_num_active() + + +@pytest.fixture +def active_region(empty_region): + inactive_region = empty_region.copy() + inactive_region.select_active() + return inactive_region + + +def test_and_is_symmertic(active_region): + region = active_region + regionc = region.copy() + + assert region & region == region + region &= region + assert regionc == region + + +def test_or_is_symmertic(active_region): + region = active_region + regionc = region.copy() + + assert region | region == region + + region |= region + assert regionc == region + + +def test_union_is_symetric(active_region): + region = active_region + regionc = region.copy() + + region.union_with(region) + assert regionc == region + + +def test_intersection_is_symetric(active_region): + region = active_region + regionc = region.copy() + + region.intersect_with(region) + assert regionc == region + + +def test_minus_self_gives_empty(active_region, empty_region): + region = active_region + assert region - region == empty_region + region -= region + assert region == empty_region + + +def test_reset(active_region, empty_region): + empty_region.select_active() + assert empty_region == active_region + empty_region.reset() + assert empty_region != active_region + assert empty_region.global_size() == 0 + + +def test_plus_is_symmetric(active_region): + region = active_region + regionc = region.copy() + + assert region + region == region + region += region + assert region == regionc + + +@pytest.fixture +def actnum_kw(grid): + return grid.export_ACTNUM_kw() + + +def test_select_more_actnum_is_active_region(active_region, empty_region, actnum_kw): + empty_region.select_more(actnum_kw, 0) + assert empty_region == active_region + + +def test_select_equal_actnum_is_active_region(active_region, empty_region, actnum_kw): + empty_region.select_equal(actnum_kw, 1) + assert empty_region == active_region + + +def test_select_less_actnum_is_inactive_region( + inactive_region, empty_region, actnum_kw +): + empty_region.select_less(actnum_kw, 1) + assert empty_region == inactive_region + + +def test_deselect_more_actnum_is_inactive_region( + inactive_region, full_region, actnum_kw +): + full_region.deselect_more(actnum_kw, 0) + assert full_region == inactive_region + + +def test_deselect_less_actnum_is_active_region(active_region, full_region, actnum_kw): + full_region.deselect_less(actnum_kw, 1) + assert full_region == active_region + + +def test_deselect_equal_actnum_is_inactive_region( + inactive_region, full_region, actnum_kw +): + full_region.deselect_equal(actnum_kw, 1) + assert full_region == inactive_region + + +@pytest.fixture +def poro(grid): + return grid.create_kw( + np.ones((grid.nx, grid.ny, grid.nz), dtype=np.float32), "PORO", True + ) + + +def test_select_in_range(empty_region, active_region, poro): + empty_region.select_in_range(poro, 0.9, 1.1) + assert empty_region == active_region + + +def test_deselect_in_range(full_region, inactive_region, poro): + full_region.deselect_in_range(poro, 0.9, 1.1) + assert full_region == inactive_region + + +def test_less_than_self_is_empty(empty_region, poro): + cmp_less_region = empty_region.copy() + cmp_less_region.select_cmp_less(poro, poro) + assert cmp_less_region == empty_region + + +def test_deselect_less_than_self_is_same(active_region, poro): + cmp_less_region = active_region.copy() + cmp_less_region.deselect_cmp_less(poro, poro) + assert cmp_less_region == active_region + + +def test_more_than_self_is_empty(empty_region, poro): + cmp_more_region = empty_region.copy() + cmp_more_region.select_cmp_less(poro, poro) + assert cmp_more_region == empty_region + + +def test_deselect_more_than_self_is_same(active_region, poro): + cmp_more_region = active_region.copy() + cmp_more_region.deselect_cmp_less(poro, poro) + assert cmp_more_region == active_region