-
Notifications
You must be signed in to change notification settings - Fork 297
Closed
Labels
Description
I might have some code that could help with this:
iris/lib/iris/tests/stock/__init__.py
Lines 840 to 886 in 6adac1b
def remove_duplicate_nodes(mesh: ugrid.Mesh): | |
"""Remove duplicate nodes from a mesh. | |
Mesh.from_coords() does not do this due to complications like lazy | |
arrays. Not a problem here. | |
""" | |
# TODO: | |
# Contained in a function because this _could_ be generalised into a | |
# public function. Would need to make it handle Dask arrays and masked | |
# indices. | |
# Example nodes: [a, b, c, a, c, b, d] | |
# (Real nodes are X-Y pairs so a 2d array). | |
# Example faces: [[0, 1, 2, 6], [3, 4, 5, 6]] | |
# I.e. faces made by connecting: a-b-c-d , a-c-b-d | |
# Processed nodes: [a, b, c, d] | |
# Processed faces: [[0, 1, 2, 3], [0, 2, 1, 3]] | |
nodes = np.stack([c.points for c in mesh.node_coords]) | |
face_node = mesh.face_node_connectivity | |
# first_instances = a full length array but always with the index of | |
# the first instance of each node e.g.: [0, 1, 2, 0, 2, 1, 3] | |
nodes_unique, first_instances = np.unique( | |
nodes, | |
return_inverse=True, | |
axis=1, | |
) | |
# E.g. indexing [0, 1, 2, 0, 2, 1, 3] with [[0, 1, 2, 6], [3, 4, 5, 6]] | |
# -> [[0, 1, 2, 3], [0, 2, 1, 3]] | |
indices_unique = first_instances[face_node.indices] | |
# Connectivity indices expected to be a masked array. | |
indices_unique = np.ma.masked_array(indices_unique, mask=face_node.indices.mask) | |
# Replace the original node coords and face-node connectivity with the | |
# unique-d versions. | |
node_x, node_y = [ | |
AuxCoord(nodes_unique[i], **c.metadata._asdict()) | |
for i, c in enumerate(mesh.node_coords) | |
] | |
mesh.add_coords(node_x=node_x, node_y=node_y) | |
conn_kwargs = dict(indices=indices_unique, start_index=0) | |
mesh.add_connectivities( | |
ugrid.Connectivity(**(face_node.metadata._asdict() | conn_kwargs)) | |
) | |
return mesh |