Skip to content

Commit 630084d

Browse files
committed
benchmark
1 parent c0ac5bb commit 630084d

1 file changed

Lines changed: 115 additions & 0 deletions

File tree

autotest/test_prt_voronoi_perf.py

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
"""
2+
Bigger PRT benchmark on the Voronoi grid from test_prt_voronoi1.py.
3+
4+
Uses the same simple left-to-right flow field but with many more particles,
5+
generating many more track events. Meant to benchmark event buffer options,
6+
in-memory vs scratch file, at a scale where I/O overhead differences start
7+
to be measurable; very likely larger than configured here, but the runtime
8+
also grows quickly, so tune particle count and TDIS granularity as needed.
9+
"""
10+
11+
from pathlib import Path
12+
13+
import flopy
14+
import numpy as np
15+
import pytest
16+
from flopy.discretization import VertexGrid
17+
from framework import TestFramework
18+
from prt_test_utils import get_model_name
19+
from test_prt_voronoi1 import botm, build_gwf_sim, get_grid, nlay, porosity, top
20+
21+
simname = "prtvorperf"
22+
ntracktimes = 500
23+
tracktimes = list(np.linspace(0, 40000, ntracktimes))
24+
rpts = [[20, y, 0.5] for y in np.linspace(0.5, 999.5, 10000)]
25+
26+
27+
def build_prt_sim(name, gwf_ws, prt_ws, targets, scratch_buffer=False):
28+
prt_ws = Path(prt_ws)
29+
gwf_name = get_model_name(name, "gwf")
30+
prt_name = get_model_name(name, "prt")
31+
32+
grid = get_grid(prt_ws / "grid", targets)
33+
vgrid = VertexGrid(**grid.get_gridprops_vertexgrid(), nlay=1)
34+
35+
sim = flopy.mf6.MFSimulation(
36+
sim_name=name, version="mf6", exe_name=targets["mf6"], sim_ws=prt_ws
37+
)
38+
flopy.mf6.ModflowTdis(sim, time_units="DAYS", perioddata=[[1.0, 1, 1.0]])
39+
prt = flopy.mf6.ModflowPrt(sim, modelname=prt_name)
40+
flopy.mf6.ModflowGwfdisv(
41+
prt, nlay=nlay, **grid.get_disv_gridprops(), top=top, botm=botm
42+
)
43+
flopy.mf6.ModflowPrtmip(prt, pname="mip", porosity=porosity)
44+
45+
prpdata = [
46+
(i, (0, vgrid.intersect(p[0], p[1])), p[0], p[1], p[2])
47+
for i, p in enumerate(rpts)
48+
]
49+
prp_track_file = f"{prt_name}.prp.trk"
50+
flopy.mf6.ModflowPrtprp(
51+
prt,
52+
pname="prp1",
53+
filename=f"{prt_name}_1.prp",
54+
nreleasepts=len(prpdata),
55+
packagedata=prpdata,
56+
perioddata={0: ["FIRST"]},
57+
track_filerecord=[prp_track_file],
58+
boundnames=True,
59+
stop_at_weak_sink=True,
60+
exit_solve_tolerance=1e-10,
61+
extend_tracking=True,
62+
)
63+
flopy.mf6.ModflowPrtoc(
64+
prt,
65+
pname="oc",
66+
track_exit=True,
67+
track_release=True,
68+
track_terminate=True,
69+
track_usertime=True,
70+
ntracktimes=ntracktimes,
71+
tracktimes=[(t,) for t in tracktimes],
72+
scratch_buffer=scratch_buffer,
73+
)
74+
gwf_budget_file = gwf_ws / f"{gwf_name}.bud"
75+
gwf_head_file = gwf_ws / f"{gwf_name}.hds"
76+
flopy.mf6.ModflowPrtfmi(
77+
prt, packagedata=[("GWFHEAD", gwf_head_file), ("GWFBUDGET", gwf_budget_file)]
78+
)
79+
ems = flopy.mf6.ModflowEms(sim, pname="ems", filename=f"{prt_name}.ems")
80+
sim.register_solution_package(ems, [prt.name])
81+
return sim
82+
83+
84+
def build_models(test, scratch_buffer=False):
85+
gwf_sim, _ = build_gwf_sim(test.name, test.workspace, test.targets)
86+
prt_sim = build_prt_sim(
87+
test.name,
88+
test.workspace,
89+
test.workspace / "prt",
90+
test.targets,
91+
scratch_buffer=scratch_buffer,
92+
)
93+
return gwf_sim, prt_sim
94+
95+
96+
def check_output(test):
97+
prt_ws = test.workspace / "prt"
98+
prt_name = get_model_name(test.name, "prt")
99+
trk = prt_ws / f"{prt_name}.prp.trk"
100+
assert trk.exists() and trk.stat().st_size > 0
101+
102+
103+
@pytest.mark.skip(reason="run manually") # uncomment to run
104+
@pytest.mark.slow
105+
@pytest.mark.parametrize("scratch_buffer", [False, True], ids=["inmem", "scratch"])
106+
def test_mf6model(scratch_buffer, function_tmpdir, targets, benchmark):
107+
test = TestFramework(
108+
name=simname,
109+
workspace=function_tmpdir,
110+
build=lambda t: build_models(t, scratch_buffer),
111+
check=lambda t: check_output(t),
112+
targets=targets,
113+
compare=None,
114+
)
115+
benchmark.pedantic(test.run, rounds=1, iterations=1)

0 commit comments

Comments
 (0)