Skip to content
152 changes: 152 additions & 0 deletions autotest/test_interface.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import shutil
from pathlib import Path
from platform import system
from textwrap import dedent

import numpy as np
import pytest
Expand Down Expand Up @@ -341,6 +342,157 @@ def callback(sim, step):
raise Exception(e)


def test_sfr_input_context_names(function_tmpdir):
def callback(sim, step):
if step != Callbacks.timestep_start or sim.kstp != 0:
return
model = sim.get_model()
sfr = model.get_package("sfr_0")
if sim.kper == 1:
# the write persists into the next time step
np.testing.assert_allclose(sfr.packagedata.values["hk"], written["hk"], err_msg="hk write did not persist")
written["persisted"] = True
return
if f"__INPUT__/{model.name}/SFR_0/BEDK" in sim.mf6.get_input_var_names():
path = f"__INPUT__/{model.name}/SFR_0"
names = ("BEDK", "MANNING", "UPSTREAM_FRAC")
else:
path = f"{model.name}/SFR_0"
names = ("HK", "ROUGH", "USTRF")
addrs = [f"{path}/{name}" for name in names]
for addr in addrs:
assert addr in sfr._package_var_addrs, f"{addr} not used"

pd = sfr.packagedata.values
for column, values in expected.items():
np.testing.assert_allclose(pd[column], values, err_msg=f"{column} does not match the input")

pd["hk"] *= 10.0
sfr.packagedata = pd
np.testing.assert_allclose(sim.mf6.get_value(addrs[0]), pd["hk"], err_msg="hk is not being properly set")
written["hk"] = pd["hk"].copy()

written = {}

# three reaches in a row of three cells; reach 1 flows to reach 2 and
# diverts to reach 3
expected = {"hk": [0.1, 0.2, 0.3], "rough": [0.03, 0.035, 0.04], "ustrf": [1.0, 1.0, 0.0]}
packagedata = "\n".join(
f" {i + 1} 1 1 {i + 1} 100.0 {width} 0.001 {rtp} 1.0 {hk} {rough} {ncon} {ustrf} {ndiv}"
for i, (width, rtp, hk, rough, ncon, ustrf, ndiv) in enumerate(
zip(
[10.0, 10.0, 5.0],
[9.0, 8.9, 8.9],
expected["hk"],
expected["rough"],
[2, 1, 1],
expected["ustrf"],
[1, 0, 0],
)
)
)
files = {
"mfsim.nam": """
BEGIN timing
TDIS6 sim.tdis
END timing
BEGIN models
gwf6 sfr.nam sfr
END models
BEGIN exchanges
END exchanges
BEGIN solutiongroup 1
ims6 sim.ims sfr
END solutiongroup
""",
"sim.tdis": """
BEGIN dimensions
NPER 2
END dimensions
BEGIN perioddata
1.0 1 1.0
1.0 1 1.0
END perioddata
""",
"sim.ims": "",
"sfr.nam": """
BEGIN packages
DIS6 sfr.dis dis
NPF6 sfr.npf npf
IC6 sfr.ic ic
CHD6 sfr.chd chd_0
SFR6 sfr.sfr sfr_0
END packages
""",
"sfr.dis": """
BEGIN dimensions
NLAY 1
NROW 1
NCOL 3
END dimensions
BEGIN griddata
delr
CONSTANT 100.0
delc
CONSTANT 100.0
top
CONSTANT 10.0
botm
CONSTANT 0.0
END griddata
""",
"sfr.npf": """
BEGIN griddata
icelltype
CONSTANT 0
k
CONSTANT 10.0
END griddata
""",
"sfr.ic": """
BEGIN griddata
strt
CONSTANT 8.0
END griddata
""",
"sfr.chd": """
BEGIN dimensions
MAXBOUND 1
END dimensions
BEGIN period 1
1 1 1 8.0
END period
""",
"sfr.sfr": """
BEGIN dimensions
NREACHES 3
END dimensions
BEGIN packagedata
{packagedata}
END packagedata
BEGIN connectiondata
1 -2 -3
2 1
3 1
END connectiondata
BEGIN diversions
1 1 3 UPTO
END diversions
BEGIN period 1
1 INFLOW 10.0
1 DIVERSION 1 2.0
END period
""",
}
test_pth = function_tmpdir / "sfr_model"
test_pth.mkdir()
for name, text in files.items():
(test_pth / name).write_text(dedent(text).format(packagedata=packagedata))

run_simulation(so, test_pth, callback)
assert written.get("persisted"), "hk was not checked in the second stress period"


def test_rhs_hcof_advanced(function_tmpdir):
def callback(sim, step):
model = sim.test_model
Expand Down
4 changes: 3 additions & 1 deletion modflowapi/extensions/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,9 @@ def _set_data(self):
else:
continue

reduced = var_addr.split("/")[-1].lower()
# keep the column name of a variable read from the input context
column_names = getattr(self.parent, "_column_names", {})
reduced = column_names.get(var_addr, var_addr.split("/")[-1].lower())
if reduced in ("maxbound", "nbound"):
setattr(self, f"_{reduced}", values)
if not self._spd and reduced == "maxbound":
Expand Down
10 changes: 10 additions & 0 deletions modflowapi/extensions/datamodel.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,16 @@
"maw": {"packagedata": ["nmawwells", ("ifno:range:nmawwells", "radius", "bot", "strt", "ngwfnodes")]},
}

# advanced package variables read from the input context when libmf6 has them,
# keyed by column name, with the input context name
adv_input_vars = {
"sfr": {
"hk": "BEDK",
"rough": "MANNING",
"ustrf": "UPSTREAM_FRAC",
},
}


def get_package_type(pkg_type):
from .advpaks import LakPackage, MawPackage, SfrPakage, UzfPackage
Expand Down
12 changes: 11 additions & 1 deletion modflowapi/extensions/pakbase.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import numpy as np

from .data import AdvancedInput, ArrayInput, ListInput, ScalarInput
from .datamodel import adv_pkgvars, pkgvars
from .datamodel import adv_input_vars, adv_pkgvars, pkgvars


class PackageBase:
Expand Down Expand Up @@ -468,6 +468,10 @@ def __init__(self, model, pkg_type, pkg_name, sim_package=False):
self._sp_var_addrs = []
self._package_vars = None
self._sp_vars = None
self._input_vars = adv_input_vars.get(pkg_type, {})
self._column_names = {}
if self._input_vars:
self._input_var_names = set(self.model.mf6.get_input_var_names())

if pkg_type in adv_pkgvars:
self._adv_var_dict = adv_pkgvars[pkg_type]
Expand Down Expand Up @@ -550,6 +554,12 @@ def _get_advanced_variable_addr(self, var_str):
-------
var_addr : str
"""
var = var_str.lower()
if var in self._input_vars:
s = f"__INPUT__/{self.model.name}/{self.pkg_name}/{self._input_vars[var]}"
if s in self._input_var_names:
self._column_names[s] = var
return s
s = f"{self.model.name}/{self.pkg_name}/{var_str.upper()}"
return s

Expand Down
Loading