Skip to content

Commit 20ce356

Browse files
authored
fix(vtk): fix add_pathline_points prt data handling (#2732)
The logic to separate PRT pathlines by composite key for VTK export was - slow: O(n^4 * m) where n is unique values per column and m is the total number of rows - wrong: exported empty pathlines in most cases due to some incorrect filtering Replace the nested loops and repeated np.unique() calls with a single unique(return_inverse=True) taking a composite key dtype. Should be O(n log n) now.
1 parent 10031ad commit 20ce356

File tree

2 files changed

+35
-19
lines changed

2 files changed

+35
-19
lines changed

autotest/test_export.py

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import os
33
import shutil
44
from pathlib import Path
5+
from pprint import pformat
56

67
import matplotlib.pyplot as plt
78
import numpy as np
@@ -38,6 +39,7 @@
3839
)
3940
from flopy.modflow import Modflow, ModflowDis
4041
from flopy.modpath import Modpath6, Modpath6Bas
42+
from flopy.plot.plotutil import to_prt_pathlines
4143
from flopy.utils import (
4244
CellBudgetFile,
4345
HeadFile,
@@ -1508,8 +1510,6 @@ def test_vtk_unstructured(function_tmpdir, unstructured_grid):
15081510

15091511
@requires_pkg("vtk", "pyvista")
15101512
def test_vtk_to_pyvista(function_tmpdir):
1511-
from pprint import pformat
1512-
15131513
from autotest.test_mp7_cases import Mp7Cases
15141514

15151515
case_mf6 = Mp7Cases.mp7_mf6(function_tmpdir)
@@ -1529,13 +1529,29 @@ def test_vtk_to_pyvista(function_tmpdir):
15291529
assert grid.n_cells == gwf.modelgrid.nnodes
15301530

15311531
vtk.add_pathline_points(pls)
1532-
grid, pathlines = vtk.to_pyvista()
1532+
grid, mp7_pls = vtk.to_pyvista()
1533+
n_pts = sum(pl.shape[0] for pl in pls)
1534+
assert mp7_pls.n_points == n_pts
1535+
assert mp7_pls.n_cells == n_pts + len(pls)
1536+
assert "particleid" in mp7_pls.point_data
1537+
assert "time" in mp7_pls.point_data
1538+
assert "k" in mp7_pls.point_data
1539+
1540+
vtk = Vtk(model=gwf, binary=True, smooth=False)
1541+
assert not any(vtk.to_pyvista())
1542+
1543+
prt_pathlines = to_prt_pathlines(np.hstack(pls).view(np.recarray))
1544+
1545+
vtk.add_model(gwf)
1546+
vtk.add_pathline_points(prt_pathlines)
1547+
grid, prt_pls = vtk.to_pyvista()
15331548
n_pts = sum(pl.shape[0] for pl in pls)
1534-
assert pathlines.n_points == n_pts
1535-
assert pathlines.n_cells == n_pts + len(pls)
1536-
assert "particleid" in pathlines.point_data
1537-
assert "time" in pathlines.point_data
1538-
assert "k" in pathlines.point_data
1549+
assert prt_pls.n_points == n_pts
1550+
assert prt_pls.n_cells == n_pts + len(pls)
1551+
assert "imdl" in prt_pls.point_data
1552+
assert "iprp" in prt_pls.point_data
1553+
assert "irpt" in prt_pls.point_data
1554+
assert "trelease" in prt_pls.point_data
15391555

15401556
# uncomment to debug
15411557
# grid.plot()

flopy/export/vtk.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,17 +1109,17 @@ def add_pathline_points(self, pathlines, timeseries=False):
11091109
pids = np.unique(pathlines.particleid)
11101110
pathlines = [pathlines[pathlines.particleid == pid] for pid in pids]
11111111
elif all(k in pathlines.dtype.names for k in prt_fields):
1112-
pls = []
1113-
for imdl in np.unique(pathlines.imdl):
1114-
for iprp in np.unique(pathlines.iprp):
1115-
for irpt in np.unique(pathlines.irpt):
1116-
pl = pathlines[
1117-
(pathlines.imdl == imdl)
1118-
& (pathlines.iprp == iprp)
1119-
& (pathlines.irpt == irpt)
1120-
]
1121-
pls.extend([pl[pl.trelease == t] for t in np.unique(pl.t)])
1122-
pathlines = pls
1112+
# particle composite key
1113+
keys = np.column_stack(
1114+
[
1115+
pathlines["imdl"],
1116+
pathlines["iprp"],
1117+
pathlines["irpt"],
1118+
pathlines["trelease"],
1119+
]
1120+
)
1121+
_, inv = np.unique(keys, axis=0, return_inverse=True)
1122+
pathlines = [pathlines[inv == i] for i in range(inv.max() + 1)]
11231123
else:
11241124
raise ValueError("Unrecognized pathline dtype")
11251125
else:

0 commit comments

Comments
 (0)