@@ -862,6 +862,10 @@ def calc_ghost_cells_for_swegnn(
862862 ghost_ds ['node_BC' ] = (['num_BC_edges' ], ghost_cell_indices )
863863 ghost_ds ['node_BC' ].attrs = {'description' : 'Indices assigned to ghost cells (faces) appended after real faces' }
864864
865+ ghost_ds ['edge_BC_length' ] = (['num_BC_edges' ], calculate_boundary_edge_lengths (
866+ original_node_xy , edge_index_BC
867+ ))
868+
865869 # Assign coordinates/dimensions
866870 ghost_ds = ghost_ds .assign_coords (
867871 num_BC_edges = np .arange (face_BC .shape [0 ]),
@@ -1283,6 +1287,51 @@ def grad_for_triangle_static(
12831287 return np .stack ((grad_x , grad_y )) # (2, M)
12841288
12851289
1290+ def calculate_boundary_edge_lengths (
1291+ node_xy : np .ndarray ,
1292+ edge_index_BC : np .ndarray
1293+ ) -> np .ndarray :
1294+ """
1295+ Calculates the physical length of each boundary edge.
1296+
1297+ Assumes node_xy coordinates allow for Euclidean distance calculation
1298+ (e.g., meters in a projected coordinate system). For lat/lon degrees,
1299+ a geodesic distance calculation would be more accurate.
1300+
1301+ Args:
1302+ node_xy: Array of node coordinates, shape (num_nodes, 2).
1303+ edge_index_BC: Array of node indices forming boundary edges,
1304+ shape (num_BC_edges, 2).
1305+
1306+ Returns:
1307+ np.ndarray: Array containing the length of each boundary edge,
1308+ shape (num_BC_edges,).
1309+
1310+ Doctests:
1311+ >>> node_coords = np.array([[0., 0.], [3., 0.], [3., 4.], [0., 4.]])
1312+ >>> bc_edges = np.array([[0, 1], [1, 2], [3, 0]]) # Edges (0,1), (1,2), (3,0)
1313+ >>> calculate_boundary_edge_lengths(node_coords, bc_edges)
1314+ array([3., 4., 4.])
1315+ >>> bc_edges_empty = np.empty((0, 2), dtype=int)
1316+ >>> calculate_boundary_edge_lengths(node_coords, bc_edges_empty)
1317+ array([], dtype=float64)
1318+ """
1319+ if edge_index_BC .shape [0 ] == 0 :
1320+ return np .array ([], dtype = float )
1321+
1322+ # Get coordinates for the start and end node of each boundary edge
1323+ start_nodes_xy = node_xy [edge_index_BC [:, 0 ]] # Shape: (num_BC_edges, 2)
1324+ end_nodes_xy = node_xy [edge_index_BC [:, 1 ]] # Shape: (num_BC_edges, 2)
1325+
1326+ # Calculate the difference in coordinates (dx, dy)
1327+ delta_xy = end_nodes_xy - start_nodes_xy # Shape: (num_BC_edges, 2)
1328+
1329+ # Calculate Euclidean distance (length) = sqrt(dx^2 + dy^2)
1330+ edge_lengths = np .linalg .norm (delta_xy , axis = 1 ) # Calculate norm along axis 1
1331+
1332+ return edge_lengths
1333+
1334+
12861335def grad_for_triangle_timeseries (
12871336 x_lon : np .ndarray , y_lat : np .ndarray , z_values : np .ndarray , triangles : np .ndarray
12881337) -> np .ndarray :
0 commit comments