Particles get permanently stuck near seafloor topography (A-grid, silent zero velocity): is deletion the only option, or is there a vertical equivalent to XFreeslip/XPartialslip? #2900
Unanswered
imariaguiar
asked this question in
Q&A
Replies: 1 comment 2 replies
|
Thank you for reaching out, @imariaguiar. Indeed, stuck particles near complex/deep topography is a known issue in Parcels. Coincidentally, MSc student Paolo started a project today to explore best interpolation practises near seafloor topography. Note that he will do this in the new Parcels v4. So I'm afraid I don't have a quick solution, but keep an eye on the tracker here fr updates! |
2 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Question
Question
Hi,
I'm running Lagrangian simulations with Parcels (v3.1.4) to study Antarctic Bottom Water (AABW) pathways in the Vema Channel region, using OFES model output. I release particles at every valid grid point along a vertical section (from ~3800 m down to the local seafloor) and track them for up to 50 years (using time_periodic to loop over the ~28 yr of available velocity data).
The problem: a significant fraction of particles get permanently stuck, their position never changes again, for the remainder of the simulation (sometimes 40+ years), while neighboring particles continue moving normally.
This looked at first like a bug in my error-handling kernels, but after diagnosing it directly, I found:
Querying fieldset.U/fieldset.V directly (via .eval()) at the stuck particle's position raises FieldOutOfBoundError, confirming the particle is at a depth below the local seafloor (I verified this by comparing the particle's depth to the deepest valid level in that same water column: margins as small as 0 m, since my release grid intentionally includes the deepest available level in each column).
However, during the actual pset.execute() run with AdvectionRK4_3D, no error is ever raised, particle.state stays Success the whole time. Instead, U and V silently return 0.0 at that exact position. This means neither in-list check-kernels nor postIterationCallbacks (checking particle.state) ever catch it, since there's simply no error state to catch.
I found your "Preventing stuck particles" tutorial afterward, and the DeleteOnLand example ((u==0)&(v==0) → delete) confirms this is the known A-grid behavior, just for a horizontal coastline case rather than a vertical seafloor case. My current workaround is a custom kernel that checks particle depth against a locally-computed bathymetry field (deepest valid U level per lon/lat column) and deletes the particle if it exceeds that, which works correctly.
My question: is deletion really my only reasonable option here, or is there a vertical equivalent to XFreeslip/XPartialslip (which, as far as I understand, only correct interpolation in the horizontal ξ/η directions)? I'd like to know if there's a recommended way to instead "rescue" these particles with a corrected vertical interpolation near the seafloor, rather than just deleting them, since a fairly large fraction of my release points (~35% in one test batch) have near-zero margin to the local seafloor by construction (since I want to sample water immediately above the bottom).
Here's the core of my diagnostic:
traj 6: LAST position = lon=320.69, lat=-29.00, depth=4126.3m
traj 15: LAST position = lon=321.23, lat=-29.12, depth=4388.6m
traj 16: LAST position = lon=321.00, lat=-29.32, depth=4675.3m
local seafloor depth at these same (lon, lat) columns, from the
deepest finite U level:
traj 6: seafloor = 4113.4 m -> particle is ~13 m BELOW seafloor
traj 15: seafloor = 4388.6 m -> margin = 0.0 m (exact bottom cell)
traj 16: seafloor = 4388.6 m -> margin ~ -287 m
Any guidance on best practice here would be much appreciated, happy to share more of my code/data if useful.
Thanks!
All reactions