Source code for openpnm.models.network._health

"""
Health Checks
-------------

"""
import logging
import numpy as np
import pandas as pd
logger = logging.getLogger(__name__)

__all__ = [
    'bidirectional_throats',
    'cluster_number',
    'cluster_size',
    'count_coincident_pores',
    'duplicate_throats',
    'find_coincident_pores',
    'isolated_pores',
    'reversed_throats',
    'looped_throats',
    'headless_throats',
]


[docs] def cluster_number(network): r""" Assign a cluster number to each pore """ from scipy.sparse import csgraph as csg am = network.create_adjacency_matrix(fmt='coo', triu=True) N, Cs = csg.connected_components(am, directed=False) return Cs
[docs] def cluster_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 """ if cluster is None: from scipy.sparse import csgraph as csg am = 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] return values
[docs] def isolated_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) if np.any(hits >= network.Np): logger.warning("Some throats point to non-existent pores") hits = hits[hits < network.Np] values[hits] = False return values
[docs] def reversed_throats(network): r""" Find any throat connections that are pointing from j -> i where j > i """ hits = network.conns[:, 0] > network.conns[:, 1] return hits
[docs] def looped_throats(network): r""" Find any throats that are connected to the same pore on both ends """ hits = network.conns[:, 0] == network.conns[:, 1] return hits
[docs] def headless_throats(network): r""" Find any throats that point to a non-existent pore """ hits = np.any(network.conns > (network.Np - 1), axis=1) return hits
[docs] def duplicate_throats(network): r""" Find repeat occurrences of throat connections """ return pd.DataFrame(network.conns).duplicated().to_numpy()
[docs] def count_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 connected import scipy.spatial as sptl coords = network.coords tree = 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)] = n return values
[docs] def find_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 connected import scipy.spatial as sptl coords = network['pore.coords'] tree = sptl.KDTree(coords) a = tree.sparse_distance_matrix(tree, max_distance=thresh, output_type='coo_matrix') a.data += 1.0 a.setdiag(0) a.eliminate_zeros() a.data -= 1.0 a = a.tolil() return a.rows
[docs] def bidirectional_throats(network): biTs = network['throat.conns'][:, 0] > network['throat.conns'][:, 1] return biTs