def check_geometry_health(self): r""" Perform a check to find pores with overlapping or undefined Geometries """ geoms = self.geometries() Ptemp = sp.zeros((self.Np,)) Ttemp = sp.zeros((self.Nt,)) for item in geoms: Pind = self['pore.'+item] Tind = self['throat.'+item] Ptemp[Pind] = Ptemp[Pind] + 1 Ttemp[Tind] = Ttemp[Tind] + 1 health = Tools.HealthDict() health['overlapping_pores'] = sp.where(Ptemp > 1)[0].tolist() health['undefined_pores'] = sp.where(Ptemp == 0)[0].tolist() health['overlapping_throats'] = sp.where(Ttemp > 1)[0].tolist() health['undefined_throats'] = sp.where(Ttemp == 0)[0].tolist() return health
def check_physics_health(self): r''' Perform a check to find pores which have overlapping or undefined Physics ''' phys = self.physics() Ptemp = sp.zeros((self.Np, )) Ttemp = sp.zeros((self.Nt, )) for item in phys: Pind = self['pore.' + item] Tind = self['throat.' + item] Ptemp[Pind] = Ptemp[Pind] + 1 Ttemp[Tind] = Ttemp[Tind] + 1 health = Tools.HealthDict() health['overlapping_pores'] = sp.where(Ptemp > 1)[0].tolist() health['undefined_pores'] = sp.where(Ptemp == 0)[0].tolist() health['overlapping_throats'] = sp.where(Ttemp > 1)[0].tolist() health['undefined_throats'] = sp.where(Ttemp == 0)[0].tolist() return health
def check_network_health(self): r""" This method check the network topological health by checking for: (1) Isolated pores (2) Islands or isolated clusters of pores (3) Duplicate throats (4) Bidirectional throats (ie. symmetrical adjacency matrix) (5) Headless throats Returns ------- A dictionary containing the offending pores or throat numbers under each named key. It also returns a list of which pores and throats should be trimmed from the network to restore health. This list is a suggestion only, and is based on keeping the largest cluster and trimming the others. Notes ----- - Does not yet check for duplicate pores - Does not yet suggest which throats to remove - This is just a 'check' method and does not 'fix' the problems it finds """ health = Tools.HealthDict() health['disconnected_clusters'] = [] health['isolated_pores'] = [] health['trim_pores'] = [] health['duplicate_throats'] = [] health['bidirectional_throats'] = [] health['headless_throats'] = [] health['looped_throats'] = [] # Check for headless throats hits = sp.where(self['throat.conns'] > self.Np - 1)[0] if sp.size(hits) > 0: health['headless_throats'] = sp.unique(hits) logger.warning('Health check cannot complete due to connectivity ' 'errors. Please correct existing errors & recheck.') return health # Check for throats that loop back onto the same pore P12 = self['throat.conns'] hits = sp.where(P12[:, 0] == P12[:, 1])[0] if sp.size(hits) > 0: health['looped_throats'] = hits # Check for individual isolated pores Ps = self.num_neighbors(self.pores()) if sp.sum(Ps == 0) > 0: logger.warning(str(sp.sum(Ps == 0)) + ' pores have no neighbors') health['isolated_pores'] = sp.where(Ps == 0)[0] # Check for separated clusters of pores temp = [] Cs = self.find_clusters(self.tomask(throats=self.throats('all'))) if sp.shape(sp.unique(Cs))[0] > 1: logger.warning('Isolated clusters exist in the network') for i in sp.unique(Cs): temp.append(sp.where(Cs == i)[0]) b = sp.array([len(item) for item in temp]) c = sp.argsort(b)[::-1] for i in range(0, len(c)): health['disconnected_clusters'].append(temp[c[i]]) if i > 0: health['trim_pores'].extend(temp[c[i]]) # Check for duplicate throats am = self.create_adjacency_matrix(sprsfmt='lil') mergeTs = [] for i in range(0, self.Np): for j in sp.where(sp.array(am.data[i]) > 1)[0]: k = am.rows[i][j] mergeTs.extend(self.find_connecting_throat(i, k)) # Remove duplicates mergeTs = [list(i) for i in set(tuple(i) for i in mergeTs)] health['duplicate_throats'] = mergeTs # Check for bidirectional throats adjmat = self.create_adjacency_matrix(sprsfmt='coo') num_full = adjmat.sum() temp = sprs.triu(adjmat, k=1) num_upper = temp.sum() if num_full > num_upper: biTs = sp.where(self['throat.conns'][:, 0] > self['throat.conns'][:, 1])[0] health['bidirectional_throats'] = biTs.tolist() return health
def check_network_health(self): r''' This method check the network topological health by checking for: (1) Isolated pores (2) Islands or isolated clusters of pores (3) Duplicate throats (4) Bidirectional throats (ie. symmetrical adjacency matrix) Returns ------- A dictionary containing the offending pores or throat numbers under each named key. It also returns a list of which pores and throats should be trimmed from the network to restore health. This list is a suggestion only, and is based on keeping the largest cluster and trimming the others. Notes ----- - Does not yet check for duplicate pores - Does not yet suggest which throats to remove - This is just a 'check' method and does not 'fix' the problems it finds ''' health = Tools.HealthDict() health['disconnected_clusters'] = [] health['isolated_pores'] = [] health['trim_pores'] = [] health['duplicate_throats'] = [] health['bidirectional_throats'] = [] #Check for individual isolated pores Ps = self.num_neighbors(self.pores()) if sp.sum(Ps==0) > 0: logger.warning(str(sp.sum(Ps==0))+' pores have no neighbors') health['isolated_pores'] = sp.where(Ps==0)[0] #Check for separated clusters of pores temp = [] Cs = self.find_clusters(self.tomask(throats=self.throats('all'))) if sp.shape(sp.unique(Cs))[0] > 1: logger.warning('Isolated clusters exist in the network') for i in sp.unique(Cs): temp.append(sp.where(Cs==i)[0]) b = sp.array([len(item) for item in temp]) c = sp.argsort(b)[::-1] for i in range(0,len(c)): health['disconnected_clusters'].append(temp[c[i]]) if i > 0: health['trim_pores'].extend(temp[c[i]]) #Check for duplicate throats i = self['throat.conns'][:,0] j = self['throat.conns'][:,1] v = sp.array(self['throat.all'],dtype=int) Np = self.num_pores() adjmat = sprs.coo_matrix((v,(i,j)),[Np,Np]) temp = adjmat.tocsr() # Convert to CSR to combine duplicates temp = adjmat.tocoo() # And back to COO mergedTs = sp.where(temp.data>1) Ps12 = sp.vstack((temp.row[mergedTs], temp.col[mergedTs])).T dupTs = [] for i in range(0,sp.shape(Ps12)[0]): dupTs.append(self.find_connecting_throat(Ps12[i,0],Ps12[i,1]).tolist) health['duplicate_throats'] = dupTs #Check for bidirectional throats num_full = adjmat.sum() temp = sprs.triu(adjmat,k=1) num_upper = temp.sum() if num_full > num_upper: health['bidirectional_throats'] = str(num_full-num_upper)+' detected!' #Check for coincident pores # temp = misc.dist(self['pore.coords'],self['pore.coords']) # temp = sp.triu(temp,k=1) # Remove lower triangular of matrix # temp = sp.where(temp==0) # Find 0 values in distance matrix # dupPs = sp.where(temp[1]>temp[0])[0] # Find 0 values above diagonal # health['duplicate_pores'] = dupPs return health