diff --git a/tests/conftest.py b/tests/conftest.py index 6147833..5659398 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -6,10 +6,14 @@ # grid-apps is distributed under the terms and conditions of the MIT License ' # (see LICENSE file at the root of this source code package). ' # ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' +from __future__ import annotations import numpy as np import pytest from discretize.utils import mesh_builder_xyz +from geoh5py.objects import BlockModel, Grid2D, Points + +from grid_apps.block_models.driver import Driver as BlockModelDriver @pytest.fixture @@ -62,3 +66,39 @@ def setup_test_octree(diagonal_balance=False): treemesh, params_dict, ) + + +def setup_block_model( + workspace, + *, + top=200, + depth_core=300.0, + pads=(100, 150, 200, 300, 0, 0), + cell_size=(50, 50, 50), + expansion_factor=1.1, +) -> BlockModel: + # padding in the W/E/N/S directions should create locations at least as + # far as the core hull plus the padding distances + height = 300 + width = 1000 + n = 11 + x_grid, y_grid = np.meshgrid(np.linspace(0, width, n), np.linspace(0, height, n)) + z_grid = np.around((top / 2) * np.sin(x_grid) + (top / 2), -1) + locs = np.c_[x_grid.ravel(), y_grid.ravel(), z_grid.ravel()] + Points.create(workspace, vertices=locs) + mesh = BlockModelDriver.get_block_model( + workspace, locs, cell_size, depth_core, pads, expansion_factor, name="test" + ) + return mesh + + +def setup_grid2d_model(workspace) -> Grid2D: + mesh = Grid2D.create( + workspace, + origin=[0, 0, 0], + u_cell_size=50.0, + v_cell_size=50.0, + u_count=10, + v_count=15, + ) + return mesh diff --git a/tests/run_tests/block_model_test.py b/tests/run_tests/block_model_test.py index 9c53949..858da0b 100644 --- a/tests/run_tests/block_model_test.py +++ b/tests/run_tests/block_model_test.py @@ -12,79 +12,83 @@ from pathlib import Path import numpy as np +from geoh5py.objects import Points from geoh5py.workspace import Workspace -from grid_apps.block_models.driver import Driver as BlockModelDriver +from tests.conftest import setup_block_model def test_get_block_model(tmp_path: Path): # pylint: disable=too-many-locals # padding in the W/E/N/S directions should make create locs at least as # far as the core hull plus the padding distances - top = 500 - depth_core = 300.0 - height = 300 - width = 1000 - n = 100 - x_grid, y_grid = np.meshgrid(np.arange(0, width, n), np.arange(0, height, n)) - z_grid = np.around((top / 2) * np.sin(x_grid) + (top / 2), -1) - locs = np.c_[x_grid.ravel(), y_grid.ravel(), z_grid.ravel()] pads = [100, 150, 200, 300, 0, 0] - ws = Workspace(tmp_path / "block_model.geoh5") - obj = BlockModelDriver.get_block_model( - ws, locs, [50, 50, 50], depth_core, pads, 1.1, name="test" - ) - assert (obj.origin["z"] + obj.z_cell_delimiters).max() == top - assert obj.origin["x"] < -pads[0] - assert obj.origin["y"] < -pads[2] - assert obj.u_cell_delimiters.max() >= locs[:, 0].max() + pads[1] + pads[0] # type: ignore - assert obj.v_cell_delimiters.max() >= locs[:, 1].max() + pads[3] + pads[2] # type: ignore + top = 500 + with Workspace(tmp_path / f"{__name__}.geoh5") as ws: + grid = setup_block_model( + ws, + top=top, + depth_core=300.0, + pads=pads, + ) + points: Points = ws.get_entity("Points")[0] + + assert (grid.origin["z"] + grid.z_cell_delimiters).max() == top + assert grid.origin["x"] <= points.vertices[:, 0].min() - pads[0] + assert grid.origin["y"] <= points.vertices[:, 1].min() - pads[2] + assert ( + grid.u_cell_delimiters.max() + >= points.vertices[:, 0].max() + pads[0] + pads[1] + ) # type: ignore + assert ( + grid.v_cell_delimiters.max() + >= points.vertices[:, 1].max() + pads[2] + pads[3] + ) # type: ignore + +def test_padding(tmp_path: Path): # padding in the down direction should create locs at least as deep as the top # minus the sum of depth_core, h[2], and bottom padding. top = 500 - depth_core = 300.0 - height = 300 - width = 1000 - n = 100 - - x_grid, y_grid = np.meshgrid(np.arange(0, width, n), np.arange(0, height, n)) - z_grid = np.around((top / 2) * np.sin(x_grid) + (top / 2), -1) - locs = np.c_[x_grid.ravel(), y_grid.ravel(), z_grid.ravel()] pads = [0, 0, 0, 0, 100, 0] # padding on the bottom - h = [50, 50, 50] + depth_core = 300.0 + cell_size = (50, 50, 50) + with Workspace(tmp_path / f"{__name__}.geoh5") as ws: + grid = setup_block_model( + ws, + top=top, + depth_core=depth_core, + pads=pads, + cell_size=cell_size, + ) - obj = BlockModelDriver.get_block_model( - ws, locs, h, depth_core, pads, 1.1, name="test2" - ) + depth_delimiters = grid.origin["z"] + grid.z_cell_delimiters + assert top - (depth_core + cell_size[2] + pads[4]) >= np.min(depth_delimiters) - assert top - (depth_core + h[2] + pads[4]) >= np.min( - obj.origin["z"] + obj.z_cell_delimiters - ) +def test_padding_up_to(tmp_path: Path): # padding in the up direction should shift the origin so that the core area # envelopes the locs (adjusted by depth_core). top = 500 + pads = [0, 0, 0, 0, 0, 100] # padding on the bottom depth_core = 300.0 - height = 300 - width = 1000 - n = 100 - expansion_rate = 1.1 - - x_grid, y_grid = np.meshgrid(np.arange(0, width, n), np.arange(0, height, n)) - z_grid = np.around((top / 2) * np.sin(x_grid) + (top / 2), -1) - locs = np.c_[x_grid.ravel(), y_grid.ravel(), z_grid.ravel()] - pads = [0, 0, 0, 0, 0, 100] # padding on the top - h = [50, 50, 50] - - obj = BlockModelDriver.get_block_model( - ws, locs, h, depth_core, pads, expansion_rate, name="test2" - ) + expansion_factor = 1.1 + cell_size = (50, 50, 50) + with Workspace(tmp_path / f"{__name__}.geoh5") as ws: + grid = setup_block_model( + ws, + top=top, + depth_core=depth_core, + pads=pads, + expansion_factor=expansion_factor, + cell_size=cell_size, + ) - assert obj.origin["z"] >= top + pads[-1] - depth_delimiters = obj.origin["z"] + obj.z_cell_delimiters - core_top_ind = np.argwhere(depth_delimiters == 500).flatten()[0] - assert np.abs(np.diff(depth_delimiters))[core_top_ind] == h[2] - assert np.isclose( - np.abs(np.diff(depth_delimiters))[core_top_ind - 1], h[2] * expansion_rate - ) + assert grid.origin["z"] >= top + pads[-1] + depth_delimiters = grid.origin["z"] + grid.z_cell_delimiters + core_top_ind = np.argwhere(depth_delimiters == 500).flatten()[0] + assert np.abs(np.diff(depth_delimiters))[core_top_ind] == cell_size[2] + assert np.isclose( + np.abs(np.diff(depth_delimiters))[core_top_ind - 1], + cell_size[2] * expansion_factor, + ) diff --git a/tests/run_tests/grid_model_merger_test.py b/tests/run_tests/grid_model_merger_test.py index 35db3b5..92b66fd 100644 --- a/tests/run_tests/grid_model_merger_test.py +++ b/tests/run_tests/grid_model_merger_test.py @@ -17,42 +17,11 @@ from geoh5py.workspace import Workspace from pytest import mark -from grid_apps.block_models.driver import Driver as BlockModelDriver from grid_apps.grid_model_merger.driver import Driver from grid_apps.grid_model_merger.options import GridModelMergerOptions from grid_apps.octree_creation.driver import OctreeDriver from grid_apps.octree_creation.options import OctreeOptions - - -def setup_block_model(workspace) -> BlockModel: - # padding in the W/E/N/S directions should make create locs at least as - # far as the core hull plus the padding distances - top = 200 - depth_core = 300.0 - height = 300 - width = 1000 - n = 100 - - x_grid, y_grid = np.meshgrid(np.arange(0, width, n), np.arange(0, height, n)) - z_grid = np.around((top / 2) * np.sin(x_grid) + (top / 2), -1) - locs = np.c_[x_grid.ravel(), y_grid.ravel(), z_grid.ravel()] - pads = [100, 150, 200, 300, 0, 0] - mesh = BlockModelDriver.get_block_model( - workspace, locs, [50, 50, 50], depth_core, pads, 1.1, name="test" - ) - return mesh - - -def setup_grid2d_model(workspace) -> Grid2D: - mesh = Grid2D.create( - workspace, - origin=[0, 0, 0], - u_cell_size=50.0, - v_cell_size=50.0, - u_count=10, - v_count=15, - ) - return mesh +from tests.conftest import setup_block_model, setup_grid2d_model def setup_octree(workspace, locations, refinement, params_dict) -> Octree: @@ -101,7 +70,7 @@ def test_merge_block_model(tmp_path: Path): # pylint: disable=too-many-locals out_grid = driver.run() merged_model = out_grid.children[0] - np.testing.assert_almost_equal(merged_model.values[3406], 1.5, decimal=1) + np.testing.assert_almost_equal(merged_model.values[3937], 1.5, decimal=1) # Repeat with a hole in the first model values = model_a.values @@ -110,7 +79,7 @@ def test_merge_block_model(tmp_path: Path): # pylint: disable=too-many-locals out_grid = driver.run() merged_model = out_grid.children[0] - np.testing.assert_almost_equal(merged_model.values[3406], 2.0, decimal=1) + np.testing.assert_almost_equal(merged_model.values[3937], 2.0, decimal=1) def test_merge_all_nan(tmp_path: Path, caplog): # pylint: disable=too-many-locals