Skip to content

Commit f3f6938

Browse files
fix(gwf-uzf.f90): auxmultname option not working as expected (#1930)
* fix(gwf-uzf.f90): auxmultname option not working as expected * use xfail for determining test status * Update doc/ReleaseNotes/develop.tex Co-authored-by: langevin-usgs <[email protected]> --------- Co-authored-by: langevin-usgs <[email protected]>
1 parent 61f1e31 commit f3f6938

File tree

3 files changed

+274
-1
lines changed

3 files changed

+274
-1
lines changed

autotest/test_gwf_uzf_auxmult.py

Lines changed: 272 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,272 @@
1+
"""
2+
A simple test of multiple UZF objects within a cell.
3+
The fourth sub-test is designed to fail. An assert statement
4+
ensure this to be the case.
5+
"""
6+
7+
import flopy
8+
import numpy as np
9+
import pytest
10+
11+
from framework import TestFramework
12+
13+
cases = ["uzauxmlt-1to1", "uzauxmlt-2to1", "uzauxmlt-3to1", "uzauxmlt-bad"]
14+
uzarea_correspondences = ("1to1", "2to1", "3to1", "bad")
15+
iuz_cell_dict = {}
16+
cell_iuz_dict = {}
17+
18+
nouter, ninner = 100, 300
19+
hclose, rclose, relax = 1e-9, 1e-3, 0.97
20+
21+
uzarea_data = {
22+
uzarea_correspondences[0]: {
23+
"uzf_pkdat": [
24+
[0, (0, 0, 3), 1, -1, 1.0, 1e-5, 0.2, 0.3, 0.25, 3.5, "uzf01"],
25+
[1, (0, 0, 4), 1, -1, 1.0, 1e-5, 0.2, 0.3, 0.25, 3.5, "uzf02"],
26+
[2, (0, 0, 5), 1, -1, 1.0, 1e-5, 0.2, 0.3, 0.25, 3.5, "uzf03"],
27+
[3, (0, 0, 6), 1, -1, 1.0, 1e-5, 0.2, 0.3, 0.25, 3.5, "uzf04"],
28+
],
29+
"auxmultval": 1.0,
30+
},
31+
uzarea_correspondences[1]: {
32+
"uzf_pkdat": [
33+
[0, (0, 0, 3), 1, -1, 1.0, 1e-5, 0.2, 0.3, 0.25, 3.5, "uzf01"],
34+
[1, (0, 0, 3), 1, -1, 1.0, 1e-5, 0.2, 0.3, 0.25, 3.5, "uzf01"],
35+
[2, (0, 0, 4), 1, -1, 1.0, 1e-5, 0.2, 0.3, 0.25, 3.5, "uzf02"],
36+
[3, (0, 0, 4), 1, -1, 1.0, 1e-5, 0.2, 0.3, 0.25, 3.5, "uzf02"],
37+
[4, (0, 0, 5), 1, -1, 1.0, 1e-5, 0.2, 0.3, 0.25, 3.5, "uzf03"],
38+
[5, (0, 0, 5), 1, -1, 1.0, 1e-5, 0.2, 0.3, 0.25, 3.5, "uzf03"],
39+
[6, (0, 0, 6), 1, -1, 1.0, 1e-5, 0.2, 0.3, 0.25, 3.5, "uzf04"],
40+
[7, (0, 0, 6), 1, -1, 1.0, 1e-5, 0.2, 0.3, 0.25, 3.5, "uzf04"],
41+
],
42+
"auxmultval": 0.5,
43+
},
44+
uzarea_correspondences[2]: {
45+
"uzf_pkdat": [
46+
[0, (0, 0, 3), 1, -1, 1.0, 1e-5, 0.2, 0.3, 0.25, 3.5, "uzf01"],
47+
[1, (0, 0, 3), 1, -1, 1.0, 1e-5, 0.2, 0.3, 0.25, 3.5, "uzf01"],
48+
[2, (0, 0, 3), 1, -1, 1.0, 1e-5, 0.2, 0.3, 0.25, 3.5, "uzf01"],
49+
[3, (0, 0, 4), 1, -1, 1.0, 1e-5, 0.2, 0.3, 0.25, 3.5, "uzf02"],
50+
[4, (0, 0, 4), 1, -1, 1.0, 1e-5, 0.2, 0.3, 0.25, 3.5, "uzf02"],
51+
[5, (0, 0, 4), 1, -1, 1.0, 1e-5, 0.2, 0.3, 0.25, 3.5, "uzf02"],
52+
[6, (0, 0, 5), 1, -1, 1.0, 1e-5, 0.2, 0.3, 0.25, 3.5, "uzf03"],
53+
[7, (0, 0, 5), 1, -1, 1.0, 1e-5, 0.2, 0.3, 0.25, 3.5, "uzf03"],
54+
[8, (0, 0, 5), 1, -1, 1.0, 1e-5, 0.2, 0.3, 0.25, 3.5, "uzf03"],
55+
[9, (0, 0, 6), 1, -1, 1.0, 1e-5, 0.2, 0.3, 0.25, 3.5, "uzf04"],
56+
[10, (0, 0, 6), 1, -1, 1.0, 1e-5, 0.2, 0.3, 0.25, 3.5, "uzf04"],
57+
[11, (0, 0, 6), 1, -1, 1.0, 1e-5, 0.2, 0.3, 0.25, 3.5, "uzf04"],
58+
],
59+
"auxmultval": 0.333,
60+
},
61+
uzarea_correspondences[3]: {
62+
"uzf_pkdat": [
63+
[0, (0, 0, 3), 1, -1, 1.0, 1e-5, 0.2, 0.3, 0.25, 3.5, "uzf01"],
64+
[1, (0, 0, 3), 1, -1, 1.0, 1e-5, 0.2, 0.3, 0.25, 3.5, "uzf01"],
65+
[2, (0, 0, 3), 1, -1, 1.0, 1e-5, 0.2, 0.3, 0.25, 3.5, "uzf01"],
66+
[3, (0, 0, 4), 1, -1, 1.0, 1e-5, 0.2, 0.3, 0.25, 3.5, "uzf02"],
67+
[4, (0, 0, 4), 1, -1, 1.0, 1e-5, 0.2, 0.3, 0.25, 3.5, "uzf02"],
68+
[5, (0, 0, 4), 1, -1, 1.0, 1e-5, 0.2, 0.3, 0.25, 3.5, "uzf02"],
69+
[6, (0, 0, 5), 1, -1, 1.0, 1e-5, 0.2, 0.3, 0.25, 3.5, "uzf03"],
70+
[7, (0, 0, 5), 1, -1, 1.0, 1e-5, 0.2, 0.3, 0.25, 3.5, "uzf03"],
71+
[8, (0, 0, 5), 1, -1, 1.0, 1e-5, 0.2, 0.3, 0.25, 3.5, "uzf03"],
72+
[9, (0, 0, 6), 1, -1, 1.0, 1e-5, 0.2, 0.3, 0.25, 3.5, "uzf04"],
73+
[10, (0, 0, 6), 1, -1, 1.0, 1e-5, 0.2, 0.3, 0.25, 3.5, "uzf04"],
74+
[11, (0, 0, 6), 1, -1, 1.0, 1e-5, 0.2, 0.3, 0.25, 3.5, "uzf04"],
75+
],
76+
"auxmultval": 0.334,
77+
},
78+
}
79+
80+
81+
def build_models(idx, test):
82+
name = cases[idx]
83+
uzarea_correspondence = uzarea_correspondences[idx]
84+
85+
nlay, nrow, ncol = 3, 1, 10
86+
nper = 1
87+
perlen = [1.0]
88+
nstp = [1]
89+
tsmult = [1.0]
90+
91+
delr = 100.0
92+
delc = 100.0
93+
strt = -9.0
94+
95+
tdis_rc = []
96+
for i in range(nper):
97+
tdis_rc.append((perlen[i], nstp[i], tsmult[i]))
98+
99+
# build MODFLOW 6 files
100+
ws = test.workspace
101+
sim = flopy.mf6.MFSimulation(
102+
sim_name=name, version="mf6", exe_name="mf6", sim_ws=ws
103+
)
104+
105+
# create tdis package
106+
flopy.mf6.ModflowTdis(
107+
sim, time_units="DAYS", nper=nper, perioddata=tdis_rc
108+
)
109+
110+
# create gwf model
111+
gwf = flopy.mf6.ModflowGwf(
112+
sim, modelname=name, newtonoptions="NEWTON", save_flows=True
113+
)
114+
115+
# create iterative model solution and register the gwf model with it
116+
ims = flopy.mf6.ModflowIms(
117+
sim,
118+
print_option="SUMMARY",
119+
complexity="MODERATE",
120+
outer_dvclose=hclose,
121+
outer_maximum=nouter,
122+
under_relaxation="DBD",
123+
inner_maximum=ninner,
124+
inner_dvclose=hclose,
125+
rcloserecord=rclose,
126+
linear_acceleration="BICGSTAB",
127+
scaling_method="NONE",
128+
reordering_method="NONE",
129+
relaxation_factor=relax,
130+
)
131+
sim.register_ims_package(ims, [gwf.name])
132+
133+
flopy.mf6.ModflowGwfdis(
134+
gwf,
135+
nlay=nlay,
136+
nrow=nrow,
137+
ncol=ncol,
138+
delr=delr,
139+
delc=delc,
140+
top=0.0,
141+
botm=[-10.0, -20.0, -30.0],
142+
)
143+
144+
# initial conditions
145+
flopy.mf6.ModflowGwfic(gwf, strt=strt)
146+
147+
# node property flow
148+
flopy.mf6.ModflowGwfnpf(
149+
gwf,
150+
save_flows=True,
151+
icelltype=1,
152+
k=1.0e-4,
153+
k22=1.0e-4,
154+
k33=1.0e-5,
155+
)
156+
157+
# aquifer storage
158+
flopy.mf6.ModflowGwfsto(
159+
gwf,
160+
save_flows=True,
161+
iconvert=1,
162+
ss=1e-5,
163+
sy=0.2,
164+
transient=True,
165+
)
166+
167+
# chd files
168+
chdval = -9.0
169+
iface = 0
170+
chdspd = {
171+
0: [
172+
[(0, 0, 0), chdval, iface, "object0"],
173+
[(0, 0, ncol - 1), chdval, iface, "object0"],
174+
]
175+
}
176+
flopy.mf6.ModflowGwfchd(
177+
gwf,
178+
auxiliary="iface",
179+
boundnames=True,
180+
print_input=True,
181+
save_flows=True,
182+
stress_period_data=chdspd,
183+
)
184+
185+
# transient uzf info
186+
# ifno cellid landflg ivertcn surfdp vks thtr thts thti eps [bndnm]
187+
uz_pkdat = uzarea_data[uzarea_correspondence]["uzf_pkdat"]
188+
189+
for itm in uz_pkdat:
190+
iuz_cell_dict.update({itm[0]: (itm[1][0], itm[1][1], itm[1][2])})
191+
cell_iuz_dict.update({(itm[1][0], itm[1][1], itm[1][2]): itm[0]})
192+
193+
finf = 1.0
194+
extdp = 0.0
195+
extwc = 0.0
196+
pet = 0.0
197+
zero = 0.0
198+
auxmultval = uzarea_data[uzarea_correspondence]["auxmultval"]
199+
uzf_spd = {
200+
0: [
201+
[i, finf, pet, extdp, extwc, zero, zero, zero, auxmultval]
202+
for i in np.arange(len(uz_pkdat))
203+
]
204+
}
205+
206+
flopy.mf6.ModflowGwfuzf(
207+
gwf,
208+
print_input=True,
209+
print_flows=True,
210+
save_flows=True,
211+
boundnames=True,
212+
ntrailwaves=7,
213+
nwavesets=40,
214+
auxiliary="multiplier",
215+
auxmultname="multiplier",
216+
package_convergence_filerecord=f"{name}.UzfConvergence.csv",
217+
wc_filerecord=f"{name}.wc",
218+
nuzfcells=len(uz_pkdat),
219+
packagedata=uz_pkdat,
220+
perioddata=uzf_spd,
221+
budget_filerecord=f"{name}.uzf.bud",
222+
filename=f"{name}.uzf",
223+
)
224+
225+
# output control
226+
flopy.mf6.ModflowGwfoc(
227+
gwf,
228+
budget_filerecord=f"{name}.cbc",
229+
head_filerecord=f"{name}.hds",
230+
headprintrecord=[("COLUMNS", 10, "WIDTH", 15, "DIGITS", 6, "GENERAL")],
231+
saverecord=[("HEAD", "ALL"), ("BUDGET", "ALL")],
232+
printrecord=[("HEAD", "ALL"), ("BUDGET", "ALL")],
233+
filename=f"{name}.oc",
234+
)
235+
236+
return sim
237+
238+
239+
def check_output(idx, test):
240+
print("Running error check")
241+
name = cases[idx]
242+
243+
errmsg0 = f"flow model should have run successfully but didn't\n"
244+
errmsg1 = (
245+
f"flow model designed to fail, but seems to have run successfully\n"
246+
)
247+
248+
with open(test.workspace / "mfsim.lst", "r") as f:
249+
lines = f.readlines()
250+
error_count = 0
251+
for line in lines:
252+
if "error report" in line.lower():
253+
error_count += 1
254+
255+
if "bad" in name:
256+
assert error_count > 0, errmsg1
257+
else:
258+
assert error_count == 0, errmsg0
259+
260+
261+
@pytest.mark.parametrize("idx,name", enumerate(cases))
262+
def test_mf6model(idx, name, function_tmpdir, targets):
263+
xfail = ["bad" in cases[ct] for ct in np.arange(len(cases))]
264+
test = TestFramework(
265+
name=name,
266+
workspace=function_tmpdir,
267+
build=lambda t: build_models(idx, t),
268+
check=lambda t: check_output(idx, t),
269+
targets=targets,
270+
xfail=xfail[idx],
271+
)
272+
test.run()

doc/ReleaseNotes/develop.tex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
\item A refactor of the energy storage and transfer (EST) package associated with the GWE model type results in different input requirements that breaks backward compatibility with what was required in version 6.5.0. The PACKAGEDATA block was removed from the EST package input. In its place, the heat capabity of water, the specified density of water, and the latent heat of vaporization are instead given default values that can be overridden by specifying alternative values in the OPTIONS block.
2929
\item The PRT model's cell face flows were improperly combined with boundary flows; for cell faces with active neighbors, the face flow replaced any boundary flows (likely a rare situation because IFLOWFACE is typically applied to faces on the boundary of the active domain). The face flow calculation has been corrected.
3030
\item A bad pointer reference has been fixed in the PRT model. Depending on the combination of platform and compiler used to build the program, this could result in crashes (e.g. divide by zero errors) or in silent failures to properly pass particles downward between vertically adjacent cells, leading to early termination. The latter could occur as a consequence of undefined behavior which prevented detection of situations when a particle should exit a cell through its bottom face.
31+
\item For a UZF setup with multiple UZF objects in a cell, the auxmultname option would cause the program to issue an unnecessary error. The program was corrected to remove the unnecessary error. The revised program was tested to ensure that the assignment of multiple UZF objects per cell works when it should and fails when the cumulative area of the UZF objects within a cell exceed the total area for the cell.
3132
% \item xxx
3233
\end{itemize}
3334

src/Model/GroundWaterFlow/gwf-uzf.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2252,7 +2252,7 @@ subroutine check_cell_area(this)
22522252
cellarea = this%uzfobj%cellarea(i)
22532253
end do
22542254
! -- calculate the difference between the sum of UZF areas and GWF cell area
2255-
d = abs(sumarea - cellarea)
2255+
d = sumarea - cellarea
22562256
if (d > DEM6) then
22572257
call this%dis%noder_to_string(n, cellid)
22582258
write (errmsg, '(a,1x,g0,1x,a,1x,g0,1x,a,1x,a,1x,a,a,a)') &

0 commit comments

Comments
 (0)