From 8d3c90d28fb19fa50aff95dd9ade6e639034a05b Mon Sep 17 00:00:00 2001 From: Erik van Sebille Date: Mon, 26 Oct 2026 20:57:05 +0100 Subject: [PATCH 1/2] Adding test for checkoing pset.ei updating on xgrid --- tests/test_advection.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/test_advection.py b/tests/test_advection.py index b5d83e7cc..7490c9eea 100644 --- a/tests/test_advection.py +++ b/tests/test_advection.py @@ -16,6 +16,7 @@ Variable, convert, ) +from parcels._core.field import _get_positions from parcels._core.utils.time import timedelta_to_float from parcels._core.warnings import FieldEvalWarning from parcels._datasets.structured.generated import ( @@ -153,6 +154,26 @@ def test_horizontal_advection_in_3D_flow(mesh_str, npart=10): np.testing.assert_allclose(pset.x, expected_lon, atol=1.0e-1) +@pytest.mark.parametrize("npart", [1, 5]) +def test_ei_update_during_xgrid_advection(npart): + ds = simple_UV_dataset(mesh_str="flat") + ds["U"].data[:] = 100.0 + ds["V"].data[:] = -20.0 + fieldset = FieldSet.from_sgrid_conventions(ds) + + pset = ParticleSet(fieldset, x=np.linspace(0, 3e5, npart), y=np.zeros(npart)) + pset.populate_indices() + ei_before = pset.ei.copy() + + pset.execute(AdvectionRK4, runtime=np.timedelta64(1, "h"), dt=np.timedelta64(15, "m")) + + _, grid_positions = _get_positions(fieldset.U, pset.t, pset.z, pset.y, pset.x, pset, pset.ei[:, 0]) + ei_after = fieldset.U.grid.unravel_index(pset.ei[:, 0]) + assert np.all(pset.ei != ei_before) + np.testing.assert_allclose(grid_positions["X"]["index"], ei_after["X"]) + np.testing.assert_allclose(grid_positions["Y"]["index"], ei_after["Y"]) + + @pytest.mark.parametrize("direction", ["up", "down"]) @pytest.mark.parametrize("resubmerge_particle", [True, False]) def test_advection_3D_outofbounds(direction, resubmerge_particle): From be7dc0e5707282b07e69d8453b5b3c7e7588149c Mon Sep 17 00:00:00 2001 From: Erik van Sebille Date: Mon, 26 Oct 2026 20:58:47 +0100 Subject: [PATCH 2/2] Adding test for checking ei updating for ugrid Also fixing pset.populate_indices to work with ugrid too --- src/parcels/_core/particleset.py | 9 ++------- tests/test_advection.py | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/parcels/_core/particleset.py b/src/parcels/_core/particleset.py index 1067b212b..075403b9c 100644 --- a/src/parcels/_core/particleset.py +++ b/src/parcels/_core/particleset.py @@ -264,13 +264,8 @@ def populate_indices(self): """Pre-populate guesses of particle ei (element id) indices""" for i, grid in enumerate(self.fieldset.gridset): grid_positions = grid.search(self.z, self.y, self.x) - self._data["ei"][:, i] = grid.ravel_index( - { - "X": grid_positions["X"]["index"], - "Y": grid_positions["Y"]["index"], - "Z": grid_positions["Z"]["index"], - } - ) + axes = ("Z", "FACE") if isinstance(grid, UxGrid) else ("X", "Y", "Z") + self._data["ei"][:, i] = grid.ravel_index({axis: grid_positions[axis]["index"] for axis in axes}) @classmethod def from_particlefile(cls, fieldset, pclass, filename, restart=True, restarttime=None, **kwargs): diff --git a/tests/test_advection.py b/tests/test_advection.py index 7490c9eea..e12b05b4b 100644 --- a/tests/test_advection.py +++ b/tests/test_advection.py @@ -29,6 +29,7 @@ stommel_gyre_dataset, ) from parcels._datasets.structured.generic import datasets_sgrid +from parcels._datasets.unstructured.generated import simple_small_delaunay from parcels.kernels import ( RK2, RK4, @@ -174,6 +175,23 @@ def test_ei_update_during_xgrid_advection(npart): np.testing.assert_allclose(grid_positions["Y"]["index"], ei_after["Y"]) +@pytest.mark.parametrize("npart", [1, 5]) +def test_ei_update_during_ugrid_advection(npart): + ds = simple_small_delaunay() + fieldset = FieldSet.from_ugrid_conventions(ds) + + pset = ParticleSet(fieldset, x=np.linspace(0.1, 0.8, npart), y=0.6 * np.ones(npart)) + pset.populate_indices() + ei_before = pset.ei.copy() + + pset.execute(AdvectionRK4, runtime=np.timedelta64(10, "h"), dt=np.timedelta64(15, "m")) + + _, grid_positions = _get_positions(fieldset.U, pset.t, pset.z, pset.y, pset.x, pset, pset.ei[:, 0]) + ei_after = fieldset.U.grid.unravel_index(pset.ei[:, 0]) + assert np.all(pset.ei != ei_before) + np.testing.assert_allclose(grid_positions["FACE"]["index"], ei_after["FACE"]) + + @pytest.mark.parametrize("direction", ["up", "down"]) @pytest.mark.parametrize("resubmerge_particle", [True, False]) def test_advection_3D_outofbounds(direction, resubmerge_particle):