def set_boundary_conditions(self, bctype='', bcvalue=None, pores=None,
                                throats=None, mode='merge'):
        r"""
        Apply boundary conditions to specified pores or throats

        Parameters
        ----------
        bctype : string
            Specifies the type or the name of boundary condition to apply. \
            The types can be one one of the followings:
                 - 'Dirichlet' : Specify the quantity in each location
                 - 'Neumann' : Specify the flow rate into each location
                 - 'Neumann_group' : Specify the net flow rate into a group
                   of pores/throats
        component : OpenPNM Phase object
            The Phase object to which this BC applies
        bcvalue : array_like
            The boundary value to apply, such as concentration or rate
        pores : array_like
            The pores where the boundary conditions should be applied
        throats : array_like
            The throats where the boundary conditions should be applied
        mode : string, optional
            Controls how the conditions are applied.  Options are:

            - 'merge': Inserts the specified values, leaving existing values \
              elsewhere
            - 'overwrite': Inserts specified values, clearing all other \
              values for that specific bctype
            - 'remove': Removes boundary conditions from specified locations

        Notes
        -----
        - It is not possible to have multiple boundary conditions for a
          specified location in just one algorithm. So when new condition is
          going to be applied to a specific location, any existing one should
          be removed or overwritten.
        - BCs for pores and for throats should be applied independently.
        """
        try:
            self._existing_BC
        except __HOLE__:
            self._existing_BC = []
        if sp.size(self._phases) != 1:
            raise Exception('In each use of set_boundary_conditions ' +
                            'method, one component should be specified ' +
                            'or attached to the algorithm.')
        else:
            component = self._phases[0]

        if mode not in ['merge', 'overwrite', 'remove']:
            raise Exception('The mode (' + mode + ') cannot be applied to ' +
                            'the set_boundary_conditions!')

        logger.debug('BC method applies to the component: ' + component.name)
        # Validate bctype
        if bctype == '':
            raise Exception('bctype must be specified!')
        # If mode is 'remove', also bypass checks
        if mode == 'remove':
            if pores is None and throats is None:
                for item in self.labels():
                    if bctype == item.split('.')[-1]:
                        element = item.split('.')[0]
                        try:
                            del self[element + '.' + 'bcval_' + bctype]
                        except KeyError:
                            pass
                        try:
                            del self[element + '.' + bctype]
                        except KeyError:
                            pass
                logger.debug('Removing ' + bctype + ' from all locations' +
                             ' for ' + component.name + ' in ' +
                             self.name)
                self._existing_BC.remove(bctype)
            else:
                if pores is not None:
                    prop_label = 'pore.' + 'bcval_' + bctype
                    self[prop_label][pores] = sp.nan
                    info_label = 'pore.' + bctype
                    self[info_label][pores] = False
                    logger.debug('Removing ' + bctype + ' from the ' +
                                 'specified pores for ' + component.name +
                                 ' in ' + self.name)
                if throats is not None:
                    prop_label = 'throat.' + 'bcval_' + bctype
                    self[prop_label][throats] = sp.nan
                    info_label = 'throat.' + bctype
                    self[info_label][throats] = False
                    logger.debug('Removing ' + bctype + ' from the ' +
                                 'specified throats for ' +
                                 component.name + ' in ' + self.name)
            return
        # Validate pores/throats
        if pores is None and throats is None:
            raise Exception('pores/throats must be specified')
        elif pores is not None and throats is not None:
            raise Exception('BC for pores and throats must be specified ' +
                            'independently.')
        elif throats is None:
            element = 'pore'
            loc = sp.array(pores, ndmin=1)
            all_length = self.Np
        elif pores is None:
            element = 'throat'
            loc = sp.array(throats, ndmin=1)
            all_length = self.Nt
        else:
            raise Exception('Problem with the pore and/or throat list')
        # Validate bcvalue
        if bcvalue is not None:
            # Check bcvalues are compatible with bctypes
            if bctype == 'Neumann_group':  # Only scalars are acceptable
                if sp.size(bcvalue) != 1:
                    raise Exception('When specifying Neumann_group, bcval ' +
                                    'should be a scalar')
                else:
                    bcvalue = sp.float64(bcvalue)
                    if 'Neumann_group' not in self._existing_BC:
                        setattr(self, '_' + element +
                                '_Neumann_group_location', [])
                    getattr(self, '_' + element +
                            '_Neumann_group_location').append(loc)
            else:  # Only scalars or Np/Nt-long are acceptable
                if sp.size(bcvalue) == 1:
                    bcvalue = sp.ones(sp.shape(loc)) * bcvalue
                elif sp.size(bcvalue) != sp.size(loc):
                    raise Exception('The pore/throat list and bcvalue list ' +
                                    'are different lengths')
        # Confirm that prop and label arrays exist
        l_prop = element + '.' + 'bcval_' + bctype
        if l_prop not in self.props():
            self[l_prop] = sp.ones((all_length,), dtype=float) * sp.nan
        l_label = element + '.' + bctype
        if l_label not in self.labels():
            self[l_label] = sp.zeros((all_length,), dtype=bool)
        # Check all BC from specified locations, prior to setting new ones
        for item in self.labels():
            bcname = item.split('.')[-1]
            if bcname in self._existing_BC and item.split('.')[0] == element:
                if mode in ['merge', 'overwrite']:
                    try:
                        c1 = element
                        c2 = 'bcval_' + bcname
                        c1_label = c1 + c2
                        self[c1_label][loc]
                        condition1 = sp.isnan(self[c1_label][loc]).all()
                        c2_label = c1 + '_' + bcname
                        condition2 = sp.sum(self[c2_label][loc]) == 0
                        if not (condition1 and condition2):
                            if mode == 'merge':
                                raise Exception('Because of the existing ' +
                                                'BCs, the method cannot ' +
                                                'apply new BC with the merge' +
                                                ' mode to the specified pore' +
                                                '/throat.')
                            elif (mode == 'overwrite' and bcname != bctype):
                                raise Exception('Because of the existing ' +
                                                'BCs, the method cannot ' +
                                                'apply new BC with overwrite' +
                                                ' mode. This mode only ' +
                                                'overwrites this bctype, ' +
                                                'not the other ones.')
                    except KeyError:
                        pass
        # Set boundary conditions based on supplied mode
        if mode == 'merge':
            if bcvalue is not None:
                self[l_prop][loc] = bcvalue
            self[l_label][loc] = True
            if bctype not in self._existing_BC:
                self._existing_BC.append(bctype)
        elif mode == 'overwrite':
            self[l_prop] = sp.ones((all_length,), dtype=float) * sp.nan
            if bcvalue is not None:
                self[l_prop][loc] = bcvalue
            self[l_label] = sp.zeros((all_length,), dtype=bool)
            self[l_label][loc] = True
            if bctype not in self._existing_BC:
                self._existing_BC.append(bctype)
dataset/ETHPy150Open PMEAL/OpenPNM/OpenPNM/Algorithms/__GenericLinearTransport__.py/GenericLinearTransport.set_boundary_conditions