Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions autotest/dfns/__snapshots__/v2.0.0.dev2/utl-obs.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
"type": "package",
"schema_version": "2.0.0.dev2",
"name": "utl-obs",
"parent": "package",
"ftype": "OBS6",
"multi": true,
"subtype": "utility",
"parent": [
"model",
"package"
],
"blocks": {
"options": {
"fields": {
Expand Down
6 changes: 4 additions & 2 deletions autotest/dfns/__snapshots__/v2.0.0.dev2/utl-obs.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
type = "package"
schema_version = "2.0.0.dev2"
name = "utl-obs"
parent = "package"
ftype = "OBS6"
multi = true
subtype = "utility"
parent = [
"model",
"package",
]

[blocks.options.fields.digits]
type = "integer"
Expand Down
5 changes: 3 additions & 2 deletions autotest/dfns/__snapshots__/v2.0.0.dev2/utl-obs.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
type: package
schema_version: 2.0.0.dev2
name: utl-obs
parent: package
ftype: OBS6
multi: true
subtype: utility
parent:
- model
- package
blocks:
options:
fields:
Expand Down
6 changes: 4 additions & 2 deletions autotest/dfns/__snapshots__/v2.0.0.dev3/utl-obs.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
"type": "package",
"schema_version": "2.0.0.dev3",
"name": "utl-obs",
"parent": "package",
"ftype": "OBS6",
"multi": true,
"subtype": "utility",
"parent": [
"model",
"package"
],
"blocks": {
"options": {
"fields": {
Expand Down
6 changes: 4 additions & 2 deletions autotest/dfns/__snapshots__/v2.0.0.dev3/utl-obs.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
type = "package"
schema_version = "2.0.0.dev3"
name = "utl-obs"
parent = "package"
ftype = "OBS6"
multi = true
subtype = "utility"
parent = [
"model",
"package",
]

[blocks.options.fields.digits]
type = "integer"
Expand Down
5 changes: 3 additions & 2 deletions autotest/dfns/__snapshots__/v2.0.0.dev3/utl-obs.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
type: package
schema_version: 2.0.0.dev3
name: utl-obs
parent: package
ftype: OBS6
multi: true
subtype: utility
parent:
- model
- package
blocks:
options:
fields:
Expand Down
17 changes: 15 additions & 2 deletions autotest/dfns/test_migrate.py
Original file line number Diff line number Diff line change
Expand Up @@ -640,7 +640,9 @@ def test_migrate_link_selectors_resolve(linked_spec):
def test_migrate_model_packages_exclude_utilities(linked_spec):
children = linked_spec.children("gwf-nam")
assert {"gwf-dis", "gwf-gnc", "gwf-mvr"} <= set(children)
assert not any(n.startswith("utl-") for n in children)
# but a model with observations reads an OBS6 file
assert [n for n in children if n.startswith("utl-")] == ["utl-obs"]
assert linked_spec.ftype_family("OBS6", "gwf-nam") == ["utl-obs"]


def test_migrate_unlinked_files(linked_spec):
Expand All @@ -657,7 +659,7 @@ def test_migrate_unlinked_files(linked_spec):
"name, parent",
[
("utl-ts", "package"),
("utl-obs", "package"),
("utl-obs", ["model", "package"]),
(
"utl-ncf",
[f"{m}-{d}" for m in ("gwe", "gwf", "gwt", "prt") for d in ("dis", "disv")],
Expand All @@ -682,6 +684,17 @@ def test_migrate_derives_parents_from_links(linked_spec, name, parent):
assert linked_spec.components[name].parent == parent


@pytest.mark.parametrize("name, multi", [("utl-obs", False), ("utl-ts", True)])
def test_migrate_multi_overrides(linked_spec, name, multi):
# flopy3 marks both multi-package, but MF6 reads one OBS6 per parent
assert linked_spec.components[name].multi is multi


def test_migrate_obs_keeps_any_model_dims(linked_spec):
# utl-obs's parent gains `model`; it still sees any model's dims
assert {"nodes", "nlay"} <= linked_spec.inherited_dims("utl-obs")


def test_migrate_subpackage_keeps_model_dims(linked_spec):
# tvk's parent is now gwf-npf, not `package`; it must still see grid dims
assert {"nodes", "nlay"} <= linked_spec.inherited_dims("utl-tvk")
Expand Down
4 changes: 4 additions & 0 deletions autotest/dfns/test_schema_relations.py
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,10 @@ def test_covering_selector():
assert covering_selector([wel, spc], all_) == "package"
# no single term covers a model and an exchange: concrete names
assert covering_selector([nam, exg], all_) == ["exg-gwfgwf", "gwf-nam"]
# models and packages: their types
gwt = Model(name="gwt-nam")
all_[gwt.name] = gwt
assert covering_selector([wel, npf, nam, gwt], all_) == ["model", "package"]


def test_children_list_parent():
Expand Down
14 changes: 13 additions & 1 deletion modflow_devtools/dfns/migrate_to_v2_0_0_dev2.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from modflow_devtools.dfn import schema as v1
from modflow_devtools.dfns import schema as v2
from modflow_devtools.dfns.observations import OBSERVATIONS
from modflow_devtools.misc import try_literal_eval

_IDENT_RE = re.compile(r"^[A-Za-z_]\w*$")
Expand Down Expand Up @@ -114,6 +115,11 @@ def try_parse_bool(v: Any, default: bool = False) -> bool:
# to the base type when matching name-file ftypes (InputLoadType.f90).
_FTYPE_VARIANTS = frozenset({"evta", "rcha", "spca", "rivg", "chdg", "welg", "drng", "ghbg"})

# Components flopy3 marks `multi-package` that MF6 reads at most once per
# parent. utl-obs: one OBS6 per package (BoundaryPackage.f90 errors on a
# second) and per model (the last row wins). The DFN header stays for flopy3.
_SINGLE_INSTANCE = frozenset({"utl-obs"})

_MODEL_TYPES = frozenset({*_DEPENDENT_VARS, "prt"})


Expand Down Expand Up @@ -2158,7 +2164,8 @@ def _lookup(rname: str) -> dict | None:
)
is_stress_pkg = is_stress_package(name, meta)
subtype = "advanced" if is_advanced else "stress" if is_stress_pkg else None
return v2.Package(**d, subtype=subtype, multi=is_multi_package(meta))
multi = is_multi_package(meta) and name not in _SINGLE_INSTANCE
return v2.Package(**d, subtype=subtype, multi=multi)


def subpackage_keys(metas: Mapping[str, list[str]]) -> dict[str, str]:
Expand Down Expand Up @@ -2206,8 +2213,13 @@ def link_components(
The links themselves are made per file, by `to_v2_0_0_dev2`. Only
concrete links count: a name file's type selectors (``model``,
``package``, ...) pick among components whose parents are already known.
The exception is OBS: a model with observation types reads one OBS6 file
from its packages block, so it links ``utl-obs`` like a package does.
"""
links = {name: _links(c) for name, c in components.items()}
for name in OBSERVATIONS:
if name.endswith("-nam") and name in components:
links[name] = [*links[name], "utl-obs"]

for name, meta in metas.items():
if name not in components:
Expand Down
Loading