Skip to content

Commit

Permalink
test: define targets in conftest.py, refactor devtools usages (#1327)
Browse files Browse the repository at this point in the history
* configure exes in conftest.py instead of devtools
* remove usages of Case (to be removed from devtools)
* refactor test_gwf_maw[1-4] to accommodate removal
  • Loading branch information
wpbonelli authored Aug 5, 2023
1 parent 2f52a23 commit 5d4f56a
Show file tree
Hide file tree
Showing 14 changed files with 979 additions and 1,036 deletions.
42 changes: 40 additions & 2 deletions autotest/conftest.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import platform
import sys
from pathlib import Path
from os import PathLike
from typing import Dict

import pytest
from modflow_devtools.executables import Executables, build_default_exe_dict
from modflow_devtools.executables import Executables, get_suffixes

pytest_plugins = ["modflow_devtools.fixtures"]
project_root_path = Path(__file__).resolve().parent.parent
Expand Down Expand Up @@ -45,7 +48,42 @@ def libmf6_path(bin_path) -> Path:

@pytest.fixture(scope="session")
def targets(bin_path) -> Executables:
return Executables(**build_default_exe_dict(bin_path))
exe_ext, lib_ext = get_suffixes(sys.platform)
dl_bin = bin_path / "downloaded"
rb_bin = bin_path / "rebuilt"
tgts = dict()

# downloaded executables
tgts["mf2000"] = dl_bin / f"mf2000{exe_ext}"
tgts["mf2005"] = dl_bin / f"mf2005dbl{exe_ext}"
tgts["mfnwt"] = dl_bin / f"mfnwtdbl{exe_ext}"
tgts["mfusg"] = dl_bin / f"mfusgdbl{exe_ext}"
tgts["mflgr"] = dl_bin / f"mflgrdbl{exe_ext}"
tgts["mf2005s"] = dl_bin / f"mf2005{exe_ext}"
tgts["mt3dms"] = dl_bin / f"mt3dms{exe_ext}"
tgts["crt"] = dl_bin / f"crt{exe_ext}"
tgts["gridgen"] = dl_bin / f"gridgen{exe_ext}"
tgts["mp6"] = dl_bin / f"mp6{exe_ext}"
tgts["mp7"] = dl_bin / f"mp7{exe_ext}"
tgts["swtv4"] = dl_bin / f"swtv4{exe_ext}"
tgts["sutra"] = dl_bin / f"sutra{exe_ext}"
tgts["triangle"] = dl_bin / f"triangle{exe_ext}"
tgts["vs2dt"] = dl_bin / f"vs2dt{exe_ext}"
tgts["zonbudusg"] = dl_bin / f"zonbudusg{exe_ext}"

# binaries rebuilt from last release
tgts["mf6_regression"] = rb_bin / f"mf6{exe_ext}"
tgts["libmf6_regression"] = rb_bin / f"libmf6{lib_ext}"
tgts["mf5to6_regression"] = rb_bin / f"mf5to6{exe_ext}"
tgts["zbud6_regression"] = rb_bin / f"zbud6{exe_ext}"

# local development binaries
tgts["mf6"] = bin_path / f"mf6{exe_ext}"
tgts["libmf6"] = bin_path / f"libmf6{lib_ext}"
tgts["mf5to6"] = bin_path / f"mf5to6{exe_ext}"
tgts["zbud6"] = bin_path / f"zbud6{exe_ext}"

return Executables(**tgts)


@pytest.fixture
Expand Down
27 changes: 0 additions & 27 deletions autotest/test_gwf.py

This file was deleted.

213 changes: 213 additions & 0 deletions autotest/test_gwf_maw01.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
import os
from types import SimpleNamespace as Case

import flopy
import numpy as np
import pytest

from framework import TestFramework
from simulation import TestSimulation

budtol = 1e-2
bud_lst = ["GWF_IN", "GWF_OUT", "RATE_IN", "RATE_OUT"]

well1 = Case(
observations={"maw_obs.csv": [("mh1", "head", 1)]},
packagedata=[[0, 0.1, 50.0, 100.0, "THIEM", 1]],
connectiondata=[[0, 0, (0, 0, 1), 100.0, 50.0, 1.0, 0.1]],
perioddata=[[0, "rate", 0.0]],
)

ex = ["maw01", "maw01nwt", "maw01nwtur"]
krylov = ["CG", "BICGSTAB", "BICGSTAB"]
newton = [None, "NEWTON", "NEWTON UNDER_RELAXATION"]
nlay = 1
nrow = 1
ncol = 3
nper = 3
delr = 300
delc = 300
perlen = 3 * [1]
nstp = 3 * [1]
tsmult = 3 * [1]
well = well1
strt = 100
hk = 1
nouter = 100
ninner = 300
hclose = 1e-9
rclose = 1e-3
relaxation_factor = 1
compare = False


def build_model(idx, ws, mf6):
name = ex[idx]
sim = flopy.mf6.MFSimulation(
sim_name=name,
version="mf6",
exe_name=mf6,
sim_ws=ws,
)

# create tdis package
tdis_rc = [(perlen[i], nstp[i], tsmult[i]) for i in range(nper)]
tdis = flopy.mf6.ModflowTdis(
sim, time_units="DAYS", nper=nper, perioddata=tdis_rc
)

# create gwf model
gwf = flopy.mf6.MFModel(
sim,
model_type="gwf6",
modelname=name,
model_nam_file=f"{name}.nam",
)
gwf.name_file.newtonoptions = newton[idx]

# create iterative model solution and register the gwf model with it
ims = flopy.mf6.ModflowIms(
sim,
print_option="SUMMARY",
outer_dvclose=hclose,
outer_maximum=nouter,
under_relaxation="NONE",
inner_maximum=ninner,
inner_dvclose=hclose,
rcloserecord=rclose,
linear_acceleration=krylov[idx],
scaling_method="NONE",
reordering_method="NONE",
relaxation_factor=relaxation_factor,
)
sim.register_ims_package(ims, [gwf.name])

dis = flopy.mf6.ModflowGwfdis(
gwf,
nlay=nlay,
nrow=nrow,
ncol=ncol,
delr=delr,
delc=delc,
top=100.0,
botm=0.0,
idomain=1,
filename=f"{name}.dis",
)

# initial conditions
ic = flopy.mf6.ModflowGwfic(gwf, strt=strt, filename=f"{name}.ic")

# node property flow
npf = flopy.mf6.ModflowGwfnpf(
gwf,
save_flows=True,
icelltype=1,
k=hk,
k33=hk,
filename=f"{name}.npf",
)
# storage
sto = flopy.mf6.ModflowGwfsto(
gwf,
save_flows=True,
iconvert=1,
ss=0.0,
sy=0.1,
steady_state={0: True},
# transient={1: False},
filename=f"{name}.sto",
)

# chd files
chdlist0 = []
chdlist0.append([(0, 0, 0), 100.0])
chdlist0.append([(0, 0, 2), 100.0])

chdlist1 = []
chdlist1.append([(0, 0, 0), 25.0])
chdlist1.append([(0, 0, 2), 25.0])

chdspdict = {0: chdlist0, 1: chdlist1, 2: chdlist0}
chd = flopy.mf6.ModflowGwfchd(
gwf,
stress_period_data=chdspdict,
save_flows=False,
filename=f"{name}.chd",
)

# wel files
# wel = flopy.mf6.ModflowGwfwel(gwf, print_input=True, print_flows=True,
# maxbound=len(ws),
# periodrecarray=wd6,
# save_flows=False)
# MAW
maw = flopy.mf6.ModflowGwfmaw(
gwf,
filename=f"{name}.maw",
print_input=True,
print_head=True,
print_flows=True,
save_flows=True,
observations=well.observations,
packagedata=well.packagedata,
connectiondata=well.connectiondata,
perioddata=well.perioddata,
)

# output control
oc = flopy.mf6.ModflowGwfoc(
gwf,
budget_filerecord=f"{name}.cbc",
head_filerecord=f"{name}.hds",
headprintrecord=[("COLUMNS", 10, "WIDTH", 15, "DIGITS", 6, "GENERAL")],
saverecord=[("HEAD", "ALL")],
printrecord=[("HEAD", "ALL"), ("BUDGET", "ALL")],
filename=f"{name}.oc",
)

return sim, None


def eval_results(sim):
print("evaluating MAW heads...")

# MODFLOW 6 maw results
fpth = os.path.join(sim.simpath, "maw_obs.csv")
tc = np.genfromtxt(fpth, names=True, delimiter=",")

# create known results array
tc0 = np.array([100.0, 25.0, 100.0])

# calculate maximum absolute error
diff = tc["MH1"] - tc0
diffmax = np.abs(diff).max()
dtol = 1e-9
msg = f"maximum absolute maw head difference ({diffmax}) "

if diffmax > dtol:
sim.success = False
msg += f"exceeds {dtol}"
assert diffmax < dtol, msg
else:
sim.success = True
print(" " + msg)


@pytest.mark.parametrize("idx, name", list(enumerate(ex)))
def test_mf6model(idx, name, function_tmpdir, targets):
ws = str(function_tmpdir)
sim, _ = build_model(idx, ws, targets.mf6)
sim.write_simulation()
sim.run_simulation()
test = TestFramework()
test.run(
TestSimulation(
name=name,
exe_dict=targets,
exfunc=eval_results,
idxsim=idx,
make_comparison=False,
),
ws,
)
Loading

0 comments on commit 5d4f56a

Please sign in to comment.