Source code for openpnm.models.network._topology

r"""
Topology
--------
Pore-scale models related to topology of the network.

"""
from numpy.linalg import norm
import numpy as np
import scipy.spatial as sptl


__all__ = [  # Keep this alphabetical for easier inspection of what's imported
    'coordination_number',
    'distance_to_furthest_neighbor',
    'distance_to_nearest_neighbor',
    'distance_to_nearest_pore',
    'gabriel_edges',
    'pore_to_pore_distance',
]


[docs] def gabriel_edges(network): r""" Find throats which make a Gabriel subgraph Returns ------- throats : ndarray An ndarray of boolean values with ``True`` indicating that a throat satisfies the conditions of Gabriel graph, meaning that a circle (or sphere) can be drawn between its two connected pores that does not contain any other pores. Notes ----- Technically this should only be used on a Delaunay network, but it will work on any graph. By deleting all throats that are *not* identified by this fuction one would obtain the Gabriel graph [1]. References ---------- [1] `Wikipedia <https://en.wikipedia.org/wiki/Gabriel_graph>`_ """ dn = network # Find centroid or midpoint of each edge in conns c = dn['pore.coords'][dn['throat.conns']] m = (c[:, 0, :] + c[:, 1, :])/2 # Find the radius the sphere between each pair of nodes r = np.sqrt(np.sum((c[:, 0, :] - c[:, 1, :])**2, axis=1))/2 # Use the kd-tree function in Scipy's spatial module tree = sptl.cKDTree(dn['pore.coords']) # Find the nearest point for each midpoint n = tree.query(x=m, k=1)[0] # If nearest point to m is at distance r, then the edge is a Gabriel edge g = n >= r*(0.999) # This factor avoids precision errors in the distances return g
[docs] def coordination_number(network): r""" Find the number of neighbors for each pore """ N = network.num_neighbors(pores=network.Ps, flatten=False) return N
[docs] def pore_to_pore_distance(network): r""" Find the center to center distance between each pair of pores """ cn = network['throat.conns'] C1 = network['pore.coords'][cn[:, 0]] C2 = network['pore.coords'][cn[:, 1]] values = norm(C1 - C2, axis=1) return values
[docs] def distance_to_nearest_neighbor(network): r""" Find the distance between each pore and its closest topological neighbor """ cn = network['throat.conns'] C1 = network['pore.coords'][cn[:, 0]] C2 = network['pore.coords'][cn[:, 1]] D = norm(C1 - C2, axis=1) im = network.create_incidence_matrix() values = np.ones((network.Np, ))*np.inf np.minimum.at(values, im.row, D[im.col]) return np.array(values)
[docs] def distance_to_furthest_neighbor(network): r""" Find the distance between each pore and its furthest topological neighbor """ throats = network.throats(network.name) cn = network['throat.conns'][throats] C1 = network['pore.coords'][cn[:, 0]] C2 = network['pore.coords'][cn[:, 1]] D = norm(C1 - C2, axis=1) im = network.create_incidence_matrix() values = np.zeros((network.Np, )) np.maximum.at(values, im.row, D[im.col]) return np.array(values)
[docs] def distance_to_nearest_pore(network): r""" Find distance to and index of nearest pore even if not topologically connected """ import scipy.spatial as sptl coords = network.coords tree = sptl.KDTree(coords) ds, ids = tree.query(coords, k=2) values = ds[:, 1] return values