Exemplo n.º 1
0
def add_cap_ox(clust):
    # TODO: fix bug where adds multiple oxygen's to the same place
    """
    Args:
        clust:
    """
    nl = NeighborList(natural_cutoffs(clust),
                      bothways=True,
                      self_interaction=False)
    nl.update(clust)
    new_clust = clust
    cap_inds = get_cap_si(clust)
    for ind in cap_inds:
        while len(nl.get_neighbors(ind)[0]) < 4:
            neighb = nl.get_neighbors(ind)[0][
                -1]  # last index in the list of neighbor indicies
            direction = clust.get_positions()[ind] - clust.get_positions()[
                neighb]  # vector pointing from neighbor to Si
            ox_pos = clust.get_positions(
            )[ind] + 1.6 * direction / np.linalg.norm(direction)
            new_ox = Atom('O', position=ox_pos)
            new_clust.append(new_ox)
            nl = NeighborList(natural_cutoffs(clust),
                              bothways=True,
                              self_interaction=False)
            nl.update(clust)
    return (new_clust)
Exemplo n.º 2
0
def test_cutoffs():
    from ase.neighborlist import natural_cutoffs
    from ase import Atoms
    import numpy as np

    atoms = Atoms("HCOPtAu")

    assert np.allclose(natural_cutoffs(atoms), [0.31, 0.76, 0.66, 1.36, 1.36])
    assert np.allclose(natural_cutoffs(atoms, mult=1.2),
                       [0.372, 0.912, 0.792, 1.632, 1.632])
    assert np.allclose(natural_cutoffs(atoms, mult=1.2, Au=1),
                       [0.372, 0.912, 0.792, 1.632, 1])
Exemplo n.º 3
0
    def get_Z_TM(self, atoms, d_Z_TM, TM_type):
        # todo: improve flexibility to allow Z-TM-H or Z-TM-OH insertions while avoid overlapping
        nl = NeighborList(natural_cutoffs(atoms),
                          bothways=True,
                          self_interaction=False)
        nl.update(atoms)
        index_Al = [a.index for a in atoms if a.symbol == 'Al']
        indices, offsets = nl.get_neighbors(index_Al[0])
        indices = [val for val in indices if atoms[val].symbol == 'O']
        assert len(indices) == 4

        dict_Z_TM = {}
        original_atoms = copy.copy(atoms)
        pairs = list(itertools.combinations(indices, 2))
        for i, pair in enumerate(pairs):
            atoms = copy.copy(original_atoms)
            v = self._get_direction_of_insertion(atoms,
                                                 index_Al[0],
                                                 pair[0],
                                                 pair[1],
                                                 tag='TM')
            atoms = atoms + Atoms(
                TM_type, positions=[atoms[index_Al[0]].position] + v * d_Z_TM)
            atoms.wrap()
            key_tag = 'O' + str(pair[0]) + '_O' + str(pair[1])
            dict_Z_TM[key_tag] = atoms

        return dict_Z_TM
Exemplo n.º 4
0
    def get_all_Z_TM(self, d_Z_TM, TM_type):
        """
        :param d_Z_TM: Z-TM distance with Z being the T sites on the zeolite framework and TM being extraframework atom
        to be inserted
        :return: a dictionary of structures for each T site name
        """
        dict_Z_TM = {}
        for site_name, all_zeo_with_same_T in self.dict_1Al_replaced.items():
            atoms = copy.copy(all_zeo_with_same_T[0])
            nl = NeighborList(natural_cutoffs(atoms),
                              bothways=True,
                              self_interaction=False)
            nl.update(atoms)
            index_Al = [a.index for a in atoms if a.symbol == 'Al']
            indices, offsets = nl.get_neighbors(index_Al[0])
            assert len(indices) == 4

            traj = []
            pairs = list(itertools.combinations(indices, 2))
            for i, pair in enumerate(pairs):
                atoms = copy.copy(all_zeo_with_same_T[0])
                v = self._get_direction_of_insertion(atoms,
                                                     index_Al[0],
                                                     pair[0],
                                                     pair[1],
                                                     tag='TM')
                atoms = atoms + Atoms(
                    TM_type,
                    positions=[atoms[index_Al[0]].position] + v * d_Z_TM)
                traj.append(atoms)
            dict_Z_TM[site_name] = traj

        return dict_Z_TM
Exemplo n.º 5
0
def get_angles(cluster, mult=1, excluded_index=None, excluded_pair=None):
    """
    #TODO: consider combining get_bonds and get_angles function
    ase.geometry.analysis.Analysis.unique_angles function does not work, return all angles.
    three-body interactions.
    :param excluded_pair: excluding all [particle1, particle2, particle3] lists involving the excluded pair
    """
    if excluded_index is None:
        excluded_index = []
    if excluded_pair is None:
        excluded_pair = []

    nl = NeighborList(natural_cutoffs(cluster, mult=mult),
                      bothways=True,
                      self_interaction=False)
    nl.update(cluster)

    angle_list, shortened_list = [], []
    for count, indices in enumerate(Analysis(cluster, nl=nl).all_angles[0]):
        for index in indices:
            if all(
                    list(val) not in angle_list for val in list(
                        permutations([count, index[0], index[1]]))):
                angle_list.append([count, index[0], index[1]])

    for angle in angle_list:
        if all(single_index not in angle for single_index in excluded_index) and \
                all(list(value) not in excluded_pair for value in list(permutations(angle, 2))):
            shortened_list.append(angle)

    return angle_list, shortened_list
Exemplo n.º 6
0
def get_bonds(cluster, mult=1, excluded_index=None, excluded_pair=None):
    """
    Using ase.geometry.analysis.Analysis to get all bonds, then remove the repeated ones.
    Function also allows removing certain bonding pair defined by user (excluded_pair).
    Or removing pairs including certain atomic indices (excluded_index).
    :param cluster:
    :param mult:
    :param excluded_index: list of integers
    :param excluded_pair: list of lists
    :return: full bonding list, shortened list.
    If both excluded_index and excluded_pair are None, bonding list == shortened list
    """
    if excluded_index is None:
        excluded_index = []
    if excluded_pair is None:
        excluded_pair = []

    nl = NeighborList(natural_cutoffs(cluster, mult=mult),
                      bothways=True,
                      self_interaction=False)
    nl.update(cluster)

    bond_list, shortened_list = [], []
    for count, indices in enumerate(Analysis(cluster, nl=nl).all_bonds[0]):
        for index in indices:
            if [count, index] not in bond_list and [index, count
                                                    ] not in bond_list:
                bond_list.append([count, index])

    for bond in bond_list:
        if all(single_index not in bond for single_index in excluded_index) and \
                all(tuple(bond) not in list(permutations(pair)) for pair in excluded_pair):
            shortened_list.append(bond)

    return bond_list, shortened_list
def atoms2graph(atoms, kwargs={}):

    unit_cell = atoms.get_cell()
    cutoffs = neighborlist.natural_cutoffs(atoms)
    NL = neighborlist.NewPrimitiveNeighborList(
        cutoffs, self_interaction=False,
        skin=0.1)  # default atom cutoffs work well
    NL.build([False, False, False], unit_cell, atoms.positions)

    G = nx.Graph()

    for a, ccoord in zip(atoms, atoms.positions):
        ind = a.index + 1
        G.add_node(a.symbol + str(ind),
                   element_symbol=a.symbol,
                   ccoord=ccoord,
                   fcoord=np.array([0.0, 0.0, 0.0]),
                   freeze_code='0',
                   **kwargs)

    for a in G.nodes():

        nbors = [
            atoms[i].symbol + str(atoms[i].index + 1)
            for i in NL.get_neighbors(int(nl(a)) - 1)[0]
        ]

        for nbor in nbors:
            G.add_edge(a, nbor, bond_type='', bond_sym='.', bond_length=0)

    return G
def find_neighbor_index(cell, defectIndex, neighborOffset):
	# very similar to generating the mask indices
	cutOff = natural_cutoffs(cell, 1)
	nl = neighborlist.NeighborList(cutOff, 0.3, False, False, False)
	nl.update(cell)

	index_nei, offset_nei = nl.get_neighbors(defectIndex)

	# if index_nei.any():
	# 	return index_nei[0 + neighborOffset]
	# else:
	# 	return defectIndex + 1

	try:
		return index_nei[0 + neighborOffset]
	except IndexError:
		print('Warning: The defect atom does not have enough neighbor for neighborOffset = ', neighborOffset)
		print('Warning: Falling back to first neighbor')

		try:
			return index_nei[0]
		except:
			print('Warning: The defect atom does not have any available neighbor')
			print('Warning: Falling further back to next atom')

			return defectIndex + 1
def read_cif(cif):

    atoms = read(cif, format='cif')
    atoms.set_pbc(True)
    cutoffs = neighborlist.natural_cutoffs(atoms)
    unit_cell = atoms.get_cell()

    neighborlist.primitive_neighbor_list
    NL = neighborlist.NewPrimitiveNeighborList(cutoffs,
                                               use_scaled_positions=True,
                                               self_interaction=False,
                                               skin=0.1)
    NL.build([True, True, True], unit_cell, atoms.get_scaled_positions())

    G = nx.Graph()

    for a, fcoord in zip(atoms, atoms.get_scaled_positions()):
        G.add_node(a.symbol + str(a.index),
                   element_symbol=a.symbol,
                   fcoord=fcoord)

    for a in G.nodes():

        nbors = [
            atoms[i].symbol + str(atoms[i].index)
            for i in NL.get_neighbors(int(nl(a)))[0]
        ]

        for nbor in nbors:
            G.add_edge(a, nbor)

    return G, np.asarray(unit_cell).T
Exemplo n.º 10
0
def nest(atoms, index):

    position = atoms[index].position  # position of that t site

    # This centers the atom object on the T site we want to remove
    center = atoms.get_center_of_mass()
    trans = center - position
    atoms.translate(trans)
    atoms.wrap()

    # get the neighbor list
    cutoff = neighborlist.natural_cutoffs(atoms, mult=1.05)
    nl = neighborlist.NeighborList(cutoffs=cutoff,
                                   self_interaction=False,
                                   bothways=True)
    nl.update(atoms)
    oxygens = nl.get_neighbors(index)[0]

    # add a hydrogen next to each neighbor oxygen

    for o in oxygens:
        vector = position - atoms[o].position
        hyd = molecule('H')
        new_location = atoms[o].position + vector / (vector**2).sum()**.5
        hyd.translate(new_location)
        atoms = atoms + hyd

    # recenter the atoms back to their original position and delete the Si
    atoms.translate(-trans)
    atoms.wrap()
    del (atoms[index])
    return atoms
Exemplo n.º 11
0
    def get_cluster_indices_multi_T_site(zeolite, T_indices: Iterable[int],
                                         max_size: int,
                                         max_neighbors: int) -> List[int]:
        """
        get the indices of a cluster from a zeolite when specifying the
        center atom index and size of the cluster

        :param T_indices: Indices of the T site
        :type T_indices: Iterable[int]
        :param zeolite: the zeolite from which to build the cluster
        :param index: the centeral atom index
        :param max_size: the max number of atoms in the final cluster
        :param max_neighbors: the max number of neighbors from the starting cluster
        :return: a list of indices
        """
        nl = NeighborList(natural_cutoffs(zeolite),
                          self_interaction=False,
                          bothways=True)
        nl.update(zeolite)
        cluster_indices = set()
        new_cluster_indices = set(T_indices)

        for _ in range(max_neighbors):
            current_cluster_indices = set()
            for cluster_index in new_cluster_indices:
                cluster_indices.add(cluster_index)
                if len(cluster_indices) >= max_size:
                    return list(cluster_indices)
                for new_index in nl.get_neighbors(cluster_index)[0]:
                    if new_index not in T_indices:  # don't add T sites to current cluster indices
                        current_cluster_indices.add(new_index)
            new_cluster_indices = current_cluster_indices

        return list(cluster_indices)
Exemplo n.º 12
0
    def get_donor_vec(self, donor_index):
        """finds direction of lone pair electrons on an adsorbate donor atom
        :return: vector direction of donor atoms

        Args:
            donor_index:
        """
        nl = NeighborList(natural_cutoffs(self),
                          self_interaction=False,
                          bothways=True)
        nl.update(self)
        # gets neighbors of donor atom and adds the vectors from neighbor to donor
        # for most donor atoms this is roughly in the proper binding direction
        donor_neighbors = nl.get_neighbors(donor_index)[0]  # neighbor's index
        donor_vec = np.array([0, 0, 0])
        for i in donor_neighbors:
            a = self.get_distance(i, donor_index, vector=True)
            donor_vec = donor_vec + a
        if np.linalg.norm(donor_vec) == 0:
            warnings.warn(
                "donor vector with magnitude 0 found, providing default  vector"
            )
            return np.array([1, 0, 0])

        donor_vec = donor_vec / np.linalg.norm(
            donor_vec)  # normalizes donor vec
        return donor_vec
def generate_normals_original(atoms, surface_normal=0.5, normalize_final=True, adsorbate_atoms=[]):
    normals = np.zeros(shape=(len(atoms), 3), dtype=float)

    atoms = atoms.copy()

    del atoms[adsorbate_atoms]

    cutoffs = natural_cutoffs(atoms)

    nl = NeighborList(cutoffs, self_interaction=False, bothways=True)
    nl.update(atoms)

    cell = atoms.get_cell()

    for index, atom in enumerate(atoms):
        normal = np.array([0, 0, 0], dtype=float)
        for neighbor, offset in zip(*nl.get_neighbors(index)):
            direction = atom.position - offset_position(atoms, neighbor, offset)
            normal += direction
        if norm(normal) > surface_normal:
            normals[index,:] = normalize(normal) if normalize_final else normal

    surface_mask = [index for index in range(len(atoms)) if norm(normals[index]) > 1e-5]

    return normals, surface_mask
Exemplo n.º 14
0
def find_tmpo(atoms):
    """
    Args:
        atoms:
    """
    tmpo_indices = []
    p_index = None
    for a in atoms:
        if a.symbol == 'P':
            p_index = a.index
            break
    tmpo_indices.append(p_index)
    if p_index is None:
        return tmpo_indices
    nl = NeighborList(natural_cutoffs(atoms),
                      bothways=True,
                      self_interaction=False)
    nl.update(atoms)
    p_nl = nl.get_neighbors(p_index)[0]
    tmpo_indices.extend(p_nl)
    for i in p_nl:
        if atoms[i].symbol == 'C':
            tmpo_indices.extend(nl.get_neighbors(i)[0])

    return tmpo_indices
Exemplo n.º 15
0
def xyz_to_json(mol):
    cutOff = neighborlist.natural_cutoffs(mol)
    cutOff = [cc - 0.2 for cc in cutOff]
    neighborList = neighborlist.NeighborList(cutOff,
                                             self_interaction=False,
                                             bothways=True)
    neighborList.update(mol)

    neighborList.get_neighbors(0)

    bmatrix = neighborList.get_connectivity_matrix(sparse=False)

    dmatrix = sp.spatial.distance_matrix(mol.positions, mol.positions)
    dmatrix[dmatrix > 2] == 0
    g = nx.Graph(dmatrix)
    g2 = nx.Graph(bmatrix)
    list(g.edges(data=True))

    symbols = mol.get_chemical_symbols()

    nodes_data = [{'id': node, 'atom': symbols[node]} for node in g.nodes]

    edge_data = [{
        'id': num,
        'source': at[0],
        'target': at[1],
        'strength': 2 if (at[0], at[1]) in g2.edges() else 0.1,
        'bond': 1 if (at[0], at[1]) in g2.edges() else 0,
        'distance': at[2]['weight'] * 20
    } for num, at in enumerate(list(g.edges(data=True)))]

    data = {'nodes': nodes_data, 'links': edge_data}
    return data
Exemplo n.º 16
0
def create_connectivity_matrix(atoms, bothways):
    cutOff = neighborlist.natural_cutoffs(atoms)
    neighborList = neighborlist.NeighborList(cutOff,
                                             self_interaction=False,
                                             bothways=bothways)
    neighborList.update(atoms)
    connectivity_matrix = neighborList.get_connectivity_matrix()
    return connectivity_matrix
Exemplo n.º 17
0
def get_rings(atoms, index):
    '''
    WARNING: This is old and does not work for all framework types.
    WARNING: Use the updated get_orings function below instead.


    atoms: ASE atoms object of the zeolite framework to be analyzed
    index: (integer) index of the atom that you want to classify
    '''

    cell = atoms.get_cell_lengths_and_angles()[:3]
    repeat = []

    for i, c in enumerate(cell):
        if c / 2 < 15:
            l = c
            re = 1
            while l / 2 < 15:
                re += 1
                l = c * re

            repeat.append(re)
        else:
            repeat.append(1)
    atoms = atoms.repeat(repeat)
    center = atoms.get_center_of_mass()
    trans = center - atoms.positions[index]
    atoms.translate(trans)
    atoms.wrap()

    cutoff = neighborlist.natural_cutoffs(atoms, mult=1.05)
    nl = neighborlist.NeighborList(cutoffs=cutoff,
                                   self_interaction=False,
                                   bothways=True)
    nl.update(atoms)
    matrix = nl.get_connectivity_matrix(sparse=False)
    m = matrix.copy()
    G = nx.from_numpy_matrix(matrix)

    neighbs = nx.neighbors(G, index)
    for n in neighbs:
        if atoms[n].symbol == 'Si':
            fe = [n]
    fe.append(index)

    G.remove_edge(fe[0], fe[1])
    Class = []
    while len(Class) < 6:
        try:
            path = nx.shortest_path(G, fe[0], fe[1])
        except:
            break
        Class.append(int(len(path) / 2))
        for i in range(len(path) - 3):
            G.remove_edge(path[i + 1], path[i + 2])
        Class.sort(reverse=True)
    return Class
Exemplo n.º 18
0
def neighbours(atoms, centre, shell, cutoff=None, verbose=False):
    ''' Returns a list of indices of atomic neighbors from a central atom

    Parameters:
    atoms : Atoms object
        Input structure to count neighbours
    centre : list of integers
        Indices of atom(s) to start counting from
    shell : Integer
        Size of the nearest neighbour shell, 1st neighbours, 2nd neighbours ....
    cutoff: list of floats or None
        Bond length cutoff distance in Angstrom can be set for each atom individually
        The list must contain exactly len(atoms) floats. If None, natural_cutoffs
        are used by default.
    verbose: boolean
        If True, information about the cutoffs and selected neighbors is printed

    Returns:
        List of all atoms within specified neighbour distances
        List of lists containing indices of atoms that make 0th, 1st (...) shell
    '''

    from ase.neighborlist import natural_cutoffs, NeighborList

    if not cutoff:
        # Choose a cutoff to determine max bond distance, otherwise use natural cutoff
        cutoff = natural_cutoffs(atoms)
        if verbose:
            print("Default bond cutoffs selected:", set([(atoms[i].symbol, cutoff[i]) for i in range(len(atoms))]))

    # Set object storing all neighbour information
    all_neighbours = set(centre)
    # List of lists storing each neighbour shell requested
    shell_list = [centre]

    # Creates an empty list an appends atom indices whose distances are
    # x amount nearest neighbours away from centre
    for neighbors in range(shell):
        # keep new neighbor indices in a set to avoid duplicates
        new_neighbors = set()
        for index in all_neighbours:
            # find neighbors based on cutoff and connectivity matrix
            nl = NeighborList(cutoff, self_interaction=False, bothways=True)
            nl.update(atoms)
            indices = nl.get_neighbors(index)[0]
            for i in indices:
                new_neighbors.add(i)

        shell_list += [[i for i in new_neighbors if i not in all_neighbours]]
        for i in new_neighbors:
            all_neighbours.add(i)

        if verbose:
            for shell in range(len(shell_list)):
                print("Shell", shell, "contains atoms with indices:", shell_list[shell])

    return list(all_neighbours), shell_list
Exemplo n.º 19
0
    def construct(self, atoms, scale_factor=1.0):
        neighbor_list = build_neighbor_list(atoms,
                                            cutoffs=natural_cutoffs(
                                                atoms, mult=scale_factor),
                                            bothways=True,
                                            self_interaction=False)

        for atom_idx, _ in enumerate(atoms):
            neighbors, _ = neighbor_list.get_neighbors(atom_idx)
            self.list[atom_idx] = set(neighbors)
Exemplo n.º 20
0
 def update_nl(self, mult: float = 1) -> None:
     """
     Builds and updates neighborlist
     :param mult: The mult (multiply) parameter for natural cutoffs (Default 1)
     :return: None
     """
     self.neighbor_list = NeighborList(natural_cutoffs(self, mult=mult),
                                       bothways=True,
                                       self_interaction=False)
     self.neighbor_list.update(self)
Exemplo n.º 21
0
def all_trings(atoms, index, possible, delete=True):
    '''
    For developmental testing purposes only.
    '''
    possible = possible * 2
    atoms2 = atoms.copy()
    cell = atoms2.get_cell_lengths_and_angles()[:3]
    repeat = []
    maxring = max(possible)
    for i, c in enumerate(cell):
        if c / 2 < maxring / 2 + 5:
            l = c
            re = 1
            while l / 2 < maxring / 2 + 5:
                re += 1
                l = c * re

            repeat.append(re)
        else:
            repeat.append(1)
    atoms2 = atoms2.repeat(repeat)
    center = atoms2.get_center_of_mass()
    trans = center - atoms2.positions[index]
    atoms2.translate(trans)
    atoms2.wrap()

    cutoff = neighborlist.natural_cutoffs(atoms2, mult=0.95)
    nl = neighborlist.NeighborList(cutoffs=cutoff,
                                   self_interaction=False,
                                   bothways=True)
    nl.update(atoms2)
    matrix = nl.get_connectivity_matrix(sparse=False)
    m = matrix.copy()
    G = nx.from_numpy_matrix(matrix)
    rings = find_simple_o_rings(G, index, possible)
    paths = remove_dups(rings)
    # paths = remove_sec(paths)
    if delete == True:
        keepers = []
        for i in paths:
            for j in i:
                if j not in keepers:
                    keepers.append(j)
        d = [atom.index for atom in atoms2 if atom.index not in keepers]
        atoms2 = substitute.tsub(atoms2, index, 'Al')
        del atoms2[d]

    Class = []
    for p in paths:
        Class.append(int(len(p) / 2))

    paths = [x for _, x in sorted(zip(Class, paths), reverse=True)]
    Class.sort(reverse=True)

    return Class, paths, atoms2, repeat
Exemplo n.º 22
0
def type_atoms(atoms_obj):
    """
    Args:
        atoms_obj:
    """
    type_dict = defaultdict(list)

    # Getting neighbor list
    nl = NeighborList(natural_cutoffs(atoms_obj),
                      bothways=True,
                      self_interaction=False)
    nl.update(atoms_obj)

    for i in atoms_obj:
        # labels framework atoms
        if i.symbol in ['Sn', 'Al', 'Si']:
            label = 'framework-%s' % i.symbol
        # label carbon and nitrogen as adsorbate
        elif i.symbol in ['C', 'N']:
            label = 'adsorbate-%s' % i.symbol

        # label Cu, Ni as extraframework
        elif i.symbol in ['Cu', 'Ni']:
            label = 'extraframework-%s' % i.symbol

        # label oxygens as framework, adsorbate, or bound adsorbate
        elif i.symbol == 'O':
            neigh_ind = nl.get_neighbors(i.index)
            if len(neigh_ind) == 2:
                neigh_sym1, neigh_sym2 = atoms_obj[
                    neigh_ind[0][0]].symbol, atoms_obj[neigh_ind[0][1]].symbol
                # assign framework oxygens
                if neigh_sym1 in ['Sn', 'Al', 'Si'
                                  ] and neigh_sym2 in ['Sn', 'Al', 'Si']:
                    label = 'framework-%s' % i.symbol
                # assign bound adsorbate oxygen
                elif neigh_sym1 in ['H', 'C', 'N'
                                    ] and neigh_sym2 in ['Sn', 'Al', 'Si']:
                    label = 'bound-adsorbate-%s' % i.symbol
                elif neigh_sym2 in ['H', 'C', 'N'
                                    ] and neigh_sym1 in ['Sn', 'Al', 'Si']:
                    label = 'bound-adsorbate-%s' % i.symbol
                # assign rest as adsorbate oxygen
                else:
                    label = 'adsorbate-%s' % i.symbol
            # assign rest as adsorbate oxygen
            else:
                label = 'adsorbate-%s' % i.symbol
        # all others get 'none' type
        else:
            label = "None"
        type_dict[label].append(i.index)

    return dict(type_dict)
Exemplo n.º 23
0
 def attach_nl(self, cutoff=None, si=False, bw=True):
     if cutoff is None:
         coff = natural_cutoffs(self[0])
     elif type(cutoff) is float:
         coff = np.full_like(self[0].numbers, cutoff)
     elif type(cutoff) is dict:
         coff = list(map(cutoff.get, self[0].numbers))
     elif type(cutoff) is list:
         coff = cutoff
     self.nl = NeighborList(coff,
                            skin=0.0,
                            self_interaction=si,
                            bothways=bw)
def generate_mask_indices_neightbor_list(supercellPristine, defectIndex, numLayers):
	# this function should be used before the defect was inserted
	# in type 1 and type 3 defect situation, the defect atom was removed, won't be able to calculate neightbor based an vacancy
	
	# generate and update the neightborList
	cutOff = natural_cutoffs(supercellPristine, 1)
	nl = neighborlist.NeighborList(cutOff, 0.3, False, True, True)
	nl.update(supercellPristine)

	# # takes out the symmetric connectivity matrix
	# matrix = nl.get_connectivity_matrix()

	# sets of indices
	totalSet = []
	newSet = []
	newNewSet = []

	totalSet.append(defectIndex)
	newSet.append(defectIndex)

	# print totalSet
	# print newSet
	# print "======="

	# grow starting from the defect, N layers
	for layer in range(numLayers):
		# for idx in newSet:
		# 	indices, offsets = nl.get_neighbors(idx)
		# 	newSet.remove(idx)
		# 	for idxx in indices:
		# 		if idxx not in totalSet:
		# 			totalSet.add(idxx)
		# 			newSet.add(idxx)
		# 		else:
		# 			pass
		while newSet:
			idx = newSet.pop()
			indices, offsets = nl.get_neighbors(idx)
			for idxx in indices:
				if idxx not in totalSet:
					totalSet.append(idxx)
					newNewSet.append(idxx)
				else:
					pass
		newSet = newNewSet
		newNewSet = []

		# print totalSet
		# print newSet
		# print "======="
	return totalSet
Exemplo n.º 25
0
    def get_all_Bronsted_sites(self,
                               case_1Al=False,
                               case_2Al=False,
                               my_dict=None):
        """
        This function samples all Bronsted sites for each T sites names (4 Bronsted sites for each T site).
        No double counting within each sites_name ('T1', 'T2', 'T3', etc), but do have overlaps among different
        site_names.
        """

        if case_1Al is True:
            my_dict = copy.copy(self.dict_1Al_replaced)
        if case_2Al is True:
            my_dict = copy.copy(self.dict_2Al_replaced)

        dict_ZH = {}
        for site_name, all_zeo_with_same_T in my_dict.items():
            if case_2Al is True:
                atoms = copy.copy(all_zeo_with_same_T)
            else:
                atoms = copy.copy(all_zeo_with_same_T[0])

            nl = NeighborList(natural_cutoffs(atoms),
                              bothways=True,
                              self_interaction=False)
            nl.update(atoms)
            index_Al = [a.index for a in atoms if a.symbol == 'Al']
            indices = []
            for each_Al in index_Al:
                indices.append(list(nl.get_neighbors(each_Al)[0]))

            traj = []
            if case_2Al is True:
                assert len(indices) == 2
                all_pairs = []
                for count, value1 in enumerate(indices[0]):
                    all_pairs.extend([value1, value2] for value2 in indices[1])
                assert len(all_pairs) == 16
                for index_pair in all_pairs:
                    new_atoms = copy.copy(atoms)
                    for index in index_pair:
                        new_atoms = self._insert_H(new_atoms, index)
                    traj.append(new_atoms)
            else:
                for count, index in enumerate(indices[0]):
                    new_atoms = self._insert_H(atoms, index)
                    traj.append(new_atoms)

            dict_ZH[site_name] = traj
        return dict_ZH
def generate_site_graphs(atoms, full_graph, nl, sites, adsorbate_atoms=[], radius=3):
    cutoffs = natural_cutoffs(atoms)

    nl = NeighborList(cutoffs, self_interaction=False, bothways=True)
    nl.update(atoms)

    site_envs = [None] * len(sites)
    for index, site in enumerate(sites):
        new_site = process_site(atoms, full_graph, nl, site.cycle, radius=radius)
        site_envs[index] = [new_site]
        site.graph = site_envs[index]

    unique_envs, unique_sites = unique_chem_envs(site_envs, sites)

    return unique_sites
Exemplo n.º 27
0
def checkBonded(clus):
    """
    Check if every atom of the cluster is bonded to other
    """
    cutOff = neighborlist.natural_cutoffs(clus, mult=1)
    neighborList = neighborlist.NeighborList(cutOff,
                                             self_interaction=False,
                                             bothways=True)
    neighborList.update(clus)
    matrix = neighborList.get_connectivity_matrix(sparse=False)
    n_components, component_list = sparse.csgraph.connected_components(matrix)
    if n_components == 1:
        bonded = True
    else:
        bonded = False
    return bonded
Exemplo n.º 28
0
    def _get_bonding(self, struct, natural_cutoff_mult=1, skin=0):
        # Use ASE neighborlist class to identify bonding of atoms
        atoms = struct.get_ase_atoms()
        cutOff = natural_cutoffs(atoms, mult=natural_cutoff_mult)
        neighborList = NeighborList(cutOff,
                                    self_interaction=False,
                                    bothways=True,
                                    skin=0)
        neighborList.update(atoms)

        # Construct bonding list indexed by atom in struct
        bonding_list = [[] for x in range(struct.geometry.shape[0])]
        for i in range(struct.geometry.shape[0]):
            bonding_list[i] = neighborList.get_neighbors(i)[0]

        return np.array(bonding_list)
Exemplo n.º 29
0
    def get_bonds(self, mult=1.20, skin=0.0, update=False):
        """
        Returns array of covalent bonds in the molecule. In addition, these
        are stored in the Structure properties for future reference. 
        
        Arguments
        ---------
        mult: float
            For ASE neighborlist
        skin: float
            For ASE neighborlist
        update: bool
            If True, will force an update of bond information.
            
        Returns
        -------
        list
            The index of the list corresponds to the atom the bonds are 
            describing. Inside each index is another list. This is the indices
            of the atoms the atom is bonded. Please keep in mind that Python
            iterables are zero indexed whereas most visualization softwares
            will label atoms starting with 1. 
        
        """
        if update == False and "bonds" in self.properties:
            pass
        else:
            atoms = self.get_ase_atoms()
            cutOff = natural_cutoffs(atoms, mult=mult)
            neighborList = NeighborList(cutOff,
                                        self_interaction=False,
                                        bothways=True,
                                        skin=skin)
            neighborList.update(atoms)

            # Construct bonding list indexed by atom in struct
            bonding_list = [[] for x in range(self.geometry.shape[0])]
            for i in range(self.geometry.shape[0]):
                temp_list = list(neighborList.get_neighbors(i)[0])
                if len(temp_list) > 0:
                    temp_list.sort()
                bonding_list[i] = [int(x) for x in temp_list]

            self.properties["bonds"] = bonding_list

        return self.properties["bonds"]
Exemplo n.º 30
0
def atoms_to_graph(atoms, index, max_ring):
    '''
    Helper function to repeat a unit cell enough times to capture the largest
    possible ring, and turn the new larger cell into a graph object.

    RETURNS:
    G = graph object representing zeolite framework in new larger cell
    large_atoms = ASE atoms object of the new larger cell framework
    repeat = array showing the number of times the cell was repeated: [x,y,z]
    '''

    # first, repeat cell, center the cell, and wrap the atoms back into the cell
    cell = atoms.get_cell_lengths_and_angles()[:3]
    repeat = []
    for i, c in enumerate(cell):
        if c / 2 < max_ring / 2 + 5:
            l = c
            re = 1
            while l / 2 < max_ring / 2 + 5:
                re += 1
                l = c * re

            repeat.append(re)
        else:
            repeat.append(1)
    large_atoms = atoms.copy()
    large_atoms = large_atoms.repeat(repeat)
    center = large_atoms.get_center_of_mass()
    trans = center - large_atoms.positions[index]
    large_atoms.translate(trans)
    large_atoms.wrap()

    # we need a neighborlist (connectivity matrix) before we can make our graph
    from ase import neighborlist
    cutoff = neighborlist.natural_cutoffs(large_atoms, mult=1.05)
    nl = neighborlist.NeighborList(cutoffs=cutoff,
                                   self_interaction=False,
                                   bothways=True)
    nl.update(large_atoms)
    matrix = nl.get_connectivity_matrix(sparse=False)

    # now we make the graph
    import networkx as nx
    G = nx.from_numpy_matrix(matrix)

    return G, large_atoms, repeat