def subdivide(network, pores, shape, labels=[]):
    r'''
    It trim the pores and replace them by cubic networks with the sent shape.

    Parameters
    ----------
    network : OpenPNM Network Object

    pores : array_like
        The first group of pores to be replaced

    shape : array_like
        The shape of cubic networks in the target locations

    Notes
    -----
    - It works only for cubic networks.

    Examples
    --------
    >>> import openpnm as op
    >>> pn = op.network.Cubic(shape=[5, 6, 5], spacing=0.001)
    >>> pn.Np
    150
    >>> nano_pores = [2, 13, 14, 15]
    >>> op.topotools.subdivide(network=pn, pores=nano_pores, shape=[4, 7, 3],
    ...                        labels='nano')
    >>> pn.Np
    482

    '''
    mro = network._mro()
    if 'Cubic' not in mro:
        raise Exception('Subdivide is only supported for Cubic Networks')
    from openpnm.network import Cubic
    pores = network._parse_indices(pores)

    # Checks to find boundary pores in the selected pores
    if 'pore.boundary' in network.labels():
        if (sp.in1d(pores, network.pores('boundary'))).any():
            raise Exception('boundary pores cannot be subdivided!')
    if not hasattr(network, '_subdivide_flag'):
        network._subdivide_flag = True
    else:
        raise Exception('The network has subdivided pores, so the method \
                         does not support another subdivision')
    # Assigning right shape and division
    if sp.size(shape) != 2 and sp.size(shape) != 3:
        raise Exception('Subdivide not implemented for Networks other than 2D \
                         and 3D')
    elif sp.size(shape) == 3 and 1 not in shape:
        div = sp.array(shape, ndmin=1)
        single_dim = None
    else:
        single_dim = sp.where(sp.array(network.shape) == 1)[0]
        if sp.size(single_dim) == 0:
            single_dim = None
        if sp.size(shape) == 3:
            div = sp.array(shape, ndmin=1)
        else:
            div = sp.zeros(3, dtype=sp.int32)
            if single_dim is None:
                dim = 2
            else:
                dim = single_dim
            div[dim] = 1
            div[-sp.array(div, ndmin=1, dtype=bool)] = sp.array(shape, ndmin=1)

    # Creating small network and handling labels
    networkspacing = network.spacing
    new_netspacing = networkspacing/div
    new_net = Cubic(shape=div, spacing=new_netspacing)
    main_labels = ['left', 'right', 'front', 'back', 'top', 'bottom']
    if single_dim is not None:
        label_groups = sp.array([['front', 'back'],
                                 ['left', 'right'],
                                 ['top', 'bottom']])
        non_single_labels = label_groups[sp.array([0, 1, 2]) != single_dim]
    for l in main_labels:
        new_net['pore.surface_' + l] = False
        network['pore.surface_' + l] = False
        if single_dim is None:
            new_net['pore.surface_' + l][new_net.pores(labels=l)] = True
        else:
            for ind in [0, 1]:
                loc = (non_single_labels[ind] == l)
                temp_pores = new_net.pores(non_single_labels[ind][loc])
                new_net['pore.surface_' + l][temp_pores] = True

    old_coords = sp.copy(new_net['pore.coords'])
    if labels == []:
        labels = ['pore.subdivided_' + new_net.name]
    for P in pores:
        # Shifting the new network to the right location and attaching it to
        # the main network
        shift = network['pore.coords'][P] - networkspacing/2
        new_net['pore.coords'] += shift
        Pn = network.find_neighbor_pores(pores=P)
        try:
            Pn_new_net = network.pores(labels)
        except KeyError:
            Pn_new_net = []
        Pn_old_net = Pn[~sp.in1d(Pn, Pn_new_net)]
        Np1 = network.Np
        extend(pore_coords=new_net['pore.coords'],
               throat_conns=new_net['throat.conns'] + Np1,
               labels=labels, network=network)

        # Moving the temporary labels to the big network
        for l in main_labels:
            network['pore.surface_'+l][Np1:] = new_net['pore.surface_'+l]

        # Stitching the old pores of the main network to the new extended pores
        surf_pores = network.pores('surface_*')
        surf_coord = network['pore.coords'][surf_pores]
        for neighbor in Pn:
            neighbor_coord = network['pore.coords'][neighbor]
            dist = [round(sp.inner(neighbor_coord-x, neighbor_coord-x),
                          20) for x in surf_coord]
            nearest_neighbor = surf_pores[dist == sp.amin(dist)]
            if neighbor in Pn_old_net:
                coplanar_labels = network.labels(pores=nearest_neighbor)
                new_neighbors = network.pores(coplanar_labels,
                                              mode='xnor')
                # This might happen to the edge of the small network
                if sp.size(new_neighbors) == 0:
                    labels = network.labels(pores=nearest_neighbor,
                                            mode='xnor')
                    common_label = [l for l in labels if 'surface_' in l]
                    new_neighbors = network.pores(common_label)
            elif neighbor in Pn_new_net:
                new_neighbors = nearest_neighbor
            connect_pores(network=network, pores1=neighbor,
                          pores2=new_neighbors, labels=labels)

        # Removing temporary labels
        for l in main_labels:
            network['pore.surface_' + l] = False
        new_net['pore.coords'] = sp.copy(old_coords)

    label_faces(network=network)
    for l in main_labels:
        del network['pore.surface_'+l]
    trim(network=network, pores=pores)
    ws = network.project.workspace
    ws.close_project(new_net.project)
def subdivide ( network , pores , shape , labels = [ ] ) : mro = network . _mro ( ) if 'Cubic' not in mro : raise Exception ( 'Subdivide is only supported for Cubic Networks' ) from openpnm . network import Cubic pores = network . _parse_indices ( pores ) if 'pore.boundary' in network . labels ( ) : if ( sp . in1d ( pores , network . pores ( 'boundary' ) ) ) . any ( ) : raise Exception ( 'boundary pores cannot be subdivided!' ) if not hasattr ( network , '_subdivide_flag' ) : network . _subdivide_flag = True else : raise Exception ( 'The network has subdivided pores, so the method \
                         does not support another subdivision' ) if sp . size ( shape ) != 2 and sp . size ( shape ) != 3 : raise Exception ( 'Subdivide not implemented for Networks other than 2D \
                         and 3D' ) elif sp . size ( shape ) == 3 and 1 not in shape : div = sp . array ( shape , ndmin = 1 ) single_dim = None else : single_dim = sp . where ( sp . array ( network . shape ) == 1 ) [ 0 ] if sp . size ( single_dim ) == 0 : single_dim = None if sp . size ( shape ) == 3 : div = sp . array ( shape , ndmin = 1 ) else : div = sp . zeros ( 3 , dtype = sp . int32 ) if single_dim is None : dim = 2 else : dim = single_dim div [ dim ] = 1 div [ - sp . array ( div , ndmin = 1 , dtype = bool ) ] = sp . array ( shape , ndmin = 1 ) networkspacing = network . spacing new_netspacing = networkspacing / div new_net = Cubic ( shape = div , spacing = new_netspacing ) main_labels = [ 'left' , 'right' , 'front' , 'back' , 'top' , 'bottom' ] if single_dim is not None : label_groups = sp . array ( [ [ 'front' , 'back' ] , [ 'left' , 'right' ] , [ 'top' , 'bottom' ] ] ) non_single_labels = label_groups [ sp . array ( [ 0 , 1 , 2 ] ) != single_dim ] for l in main_labels : new_net [ 'pore.surface_' + l ] = False network [ 'pore.surface_' + l ] = False if single_dim is None : new_net [ 'pore.surface_' + l ] [ new_net . pores ( labels = l ) ] = True else : for ind in [ 0 , 1 ] : loc = ( non_single_labels [ ind ] == l ) temp_pores = new_net . pores ( non_single_labels [ ind ] [ loc ] ) new_net [ 'pore.surface_' + l ] [ temp_pores ] = True old_coords = sp . copy ( new_net [ 'pore.coords' ] ) if labels == [ ] : labels = [ 'pore.subdivided_' + new_net . name ] for P in pores : shift = network [ 'pore.coords' ] [ P ] - networkspacing / 2 new_net [ 'pore.coords' ] += shift Pn = network . find_neighbor_pores ( pores = P ) try : Pn_new_net = network . pores ( labels ) except KeyError : Pn_new_net = [ ] Pn_old_net = Pn [ ~ sp . in1d ( Pn , Pn_new_net ) ] Np1 = network . Np extend ( pore_coords = new_net [ 'pore.coords' ] , throat_conns = new_net [ 'throat.conns' ] + Np1 , labels = labels , network = network ) for l in main_labels : network [ 'pore.surface_' + l ] [ Np1 : ] = new_net [ 'pore.surface_' + l ] surf_pores = network . pores ( 'surface_*' ) surf_coord = network [ 'pore.coords' ] [ surf_pores ] for neighbor in Pn : neighbor_coord = network [ 'pore.coords' ] [ neighbor ] dist = [ round ( sp . inner ( neighbor_coord - x , neighbor_coord - x ) , 20 ) for x in surf_coord ] nearest_neighbor = surf_pores [ dist == sp . amin ( dist ) ] if neighbor in Pn_old_net : coplanar_labels = network . labels ( pores = nearest_neighbor ) new_neighbors = network . pores ( coplanar_labels , mode = 'xnor' ) if sp . size ( new_neighbors ) == 0 : labels = network . labels ( pores = nearest_neighbor , mode = 'xnor' ) common_label = [ l for l in labels if 'surface_' in l ] new_neighbors = network . pores ( common_label ) elif neighbor in Pn_new_net : new_neighbors = nearest_neighbor connect_pores ( network = network , pores1 = neighbor , pores2 = new_neighbors , labels = labels ) for l in main_labels : network [ 'pore.surface_' + l ] = False new_net [ 'pore.coords' ] = sp . copy ( old_coords ) label_faces ( network = network ) for l in main_labels : del network [ 'pore.surface_' + l ] trim ( network = network , pores = pores ) ws = network . project . workspace ws . close_project ( new_net . project )
r'''
    It trim the pores and replace them by cubic networks with the sent shape.

    Parameters
    ----------
    network : OpenPNM Network Object

    pores : array_like
        The first group of pores to be replaced

    shape : array_like
        The shape of cubic networks in the target locations

    Notes
    -----
    - It works only for cubic networks.

    Examples
    --------
    >>> import openpnm as op
    >>> pn = op.network.Cubic(shape=[5, 6, 5], spacing=0.001)
    >>> pn.Np
    150
    >>> nano_pores = [2, 13, 14, 15]
    >>> op.topotools.subdivide(network=pn, pores=nano_pores, shape=[4, 7, 3],
    ...                        labels='nano')
    >>> pn.Np
    482