Skip to content

Commit 476bdc0

Browse files
Remove component of point in normal direction of element plane
The spherical coordinate transformation of a point computes a cartesian location that is outside the element plane. When computing barycentric coordinates, this makes it possible for the sum of the barycentric coordinates to exceed 1. To fix this, we remove the component of the particle's cartesian coordinates that is normal to the element plane when performing point in cell checks
1 parent 704289e commit 476bdc0

File tree

1 file changed

+16
-1
lines changed

1 file changed

+16
-1
lines changed

src/parcels/_core/index_search.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ def uxgrid_point_in_cell(grid, y: np.ndarray, x: np.ndarray, yi: np.ndarray, xi:
224224
lon_rad = np.deg2rad(x)
225225
lat_rad = np.deg2rad(y)
226226
x_cart, y_cart, z_cart = _latlon_rad_to_xyz(lat_rad, lon_rad)
227-
points = np.column_stack((x_cart.flatten(), y_cart.flatten(), z_cart.flatten()))
227+
points = np.column_stack((x_cart.flatten(), y_cart.flatten(), z_cart.flatten())) # (M,3)
228228

229229
# Get the vertex indices for each face
230230
nids = grid.uxgrid.face_node_connectivity[xi].values
@@ -236,6 +236,20 @@ def uxgrid_point_in_cell(grid, y: np.ndarray, x: np.ndarray, yi: np.ndarray, xi:
236236
),
237237
axis=-1,
238238
)
239+
240+
# Get projection points onto element plane
241+
# for the projection, all points are computed relative to v0
242+
r1 = np.squeeze(face_vertices[:, 1, :] - face_vertices[:, 0, :]) # (M,3)
243+
r2 = np.squeeze(face_vertices[:, 2, :] - face_vertices[:, 0, :]) # (M,3)
244+
nhat = np.cross(r1, r2)
245+
norm = np.linalg.norm(nhat, axis=-1)
246+
nhat = nhat / norm[:, None]
247+
# Calculate the component of the points in the direction of nhat
248+
ptilde = points - np.squeeze(face_vertices[:, 0, :])
249+
pdotnhat = np.sum(ptilde * nhat, axis=-1)
250+
# Reconstruct points with normal component removed.
251+
points = ptilde - pdotnhat[:, None] * nhat + np.squeeze(face_vertices[:, 0, :])
252+
239253
else:
240254
nids = grid.uxgrid.face_node_connectivity[xi].values
241255
face_vertices = np.stack(
@@ -254,6 +268,7 @@ def uxgrid_point_in_cell(grid, y: np.ndarray, x: np.ndarray, yi: np.ndarray, xi:
254268
is_in_cell = np.zeros(M, dtype=np.int32)
255269
is_in_cell = np.where(np.all((coords >= -1e-6), axis=1), 1, 0)
256270
is_in_cell &= np.isclose(np.sum(coords, axis=1), 1.0, rtol=1e-3, atol=1e-6)
271+
257272
return is_in_cell, coords
258273

259274

0 commit comments

Comments
 (0)