From 2bb4254461003a2614ea1f4688100a76b71bd313 Mon Sep 17 00:00:00 2001 From: Joeri van Engelen Date: Fri, 15 Nov 2024 11:04:53 +0100 Subject: [PATCH 01/10] Require subunit coord for upward- and downward resistance and add from_imod5_data method --- imod/msw/infiltration.py | 38 +++++++++++++++++++++--- imod/tests/test_msw/test_infiltration.py | 22 ++++++++++---- 2 files changed, 50 insertions(+), 10 deletions(-) diff --git a/imod/msw/infiltration.py b/imod/msw/infiltration.py index bf300761f..71dd24dc1 100644 --- a/imod/msw/infiltration.py +++ b/imod/msw/infiltration.py @@ -4,6 +4,12 @@ from imod.msw.fixed_format import VariableMetaData from imod.msw.pkgbase import MetaSwapPackage from imod.msw.regrid.regrid_schemes import InfiltrationRegridMethod +from imod.typing import GridDataArray +from imod.typing.grid import concat, ones_like + + +def _concat_subunits(arg1: GridDataArray, arg2: GridDataArray): + return concat([arg1, arg2], dim="subunit").assign_coords(subunit=[0, 1]) class Infiltration(MetaSwapPackage, IRegridPackage): @@ -19,11 +25,11 @@ class Infiltration(MetaSwapPackage, IRegridPackage): a subunit coordinate to describe different land uses. downward_resistance: array of floats (xr.DataArray) Describes the downward resisitance of SVAT units. Set to -9999.0 to make - MetaSWAP ignore this resistance. This array must not have a subunit + MetaSWAP ignore this resistance. This array must have a subunit coordinate. upward_resistance: array of floats (xr.DataArray) Describes the upward resistance of SVAT units. Set to -9999.0 to make - MetaSWAP ignore this resistance. This array must not have a subunit + MetaSWAP ignore this resistance. This array must have a subunit coordinate. bottom_resistance: array of floats (xr.DataArray) Describes the infiltration capacity of SVAT units. Set to -9999.0 to @@ -47,10 +53,12 @@ class Infiltration(MetaSwapPackage, IRegridPackage): "extra_storage_coefficient": VariableMetaData(8, 0.01, 1.0, float), } - _with_subunit = ("infiltration_capacity",) - _without_subunit = ( + _with_subunit = ( + "infiltration_capacity", "downward_resistance", "upward_resistance", + ) + _without_subunit = ( "bottom_resistance", "extra_storage_coefficient", ) @@ -74,3 +82,25 @@ def __init__( self.dataset["extra_storage_coefficient"] = extra_storage_coefficient self._pkgcheck() + + @classmethod + def from_imod5_data(cls, imod5_data) -> "Infiltration": + cap_data = imod5_data["cap"] + data = {} + # Use runon resistance as downward resistance, and runoff for downward + # resistance + key_mapping = { + "infiltration_capacity": "infiltration_capacity", + "downward_resistance": "runon_resistance", + "upward_resistance": "runoff_resistance", + } + for var_rename, var_key in key_mapping.items(): + data_ls = [ + cap_data[f"{landuse}_{var_key}"] for landuse in ["rural", "urban"] + ] + data[var_rename] = _concat_subunits(*data_ls) + + data["bottom_resistance"] = ones_like(data["downward_resistance"]) + data["extra_storage_coefficient"] = ones_like(data["downward_resistance"]) + + return cls(**data) diff --git a/imod/tests/test_msw/test_infiltration.py b/imod/tests/test_msw/test_infiltration.py index d3cb0a003..4a3253885 100644 --- a/imod/tests/test_msw/test_infiltration.py +++ b/imod/tests/test_msw/test_infiltration.py @@ -28,15 +28,25 @@ def setup_infiltration_package(subunit, y, x, dy, dx): ) downward_resistance = xr.DataArray( - np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]), - dims=("y", "x"), - coords={"y": y, "x": x, "dx": dx, "dy": dy}, + np.array( + [ + [[1.0, 2.0, 3.0], [nan, nan, nan], [7.0, 8.0, 9.0]], + [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [nan, nan, nan]], + ] + ), + dims=("subunit", "y", "x"), + coords={"subunit": subunit, "y": y, "x": x, "dx": dx, "dy": dy}, ) upward_resistance = xr.DataArray( - np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]), - dims=("y", "x"), - coords={"y": y, "x": x, "dx": dx, "dy": dy}, + np.array( + [ + [[1.0, 2.0, 3.0], [nan, nan, nan], [7.0, 8.0, 9.0]], + [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [nan, nan, nan]], + ] + ), + dims=("subunit", "y", "x"), + coords={"subunit": subunit, "y": y, "x": x, "dx": dx, "dy": dy}, ) bottom_resistance = xr.DataArray( From c48127031d0fc9e93073f6c505790ce0392ee154 Mon Sep 17 00:00:00 2001 From: Joeri van Engelen Date: Fri, 15 Nov 2024 11:08:52 +0100 Subject: [PATCH 02/10] Use concat_imod5 method --- imod/msw/infiltration.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/imod/msw/infiltration.py b/imod/msw/infiltration.py index 71dd24dc1..7f0ee04b0 100644 --- a/imod/msw/infiltration.py +++ b/imod/msw/infiltration.py @@ -4,12 +4,8 @@ from imod.msw.fixed_format import VariableMetaData from imod.msw.pkgbase import MetaSwapPackage from imod.msw.regrid.regrid_schemes import InfiltrationRegridMethod -from imod.typing import GridDataArray -from imod.typing.grid import concat, ones_like - - -def _concat_subunits(arg1: GridDataArray, arg2: GridDataArray): - return concat([arg1, arg2], dim="subunit").assign_coords(subunit=[0, 1]) +from imod.msw.utilities.common import concat_imod5 +from imod.typing.grid import ones_like class Infiltration(MetaSwapPackage, IRegridPackage): @@ -98,7 +94,7 @@ def from_imod5_data(cls, imod5_data) -> "Infiltration": data_ls = [ cap_data[f"{landuse}_{var_key}"] for landuse in ["rural", "urban"] ] - data[var_rename] = _concat_subunits(*data_ls) + data[var_rename] = concat_imod5(*data_ls) data["bottom_resistance"] = ones_like(data["downward_resistance"]) data["extra_storage_coefficient"] = ones_like(data["downward_resistance"]) From 6d2105b0574a4a31fb321a32024b4c781b3b9de4 Mon Sep 17 00:00:00 2001 From: Joeri van Engelen Date: Fri, 15 Nov 2024 11:10:40 +0100 Subject: [PATCH 03/10] Remove unused arg in docstring --- imod/msw/infiltration.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/imod/msw/infiltration.py b/imod/msw/infiltration.py index 7f0ee04b0..5e470b06f 100644 --- a/imod/msw/infiltration.py +++ b/imod/msw/infiltration.py @@ -34,9 +34,6 @@ class Infiltration(MetaSwapPackage, IRegridPackage): extra_storage_coefficient: array of floats (xr.DataArray) Extra storage coefficient of phreatic layer. This array must not have a subunit coordinate. - active: array of bools (xr.DataArray) - Describes whether SVAT units are active or not. This array must not have - a subunit coordinate. """ _file_name = "infi_svat.inp" From 7051df7781dc37793cefae9eb497b586128ec645 Mon Sep 17 00:00:00 2001 From: Joeri van Engelen Date: Fri, 15 Nov 2024 11:50:39 +0100 Subject: [PATCH 04/10] Remove line --- imod/tests/test_msw/test_ponding.py | 1 - 1 file changed, 1 deletion(-) diff --git a/imod/tests/test_msw/test_ponding.py b/imod/tests/test_msw/test_ponding.py index e7bb47e06..94f0d64d0 100644 --- a/imod/tests/test_msw/test_ponding.py +++ b/imod/tests/test_msw/test_ponding.py @@ -116,7 +116,6 @@ def test_from_imod5_data(): # Create cap data cap_data = {} mapping_ls = [ - ("rural_runoff_resistance", "runoff_resistance", 0), ("rural_runoff_resistance", "runoff_resistance", 0), ("urban_runoff_resistance", "runoff_resistance", 1), ("rural_runon_resistance", "runon_resistance", 0), From 747ffe9a3e8fa9ea52b426eef3098d0efb8b59c3 Mon Sep 17 00:00:00 2001 From: Joeri van Engelen Date: Fri, 15 Nov 2024 11:51:14 +0100 Subject: [PATCH 05/10] Add test for from_imod5_data --- imod/tests/test_msw/test_infiltration.py | 82 +++++++++++++----------- 1 file changed, 46 insertions(+), 36 deletions(-) diff --git a/imod/tests/test_msw/test_infiltration.py b/imod/tests/test_msw/test_infiltration.py index 4a3253885..a5cfdf1db 100644 --- a/imod/tests/test_msw/test_infiltration.py +++ b/imod/tests/test_msw/test_infiltration.py @@ -15,8 +15,15 @@ from imod.msw.fixed_format import format_fixed_width -def setup_infiltration_package(subunit, y, x, dy, dx): - infiltration_capacity = xr.DataArray( +def setup_infiltration_package(): + x = [1.0, 2.0, 3.0] + y = [3.0, 2.0, 1.0] + subunit = [0, 1] + dx = 1.0 + dy = 1.0 + + data = {} + data["infiltration_capacity"] = xr.DataArray( np.array( [ [[0.5, 0.5, 0.5], [nan, nan, nan], [1.0, 1.0, 1.0]], @@ -26,8 +33,7 @@ def setup_infiltration_package(subunit, y, x, dy, dx): dims=("subunit", "y", "x"), coords={"subunit": subunit, "y": y, "x": x, "dx": dx, "dy": dy}, ) - - downward_resistance = xr.DataArray( + data["downward_resistance"] = xr.DataArray( np.array( [ [[1.0, 2.0, 3.0], [nan, nan, nan], [7.0, 8.0, 9.0]], @@ -37,8 +43,7 @@ def setup_infiltration_package(subunit, y, x, dy, dx): dims=("subunit", "y", "x"), coords={"subunit": subunit, "y": y, "x": x, "dx": dx, "dy": dy}, ) - - upward_resistance = xr.DataArray( + data["upward_resistance"] = xr.DataArray( np.array( [ [[1.0, 2.0, 3.0], [nan, nan, nan], [7.0, 8.0, 9.0]], @@ -48,19 +53,16 @@ def setup_infiltration_package(subunit, y, x, dy, dx): dims=("subunit", "y", "x"), coords={"subunit": subunit, "y": y, "x": x, "dx": dx, "dy": dy}, ) - - bottom_resistance = xr.DataArray( + data["bottom_resistance"] = xr.DataArray( np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]), dims=("y", "x"), coords={"y": y, "x": x, "dx": dx, "dy": dy}, ) - - extra_storage_coefficient = xr.DataArray( + data["extra_storage_coefficient"] = xr.DataArray( np.array([[0.1, 0.2, 0.3], [0.4, 0.5, 0.6], [0.7, 0.8, 0.9]]), dims=("y", "x"), coords={"y": y, "x": x, "dx": dx, "dy": dy}, ) - svat = xr.DataArray( np.array( [ @@ -71,18 +73,9 @@ def setup_infiltration_package(subunit, y, x, dy, dx): dims=("subunit", "y", "x"), coords={"subunit": subunit, "y": y, "x": x, "dx": dx, "dy": dy}, ) - # fmt: on index = (svat != 0).values.ravel() - infiltration = Infiltration( - infiltration_capacity, - downward_resistance, - upward_resistance, - bottom_resistance, - extra_storage_coefficient, - ) - - return infiltration, svat, index + return data, svat, index @given( @@ -186,13 +179,8 @@ def test_write( def test_simple_model(fixed_format_parser): - x = [1.0, 2.0, 3.0] - y = [1.0, 2.0, 3.0] - subunit = [0, 1] - dx = 1.0 - dy = 1.0 - # fmt: off - infiltration, svat, index = setup_infiltration_package(subunit, y, x, dy, dx) + data, svat, index = setup_infiltration_package() + infiltration = Infiltration(**data) with tempfile.TemporaryDirectory() as output_dir: output_dir = Path(output_dir) @@ -215,20 +203,14 @@ def test_simple_model(fixed_format_parser): def test_regrid(): - x = [1.0, 2.0, 3.0] - y = [3.0, 2.0, 1.0] - subunit = [0, 1] - dx = 1.0 - dy = 1.0 - - infiltration, _, _ = setup_infiltration_package(subunit, y, x, dy, dx) + data, _, _ = setup_infiltration_package() + infiltration = Infiltration(**data) x = [1.0, 1.5, 2.0, 2.5, 3.0] y = [3.0, 2.5, 2.0, 1.5, 1.0] subunit = [0, 1] dx = 0.5 dy = 0.5 - # fmt: off new_grid = xr.DataArray( dims=("subunit", "y", "x"), coords={"subunit": subunit, "y": y, "x": x, "dx": dx, "dy": dy} @@ -239,3 +221,31 @@ def test_regrid(): regridded = infiltration.regrid_like(new_grid, regrid_context ) assert_almost_equal(regridded.dataset.coords["x"].values, x) assert_almost_equal(regridded.dataset.coords["y"].values, y) + + +def test_from_imod5_data(): + data_infiltration, _, _ = setup_infiltration_package() + expected_pkg = Infiltration(**data_infiltration) + cap_data = {} + mapping_ls = [ + ("rural_infiltration_capacity", "infiltration_capacity", 0), + ("urban_infiltration_capacity", "infiltration_capacity", 1), + ("rural_runoff_resistance", "runoff_resistance", 0), + ("urban_runoff_resistance", "runoff_resistance", 1), + ("rural_runon_resistance", "runon_resistance", 0), + ("urban_runon_resistance", "runon_resistance", 1), + ] + for cap_key, pkg_key, subunit_nr in mapping_ls: + cap_data[cap_key] = data_infiltration[pkg_key].sel(subunit=subunit_nr, drop=True) + + imod5_data = {"cap": cap_data} + actual_pkg = Infiltration.from_imod5_data(imod5_data) + + ones_vars = ["bottom_resistance", "extra_storage_coefficient"] + expected = expected_pkg.dataset.drop_vars(ones_vars) + actual = actual_pkg.dataset.drop_vars(ones_vars) + + xr.testing.assert_equal(actual, expected) + + for var in ones_vars: + assert (actual_pkg.dataset[var] == 1.0).all() From df6d526c1137a674ab97c9b78d6ac244e7a3f44a Mon Sep 17 00:00:00 2001 From: Joeri van Engelen Date: Fri, 15 Nov 2024 12:00:20 +0100 Subject: [PATCH 06/10] type annotate, and select subunit --- imod/msw/infiltration.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/imod/msw/infiltration.py b/imod/msw/infiltration.py index 5e470b06f..7b3eac716 100644 --- a/imod/msw/infiltration.py +++ b/imod/msw/infiltration.py @@ -5,6 +5,7 @@ from imod.msw.pkgbase import MetaSwapPackage from imod.msw.regrid.regrid_schemes import InfiltrationRegridMethod from imod.msw.utilities.common import concat_imod5 +from imod.typing import GridDataDict from imod.typing.grid import ones_like @@ -77,7 +78,7 @@ def __init__( self._pkgcheck() @classmethod - def from_imod5_data(cls, imod5_data) -> "Infiltration": + def from_imod5_data(cls, imod5_data: dict[str, GridDataDict]) -> "Infiltration": cap_data = imod5_data["cap"] data = {} # Use runon resistance as downward resistance, and runoff for downward @@ -93,7 +94,8 @@ def from_imod5_data(cls, imod5_data) -> "Infiltration": ] data[var_rename] = concat_imod5(*data_ls) - data["bottom_resistance"] = ones_like(data["downward_resistance"]) - data["extra_storage_coefficient"] = ones_like(data["downward_resistance"]) + like = data["downward_resistance"].isel(subunit=0, drop=True) + data["bottom_resistance"] = ones_like(like) + data["extra_storage_coefficient"] = ones_like(like) return cls(**data) From 35389bb051a559f7e636a637d3a4799e160bbb62 Mon Sep 17 00:00:00 2001 From: Joeri van Engelen Date: Fri, 15 Nov 2024 12:00:42 +0100 Subject: [PATCH 07/10] Fix tests --- imod/tests/test_msw/test_infiltration.py | 25 +++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/imod/tests/test_msw/test_infiltration.py b/imod/tests/test_msw/test_infiltration.py index a5cfdf1db..18108a605 100644 --- a/imod/tests/test_msw/test_infiltration.py +++ b/imod/tests/test_msw/test_infiltration.py @@ -13,9 +13,10 @@ ) from imod.msw import Infiltration from imod.msw.fixed_format import format_fixed_width +from imod.typing import GridDataDict -def setup_infiltration_package(): +def setup_infiltration_package() -> tuple[GridDataDict, xr.DataArray, np.ndarray]: x = [1.0, 2.0, 3.0] y = [3.0, 2.0, 1.0] subunit = [0, 1] @@ -111,8 +112,8 @@ def test_write( ): infiltration = Infiltration( xr.DataArray(infiltration_capacity).expand_dims(subunit=[0]), - xr.DataArray(downward_resistance), - xr.DataArray(upward_resistance), + xr.DataArray(downward_resistance).expand_dims(subunit=[0]), + xr.DataArray(upward_resistance).expand_dims(subunit=[0]), xr.DataArray(bottom_resistance), xr.DataArray(extra_storage_coefficient), ) @@ -213,12 +214,12 @@ def test_regrid(): dy = 0.5 new_grid = xr.DataArray( dims=("subunit", "y", "x"), - coords={"subunit": subunit, "y": y, "x": x, "dx": dx, "dy": dy} + coords={"subunit": subunit, "y": y, "x": x, "dx": dx, "dy": dy}, ) - new_grid.values[:,:,:] = 1 + new_grid.values[:, :, :] = 1 regrid_context = RegridderWeightsCache() - regridded = infiltration.regrid_like(new_grid, regrid_context ) + regridded = infiltration.regrid_like(new_grid, regrid_context) assert_almost_equal(regridded.dataset.coords["x"].values, x) assert_almost_equal(regridded.dataset.coords["y"].values, y) @@ -230,13 +231,15 @@ def test_from_imod5_data(): mapping_ls = [ ("rural_infiltration_capacity", "infiltration_capacity", 0), ("urban_infiltration_capacity", "infiltration_capacity", 1), - ("rural_runoff_resistance", "runoff_resistance", 0), - ("urban_runoff_resistance", "runoff_resistance", 1), - ("rural_runon_resistance", "runon_resistance", 0), - ("urban_runon_resistance", "runon_resistance", 1), + ("rural_runoff_resistance", "upward_resistance", 0), + ("urban_runoff_resistance", "upward_resistance", 1), + ("rural_runon_resistance", "downward_resistance", 0), + ("urban_runon_resistance", "downward_resistance", 1), ] for cap_key, pkg_key, subunit_nr in mapping_ls: - cap_data[cap_key] = data_infiltration[pkg_key].sel(subunit=subunit_nr, drop=True) + cap_data[cap_key] = data_infiltration[pkg_key].sel( + subunit=subunit_nr, drop=True + ) imod5_data = {"cap": cap_data} actual_pkg = Infiltration.from_imod5_data(imod5_data) From 09c32ca2da8d2c0a6b0d38f85f6c6f8d810d4643 Mon Sep 17 00:00:00 2001 From: Joeri van Engelen Date: Fri, 15 Nov 2024 13:50:04 +0100 Subject: [PATCH 08/10] Deactivate small resistances and add cases --- imod/msw/infiltration.py | 25 +++++++ imod/tests/test_msw/test_infiltration.py | 93 +++++++++++++++++------- 2 files changed, 91 insertions(+), 27 deletions(-) diff --git a/imod/msw/infiltration.py b/imod/msw/infiltration.py index 7b3eac716..830365681 100644 --- a/imod/msw/infiltration.py +++ b/imod/msw/infiltration.py @@ -1,5 +1,8 @@ +from textwrap import dedent + import xarray as xr +from imod.logging import LogLevel, logger from imod.mf6.interfaces.iregridpackage import IRegridPackage from imod.msw.fixed_format import VariableMetaData from imod.msw.pkgbase import MetaSwapPackage @@ -9,6 +12,26 @@ from imod.typing.grid import ones_like +def deactivate_small_resistances_in_data(data: GridDataDict): + """ + Deactivate cells where resistance smaller than 5 days are set to + -9999.0. + """ + message = dedent("""Detected cells with resistances smaller than 5.0 in {var}, set + to inactive""") + + for var in ["downward_resistance", "upward_resistance"]: + to_deactivate = data[var] < 5.0 + if to_deactivate.any(): + logger.log( + loglevel=LogLevel.WARNING, + message=message.format(var=var), + additional_depth=1, + ) + data[var] = data[var].where(~to_deactivate, -9999.0) + return data + + class Infiltration(MetaSwapPackage, IRegridPackage): """ This contains the infiltration data. @@ -94,6 +117,8 @@ def from_imod5_data(cls, imod5_data: dict[str, GridDataDict]) -> "Infiltration": ] data[var_rename] = concat_imod5(*data_ls) + data = deactivate_small_resistances_in_data(data) + like = data["downward_resistance"].isel(subunit=0, drop=True) data["bottom_resistance"] = ones_like(like) data["extra_storage_coefficient"] = ones_like(like) diff --git a/imod/tests/test_msw/test_infiltration.py b/imod/tests/test_msw/test_infiltration.py index 18108a605..b87940a88 100644 --- a/imod/tests/test_msw/test_infiltration.py +++ b/imod/tests/test_msw/test_infiltration.py @@ -1,12 +1,15 @@ import tempfile +from copy import deepcopy from pathlib import Path import numpy as np +import pytest import xarray as xr from hypothesis import given, settings from hypothesis.strategies import floats from numpy import nan from numpy.testing import assert_almost_equal, assert_equal +from pytest_cases import case, parametrize_with_cases from imod.mf6.utilities.regrid import ( RegridderWeightsCache, @@ -16,13 +19,40 @@ from imod.typing import GridDataDict -def setup_infiltration_package() -> tuple[GridDataDict, xr.DataArray, np.ndarray]: +@pytest.fixture(scope="function") +def coords_planar() -> dict: x = [1.0, 2.0, 3.0] y = [3.0, 2.0, 1.0] - subunit = [0, 1] dx = 1.0 dy = 1.0 + return {"y": y, "x": x, "dx": dx, "dy": dy} + + +@pytest.fixture(scope="function") +def coords_subunit(coords_planar: dict) -> dict: + coords_subunit = deepcopy(coords_planar) + coords_subunit["subunit"] = [0, 1] + return coords_subunit + + +@pytest.fixture(scope="function") +def svat_index(coords_subunit: dict) -> tuple[xr.DataArray, np.ndarray]: + svat = xr.DataArray( + np.array( + [ + [[0, 1, 0], [0, 0, 0], [0, 2, 0]], + [[0, 3, 0], [0, 4, 0], [0, 0, 0]], + ] + ), + dims=("subunit", "y", "x"), + coords=coords_subunit, + ) + index = (svat != 0).values.ravel() + return svat, index + +@pytest.fixture(scope="function") +def setup_infiltration_data(coords_planar, coords_subunit) -> GridDataDict: data = {} data["infiltration_capacity"] = xr.DataArray( np.array( @@ -32,7 +62,7 @@ def setup_infiltration_package() -> tuple[GridDataDict, xr.DataArray, np.ndarray ] ), dims=("subunit", "y", "x"), - coords={"subunit": subunit, "y": y, "x": x, "dx": dx, "dy": dy}, + coords=coords_subunit, ) data["downward_resistance"] = xr.DataArray( np.array( @@ -42,7 +72,7 @@ def setup_infiltration_package() -> tuple[GridDataDict, xr.DataArray, np.ndarray ] ), dims=("subunit", "y", "x"), - coords={"subunit": subunit, "y": y, "x": x, "dx": dx, "dy": dy}, + coords=coords_subunit, ) data["upward_resistance"] = xr.DataArray( np.array( @@ -52,31 +82,33 @@ def setup_infiltration_package() -> tuple[GridDataDict, xr.DataArray, np.ndarray ] ), dims=("subunit", "y", "x"), - coords={"subunit": subunit, "y": y, "x": x, "dx": dx, "dy": dy}, + coords=coords_subunit, ) data["bottom_resistance"] = xr.DataArray( np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]), dims=("y", "x"), - coords={"y": y, "x": x, "dx": dx, "dy": dy}, + coords=coords_planar, ) data["extra_storage_coefficient"] = xr.DataArray( np.array([[0.1, 0.2, 0.3], [0.4, 0.5, 0.6], [0.7, 0.8, 0.9]]), dims=("y", "x"), - coords={"y": y, "x": x, "dx": dx, "dy": dy}, + coords=coords_planar, ) - svat = xr.DataArray( - np.array( - [ - [[0, 1, 0], [0, 0, 0], [0, 2, 0]], - [[0, 3, 0], [0, 4, 0], [0, 0, 0]], - ] - ), - dims=("subunit", "y", "x"), - coords={"subunit": subunit, "y": y, "x": x, "dx": dx, "dy": dy}, - ) - index = (svat != 0).values.ravel() - return data, svat, index + return data + + +@case(tags="r_low") +def case_low_resistance(setup_infiltration_data: GridDataDict) -> GridDataDict: + return setup_infiltration_data + + +@case(tags="r_high") +def case_high_resistance(setup_infiltration_data: GridDataDict) -> GridDataDict: + data = setup_infiltration_data + data["downward_resistance"] += 10.0 + data["upward_resistance"] += 10.0 + return data @given( @@ -179,9 +211,10 @@ def test_write( ) -def test_simple_model(fixed_format_parser): - data, svat, index = setup_infiltration_package() - infiltration = Infiltration(**data) +@parametrize_with_cases("infiltration_data", cases=".", has_tag="r_low") +def test_simple_model(fixed_format_parser, svat_index, infiltration_data): + svat, index = svat_index + infiltration = Infiltration(**infiltration_data) with tempfile.TemporaryDirectory() as output_dir: output_dir = Path(output_dir) @@ -203,9 +236,9 @@ def test_simple_model(fixed_format_parser): ) -def test_regrid(): - data, _, _ = setup_infiltration_package() - infiltration = Infiltration(**data) +@parametrize_with_cases("infiltration_data", cases=".", has_tag="r_low") +def test_regrid(infiltration_data): + infiltration = Infiltration(**infiltration_data) x = [1.0, 1.5, 2.0, 2.5, 3.0] y = [3.0, 2.5, 2.0, 1.5, 1.0] @@ -224,9 +257,15 @@ def test_regrid(): assert_almost_equal(regridded.dataset.coords["y"].values, y) -def test_from_imod5_data(): - data_infiltration, _, _ = setup_infiltration_package() +@parametrize_with_cases("data_infiltration", cases=".") +def test_from_imod5_data(data_infiltration): expected_pkg = Infiltration(**data_infiltration) + # Deactivate cells which have a resistance lower than 5.0 + for var in ["upward_resistance", "downward_resistance"]: + da = expected_pkg.dataset[var] + to_deactivate = da < 5.0 + expected_pkg.dataset[var] = da.where(~to_deactivate, -9999.0) + cap_data = {} mapping_ls = [ ("rural_infiltration_capacity", "infiltration_capacity", 0), From 72effc484e0188247cc6e6ea576783b1a7e2b780 Mon Sep 17 00:00:00 2001 From: Joeri van Engelen Date: Fri, 15 Nov 2024 14:12:54 +0100 Subject: [PATCH 09/10] Update model fixture --- imod/tests/fixtures/msw_model_fixture.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imod/tests/fixtures/msw_model_fixture.py b/imod/tests/fixtures/msw_model_fixture.py index 3b7c73c80..1fcaf9015 100644 --- a/imod/tests/fixtures/msw_model_fixture.py +++ b/imod/tests/fixtures/msw_model_fixture.py @@ -226,8 +226,8 @@ def make_msw_model(): # %% Infiltration msw_model["infiltration"] = msw.Infiltration( infiltration_capacity=xr.full_like(area, 1.0), - downward_resistance=xr.full_like(msw_grid, -9999.0), - upward_resistance=xr.full_like(msw_grid, -9999.0), + downward_resistance=xr.full_like(area, -9999.0), + upward_resistance=xr.full_like(area, -9999.0), bottom_resistance=xr.full_like(msw_grid, -9999.0), extra_storage_coefficient=xr.full_like(msw_grid, 0.1), ) From a7a32a52e16835606407fb8e6f48275a9bc43317 Mon Sep 17 00:00:00 2001 From: Joeri van Engelen Date: Fri, 15 Nov 2024 14:22:36 +0100 Subject: [PATCH 10/10] Update changelog --- docs/api/changelog.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/api/changelog.rst b/docs/api/changelog.rst index 59642ac66..68ebc2591 100644 --- a/docs/api/changelog.rst +++ b/docs/api/changelog.rst @@ -7,6 +7,16 @@ The format is based on `Keep a Changelog`_, and this project adheres to `Semantic Versioning`_. +[Unreleased] +------------ + +Changed +~~~~~~~ + +- :class:`imod.msw.Infiltration`'s variables ``upward_resistance`` and + ``downward_resistance`` now require a ``subunit`` coordinate. + + [0.18.0] --------