I'm really struggling to understand how to reduce the number of nodes in my CFD mesh in Python and have been trying for 4+ hours with no luck. I'd really appreciate some guidance! For context, I have a 2D CFD mesh generated by Fluent and exported as a .msh.h5 file. The file has the following structure: ├── meshes │ └── 1 │ ├── nodes │ │ ├── zoneTopology │ │ │ ├── id (1) │ │ │ ├── dimension (1) │ │ │ ├── maxId (1) │ │ │ ├── minId (1) │ │ │ ├── name (1) │ │ │ ├── zoneType (1) │ │ │ └── fields (1) │ │ └── coords │ │ └── 1 (418030) │ ├── faces │ │ ├── zoneTopology │ │ │ ├── id (5) │ │ │ ├── dimension (5) │ │ │ ├── maxId (5) │ │ │ ├── minId (5) │ │ │ ├── name (1) │ │ │ ├── childZoneId (5) │ │ │ ├── faceType (5) │ │ │ ├── shadowZoneId (5) │ │ │ ├── zoneType (5) │ │ │ └── fields (1) │ │ ├── nodes │ │ │ ├── 1 │ │ │ │ ├── nnodes (12193) │ │ │ │ └── nodes (24386) │ │ │ ├── 2 │ │ │ │ ├── nnodes (36) │ │ │ │ └── nodes (72) │ │ │ ├── 3 │ │ │ │ ├── nnodes (20) │ │ │ │ └── nodes (40) │ │ │ ├── 4 │ │ │ │ ├── nnodes (19) │ │ │ │ └── nodes (38) │ │ │ └── 5 │ │ │ ├── nnodes (985700) │ │ │ └── nodes (1971400) │ │ ├── c1 │ │ │ ├── 1 (12193) │ │ │ ├── 2 (36) │ │ │ ├── 3 (20) │ │ │ ├── 4 (19) │ │ │ └── 5 (985700) │ │ └── c0 │ │ ├── 1 (12193) │ │ ├── 2 (36) │ │ ├── 3 (20) │ │ ├── 4 (19) │ │ └── 5 (985700) │ └── cells │ ├── zoneTopology │ │ ├── id (1) │ │ ├── dimension (1) │ │ ├── maxId (1) │ │ ├── minId (1) │ │ ├── name (1) │ │ ├── cellType (1) │ │ ├── childZoneId (1) │ │ └── fields (1) │ └── ctype │ └── 1 │ └── cell-types (579936) └── settings ├── Cortex Variables (1) ├── Origin (1) ├── Solver (1) ├── Thread Variables (1) └── Version (1) I'm using h5py to read the file and extract the mesh node coordinates like so: mesh_filepath = r'...' with h5py.File(mesh_filepath, 'r') as h5file: node_coordinates = np.array(h5file['meshes/1/nodes/coords/1']) I then create a numpy array to store the connections between each node based on their indices in the mesh: faces_nodes_group = h5file['meshes/1/faces/nodes'] nodes_connectivity = [] for key in faces_nodes_group.keys(): nodes = faces_nodes_group[key]['nodes'][:] nodes = nodes.reshape(-1, 2) nodes_connectivity.append(nodes) nodes_connectivity = np.vstack(nodes_connectivity) To be honest I'm not 100% sure what each numeric heading is after meshes/1/faces/nodes and couldn't find much information online. But with some trial and error I found it to contain the information I needed. I then create a scipy.sparse.coo_matrix to store the adjacency nodes information like so: num_mesh_nodes = nodes_connectivity.max() + 1 row, col = nodes_connectivity[:, 0] - 1, nodes_connectivity[:, 1] - 1 adjacency_matrix = sp.coo_matrix((np.ones(len(row)), (row, col)), shape=(num_mesh_nodes, num_mesh_nodes)) adjacency_matrix += adjacency_matrix.T Finally I plot a NetworkX graph to visualise the result: G = nx.Graph() row, col = adjacency_matrix.nonzero() edges = list(zip(row, col)) G.add_edges_from(edges) pos = {i: coord for i, coord in enumerate(node_coordinates)} nx.draw(G, pos, node_size=5) plt.show() This works completely fine and shows the graph exactly how the mesh should look. However, I need to remove a bunch of nodes from the network due to complications on another project but I have been unable to get it working. Whenever I try to remove connections in nodes_connectivity to those that only contain indices for the mesh nodes I want, it results in an array that is larger than my total mesh node count and therefore unable to draw the graph due to edges missing positions. This is what I've tried so far: # Removing nodes that are too close or far from some boundary coordinates tree = scipy.spatial.KDTree(boundary_coordinates) distances, _ = tree.query(node_coordinates) indices_to_keep = np.where( np.logical_and(min_dist <= distances, distances < max_dist) )[0] reduced_node_coordinates = node_coordinates[indices_to_keep] # Remove all connections containing node indices that are not in the `indices_to_keep` list. # This is to prevent connections pointing to nodes that no longer exist node_removal_mask = np.all(np.isin(nodes_connectivity, indices_to_keep), axis=1) masked_nodes_connectivity = nodes_connectivity[node_removal_mask] # Create an index map as reduction in nodes connectivity leads to previous connections pointing to indices # exceeding the length of the reduced array index_map = {old_idx: new_idx for new_idx, old_idx in enumerate(indices_to_keep)} remapped_nodes_connectivity = np.vectorize(lambda x: index_map.get(x, -1))(nodes_connectivity) I'm seriously wondering if I'm taking the wrong approach with this and if there's a simpler way, but I have not been able to find one. If anyone has any ideas on how to solve this issue I'd greatly appreciate it, even if it's a resource I can look at. Continue reading...