Esempio n. 1
0
def atoms_moved(cell1, cell2, tol=0.1):
    """Return a list of atoms that have moved between the two cells.

    If lattices are compatible, take periodic boundary conditions into account.
    
    Arguments:
    cell1,2 -- The supercells to compare
    tol -- The tolerance in Å

    Return value -- A list of (atom index, distance moved) tuples.

    """
    (latt, nat) = check_cells(cell1, cell2)
    if latt:
        at1 = cell1.get_scaled_positions()
        at2 = cell2.get_scaled_positions()
    else:
        at1 = cell1.positions
        at2 = cell2.positions
    nmax = min(natoms(cell1), natoms(cell2))
    am = []
    for nn in range(nmax):
        dvec = at1[nn, :] - at2[nn, :]
        if latt:
            dvec = np.dot(vg.vec_pbc(dvec), cell1.get_cell())
        dist = np.linalg.norm(dvec)
        if dist > tol:
            am.append((nn, dist, dvec))
    return am
Esempio n. 2
0
def nearest_neighbors(atoms, tol=1.0, num_neigh=None):
    """Nearest neighbors and distances.

    Arguments:
    atoms -- The ASE Atoms object with all the atoms.
    tol  -- Return only distances smaller than this. Default 1.0 Å.
    num_neigh -- Number of nearest neighbors per atom returned.

    Returns -- List containing 
               (source_atom, target_atom, dist) tuples. 

    """
    at = atoms.get_scaled_positions()
    nn = []
    for anum in range(len(at)):
        dvec = at - at[anum]
        dvec = np.dot(vg.vec_pbc(dvec), \
                atoms.get_cell())
        dist = np.empty(dvec.shape[0])
        for ii in range(len(dvec)):
            dist[ii] = np.linalg.norm(dvec[ii])
        if num_neigh == None:
            mask = dist < tol
            for ii in range(len(mask)):
                if mask[ii] and ii != anum:
                    nn.append((anum, ii, dist[ii]))
        else:
            sind = dist.argsort()
            for ii in range(min(num_neigh + 1, len(dist))):
                if anum != sind[ii]:
                    nn.append((anum, sind[ii], dist[sind[ii]]))
    return nn
Esempio n. 3
0
def atoms_moved(cell1, cell2, tol=0.1):
    """Return a list of atoms that have moved between the two cells.

    If lattices are compatible, take periodic boundary conditions into account.

    Arguments:
    cell1,2 -- The supercells to compare
    tol -- The tolerance in Å

    Return value -- A list of (atom index, distance moved) tuples.

    """
    (latt, nat) = check_cells(cell1, cell2)
    if latt:
        at1 = cell1.get_scaled_positions()
        at2 = cell2.get_scaled_positions()
    else:
        at1 = cell1.positions
        at2 = cell2.positions
    nmax = min(natoms(cell1), natoms(cell2))
    am = []
    for nn in range(nmax):
        dvec = at1[nn, :] - at2[nn, :]
        if latt:
            dvec = np.dot(vg.vec_pbc(dvec), cell1.get_cell())
        dist = np.linalg.norm(dvec)
        if dist > tol:
            am.append((nn, dist, dvec))
    return am
Esempio n. 4
0
def nearest_neighbors(atoms, tol=1.0, num_neigh=None):
    """Nearest neighbors and distances.

    Arguments:
    atoms -- The ASE Atoms object with all the atoms.
    tol  -- Return only distances smaller than this. Default 1.0 Å.
    num_neigh -- Number of nearest neighbors per atom returned.

    Returns -- List containing 
               (source_atom, target_atom, dist) tuples. 

    """
    at = atoms.get_scaled_positions()
    nn = []
    for anum in range(len(at)):
        dvec = at - at[anum]
        dvec = np.dot(vg.vec_pbc(dvec), \
                atoms.get_cell())
        dist = np.empty(dvec.shape[0])
        for ii in range(len(dvec)):
            dist[ii] = np.linalg.norm(dvec[ii])
        if num_neigh == None:
            mask = dist < tol
            for ii in range(len(mask)):
                if mask[ii] and ii != anum:
                    nn.append((anum, ii, dist[ii]))
        else:
            sind = dist.argsort()
            for ii in range(min(num_neigh + 1, len(dist))):
                if anum != sind[ii]:
                    nn.append((anum, sind[ii], dist[sind[ii]]))
    return nn
Esempio n. 5
0
def atoms_distance(atoms, atom1, atom2, proj=None):
    """Measure the distance between two atoms.
    
    Atoms are indexed starting from 0, following the usual Python
    convention.  Note that this is different from VASP itself, which starts
    indexing from 1.  This method takes into account periodic boundary
    conditions.

    Arguments:
    atoms -- ASE Atoms object containing the atoms.
    atom1 -- The index of one of the atoms, starting from 0.
    atom2 -- The index of the other atom, starting from 0.
    proj  -- Projection along a vector or plane. If a string, it can
             contain x, y, z and the method then measures the distance
             in the plane defined by the string. If it's a sequence
             of three numbers, the method measures the distance
             projected along the vector.
    
    """
    at = atoms.get_scaled_positions()
    dvec = at[atom1, :] - at[atom2, :]
    dvec = np.dot(vg.vec_pbc(dvec), \
            atoms.get_cell())
    if proj == None:
        return np.linalg.norm(dvec)
    elif type(proj) == str:
        if len(proj) != 2:
            raise TypeError("Length of string specifying plane must be 2.")
        pvec = dvec.copy()
        if proj.find("x") == -1:
            pvec[0] = 0.
        if proj.find("y") == -1:
            pvec[1] = 0.
        if proj.find("z") == -1:
            pvec[2] = 0.
        return abs(np.dot(dvec, pvec) / np.linalg.norm(pvec))
    else:
        return abs(np.dot(dvec, proj) / np.linalg.norm(proj))
Esempio n. 6
0
def atoms_distance(atoms, atom1, atom2, proj=None):
    """Measure the distance between two atoms.

    Atoms are indexed starting from 0, following the usual Python
    convention.  Note that this is different from VASP itself, which starts
    indexing from 1.  This method takes into account periodic boundary
    conditions.

    Arguments:
    atoms -- ASE Atoms object containing the atoms.
    atom1 -- The index of one of the atoms, starting from 0.
    atom2 -- The index of the other atom, starting from 0.
    proj  -- Projection along a vector or plane. If a string, it can
             contain x, y, z and the method then measures the distance
             in the plane defined by the string. If it's a sequence
             of three numbers, the method measures the distance
             projected along the vector.

    """
    at = atoms.get_scaled_positions()
    dvec = at[atom1, :] - at[atom2, :]
    dvec = np.dot(vg.vec_pbc(dvec), \
            atoms.get_cell())
    if proj == None:
        return np.linalg.norm(dvec)
    elif type(proj) == str:
        if len(proj) != 2:
            raise TypeError("Length of string specifying plane must be 2.")
        pvec = dvec.copy()
        if proj.find("x") == -1:
            pvec[0] = 0.
        if proj.find("y") == -1:
            pvec[1] = 0.
        if proj.find("z") == -1:
            pvec[2] = 0.
        return abs(np.dot(dvec, pvec) / np.linalg.norm(pvec))
    else:
        return abs(np.dot(dvec, proj) / np.linalg.norm(proj))