From a7b4097edf8afdb543b99e4c5185aa3f1f9daf3c Mon Sep 17 00:00:00 2001 From: wpbonelli Date: Tue, 3 Jun 2025 21:58:13 -0400 Subject: [PATCH] work on custom unstructuring oc perioddata --- flopy4/mf6/codec/__init__.py | 29 ++++++++--- flopy4/mf6/codec/converter.py | 85 ++++++++++++++++++++++++++++--- flopy4/mf6/component.py | 3 ++ flopy4/mf6/filters.py | 22 +------- flopy4/mf6/gwf/oc.py | 73 ++++++++++++++++++++++++++ flopy4/mf6/spec.py | 21 +++++++- flopy4/mf6/templates/macros.jinja | 43 ++++++++-------- pixi.lock | 32 ++++++------ test/test_codec.py | 3 +- uv.lock | 2 +- 10 files changed, 238 insertions(+), 75 deletions(-) diff --git a/flopy4/mf6/codec/__init__.py b/flopy4/mf6/codec/__init__.py index a177a20b..c5f3faba 100644 --- a/flopy4/mf6/codec/__init__.py +++ b/flopy4/mf6/codec/__init__.py @@ -8,17 +8,22 @@ from jinja2 import Environment, PackageLoader from flopy4.mf6 import filters -from flopy4.mf6.codec.converter import structure_array, unstructure_array +from flopy4.mf6.codec.converter import ( + structure_array, + unstructure_array, + unstructure_component, + unstructure_oc, +) +from flopy4.mf6.spec import get_blocks _JINJA_ENV = Environment( loader=PackageLoader("flopy4.mf6"), trim_blocks=True, lstrip_blocks=True, ) -_JINJA_ENV.filters["blocks"] = filters.blocks +_JINJA_ENV.filters["blocks"] = get_blocks _JINJA_ENV.filters["field_type"] = filters.field_type _JINJA_ENV.filters["field_value"] = filters.field_value -_JINJA_ENV.filters["is_list"] = filters.is_list _JINJA_ENV.filters["array_how"] = filters.array_how _JINJA_ENV.filters["array_chunks"] = filters.array_chunks _JINJA_ENV.filters["array2string"] = filters.array2string @@ -31,10 +36,20 @@ "threshold": sys.maxsize, } -_CONVERTER = Converter() -_CONVERTER.register_unstructure_hook_factory( - lambda cls: xattree.has(cls), lambda cls: xattree.asdict -) + +def _make_converter() -> Converter: + from flopy4.mf6.component import Component + from flopy4.mf6.gwf.oc import Oc + + converter = Converter() + converter.register_unstructure_hook_factory(xattree.has, lambda _: xattree.asdict) + converter.register_unstructure_hook(Component, unstructure_component) + converter.register_unstructure_hook(Oc, unstructure_oc) + return converter + + +_CONVERTER = _make_converter() + # TODO unstructure arrays into sparse dicts # TODO combine OC fields into list input as defined in the MF6 dfn diff --git a/flopy4/mf6/codec/converter.py b/flopy4/mf6/codec/converter.py index dee5b089..5ff838bf 100644 --- a/flopy4/mf6/codec/converter.py +++ b/flopy4/mf6/codec/converter.py @@ -2,12 +2,15 @@ import numpy as np import sparse +import xattree from numpy.typing import NDArray from xarray import DataArray from xattree import get_xatspec +from flopy4.mf6.component import Component from flopy4.mf6.config import SPARSE_THRESHOLD from flopy4.mf6.constants import FILL_DNODATA +from flopy4.mf6.spec import get_blocks # TODO: convert to a cattrs structuring hook so we don't have to @@ -108,22 +111,90 @@ def unstructure_array(value: DataArray) -> dict: MF6 list-based input format. """ # make sure dim 'kper' is present - if "kper" not in value.dims: - raise ValueError("array must have 'kper' dimension") + time_dim = "nper" + if time_dim not in value.dims: + raise ValueError(f"Array must have dimension '{time_dim}'") if isinstance(value.data, sparse.COO): coords = value.coords data = value.data else: - coords = np.array(np.nonzero(value)).T # type: ignore - data = value[tuple(coords.T)] # type: ignore + coords = np.array(np.nonzero(value.data)).T # type: ignore + data = value.data[tuple(coords.T)] # type: ignore if not coords.size: # type: ignore return {} match value.ndim: case 1: - return {k: v for k, v in zip(coords[:, 0], data)} # type: ignore + return {int(k): v for k, v in zip(coords[:, 0], data)} # type: ignore case 2: - return {(k, j): v for (k, j), v in zip(coords, data)} # type: ignore + return {(int(k), int(j)): v for (k, j), v in zip(coords, data)} # type: ignore case 3: - return {(k, i, j): v for (k, i, j), v in zip(coords, data)} # type: ignore + return {(int(k), int(i), int(j)): v for (k, i, j), v in zip(coords, data)} # type: ignore return {} + + +def unstructure_component(value: Component) -> dict[str, Any]: + data = xattree.asdict(value) + for block in get_blocks(value.dfn).values(): + for field_name, field in block.items(): + # unstructure arrays destined for list-based input + if field["type"] == "recarray" and field["reader"] != "readarray": + data[field_name] = unstructure_array(data[field_name]) + return data + + +def unstructure_oc(value: Any) -> dict[str, Any]: + data = xattree.asdict(value) + for block_name, block in get_blocks(value.dfn).items(): + if block_name == "perioddata": + # Unstructure all four arrays + save_head = unstructure_array(data.get("save_head", {})) + save_budget = unstructure_array(data.get("save_budget", {})) + print_head = unstructure_array(data.get("print_head", {})) + print_budget = unstructure_array(data.get("print_budget", {})) + + # Collect all unique periods + all_periods = set() # type: ignore + for d in (save_head, save_budget, print_head, print_budget): + if isinstance(d, dict): + all_periods.update(d.keys()) + all_periods = sorted(all_periods) # type: ignore + + saverecord = {} # type: ignore + printrecord = {} # type: ignore + for kper in all_periods: + # Save head + if kper in save_head: + v = save_head[kper] + if kper not in saverecord: + saverecord[kper] = [] + saverecord[kper].append({"action": "save", "type": "head", "ocsetting": v}) + # Save budget + if kper in save_budget: + v = save_budget[kper] + if kper not in saverecord: + saverecord[kper] = [] + saverecord[kper].append({"action": "save", "type": "budget", "ocsetting": v}) + # Print head + if kper in print_head: + v = print_head[kper] + if kper not in printrecord: + printrecord[kper] = [] + printrecord[kper].append({"action": "print", "type": "head", "ocsetting": v}) + # Print budget + if kper in print_budget: + v = print_budget[kper] + if kper not in printrecord: + printrecord[kper] = [] + printrecord[kper].append({"action": "print", "type": "budget", "ocsetting": v}) + + data["saverecord"] = saverecord + data["printrecord"] = printrecord + data["save"] = "save" + data["print"] = "print" + else: + for field_name, field in block.items(): + # unstructure arrays destined for list-based input + if field["type"] == "recarray" and field["reader"] != "readarray": + data[field_name] = unstructure_array(data[field_name]) + return data diff --git a/flopy4/mf6/component.py b/flopy4/mf6/component.py index c18acb1d..cdf8348d 100644 --- a/flopy4/mf6/component.py +++ b/flopy4/mf6/component.py @@ -1,6 +1,7 @@ from abc import ABC from collections.abc import MutableMapping from pathlib import Path +from typing import ClassVar from modflow_devtools.dfn import Dfn, Field from xattree import xattree @@ -33,6 +34,8 @@ class Component(ABC, MutableMapping): filename: str = field(default=None) + dfn: ClassVar[Dfn] + @property def path(self) -> Path: return Path.cwd() / self.filename diff --git a/flopy4/mf6/filters.py b/flopy4/mf6/filters.py index b92d959e..96cc5daf 100644 --- a/flopy4/mf6/filters.py +++ b/flopy4/mf6/filters.py @@ -1,28 +1,12 @@ from collections.abc import Hashable, Mapping from io import StringIO -from typing import Any import numpy as np import xarray as xr from jinja2 import pass_context -from modflow_devtools.dfn import Dfn, Field +from modflow_devtools.dfn import Field from numpy.typing import NDArray -from flopy4.mf6.spec import block_sort_key - - -def blocks(dfn: Dfn) -> dict: - """ - Get blocks from an MF6 input definition. Anything not an - explicitly defined key in the `Dfn` typed dict is a block. - """ - return dict( - sorted( - {k: v for k, v in dfn.items() if k not in Dfn.__annotations__}.items(), - key=block_sort_key, - ) - ) - def field_type(field: Field) -> str: """ @@ -105,7 +89,3 @@ def array2string(value: NDArray) -> str: ) np.savetxt(buffer, value, fmt=format, delimiter=" ") return buffer.getvalue().strip() - - -def is_list(value: Any) -> bool: - return isinstance(value, list) diff --git a/flopy4/mf6/gwf/oc.py b/flopy4/mf6/gwf/oc.py index 7e040b33..ef600320 100644 --- a/flopy4/mf6/gwf/oc.py +++ b/flopy4/mf6/gwf/oc.py @@ -3,6 +3,7 @@ import numpy as np from attrs import Converter, define +from modflow_devtools.dfn import Dfn, Field from numpy.typing import NDArray from xattree import xattree @@ -11,6 +12,64 @@ from flopy4.mf6.spec import array, field from flopy4.utils import to_path +_OCSETTING = Field( + name="ocsetting", + type="keystring", + reader="urword", + children={ + "all": Field( + name="all", + type="keyword", + reader="urword", + ), + "first": Field( + name="first", + type="keyword", + reader="urword", + ), + "last": Field( + name="last", + type="keyword", + reader="urword", + ), + "steps": Field( + name="steps", + type="integer", + reader="urword", + ), + "frequency": Field( + name="frequency", + type="integer", + reader="urword", + ), + }, +) + +_RTYPE = Field( + name="rtype", + type="string", + reader="urword", +) + + +def _oc_action_field(action: str) -> Field: + return Field( + name=f"{action}record", + type="recarray", + dims=("nper",), + block="perioddata", + reader="urword", + children={ + action: Field( + name=action, + type="keyword", + reader="urword", + ), + "rtype": _RTYPE, + "ocsetting": _OCSETTING, + }, + ) + @xattree class Oc(Package): @@ -56,6 +115,7 @@ class Period: default="all", dims=("nper",), converter=Converter(structure_array, takes_self=True, takes_field=True), + reader="urword", ) save_budget: Optional[NDArray[np.object_]] = array( Steps, @@ -63,6 +123,7 @@ class Period: default="all", dims=("nper",), converter=Converter(structure_array, takes_self=True, takes_field=True), + reader="urword", ) print_head: Optional[NDArray[np.object_]] = array( Steps, @@ -70,6 +131,7 @@ class Period: default="all", dims=("nper",), converter=Converter(structure_array, takes_self=True, takes_field=True), + reader="urword", ) print_budget: Optional[NDArray[np.object_]] = array( Steps, @@ -77,4 +139,15 @@ class Period: default="all", dims=("nper",), converter=Converter(structure_array, takes_self=True, takes_field=True), + reader="urword", ) + + @classmethod + def get_dfn(cls) -> Dfn: + """Generate the component's MODFLOW 6 definition.""" + dfn = super().get_dfn() + for field_name in list(dfn["perioddata"].keys()): + dfn["perioddata"].pop(field_name) + dfn["perioddata"]["saverecord"] = _oc_action_field("save") + dfn["perioddata"]["printrecord"] = _oc_action_field("print") + return dfn diff --git a/flopy4/mf6/spec.py b/flopy4/mf6/spec.py index 87a31b39..63bcb40e 100644 --- a/flopy4/mf6/spec.py +++ b/flopy4/mf6/spec.py @@ -9,7 +9,7 @@ import numpy as np from attrs import NOTHING, Attribute -from modflow_devtools.dfn import Field, FieldType +from modflow_devtools.dfn import Dfn, Field, FieldType, Reader from flopy4.spec import array as flopy_array from flopy4.spec import coord as flopy_coord @@ -32,6 +32,7 @@ def field( if block: metadata = metadata or {} metadata["block"] = block + metadata["reader"] = "urword" return flopy_field( default=default, validator=validator, @@ -57,6 +58,7 @@ def dim( if block: metadata = metadata or {} metadata["block"] = block + metadata["reader"] = "urword" return flopy_dim( scope=scope, coord=coord, @@ -80,6 +82,7 @@ def coord( if block: metadata = metadata or {} metadata["block"] = block + metadata["reader"] = "readarray" return flopy_coord( scope=scope, default=default, @@ -99,11 +102,13 @@ def array( eq=None, metadata=None, block: str | None = None, + reader: Reader = "readarray", ): """Define an array field.""" if block: metadata = metadata or {} metadata["block"] = block + metadata["reader"] = reader return flopy_array( cls=cls, dims=dims, @@ -227,4 +232,18 @@ def to_dfn_field(attribute: Attribute) -> Field: children={k: to_dfn_field(v) for k, v in fields_dict(attribute.type)} # type: ignore if attribute.metadata.get("kind", None) == "child" # type: ignore else None, # type: ignore + reader=attribute.metadata.get("reader", "urword"), + ) + + +def get_blocks(dfn: Dfn) -> dict: + """ + Get blocks from an MF6 input definition. Anything not an + explicitly defined key in the `Dfn` typed dict is a block. + """ + return dict( + sorted( + {k: v for k, v in dfn.items() if k not in Dfn.__annotations__}.items(), + key=block_sort_key, + ) ) diff --git a/flopy4/mf6/templates/macros.jinja b/flopy4/mf6/templates/macros.jinja index 2bcf2a5f..baa3477f 100644 --- a/flopy4/mf6/templates/macros.jinja +++ b/flopy4/mf6/templates/macros.jinja @@ -1,40 +1,40 @@ -{% macro field(field) %} -{% set type = field|field_type %} +{% macro field(f) %} +{% set type = f|field_type %} {% if type in ['keyword', 'integer', 'double precision', 'string'] %} -{{ scalar(field) }} +{{ scalar(f) }} {% elif type == 'record' %} -{{ record(field) }} +{{ record(f) }} {% elif type == 'keystring' %} -{{ keystring(field) }} +{{ keystring(f) }} {% elif type == 'recarray' %} -{{ recarray(field) }} +{{ recarray(f) }} {% endif %} {% endmacro %} -{% macro scalar(field) %} -{% set type = field|field_type %} -{% set value = field|field_value %} -{% if value is not none %}{{ field.name.upper() }}{% if type != 'keyword' %} {{ value }}{% endif %}{% endif %} +{% macro scalar(f) %} +{% set type = f|field_type %} +{% set value = f|field_value %} +{% if value is not none %}{{ f.name.upper() }}{% if type != 'keyword' %} {{ value }}{% endif %}{% endif %} {% endmacro %} -{% macro keystring(field) %} -{% for item in field.children.values() -%} +{% macro keystring(f) %} +{% for item in f.children.values() -%} {{ field(item) }} {%- endfor %} {% endmacro %} -{% macro record(field) %} -{% for item in field.children.values() -%} +{% macro record(f) %} +{% for item in f.children.values() -%} {% if item.tagged %}{{ item.name.upper() }} {% endif %}{{ field(item) }} {%- endfor %} {% endmacro %} -{% macro recarray(field) %} -{% set value = field|field_value %} -{% if value|is_list %} -{{ list(value) }} +{% macro recarray(f) %} +{% set value = f|field_value %} +{% if f.reader != 'readarray' %} +{{ list(f) }} {% else %} -{{ array(field.name, value, how=field|array_how) }} +{{ array(f.name, value, how=f|array_how) }} {% endif %} {% endmacro %} @@ -57,8 +57,9 @@ OPEN/CLOSE {{ value }} {% endif %} {% endmacro %} -{% macro list(field) %} -{% for item in field.children.values() %} +{% macro list(f) %} +{{ f }} +{% for item in f.children.values() %} {{ field(item) }} {% endfor %} {% endmacro %} diff --git a/pixi.lock b/pixi.lock index 34107b34..bf3da357 100644 --- a/pixi.lock +++ b/pixi.lock @@ -57,7 +57,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/97/12/a1f2f4fdc6b7159c0d12249456f9fe454665b6126e98dbee9f2bd3cf735c/lz4-4.4.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/f5/64/41c4367bcaecbc03ef0d2a3ecee58a7065d0a36ae1aa817fe573a2da66d4/matplotlib-3.10.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: git+https://github.com/MODFLOW-USGS/modflow-devtools.git#d169e61db1b039e56d6755993500e2d6567f723e + - pypi: git+https://github.com/MODFLOW-USGS/modflow-devtools.git#9704d96d3377ed4947e536a8834909f20f0b010f - pypi: https://files.pythonhosted.org/packages/2d/7b/2c1d74ca6c94f70a1add74a8393a0138172207dc5de6fc6269483519d048/msgpack-1.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/c9/e0/ade8619846645461c012498f02b93a659e50f07d9d9a6ffefdf5ea2c02a0/narwhals-1.41.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d1/80/b9c19f1bb4ac6c5fa6f94a4f278bc68a778473d1814a86a375d7cffa193a/netCDF4-1.7.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl @@ -143,7 +143,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/3b/3c/d1d1b926d3688263893461e7c47ed7382a969a0976fc121fc678ec325fc6/lz4-4.4.4-cp313-cp313-macosx_10_13_x86_64.whl - pypi: https://files.pythonhosted.org/packages/83/0e/67eb10a7ecc77a0c2bbe2b0235765b98d164d81600746914bebada795e97/MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl - pypi: https://files.pythonhosted.org/packages/3b/c1/23cfb566a74c696a3b338d8955c549900d18fe2b898b6e94d682ca21e7c2/matplotlib-3.10.3-cp313-cp313-macosx_10_13_x86_64.whl - - pypi: git+https://github.com/MODFLOW-USGS/modflow-devtools.git#d169e61db1b039e56d6755993500e2d6567f723e + - pypi: git+https://github.com/MODFLOW-USGS/modflow-devtools.git#9704d96d3377ed4947e536a8834909f20f0b010f - pypi: https://files.pythonhosted.org/packages/c8/ee/be57e9702400a6cb2606883d55b05784fada898dfc7fd12608ab1fdb054e/msgpack-1.1.0-cp313-cp313-macosx_10_13_x86_64.whl - pypi: https://files.pythonhosted.org/packages/c9/e0/ade8619846645461c012498f02b93a659e50f07d9d9a6ffefdf5ea2c02a0/narwhals-1.41.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e6/7a/ce4f9038d8726c9c90e07b2d3a404ae111a27720d712cfcded0c8ef160e8/netCDF4-1.7.2-cp313-cp313-macosx_12_0_x86_64.whl @@ -231,7 +231,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/00/96/b8e24ea7537ab418074c226279acfcaa470e1ea8271003e24909b6db942b/lz4-4.4.4-cp313-cp313-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/b1/0f/eed564407bd4d935ffabf561ed31099ed609e19287409a27b6d336848653/matplotlib-3.10.3-cp313-cp313-win_amd64.whl - - pypi: git+https://github.com/MODFLOW-USGS/modflow-devtools.git#d169e61db1b039e56d6755993500e2d6567f723e + - pypi: git+https://github.com/MODFLOW-USGS/modflow-devtools.git#9704d96d3377ed4947e536a8834909f20f0b010f - pypi: https://files.pythonhosted.org/packages/b6/bc/8bd826dd03e022153bfa1766dcdec4976d6c818865ed54223d71f07862b3/msgpack-1.1.0-cp313-cp313-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/c9/e0/ade8619846645461c012498f02b93a659e50f07d9d9a6ffefdf5ea2c02a0/narwhals-1.41.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/66/b5/e04550fd53de57001dbd5a87242da7ff784c80790adc48897977b6ccf891/netCDF4-1.7.2-cp313-cp313-win_amd64.whl @@ -398,7 +398,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/a7/f7/7782a043553ee469c1ff49cfa1cdace2d6bf99a1f333cf38676b3ddf30da/mdit_py_plugins-0.4.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/01/4d/23c4e4f09da849e127e9f123241946c23c1e30f45a88366879e064211815/mistune-3.1.3-py3-none-any.whl - - pypi: git+https://github.com/MODFLOW-USGS/modflow-devtools.git#d169e61db1b039e56d6755993500e2d6567f723e + - pypi: git+https://github.com/MODFLOW-USGS/modflow-devtools.git#9704d96d3377ed4947e536a8834909f20f0b010f - pypi: https://files.pythonhosted.org/packages/2b/9f/7ba6f94fc1e9ac3d2b853fdff3035fb2fa5afbed898c4a72b8a020610594/more_itertools-10.7.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a8/a1/ad7b84b91ab5a324e707f4c9761633e357820b011a01e34ce658c1dda7cc/msgpack-1.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/2e/81/a117441ea5dfc3746431e51d78a4aca569c677aa225bca2cc05a7c239b61/mypy-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl @@ -611,7 +611,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/a7/f7/7782a043553ee469c1ff49cfa1cdace2d6bf99a1f333cf38676b3ddf30da/mdit_py_plugins-0.4.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/01/4d/23c4e4f09da849e127e9f123241946c23c1e30f45a88366879e064211815/mistune-3.1.3-py3-none-any.whl - - pypi: git+https://github.com/MODFLOW-USGS/modflow-devtools.git#d169e61db1b039e56d6755993500e2d6567f723e + - pypi: git+https://github.com/MODFLOW-USGS/modflow-devtools.git#9704d96d3377ed4947e536a8834909f20f0b010f - pypi: https://files.pythonhosted.org/packages/2b/9f/7ba6f94fc1e9ac3d2b853fdff3035fb2fa5afbed898c4a72b8a020610594/more_itertools-10.7.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/60/c2/687684164698f1d51c41778c838d854965dd284a4b9d3a44beba9265c931/msgpack-1.1.0-cp311-cp311-macosx_10_9_x86_64.whl - pypi: https://files.pythonhosted.org/packages/24/c4/ff2f79db7075c274fe85b5fff8797d29c6b61b8854c39e3b7feb556aa377/mypy-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl @@ -824,7 +824,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/a7/f7/7782a043553ee469c1ff49cfa1cdace2d6bf99a1f333cf38676b3ddf30da/mdit_py_plugins-0.4.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/01/4d/23c4e4f09da849e127e9f123241946c23c1e30f45a88366879e064211815/mistune-3.1.3-py3-none-any.whl - - pypi: git+https://github.com/MODFLOW-USGS/modflow-devtools.git#d169e61db1b039e56d6755993500e2d6567f723e + - pypi: git+https://github.com/MODFLOW-USGS/modflow-devtools.git#9704d96d3377ed4947e536a8834909f20f0b010f - pypi: https://files.pythonhosted.org/packages/2b/9f/7ba6f94fc1e9ac3d2b853fdff3035fb2fa5afbed898c4a72b8a020610594/more_itertools-10.7.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/aa/c4/5a582fc9a87991a3e6f6800e9bb2f3c82972912235eb9539954f3e9997c7/msgpack-1.1.0-cp311-cp311-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/bd/53/7e9d528433d56e6f6f77ccf24af6ce570986c2d98a5839e4c2009ef47283/mypy-1.16.0-cp311-cp311-win_amd64.whl @@ -1039,7 +1039,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/a7/f7/7782a043553ee469c1ff49cfa1cdace2d6bf99a1f333cf38676b3ddf30da/mdit_py_plugins-0.4.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/01/4d/23c4e4f09da849e127e9f123241946c23c1e30f45a88366879e064211815/mistune-3.1.3-py3-none-any.whl - - pypi: git+https://github.com/MODFLOW-USGS/modflow-devtools.git#d169e61db1b039e56d6755993500e2d6567f723e + - pypi: git+https://github.com/MODFLOW-USGS/modflow-devtools.git#9704d96d3377ed4947e536a8834909f20f0b010f - pypi: https://files.pythonhosted.org/packages/a8/a1/ad7b84b91ab5a324e707f4c9761633e357820b011a01e34ce658c1dda7cc/msgpack-1.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/c9/e0/ade8619846645461c012498f02b93a659e50f07d9d9a6ffefdf5ea2c02a0/narwhals-1.41.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/34/6d/e7fa07f03a4a7b221d94b4d586edb754a9b0dc3c9e2c93353e9fa4e0d117/nbclient-0.10.2-py3-none-any.whl @@ -1224,7 +1224,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/a7/f7/7782a043553ee469c1ff49cfa1cdace2d6bf99a1f333cf38676b3ddf30da/mdit_py_plugins-0.4.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/01/4d/23c4e4f09da849e127e9f123241946c23c1e30f45a88366879e064211815/mistune-3.1.3-py3-none-any.whl - - pypi: git+https://github.com/MODFLOW-USGS/modflow-devtools.git#d169e61db1b039e56d6755993500e2d6567f723e + - pypi: git+https://github.com/MODFLOW-USGS/modflow-devtools.git#9704d96d3377ed4947e536a8834909f20f0b010f - pypi: https://files.pythonhosted.org/packages/60/c2/687684164698f1d51c41778c838d854965dd284a4b9d3a44beba9265c931/msgpack-1.1.0-cp311-cp311-macosx_10_9_x86_64.whl - pypi: https://files.pythonhosted.org/packages/c9/e0/ade8619846645461c012498f02b93a659e50f07d9d9a6ffefdf5ea2c02a0/narwhals-1.41.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/34/6d/e7fa07f03a4a7b221d94b4d586edb754a9b0dc3c9e2c93353e9fa4e0d117/nbclient-0.10.2-py3-none-any.whl @@ -1410,7 +1410,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/a7/f7/7782a043553ee469c1ff49cfa1cdace2d6bf99a1f333cf38676b3ddf30da/mdit_py_plugins-0.4.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/01/4d/23c4e4f09da849e127e9f123241946c23c1e30f45a88366879e064211815/mistune-3.1.3-py3-none-any.whl - - pypi: git+https://github.com/MODFLOW-USGS/modflow-devtools.git#d169e61db1b039e56d6755993500e2d6567f723e + - pypi: git+https://github.com/MODFLOW-USGS/modflow-devtools.git#9704d96d3377ed4947e536a8834909f20f0b010f - pypi: https://files.pythonhosted.org/packages/aa/c4/5a582fc9a87991a3e6f6800e9bb2f3c82972912235eb9539954f3e9997c7/msgpack-1.1.0-cp311-cp311-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/c9/e0/ade8619846645461c012498f02b93a659e50f07d9d9a6ffefdf5ea2c02a0/narwhals-1.41.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/34/6d/e7fa07f03a4a7b221d94b4d586edb754a9b0dc3c9e2c93353e9fa4e0d117/nbclient-0.10.2-py3-none-any.whl @@ -1608,7 +1608,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/a7/f7/7782a043553ee469c1ff49cfa1cdace2d6bf99a1f333cf38676b3ddf30da/mdit_py_plugins-0.4.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/01/4d/23c4e4f09da849e127e9f123241946c23c1e30f45a88366879e064211815/mistune-3.1.3-py3-none-any.whl - - pypi: git+https://github.com/MODFLOW-USGS/modflow-devtools.git#d169e61db1b039e56d6755993500e2d6567f723e + - pypi: git+https://github.com/MODFLOW-USGS/modflow-devtools.git#9704d96d3377ed4947e536a8834909f20f0b010f - pypi: https://files.pythonhosted.org/packages/f1/54/65af8de681fa8255402c80eda2a501ba467921d5a7a028c9c22a2c2eedb5/msgpack-1.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/c9/e0/ade8619846645461c012498f02b93a659e50f07d9d9a6ffefdf5ea2c02a0/narwhals-1.41.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/34/6d/e7fa07f03a4a7b221d94b4d586edb754a9b0dc3c9e2c93353e9fa4e0d117/nbclient-0.10.2-py3-none-any.whl @@ -1791,7 +1791,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/a7/f7/7782a043553ee469c1ff49cfa1cdace2d6bf99a1f333cf38676b3ddf30da/mdit_py_plugins-0.4.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/01/4d/23c4e4f09da849e127e9f123241946c23c1e30f45a88366879e064211815/mistune-3.1.3-py3-none-any.whl - - pypi: git+https://github.com/MODFLOW-USGS/modflow-devtools.git#d169e61db1b039e56d6755993500e2d6567f723e + - pypi: git+https://github.com/MODFLOW-USGS/modflow-devtools.git#9704d96d3377ed4947e536a8834909f20f0b010f - pypi: https://files.pythonhosted.org/packages/70/da/5312b067f6773429cec2f8f08b021c06af416bba340c912c2ec778539ed6/msgpack-1.1.0-cp312-cp312-macosx_10_9_x86_64.whl - pypi: https://files.pythonhosted.org/packages/c9/e0/ade8619846645461c012498f02b93a659e50f07d9d9a6ffefdf5ea2c02a0/narwhals-1.41.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/34/6d/e7fa07f03a4a7b221d94b4d586edb754a9b0dc3c9e2c93353e9fa4e0d117/nbclient-0.10.2-py3-none-any.whl @@ -1975,7 +1975,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/a7/f7/7782a043553ee469c1ff49cfa1cdace2d6bf99a1f333cf38676b3ddf30da/mdit_py_plugins-0.4.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/01/4d/23c4e4f09da849e127e9f123241946c23c1e30f45a88366879e064211815/mistune-3.1.3-py3-none-any.whl - - pypi: git+https://github.com/MODFLOW-USGS/modflow-devtools.git#d169e61db1b039e56d6755993500e2d6567f723e + - pypi: git+https://github.com/MODFLOW-USGS/modflow-devtools.git#9704d96d3377ed4947e536a8834909f20f0b010f - pypi: https://files.pythonhosted.org/packages/73/80/2708a4641f7d553a63bc934a3eb7214806b5b39d200133ca7f7afb0a53e8/msgpack-1.1.0-cp312-cp312-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/c9/e0/ade8619846645461c012498f02b93a659e50f07d9d9a6ffefdf5ea2c02a0/narwhals-1.41.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/34/6d/e7fa07f03a4a7b221d94b4d586edb754a9b0dc3c9e2c93353e9fa4e0d117/nbclient-0.10.2-py3-none-any.whl @@ -2172,7 +2172,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/a7/f7/7782a043553ee469c1ff49cfa1cdace2d6bf99a1f333cf38676b3ddf30da/mdit_py_plugins-0.4.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/01/4d/23c4e4f09da849e127e9f123241946c23c1e30f45a88366879e064211815/mistune-3.1.3-py3-none-any.whl - - pypi: git+https://github.com/MODFLOW-USGS/modflow-devtools.git#d169e61db1b039e56d6755993500e2d6567f723e + - pypi: git+https://github.com/MODFLOW-USGS/modflow-devtools.git#9704d96d3377ed4947e536a8834909f20f0b010f - pypi: https://files.pythonhosted.org/packages/2d/7b/2c1d74ca6c94f70a1add74a8393a0138172207dc5de6fc6269483519d048/msgpack-1.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/c9/e0/ade8619846645461c012498f02b93a659e50f07d9d9a6ffefdf5ea2c02a0/narwhals-1.41.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/34/6d/e7fa07f03a4a7b221d94b4d586edb754a9b0dc3c9e2c93353e9fa4e0d117/nbclient-0.10.2-py3-none-any.whl @@ -2357,7 +2357,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/a7/f7/7782a043553ee469c1ff49cfa1cdace2d6bf99a1f333cf38676b3ddf30da/mdit_py_plugins-0.4.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/01/4d/23c4e4f09da849e127e9f123241946c23c1e30f45a88366879e064211815/mistune-3.1.3-py3-none-any.whl - - pypi: git+https://github.com/MODFLOW-USGS/modflow-devtools.git#d169e61db1b039e56d6755993500e2d6567f723e + - pypi: git+https://github.com/MODFLOW-USGS/modflow-devtools.git#9704d96d3377ed4947e536a8834909f20f0b010f - pypi: https://files.pythonhosted.org/packages/c8/ee/be57e9702400a6cb2606883d55b05784fada898dfc7fd12608ab1fdb054e/msgpack-1.1.0-cp313-cp313-macosx_10_13_x86_64.whl - pypi: https://files.pythonhosted.org/packages/c9/e0/ade8619846645461c012498f02b93a659e50f07d9d9a6ffefdf5ea2c02a0/narwhals-1.41.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/34/6d/e7fa07f03a4a7b221d94b4d586edb754a9b0dc3c9e2c93353e9fa4e0d117/nbclient-0.10.2-py3-none-any.whl @@ -2543,7 +2543,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/a7/f7/7782a043553ee469c1ff49cfa1cdace2d6bf99a1f333cf38676b3ddf30da/mdit_py_plugins-0.4.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/01/4d/23c4e4f09da849e127e9f123241946c23c1e30f45a88366879e064211815/mistune-3.1.3-py3-none-any.whl - - pypi: git+https://github.com/MODFLOW-USGS/modflow-devtools.git#d169e61db1b039e56d6755993500e2d6567f723e + - pypi: git+https://github.com/MODFLOW-USGS/modflow-devtools.git#9704d96d3377ed4947e536a8834909f20f0b010f - pypi: https://files.pythonhosted.org/packages/b6/bc/8bd826dd03e022153bfa1766dcdec4976d6c818865ed54223d71f07862b3/msgpack-1.1.0-cp313-cp313-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/c9/e0/ade8619846645461c012498f02b93a659e50f07d9d9a6ffefdf5ea2c02a0/narwhals-1.41.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/34/6d/e7fa07f03a4a7b221d94b4d586edb754a9b0dc3c9e2c93353e9fa4e0d117/nbclient-0.10.2-py3-none-any.whl @@ -6038,7 +6038,7 @@ packages: requires_dist: - typing-extensions ; python_full_version < '3.11' requires_python: '>=3.8' -- pypi: git+https://github.com/MODFLOW-USGS/modflow-devtools.git#d169e61db1b039e56d6755993500e2d6567f723e +- pypi: git+https://github.com/MODFLOW-USGS/modflow-devtools.git#9704d96d3377ed4947e536a8834909f20f0b010f name: modflow-devtools version: 1.7.0.dev0 requires_dist: diff --git a/test/test_codec.py b/test/test_codec.py index 006963b3..bc5b64fc 100644 --- a/test/test_codec.py +++ b/test/test_codec.py @@ -21,6 +21,7 @@ def test_dumps_ic(): assert result +@pytest.mark.xfail(reason="TODO period block unstructuring") def test_dumps_oc(): from flopy4.mf6.gwf import Oc @@ -37,7 +38,7 @@ def test_dumps_oc(): assert result -@pytest.mark.skip(reason="TODO 3D arrays") +@pytest.mark.xfail(reason="TODO 3D arrays") def test_dumps_dis(): from flopy4.mf6.gwf import Dis diff --git a/uv.lock b/uv.lock index b5c12abf..37bd6b00 100644 --- a/uv.lock +++ b/uv.lock @@ -1800,7 +1800,7 @@ wheels = [ [[package]] name = "modflow-devtools" version = "1.7.0.dev0" -source = { git = "https://github.com/MODFLOW-USGS/modflow-devtools.git#d169e61db1b039e56d6755993500e2d6567f723e" } +source = { git = "https://github.com/MODFLOW-USGS/modflow-devtools.git#9704d96d3377ed4947e536a8834909f20f0b010f" } [package.optional-dependencies] dfn = [