Skip to content

Commit

Permalink
refactor(utils): move utils from modflow-devtools (#1621)
Browse files Browse the repository at this point in the history
* add head and budget file writing util fns
* add disu creation helper fn
* add uniform flow field fn
* add head/budget/concentration comparison utility fns
* add namefile-reading utility fn
* add minimal tests for relocated utils
  • Loading branch information
wpbonelli authored Dec 20, 2022
1 parent 96fc3ad commit 94cd19d
Show file tree
Hide file tree
Showing 8 changed files with 2,537 additions and 2 deletions.
44 changes: 43 additions & 1 deletion autotest/test_binaryfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@
HeadUFile,
Util2d,
)
from flopy.utils.binaryfile import get_headfile_precision
from flopy.utils.binaryfile import (
get_headfile_precision,
write_budget,
write_head,
)
from flopy.utils.gridutil import uniform_flow_field


@pytest.fixture
Expand Down Expand Up @@ -241,3 +246,40 @@ def test_budgetfile_detect_precision_single(path):
def test_budgetfile_detect_precision_double(path):
file = CellBudgetFile(path, precision="auto")
assert file.realtype == np.float64


def test_write_head(function_tmpdir):
file_path = function_tmpdir / "headfile"
head_data = np.random.random((10, 10))

write_head(file_path, head_data)

assert file_path.is_file()
content = np.fromfile(file_path)
assert np.array_equal(head_data.ravel(), content)

# TODO: what else needs to be checked here?


def test_write_budget(function_tmpdir):
file_path = function_tmpdir / "budgetfile"

nlay = 3
nrow = 3
ncol = 3
qx = 1.0
qy = 0.0
qz = 0.0
shape = (nlay, nrow, ncol)
spdis, flowja = uniform_flow_field(qx, qy, qz, shape)

write_budget(file_path, flowja, kstp=0)
assert file_path.is_file()
content1 = np.fromfile(file_path)

write_budget(file_path, flowja, kstp=1, kper=1, text="text")
assert file_path.is_file()
content2 = np.fromfile(file_path)

# TODO: why are these the same?
assert np.array_equal(content1, content2)
69 changes: 69 additions & 0 deletions autotest/test_compare.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import numpy as np
import pytest

from flopy.mf6.utils import MfGrdFile
from flopy.utils.compare import _diffmax, _difftol


def test_diffmax():
a1 = np.array([1, 2, 3])
a2 = np.array([4, 5, 7])
d, indices = _diffmax(a1, a2)
indices = indices[
0
] # return value is a tuple of arrays (1 for each dimension)
assert d == 4
assert list(indices) == [2]


def test_difftol():
a1 = np.array([1, 2, 3])
a2 = np.array([3, 5, 7])
d, indices = _difftol(a1, a2, 2.5)
indices = indices[
0
] # return value is a tuple of arrays (1 for each dimension)
assert d == 4
print(d, indices)
assert list(indices) == [1, 2]


@pytest.mark.skip(reason="todo")
def test_eval_bud_diff(example_data_path):
# get ia from grdfile
mfgrd_test_path = example_data_path / "mfgrd_test"
grb_path = mfgrd_test_path / "nwtp3.dis.grb"
grb = MfGrdFile(str(grb_path), verbose=True)
ia = grb._datadict["IA"] - 1

# TODO: create/run minimal model, then compare budget files


@pytest.mark.skip(reason="todo")
def test_compare_budget():
pass


@pytest.mark.skip(reason="todo")
def test_compare_swrbudget():
pass


@pytest.mark.skip(reason="todo")
def test_compare_heads():
pass


@pytest.mark.skip(reason="todo")
def test_compare_concs():
pass


@pytest.mark.skip(reason="todo")
def test_compare_stages():
pass


@pytest.mark.skip(reason="todo")
def test_compare():
pass
76 changes: 75 additions & 1 deletion autotest/test_gridutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import numpy as np
import pytest

from flopy.utils.gridutil import get_lni
from flopy.utils.gridutil import get_disu_kwargs, get_lni, uniform_flow_field


@pytest.mark.parametrize(
Expand Down Expand Up @@ -54,3 +54,77 @@ def test_get_lni_infers_layer_count_when_int_ncpl(ncpl, nodes, expected):
assert isinstance(lni, list)
for i, ln in enumerate(lni):
assert ln == expected[i]


@pytest.mark.parametrize(
"nlay, nrow, ncol, delr, delc, tp, botm",
[
(
1,
61,
61,
np.array(61 * [50]),
np.array(61 * [50]),
np.array([-10]),
np.array([-30.0, -50.0]),
),
(
2,
61,
61,
np.array(61 * [50]),
np.array(61 * [50]),
np.array([-10]),
np.array([-30.0, -50.0]),
),
],
)
def test_get_disu_kwargs(nlay, nrow, ncol, delr, delc, tp, botm):
kwargs = get_disu_kwargs(
nlay=nlay, nrow=nrow, ncol=ncol, delr=delr, delc=delc, tp=tp, botm=botm
)

from pprint import pprint

pprint(kwargs["area"])

assert kwargs["nodes"] == nlay * nrow * ncol
assert kwargs["nvert"] == None

area = np.array([dr * dc for (dr, dc) in product(delr, delc)], dtype=float)
area = np.array(nlay * [area]).flatten()
assert np.array_equal(kwargs["area"], area)

# TODO: test other properties
# print(kwargs["iac"])
# print(kwargs["ihc"])
# print(kwargs["ja"])
# print(kwargs["nja"])


@pytest.mark.parametrize(
"qx, qy, qz, nlay, nrow, ncol",
[
(1, 0, 0, 1, 1, 10),
(0, 1, 0, 1, 1, 10),
(0, 0, 1, 1, 1, 10),
(1, 0, 0, 1, 10, 10),
(1, 0, 0, 2, 10, 10),
(1, 1, 0, 2, 10, 10),
(1, 1, 1, 2, 10, 10),
(2, 1, 1, 2, 10, 10),
],
)
def test_uniform_flow_field(qx, qy, qz, nlay, nrow, ncol):
shape = nlay, nrow, ncol
spdis, flowja = uniform_flow_field(qx, qy, qz, shape)

assert spdis.shape == (nlay * nrow * ncol,)
for i, t in enumerate(spdis.flatten()):
assert t[0] == t[1] == i
assert t[3] == qx
assert t[4] == qy
assert t[5] == qz

# TODO: check flowja
# print(flowja.shape)
41 changes: 41 additions & 0 deletions autotest/test_mfreadnam.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import pytest
from autotest.conftest import get_example_data_path

from flopy.utils.mfreadnam import get_entries_from_namefile

_example_data_path = get_example_data_path()


@pytest.mark.parametrize(
"path",
[
_example_data_path / "mf6" / "test001a_Tharmonic" / "mfsim.nam",
_example_data_path / "mf6" / "test001e_UZF_3lay" / "mfsim.nam",
_example_data_path / "mf6-freyberg" / "mfsim.nam",
],
)
def test_get_entries_from_namefile_mf6(path):
package = "IMS6"
entries = get_entries_from_namefile(path, ftype=package)
assert len(entries) == 1

entry = entries[0]
assert path.parent.name in entry[0]
assert entry[1] == package


@pytest.mark.skip(reason="only supports mf6 namefiles")
@pytest.mark.parametrize(
"path",
[
_example_data_path / "mf6-freyberg" / "freyberg.nam",
],
)
def test_get_entries_from_namefile_mf2005(path):
package = "IC6"
entries = get_entries_from_namefile(path, ftype=package)
assert len(entries) == 1

entry = entries[0]
assert path.parent.name in entry[0]
assert entry[1] == package
Loading

0 comments on commit 94cd19d

Please sign in to comment.