Skip to content

Commit 069ae59

Browse files
Simplifying particleset.populate_indices
1 parent 7e3e842 commit 069ae59

2 files changed

Lines changed: 17 additions & 22 deletions

File tree

parcels/particleset.py

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,11 @@
66

77
import numpy as np
88
import xarray as xr
9-
from scipy.spatial import KDTree
109
from tqdm import tqdm
1110

1211
from parcels._core.utils.time import TimeInterval, maybe_convert_python_timedelta_to_numpy
1312
from parcels._reprs import particleset_repr
1413
from parcels.application_kernels.advection import AdvectionRK4
15-
from parcels.basegrid import GridType
1614
from parcels.kernel import Kernel
1715
from parcels.particle import KernelParticle, Particle, create_particle_data
1816
from parcels.tools.converters import convert_to_flat_array
@@ -308,28 +306,17 @@ def _neighbors_by_coor(self, coor):
308306
neighbor_ids = self._data["trajectory"][neighbor_idx]
309307
return neighbor_ids
310308

311-
# TODO: This method is only tested in tutorial notebook. Add unit test?
312309
def populate_indices(self):
313-
"""Pre-populate guesses of particle ei (element id) indices using a kdtree.
314-
315-
This is only intended for curvilinear grids, where the initial index search
316-
may be quite expensive.
317-
"""
310+
"""Pre-populate guesses of particle ei (element id) indices"""
318311
for i, grid in enumerate(self.fieldset.gridset):
319-
if grid._gtype not in [GridType.CurvilinearZGrid, GridType.CurvilinearSGrid]:
320-
continue
321-
322-
tree_data = np.stack((grid.lon.flat, grid.lat.flat), axis=-1)
323-
IN = np.all(~np.isnan(tree_data), axis=1)
324-
tree = KDTree(tree_data[IN, :])
325-
# stack all the particle positions for a single query
326-
pts = np.stack((self._data["lon"], self._data["lat"]), axis=-1)
327-
# query datatype needs to match tree datatype
328-
_, idx_nan = tree.query(pts.astype(tree_data.dtype))
329-
330-
idx = np.where(IN)[0][idx_nan]
331-
332-
self._data["ei"][:, i] = idx # assumes that we are in the surface layer (zi=0)
312+
position = grid.search(self.depth, self.lat, self.lon)
313+
self._data["ei"][:, i] = grid.ravel_index(
314+
{
315+
"X": position["X"][0],
316+
"Y": position["Y"][0],
317+
"Z": position["Z"][0],
318+
}
319+
)
333320

334321
@classmethod
335322
def from_particlefile(cls, fieldset, pclass, filename, restart=True, restarttime=None, **kwargs):

tests/v4/test_particleset.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from parcels._datasets.structured.generic import datasets as datasets_structured
1818
from parcels.xgrid import XGrid
1919
from tests.common_kernels import DoNothing
20+
from tests.utils import round_and_hash_float_array
2021

2122

2223
@pytest.fixture
@@ -126,6 +127,13 @@ def Addlon(particles, fieldset): # pragma: no cover
126127
assert np.allclose([p.lon_nextloop for p in pset], [8 - t for t in times])
127128

128129

130+
def test_populate_indices(fieldset):
131+
npart = 11
132+
pset = ParticleSet(fieldset, lon=np.linspace(0, 1, npart), lat=np.linspace(1, 0, npart))
133+
pset.populate_indices()
134+
np.testing.assert_equal(round_and_hash_float_array(pset.ei, decimals=0), 935996932384571063274191)
135+
136+
129137
def test_pset_add_explicit(fieldset):
130138
npart = 11
131139
lon = np.linspace(0, 1, npart)

0 commit comments

Comments
 (0)