def set_source_term(self, source_name=None, pores=None, x0=None, tol=None,
                        maxiter=None, mode='merge'):
        r"""
        Apply source terms to specified pores

        Parameters
        ----------
        source_name : string
          Specifies the name of source term from a Physics object to apply.
        pores : array_like
          The pores where the boundary conditions should be applied
        x0 : array_like, optional
          By sending guess values for the quantity, the method calculates the
          source terms and stores them in the algorithm
        tol : float, optional
          Tolerance for the iterative method. (if maxiter>0)
        maxiter : integer, optional
          Maximum number of iterations for this source term. Iteration will
          stop after maxiter steps.
        mode : string, optional
          Controls how the source terms should be applied.
          Options are:
                - 'merge': Inserts specified values, leaving existing values \
                  elsewhere.
                - 'overwrite': Inserts specified values, clearing all other \
                  values.
                - 'remove': Removes boundary conditions from specified \
                  locations.
                - 'update': Allows to insert specified values to new \
                  locations, updating existing ones.

        Notes
        -----
        Difference between 'merge' and 'update' modes: in the merge, a new
        value cannot be applied to a pore with existing one, but in the
        'update' it is possible.

        """

        if mode not in ['merge', 'overwrite', 'remove', 'update']:
            raise Exception('The mode (' + mode + ') cannot be applied to ' +
                            'the set_source_term!')
        if pores is not None:
            pores = sp.array(pores, ndmin=1)
        # Checking for existance of source_name
        if source_name is not None:
            s_group = sp.array(source_name, ndmin=1)
            for source_name in s_group:
                source_name = 'pore.' + source_name.split('.')[-1]
                prop = source_name.split('.')[-1]
                try:
                    self._phase[source_name]
                except KeyError:
                    Exception('The attached phase in the algorithm ' +
                              self.name + ', does not have the source ' +
                              'property ' + source_name + ' in its physics!')
                except ValueError:
                    pass

                if mode == 'remove':
                    s_mode = ['linear', 'nonlinear']
                    if pores is None:
                        try:
                            del self['pore.source_' + prop]
                        except KeyError:
                            pass
                        for s in s_mode:
                            try:
                                del self['pore.source_' +
                                         s + '_s1_' + prop]
                            except KeyError:
                                pass
                            try:
                                del self['pore.source_' +
                                         s + '_s2_' + prop]
                            except KeyError:
                                pass
                    else:
                        try:
                            self['pore.source_' + prop][pores] = False
                        except KeyError:
                            pass
                        for s in s_mode:
                            try:
                                self['pore.source_' +
                                     s + '_s1_' +
                                     prop][pores] = sp.nan
                            except KeyError:
                                pass
                            try:
                                self['pore.source_' +
                                     s + '_s2_' + prop][pores] = sp.nan
                            except KeyError:
                                pass

                else:
                    # Handle tol, x0 and maxiter for the Picard algorithm
                    if 'pore.source_tol' not in self.props():
                        self['pore.source_tol'] = sp.ones((self.Np,),
                                                          dtype=float) * sp.nan
                    if 'pore.source_maxiter' not in self.props():
                        maxiter_arr = sp.ones((self.Np,), dtype=float) * sp.nan
                        self['pore.source_maxiter'] = maxiter_arr

                    if x0 is None:
                        x0 = 0
                    self._guess = x0
                    # Check value of maxiter
                    if maxiter is None:
                        maxiter = int(100)
                        source_mode = 'nonlinear'
                    else:
                        try:
                            maxiter = int(maxiter)
                        except (ValueError, __HOLE__):
                            raise Exception('input for maxiter cannot be ' +
                                            'converted to integer!')
                        if maxiter > 0:
                            source_mode = 'nonlinear'
                        elif maxiter == 0:
                            source_mode = 'linear'
                    # Check value of tol
                    if tol is None:
                        tol = 1e-5
                    else:
                        try:
                            tol = float(tol)
                        except (ValueError, TypeError):
                            raise Exception('input for tol cannot be ' +
                                            'converted to float!')

                    if ('pore.source_' + prop not in self.labels() or
                            mode == 'overwrite'):
                        self['pore.source_' + prop] = sp.zeros((self.Np,),
                                                               dtype=bool)
                        temp_arr = sp.ones((self.Np,), dtype=float) * sp.nan
                        self['pore.source_' + source_mode +
                             '_s1_' + prop] = temp_arr
                        self['pore.source_' + source_mode +
                             '_s2_' + prop] = temp_arr

                    # Setting the source term for all the modes except 'remove'
                    matching_physics = [phys for phys in self._phase._physics
                                        if source_name in phys.models.keys()]
                    for phys in matching_physics:
                        x = phys.models[source_name]['x']
                        return_rate = phys.models[source_name]['return_rate']
                        regen_mode = phys.models[source_name]['regen_mode']
                        phys.models[source_name]['x'] = x0
                        phys.models[source_name]['return_rate'] = False
                        phys.models[source_name]['regen_mode'] = 'normal'
                        s_regen = phys.models[source_name].run()
                        phys.models[source_name]['x'] = x
                        phys.models[source_name]['return_rate'] = return_rate
                        phys.models[source_name]['regen_mode'] = regen_mode
                        map_pores = phys.map_pores()
                        loc = pores[sp.in1d(pores, map_pores)]
                        if mode == 'merge':
                            try:
                                spore = self.pores('source_' + prop)
                                if sp.sum(sp.in1d(loc, spore)) > 0:
                                    raise Exception('Because of the existing '
                                                    'source term, the method '
                                                    'cannot apply new source '
                                                    'terms with the merge mode'
                                                    ' to the specified pores.')
                            except KeyError:
                                pass
                        self['pore.source_' + prop][loc] = True
                        map_pores_loc = sp.in1d(map_pores, pores)
                        self['pore.source_' + source_mode +
                             '_s1_' + prop][loc] = s_regen[:, 0][map_pores_loc]
                        self['pore.source_' + source_mode +
                             '_s2_' + prop][loc] = s_regen[:, 1][map_pores_loc]
                        if source_mode is not 'linear':
                            self['pore.source_maxiter'][loc] = maxiter
                            self['pore.source_tol'][loc] = tol
        else:
            raise Exception('No source_name has been sent for set_source_' +
                            'term method in the algorithm ' + self.name)
dataset/ETHPy150Open PMEAL/OpenPNM/OpenPNM/Algorithms/__GenericLinearTransport__.py/GenericLinearTransport.set_source_term