コード例 #1
0
    def run(self, points=25, start=None, stop=None):
        r"""
        Runs the percolation algorithm to determine which pores and throats
        will be invaded at each given pressure point.

        Parameters
        ----------
        points: int or array_like
            An array containing the pressure points to apply.  If a scalar is
            given then an array will be generated with the given number of
            points spaced between the lowest and highest values of
            throat entry pressures using logarithmic spacing.  To specify low
            and high pressure points use the ``start`` and ``stop`` arguments.
        start : int
            The optional starting point to use when generating pressure points.
            If not given the half the lowest capillary entry pressure in the
            network is used.
        stop : int
            The optional stopping point to use when generating pressure points.
            If not given, then twice the highest capillary entry pressure in
            the network is used.

        Notes
        -----
        The inlet sites are set to invaded to start the simulation.  This means
        that if 'internal' pores are used as inlets the capillary pressure
        curve will begin at a non-zero invading phase saturation.  To avoid
        this either set the inlet pore volumes to zero or add boundary pores
        to the inlet face, and set their volumes to zero.

        """
        phase = self.project[self.settings.phase]
        # Parse inputs and generate list of invasion points if necessary
        if self.settings['mode'] == 'bond':
            self['throat.entry_pressure'] = \
                phase[self.settings['throat_entry_threshold']]
            if start is None:
                start = np.amin(self['throat.entry_pressure'])*0.5
            if stop is None:
                stop = np.amax(self['throat.entry_pressure'])*2.0

        elif self.settings['mode'] == 'site':
            self['pore.entry_pressure'] = \
                phase[self.settings['pore_entry_threshold']]
            if start is None:
                start = np.amin(self['pore.entry_pressure'])*0.5
            if stop is None:
                stop = np.amax(self['pore.entry_pressure'])*2.0
        else:
            raise Exception('Percolation type has not been set')
        if isinstance(points, int):
            points = np.logspace(start=np.log10(max(1, start)),
                                 stop=np.log10(stop), num=points)
        self._points = points

        # Ensure pore inlets have been set IF access limitations is True
        if self.settings['access_limited']:
            if np.sum(self['pore.inlets']) == 0:
                raise Exception('Inlet pores must be specified first')
            else:
                Pin = self['pore.inlets']

        # Generate curve from points
        conns = self.project.network['throat.conns']
        for inv_val in points:
            if self.settings['mode'] == 'bond':
                t_invaded = self['throat.entry_pressure'] <= inv_val
                labels = bond_percolation(conns, t_invaded)
            elif self.settings['mode'] == 'site':
                p_invaded = self['pore.entry_pressure'] <= inv_val
                labels = site_percolation(conns, p_invaded)

            # Optionally remove clusters not connected to the inlets
            if self.settings['access_limited']:
                labels = remove_isolated_clusters(labels=labels,
                                                  inlets=Pin)

            # Store current applied pressure in newly invaded pores
            pinds = (self['pore.invasion_pressure'] == np.inf) * \
                    (labels.sites >= 0)
            self['pore.invasion_pressure'][pinds] = inv_val
            # Store current applied pressure in newly invaded throats
            tinds = (self['throat.invasion_pressure'] == np.inf) * \
                    (labels.bonds >= 0)
            self['throat.invasion_pressure'][tinds] = inv_val

        # Convert invasion pressures in sequence values
        Pinv = self['pore.invasion_pressure']
        Tinv = self['throat.invasion_pressure']
        Pseq = np.searchsorted(np.unique(Pinv), Pinv)
        Tseq = np.searchsorted(np.unique(Tinv), Tinv)
        self['pore.invasion_sequence'] = Pseq
        self['throat.invasion_sequence'] = Tseq
コード例 #2
0
ファイル: OrdinaryPercolation.py プロジェクト: PMEAL/OpenPNM
    def run(self, points=25, start=None, stop=None):
        r"""
        Runs the percolation algorithm to determine which pores and throats
        will be invaded at each given pressure point.

        Parameters
        ----------
        points: int or array_like
            An array containing the pressure points to apply.  If a scalar is
            given then an array will be generated with the given number of
            points spaced between the lowest and highest values of
            throat entry pressures using logarithmic spacing.  To specify low
            and high pressure points use the ``start`` and ``stop`` arguments.

        start : int
            The optional starting point to use when generating pressure points.
            If not given the half the lowest capillary entry pressure in the
            network is used.

        stop : int
            The optional stopping point to use when generating pressure points.
            If not given, then twice the highest capillary entry pressure in
            the network is used.

        Note
        ----
        The inlet sites are set to invaded to start the simulation.  This means
        that if 'internal' pores are used as inlets the capillary pressure
        curve will begin at a non-zero invading phase saturation.  To avoid
        this either set the inlet pore volumes to zero or add boundary pores
        to the inlet face, and set their volumes to zero.

        """
        phase = self.project.find_phase(self)
        # Parse inputs and generate list of invasion points if necessary
        if self.settings['mode'] == 'bond':
            self['throat.entry_pressure'] = \
                phase[self.settings['throat_entry_threshold']]
            if start is None:
                start = sp.amin(self['throat.entry_pressure'])*0.5
            if stop is None:
                stop = sp.amax(self['throat.entry_pressure'])*2.0

        elif self.settings['mode'] == 'site':
            self['pore.entry_pressure'] = \
                phase[self.settings['pore_entry_threshold']]
            if start is None:
                start = sp.amin(self['pore.entry_pressure'])*0.5
            if stop is None:
                stop = sp.amax(self['pore.entry_pressure'])*2.0
        else:
            raise Exception('Percolation type has not been set')
        if type(points) is int:
            points = sp.logspace(start=sp.log10(max(1, start)),
                                 stop=sp.log10(stop), num=points)
        self._points = points

        # Ensure pore inlets have been set IF access limitations is True
        if self.settings['access_limited']:
            if sp.sum(self['pore.inlets']) == 0:
                raise Exception('Inlet pores must be specified first')
            else:
                Pin = self['pore.inlets']

        # Generate curve from points
        conns = self.project.network['throat.conns']
        for inv_val in points:
            if self.settings['mode'] == 'bond':
                t_invaded = self['throat.entry_pressure'] <= inv_val
                labels = bond_percolation(conns, t_invaded)
            elif self.settings['mode'] == 'site':
                p_invaded = self['pore.entry_pressure'] <= inv_val
                labels = site_percolation(conns, p_invaded)

            # Optionally remove clusters not connected to the inlets
            if self.settings['access_limited']:
                labels = remove_isolated_clusters(labels=labels,
                                                  inlets=Pin)

            # Store current applied pressure in newly invaded pores
            pinds = (self['pore.invasion_pressure'] == sp.inf) * \
                    (labels.sites >= 0)
            self['pore.invasion_pressure'][pinds] = inv_val
            # Store current applied pressure in newly invaded throats
            tinds = (self['throat.invasion_pressure'] == sp.inf) * \
                    (labels.bonds >= 0)
            self['throat.invasion_pressure'][tinds] = inv_val

        # Convert invasion pressures in sequence values
        Pinv = self['pore.invasion_pressure']
        Tinv = self['throat.invasion_pressure']
        Pseq = sp.searchsorted(sp.unique(Pinv), Pinv)
        Tseq = sp.searchsorted(sp.unique(Tinv), Tinv)
        self['pore.invasion_sequence'] = Pseq
        self['throat.invasion_sequence'] = Tseq