Example #1
0
 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
Example #2
0
 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
Example #3
0
    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