예제 #1
0
def chgcarBondAnalysis(chgcarfile,bondLengths,normalize=False,verbose=False,Ninterps=None,loc=None):

    BLs=bondLengths
    nBLs=len(BLs)

    #Parse CHGCAR
    chgcar=open(chgcarfile,"r").readlines()
    (v1,v2,v3,atypes,axs,ays,azs,header),chg = chgcarIO.read(chgcar)
    gridSize = chg.shape
    basis=asarray([v1,v2,v3])
    lengths=array([v1[0],v2[1],v3[2]])
    atoms=array(zip(axs,ays,azs))

    #Grid properties
    nGridPoints=reduce(operator.mul,gridSize)

    #Neighbors
    halfNeighbors=voronoiNeighbors(atoms,basis,atypes,style='half')

    a=chg.shape
    AvgChg=sum([sum([sum(line) for line in plane]) for plane in chg])/a[0]/a[1]/a[2]
    if verbose:
        print "Average CHG value:",AvgChg

    #Evaluate the CHG between each nieghbor pair
    if Ninterps==None:
        Ninterps=array([1,50,50])
        avgGrids,grids,bondcounts=fieldNeighbors3D(atoms,atypes,basis,chg,gridSize,halfNeighbors,cutoffs=bondLengths,loc=loc)
    else:
        Ninterps=array([1]+Ninterps)
        avgGrids,grids,bondcounts=fieldNeighbors3D(atoms,atypes,basis,chg,gridSize,halfNeighbors,cutoffs=bondLengths,Ninterps=Ninterps,loc=loc)

    #Normalize if necessary
    if normalize:
        avgGrids=[avgGrid/AvgChg for avgGrid in avgGrids]
            
    return avgGrids,grids,bondcounts

    """
예제 #2
0
if len(sys.argv) < 2:
    print "Usage:"
    print sys.argv[0] + " <poscar> <opt: max bond length>"
    exit(0)

poscar = open(sys.argv[1], "r").readlines()
mbl = -1.
if len(sys.argv) == 3:
    mbl = float(sys.argv[2])

[basis, atypes, atoms, head, poscar] = poscarIO.read(poscar)
bounds = array([basis[0][0], basis[1][1], basis[2][2]])

#Generate neighbor lists, half and full
vhalfNeighbors = voronoiNeighbors(atoms, basis, atypes, style='half')
vfullNeighbors = half2full(vhalfNeighbors)

#Check lengths of bonds
if mbl > 0:
    ls = list()
    for ai, neighbs in enumerate(vfullNeighbors):
        ls.append(
            [dist_periodic(atoms[ai], atoms[aj], bounds) for aj in neighbs])

    vfullNeighbors = [[
        vfullNeighbors[i][j] for j, dist in enumerate(dists) if dist <= mbl
    ] for i, dists in enumerate(ls)]
    for i, j in zip(vfullNeighbors, ls):
        print len(i), len(j)
예제 #3
0
for i in sys.argv[2:]:
    try:
        maxls.append(float(i))
    except ValueError:
        if i[0] in ["v","V"]:
            voronEnable=True
            voronCap=float(i.split(",")[1])
        else:
            raise ValueError

[basis,atypes,atoms,head,poscar] = poscarIO.read(poscar)
atoms=array(atoms)
lengths=array([basis[0][0],basis[1][1],basis[2][2]])

atLFullNeighbors=[neighbors(atoms,array([[0,basis[0][0]],[0,basis[1][1]],[0,basis[2][2]]]),maxlen,style='full') for maxlen in maxls]
vFullNeighbors=voronoiNeighbors(atoms,basis,atypes,style='full')
vFullNeighbors=[[j for j in vFullNeighbors[i] if dist_periodic(atoms[i],atoms[j],lengths)<voronCap] for i in range(len(vFullNeighbors))]

atLCoordNumbers=map(lambda x:map(len,x),atLFullNeighbors)
vCoordNumbers=map(len,vFullNeighbors)

#To include Voronoi (capped at max length) uncomment:
if voronEnable:
    atLCoordNumbers.append(vCoordNumbers)

absMin=0
absMax=50
mncn=max(min(map(min,atLCoordNumbers))-3,absMin)
mxcn=min(max(map(max,atLCoordNumbers))+4,absMax)

colors=["red","blue","green","purple","yellow"]
예제 #4
0
if len(sys.argv)<2:
    print "Usage:"
    print sys.argv[0]+" <poscar> <opt: max bond length>"
    exit(0)

poscar = open(sys.argv[1],"r").readlines()
mbl=-1.
if len(sys.argv)==3:
    mbl=float(sys.argv[2])

[basis,atypes,atoms,head,poscar] = poscarIO.read(poscar)
bounds=array([basis[0][0],basis[1][1],basis[2][2]])

#Generate neighbor lists, half and full
vhalfNeighbors=voronoiNeighbors(atoms,basis,atypes,style='half')
vfullNeighbors=half2full(vhalfNeighbors)

#Check lengths of bonds
if mbl>0:
    ls=list()
    for ai,neighbs in enumerate(vfullNeighbors):
        ls.append([dist_periodic(atoms[ai],atoms[aj],bounds) for aj in neighbs])
        
    vfullNeighbors= [[vfullNeighbors[i][j] for j,dist in enumerate(dists) if dist<=mbl] for i,dists in enumerate(ls)]
    for i,j in zip(vfullNeighbors,ls):
        print len(i),len(j)

coordNumbers=map(len,vfullNeighbors)

CNhist=zeros(200)
예제 #5
0
            voronEnable = True
            voronCap = float(i.split(",")[1])
        else:
            raise ValueError

[basis, atypes, atoms, head, poscar] = poscarIO.read(poscar)
atoms = array(atoms)
lengths = array([basis[0][0], basis[1][1], basis[2][2]])

atLFullNeighbors = [
    neighbors(atoms,
              array([[0, basis[0][0]], [0, basis[1][1]], [0, basis[2][2]]]),
              maxlen,
              style='full') for maxlen in maxls
]
vFullNeighbors = voronoiNeighbors(atoms, basis, atypes, style='full')
vFullNeighbors = [[
    j for j in vFullNeighbors[i]
    if dist_periodic(atoms[i], atoms[j], lengths) < voronCap
] for i in range(len(vFullNeighbors))]

atLCoordNumbers = map(lambda x: map(len, x), atLFullNeighbors)
vCoordNumbers = map(len, vFullNeighbors)

#To include Voronoi (capped at max length) uncomment:
if voronEnable:
    atLCoordNumbers.append(vCoordNumbers)

absMin = 0
absMax = 50
mncn = max(min(map(min, atLCoordNumbers)) - 3, absMin)
예제 #6
0
def chgcarBondAnalysis(chgcarfile,
                       bondLengths,
                       normalize=False,
                       verbose=False):

    BLs = bondLengths
    nBLs = len(BLs)

    #Parse CHGCAR
    chgcar = open(chgcarfile, "r").readlines()
    (v1, v2, v3, atypes, axs, ays, azs,
     header), gridSize, chg = chgcarIO.read(chgcar)
    basis = asarray([v1, v2, v3])
    lengths = array([v1[0], v2[1], v3[2]])
    atoms = array(zip(axs, ays, azs))

    #Grid properties
    nGridPoints = reduce(operator.mul, gridSize)

    #Neighbors
    halfNeighbors = voronoiNeighbors(atoms, basis, atypes, style='half')

    a = chg.shape
    AvgChg = sum([sum([sum(line) for line in plane])
                  for plane in chg]) / a[0] / a[1] / a[2]
    if verbose:
        print "Average CHG value:", AvgChg

    #Evaluate the CHG between each nieghbor pair
    avgchgline, xchglines, ychglines, halfNeighbors = fieldNeighbors1D(
        atoms, atypes, basis, chg, gridSize, halfNeighbors)

    #Cutoff neighbors that fall below the thresh-hold
    Ninterp = len(avgchgline)
    avgIBL = zeros([nBLs, Ninterp])  #avg line inside the bond length
    avgOBL = zeros([nBLs, Ninterp])  #avg line outside the bond length
    nibl = zeros(nBLs)
    nobl = zeros(nBLs)

    cnt = 0
    for a, jNeighbors in enumerate(halfNeighbors):
        atoma = atoms[a]
        for b, jNeighb in enumerate(jNeighbors):
            atomb = atoms[jNeighb]
            d = dist_periodic(atoma, atomb, lengths)
            vals = ychglines[a][b]
            xx = xchglines[a][b]
            for j, bl in enumerate(BLs):
                if normalize:
                    avals = array(vals) / AvgChg
                else:
                    avals = array(vals)
                if d < bl:
                    nibl[j] += 2
                    avgIBL[j] += avals
                    avgIBL[j] += avals[::-1]
                else:
                    cnt += 1
                    nobl[j] += 2
                    avgOBL[j] += avals
                    avgOBL[j] += avals[::-1]
    for i in range(nBLs):
        if nibl[i] == 0:
            nibl[i] = 1
        if nobl[i] == 0:
            nobl[i] = 1
    avgOBL = [avgOBL[i] / nobl[i] for i in range(nBLs)]
    avgIBL = [avgIBL[i] / nibl[i] for i in range(nBLs)]
    return avgOBL, nobl, avgIBL, nibl
예제 #7
0
def outcarCoordination(outcarfile, maxls, voronoiEnable):
    outcar = open(outcarfile, "r")

    #Grab ion types
    while True:
        line = outcar.readline()
        if "ions per type" in line:
            break
    atypes = map(int, line.split("=")[1].split())

    tCoordNumbers = zeros([len(maxls), sum(atypes)])

    #Grab basis vectors
    while True:
        line = outcar.readline()
        if "direct lattice vectors" in line:
            break
    basis = array(
        [map(float,
             outcar.readline().split()[:3]) for i in range(3)])
    lengths = array([basis[0][0], basis[1][1], basis[2][2]])

    absMax = 50
    if voronoiEnable:
        avgCNhist = zeros([len(maxls) + 1, absMax])
    else:
        avgCNhist = zeros([len(maxls), absMax])

    #Grab atom positions and perform adf calculation
    count = 0
    posit = False
    for line in outcar:
        if posit:
            if "--" in line:
                if len(atoms) == 0:
                    continue
                else:
                    #Analysis
                    if max(zip(*atoms)[0]) < 1.01:
                        atoms = dot(array(atoms), basis)
                    else:
                        atoms = array(atoms)

                    atLFullNeighbors = [
                        neighborOrtho(
                            atoms,
                            array([basis[0][0], basis[1][1], basis[2][2]]),
                            6.0,
                            style='full') for maxlen in maxls
                    ]
                    atLCoordNumbers = map(lambda x: map(len, x),
                                          atLFullNeighbors)

                    if voronoiEnable:
                        vFullNeighbors = voronoiNeighbors(atoms,
                                                          basis,
                                                          atypes,
                                                          style='full')
                        vFullNeighbors = [[
                            j for j in vFullNeighbors[i] if dist_periodic(
                                atoms[i], atoms[j], lengths) < voronCap
                        ] for i in range(len(vFullNeighbors))]
                        vCoordNumbers = map(len, vFullNeighbors)
                        atLCoordNumbers.append(vCoordNumbers)

                    hist = [[i.count(j) for j in range(absMax)]
                            for i in atLCoordNumbers]
                    avgCNhist += array(hist)

                    print count
                    posit = False
            else:
                atoms.append(map(float, line.split()[:3]))
        elif "POSITION" in line:
            atoms = list()
            posit = True
            count += 1

    avgCNhist /= count
    return avgCNhist.tolist()
예제 #8
0
def elfcarNeighborAnalysis(elfcarfile,
                           verbose=False,
                           minELF=0.5,
                           maxBondLength=4.0):
    #Loads up an ELFCAR, generates a starting neighbor list from voronoi tesselation
    #Initial neighbors are dropped if bondlength is greater than maxBondLength
    #Generates a bunch of points on a cylinder
    #Maps the cylinder points across each neighbor pair
    #If the average ELF is always above minELF accross this cylinder, atoms are bonded.

    #Parse ELFCAR
    elfcar = open(elfcarfile, "r").readlines()
    (basis, atypes, atoms, header), elf = elfcarIO.read(elfcar)
    lengths = array([basis[0][0], basis[1][1], basis[2][2]])

    #Neighbors
    bounds = [[0, basis[0][0]], [0, basis[1][1]], [0, basis[2][2]]]
    halfNeighbs = voronoiNeighbors(atoms, basis, style="half")

    a = elf.shape
    AvgElf = sum([sum([sum(line) for line in plane])
                  for plane in elf]) / a[0] / a[1] / a[2]
    if verbose:
        print elfcarfile
        print "Average ELF value:", AvgElf

    #Evaluate the ELF between each nieghbor pair
    #creates a bunch of points on a circle in the x-y plane
    def circlePoints(center, radius):
        N = 4
        ps = [float(p) / N * radius for p in range(-N, N + 1)]
        r2 = radius * radius
        points = list()
        for x in ps:
            for y in ps:
                if (x**2 + y**2) <= r2:
                    points.append(asarray([x, y]))
        return asarray(points)

    atoms = asarray([lengths[i] - v for i, v in enumerate(atoms.T)]).T

    #Flip the ELF because its off, thanks a lot VASP.
    elf = elf[::-1, ::-1, ::-1]

    #Loop over atom pairs, generate cylinders
    cylSlices = 10
    cylRadius = 0.7
    cirPoints = circlePoints(a, cylRadius).T
    cylPoints = [
        vstack([cirPoints, zeros(cirPoints.shape[1]) + float(z)])
        for z in range(cylSlices + 1)
    ]
    coordination = zeros(len(atoms))
    neighborsELF = [list() for i in range(len(atoms))]

    for i, ineighbs in enumerate(halfNeighbs):
        a = atoms[i]

        for j in ineighbs:
            #copy the cylinder points so you can play with them...
            localCyl = array(cylPoints)

            #Find the minimum image atom
            b = minImageAtom(a, atoms[j], basis)
            l = minImageDist(a, b, basis)

            if l > maxBondLength or l == 0.0: continue

            #How to map your cylinder onto the local atom
            R = rotmatx([0, 0, l], b - a)

            #Loop over each cylinder slice
            sliceParam = list()
            for cir in localCyl:
                #cir is stretched and rotated cylinder
                cir[2] /= cylSlices / l
                cir = asarray([dot(R, p) + a for p in cir.T]).T

                #cir2 is cir with periodic boundary conditions applied and mapped to index space
                cir2 = asarray([((c / lengths[ind] * elf.shape[ind]) %
                                 (elf.shape[ind] - 1))
                                for ind, c in enumerate(cir)])

                #Interpolation across cylinder
                z = ndimage.map_coordinates(elf, cir2)

                #Average ELF value across each slice.
                sliceParam.append(sum(z) / len(z))

            if min(sliceParam) > minELF:
                #neighbor pair is bonded, count it!
                neighborsELF[i].append(j)
                neighborsELF[j].append(i)

    return neighborsELF
예제 #9
0
def chgcarBondAnalysis(chgcarfile,bondLengths,normalize=False,verbose=False):

    BLs=bondLengths
    nBLs=len(BLs)

    #Parse CHGCAR
    chgcar=open(chgcarfile,"r").readlines()
    (v1,v2,v3,atypes,axs,ays,azs,header),gridSize,chg = chgcarIO.read(chgcar)
    basis=asarray([v1,v2,v3])
    lengths=array([v1[0],v2[1],v3[2]])
    atoms=array(zip(axs,ays,azs))

    #Grid properties
    nGridPoints=reduce(operator.mul,gridSize)

    #Neighbors
    halfNeighbors=voronoiNeighbors(atoms,basis,atypes,style='half')

    a=chg.shape
    AvgChg=sum([sum([sum(line) for line in plane]) for plane in chg])/a[0]/a[1]/a[2]
    if verbose:
        print "Average CHG value:",AvgChg

    #Evaluate the CHG between each nieghbor pair
    avgchgline,xchglines,ychglines,halfNeighbors=fieldNeighbors1D(atoms,atypes,basis,chg,gridSize,halfNeighbors)

    #Cutoff neighbors that fall below the thresh-hold
    Ninterp=len(avgchgline)
    avgIBL=zeros([nBLs,Ninterp]) #avg line inside the bond length
    avgOBL=zeros([nBLs,Ninterp]) #avg line outside the bond length
    nibl=zeros(nBLs)
    nobl=zeros(nBLs)

    cnt=0
    for a,jNeighbors in enumerate(halfNeighbors):
        atoma=atoms[a]
        for b,jNeighb in enumerate(jNeighbors):
            atomb=atoms[jNeighb]
            d=dist_periodic(atoma,atomb,lengths)
            vals=ychglines[a][b]
            xx=xchglines[a][b]
            for j,bl in enumerate(BLs):
                if normalize:
                    avals=array(vals)/AvgChg
                else:
                    avals=array(vals)
                if d<bl:
                    nibl[j]+=2
                    avgIBL[j]+=avals
                    avgIBL[j]+=avals[::-1]
                else:
                    cnt+=1
                    nobl[j]+=2
                    avgOBL[j]+=avals
                    avgOBL[j]+=avals[::-1]
    for i in range(nBLs):
        if nibl[i]==0:
            nibl[i]=1
        if nobl[i]==0:
            nobl[i]=1
    avgOBL=[avgOBL[i]/nobl[i] for i in range(nBLs)]
    avgIBL=[avgIBL[i]/nibl[i] for i in range(nBLs)]
    return avgOBL,nobl,avgIBL,nibl
예제 #10
0
bondCutoffs = [float(i) / 10 for i in range(2, 7)]
if len(sys.argv) == 3:
    bondCutoffs = [float(sys.argv[2])]

# Parse ELFCAR
elfcar = open(sys.argv[1], "r").readlines()
(basis, atypes, atoms, header), gridSize, elf = elfcarIO.read(elfcar)
basis = array(basis)
bounds = [[0.0, basis[0][0]], [0.0, basis[1][1]], [0.0, basis[2][2]]]
atoms = array(atoms)

# Grid properties
nGridPoints = reduce(operator.mul, gridSize)

# Neighbors
halfNeighbors = voronoiNeighbors(atoms=atoms, basis=basis, atypes=atypes, style="half")

print "Number of Neighbors before elimination:", sum([len(i) for i in halfNeighbors])

a = elf.shape
print "Average ELF value:", sum([sum([sum(line) / a[2] for line in plane]) / a[1] for plane in elf]) / a[0]

# Evaluate the ELF between each nieghbor pair
avgelfline, elflines, halfNeighbors = fieldNeighbors(atoms, atypes, basis, elf, gridSize, halfNeighbors)

# Cutoff neighbors that fall below the thresh-hold
Ninterp = len(avgelfline)
avgbig = zeros([len(bondCutoffs), Ninterp])
avgsmall = zeros([len(bondCutoffs), Ninterp])
nab = zeros(len(bondCutoffs))
nas = zeros(len(bondCutoffs))
예제 #11
0
def outcarCoordination(outcarfile,maxls,voronoiEnable):
    outcar=open(outcarfile,"r")

    #Grab ion types
    while True:
        line=outcar.readline()
        if "ions per type" in line:
            break
    atypes=map(int,line.split("=")[1].split())

    tCoordNumbers=zeros([len(maxls),sum(atypes)])

    #Grab basis vectors
    while True:
        line=outcar.readline()
        if "direct lattice vectors" in line:
            break
    basis=array([map(float,outcar.readline().split()[:3]) for i in range(3)])
    lengths=array([basis[0][0],basis[1][1],basis[2][2]])

    absMax=50
    if voronoiEnable:
        avgCNhist=zeros([len(maxls)+1,absMax])
    else:
        avgCNhist=zeros([len(maxls),absMax])

    #Grab atom positions and perform adf calculation
    count=0
    posit=False
    for line in outcar:
        if posit:
            if "--" in line:
                if len(atoms)==0:
                    continue
                else:
                    #Analysis
                    if max(zip(*atoms)[0])<1.01:
                        atoms=dot(array(atoms),basis)
                    else:
                        atoms=array(atoms)

                    atLFullNeighbors=[neighborOrtho(atoms,array([basis[0][0],basis[1][1],basis[2][2]]),6.0,style='full') for maxlen in maxls]
                    atLCoordNumbers=map(lambda x:map(len,x),atLFullNeighbors)

                    if voronoiEnable:
                        vFullNeighbors=voronoiNeighbors(atoms,basis,atypes,style='full')
                        vFullNeighbors=[[j for j in vFullNeighbors[i] if dist_periodic(atoms[i],atoms[j],lengths)<voronCap] for i in range(len(vFullNeighbors))]
                        vCoordNumbers=map(len,vFullNeighbors)
                        atLCoordNumbers.append(vCoordNumbers)
                    
                    hist=[[i.count(j) for j in range(absMax)] for i in atLCoordNumbers]
                    avgCNhist+=array(hist)
                    
                    print count
                    posit=False
            else:
                atoms.append(map(float,line.split()[:3]))
        elif "POSITION" in line:
            atoms=list()
            posit=True
            count+=1
    
    avgCNhist/=count
    return avgCNhist.tolist()
예제 #12
0
def outcarADF(outcarfile,nbins,bl=-1.0,bw=-1.0):
    outcar=open(outcarfile,"r")
    tbinvals=list()

    #Grab ion types
    while True:
        line=outcar.readline()
        if "ions per type" in line:
            break
    atypes=map(int,line.split("=")[1].split())

    #Grab basis vectors
    while True:
        line=outcar.readline()
        if "direct lattice vectors" in line:
            break
    basis=array([map(float,outcar.readline().split()[:3]) for i in range(3)])
    lengths=array([basis[0][0],basis[1][1],basis[2][2]])

    #Grab atom positions and perform adf calculation
    count=0
    posit=False
    for line in outcar:
        if posit:
            if "--" in line:
                if len(atoms)==0:
                    continue
                else:
                    #Analysis
                    if max(zip(*atoms)[0])<1.01:
                        atoms=dot(array(atoms),basis)
                    else:
                        atoms=array(atoms)
                    neighbs=voronoiNeighbors(atoms,basis,atypes,style='full')
                    if bl!=-1 and bw!=-1:
                        specbonds=[list() for i in range(len(atoms))]
                        for i in range(len(atoms)):
                            ai=atoms[i]#dot(atoms[i],basis)
                            for j in neighbs[i]:
                                aj=atoms[j]#dot(atoms[j],basis)
                                d=dist_periodic(ai,aj,lengths)
                       
                                if fabs(d-bl)<bw:
                                    if d<1.0:
                                        print d
                                        print dist_periodic(ai,aj,lengths)
                                        print ai
                                        print aj
                                        exit(0)
                                    specbonds[i].append(j)
                    else:
                        specbonds=neighbs
                    [angs,abins]=adf(atoms,specbonds,basis,nbins=nbins)
                    tbinvals.append(abins)
                    print count
                    posit=False
            else:
                atoms.append(map(float,line.split()[:3]))
        elif "POSITION" in line:
            atoms=list()
            posit=True
            count+=1
    
    return angs,tbinvals
예제 #13
0
def outcarADF(outcarfile, nbins, bl=-1.0, bw=-1.0):
    outcar = open(outcarfile, "r")
    tbinvals = list()

    #Grab ion types
    while True:
        line = outcar.readline()
        if "ions per type" in line:
            break
    atypes = map(int, line.split("=")[1].split())

    #Grab basis vectors
    while True:
        line = outcar.readline()
        if "direct lattice vectors" in line:
            break
    basis = array(
        [map(float,
             outcar.readline().split()[:3]) for i in range(3)])
    lengths = array([basis[0][0], basis[1][1], basis[2][2]])

    #Grab atom positions and perform adf calculation
    count = 0
    posit = False
    for line in outcar:
        if posit:
            if "--" in line:
                if len(atoms) == 0:
                    continue
                else:
                    #Analysis
                    if max(zip(*atoms)[0]) < 1.01:
                        atoms = dot(array(atoms), basis)
                    else:
                        atoms = array(atoms)
                    neighbs = voronoiNeighbors(atoms,
                                               basis,
                                               atypes,
                                               style='full')
                    if bl != -1 and bw != -1:
                        specbonds = [list() for i in range(len(atoms))]
                        for i in range(len(atoms)):
                            ai = atoms[i]  #dot(atoms[i],basis)
                            for j in neighbs[i]:
                                aj = atoms[j]  #dot(atoms[j],basis)
                                d = dist_periodic(ai, aj, lengths)

                                if fabs(d - bl) < bw:
                                    if d < 1.0:
                                        print d
                                        print dist_periodic(ai, aj, lengths)
                                        print ai
                                        print aj
                                        exit(0)
                                    specbonds[i].append(j)
                    else:
                        specbonds = neighbs
                    [angs, abins] = adf(atoms, specbonds, basis, nbins=nbins)
                    tbinvals.append(abins)
                    print count
                    posit = False
            else:
                atoms.append(map(float, line.split()[:3]))
        elif "POSITION" in line:
            atoms = list()
            posit = True
            count += 1

    return angs, tbinvals
예제 #14
0
def elfcarNeighborAnalysis(elfcarfile,verbose=False,minELF=0.5,maxBondLength=4.0):
    #Loads up an ELFCAR, generates a starting neighbor list from voronoi tesselation
    #Initial neighbors are dropped if bondlength is greater than maxBondLength
    #Generates a bunch of points on a cylinder
    #Maps the cylinder points across each neighbor pair
    #If the average ELF is always above minELF accross this cylinder, atoms are bonded.

    #Parse ELFCAR
    elfcar=open(elfcarfile,"r").readlines()
    (basis,atypes,atoms,header),elf = elfcarIO.read(elfcar)
    lengths=array([basis[0][0],basis[1][1],basis[2][2]])

    #Neighbors
    bounds=[[0,basis[0][0]],[0,basis[1][1]],[0,basis[2][2]]]
    halfNeighbs = voronoiNeighbors(atoms,basis,style="half")

    a=elf.shape
    AvgElf=sum([sum([sum(line) for line in plane]) for plane in elf])/a[0]/a[1]/a[2]
    if verbose:
        print elfcarfile
        print "Average ELF value:",AvgElf

    #Evaluate the ELF between each nieghbor pair
    #creates a bunch of points on a circle in the x-y plane
    def circlePoints(center,radius):
        N=4
        ps=[float(p)/N*radius for p in range(-N,N+1)]
        r2=radius*radius
        points=list()
        for x in ps:
            for y in ps:
                if (x**2+y**2)<=r2:
                    points.append(asarray([x,y]))
        return asarray(points)

    atoms=asarray([lengths[i]-v for i,v in enumerate(atoms.T)]).T

    #Flip the ELF because its off, thanks a lot VASP.
    elf=elf[::-1,::-1,::-1]

    #Loop over atom pairs, generate cylinders
    cylSlices = 10   
    cylRadius = 0.7
    cirPoints = circlePoints(a,cylRadius).T
    cylPoints = [vstack([cirPoints,zeros(cirPoints.shape[1])+float(z)]) for z in range(cylSlices+1)]
    coordination=zeros(len(atoms))
    neighborsELF=[list() for i in range(len(atoms))]

    for i,ineighbs in enumerate(halfNeighbs):
        a=atoms[i]

        for j in ineighbs:
            #copy the cylinder points so you can play with them...
            localCyl=array(cylPoints)

            #Find the minimum image atom
            b=minImageAtom(a,atoms[j],basis)
            l=minImageDist(a,b,basis)

            if l>maxBondLength or l==0.0: continue

            #How to map your cylinder onto the local atom
            R=rotmatx([0,0,l],b-a)

            #Loop over each cylinder slice
            sliceParam=list()
            for cir in localCyl:
                #cir is stretched and rotated cylinder
                cir[2]/=cylSlices/l
                cir=asarray([dot(R,p)+a for p in cir.T]).T
                
                #cir2 is cir with periodic boundary conditions applied and mapped to index space
                cir2=asarray([((c/lengths[ind]*elf.shape[ind])%(elf.shape[ind]-1)) for ind,c in enumerate(cir)])            

                #Interpolation across cylinder
                z=ndimage.map_coordinates(elf,cir2)

                #Average ELF value across each slice.
                sliceParam.append(sum(z)/len(z))

            if min(sliceParam)>minELF:
                #neighbor pair is bonded, count it!
                neighborsELF[i].append(j)
                neighborsELF[j].append(i)

    return neighborsELF