Beispiel #1
0
def lindemann_index(trajectory_dir="./"):
    """
    Calculates the Lindemann index
    \delta = \frac{2}{N(N-1)} \sum_{i<j} \frac{\sqrt{\langle r_{ij}^2\rangle_t - \langle r_{ij} \rangle^2_t }}{ \langle r_{ij} \rangle_t }
    """

    # Import vasprun.xml:
    traj = read_trajectory(dir=trajectory_dir, unwrap_pbcs=False)
    pos = traj.get_all_trajectories(coords="direct")

    nsteps = pos.shape[0]
    natoms = pos.shape[1]

    # Get all atom pairs:
    pairs = get_pairs(natoms)
    npairs = pairs.shape[0]

    print "%d steps, %d atoms, %d pairs" % (nsteps, natoms, npairs)

    stepsize = 50
    samplesteps = np.arange(0, nsteps, stepsize)
    r = np.zeros((samplesteps.size, npairs))  # increase stepsize if we run out of memory
    r2 = np.zeros((samplesteps.size, npairs))  # increase stepsize if we run out of memory
    print "Allocated %.3f MB" % ((r.nbytes + r2.nbytes) / (1024.0 ** 2))

    pbar = ProgressBar(widgets=["At step...", SimpleProgress()], maxval=samplesteps.size).start()
    for idx, s in enumerate(samplesteps):
        pbar.update(idx)
        x = pos[s, pairs[:, 0]] - pos[s, pairs[:, 1]]
        x = x - (2 * x).astype("int")  # minimum image convention
        r2[idx] = lensq(x)
        r[idx] = np.sqrt(r2[idx])
    pbar.finish()

    meanr2 = np.mean(r2, axis=0)
    meanr = np.mean(r, axis=0)

    return np.sum(np.sqrt((meanr2 - meanr ** 2)) / meanr) * 2 / (npairs * 2)
Beispiel #2
0
def lindemann_index(trajectory_dir='./'):
    """
    Calculates the Lindemann index
    \delta = \frac{2}{N(N-1)} \sum_{i<j} \frac{\sqrt{\langle r_{ij}^2\rangle_t - \langle r_{ij} \rangle^2_t }}{ \langle r_{ij} \rangle_t }
    """
    
    # Import vasprun.xml:
    traj = read_trajectory( dir = trajectory_dir, unwrap_pbcs = False )
    pos = traj.get_all_trajectories( coords = 'direct' )
    
    nsteps = pos.shape[0]
    natoms = pos.shape[1]

    # Get all atom pairs:
    pairs = get_pairs(natoms)
    npairs = pairs.shape[0]

    print "%d steps, %d atoms, %d pairs" % (nsteps, natoms, npairs)

    stepsize = 50
    samplesteps = np.arange(0,nsteps,stepsize)
    r = np.zeros((samplesteps.size, npairs)) # increase stepsize if we run out of memory
    r2 = np.zeros((samplesteps.size, npairs)) # increase stepsize if we run out of memory
    print "Allocated %.3f MB" % ((r.nbytes+r2.nbytes)/(1024.**2))

    pbar = ProgressBar(widgets=['At step...',SimpleProgress()], maxval = samplesteps.size).start()
    for idx,s in enumerate(samplesteps):
        pbar.update(idx)
        x = pos[s,pairs[:,0]] - pos[s,pairs[:,1]]
        x = x - (2*x).astype('int')  # minimum image convention
        r2[idx] = lensq(x)
        r[idx] = np.sqrt(r2[idx])
    pbar.finish()

    meanr2 = np.mean(r2,axis=0)
    meanr = np.mean(r,axis=0)

    return np.sum(np.sqrt((meanr2 - meanr**2))/meanr)*2/(npairs*2)
Beispiel #3
0
parser.add_argument('--abs_diff', '-a', action='store_true',
        help='Print abs(displacements) for all atoms' )
parser.add_argument('--rad_diff', '-r', action='store_true',
        help='Print radial displacements (displacement vector norms) for all atoms' )
parser.add_argument('--no_unwrap', '-n', action='store_true',
        help='Don\'t try to unwrap motion over periodic boundaries.' )
parser.add_argument('infile', nargs='?', default='POSCAR', type=argparse.FileType('r'), help='POSCAR filename')
args = parser.parse_args()

# Read atoms from POSCAR:
poscar1 = PoscarParser(args.infile).get_structure()
pos = poscar1.get_positions( coords = 'direct' )
natoms = pos.shape[0]

# Build array of pair indices:
pairs = get_pairs(natoms)
npairs = pairs.shape[0]

print "%d atoms, %d pairs" % (natoms, npairs)

# Find displacement vectors for all atoms:
x = pos[pairs[:,0]] - pos[pairs[:,1]]

# Use minimum image convention to threat bonds over PBCs
# Note: This will not work with *very* tilted unit cells
x = x - (2*x).astype('int')

X = direct_to_cartesian(x, poscar1.get_cell())

r2 = (X**2).sum(axis=1)
r = np.sqrt(r2)
Beispiel #4
0
    action='store_true',
    help='Don\'t try to unwrap motion over periodic boundaries.')
parser.add_argument('infile',
                    nargs='?',
                    default='POSCAR',
                    type=argparse.FileType('r'),
                    help='POSCAR filename')
args = parser.parse_args()

# Read atoms from POSCAR:
poscar1 = PoscarParser(args.infile).get_structure()
pos = poscar1.get_positions(coords='direct')
natoms = pos.shape[0]

# Build array of pair indices:
pairs = get_pairs(natoms)
npairs = pairs.shape[0]

print "%d atoms, %d pairs" % (natoms, npairs)

# Find displacement vectors for all atoms:
x = pos[pairs[:, 0]] - pos[pairs[:, 1]]

# Use minimum image convention to threat bonds over PBCs
# Note: This will not work with *very* tilted unit cells
x = x - (2 * x).astype('int')

X = direct_to_cartesian(x, poscar1.get_cell())

r2 = (X**2).sum(axis=1)
r = np.sqrt(r2)
def main():
    import ase
    #from connectivities import connectivities, partition, plot
    atoms = ase.io.read('CONTCAR', format='vasp')
    #dists, idx, bonds = connectivities(atoms, maxdist=2.5)
    #groups = partition(atoms, dists, idx, mincount=50, maxwidth=2.0)
    #cats = categorize(atoms, dists, idx)
    #cats[0]

    pos = atoms.positions

    # Get all atom pairs:
    n = len(atoms)
    pairs = get_pairs(n)

    # Filter pairs based on atom types:
    bond = (14, 14)
    pnum = atoms.numbers[pairs]
    # numbers == (bond[0],bond[1]) or numbers == (bond[1],bond[0]) :
    mask = np.any(np.column_stack(
        (np.all(pnum == bond, axis=1), np.all(pnum == reversed(bond),
                                              axis=1))),
                  axis=1)
    del pnum

    # Calculate distancess:
    neighbours = [(-1, 2), (-1, 2), (-1, 2)]
    vectors = atoms.positions[pairs[:, 0]] - atoms.positions[pairs[:, 1]]
    tmp = np.zeros((len(vectors), 2))
    tmp[:, 0] = lensq(vectors)
    for d0 in range(*neighbours[0]):
        for d1 in range(*neighbours[1]):
            for d2 in range(*neighbours[2]):
                if d0 == d1 == d2 == 0:
                    continue
                tmp[:, 1] = lensq(vectors +
                                  np.dot(np.array([d0, d1, d2]), atoms.cell))
                tmp.min(axis=1, out=tmp[:, 0])

    #
    # vectors må korrigeres for PBC. Sjekk om vi kan få pair list rett ut fra ASE
    #

    dists = np.sqrt(tmp[:, 0])
    del tmp

    # Filter pairs based on bond lengths:
    maxdist = 2.8
    if maxdist is not None:
        # add to mask
        mask = np.all(np.column_stack((mask, dists <= maxdist)), axis=1)

    dists = dists[mask]
    pairs = pairs[mask, :]
    vectors = vectors[mask, :]

    import matplotlib.pyplot as plt

    vec2d = np.zeros((vectors.shape[0], 2))
    x = np.array([1, 0, 0])
    y = np.array([0, 1, 0])
    vec2d = vectors[:, ::2]

    pos2d = pos[pairs[:, 0], ::2]

    print vec2d.shape
    print pos2d.shape

    plt.quiver(pos[:, 0], pos[:, 1], vec2d[:, 0], vec2d[:, 1])

    plt.show()
Beispiel #6
0
    def get_shortest_bond(self, include_self = False, safe_mode = True, rmax = 3.0):
        """
        Returns a tupple containing the shortest bond length in Angstrom,
        followed by the indices of the two atoms making up the bond
        
        Parameters:
            include_self : bool (default False)
                Whether to check for bonds between an atom and its _own_ periodic image.
                This is only needed for very small unit cells, typically with a single atom.
            safe_mode : bool (default True)
                Much slower, but safer for non-cubic cells
            rmax : float (default 3.0)
                Maximum bond length (in Angstrom) to check for 
                (only used in safe_mode)

        """
        a = self._cell[0]
        b = self._cell[1]
        c = self._cell[2]

        pos = self._positions
        natoms = pos.shape[0]
        if natoms == 1:
            print "Note from get_shortest_bond(): include_self is enabled since only a single atom was found!"
            include_self = True

        # Limit to sphere of radius Rc
        if safe_mode:
            #if include_self:
            #    print "include_self and safe_mode are not currently compatible. sorry"
            #    return
            
            natoms = self.get_num_atoms()
            a = self._cell[0]
            b = self._cell[1]
            c = self._cell[2]

            # Find distance between opposing faces of the cell:
            wa = abs(np.dot(a,np.cross(b,c))) / np.linalg.norm(np.cross(b,c))
            wb = abs(np.dot(b,np.cross(c,a))) / np.linalg.norm(np.cross(c,a))
            wc = abs(np.dot(c,np.cross(a,b))) / np.linalg.norm(np.cross(a,b))

            # If half the max radius exceeds one of the face-to-face distances (wa, wb or wc), 
            # we add more atoms in the given direction(s) as necessary.
            la = 1 + int(2*rmax/wa)
            lb = 1 + int(2*rmax/wb)
            lc = 1 + int(2*rmax/wc)
            print "dim:",la,lb,lc
            #p2 = self.get_supercell_positions(la,lb,lc, coords='d')
            pos = np.zeros((natoms*la*lb*lc,3))
            #offsets = np.zeros((natoms*la*lb*lc,3), dtype=np.int)
            #c = np.diag((1,1,1)) # since we use direct coordinates
            for i in range(la):
                for j in range(lb):
                    for k in range(lc):
                        m = i*lb*lc + j*lc + k
                        pos[m*natoms:(m+1)*natoms] = self._positions + np.array((i, j, k))
                        #offsets[m*natoms:(m+1)*natoms] = [i, j, k]
            indices = np.tile(np.arange(natoms), la*lb*lc)

            paired = np.zeros(natoms, dtype=np.int)
            minr = np.zeros(natoms)
            for j in np.arange(natoms):
                # Center at atom <index>:
                pos -= pos[j]
                # Minimum image convention with coordinates in range lb*[-0.5,0.5>
                pos[:,0] -= la*(pos[:,0]*2/la).astype('int')
                pos[:,1] -= lb*(pos[:,1]*2/lb).astype('int')
                pos[:,2] -= lc*(pos[:,2]*2/lc).astype('int')
                
                cart = direct_to_cartesian(pos,self._cell)
                dr = np.sqrt(np.sum(cart**2,1))
                cond = np.logical_and(dr < rmax, dr > 0.0)

                dr = dr[cond]
                if dr.shape[0] == 0:
                    print "[Warning]: No neighbours found within %.2f Angstrom of atom %d" % (rmax,j)
                    minr[j] = 1001.0
                    continue

                so = np.argsort(dr)

                #pos = pos[cond]
                #offsets = (2*pos).astype('int')
                ##indices = indices[cond]

                ## sort:
                #dr = dr[so]
                #pos = pos[so]
                #offsets = offsets[so]
                #indices = indices[so]

                #indices, dr, offsets, pos = self.get_neighbours(j)
                paired[j] = indices[cond][so][0]
                minr[j] = dr[so][0]
                #pairs[j,nearest] = 
                #minpair = pairs[j,nearest] 
                #minr = dr[0]
            
            #print nearest,shortest
            minidx = np.argmin(minr)
            minr = minr[minidx]
            if minr > 1000.0:
                print "[Error]: No bonds shorter than %.2f Angstrom found. Please increase rmax" % rmax

            return (minr,minidx,paired[minidx])

        else:

            # Build array of pair indices:
            pairs = get_pairs(natoms, include_self=include_self)
            npairs = pairs.shape[0]

            # Find displacement vectors for all pairs:
            x = pos[pairs[:,0]] - pos[pairs[:,1]]
        
            # Use minimum image convention to threat bonds over PBCs
            # Note: use safe_mode with tilted unit cells in which the 
            # shortest bond is close to half of one of the cell dimensions
            x = x - (2*x).astype('int')

            X = direct_to_cartesian(x, self._cell)

            r2 = (X**2).sum(axis=1)
            r = np.sqrt(r2)

            meanr2 = np.mean(r2,axis=0)
            meanr = np.mean(r,axis=0)

            minidx = np.argmin(r)
            minpair = pairs[minidx]
            minr = r[minidx]
    
            return (minr,minpair[0],minpair[1])
def main():
    import ase
    #from connectivities import connectivities, partition, plot
    atoms = ase.io.read('CONTCAR', format='vasp')
    #dists, idx, bonds = connectivities(atoms, maxdist=2.5)
    #groups = partition(atoms, dists, idx, mincount=50, maxwidth=2.0)
    #cats = categorize(atoms, dists, idx)
    #cats[0]

    pos = atoms.positions

    # Get all atom pairs:
    n = len(atoms)
    pairs = get_pairs(n)

    # Filter pairs based on atom types:
    bond = (14,14)
    pnum = atoms.numbers[pairs]
    # numbers == (bond[0],bond[1]) or numbers == (bond[1],bond[0]) :
    mask = np.any(np.column_stack((np.all(pnum == bond, axis=1), np.all(pnum == reversed(bond), axis = 1))),axis=1)
    del pnum

    # Calculate distancess:
    neighbours = [(-1, 2), (-1, 2), (-1, 2)]
    vectors = atoms.positions[pairs[:,0]] - atoms.positions[pairs[:,1]]
    tmp = np.zeros((len(vectors), 2))
    tmp[:,0] = lensq(vectors)
    for d0 in range(*neighbours[0]):
        for d1 in range(*neighbours[1]):
            for d2 in range(*neighbours[2]):
                if d0 == d1 == d2 == 0:
                    continue
                tmp[:,1] = lensq(vectors + np.dot(np.array([d0, d1, d2]), 
                                               atoms.cell))
                tmp.min(axis=1, out=tmp[:,0])

    #
    # vectors må korrigeres for PBC. Sjekk om vi kan få pair list rett ut fra ASE
    #

    dists = np.sqrt(tmp[:,0])
    del tmp

    # Filter pairs based on bond lengths:
    maxdist = 2.8
    if maxdist is not None:
        # add to mask
        mask = np.all(np.column_stack((mask, dists <= maxdist)), axis = 1)

    dists = dists[mask]
    pairs = pairs[mask,:]
    vectors = vectors[mask,:]

    import matplotlib.pyplot as plt

    vec2d = np.zeros((vectors.shape[0],2))
    x = np.array([1,0,0])
    y = np.array([0,1,0])
    vec2d = vectors[:,::2]

    pos2d = pos[pairs[:,0],::2]

    print vec2d.shape
    print pos2d.shape

    plt.quiver(pos[:,0], pos[:,1], vec2d[:,0], vec2d[:,1])

    plt.show()
Beispiel #8
0
    def get_shortest_bond(self, include_self=False, safe_mode=True, rmax=3.0):
        """
        Returns a tupple containing the shortest bond length in Angstrom,
        followed by the indices of the two atoms making up the bond
        
        Parameters:
            include_self : bool (default False)
                Whether to check for bonds between an atom and its _own_ periodic image.
                This is only needed for very small unit cells, typically with a single atom.
            safe_mode : bool (default True)
                Much slower, but safer for non-cubic cells
            rmax : float (default 3.0)
                Maximum bond length (in Angstrom) to check for 
                (only used in safe_mode)

        """
        a = self._cell[0]
        b = self._cell[1]
        c = self._cell[2]

        pos = self._positions
        natoms = pos.shape[0]
        if natoms == 1:
            print "Note from get_shortest_bond(): include_self is enabled since only a single atom was found!"
            include_self = True

        # Limit to sphere of radius Rc
        if safe_mode:
            #if include_self:
            #    print "include_self and safe_mode are not currently compatible. sorry"
            #    return

            natoms = self.get_num_atoms()
            a = self._cell[0]
            b = self._cell[1]
            c = self._cell[2]

            # Find distance between opposing faces of the cell:
            wa = abs(np.dot(a, np.cross(b, c))) / np.linalg.norm(np.cross(
                b, c))
            wb = abs(np.dot(b, np.cross(c, a))) / np.linalg.norm(np.cross(
                c, a))
            wc = abs(np.dot(c, np.cross(a, b))) / np.linalg.norm(np.cross(
                a, b))

            # If half the max radius exceeds one of the face-to-face distances (wa, wb or wc),
            # we add more atoms in the given direction(s) as necessary.
            la = 1 + int(2 * rmax / wa)
            lb = 1 + int(2 * rmax / wb)
            lc = 1 + int(2 * rmax / wc)
            print "dim:", la, lb, lc
            #p2 = self.get_supercell_positions(la,lb,lc, coords='d')
            pos = np.zeros((natoms * la * lb * lc, 3))
            #offsets = np.zeros((natoms*la*lb*lc,3), dtype=np.int)
            #c = np.diag((1,1,1)) # since we use direct coordinates
            for i in range(la):
                for j in range(lb):
                    for k in range(lc):
                        m = i * lb * lc + j * lc + k
                        pos[m * natoms:(m + 1) *
                            natoms] = self._positions + np.array((i, j, k))
                        #offsets[m*natoms:(m+1)*natoms] = [i, j, k]
            indices = np.tile(np.arange(natoms), la * lb * lc)

            paired = np.zeros(natoms, dtype=np.int)
            minr = np.zeros(natoms)
            for j in np.arange(natoms):
                # Center at atom <index>:
                pos -= pos[j]
                # Minimum image convention with coordinates in range lb*[-0.5,0.5>
                pos[:, 0] -= la * (pos[:, 0] * 2 / la).astype('int')
                pos[:, 1] -= lb * (pos[:, 1] * 2 / lb).astype('int')
                pos[:, 2] -= lc * (pos[:, 2] * 2 / lc).astype('int')

                cart = direct_to_cartesian(pos, self._cell)
                dr = np.sqrt(np.sum(cart**2, 1))
                cond = np.logical_and(dr < rmax, dr > 0.0)

                dr = dr[cond]
                if dr.shape[0] == 0:
                    print "[Warning]: No neighbours found within %.2f Angstrom of atom %d" % (
                        rmax, j)
                    minr[j] = 1001.0
                    continue

                so = np.argsort(dr)

                #pos = pos[cond]
                #offsets = (2*pos).astype('int')
                ##indices = indices[cond]

                ## sort:
                #dr = dr[so]
                #pos = pos[so]
                #offsets = offsets[so]
                #indices = indices[so]

                #indices, dr, offsets, pos = self.get_neighbours(j)
                paired[j] = indices[cond][so][0]
                minr[j] = dr[so][0]
                #pairs[j,nearest] =
                #minpair = pairs[j,nearest]
                #minr = dr[0]

            #print nearest,shortest
            minidx = np.argmin(minr)
            minr = minr[minidx]
            if minr > 1000.0:
                print "[Error]: No bonds shorter than %.2f Angstrom found. Please increase rmax" % rmax

            return (minr, minidx, paired[minidx])

        else:

            # Build array of pair indices:
            pairs = get_pairs(natoms, include_self=include_self)
            npairs = pairs.shape[0]

            # Find displacement vectors for all pairs:
            x = pos[pairs[:, 0]] - pos[pairs[:, 1]]

            # Use minimum image convention to threat bonds over PBCs
            # Note: use safe_mode with tilted unit cells in which the
            # shortest bond is close to half of one of the cell dimensions
            x = x - (2 * x).astype('int')

            X = direct_to_cartesian(x, self._cell)

            r2 = (X**2).sum(axis=1)
            r = np.sqrt(r2)

            meanr2 = np.mean(r2, axis=0)
            meanr = np.mean(r, axis=0)

            minidx = np.argmin(r)
            minpair = pairs[minidx]
            minr = r[minidx]

            return (minr, minpair[0], minpair[1])