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
ay=atoms[:,1] az=atoms[:,2] types=[0]*atypes[0] fig=mlab.figure(bgcolor=(1.0,1.0,1.0)) rlen=list() soft=list() s2=list() mxSoft=0 mnSoft=10 mxLen=0 mnLen=10 for i in range(nIon): s2.append(list()) for j in neighbs[i]: r=dist_periodic(atoms[i],atoms[j],lengths) #g(E,atomi) ga=occGrid[i][uBounds] gb=occGrid[j][uBounds] #soft.append(sum(ga*gb)/d/delU*2) soft.append(sum(ga+gb)/delU) s2[-1].append(sum(ga+gb)/delU) mxSoft=max(mxSoft,soft[-1]) mnSoft=min(mnSoft,soft[-1]) rlen.append(r) if r<3.2: mxLen=max(mxLen,rlen[-1]) mnLen=min(mnLen,rlen[-1]) mnSoft,mxSoft=0.15,4.0 mnLen,mxLen = 2.40,2.9
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
ay = atoms[:, 1] az = atoms[:, 2] types = [0] * atypes[0] fig = mlab.figure(bgcolor=(1.0, 1.0, 1.0)) rlen = list() soft = list() s2 = list() mxSoft = 0 mnSoft = 10 mxLen = 0 mnLen = 10 for i in range(nIon): s2.append(list()) for j in neighbs[i]: r = dist_periodic(atoms[i], atoms[j], lengths) #g(E,atomi) ga = occGrid[i][uBounds] gb = occGrid[j][uBounds] #soft.append(sum(ga*gb)/d/delU*2) soft.append(sum(ga + gb) / delU) s2[-1].append(sum(ga + gb) / delU) mxSoft = max(mxSoft, soft[-1]) mnSoft = min(mnSoft, soft[-1]) rlen.append(r) if r < 3.2: mxLen = max(mxLen, rlen[-1]) mnLen = min(mnLen, rlen[-1]) mnSoft, mxSoft = 0.15, 4.0 mnLen, mxLen = 2.40, 2.9
def fieldNeighbors1D(atoms,atypes,basis,field,halfNeighbors=None,Ninterp=50): [v1,v2,v3]=basis latoms=array(atoms) #Ensure simulation box is orthorhombic if sum(map(fabs,v1))-fabs(v1[0]) > 1e-10 or \ sum(map(fabs,v2))-fabs(v2[1]) > 1e-10 or \ sum(map(fabs,v3))-fabs(v3[2]) > 1e-10: print "Error: simulation axes are not sufficiently orthogonal. Use script poscarRectify.py and regenerate doscar" exit(0) bounds=[[0.,v1[0]],[0.,v2[1]],[0.,v3[2]]] simSize=asarray([v1[0],v2[1],v3[2]]) if halfNeighbors==None: halfNeighbors=voronoiNeighbors(atoms=latoms,basis=basis,atypes=atypes,style='half') #Interpolation and summation properties xlines=list() ylines=list() avgyline=zeros(Ninterp) nlines=float(sum(map(len,halfNeighbors))) #Local Grid size fieldSize=elf.size delGrids=simSize/fieldSize lGridSize=fieldSize nlGridPoints=reduce(operator.mul,lGridSize) for iNeighb,jNeighbors in enumerate(halfNeighbors): xlines.append(list()) ylines.append(list()) if len(jNeighbors)==0: continue atomi=latoms[iNeighb] for i,ai in enumerate(atomi): if ai < 0.0: atomi[i]+=simSize[i] if ai > simSize[i]: atomi[i]-=simSize[i] lGridCenter = map(int,atomi/simSize*fieldSize) lGridBounds = [[lGridCenter[i]-lGridSize[i]/2,lGridCenter[i]+lGridSize[i]/2] for i in range(3)] lGridBoundPoints = array([[lGridBounds[i][0]*delGrids[i],lGridBounds[i][1]*delGrids[i]] for i in range(3)]) lGridPoints = array([map(lambda x: x*delGrids[i],range(lGridCenter[i]-lGridSize[i]/2,lGridCenter[i]+lGridSize[i]/2)) for i in range(3)]) #Stitch together field in local field (lfield) to enforce periodicity, use bounds to simplify bnds=list() lbnds=list() bnds.append(list(lGridBounds)) lbnds.append(map(list,zip([0,0,0],lGridSize))) while outOfBounds(bnds,fieldSize): a=whichBounds(bnds,fieldSize) bnds.append(map(list,bnds[a])) lbnds.append(map(list,lbnds[a])) for i in range(3): if bnds[-1][i][1] > fieldSize[i]: lbnds[a][i][1] = lGridSize[i]-(bnds[-1][i][1]-fieldSize[i]) lbnds[-1][i][0] = lGridSize[i]-(bnds[-1][i][1]-fieldSize[i]) lbnds[-1][i][1] = lbnds[-1][i][0]+(bnds[-1][i][1]-fieldSize[i]) bnds[-1][i][0] = 0 bnds[-1][i][1] -= fieldSize[i] bnds[a][i][1] = fieldSize[i] break elif bnds[-1][i][0] < 0: lbnds[-1][i][0] = 0 lbnds[-1][i][1] = -bnds[-1][i][0] lbnds[a][i][0] = -bnds[-1][i][0] bnds[-1][i][1] = fieldSize[i] bnds[-1][i][0] += fieldSize[i] bnds[a][i][0] = 0 break lfield=zeros(lGridSize) for lbnd,bnd in zip(lbnds,bnds): [[lxa,lxb],[lya,lyb],[lza,lzb]]=lbnd [[xa,xb],[ya,yb],[za,zb]]=bnd lfield[lxa:lxb, lya:lyb, lza:lzb]=field[xa:xb, ya:yb, za:zb] #Loop over Neighboring atoms within the local grid for jNeighb in jNeighbors: xlines[-1].append(zeros([Ninterp])) ylines[-1].append(zeros([Ninterp])) atomj=latoms[jNeighb] for i,aj in enumerate(atomj): if aj < lGridPoints[i][0]: atomj[i]+=simSize[i] if aj > lGridPoints[i][-1]: atomj[i]-=simSize[i] #Error detection if atomj[0]>lGridPoints[0][-1] or atomj[1]>lGridPoints[1][-1] or atomj[2]>lGridPoints[2][-1] or \ atomj[0]<lGridPoints[0][0] or atomj[1]<lGridPoints[1][0] or atomj[2]<lGridPoints[2][0]: d=dist_periodic(atomi,atomj,array(zip([0,0,0],simSize))) if d>7.5: continue print "="*50 print "Start Error Report:" print "AtomI(%d):"%iNeighb,atomi print "AtomJ(%d):"%jNeighb,atomj print "Distance:",dist_periodic(atomi,atomj,array(zip([0,0,0],simSize))) print "GridX Min,Max:","% 5.5f % 5.5f"%(min(lGridPoints[0]),max(lGridPoints[0])) print "GridY Min,Max:","% 5.5f % 5.5f"%(min(lGridPoints[1]),max(lGridPoints[1])) print "GridZ Min,Max:","% 5.5f % 5.5f"%(min(lGridPoints[2]),max(lGridPoints[2])) print "Error: AtomJ seems to be lying outside the local grid, which should not be possible." exit(0) #This is where the magic happens, finally do some computing... #Interpolate on local FIELD grid between these two atoms 75% of time spent here pnts2interp=linePoints(atomi,atomj,Ninterp) yys=array([interp3d(i,lGridBoundPoints,lGridPoints,lfield) for i in pnts2interp]) xwid=dist(pnts2interp[0],pnts2interp[-1]) xdel=xwid/Ninterp xxs=[xdel*x-xwid/2 for x in range(Ninterp)] xlines[-1][-1]=xxs ylines[-1][-1]=yys avgyline+=yys avgyline/=nlines return avgyline,xlines,ylines,halfNeighbors