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
예제 #2
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
예제 #3
0
def buildNL(mol, path='./', radii=None, save=True):
    #create nl
    if radii is None:
        radii = {}
        radii['H'] = 0.30
        radii['C'] = 0.77
        radii['N'] = 0.70
        radii['O'] = 0.66
        radii['Ni'] = 1.24
    nAtoms = len(mol)

    if (not os.path.isfile(os.path.join(path,
                                        'neighborList.pickle'))) or (not save):
        #create a list of cutoffs
        cutOff = []
        for j in range(0, nAtoms):
            cutOff.append(radii[mol[j].symbol])
        #initiate neighborlist
        neighborList = neighborlist.NeighborList(cutOff,
                                                 self_interaction=False,
                                                 bothways=True)
        neighborList.update(mol)
        if save:
            with open(os.path.join(path, 'neighborList.pickle'), 'wb') as f:
                pickle.dump(neighborList, f)
    elif save:
        with open(os.path.join(path, 'neighborList.pickle'), 'rb') as f:
            neighborList = pickle.load(f)
    print("Bond Map created")
    return neighborList
예제 #4
0
    def get_bonds(self, atoms):
        atoms = atoms.copy()
        nl = neighborlist.NeighborList(
            ase.neighborlist.natural_cutoffs(atoms),
            self_interaction=False,
            bothways=True,
        )
        nl.update(atoms)
        connectivity_matrix = nl.get_connectivity_matrix(sparse=False)

        con_tuples = {}  # connected first neighbors
        for row in range(connectivity_matrix.shape[0]):
            con_tuples[row] = []
            for col in range(connectivity_matrix.shape[1]):
                if connectivity_matrix[row, col] == 1:
                    con_tuples[row].append(col)

        pairs = []  # cleaning up the first neighbors
        for index in con_tuples.keys():
            for value in con_tuples[index]:
                if index > value:
                    pairs.append((index, value))
                elif index <= value:
                    pairs.append((value, index))
        pairs = set(pairs)
        return pairs
예제 #5
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
예제 #6
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
예제 #7
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
예제 #8
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
예제 #9
0
def get_neighbor_idx(m_at,latt,n_order,max_radii=3.):
    """
    get the indexes neighbors of order n_order
    0 is first order
    """
    n_at=latt.get_number_of_atoms()
    num_n=nl.NeighborList(np.ones(n_at)*max_radii,self_interaction=False,bothways=True)
    num_n.update(latt)
    idxs,vec=num_n.get_neighbors(m_at)
    dist_lst=latt.get_distances(m_at,idxs).round(4)
    distances=np.unique(dist_lst)
    nnidxs=idxs[np.where(dist_lst==distances[n_order])[0]]
    return nnidxs
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
예제 #11
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
예제 #12
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
예제 #13
0
def get_connectivity(adsorbate):
    """
    Generate the connectivity of an adsorbate atoms obj.

    Args:
        adsorbate  An `ase.Atoms` object of the adsorbate

    Returns:
        matrix     The connectivity matrix of the adsorbate.
    """
    cutoff = natural_cutoffs(adsorbate)
    neighborList = neighborlist.NeighborList(cutoff,
                                             self_interaction=False,
                                             bothways=True)
    neighborList.update(adsorbate)
    matrix = neighborlist.get_connectivity_matrix(neighborList.nl).toarray()
    return matrix
예제 #14
0
def create_connectivity_matrix(atoms, bothways):
    """Summary

    Args:
        atoms (TYPE): Description
        bothways (TYPE): Description

    Returns:
        TYPE: Description
    """
    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
예제 #15
0
def neighbor_list_and_relative_vec(pos, r_max, self_interaction=True):
    """
    Create neighbor list (edge_index) and relative vectors (edge_attr)
    based on radial cutoff.

    :param pos: torch.tensor of coordinates with shape (N, 3)
    :param r_max: float of radial cutoff
    :param self_interaction: whether or not to include self edge

    :return: list of edges [(2, num_edges)], Tensor of relative vectors [num_edges, 3]

    edges are given by the convention
    edge_list[0] = source (convolution center)
    edge_list[1] = target (neighbor)

    Thus, the edge_list has the same convention vector notation for relative vectors
    \vec{r}_{source, target}
    """
    N, _ = pos.shape
    atoms = Atoms(symbols=['H'] * N, positions=pos)
    nl = neighborlist.NeighborList(
        [r_max / 2.] * N,  # NeighborList looks for intersecting spheres
        self_interaction=self_interaction,
        bothways=True,
        skin=0.0,
    )
    nl.update(atoms)

    nei_list = []
    geo_list = []

    for i, p in enumerate(pos):
        indices = nl.get_neighbors(i)[0]
        if self_interaction:
            indices = indices[:-1]  # Remove extra self edge
        cart = pos[indices]
        indices = torch.LongTensor([[i, target] for target in indices])
        dist = cart - p
        nei_list.append(indices)
        geo_list.append(dist)
    return torch.cat(nei_list, dim=0).transpose(1, 0), torch.cat(geo_list,
                                                                 dim=0)
def get_nuclearity_from_atoms(atoms, structure, actives):
    #Get surface nuclearity from given Atoms object
    slab_atoms = atoms.copy()
    #pick surface atoms
    bulk_atoms = AseAtomsAdaptor.get_atoms(structure)
    bulk_cn = find_bulk_cn_dict(bulk_atoms)
    surface_indices = find_surface_atoms_indices(bulk_cn, slab_atoms)

    #Generate connectivity matrix
    cutOff = natural_cutoffs(slab_atoms)
    neighborList = neighborlist.NeighborList(cutOff,
                                             self_interaction=False,
                                             bothways=True)
    neighborList.update(slab_atoms)
    connectivity_matrix = neighborList.get_connectivity_matrix()

    #Ignore connectivity with atoms which are not active or on the surface
    active_connectivity_matrix = connectivity_matrix.copy()
    active_list = [
        atom.symbol in actives and atom.index in surface_indices
        for atom in slab_atoms
    ]

    if sum(active_list) == 0:
        # No active surface atoms!
        return {'max_nuclearity': 0, 'nuclearities': []}

    else:
        active_connectivity_matrix = active_connectivity_matrix[active_list, :]
        active_connectivity_matrix = active_connectivity_matrix[:, active_list]

        # Make a graph-tool graph from the adjacency matrix
        graph = gt.Graph(directed=False)

        for i in range(active_connectivity_matrix.shape[0]):
            graph.add_vertex()

        graph.add_edge_list(np.transpose(active_connectivity_matrix.nonzero()))

        labels, hist = topology.label_components(graph, directed=False)

        return {'max_nuclearity': np.max(hist), 'nuclearities': hist}
예제 #17
0
def get_rings(atoms, index, possible_rings):
    # first we need the connectivity matrix
    # atoms: ase Atoms object of a zeolite structure
    # index: (integer) index of the oxygen atom that you want to classify
    # possible_rings: (array) what size rings are possible in this zeolite framework?
    # Check IZA if you don't know. Example: CHA has 8-,6-,4-MR i.e. [8,6,4]

    cell = atoms.get_cell_lengths_and_angles()
    repeat = []
    for i, c in enumerate(cell):
        if c / 2 < 8:
            repeat.append(2)
        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)
    nl = neighborlist.NeighborList(cutoffs=cutoff,
                                   self_interaction=False,
                                   bothways=True)
    nl.update(atoms)
    matrix = nl.get_connectivity_matrix(sparse=False)
    m = matrix.copy()

    Class = []
    pr = possible_rings
    pr.sort()
    for i in pr:
        ring, m = zeoc(m, index, i * 2 + 1)
        if ring:
            for r in ring:
                temp = r
                Class.append(int((len(temp) - 1) / 2))
    Class.sort(reverse=True)
    return Class
def FromXYZtoGraph(input_file):
    atoms = ['H', 'He', 'Li', 'C', 'N', 'O', 'F', 'Na', 'Si', 'P', 'S', 'Cl']
    atomic_numb = [1, 2, 3, 6, 7, 8, 9, 11, 14, 15, 16, 17]
    mol = io.read(input_file)
    #compute neighbor of the atoms in xyz format
    cutOff = neighborlist.natural_cutoffs(mol)
    neighborList = neighborlist.NeighborList(cutOff,
                                             self_interaction=False,
                                             bothways=True)
    neighborList.update(mol)
    #compure adjacency matrix and atoms list
    adj_matrix = neighborList.get_connectivity_matrix(sparse=False)
    Natom_list = mol.get_atomic_numbers()
    atoms_list = []
    for i, item in enumerate(Natom_list):
        for k in range(len(atomic_numb)):
            if item == atomic_numb[k]:
                atoms_list.append(atoms[k])
    #convert in networkx-molecules graph
    G = nx.from_numpy_matrix(adj_matrix)
    for i, item in enumerate(atoms_list):
        tmp_attr = {'atom': item}
        G.nodes[i].update(tmp_attr.copy())
    return (G)
예제 #19
0
    def pruneoverlap(self, criteria=0.5, verbose=False):
        ''' TODO: remove atoms overlapping assume PBC conditions'''
        print(
            "NOTICE: The pruning routine does not accoutn for stoichiometry restrictions."
        )

        cutoff = neighborlist.natural_cutoffs(self.polycrystal)
        neighbors = neighborlist.NeighborList(cutoff,
                                              self_interaction=False,
                                              bothways=False)
        neighbors.update(self.polycrystal)

        isremoved = []
        for a in self.polycrystal:
            ineigh = neighbors.get_neighbors(a.index)
            for j in ineigh[0]:
                r = self.polycrystal.get_distance(a.index, j, mic=True)
                if r < criteria and j not in isremoved:
                    isremoved.append(j)
                    if verbose:
                        print("Atom ID %i removed due to overlap!" % (j))

        del self.polycrystal[isremoved]
        self.natoms = self.polycrystal.get_global_number_of_atoms()
예제 #20
0
def lorb2fod(mf, lo_coeff, s=0, grid_level=7):
    """
    lo_coeff[:] localized orbital
    """
    from scipy import optimize
    # get estimate for FOD'position
    # by using the COM of the orbital density
    mol = mf.mol
    ao1 = numint.eval_ao(mol, mf.grids.coords)
    phi = ao1.dot(lo_coeff)
    #print(phi.shape)

    #print('lorb2fod: s={}'.format(s))
    #print('lorb2fod: lo_coeff={}'.format(lo_coeff.sum()))

    #print(np.sum(phi**2*mf.grids.weights))
    dens = np.conjugate(phi) * phi * mf.grids.weights
    # COM
    x = np.sum(dens * mf.grids.coords[:, 0])
    y = np.sum(dens * mf.grids.coords[:, 1])
    z = np.sum(dens * mf.grids.coords[:, 2])
    #print x

    print("  -> COM: {0:7.5f} {1:7.5f} {2:7.5f}".format(
        x * units.Bohr, y * units.Bohr, z * units.Bohr))
    ig_fod = np.array([x, y, z])

    #if s==1:
    #    sys.exit()

    ## build a new, smaller mesh for the density fitting
    # find nearest atom
    dists = np.linalg.norm((mol.atom_coords() - ig_fod), axis=1)
    didx = np.argsort(dists)
    #print dists
    #print didx
    nidx = -1
    for i in range(mol.natm):
        if mol.atom_pure_symbol(i) == 'H': continue
        nidx = didx[i]
        break

    if nidx == -1:
        print("ERROR")
        sys.exit()

    #print nidx, mol.atom_pure_symbol(nidx)

    # build atom object (make sure to enter ccors in Angst)
    acoord = mol.atom_coords()
    atoms = Atoms()
    for na in range(mol.natm):
        aa = Atom(symbol=mol.atom_symbol(na), position=acoord[na] * units.Bohr)
        atoms.extend(aa)

    cutoffs = natural_cutoffs(atoms)

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

    # generate a per-atom grid (include neigbours)
    neiatm = nl.get_neighbors(nidx)[0]
    mstr = ''
    for na in neiatm:
        sym = mol.atom_pure_symbol(na)
        pos = mol.atom_coord(na) * units.Bohr  # in Angst
        #print sym, pos
        mstr += "{0} {1:0.12f} {2:0.12f} {3:0.12f};".format(
            sym, pos[0], pos[1], pos[2])

    # also add the nearest Atom to the grid algorithm
    sym = mol.atom_pure_symbol(nidx)
    pos = mol.atom_coord(nidx) * units.Bohr  # in Angst
    #print sym, pos
    mstr += "{0} {1:0.12f} {2:0.12f} {3:0.12f};".format(
        sym, pos[0], pos[1], pos[2])

    #print ">>>"
    #print mstr

    # build a Mole object from subsystem
    b = mol.basis
    try:
        onmol = gto.M(atom=mstr, basis=b, verbose=0)
    except RuntimeError:
        onmol = gto.M(atom=mstr, basis=b, spin=1, verbose=0)

    _mdft = dft.UKS(onmol)
    _mdft.max_cycle = 0
    _mdft.grids.level = grid_level
    _mdft.kernel()
    ongrid = copy.copy(_mdft.grids)

    #print("Original grid size: {0}".format(mf.grids.coords.shape[0]))
    #print("  building FO, grid size: {0}"
    #    .format(ongrid.coords.shape[0]))

    ## re-calculate lo density on O(N) grid
    ao1 = numint.eval_ao(mol, ongrid.coords)
    phi = ao1.dot(lo_coeff)
    dens = np.conjugate(phi) * phi * ongrid.weights

    #sys.exit()

    # now build the corresponding fermi orbital
    #lfo = fo(mf, ig_fod, s)

    def densdiff(x0):
        #print ig_fod
        #print(s)
        _x = np.reshape(x0, (-1, 3))
        lfo = fo(mf, _x, s)

        mol = mf.mol
        ao1 = numint.eval_ao(mol, ongrid.coords)
        _fo = ao1.dot(lfo)

        dens_fo = np.conjugate(_fo) * _fo * ongrid.weights

        ##print dens_fo.shape
        ##print dens.shape

        diff = np.linalg.norm(dens_fo - dens)

        return diff

    options = {
        'disp': False,
        'eps': 1e-05,
        'gtol': 1e-05,
        'maxiter': 299,
    }

    db = 1.5
    if np.linalg.norm(mol.atom_coord(nidx) - ig_fod) < 0.5:
        db = 0.75

    bounds = [(x - db, x + db), (y - db, y + db), (z - db, z + db)]

    res = optimize.minimize(densdiff,
                            ig_fod.flatten(),
                            method='L-BFGS-B',
                            options=options,
                            bounds=bounds)

    #print ">> done <<"
    #print res.x
    #print ig_fod
    #print ">> initial FOD moved by: {0:0.4f} [B]".format(np.linalg.norm(res.x-ig_fod))
    #print ">> density fit quality : {0:0.4f}".format(res.fun)
    print("  -> a_i: {0:7.5f} {1:7.5f} {2:7.5f}"\
      .format(res.x[0]*units.Bohr,res.x[1]*units.Bohr,res.x[2]*units.Bohr))

    return res.x
예제 #21
0
def tring_driver(atoms, index, possible, delete=True):
    '''
    atoms: ASE atoms object of the zeolite framework to be analyzed
    index: (integer) index of the atom that you want to classify
    possible: (list) of the types of rings known to be present in the zeolite
              framework you are studying. This information is available on IZA
              or in the collections module of this package.
    Returns: Class - The size of the rings associated with the desire T Site.
             Rings - The actual atom indices that compose those rings.
             atoms2 - An atoms object with the desired T Site changed to an
             Aluminum atom (just for visual purposes), and all atoms removed
             except for those that share a ring with the T Site provided.
    '''
    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_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
예제 #22
0
def find_fragments(atoms, scale=1.0) -> list:
    """Finds unconnected structural fragments by constructing
    the first-neighbor topology matrix and the resulting graph
    of connected vertices.

    Args:
        atoms: :class:`~ase.atoms.Atoms` or :class:`~aimstools.structuretools.structure.Structure`.
        scale: Scaling factor for covalent radii.

    Note:
        Requires networkx library.

    Returns:
        list: NamedTuple with indices and atoms object.

    """

    atoms = atoms.copy()
    radii = scale * covalent_radii[atoms.get_atomic_numbers()]
    nl = neighborlist.NeighborList(radii, skin=0, self_interaction=False, bothways=True)
    nl.update(atoms)
    connectivity_matrix = nl.get_connectivity_matrix(sparse=False)

    con_tuples = {}  # connected first neighbors
    for row in range(connectivity_matrix.shape[0]):
        con_tuples[row] = []
        for col in range(connectivity_matrix.shape[1]):
            if connectivity_matrix[row, col] == 1:
                con_tuples[row].append(col)

    pairs = []  # cleaning up the first neighbors
    for index in con_tuples.keys():
        for value in con_tuples[index]:
            if index > value:
                pairs.append((index, value))
            elif index <= value:
                pairs.append((value, index))
    pairs = set(pairs)

    graph = nx.from_edgelist(pairs)  # converting to a graph
    con_tuples = list(
        nx.connected_components(graph)
    )  # graph theory can be pretty handy

    fragments = {}
    i = 0
    for tup in con_tuples:
        fragment = namedtuple("fragment", ["indices", "atoms"])
        ats = ase.Atoms()
        indices = []
        for entry in tup:
            ats.append(atoms[entry])
            indices.append(entry)
        ats.cell = atoms.cell
        ats.pbc = atoms.pbc
        fragments[i] = fragment(indices, ats)
        i += 1
    fragments = [
        v
        for k, v in sorted(
            fragments.items(),
            key=lambda item: np.average(item[1][1].get_positions()[:, 2]),
        )
    ]
    return fragments
예제 #23
0
def get_orings(atoms, index, possible):
    '''
    atoms: ASE atoms object of the zeolite framework to be analyzed
    index: (integer) index of the atom that you want to classify
    possible: (list) of the types of rings known to be present in the zeolite
              framework you are studying. This information is available on IZA
              or in the collections module of this package.
    Returns: Class - The size of rings associated with the oxygen.
             paths - The actual atom indices that compose those rings.
    '''

    cell = atoms.get_cell_lengths_and_angles()[:3]
    repeat = []
    possible = possible * 2
    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 = atoms.copy()
    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=1.05)
    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)

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

    G.remove_edge(fe[0], fe[1])
    tmpClass = []
    rings = []
    while len(tmpClass) < 6:
        try:
            path = nx.shortest_path(G, fe[0], fe[1])
        except:
            break
        length = len(path)
        if length in possible:
            tmpClass.append(int(len(path) / 2))
            rings.append(path)
            if length == 18:
                G.remove_edge(path[8], path[9])
            elif length < 16 and length > 6:
                G.remove_edge(path[3], path[4])
            elif length >= 16:
                G.remove_edge(path[int(len(path) / 2 - 1)],
                              path[int(len(path) / 2)])
            if length == 8:
                G.remove_node(path[4])
            if length == 6:
                G.remove_node(path[3])
        else:
            G.remove_edge(path[int(length / 2)], path[int(length / 2 + 1)])

    rings = remove_dups(rings)
    rings = remove_sec(rings)
    Class = []
    for r in rings:
        Class.append(int(len(r) / 2))
    paths = rings
    paths = [x for _, x in sorted(zip(Class, paths), reverse=True)]
    Class.sort(reverse=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]
    del atoms2[d]

    return Class, paths, atoms2
예제 #24
0
    def _render_structure(self, change=None):
        """Render the structure with POVRAY."""

        if not isinstance(self.structure, Atoms):
            return

        self.render_btn.disabled = True
        omat = np.array(self._viewer._camera_orientation).reshape(
            4, 4).transpose()

        zfactor = norm(omat[0, 0:3])
        omat[0:3, 0:3] = omat[0:3, 0:3] / zfactor

        bb = deepcopy(self.structure)
        bb.pbc = (False, False, False)

        for i in bb:
            ixyz = omat[0:3, 0:3].dot(np.array([i.x, i.y, i.z]) + omat[0:3, 3])
            i.x, i.y, i.z = -ixyz[0], ixyz[1], ixyz[2]

        vertices = []

        cell = bb.get_cell()
        vertices.append(np.array([0, 0, 0]))
        vertices.extend(cell)
        vertices.extend([
            cell[0] + cell[1],
            cell[0] + cell[2],
            cell[1] + cell[2],
            cell[0] + cell[1] + cell[2],
        ])

        for n, i in enumerate(vertices):
            ixyz = omat[0:3, 0:3].dot(i + omat[0:3, 3])
            vertices[n] = np.array([-ixyz[0], ixyz[1], ixyz[2]])

        bonds = []

        cutOff = neighborlist.natural_cutoffs(
            bb)  # Takes the cutoffs from the ASE database
        neighborList = neighborlist.NeighborList(cutOff,
                                                 self_interaction=False,
                                                 bothways=False)
        neighborList.update(bb)
        matrix = neighborList.get_connectivity_matrix()

        for k in matrix.keys():
            i = bb[k[0]]
            j = bb[k[1]]

            v1 = np.array([i.x, i.y, i.z])
            v2 = np.array([j.x, j.y, j.z])
            midi = v1 + (v2 - v1) * Radius[i.symbol] / (Radius[i.symbol] +
                                                        Radius[j.symbol])
            bond = Cylinder(
                v1,
                midi,
                0.2,
                Pigment("color", np.array(Colors[i.symbol])),
                Finish("phong", 0.8, "reflection", 0.05),
            )
            bonds.append(bond)
            bond = Cylinder(
                v2,
                midi,
                0.2,
                Pigment("color", np.array(Colors[j.symbol])),
                Finish("phong", 0.8, "reflection", 0.05),
            )
            bonds.append(bond)

        edges = []
        for x, i in enumerate(vertices):
            for j in vertices[x + 1:]:
                if (norm(np.cross(i - j, vertices[1] - vertices[0])) < 0.001
                        or norm(np.cross(i - j,
                                         vertices[2] - vertices[0])) < 0.001
                        or norm(np.cross(i - j,
                                         vertices[3] - vertices[0])) < 0.001):
                    edge = Cylinder(
                        i,
                        j,
                        0.06,
                        Texture(
                            Pigment("color",
                                    [212 / 255.0, 175 / 255.0, 55 / 255.0])),
                        Finish("phong", 0.9, "reflection", 0.01),
                    )
                    edges.append(edge)

        camera = Camera(
            "perspective",
            "location",
            [0, 0, -zfactor / 1.5],
            "look_at",
            [0.0, 0.0, 0.0],
        )
        light = LightSource([0, 0, -100.0], "color", [1.5, 1.5, 1.5])

        spheres = [
            Sphere(
                [i.x, i.y, i.z],
                Radius[i.symbol],
                Texture(Pigment("color", np.array(Colors[i.symbol]))),
                Finish("phong", 0.9, "reflection", 0.05),
            ) for i in bb
        ]

        objects = (
            [light] + spheres + edges + bonds +
            [Background("color", np.array(to_rgb(self._viewer.background)))])

        scene = Scene(camera, objects=objects)
        fname = bb.get_chemical_formula() + ".png"
        scene.render(
            fname,
            width=2560,
            height=1440,
            antialiasing=0.000,
            quality=11,
            remove_temp=False,
        )
        with open(fname, "rb") as raw:
            payload = base64.b64encode(raw.read()).decode()
        self._download(payload=payload, filename=fname)
        self.render_btn.disabled = False
예제 #25
0
N_indices = np.flatnonzero(symbols == 'N')
C_indices = np.flatnonzero(symbols == 'C')
H_indices = np.flatnonzero(symbols == 'H')

organic_indices = np.concatenate((N_indices, C_indices, H_indices))

organic = frame[organic_indices]

inorganic_indices = np.concatenate((Pb_indices, Br_indices))

inorganic = frame[inorganic_indices]

##### Find positions of nitrogens/carbons in the frame

cutOff = neighborlist.natural_cutoffs(organic)
neighborList = neighborlist.NeighborList(cutOff, self_interaction=False, bothways=True)
neighborList.update(organic)

matrix = neighborList.get_connectivity_matrix()

n_components, component_list = sparse.csgraph.connected_components(matrix)

MA=np.empty((0), dtype='int')
MA_counter = 0

Long=np.empty((0), dtype='int')
Long_counter = 0

for i in range(n_components):
    molIdx=i
    molIdxs = [ j for j in range(len(component_list)) if component_list[j] == molIdx ]
예제 #26
0
파일: rings_old.py 프로젝트: cwaitt/zse
def get_orings_new(atoms, index, possible):
    cell = atoms.get_cell_lengths_and_angles()[:3]
    repeat = []
    possible = possible * 2
    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 = atoms.copy()
    atoms2 = atoms2.repeat(repeat)
    center = atoms2.get_center_of_mass()
    trans = center - atoms2.positions[index]
    atoms2.translate(trans)
    atoms2.wrap()
    atoms3 = atoms2.copy()
    cutoff = neighborlist.natural_cutoffs(atoms2, mult=1.05)
    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)

    neighbs = nx.neighbors(G, index)
    fe = []
    for n in neighbs:
        if atoms2[n].symbol != 'O':
            fe.append(n)
    fe.append(index)
    rings = []
    for path in nx.all_simple_paths(G, index, fe[0], cutoff=max(possible) - 1):
        rings.append(path)
    new_rings = []
    for r in rings:
        if len(r) in possible:
            new_rings.append(r)
    rings = new_rings

    delete = []
    for j, r in enumerate(rings):
        flag = False
        if len(r) >= 12:
            for i in range(1, len(r) - 3, 2):
                angle = atoms3.get_angle(r[i], r[i + 2], r[i + 4], mic=True)
                if angle < 100:
                    delete.append(j)
                    break
    new_rings = []
    for j, r in enumerate(rings):
        if j not in delete:
            new_rings.append(r)
    rings = new_rings

    rings = remove_sec(rings)
    rings = remove_dups(rings)
    Class = []
    for r in rings:
        Class.append(int(len(r) / 2))
    paths = rings
    paths = [x for _, x in sorted(zip(Class, paths), reverse=True)]
    Class.sort(reverse=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]
    del atoms2[d]

    return Class, paths, atoms2
예제 #27
0
파일: rings_old.py 프로젝트: cwaitt/zse
def test_orings(atoms, index, possible):
    cell = atoms.get_cell_lengths_and_angles()[:3]
    repeat = []
    possible = possible * 2
    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 = atoms.copy()
    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=1.05)
    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)

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

    tmpClass = []
    rings = []
    G2 = G.copy()
    G2.remove_edge(fe[0], fe[2])
    pr = sorted(possible)
    rings = []

    for q in pr:
        tmprings = []
        paths = nx.all_simple_paths(G2, fe[0], fe[2], cutoff=q - 1)
        for p in paths:
            tmprings.append(p)
        for r in tmprings:
            length = len(r)
            if length in possible:
                if ((len(r) / 2) % 2) == 0:
                    try:
                        G2.remove_node(r[int(length / 2 - 1)])
                    except:
                        2 + 2
                elif ((len(r) / 2) % 2) != 0:
                    try:
                        G2.remove_node(r[int(length / 2)])
                    except:
                        2 + 2

                rings.append(r)
    rings = remove_dups(rings)
    rings = remove_sec(rings)
    Class = []
    for r in rings:
        Class.append(int(len(r) / 2))
    paths = rings
    paths = [x for _, x in sorted(zip(Class, paths), reverse=True)]
    Class.sort(reverse=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]
    del atoms2[d]

    return Class, paths, atoms2