-
Notifications
You must be signed in to change notification settings - Fork 323
/
Copy pathtest_cbc_full3D.py
163 lines (126 loc) · 4.25 KB
/
test_cbc_full3D.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
import os
from pathlib import Path
import numpy as np
import pytest
from modflow_devtools.markers import requires_exe
from autotest.conftest import get_example_data_path
from flopy.mf6 import MFSimulation, ModflowGwfoc
from flopy.modflow import Modflow
from flopy.utils import CellBudgetFile
example_data_path = get_example_data_path()
mf2005_paths = [
str(example_data_path / "freyberg"),
]
mf6_paths = [
str(example_data_path / "mf6-freyberg"),
str(example_data_path / "mf6" / "test003_gwfs_disv"),
str(example_data_path / "mf6" / "test003_gwftri_disv"),
]
def load_mf2005(path, ws_out):
name_file = f"{Path(path).name}.nam"
ml = Modflow.load(
name_file,
model_ws=path,
exe_name="mf2005",
check=False,
)
# change work space
ml.change_model_ws(ws_out)
# save all budget data to a cell-by cell file
oc = ml.get_package("OC")
oc.reset_budgetunit()
oc.stress_period_data = {(0, 0): ["save budget"]}
return ml
@pytest.mark.mf6
def load_mf6(path, ws_out):
sim = MFSimulation.load(
sim_name=Path(path).name,
exe_name="mf6",
sim_ws=path,
)
# change work space
sim.set_sim_path(ws_out)
# get the groundwater flow model(s) and redefine the output control
# file to save cell by cell output
models = sim.model_names
for model in models:
gwf = sim.get_model(model)
gwf.name_file.save_flows = True
gwf.remove_package("oc")
budget_filerecord = f"{model}.cbc"
oc = ModflowGwfoc(
gwf,
budget_filerecord=budget_filerecord,
saverecord=[("BUDGET", "ALL")],
)
return sim
def cbc_eval_size(cbcobj, nnodes, shape3d):
cbc_pth = cbcobj.filename
assert cbcobj.nnodes == nnodes, (
f"{cbc_pth} nnodes ({cbcobj.nnodes}) does not equal {nnodes}"
)
a = np.squeeze(np.ones(cbcobj.shape, dtype=float))
b = np.squeeze(np.ones(shape3d, dtype=float))
assert a.shape == b.shape, (
f"{cbc_pth} shape {cbcobj.shape} does not conform to {shape3d}"
)
def cbc_eval_data(cbcobj, shape3d):
cbc_pth = cbcobj.filename
print(f"{cbc_pth}:\n")
print(cbcobj.headers[["text", "imeth"]].drop_duplicates())
names = cbcobj.get_unique_record_names(decode=True)
times = cbcobj.get_times()
for name in names:
text = name.strip()
arr = np.squeeze(cbcobj.get_data(text=text, totim=times[0], full3D=True)[0])
if text != "FLOW-JA-FACE":
b = np.squeeze(np.ones(shape3d, dtype=float))
assert arr.shape == b.shape, (
f"{cbc_pth} shape {arr.shape} for '{text}' budget item "
f"does not conform to {shape3d}"
)
def cbc_eval(cbcobj, nnodes, shape3d, modelgrid):
cbc_pth = cbcobj.filename
cbc_eval_size(cbcobj, nnodes, shape3d)
cbc_eval_data(cbcobj, shape3d)
cbcobj.close()
cobj_mg = CellBudgetFile(
cbc_pth,
modelgrid=modelgrid,
verbose=True,
)
cbc_eval_size(cobj_mg, nnodes, shape3d)
cbc_eval_data(cobj_mg, shape3d)
cobj_mg.close()
@requires_exe("mf6")
@pytest.mark.mf6
@pytest.mark.parametrize("path", mf6_paths)
def test_cbc_full3D_mf6(function_tmpdir, path):
sim = load_mf6(path, function_tmpdir)
# write the simulation
sim.write_simulation()
# run the simulation
sim.run_simulation()
# get the groundwater model and determine the size of the model grid
gwf_name = next(iter(sim.model_names))
gwf = sim.get_model(gwf_name)
nnodes, shape3d = gwf.modelgrid.nnodes, gwf.modelgrid.shape
# get the cell by cell object
cbc = gwf.output.budget()
# evaluate the full3D option
cbc_eval(cbc, nnodes, shape3d, gwf.modelgrid)
@requires_exe("mf2005")
@pytest.mark.parametrize("path", mf2005_paths)
def test_cbc_full3D_mf2005(function_tmpdir, path):
ml = load_mf2005(path, function_tmpdir)
# write the model
ml.write_input()
# run the model
ml.run_model()
# determine the size of the model grid
nnodes, shape3d = ml.modelgrid.nnodes, ml.modelgrid.shape
# get the cell by cell object
fpth = function_tmpdir / f"{Path(path).name}.cbc"
cbc = CellBudgetFile(fpth)
# evaluate the full3D option
cbc_eval(cbc, nnodes, shape3d, ml.modelgrid)