Skip to content

Commit ba29c04

Browse files
authored
fix(prt): make extended tracking opt-in (#1888)
Previously the PRT model's default behavior was to track particles until termination, as with MODPATH 7 stop time option 2 (extend). Under extended tracking, the program may not halt if particles enter a cycle in the flow system. This PR changes the default to the equivalent of MP7 stop time option 1 (final), terminating at simulation end unless a new Particle Release Point (PRP) package keyword option EXTEND is provided. This is meant to provide a stronger guarantee that the program halts under default settings. The extend option is stored as an integer rather than logical in case we need to enumerate more alternatives in future. This PR also avoids unnecessary iterations in MethodSubcellPollock/Ternary, and changes the default visibility of ParticleStore members to private, as per style conventions.
1 parent 34ef2f7 commit ba29c04

25 files changed

+120
-66
lines changed

autotest/test_prt_budget.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ def build_prt_sim(name, gwf_ws, prt_ws, mf6):
8989
stop_at_weak_sink=False,
9090
boundnames=True,
9191
exit_solve_tolerance=DEFAULT_EXIT_SOLVE_TOL,
92+
extend_tracking=True,
9293
)
9394

9495
# create output control package

autotest/test_prt_disv1.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ def build_prt_sim(idx, gwf_ws, prt_ws, mf6):
236236
print_input=True,
237237
dev_forceternary=i == 1,
238238
exit_solve_tolerance=1e-10,
239+
extend_tracking=True,
239240
)
240241

241242
# create output control package

autotest/test_prt_drape.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ def build_prt_sim(name, gwf_ws, prt_ws, mf6):
190190
trackcsv_filerecord=[prp_track_csv_file],
191191
drape="drp" in name,
192192
exit_solve_tolerance=DEFAULT_EXIT_SOLVE_TOL,
193+
extend_tracking=True,
193194
)
194195

195196
# create output control package

autotest/test_prt_exg.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ def build_mf6_sim(idx, test):
7979
perioddata={0: ["FIRST"]},
8080
boundnames="bnms" in name,
8181
exit_solve_tolerance=DEFAULT_EXIT_SOLVE_TOL,
82+
extend_tracking=True,
8283
)
8384

8485
# create output control package

autotest/test_prt_fmi.py

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@
4848
DEFAULT_EXIT_SOLVE_TOL,
4949
)
5050

51-
simname = "prtfmi01"
52-
cases = [simname, f"{simname}saws", f"{simname}bprp"]
51+
simname = "prtfmi"
52+
cases = [simname, f"{simname}saws", f"{simname}bprp", f"{simname}noext"]
5353

5454

5555
def build_prt_sim(name, gwf_ws, prt_ws, mf6):
@@ -123,6 +123,7 @@ def build_prt_sim(name, gwf_ws, prt_ws, mf6):
123123
stop_at_weak_sink="saws" in prt_name,
124124
boundnames=True,
125125
exit_solve_tolerance=DEFAULT_EXIT_SOLVE_TOL,
126+
extend_tracking="noext" not in prt_name,
126127
)
127128

128129
# create output control package
@@ -346,28 +347,32 @@ def check_output(idx, test):
346347
plt.show()
347348
plt.savefig(gwf_ws / f"test_{simname}.png")
348349

349-
# convert mf6 pathlines to mp7 format
350-
mf6_pls = to_mp7_pathlines(mf6_pls)
351-
352-
# sort both dataframes by particleid and time
353-
mf6_pls.sort_values(by=["particleid", "time"], inplace=True)
354-
mp7_pls.sort_values(by=["particleid", "time"], inplace=True)
355-
356-
# drop columns for which there is no direct correspondence between mf6 and mp7
357-
del mf6_pls["sequencenumber"]
358-
del mf6_pls["particleidloc"]
359-
del mf6_pls["xloc"]
360-
del mf6_pls["yloc"]
361-
del mf6_pls["zloc"]
362-
del mp7_pls["sequencenumber"]
363-
del mp7_pls["particleidloc"]
364-
del mp7_pls["xloc"]
365-
del mp7_pls["yloc"]
366-
del mp7_pls["zloc"]
367-
368-
# compare mf6 / mp7 pathline data
369-
assert mf6_pls.shape == mp7_pls.shape
370-
assert np.allclose(mf6_pls, mp7_pls, atol=1e-3)
350+
if "noext" in name:
351+
# maximum tracking time should be simulation stop time
352+
assert mf6_pls.t.max() == FlopyReadmeCase.nper * FlopyReadmeCase.perlen
353+
else:
354+
# convert mf6 pathlines to mp7 format
355+
mf6_pls = to_mp7_pathlines(mf6_pls)
356+
357+
# sort both dataframes by particleid and time
358+
mf6_pls.sort_values(by=["particleid", "time"], inplace=True)
359+
mp7_pls.sort_values(by=["particleid", "time"], inplace=True)
360+
361+
# drop columns for which there is no direct correspondence between mf6 and mp7
362+
del mf6_pls["sequencenumber"]
363+
del mf6_pls["particleidloc"]
364+
del mf6_pls["xloc"]
365+
del mf6_pls["yloc"]
366+
del mf6_pls["zloc"]
367+
del mp7_pls["sequencenumber"]
368+
del mp7_pls["particleidloc"]
369+
del mp7_pls["xloc"]
370+
del mp7_pls["yloc"]
371+
del mp7_pls["zloc"]
372+
373+
# compare mf6 / mp7 pathline data
374+
assert mf6_pls.shape == mp7_pls.shape
375+
assert np.allclose(mf6_pls, mp7_pls, atol=1e-3)
371376

372377

373378
@pytest.mark.parametrize("idx, name", enumerate(cases))

autotest/test_prt_quad_refinement.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ def build_mf6_sim(idx, test, **kwargs):
154154
perioddata={0: ["FIRST"]},
155155
exit_solve_tolerance=DEFAULT_EXIT_SOLVE_TOL,
156156
dev_forceternary=tracking_method == "ternary",
157+
extend_tracking=True,
157158
)
158159
prt_track_file = f"{prt_name}.trk"
159160
prt_track_csv_file = f"{prt_name}.trk.csv"

autotest/test_prt_release_timing.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ def build_prt_sim(name, gwf_ws, prt_ws, mf6, fraction=None):
177177
),
178178
print_input=True,
179179
exit_solve_tolerance=DEFAULT_EXIT_SOLVE_TOL,
180+
extend_tracking=True,
180181
)
181182

182183
# create output control package

autotest/test_prt_stop_zones.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ def build_prt_sim(name, gwf_ws, prt_ws, mf6):
131131
perioddata={0: ["FIRST"]},
132132
istopzone=1,
133133
exit_solve_tolerance=DEFAULT_EXIT_SOLVE_TOL,
134+
extend_tracking=True,
134135
)
135136

136137
# create output control package

autotest/test_prt_ternary_methods.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ def build_prt_sim(
100100
stop_at_weak_sink=True, # currently required for this problem
101101
dev_exit_solve_method=methods[idx],
102102
exit_solve_tolerance=exit_solve_tolerance,
103+
extend_tracking=True,
103104
)
104105
prt_track_file = f"{prtname}.trk"
105106
prt_track_csv_file = f"{prtname}.trk.csv"

autotest/test_prt_track_events.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ def build_prt_sim(name, gwf_ws, prt_ws, mf6):
143143
packagedata=releasepts_prt[grp],
144144
perioddata={0: ["FIRST"]},
145145
exit_solve_tolerance=DEFAULT_EXIT_SOLVE_TOL,
146+
extend_tracking=True,
146147
)
147148
for grp in ["a", "b"]
148149
]

0 commit comments

Comments
 (0)