[docs]defcluster_number(network):r""" Assign a cluster number to each pore """fromscipy.sparseimportcsgraphascsgam=network.create_adjacency_matrix(fmt='coo',triu=True)N,Cs=csg.connected_components(am,directed=False)returnCs
[docs]defcluster_size(network,cluster=None):r""" Find the size of the cluster to which each pore belongs Parameters ---------- network : dict The Network cluster : str, optional Dict key pointing to the array containing the cluster number of each pore. If not provided then it will be calculated. Returns ------- cluster_size : ndarray An Np-long array containing the size of the cluster to which each pore belongs """ifclusterisNone:fromscipy.sparseimportcsgraphascsgam=network.create_adjacency_matrix(fmt='coo',triu=True)N,cluster_num=csg.connected_components(am,directed=False)else:cluster_num=network[cluster]Cs,ind,N=np.unique(cluster_num,return_inverse=True,return_counts=True)values=N[ind]returnvalues
[docs]defisolated_pores(network):r""" Find which pores, if any, are not connected to a throat """values=np.ones(network.Np,dtype=bool)hits=np.unique(network.conns)ifnp.any(hits>=network.Np):logger.warning("Some throats point to non-existent pores")hits=hits[hits<network.Np]values[hits]=Falsereturnvalues
[docs]defreversed_throats(network):r""" Find any throat connections that are pointing from j -> i where j > i """hits=network.conns[:,0]>network.conns[:,1]returnhits
[docs]deflooped_throats(network):r""" Find any throats that are connected to the same pore on both ends """hits=network.conns[:,0]==network.conns[:,1]returnhits
[docs]defheadless_throats(network):r""" Find any throats that point to a non-existent pore """hits=np.any(network.conns>(network.Np-1),axis=1)returnhits
[docs]defduplicate_throats(network):r""" Find repeat occurrences of throat connections """returnpd.DataFrame(network.conns).duplicated().to_numpy()
[docs]defcount_coincident_pores(network,thresh=1e-6):r""" Count number of pores that are spatially coincident with other pores Parameters ---------- network : dict The Network thresh : float The distance below which two pores are considered spatially coincident Returns ------- count : ndarray A numpy array of Np length containing the number of coincident pores """# This needs to be a bit complicated because it cannot be assumed# the coincident pores are topologically connectedimportscipy.spatialassptlcoords=network.coordstree=sptl.KDTree(coords)hits=tree.query_pairs(r=thresh)arr=np.array(list(hits)).flatten()v,n=np.unique(arr,return_counts=True)values=np.zeros(network.Np,dtype=int)values[v.astype(int)]=nreturnvalues
[docs]deffind_coincident_pores(network,thresh=1e-6):r""" Find the indices of coincident pores Parameters ---------- network : dict The Network thresh : float The distance below which two pores are considered spatially coincident Returns ------- indices : list of lists One row corresponding to each pore, with each row listing the indices of any coincident pores. An empty list means no pores were found within a distance of ``thresh``. """# This needs to be a bit complicated because it cannot be assumed# the coincident pores are topologically connectedimportscipy.spatialassptlcoords=network['pore.coords']tree=sptl.KDTree(coords)a=tree.sparse_distance_matrix(tree,max_distance=thresh,output_type='coo_matrix')a.data+=1.0a.setdiag(0)a.eliminate_zeros()a.data-=1.0a=a.tolil()returna.rows