From 4e64adcf7f1d4b6246763b4f2d3cc99472071050 Mon Sep 17 00:00:00 2001 From: Eivind Jahren Date: Tue, 9 Apr 2024 10:21:58 +0200 Subject: [PATCH] Add more tests to check c calls --- python/resdata/util/test/mock/rd_sum_mock.py | 4 + python/tests/geometry_tests/test_cpolyline.py | 3 + .../tests/geometry_tests/test_geo_pointset.py | 7 ++ python/tests/rd_tests/create_restart.py | 44 +++++++++ python/tests/rd_tests/test_fault_blocks.py | 7 ++ python/tests/rd_tests/test_geertsma.py | 49 ++-------- python/tests/rd_tests/test_grav.py | 89 ++++++++++++++++-- python/tests/rd_tests/test_grdecl.py | 1 + python/tests/rd_tests/test_grid.py | 76 ++++++++++++++- python/tests/rd_tests/test_rd_file.py | 38 ++++++-- python/tests/rd_tests/test_rd_kw.py | 36 +++++++ python/tests/rd_tests/test_rd_util.py | 34 ++++++- python/tests/rd_tests/test_region.py | 16 +--- python/tests/rd_tests/test_restart_head.py | 30 +++++- python/tests/rd_tests/test_rft.py | 1 + python/tests/rd_tests/test_sum.py | 59 +++++++++++- test-data/local/ECLIPSE/simple/README.md | 7 ++ test-data/local/ECLIPSE/simple/SIMPLE.DATA | 59 ++++++++++++ test-data/local/ECLIPSE/simple/SIMPLE.EGRID | Bin 0 -> 39992 bytes test-data/local/ECLIPSE/simple/SIMPLE.SMSPEC | Bin 0 -> 1168 bytes test-data/local/ECLIPSE/simple/SIMPLE.UNRST | Bin 0 -> 187616 bytes test-data/local/ECLIPSE/simple/SIMPLE.UNSMRY | Bin 0 -> 1404 bytes 22 files changed, 488 insertions(+), 72 deletions(-) create mode 100644 python/tests/rd_tests/create_restart.py create mode 100644 test-data/local/ECLIPSE/simple/README.md create mode 100644 test-data/local/ECLIPSE/simple/SIMPLE.DATA create mode 100644 test-data/local/ECLIPSE/simple/SIMPLE.EGRID create mode 100644 test-data/local/ECLIPSE/simple/SIMPLE.SMSPEC create mode 100644 test-data/local/ECLIPSE/simple/SIMPLE.UNRST create mode 100644 test-data/local/ECLIPSE/simple/SIMPLE.UNSMRY diff --git a/python/resdata/util/test/mock/rd_sum_mock.py b/python/resdata/util/test/mock/rd_sum_mock.py index 86ff9cb4b3..0b9d13ad1a 100644 --- a/python/resdata/util/test/mock/rd_sum_mock.py +++ b/python/resdata/util/test/mock/rd_sum_mock.py @@ -48,6 +48,10 @@ def createSummary( for var in var_list: key = var.getKey1() + key2 = var.getKey2() + if key and key2: + assert var.keyword in key + assert var.keyword in key2 if key in func_table: func = func_table[key] diff --git a/python/tests/geometry_tests/test_cpolyline.py b/python/tests/geometry_tests/test_cpolyline.py index 9868ac91dc..cdf737f71a 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 de0c4a6d4e..49da256639 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/create_restart.py b/python/tests/rd_tests/create_restart.py new file mode 100644 index 0000000000..1dcea9b7fb --- /dev/null +++ b/python/tests/rd_tests/create_restart.py @@ -0,0 +1,44 @@ +from resdata import ResDataType +from resdata.resfile import ResdataKW, openFortIO, FortIO + + +def create_restart(grid, case, p1, p2=None, rporv1=None, rporv2=None): + with openFortIO("%s.UNRST" % case, mode=FortIO.WRITE_MODE) as f: + seq_hdr = ResdataKW("SEQNUM", 1, ResDataType.RD_FLOAT) + seq_hdr[0] = 10 + p = ResdataKW("PRESSURE", grid.getNumActive(), ResDataType.RD_FLOAT) + for i in range(len(p1)): + p[i] = p1[i] + + header = ResdataKW("INTEHEAD", 67, ResDataType.RD_INT) + header[64] = 1 + header[65] = 1 + header[66] = 2000 + + seq_hdr.fwrite(f) + header.fwrite(f) + p.fwrite(f) + + if rporv1: + rp = ResdataKW("RPORV", grid.getNumActive(), ResDataType.RD_FLOAT) + for idx, val in enumerate(rporv1): + rp[idx] = val + + rp.fwrite(f) + + if p2: + seq_hdr[0] = 20 + header[66] = 2010 + for i in range(len(p2)): + p[i] = p2[i] + + seq_hdr.fwrite(f) + header.fwrite(f) + p.fwrite(f) + + if rporv2: + rp = ResdataKW("RPORV", grid.getNumActive(), ResDataType.RD_FLOAT) + for idx, val in enumerate(rporv2): + rp[idx] = val + + rp.fwrite(f) diff --git a/python/tests/rd_tests/test_fault_blocks.py b/python/tests/rd_tests/test_fault_blocks.py index 44f1bebef7..0fc5734c96 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 0485721ccb..712541a653 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 @@ -6,6 +7,7 @@ from resdata.util.test import TestAreaContext from tests import ResdataTest +from tests.rd_tests.create_restart import create_restart import numpy as np @@ -22,48 +24,6 @@ def create_init(grid, case): porv.fwrite(f) -def create_restart(grid, case, p1, p2=None, rporv1=None, rporv2=None): - with openFortIO("%s.UNRST" % case, mode=FortIO.WRITE_MODE) as f: - seq_hdr = ResdataKW("SEQNUM", 1, ResDataType.RD_FLOAT) - seq_hdr[0] = 10 - p = ResdataKW("PRESSURE", grid.getNumActive(), ResDataType.RD_FLOAT) - for i in range(len(p1)): - p[i] = p1[i] - - header = ResdataKW("INTEHEAD", 67, ResDataType.RD_INT) - header[64] = 1 - header[65] = 1 - header[66] = 2000 - - seq_hdr.fwrite(f) - header.fwrite(f) - p.fwrite(f) - - if rporv1: - rp = ResdataKW("RPORV", grid.getNumActive(), ResDataType.RD_FLOAT) - for idx, val in enumerate(rporv1): - rp[idx] = val - - rp.fwrite(f) - - if p2: - seq_hdr[0] = 20 - header[66] = 2010 - for i in range(len(p2)): - p[i] = p2[i] - - seq_hdr.fwrite(f) - header.fwrite(f) - p.fwrite(f) - - if rporv2: - rp = ResdataKW("RPORV", grid.getNumActive(), ResDataType.RD_FLOAT) - for idx, val in enumerate(rporv2): - rp[idx] = val - - rp.fwrite(f) - - class GeertsmaTest(ResdataTest): @staticmethod def test_geertsma_kernel(): @@ -80,6 +40,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 +61,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 149a647315..950cae643a 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_grdecl.py b/python/tests/rd_tests/test_grdecl.py index 2d22a54892..f9e7c733af 100644 --- a/python/tests/rd_tests/test_grdecl.py +++ b/python/tests/rd_tests/test_grdecl.py @@ -16,6 +16,7 @@ def test_eclkw_read_grdecl(tmp_path): with cwrap.open(str(tmp_path / "test.grdecl")) as f: kw = ResdataKW.read_grdecl(f, "COORD") + assert ResdataKW.fseek_grdecl(f, "COORD", True) assert kw.get_name() == "COORD" assert len(kw.numpy_view()) == block_size * num_blocks diff --git a/python/tests/rd_tests/test_grid.py b/python/tests/rd_tests/test_grid.py index d360254a19..9ad7d4a2f2 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 @@ -223,13 +224,52 @@ def test_posXYEdge(self): def test_dims(self): grid = GridGen.createRectangular((10, 20, 30), (1, 1, 1)) self.assertEqual(grid.get_global_index1F(0), None) + 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( @@ -684,3 +724,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_rd_file.py b/python/tests/rd_tests/test_rd_file.py index ec699d0665..cf6bd70609 100644 --- a/python/tests/rd_tests/test_rd_file.py +++ b/python/tests/rd_tests/test_rd_file.py @@ -2,13 +2,14 @@ import datetime import os.path import gc -from unittest import skipIf from resdata import FileMode, ResDataType, FileType from resdata.resfile import ResdataFile, FortIO, ResdataKW, openFortIO, openResdataFile from resdata.util.util import CWDContext -from resdata.util.test import TestAreaContext, PathContext +from resdata.util.test import TestAreaContext +from resdata.grid import Grid from tests import ResdataTest +from tests.rd_tests.create_restart import create_restart def createFile(name, kw_list): @@ -53,12 +54,21 @@ def test_context(self): kw1.fwrite(f) kw2.fwrite(f) + self.assertFalse(ResdataFile.contains_report_step("TEST", 99)) + self.assertFalse( + ResdataFile.contains_sim_time("TEST", datetime.datetime(2024, 4, 4)) + ) with openResdataFile("TEST") as rd_file: + assert rd_file.iget_named_kw("KW1", 0).name == "KW1" self.assertEqual(len(rd_file), 2) self.assertTrue(rd_file.has_kw("KW1")) self.assertTrue(rd_file.has_kw("KW2")) + self.assertFalse(rd_file.has_report_step(99)) + self.assertFalse(rd_file.has_sim_time(datetime.datetime(2024, 4, 4))) self.assertEqual(rd_file[1], rd_file[-1]) + self.assertEqual(rd_file.iget_kw(0).name, "KW1") + def test_rd_index(self): with TestAreaContext("python/rd_file/context"): kw1 = ResdataKW("KW1", 100, ResDataType.RD_INT) @@ -209,7 +219,9 @@ def test_block_view(self): for i in range(5): view = rd_file.blockView("HEADER", i) + self.assertEqual(view.unique_size(), 3) self.assertEqual(len(view), 3) + self.assertEqual(view.unique_kw(), ["HEADER", "DATA1", "DATA2"]) header = view["HEADER"][0] data1 = view["DATA1"][0] data2 = view["DATA2"][0] @@ -233,7 +245,21 @@ def test_block_view(self): self.assertEqual(len(view), len(rd_file)) view = rd_file.blockView2(None, "DATA2", 0) - # self.assertEqual( len(view) , 2) - # self.assertTrue( "HEADER" in view ) - # self.assertTrue( "DATA1" in view ) - # self.assertFalse( "DATA2" in view ) + + +def test_report_list(tmpdir): + with tmpdir.as_cwd(): + grid = Grid.create_rectangular(dims=(1, 1, 1), dV=(50, 50, 50)) + create_restart(grid, "TEST", [1.0]) + assert ResdataFile.file_report_list("TEST.UNRST") == [10.0] + + with openResdataFile("TEST.UNRST") as rd_file: + assert rd_file.report_list == [10.0] + assert ( + rd_file.restart_get_kw("SEQNUM", datetime.datetime(2000, 1, 1)).name + == "SEQNUM" + ) + assert rd_file.iget_restart_sim_time(0) == datetime.datetime(2000, 1, 1) + assert rd_file.iget_restart_sim_days(1) == 0.0 + with openFortIO("TEST2.UNRST", FortIO.WRITE_MODE) as fortio: + rd_file.fwrite(fortio) diff --git a/python/tests/rd_tests/test_rd_kw.py b/python/tests/rd_tests/test_rd_kw.py index c99c0554e8..4ff7b17e82 100644 --- a/python/tests/rd_tests/test_rd_kw.py +++ b/python/tests/rd_tests/test_rd_kw.py @@ -352,11 +352,28 @@ def test_mul(self): for v in kw4: self.assertEqual(v, 12) + kw2 *= 2 + for v in kw2: + self.assertEqual(v, 4) + + def test_div(self): + kw1 = ResdataKW("Name1", 10, ResDataType.RD_DOUBLE) + kw1.assign(4.0) + kw2 = ResdataKW("Name1", 10, ResDataType.RD_DOUBLE) + kw2.assign(kw1) + + kw1.__idiv__(kw1) + for v in kw1: + self.assertEqual(v, 1.0) + self.assertNotEqual(kw1, kw2) + def test_numpy(self): kw1 = ResdataKW("DOUBLE", 10, ResDataType.RD_DOUBLE) view = kw1.numpyView() copy = kw1.numpyCopy() + kw2 = kw1.sub_copy(1, 3) + self.assertEqual(len(kw2), 3) self.assertTrue(copy[0] == kw1[0]) self.assertTrue(view[0] == kw1[0]) @@ -591,3 +608,22 @@ def test_fmu_stat_workflow(self): std_poro.safe_div(count) std_poro -= mean_poro * mean_poro std_poro.isqrt() + + +def test_iadd(): + kw1 = ResdataKW("KW1", 10, ResDataType.RD_INT) + kw2 = ResdataKW("KW2", 10, ResDataType.RD_INT) + for i in range(len(kw2)): + kw2[i] = 1 + + assert hash(kw1) != hash(kw2) + + kw1 += kw2 + + assert list(kw1) == list(kw2) + + +def test_get_ptr_data(): + assert ResdataKW("KW1", 10, ResDataType.RD_INT).get_data_ptr() + assert ResdataKW("KW1", 10, ResDataType.RD_FLOAT).get_data_ptr() + assert ResdataKW("KW1", 10, ResDataType.RD_DOUBLE).get_data_ptr() diff --git a/python/tests/rd_tests/test_rd_util.py b/python/tests/rd_tests/test_rd_util.py index 2845048aa4..1a2cf9ac09 100644 --- a/python/tests/rd_tests/test_rd_util.py +++ b/python/tests/rd_tests/test_rd_util.py @@ -1,5 +1,8 @@ +import pytest +import datetime +from textwrap import dedent + from resdata import FileType, ResdataTypeEnum, ResdataUtil -from resdata.grid import Grid from tests import ResdataTest @@ -18,3 +21,32 @@ def test_file_report_nr(self): with self.assertRaises(ValueError): ResdataUtil.reportStep("CASE.EGRID") + + +def test_num_cpu_from_data_file(tmp_path): + data_file = tmp_path / "dfile" + data_file_num_cpu = 4 + data_file.write_text( + dedent( + f"""\ + PARALLEL + {data_file_num_cpu} DISTRIBUTED/ + """ + ) + ) + assert ResdataUtil.get_num_cpu(str(data_file)) == 4 + + +def test_num_cpu_from_data_file_used_if_config_num_cpu_not_set(tmp_path): + data_file = tmp_path / "dfile" + data_file.write_text( + dedent( + f"""\ + START + 4 Apr 2024 / + """ + ) + ) + assert ResdataUtil.get_start_date(str(data_file)) == datetime.datetime( + 2024, 4, 4, 0, 0 + ) diff --git a/python/tests/rd_tests/test_region.py b/python/tests/rd_tests/test_region.py index 63d7a0b42c..efd7f0a388 100644 --- a/python/tests/rd_tests/test_region.py +++ b/python/tests/rd_tests/test_region.py @@ -432,12 +432,6 @@ def test_iadd_kw_empty(empty_region, poro): assert poro == poro_copy -def test_iadd_kw_full(full_region, poro): - poro_copy = poro.copy() - poro.add(poro, mask=full_region) - assert poro == poro_copy * 2 - - def test_iadd_kw_full(full_region, poro): poro_copy = poro.copy() poro.add(2.0, mask=full_region) @@ -476,7 +470,7 @@ def test_mul_kw_full(full_region, poro): assert list(poro) == [4.0] * len(poro) -def test_copy_kw(full_region, empty_region, poro, grid): +def test_copy_kw(full_region, poro, grid): poro_copy = grid.create_kw( np.zeros((grid.nx, grid.ny, grid.nz), dtype=np.float32), "PORO", True ) @@ -496,11 +490,11 @@ def test_contains_global(full_region): assert full_region.contains_global(0) -def test_contains_global(full_region): - assert full_region.contains_active(0) - - def test_get_set_name(full_region): full_region.set_name("full") assert full_region.get_name() == full_region.name assert full_region.get_name() == "full" + + +def test_contains_active(full_region): + assert full_region.contains_active(0) diff --git a/python/tests/rd_tests/test_restart_head.py b/python/tests/rd_tests/test_restart_head.py index a0c2836fed..2c7caae2c1 100644 --- a/python/tests/rd_tests/test_restart_head.py +++ b/python/tests/rd_tests/test_restart_head.py @@ -1,7 +1,8 @@ import datetime +import os.path -from tests import ResdataTest, equinor_test -from resdata import FileMode +from tests import ResdataTest, equinor_test, source_root +from resdata import FileMode, ResDataType from resdata.resfile import ( Resdata3DKW, ResdataKW, @@ -9,6 +10,7 @@ ResdataFile, FortIO, ) +from resdata.resfile.rd_restart_file import ResdataRestartHead from resdata.grid import Grid @@ -33,3 +35,27 @@ def test_headers(self): details = header.well_details() self.assertTrue("NXCONZ" in details) self.assertTrue("NCWMAX" in details) + + +def test_restart_headers(): + case_path = os.path.join( + source_root(), "test-data", "local", "ECLIPSE", "simple", "SIMPLE" + ) + g = Grid(case_path + ".EGRID") + f = ResdataRestartFile(g, case_path + ".UNRST") + + headers = f.headers() + assert len(headers) == 4 + header = headers[0] + assert header.get_report_step() == 1 + assert header.get_sim_date() == datetime.datetime(2017, 1, 16, 0, 0) + assert header.get_sim_days() == 15.0 + assert header.well_details() == {"NCWMAX": 0, "NXCONZ": 58} + + +def test_restart_headers_from_kw(): + intehead = ResdataKW("INTEHEAD", 100, ResDataType.RD_INT) + doubhead = ResdataKW("DOUBHEAD", 100, ResDataType.RD_DOUBLE) + logihead = ResdataKW("DOUBHEAD", 100, ResDataType.RD_BOOL) + header = ResdataRestartHead(kw_arg=(1, intehead, doubhead, logihead)) + assert header.get_report_step() == 1 diff --git a/python/tests/rd_tests/test_rft.py b/python/tests/rd_tests/test_rft.py index 7ffab89327..0aa92b0221 100644 --- a/python/tests/rd_tests/test_rft.py +++ b/python/tests/rd_tests/test_rft.py @@ -15,6 +15,7 @@ class RFTTest(ResdataTest): def test_create(self): rft = ResdataRFT("WELL", "RFT", datetime.date(2015, 10, 1), 100) self.assertEqual(len(rft), 0) + self.assertEqual(rft.get_well_name(), "WELL") with self.assertRaises(IndexError): cell = rft[5] diff --git a/python/tests/rd_tests/test_sum.py b/python/tests/rd_tests/test_sum.py index cc777eb032..9e4378a816 100644 --- a/python/tests/rd_tests/test_sum.py +++ b/python/tests/rd_tests/test_sum.py @@ -1,13 +1,12 @@ import csv import datetime -import inspect import os import os.path import shutil import stat +import datetime import cwrap -import pandas def assert_frame_equal(a, b): @@ -21,7 +20,6 @@ def assert_frame_equal(a, b): pass from contextlib import contextmanager -from unittest import skipIf, skipUnless from resdata import ResDataType, UnitSystem from resdata.resfile import FortIO, ResdataFile, ResdataKW, openFortIO @@ -179,11 +177,16 @@ def test_identify_var_type(self): node2 = case.smspec_node("AARQ:10") self.assertEqual(node2.varType(), SummaryVarType.RD_SMSPEC_AQUIFER_VAR) self.assertEqual(node2.getNum(), 10) + self.assertFalse(node2.isRate()) node3 = case.smspec_node("RGPT:1") self.assertEqual(node3.varType(), SummaryVarType.RD_SMSPEC_REGION_VAR) self.assertEqual(node3.getNum(), 1) + self.assertEqual(node3.default, 0) self.assertTrue(node3.isTotal()) + self.assertFalse(node3.isHistorical()) + + self.assertEqual(node3.keyword, "RGPT") self.assertLess(node1, node3) self.assertGreater(node2, node3) @@ -347,6 +350,7 @@ def test_kw_vector(self): num_mini_step=10, func_table={"FOPT": fopt, "FOPR": fopr, "FWPT": fgpt}, ) + self.assertEqual(case2.get_key_index("FOPR"), 1) kw_list = SummaryKeyWordVector(case1) kw_list.add_keyword("FOPT") @@ -587,6 +591,11 @@ def test_vector(self): s1 = sum([x.value for x in v1]) s2 = sum([x.value for x in v2]) + def test_wells_and_groups(self): + case = create_case() + self.assertEqual(case.wells(), []) + self.assertEqual(case.groups(), []) + def test_pandas(self): case = create_case() dates = ( @@ -752,3 +761,47 @@ def test_resample_extrapolate(self): resampled.iget(key_rate, time_index), rd_sum.get_interp_direct(key_rate, t), ) + + +def test_t_step(): + sum = createSummary( + "CASE", + [ + ("FOPT", None, 0, "SM3"), + ("FOPR", None, 0, "SM3/DAY"), + ("FGPT", None, 0, "SM3"), + ], + sim_length_days=100, + num_report_step=10, + num_mini_step=10, + sim_start=datetime.date(2010, 1, 1), + func_table={"FOPT": fopt, "FOPR": fopr, "FGPT": fgpt}, + ) + assert sum.path is None + + t_step = sum.add_t_step(11, 101) + assert t_step.get_report() == 11 + assert t_step.get_sim_days() == 101 + assert t_step.get_mini_step() == 10 * 10 + assert sum.iget_days(100) == 101 + assert "FOPT" in t_step + assert t_step["FOPT"] == 0.0 + t_step["FOPT"] = 100.0 + assert t_step["FOPT"] == 100.0 + assert t_step.get_sim_time().datetime() == datetime.datetime(2010, 4, 12, 0, 0) + + node = sum.get_last("FOPT") + assert node.days == 101 + assert sum.get_report(days=101) == 11 + + assert list(sum.get_interp_vector("FOPT", days_list=[1, 10, 20, 30, 101])) == [ + 1.0, + 10.0, + 20.0, + 30.0, + 100.0, + ] + + assert sum.get_from_report("FOPT", 11) == 100.0 + assert sum.first_gt_index("FOPT", 10) == 11 + assert sum.first_lt_index("FOPT", 10) == 0 diff --git a/test-data/local/ECLIPSE/simple/README.md b/test-data/local/ECLIPSE/simple/README.md new file mode 100644 index 0000000000..7d6dbef0b8 --- /dev/null +++ b/test-data/local/ECLIPSE/simple/README.md @@ -0,0 +1,7 @@ +This is a completely synthetic case with output created +by opm flow 2023.04 . It can be reproduced by [installing opm flow](https://opm-project.org) and +running + +```bash +flow SIMPLE.DATA +``` diff --git a/test-data/local/ECLIPSE/simple/SIMPLE.DATA b/test-data/local/ECLIPSE/simple/SIMPLE.DATA new file mode 100644 index 0000000000..69514aba78 --- /dev/null +++ b/test-data/local/ECLIPSE/simple/SIMPLE.DATA @@ -0,0 +1,59 @@ +RUNSPEC +START +1 JAN 2017 / + +DIMENS + 10 10 10 / +OIL +UNIFOUT +WATER +WELLDIMS + 0 / +EQLDIMS +/ +TABDIMS + 1* 1* 30 30 / +GRID + +SPECGRID + 10 10 10 1 F / +DX + 1000*1.0 / +DY + 1000*1.0 / +DZ + 1000*1.0 / +TOPS + 100*1.0 / +PORO + 1000*0.1 / +PERMX + 1000*150 / +PERMY + 1000*150 / +PERMZ + 1000*15 / +PROPS +SWOF + 0.0 0.0 1.0 0.0 + 1.0 1.0 0 0.0 / +DENSITY + 3*40 / +PVTW + 400 1 1.0E-06 1 0 / +PVTO + 0.001 15.0 1.0 0.1 / + 1.6 5000.0 1.8 0.5 + 9000.0 1.7 0.6 / +/ +SOLUTION +EQUIL + 3*1000 0 1000 0 0 0 0 / +SUMMARY +ALL +SCHEDULE +RPTRST + 'BASIC=2' 'ALLPROPS' / +TSTEP + 4*15 / +END diff --git a/test-data/local/ECLIPSE/simple/SIMPLE.EGRID b/test-data/local/ECLIPSE/simple/SIMPLE.EGRID new file mode 100644 index 0000000000000000000000000000000000000000..5a65973b4cec765ed3a2c8f2734c2fcf880a14a4 GIT binary patch literal 39992 zcmeI5L5|Zv5Jh`nfdmVD1NsQufVL(9B0)w9K|-uKh>yS#d=#Gowq9}!>VH?+r4cNG zG9aPfQp?|OYC7)n%S_B-D5Z3-5AXJG_x-Mv^5t+m@9o%?a`V-Wk4t&--H!Li&3&Nr zztI8SlkUywu={vCob44K-M;NlcC`Cdy7&9@Y5$?FBRJ}RbANFkpQdT?szaV!)XwGp z-rn7vc6Jx-_I^9<`**g4-QQ=QVyRa{q*D5qrNlXok-?jnfkh_w6LQbwR);}8FmnAi zE}7gj>!-v$lh28J2JaWl^&^wp?l7=^@0q-UIIj&tN#3mF_o%=kJo zxdmi$&*Vemp2^3=J(Ev~dnTU~_Y97`H=B6f$mCt(p2=(Cp20C%Th@sT9{a&DGPsql z^^wW#B-X(ZlYB_rGx?afXYwg=&*XFBp24~Imil0syxZ#WzKHATYvP_!kI{zI2g~5x zyYtB4t!(v?$?YW8VIPLn2g|VrYFIy}de7uj;-1Op#65$v4@2sMW%6#TXCH#s#66=P z13$BHofydAyl%@lMh0(XtB*`>C$SFuF#3Ln#67d#zP{FbCZ7`bOg<;>8Jv9>murkn z-fi{lgVm7N#65#!v}su@W2*N|J|*s%d`{dmIA5ovYqU(>ZT09wTu)yU_l$ZB)L~y3{2t@nyYtAr9uJ@2j6kmG1`-IH_w zY~6jny*nNGx%)-iK6gJKQLm{U$N@PZ2jsw|4z#lT?$l9zkOOi+4#)vHAP3~YbsQ+= z`G~20UZD_&kp_klml`=4#)vHAP4@~fysKO zsUFAyIUon*z=aO1&*>L_pMK})_pTg}19CtP(1F?dps60n0XZNCgm;bs?V$c-)DCIJ;!2yqft{mkOOi+4#)vHAP3}t9FPNY;DH^8=XCzfc>E1{P4z$y z$N@PZ2jqYpkOOi+4#IGVfE`2O#exr6Q2}NhYnST2ASt) zo*i2Ogb>p9!L&x#LWo=Pff9BPyMcYMFTELq_CbL^99!*yq-)hLEviK|YulNAR0{sC z=w}aJ!5#~Pn-)EjZ)T3p*CYI@=x+(AM=j1qdz4kD#ty^@8^-sHp5q~-V?JCl#~tSb zQ$8@|JDYXRvX1lIka?!+G_h`C-Nd?yb@7<>k@tzLkF1ZZk6Dj-7n(mdz3$AY;IHO? zdHUZM=3QX2KX-Jz3Vv0*Hy7}~UbLq?_cl;N@K@(i>pAs#eILi}nc7z0-~rk)ejp8O y8~<^BS??8}gGQ$3dcag?%To}yqQC9_D~@>=m`s0*S_k;s@0k88u)9xSx%OYl61Xe? literal 0 HcmV?d00001 diff --git a/test-data/local/ECLIPSE/simple/SIMPLE.UNRST b/test-data/local/ECLIPSE/simple/SIMPLE.UNRST new file mode 100644 index 0000000000000000000000000000000000000000..4b70934b9f90f5e842126d57c79ec229e9cae31c GIT binary patch literal 187616 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

)*rc zo?ib_^1U#B{$;;p#px2t!up|q?I&HRJ?%QH`fXRO>nG!CbzkFGzxsZ^d?2{)t39pO z>uECHq~EmTBYRgL+HPs6Iu_g$&)FI6>oYUaJhs}zfbKg@?!z%Z4{j~W(Vl8CSH=M@ zzVDuX@uPje2*iQb+SV~sZJLv26T6nV{$MTb$Lsj|Vo&ztb4_hioXyxwzD+juEo0Xj ztNdGLYfI)d{JGCX`8^qZm+h=$jD-x40Wv@atYo0Gj!H+g9d)IiLop0cwC6 zpa!S`YJeJ`2B-mQfEtMH-_6e*y6=UVJYf?DZy+B8IiLp28aRmagRqB#H<1s598d#h z4ZMZ(gCGagfLQ~FaDEW>aBvv;AS~e^zJE78cj)Qwf7(b`#ldFegRqB#dyo&p9uDqB zJ_vg_=s`XRdpPJtJ_vg_=tDjTdpLL)`5^4!pda}l?BQT5@IlKb_T6~@x>XO40gwSQKnBPF86X2>fDDiUGC&5%02v?yU|?bYZoYqA_lDhh zf*eo-)BrU=4NwEr05w1jPy^HeH9!qe1FNcm`2O8=|2jUSfX^tP2B-mQfEu6%r~zt# z8lVQK0cwC6paxc71G;}NjuvW_vi$ztaYk?}J5;WqR(y7JV#K#+N~7brznyQt4z7v9lFSxjq=jedOWC| z4EUcnZn-j43OwWR4U$WsRt9LHwFO2KFv6n{9{`%ox15-czHv8F$VQ<_%Bzh>_b#=M!SxuK8O?;rT&t3T_fF2C)C{P`LBN-TO`*$!eW8@84oq9@65~ z_o;Q-yhe6CUh78lKflswMswr3zSj9ChWE;sUhj{}XuxH-5rry&uE+_wc%>*T0l}FU+5R*)Lgfx`eW@e&}EONf&BQyUwb9+g0oO z$+%kG*Z9@1zTYn&2(J5TPpkEMnv6H;H|_Yy-qnY;TNk~s~3?sHLoPe$KmJL?!@Ap>N943GgU8R)Dd zEcf~7`rSD=oU4ir=-XB*mJ9ObszH&ta!hSJR~^S+Xwd%0-)A1FY%f;xmG0zyi@n#* zpCPQ`;9KN_AP3ZdSp#Qreh}n<8Zc|%9L^7d98d#h4Sa|5gCGag05xE}2K4`32K)CN zSMT4a?>OWUl5#)dxpa!S`YG6qk(EWR*R5m_$h`()J z{ol4S2h0IAKn+j>)BrU=4NwEr05w1jPy^IJZ2xY4?$CWN%;X81ICum3AjknVVAjAv zoF9Ze9K4Bq5afUwFl*o~oF4=^pa#quIE3?qu!n=g$OmBw2l4&8>A6EsfB(})!YU3n zBOio49NdF^5cY6zFY-ay!$A-7LD<7VFY-ay!$BYNLD<8=!^j6=4+s6o2VoBfTagdK z5)O3#K32uUh9;`T zfDDiUGC&5%02v?yWMI`9SXV~~F1GK+``4{{cnp9HkO4A42FL&zAOmE843GgbKnBPF z82|$d`*-vG>$*4W&J*N-8lVQK0cwC6pa!S`YJeJ`2B-mQfErj;4aE2Fru*0N83lYs x0X0AkPy^HeH9!qe1JnRDKn+j>)BrWG`Wn#vdvUZ-tCZ#U?~XHqTiKy<{~u&Cr^EmN literal 0 HcmV?d00001 diff --git a/test-data/local/ECLIPSE/simple/SIMPLE.UNSMRY b/test-data/local/ECLIPSE/simple/SIMPLE.UNSMRY new file mode 100644 index 0000000000000000000000000000000000000000..9b9a2e2729d1afdf568f8b3118fac8320dae7c0e GIT binary patch literal 1404 zcmZQzU=Rp)4fJpcQcz%EU|{t03vmU~0zk|H;zMZxUr#^J;1JgUkQka8pb%KCK!9VA zqi-jThVD+ZOn;BkS+U#x`u_IUNE3_M3pd literal 0 HcmV?d00001