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 """
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)
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"]
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)
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)
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
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()
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
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
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))
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()
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
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
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