Ejemplo n.º 1
0
    def check_geometry_health(self):
        r"""
        Perform a check to find pores with overlapping or undefined Geometries

        Returns
        -------
        A HealthDict
        """
        health = HealthDict()
        health['overlapping_pores'] = []
        health['undefined_pores'] = []
        health['overlapping_throats'] = []
        health['undefined_throats'] = []
        geoms = self.geometries().keys()
        if len(geoms):
            net = self.network
            Ptemp = np.zeros((net.Np, ))
            Ttemp = np.zeros((net.Nt, ))
            for item in geoms:
                Pind = net['pore.' + item]
                Tind = net['throat.' + item]
                Ptemp[Pind] = Ptemp[Pind] + 1
                Ttemp[Tind] = Ttemp[Tind] + 1
            health['overlapping_pores'] = np.where(Ptemp > 1)[0].tolist()
            health['undefined_pores'] = np.where(Ptemp == 0)[0].tolist()
            health['overlapping_throats'] = np.where(Ttemp > 1)[0].tolist()
            health['undefined_throats'] = np.where(Ttemp == 0)[0].tolist()
        return health
Ejemplo n.º 2
0
    def check_data_health(self, obj):
        r"""
        Check the health of pore and throat data arrays.

        Parameters
        ----------
        obj : OpenPNM object
            A handle of the object to be checked

        Returns
        -------
        health : dict
            Returns a HealthDict object which a basic dictionary with an added
            ``health`` attribute that is True is all entries in the dict are
            deemed healthy (empty lists), or False otherwise.

        """
        health = HealthDict()
        for item in obj.props():
            health[item] = []
            if obj[item].dtype == 'O':
                health[item] = 'No checks on object'
            elif np.sum(np.isnan(obj[item])) > 0:
                health[item] = 'Has NaNs'
            elif np.shape(obj[item])[0] != obj._count(item.split('.')[0]):
                health[item] = 'Wrong Length'
        return health
Ejemplo n.º 3
0
    def check_mixture_health(self):
        r"""
        Checks the "health" of the mixture

        Calculates the mole fraction of all species in each pore and returns
        an list of where values are too low or too high

        Returns
        -------
        health : dict
            A HealtDict object containing lists of locations where the mole
            fractions are not unity.  One value indiates locations that are
            too high, and another where they are too low.

        """
        h = HealthDict()
        h['mole_fraction_too_low'] = []
        h['mole_fraction_too_high'] = []
        self._update_total_molfrac()
        lo = np.where(self['pore.mole_fraction.all'] < 1.0)[0]
        hi = np.where(self['pore.mole_fraction.all'] > 1.0)[0]
        if len(lo) > 0:
            h['mole_fraction_too_low'] = lo
        if len(hi) > 0:
            h['mole_fraction_too_high'] = hi
        return h
Ejemplo n.º 4
0
    def check_network_health(self):
        r"""
        This method checks the topological health of the network

        The following aspects are checked for:

            (1) Isolated pores
            (2) Disconnected clusters of pores
            (3) Duplicate throats
            (4) Headless throats
            (5) Bidirectional throats

        Returns
        -------
        health : dict
            A dictionary containing the offending pores or throat numbers
            under each named key.

        Notes
        -----
        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.

        - Does not yet check for duplicate pores
        - Does not yet suggest which throats to remove
        - This is just a 'check' and does not 'fix' the problems it finds

        """
        import openpnm.models.network as mods

        health = HealthDict()
        net = self.network

        # Check for headless throats
        headless = mods.headless_throats(net)
        health['headless_throats'] = np.where(headless)[0].tolist()

        # Check for throats that loop back onto the same pore
        looped = mods.looped_throats(net)
        health['looped_throats'] = np.where(looped)[0].tolist()

        # Check for individual isolated pores
        isolated = mods.isolated_pores(net)
        health['isolated_pores'] = np.where(isolated)[0].tolist()

        # Check for separated clusters of pores
        size = mods.cluster_size(net)
        mx = np.max(size)
        health['disconnected_pores'] = np.where(size < mx)[0].tolist()

        # Check for duplicate throats
        dupes = mods.duplicate_throats(net)
        health['duplicate_throats'] = np.where(dupes)[0].tolist()

        # Check for bidirectional throats
        bidir = mods.bidirectional_throats(net)
        health['bidirectional_throats'] = np.where(bidir)[0].tolist()

        return health
Ejemplo n.º 5
0
    def check_physics_health(self, phase):
        r"""
        Performs a check to find pores which have overlapping or missing
        Physics.

        Parameters
        ----------
        phase : GenericPhase
            The Phase whose Physics should be checked

        Returns
        -------
        HealthDict

        """
        health = HealthDict()
        health['overlapping_pores'] = []
        health['undefined_pores'] = []
        health['overlapping_throats'] = []
        health['undefined_throats'] = []
        geoms = self.geometries().keys()
        if len(geoms) > 0:
            phys = self.find_physics(phase=phase)
            if len(phys) == 0:
                raise Exception(
                    str(len(geoms)) + ' geometries were found, but' +
                    ' no physics')
            if None in phys:
                raise Exception('Undefined physics found, check the grid')
            Ptemp = np.zeros((phase.Np, ))
            Ttemp = np.zeros((phase.Nt, ))
            for item in phys:
                Pind = phase['pore.' + item.name]
                Tind = phase['throat.' + item.name]
                Ptemp[Pind] = Ptemp[Pind] + 1
                Ttemp[Tind] = Ttemp[Tind] + 1
            health['overlapping_pores'] = np.where(Ptemp > 1)[0].tolist()
            health['undefined_pores'] = np.where(Ptemp == 0)[0].tolist()
            health['overlapping_throats'] = np.where(Ttemp > 1)[0].tolist()
            health['undefined_throats'] = np.where(Ttemp == 0)[0].tolist()
        return health
Ejemplo n.º 6
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' and does not 'fix' the problems it finds
        """

        health = 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)
            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:
            health['isolated_pores'] = sp.where(Ps == 0)[0]

        # Check for separated clusters of pores
        temp = []
        am = self.create_adjacency_matrix(fmt='coo', triu=True)
        Cs = csg.connected_components(am, directed=False)[1]
        if sp.unique(Cs).size > 1:
            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(fmt='csr', triu=True).tocoo()
        hits = sp.where(am.data > 1)[0]
        if len(hits):
            mergeTs = []
            hits = sp.vstack((am.row[hits], am.col[hits])).T
            ihits = hits[:, 0] + 1j * hits[:, 1]
            conns = self['throat.conns']
            iconns = conns[:, 0] + 1j * conns[:, 1]  # Convert to imaginary
            for item in ihits:
                mergeTs.append(sp.where(iconns == item)[0])
            health['duplicate_throats'] = mergeTs

        # Check for bidirectional throats
        adjmat = self.create_adjacency_matrix(fmt='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