@@ -209,9 +209,9 @@ def uxgrid_point_in_cell(grid, y: np.ndarray, x: np.ndarray, yi: np.ndarray, xi:
209209 x : np.ndarray
210210 Array of longitudes of the points to check.
211211 yi : np.ndarray
212- Array of face indices corresponding to the points.
213- xi : np.ndarray
214212 Not used, but included for compatibility with other search functions.
213+ xi : np.ndarray
214+ Array of face indices corresponding to the points.
215215
216216 Returns
217217 -------
@@ -227,7 +227,7 @@ def uxgrid_point_in_cell(grid, y: np.ndarray, x: np.ndarray, yi: np.ndarray, xi:
227227 points = np .column_stack ((x_cart .flatten (), y_cart .flatten (), z_cart .flatten ()))
228228
229229 # Get the vertex indices for each face
230- nids = grid .uxgrid .face_node_connectivity [yi ].values
230+ nids = grid .uxgrid .face_node_connectivity [xi ].values
231231 face_vertices = np .stack (
232232 (
233233 grid .uxgrid .node_x [nids .ravel ()].values .reshape (nids .shape ),
@@ -237,7 +237,7 @@ def uxgrid_point_in_cell(grid, y: np.ndarray, x: np.ndarray, yi: np.ndarray, xi:
237237 axis = - 1 ,
238238 )
239239 else :
240- nids = grid .uxgrid .face_node_connectivity [yi ].values
240+ nids = grid .uxgrid .face_node_connectivity [xi ].values
241241 face_vertices = np .stack (
242242 (
243243 grid .uxgrid .node_lon [nids .ravel ()].values .reshape (nids .shape ),
@@ -249,11 +249,11 @@ def uxgrid_point_in_cell(grid, y: np.ndarray, x: np.ndarray, yi: np.ndarray, xi:
249249
250250 M = len (points )
251251
252- is_in_cell = np .zeros (M , dtype = np .int32 )
253-
254252 coords = _barycentric_coordinates (face_vertices , points )
255- is_in_cell = np .where (np .all ((coords >= - 1e-6 ) & (coords <= 1 + 1e-6 ), axis = 1 ), 1 , 0 )
256253
254+ is_in_cell = np .zeros (M , dtype = np .int32 )
255+ is_in_cell = np .where (np .all ((coords >= - 1e-6 ), axis = 1 ), 1 , 0 )
256+ is_in_cell &= np .isclose (np .sum (coords , axis = 1 ), 1.0 , rtol = 1e-3 , atol = 1e-6 )
257257 return is_in_cell , coords
258258
259259
@@ -278,8 +278,10 @@ def _triangle_area(A, B, C):
278278def _barycentric_coordinates (nodes , points , min_area = 1e-8 ):
279279 """
280280 Compute the barycentric coordinates of a point P inside a convex polygon using area-based weights.
281- So that this method generalizes to n-sided polygons, we use the Waschpress points as the generalized
282- barycentric coordinates, which is only valid for convex polygons.
281+ This method currently only works for triangular cells (K=3)
282+
283+ TODO: So that this method generalizes to n-sided polygons, we can use the Waschpress points as the generalized
284+ barycentric coordinates, which is valid for convex polygons.
283285
284286 Parameters
285287 ----------
@@ -300,29 +302,24 @@ def _barycentric_coordinates(nodes, points, min_area=1e-8):
300302 """
301303 M , K = nodes .shape [:2 ]
302304
303- # roll(-1) to get vi+1, roll(+1) to get vi-1
304- vi = nodes # (M,K,2)
305- vi1 = np .roll (nodes , shift = - 1 , axis = 1 ) # (M,K,2)
306- vim1 = np .roll (nodes , shift = + 1 , axis = 1 ) # (M,K,2)
305+ vi = np .squeeze (nodes [:, 0 , :]) # (M,K,2)
306+ vi1 = np .squeeze (nodes [:, 1 , :]) # (M,K,2)
307+ vim1 = np .squeeze (nodes [:, 2 , :]) # (M,K,2)
307308
308309 # a0 = area(v_{i-1}, v_i, v_{i+1})
309310 a0 = _triangle_area (vim1 , vi , vi1 ) # (M,K)
310311
311312 # a1 = area(P, v_{i-1}, v_i); a2 = area(P, v_i, v_{i+1})
312- P = points [:, None , :] # (M,1,2) -> (M,K,2)
313- a1 = _triangle_area (P , vim1 , vi )
314- a2 = _triangle_area (P , vi , vi1 )
315-
316- # clamp tiny denominators for stability
317- a1c = np .maximum (a1 , min_area )
318- a2c = np .maximum (a2 , min_area )
319-
320- wi = a0 / (a1c * a2c ) # (M,K)
321-
322- sum_wi = wi .sum (axis = 1 , keepdims = True ) # (M,1)
323- # Avoid 0/0: if sum_wi==0 (degenerate), keep zeros
324- with np .errstate (invalid = "ignore" , divide = "ignore" ):
325- bcoords = wi / sum_wi
313+ P = points
314+ a1 = _triangle_area (P , vi1 , vim1 )
315+ a2 = _triangle_area (P , vim1 , vi )
316+ a3 = _triangle_area (P , vi , vi1 )
317+
318+ # wi = a0 / (a1c * a2c) # (M,K)
319+ bcoords = np .zeros ((M , K ))
320+ bcoords [:, 0 ] = a1 / a0
321+ bcoords [:, 1 ] = a2 / a0
322+ bcoords [:, 2 ] = a3 / a0
326323
327324 return bcoords
328325
0 commit comments