def findmin(M,B,run): #normal routine for varying a single element at a time. '''Finds minimum cost for the lattice by varying the integers of m, in the element that gives steepest descent The 'run' indicates the cost function to use''' maxsteps = 10000 istep = 1 M = minkM(M,B)#;print'Mink reduced M'; print M while istep<maxsteps: # sys.exit('stop') bestindex = changewhich(M,B,run) if bestindex[2]==0:#found minimum # newcost = cost(M,B,run) break else: M[bestindex[0],bestindex[1]] += bestindex[2] # newcost = cost(M,B,run) if run == 'minsvsym' and B.Nmesh/float(det(M))>1.2: M = M*2 # open up search space when when det(M) gets too low # print; print M;print newcost istep += 1 if istep < maxsteps: # print 'Found minimum after %i steps' % istep # print 'Best M'; print M K = lattice();K.vecs = trimSmall(dot(B.vecs,inv(M)));K.det = abs(det(K.vecs)); K.Nmesh = B.det/K.det else: print 'Ended without minimum after maximum %i steps' % istep sys.exit('Stop') return [trimSmall(M),K]
def findmin_i(M,B,iop): '''Finds minimum cost for the lattice by varying the integers of m, in the element that gives steepest descent The 'run' indicates the cost function to use''' maxsteps = 200 istep = 1 # print 'M in findmin'; print M while istep<maxsteps: bestindex = changewhich_i(M,B,iop) # print 'bestindex',bestindex if bestindex[2]==0:#found minimum newcost = costi(M,B,iop) # print 'newcost',newcost break else: M[bestindex[0],bestindex[1]] += bestindex[2] # print 'M altered in findmin_i';print M newcost = costi(M,B,iop) # print; print M;print newcost istep += 1 if istep < maxsteps: 'go on' # print 'Found minimum after %i steps' % istep # print 'Best M'; print M else: print 'Ended without minimum after %i steps' % istep # sys.exit('Stop') return trimSmall(M)
def findmin_i(M, B, iop): '''Finds minimum cost for the lattice by varying the integers of m, in the element that gives steepest descent The 'run' indicates the cost function to use''' maxsteps = 200 istep = 1 # print 'M in findmin'; print M while istep < maxsteps: bestindex = changewhich_i(M, B, iop) # print 'bestindex',bestindex if bestindex[2] == 0: #found minimum newcost = costi(M, B, iop) # print 'newcost',newcost break else: M[bestindex[0], bestindex[1]] += bestindex[2] # print 'M altered in findmin_i';print M newcost = costi(M, B, iop) # print; print M;print newcost istep += 1 if istep < maxsteps: 'go on' # print 'Found minimum after %i steps' % istep # print 'Best M'; print M else: print 'Ended without minimum after %i steps' % istep # sys.exit('Stop') return trimSmall(M)
def findmin_i(M, B, iop): '''Finds minimum cost for the lattice by varying the integers of m, in the element that gives steepest descent The 'run' indicates the cost function to use''' maxsteps = 200 istep = 1 # print 'M in findmin'; print M while istep < maxsteps: bestindex = changewhich_i(M, B, iop) # print 'bestindex',bestindex if bestindex[2] == 0: #found minimum newcost = costi(M, B, iop) # print 'newcost',newcost break else: # print 'M before change';print M # print bestindex[0],bestindex[1] M[bestindex[0], bestindex[1]] += bestindex[2] print 'M altered in findmin_i' print M newcost = costi(M, B, iop) # print; print M;print newcost istep += 1 if istep < maxsteps: 'go on' # print 'Found minimum after %i steps' % istep # print 'Best M'; print M else: print 'Ended without minimum after %i steps' % istep # print 'Restart with different M' # a = B.Nmesh**(1/3.0); c = 3; # M = array([[-a+5, a/c , a/c],[a/c,-a,a/c],[a/c,a/c,-a-5]]) # sys.exit('Stop') return trimSmall(M)
def findmin_i(M,B,iop): '''Finds minimum cost for the lattice by varying the integers of m, in the element that gives steepest descent The 'run' indicates the cost function to use''' maxsteps = 200 istep = 1 # print 'M in findmin'; print M while istep<maxsteps: bestindex = changewhich_i(M,B,iop) # print 'bestindex',bestindex if bestindex[2]==0:#found minimum newcost = costi(M,B,iop) # print 'newcost',newcost break else: # print 'M before change';print M # print bestindex[0],bestindex[1] M[bestindex[0],bestindex[1]] += bestindex[2] print 'M altered in findmin_i';print M newcost = costi(M,B,iop) # print; print M;print newcost istep += 1 if istep < maxsteps: 'go on' # print 'Found minimum after %i steps' % istep # print 'Best M'; print M else: print 'Ended without minimum after %i steps' % istep # print 'Restart with different M' # a = B.Nmesh**(1/3.0); c = 3; # M = array([[-a+5, a/c , a/c],[a/c,-a,a/c],[a/c,a/c,-a-5]]) # sys.exit('Stop') return trimSmall(M)
def costi(M, B, iop): '''Here the symmetry cost is that due to only one symm operation,iop''' if det(M) < 1: return 1000 kvecs = dot(B.vecs, inv(M)) # print 'iop in costi'; print B.symops[:,:,iop] mmat = trimSmall(dot(dot(inv(kvecs), B.symops[:, :, iop]), kvecs)) # print 'mmat in costi';print mmat operr = 0.0 for i in range(3): for j in range(3): if abs(rint(mmat[i, j]) - mmat[i, j]) > 1.0e-4: operr += abs(rint(mmat[i, j]) - mmat[i, j]) # print iop, 'Symmetry failed for mmat[i,j]',mmat[i,j] # print 'Cartesian operator' # print parentlatt.symops[:,:,iop] # print 'Cartesian Lattice' # print lmat # Nscale =0*.05#.05; # Ncost = Nscale * abs((B.det/det(kvecs))-B.Nmesh)/B.Nmesh # shapescale = 0 * 0.01; shapecost = shapescale * surfvol(kvecs) cost = operr #+ Ncost + shapecost return cost
def three_perp_eigs(A): testvecs = [] testindices = [] svecs = zeros((3, 3), dtype=float) for k in range(A.nops): # print; print k op = array(A.symops[:, :, k]) [vals, vecs] = eig(op) vecs = array(vecs) #find operations with nondegenerate real eigenvalues # print k, nonDegen(vals) for i in nonDegen(vals): if not matchDirection(transpose(vecs[:, i]), testvecs): #keep only unique directions testvecs.append(real(vecs[:, i])) testindices.append([k, i]) if len(testvecs) >= 3: testvecstrials = [list(x) for x in combinations(testvecs, 3)] # print testvecstrials for trial in testvecstrials: #find superlattice for i in range(3): # print; print 'trial u',trial[i] svecs[i, :] = lattvec_u(A.vecs, trial[i]) # print svecs[i,:] # print 'lattice m for lattice vector', dot(inv(A.vecs),transpose(svecs[i,:])) # print 'cosvecs', cosvecs(svecs[0,:],svecs[1,:]) , cosvecs(svecs[1,:],svecs[2,:]) , cosvecs(svecs[2,:],svecs[0,:]) # print arenormal(svecs[0,:],svecs[1,:]) , arenormal(svecs[1,:],svecs[2,:]) , arenormal(svecs[2,:],svecs[0,:]) if arenormal(svecs[0, :], svecs[1, :]) and arenormal( svecs[1, :], svecs[2, :]) and arenormal( svecs[2, :], svecs[0, :]): S = transpose(array([svecs[0, :], svecs[1, :], svecs[2, :]])) # print 'found 3 perp'; print unique_anorms(S) # print S; print norm(S[:,0]); print norm(S[:,1]); print norm(S[:,2]) # print unique_anorms(S).count(True); print A.lattype if A.lattype == 'Cubic' and unique_anorms(S).count(True) == 0: return trimSmall(S) if A.lattype == 'Tetragonal' and unique_anorms(S).count( True) <= 1: return trimSmall(S) if A.lattype == 'Orthorhombic': #and unique_anorms(S).count(True) == 3: return trimSmall(S) sys.exit('error in three_perp_eigs')
def minkM(M,B): '''Transform to M on same lattice, but minked''' kvecs = dot(B.vecs,inv(M)) # print det(kvecs); print kvecs if det(kvecs) < 0.1: #do reduction in inverse space so we don't run into small number problems A = transpose(inv(B.vecs)) S = dot(A,transpose(M)) S = transpose(mink_reduce(transpose(S), 1e-4)) M = transpose(dot(inv(A),S)) else: kvecs = transpose(mink_reduce(transpose(kvecs), 1e-4)) #fortran routines use vectors as rows M = rint(dot(inv(kvecs),B.vecs)) return trimSmall(M)
def three_perp_eigs(A): testvecs = []; testindices = [] svecs = zeros((3,3),dtype = float) for k in range(A.nops): # print; print k op = array(A.symops[:,:,k]) [vals,vecs]=eig(op); vecs = array(vecs) #find operations with nondegenerate real eigenvalues # print k, nonDegen(vals) for i in nonDegen(vals): if not matchDirection(transpose(vecs[:,i]),testvecs): #keep only unique directions testvecs.append(real(vecs[:,i])) testindices.append([k,i]) if len(testvecs) >= 3: testvecstrials = [list(x) for x in combinations(testvecs,3)] # print testvecstrials for trial in testvecstrials: #find superlattice for i in range(3): # print; print 'trial u',trial[i] svecs[i,:] = lattvec_u(A.vecs,trial[i]) # print svecs[i,:] # print 'lattice m for lattice vector', dot(inv(A.vecs),transpose(svecs[i,:])) # print 'cosvecs', cosvecs(svecs[0,:],svecs[1,:]) , cosvecs(svecs[1,:],svecs[2,:]) , cosvecs(svecs[2,:],svecs[0,:]) # print arenormal(svecs[0,:],svecs[1,:]) , arenormal(svecs[1,:],svecs[2,:]) , arenormal(svecs[2,:],svecs[0,:]) if arenormal(svecs[0,:],svecs[1,:]) and arenormal(svecs[1,:],svecs[2,:]) and arenormal(svecs[2,:],svecs[0,:]): S = transpose(array([svecs[0,:],svecs[1,:],svecs[2,:]])) # print 'found 3 perp'; print unique_anorms(S) # print S; print norm(S[:,0]); print norm(S[:,1]); print norm(S[:,2]) # print unique_anorms(S).count(True); print A.lattype if A.lattype == 'Cubic' and unique_anorms(S).count(True) == 0: return trimSmall(S) if A.lattype == 'Tetragonal' and unique_anorms(S).count(True) <= 1: return trimSmall(S) if A.lattype == 'Orthorhombic': #and unique_anorms(S).count(True) == 3: return trimSmall(S) sys.exit('error in three_perp_eigs')
def findmin(M, B, run): #normal routine for varying a single element at a time. '''Finds minimum cost for the lattice by varying the integers of m, in the element that gives steepest descent The 'run' indicates the cost function to use''' maxsteps = 10000 istep = 1 # M = minkM(M,B)#;print'Mink reduced M'; print M while istep < maxsteps: # sys.exit('stop') bestindex = changewhich(M, B, run) # print 'bestindex',bestindex if bestindex[2] == 0: #found minimum # newcost = cost(M,B,run) break else: M[bestindex[0], bestindex[1]] += bestindex[2] # print 'M altered in findmin';print M # newcost = cost(M,B,run) # if run == 'minsvsym' and B.Nmesh/float(det(M))>1.2: M = M*2 # open up search space when when det(M) gets too low # print; print M;print newcost istep += 1 if istep < maxsteps: # print 'Found minimum after %i steps' % istep # print 'Best M'; print M K = lattice() K.vecs = trimSmall(dot(B.vecs, inv(M))) K.det = abs(det(K.vecs)) K.Nmesh = B.det / K.det else: print 'Ended without minimum after maximum %i steps' % istep sys.exit('Stop') return [trimSmall(M), K]
def minkM(M, B): '''Transform to M on same lattice, but minked''' kvecs = dot(B.vecs, inv(M)) # print det(kvecs); print kvecs if det( kvecs ) < 0.1: #do reduction in inverse space so we don't run into small number problems A = transpose(inv(B.vecs)) S = dot(A, transpose(M)) S = transpose(mink_reduce(transpose(S), 1e-4)) M = transpose(dot(inv(A), S)) else: kvecs = transpose(mink_reduce( transpose(kvecs), 1e-4)) #fortran routines use vectors as rows M = rint(dot(inv(kvecs), B.vecs)) return trimSmall(M)
def orthsuper(B): '''For lattice with orthogonal nonprimitive lattice vectors (cubic, tetragonal, orthorhombic), finds the simple orthorhombic superlattice with minimum s/v.''' # Find a set of three shortest lattice vectors that are perpendicular A = lattice() A.vecs = trimSmall(inv(transpose(B.vecs))) # print 'A'; print A.vecs # print 'det a', det(A.vecs) [A.symops, A.nops] = getGroup(A.vecs) A.lattype = latticeType(A.nops) # printops_eigs(A) # print 'transp A'; print transpose(A) S = zeros((3, 3), dtype=float) M = zeros((3, 3), dtype=int) K = zeros((3, 3), dtype=float) # S_orth = three_perp(A.vecs,B.lattype) print S_orth = three_perp_eigs(A) # sys.exit('stop') M = rint(transpose(dot(inv(A.vecs), S_orth))).astype(int) print 'M by finding 3 shortest perpendicular vectors' print M print 'det M', det(M) #starting mesh Q with 3 free directions. Q = dot(B.vecs, inv(M)) print 'mesh numbers' [n0, n1, n2] = svmesh(B.Nmesh / abs(det(M)), Q)[0] print[n0, n1, n2] K[:, 0] = Q[:, 0] / n0 K[:, 1] = Q[:, 1] / n1 K[:, 2] = Q[:, 2] / n2 # print K Nmesh = B.det / abs(det(K)) if checksymmetry(K, B): pf = packingFraction(K) print 'Packing fraction (orthmesh)', pf, 'vs original B', packingFraction( B.vecs) print 'Nmesh', Nmesh, 'vs target', B.Nmesh else: sys.exit('Symmetry failed in orthsuper') return [K, pf, True]
def unconstrainedSVsearch(B): K = lattice() K.vecs = zeros((3, 3), dtype=float) Nmesh = B.Nmesh M = zeros((3, 3), dtype=np_int) # print 'Target N kpoints', Nmesh a = rint(Nmesh ** (1 / 3.0)) c = a f = int(Nmesh / a / c) M[0, 0] = a M[1, 1] = c M[2, 2] = f print "Starting M" print M maxsteps = 1000 istep = 1 while istep < maxsteps: bestindex = changewhich(M, B) if bestindex[2] == 0: # found minimum newcost = cost(M, B) break else: M[bestindex[0], bestindex[1]] += bestindex[2] newcost = cost(M, B) istep += 1 if istep < maxsteps: print print "Found minimum after %i steps" % istep # print 'Best M'; print M K = lattice() K.vecs = trimSmall(dot(B.vecs, inv(M))) # K.det = det(K.vecs) # print 'Best K mesh\n', K.vecs # print 'Number of mesh points', B.det/K.det # print 'Minimum cost', newcost # print 'Orth defect',orthdef(K.vecs) # print 'Surface/vol', surfvol(K.vecs) # print 'Mesh vector lengths', norm(K.vecs[:,0]),norm(K.vecs[:,1]),norm(K.vecs[:,2]) else: print "Ended without minimum after maximum %i steps" % istep return [M, K.vecs]
def unconstrainedSVsearch(B): K = lattice() K.vecs = zeros((3, 3), dtype=float) Nmesh = B.Nmesh M = zeros((3, 3), dtype=np_int) # print 'Target N kpoints', Nmesh a = rint(Nmesh**(1 / 3.0)) c = a f = int(Nmesh / a / c) M[0, 0] = a M[1, 1] = c M[2, 2] = f print 'Starting M' print M maxsteps = 1000 istep = 1 while istep < maxsteps: bestindex = changewhich(M, B) if bestindex[2] == 0: #found minimum newcost = cost(M, B) break else: M[bestindex[0], bestindex[1]] += bestindex[2] newcost = cost(M, B) istep += 1 if istep < maxsteps: print print 'Found minimum after %i steps' % istep # print 'Best M'; print M K = lattice() K.vecs = trimSmall(dot(B.vecs, inv(M))) # K.det = det(K.vecs) # print 'Best K mesh\n', K.vecs # print 'Number of mesh points', B.det/K.det # print 'Minimum cost', newcost # print 'Orth defect',orthdef(K.vecs) # print 'Surface/vol', surfvol(K.vecs) # print 'Mesh vector lengths', norm(K.vecs[:,0]),norm(K.vecs[:,1]),norm(K.vecs[:,2]) else: print 'Ended without minimum after maximum %i steps' % istep return [M, K.vecs]
def orthsuper(B): '''For lattice with orthogonal nonprimitive lattice vectors (cubic, tetragonal, orthorhombic), finds the simple orthorhombic superlattice with minimum s/v.''' # Find a set of three shortest lattice vectors that are perpendicular A = lattice() A.vecs = trimSmall(inv(transpose(B.vecs))) # print 'A'; print A.vecs # print 'det a', det(A.vecs) [A.symops,A.nops] = getGroup(A.vecs) A.lattype = latticeType(A.nops) # printops_eigs(A) # print 'transp A'; print transpose(A) S = zeros((3,3),dtype = float) M = zeros((3,3),dtype = int) K = zeros((3,3),dtype = float) # S_orth = three_perp(A.vecs,B.lattype) print; S_orth = three_perp_eigs(A) # sys.exit('stop') M = rint(transpose(dot(inv(A.vecs),S_orth))).astype(int) print 'M by finding 3 shortest perpendicular vectors';print M print 'det M', det(M) #starting mesh Q with 3 free directions. Q = dot(B.vecs,inv(M)) print 'mesh numbers'; [n0,n1,n2] = svmesh(B.Nmesh/abs(det(M)),Q)[0] print [n0,n1,n2] K[:,0] = Q[:,0]/n0; K[:,1] = Q[:,1]/n1; K[:,2] = Q[:,2]/n2 # print K Nmesh = B.det/abs(det(K)) if checksymmetry(K,B): pf = packingFraction(K) print 'Packing fraction (orthmesh)', pf, 'vs original B', packingFraction(B.vecs) print 'Nmesh', Nmesh, 'vs target', B.Nmesh else: sys.exit('Symmetry failed in orthsuper') return [K,pf,True]
def costi(M,B,iop): '''Here the symmetry cost is that due to only one symm operation,iop''' if det(M)<1: return 1000 kvecs = dot(B.vecs,inv(M)) # print 'iop in costi'; print B.symops[:,:,iop] mmat = trimSmall(dot(dot(inv(kvecs),B.symops[:,:,iop]),kvecs)) # print 'mmat in costi';print mmat operr = 0.0 for i in range(3): for j in range(3): if abs(rint(mmat[i,j])-mmat[i,j])>1.0e-4: operr += abs(rint(mmat[i,j])-mmat[i,j]) # print iop, 'Symmetry failed for mmat[i,j]',mmat[i,j] # print 'Cartesian operator' # print parentlatt.symops[:,:,iop] # print 'Cartesian Lattice' # print lmat Nscale =0*.05#.05; Ncost = Nscale * abs((B.det/det(kvecs))-B.Nmesh)/B.Nmesh shapescale = 0 * 0.01; shapecost = shapescale * surfvol(kvecs) cost = operr + Ncost + shapecost return cost
def bestmeshIter_vary_pf(Blatt,Nmesh,path): '''The kmesh can be related to the reciprocal lattice B by B = KM, where M is an integer 3x3 matrix So K = B Inv(M). Change M one element at a time to minimize the errors in symmetry and the cost in S/V and Nmesh ''' ############################################################## ########################## Script ############################ # print path.split('/') npathsegs = len(path.split('/')) # print npathsegs vaspinputdir = '/'.join(path.split('/')[0:npathsegs-3])+'/vaspinput/' #up two levels, 2 are for spaces at beg and end # print vaspinputdir M = zeros((3,3),dtype = int) S = zeros((3,3),dtype = fprec) B = lattice() A = lattice() K = lattice() status = '' pf_minsv = 0; pf_sv2fcc = 0; pf_maxpf = 0; pf_pf2fcc = 0; #kvecs_pf2fcc = identity(3) sym_maxpf = False; sym_sv2fcc = False; sym_minsv = False; sym_pf2fcc = False print 'Target mesh number', Nmesh B.vecs = Blatt/2/pi #Don't use 2pi constants in reciprocal lattice here # B.pftarget = 0.7405 #default best packing fraction #############End BCT lattice eps = 1.0e-6 B.Nmesh = Nmesh print 'B vectors (differ by 2pi from traditional)';print B.vecs # #print 'B transpose'; print transpose(B.vecs) B.det = det(B.vecs) print 'Det of B', B.det print 'Orth Defect of B', orthdef(B.vecs) print 'Surf/vol of B', surfvol(B.vecs) pfB = packingFraction(B.vecs) print 'Packing fraction of B:', pfB [B.symops,B.nops] = getGroup(B.vecs) B.msymops = intsymops(B) #integer sym operations in B basis # print'Symmetry operators in basis of B' # for i in range: # print B.msymops[:,:,i];print # printops_eigs(B) B.lattype = latticeType(B.nops) print 'Lattice type:', B.lattype A = lattice() A.vecs = trimSmall(inv(transpose(B.vecs))) [A.symops,A.nops] = getGroup(A.vecs) A.msymops = intsymops(A) print 'Real space lattice A'; print A.vecs print 'Det A', det(A.vecs) pfA = packingFraction(A.vecs) print 'Packing fraction of A:', pfA # print 'current dir for meshesfile', os.getcwd() meshesfile = open('meshesfile','w') # meshesfile = open('meshesfile2','w') meshesfile.write('N target %i\n' % B.Nmesh) meshesfile.write('Format: pf then Nmesh then kmesh\n\n') pflist = [] # for pftry in frange(pfB/2,0.75,0.005): for pftry in frange(pfB/2,0.75,0.01): # for pftry in frange(.3,0.505,0.005): print '\nPacking fraction target',pftry B.pftarget = pftry pf_orth=0; pf_orth2fcc=0; sym_orth = False; sym_orth2fcc = False #'--------------------------------------------------------------------------------------------------------' #'--------------------------------------------------------------------------------------------------------' M = zeros((3,3),dtype=int) ctest = [] type = 'maxpfsym'; print type ctrials = [3] a = rint(Nmesh**(1/3.0));# f = int(Nmesh/a/a) randnums = zeros(9) print 'M scale a',a for c in ctrials: # ri = [randint(5) for i in range(9)] # M = array([[-a+ri[0], a/c +ri[1] , a/c+ri[2]],[a/c+ri[3],-a+ri[4],a/c+ri[5]],\ # [a/c+ri[6],a/c+ri[7],-a+ri[8]]]) #bcc like best avg pf on 50: 0.66 #HNF:::::: M = array([[a, 0 , 0], [a/c,a,0],\ [a/c,a/c,a]]) #bcc like best avg pf on 50: 0.66 # # M = array([[-a+1, a/c , a/c],[a/c,-a,a/c],[a/c,a/c,-a-1]]) #bcc like best avg pf on 50: 0.66 # M = array([[a, 0,0],[0,a,0],[0,0,a+3]]) # M = array([[-16 , 1 , 5 ], # [6 , -10 , 5], # [-6 , -1 , 6 ]]) # M = array([[5, a/c , a/c],[a/c,0,a/c],[a/c,a/c,-5]]) #fcc like best avg pf on 50: 0.59 M = rint(M * (B.Nmesh/abs(det(M)))**(1/3.0)) print 'Start mesh trial'; print M # [M,K] = findmin(M,B,type) # print 'Test trial M'; print M ctest.append(cost(M,B,type)) # print'Trial costs',ctest cbest = ctrials[argmin(ctest)] # print'Best c', cbest iternpf = 0 itermaxnpf = 10 itermaxsym = 5 # bestpf = 100 # NPFcost = 100;delNPFcost = -1 #initial values type = 'maxpfsym'; print type delcost = -1; lowcost = 1000 #initialize #### while iternpf<itermaxnpf and delNPFcost <0 and abs(delNPFcost)>0.1 : while iternpf<itermaxnpf and delcost < -0.1: oldcost = cost(M,B,type) # NPFcost = cost(M,B,'maxpf') # delNPFcost = (NPFcost-oldNPFcost)/NPFcost : '''Here we let M vary in the search, but record pf and kvecs when we find min cost''' # print 'cost(N,PF):', cost(M,B,type) # while not symm and and iternpf<itermax: M = rint(M * (B.Nmesh/abs(det(M)))**(1/3.0)) print 'Scaled M';print M iternpf += 1 print 'Iteration',type,iternpf, '**********' [M,K] = findmin(M,B,type) M = rint(M) itersym = 0 symm = False while not symm and itersym <itermaxsym: itersym += 1 print 'Symmetry iteration', itersym, '-------' # print 'Nmesh', abs(det(M)), 'packing', packingFraction(dot(B.vecs,inv(M))) # M = rint(minkM(M,B))#; print'Mink reduced M'; print M for iop in range(B.nops): M = rint(findmin_i(M,B,iop)) # M = rint(minkM(M,B))#; print'Mink reduced M'; print M if abs(det(M)-B.Nmesh)/B.Nmesh > 0.15: #how far off from target N M = rint(M * (B.Nmesh/abs(det(M)))**(1/3.0)) print 'Scaled M';print M K = lattice();K.vecs = trimSmall(dot(B.vecs,inv(M)));K.det = abs(det(K.vecs)); K.Nmesh = B.det/K.det symm = checksymmetry(K.vecs,B) print 'Symmetry check', symm if symm: newcost = cost(M,B,type) if newcost - lowcost < 0: lowcost = newcost; print'New lowcost',newcost pf_maxpf = packingFraction(K.vecs) sym_maxpf = True kvecs_maxpf = K.vecs # if pf_maxpf<bestpf: bestpf = pf_maxpf; bestM = M print 'Packing fraction', pf_maxpf, 'vs original B', pfB print 'Nmesh', K.Nmesh, 'vs target', B.Nmesh delcost = cost(M,B,type) - oldcost #write to files # meshesfile.write('Packing fraction target %f\n' % pftry) if symm and pf_maxpf not in pflist: pflist.append(pf_maxpf) # meshesfile.write('Packing fraction achieved %f\n' % pf_maxpf) meshesfile.write('%12.8f %8.3f \n' % (pf_maxpf,K.Nmesh)) # meshesfile.write('M\n') # for i in range(3): # for j in range(3): # meshesfile.write('%i6' %M[i,j]) # meshesfile.write('\n') ## meshesfile.write('\n') # meshesfile.write('k mesh\n') M = rint(dot(inv(K.vecs),B.vecs)) for i in range(3): for j in range(3): meshesfile.write('%i ' % int(rint(M[i,j]))) meshesfile.write('\n') meshesfile.write('\n') meshesfile.flush() M = rint(dot(inv(K.vecs),B.vecs)) #We assign K only when M is ideal, so remake the best M print 'Check M' print M print 'Check K' print K.vecs print 'Check B' print B.vecs print 'Check pf' print packingFraction(K.vecs) #create a dir and prepare for vasp run newdir = str(round(pf_maxpf,4)) newpath = path + newdir + '/' if not os.path.isdir(newpath): os.system('mkdir %s' % newpath) os.chdir(newpath) os.system ('cp %s* %s' % (vaspinputdir,newpath)) os.system ('cp %sPOSCAR %s' % (path,newpath)) print 'SKIPPING writekpts_vasp_M AND submission' # writekpts_vasp_M(newpath,B,M,K) # writekpts_vasp_pf(newpath,K.vecs,pf_maxpf,K.Nmesh) writejobfile(newpath) # subprocess.call(['sbatch', 'vaspjob']) #!!!!!!! Submit jobs os.chdir(path) else: 'do nothing' # meshesfile.write('Failed symmetry\n\n') meshesfile.close() # Summary pfs = [pfB] pftypes = ['B_latt'] ks = [B.vecs/a] #one solutions is to simply divide B by an integer if not (sym_minsv or sym_sv2fcc or sym_maxpf or pf_pf2fcc or sym_orth or sym_orth2fcc): meshtype = 'B_latt_revert' ; #status += 'MHPrevert;' K.vecs = B.vecs/a; K.det = abs(det(K.vecs)); K.Nmesh = abs(B.det/K.det) pfmax = packingFraction(K.vecs) else: if sym_orth: pfs.append(pf_orth) pftypes.append('orth') ks.append(kvecs_orth) if sym_orth2fcc: pfs.append(pf_orth2fcc) pftypes.append('orth2fcc') ks.append(kvecs_orth2fcc) if sym_maxpf: pfs.append(pf_maxpf) pftypes.append('maxpf') ks.append(kvecs_maxpf) if sym_pf2fcc: pfs.append(pf_pf2fcc) pftypes.append('pf2fcc') ks.append(kvecs_pf2fcc) pfmax = max(pfs) meshtype = pftypes[argmax(pfs)] K.vecs = ks[argmax(pfs)]; K.det = abs(det(K.vecs)); K.Nmesh = B.det/K.det # return [K.vecs, K.Nmesh, B.Nmesh, B.lattype, pfB, pf_orth, pf_orth2fcc, pf_maxpf, pf_minsv, pf_sv2fcc, pfmax, meshtype, fcctype(B),status] return [K.vecs, K.Nmesh, B.Nmesh, B.lattype, pfB, pf_orth, pf_orth2fcc, pf_maxpf, pf_pf2fcc, pfmax, meshtype, fcctype(B),cbest,status]
B.Nmesh = Nmesh print 'B vectors';print B.vecs print 'B transpose'; print transpose(B.vecs) print 'Det of B', B.det print 'Orth Defect of B', orthdef(B.vecs) print 'Surf/vol of B', surfvol(B.vecs) [B.symops,B.nops] = getGroup(B.vecs) print 'Number of symmetry operations', B.nops #print 'symmetry operations of B\n' #for j in range(nopsB): # print j # op = matrix(symopsB[:,:,j]) # print op #find real lattice A.vecs = trimSmall(transpose(inv(B.vecs))) A.det = det(A.vecs) A.Nmesh = Nmesh print 'A vectors';print A.vecs print 'Det of A', A.det print 'Orth Defect of A', orthdef(A.vecs) print 'Surf/vol of A', surfvol(A.vecs) [A.symops,A.nops] = getGroup(A.vecs) if A.nops != B.nops: sys.exit('Number of operations different for A and B; stop') print 'symmetry operations R of A\n' testvecs = [];oplist = [] for k in range(A.nops): print; print k
scaleposcar(scale) #inserts length scale into appropriate spot. writefile([str(dL)], finalDir + dir + 'detL') writefile([lattype], finalDir + dir + 'lattype') os.system('cp %s* %s' % (vaspinputdir, '.')) os.system('rm slurm*') n = m * dL shift = '0.00' if meshtype == 'cub': M = n * transpose(inv(A)) print 'M matrix for cubic mesh' print M print 'det M (kpoints in unreduced 1BZ)', det(M) writekpts_cubic_n(n, shift) if meshtype == 'fcc': M = trimSmall(n * dot(bccsq, transpose(inv(L)))) print 'test K' print trimSmall(dot(B, inv(M))) # print 'test Bo';print transpose(inv(platt)) print 'M matrix for fcc mesh' print M print 'det M (kpoints in unreduced 1BZ)', det(M) writekpts_fcc_n(n, shift) writefile([str(abs(det(M)))], finalDir + dir + 'detM') # writekpts_vasp_M(finalDir+dir,B,M,Bnops,Bsymops) #define K's explicitly!!! writejobfile(finalDir + dir) if n <= nmax: #(don't submit the biggest jobs ''
def enerGrad(self, indComps): '''restrict the energy sum to the pairs that contain independent points''' # print 'oldindvecs',self.oldindVecs indVecs = indComps.reshape((self.nIndIn, 3)) self.oldindVecs = indVecs #update all positions by symmetry and translation self.oldPoints = deepcopy(self.points) self.updatePoints(indVecs) #indVecs now cannot be used for current points because they might be out of cell. # print 'movement' # for i in range(self.npoints): # # print 'old',i,self.oldPoints[i]['pos'] # # print 'new',i,self.points[i]['pos'] # # print # move = norm(self.points[i]['pos']-self.oldPoints[i]['pos']) # if move > 1e-6 : # print i,move ener = 0.0 self.power = 2.0 # scale = 1 for ipos in range(self.nIndIn): force = zeros(3) rs = zeros(self.npoints, dtype=[('r', 'float'), ('rij', '3float'), ('force', '3float')]) nearest = -1 rnearest = 100.0 for jpos in range(self.npoints): rij = self.points[jpos]['pos'] - self.points[ipos]['pos'] r = norm([rij]) if r > 1e-4 * self.rmin: if r < rnearest: nearest = jpos rnearest = r # # epair = r**2 #attractive springs...dumb because those farthest away influence most # force += rij #attractive springs) epair = (self.ravg / r)**self.power forcepair = -self.power * epair / r * rij / r force += forcepair # print 'jpos',jpos,r,forcepair ener += epair rs[jpos]['r'] = r rs[jpos]['rij'] = rij rs[jpos]['force'] = forcepair self.points[ipos]['force'] = trimSmall(force) if ipos in self.indIn: rs = sort(rs, order='r') # print ipos, rs[:20]['r'] # print rs[:20]['rij'] print ipos, 'pos', self.points[ipos]['pos'] print 'nerst', self.points[nearest]['pos'], nearest, rnearest print 'vectr', trimSmall(self.points[nearest]['pos'] - self.points[ipos]['pos']) print 'force', ipos, self.points[ipos]['force'] ener = ener / self.nIndIn grad = -self.points[:self.nIndIn]['force'].flatten() / self.nIndIn print 'energy:', self.count, ener print # if self.count == 19: # self.plotPoints(self.points,'pos') self.count += 1 #now update all the dependent positions # ! Note: need to update the positions at each step! Do we have to get inside # return ener# return ener, grad
def bestmeshEigen(Blatt,Nmesh): '''The kmesh can be related to the reciprocal lattice B by B = KM, where M is an integer 3x3 matrix So K = B Inv(M) . Work in the inverse space of this problem, where we can work with M instead of Inv(M). T(InvK) = T(InvB)T(M). Define S = T(InvK), and the real lattice A = T(InvB). So S = A T(M) is a superlattice on the real lattice. Minimization scheme''' ############################################################## ########################## Script ############################ M = zeros((3,3),dtype = int) S = zeros((3,3),dtype = fprec) B = lattice() A = lattice() K = lattice() B.vecs = Blatt/2/pi #Don't use 2pi constants in RL here. #############End BCT lattice eps = 1.0e-6 B.det = det(B.vecs) B.Nmesh = Nmesh print 'B vectors';print B.vecs # #print 'B transpose'; print transpose(B.vecs) print 'Det of B', B.det print 'Orth Defect of B', orthdef(B.vecs) print 'Surf/vol of B', surfvol(B.vecs) [B.symops,B.nops] = getGroup(B.vecs) print 'Number of symmetry operations', B.nops eigendirs = zeros([3,3,B.nops],dtype = int) #print 'symmetry operations of B\n' #for j in range(nopsB): # print j # op = array(symopsB[:,:,j]) # print op #find real lattice A.vecs = transpose(inv(B.vecs)) A.det = det(A.vecs) A.Nmesh = Nmesh print;print 'A vectors';print A.vecs print 'Det of A', A.det print 'Orth Defect of A', orthdef(A.vecs) print 'Surf/vol of A', surfvol(A.vecs) [A.symops,A.nops] = getGroup(A.vecs) if A.nops != B.nops: sys.exit('Number of operations different for A and B; stop') testvecs = [];testindices = [] # print 'symmetry operations R of A\n' for k in range(A.nops): print print k op = array(A.symops[:,:,k]) print'symop R of A'; print trimSmall(op) m = trimSmall(dot(dot(inv(A.vecs), A.symops[:,:,k]),A.vecs)) print'symop m'; print m # print 'det(m)', det(m) 'Take eigenvectors in cartesian space' [vals,vecs]=eig(op) print 'eigen of m',vals print 'eigenvecs are calculated in cartesian space'; print vecs #transform to m space for i in range(3): vecs[:,i] = dot(inv(A.vecs),vecs[:,i]) print 'eigenvecs in m space'; print vecs print 'scaled to integers' for i in range(3): vecs[:,i] = vecs[:,i]/abs(vecs[:,i])[nonzero(vecs[:,i])].min() vecs = rint(vecs) print vecs eigendirs[:,:,k]= vecs #find operations with nondegenerate real eigenvalues print 'nonDegen', nonDegen(vals) for i in nonDegen(vals): if not matchDirection(transpose(vecs[:,i]),testvecs): #keep only unique directions testvecs.append(vecs[:,i].real/abs(vecs[:,i])[nonzero(vecs[:,i])].min()) testindices.append([k,i]) #print; print oplist; print 'testvecs'; print testvecs #print testindices MT = zeros((3,3),dtype = fprec) if len(testvecs) == 0: print 'No eigen directions' [M,K.vecs] = unconstrainedSVsearch(B) if det(K.vecs)==0: sys.exit('Det(K) is zero after unconstrained search! Stop') if not checksymmetry(K.vecs,B): sys.exit('Symmetry missing in mesh! Stop') # MT = unconstrainedmin(B.vecs) if len(testvecs) == 1: print 'Only 1 eigen direction' #Choose this one and the other two in the plane perpendicular to this. MT[:,0] = testvecs[0] # print 'testindices',testindices kop = testindices[0][0] #useful operator ieigen = testindices[0][1] #index of the only eigendirection op = array(A.symops[:,:,kop]) # print trimSmall(op) # find one other direction in the plane perp to the eigendireation; either degenerate eigenvalue will do. otherindices = nonzero(array([0,1,2])-ieigen) print eigendirs[:,:,otherindices[0][0]] MT[:,1] = eigendirs[:,:,kop][:,otherindices[0][0]] #Make 3rd vector perp as possible to the other two ur0 = dot(A.vecs,MT[:,0])/norm(dot(A.vecs,MT[:,0])) #unit vectors in real space ur1 = dot(A.vecs,MT[:,1])/norm(dot(A.vecs,MT[:,1])) ur2 = cross(ur0,ur1) print ur0 print ur1 print ur2 print 'ur2 transformed to m space'; print dot(inv(A.vecs),ur2) mvec = dot(inv(A.vecs),ur2) #transformed to M space, but real mvec = rint(mvec/abs(mvec[nonzero(mvec)]).min()) #Scale so smallest comp is 1 MT[:,2] = mvec print 'MT from single operator';print MT print 'starting superlattice'; print dot(A.vecs,MT) # Q2 = MT2mesh_three_ns(MT,B) Q2 = MT2mesh(MT,B,A) if checksymmetry(Q2,B): SV = surfvol(Q2) # print round(surfvol(Q2),4),round(orthdef(Q2),4),'SV of Q2,','OD' K.vecs = Q2 else: print'Q from single operator fails symmetry' if len(testvecs) == 2: print 'Only 2 eigen directions' MT[:,0] = testvecs[0] MT[:,1] = testvecs[1] #Make 3rd vector perp as possible to the other two ur0 = dot(A.vecs,MT[:,0])/norm(dot(A.vecs,MT[:,0])) #unit vector in real space ur1 = dot(A.vecs,MT[:,1])/norm(dot(A.vecs,MT[:,1])) ur2 = cross(ur0,ur1) MT[:,2] = rint(dot(inv(A.vecs),ur2)) print 'MT from two eigen directions';print MT # Q2 = MT2mesh_three_ns(MT,B) Q2 = MT2mesh(MT,B) if checksymmetry(Q2,B): SV = surfvol(Q2) print round(surfvol(Q2),4),round(orthdef(Q2),4),'SV of Q2,','OD' K.vecs = Q2 else: print'Q fails symmetry' if len(testvecs) >= 3: print 'MT from three eigen directions' testvecstrials = [list(x) for x in combinations(testvecs,3)] print testvecstrials bestindex = -1 bestcost = 1000 for i,vecs in enumerate(testvecstrials): print; print 'trial',i print vecs MT[:,0] = vecs[0] MT[:,1] = vecs[1] MT[:,2] = vecs[2] print 'MT'; print MT print 'det MT', det(MT) if not areEqual(det(MT),0): Q2 = MT2mesh(MT,B) if checksymmetry(Q2,B): Nscale =1*.8; Ncost = Nscale * abs((B.det/det(Q2))-B.Nmesh)/B.Nmesh cost = surfvol(Q2)*(1+Ncost) print cost if cost<bestcost: bestcost = cost; bestindex = i; K.vecs = Q2 print round(surfvol(Q2),4),round(orthdef(Q2),4),'SV of Q2,','OD' else: print'Q from trial %i fails symmetry' % i print '___________ Best mesh ___________' print 'trial', bestindex if checksymmetry(K.vecs,B): print K.vecs K.det = abs(det(K.vecs)) print 'N of mesh', B.det/K.det SV = surfvol(K.vecs) print round(surfvol(K.vecs),4),round(orthdef(K.vecs),4),'SV of Q2,','OD' else: print'K mesh fails symmetry'
B.Nmesh = Nmesh print 'B vectors';print B.vecs #print 'B transpose'; print transpose(B.vecs) print 'Det of B', B.det print 'Orth Defect of B', orthdef(B.vecs) print 'Surf/vol of B', surfvol(B.vecs) [B.symops,B.nops] = getGroup(B.vecs) print 'Number of symmetry operations', B.nops #print 'symmetry operations of B\n' #for j in range(nopsB): # print j # op = array(symopsB[:,:,j]) # print op #find real lattice A.vecs = trimSmall(transpose(inv(B.vecs))) A.det = det(A.vecs) A.Nmesh = Nmesh print;print 'A vectors';print A.vecs print 'Det of A', A.det print 'Orth Defect of A', orthdef(A.vecs) print 'Surf/vol of A', surfvol(A.vecs) [A.symops,A.nops] = getGroup(A.vecs) if A.nops != B.nops: sys.exit('Number of operations different for A and B; stop') print 'symmetry operations R of A\n' testvecs = [];testindices = [] for k in range(A.nops): print; print k
def bestmeshIter(Blatt, Nmesh): '''The kmesh can be related to the reciprocal lattice B by B = KM, where M is an integer 3x3 matrix So K = B Inv(M). Change M one element at a time to minimize the errors in symmetry and the cost in S/V and Nmesh ''' ############################################################## ########################## Script ############################ M = zeros((3, 3), dtype=int) S = zeros((3, 3), dtype=fprec) B = lattice() A = lattice() K = lattice() status = '' pf_minsv = 0 pf_sv2fcc = 0 pf_maxpf = 0 pf_pf2fcc = 0 #kvecs_pf2fcc = identity(3) sym_maxpf = False sym_sv2fcc = False sym_minsv = False sym_pf2fcc = False a = rint(Nmesh**(1 / 3.0)) f = int(Nmesh / a / a) print 'Target mesh number', Nmesh B.vecs = Blatt / 2 / pi #Don't use 2pi constants in reciprocal lattice here # B.pftarget = 0.7405 #default best packing fraction B.pftarget = 0.35 #############End BCT lattice eps = 1.0e-6 B.Nmesh = Nmesh print 'B vectors (differ by 2pi from traditional)' print B.vecs # #print 'B transpose'; print transpose(B.vecs) B.det = det(B.vecs) print 'Det of B', B.det print 'Orth Defect of B', orthdef(B.vecs) print 'Surf/vol of B', surfvol(B.vecs) pfB = packingFraction(B.vecs) print 'Packing fraction of B:', pfB [B.symops, B.nops] = getGroup(B.vecs) B.msymops = intsymops(B) #integer sym operations in B basis # printops_eigs(B) B.lattype = latticeType(B.nops) print 'Lattice type:', B.lattype A = lattice() A.vecs = trimSmall(inv(transpose(B.vecs))) [A.symops, A.nops] = getGroup(A.vecs) A.msymops = intsymops(A) print 'Real space lattice A' print A.vecs print 'Det A', det(A.vecs) pfA = packingFraction(A.vecs) print 'Packing fraction of A:', pfA pf_orth = 0 pf_orth2fcc = 0 sym_orth = False sym_orth2fcc = False if B.lattype in ['Orthorhombic', 'Tetragonal', 'Cubic']: cbest = '' #need for passing other structures' results to main program [kvecs_orth, pf_orth, sym_orth] = orthsuper(B) M = rint(dot(inv(kvecs_orth), B.vecs)).astype(int) print print 'Try orth2FCC substitution.', kmesh2 = zeros((3, 3), dtype=float) scale = 2 / 4**(1 / 3.0) kmesh2[:, 0] = kvecs_orth[:, 1] / scale + kvecs_orth[:, 2] / scale kmesh2[:, 1] = kvecs_orth[:, 2] / scale + kvecs_orth[:, 0] / scale kmesh2[:, 2] = kvecs_orth[:, 0] / scale + kvecs_orth[:, 1] / scale sym_orth2fcc = checksymmetry(kmesh2, B) if sym_orth2fcc: pf = packingFraction(kmesh2) print print 'Packing fraction', pf, 'vs original B', pfB if pf > pf_orth: M = rint(dot(inv(kmesh2), B.vecs)).astype(int) print 'M' print M else: ' Packing fraction too small' kvecs_orth2fcc = kmesh2 pf_orth2fcc = pf else: print ' It fails symmetry test' # sys.exit('stop') else: #'--------------------------------------------------------------------------------------------------------' #'--------------------------------------------------------------------------------------------------------' M = zeros((3, 3), dtype=int) ctest = [] type = 'maxpfsym' print type ctrials = [3] for c in ctrials: M = array([[-a + 2, a / c, a / c], [a / c, -a, a / c], [a / c, a / c, -a - 2]]) #bcc like best avg pf on 50: 0.66 # M = array([[2, a/c , a/c],[a/c,0,a/c],[a/c,a/c,-2]]) #fcc like best avg pf on 50: 0.59 M = rint(M * (B.Nmesh / abs(det(M)))**(1 / 3.0)) print 'Start mesh trial' print M [M, K] = findmin(M, B, type) print 'Test trial M' print M ctest.append(cost(M, B, type)) # print'Trial costs',ctest cbest = ctrials[argmin(ctest)] # print'Best c', cbest iternpf = 0 itermaxnpf = 10 itermaxsym = 5 # bestpf = 100 # NPFcost = 100;delNPFcost = -1 #initial values type = 'maxpfsym' print type delcost = -1 lowcost = 1000 #initialize #### while iternpf<itermaxnpf and delNPFcost <0 and abs(delNPFcost)>0.1 : while iternpf < itermaxnpf and delcost < -0.1: oldcost = cost(M, B, type) # NPFcost = cost(M,B,'maxpf') # delNPFcost = (NPFcost-oldNPFcost)/NPFcost : '''Here we let M vary in the search, but record pf and kvecs when we find min cost''' # print 'cost(N,PF):', cost(M,B,type) # while not symm and and iternpf<itermax: M = rint(M * (B.Nmesh / abs(det(M)))**(1 / 3.0)) print 'Scaled M' print M iternpf += 1 print 'Iteration', type, iternpf, '**********' [M, K] = findmin(M, B, type) print M itersym = 0 symm = False while not symm and itersym < itermaxsym: itersym += 1 print 'Symmetry iteration', itersym, '-------' # print 'Nmesh', abs(det(M)), 'packing', packingFraction(dot(B.vecs,inv(M))) M = minkM(M, B) #; print'Mink reduced M'; print M for iop in range(B.nops): M = findmin_i(M, B, iop) if abs(det(M) - B.Nmesh ) / B.Nmesh > 0.15: #how far off from target N M = rint(M * (B.Nmesh / abs(det(M)))**(1 / 3.0)) print 'Scaled M' print M K = lattice() K.vecs = trimSmall(dot(B.vecs, inv(M))) K.det = abs(det(K.vecs)) K.Nmesh = B.det / K.det symm = checksymmetry(K.vecs, B) print 'Symmetry check', symm if symm: newcost = cost(M, B, type) if newcost - lowcost < 0: lowcost = newcost print 'New lowcost', newcost pf_maxpf = packingFraction(K.vecs) sym_maxpf = True kvecs_maxpf = K.vecs # if pf_maxpf<bestpf: bestpf = pf_maxpf; bestM = M print 'Packing fraction', pf_maxpf, 'vs original B', pfB print 'Nmesh', K.Nmesh, 'vs target', B.Nmesh print print 'Try FCC-like substitution.' kmesh2 = zeros((3, 3), dtype=float) scale = 2 / 4**(1 / 3.0) kmesh2[:, 0] = K.vecs[:, 1] / scale + K.vecs[:, 2] / scale kmesh2[:, 1] = K.vecs[:, 2] / scale + K.vecs[:, 0] / scale kmesh2[:, 2] = K.vecs[:, 0] / scale + K.vecs[:, 1] / scale # M = rint(dot(inv(kmesh2),B.vecs)).astype(int) #set this for maxpf run if checksymmetry(kmesh2, B): sym_pf2fcc = True kvecs_pf2fcc = kmesh2 pf_pf2fcc = packingFraction(kmesh2) Mtemp = rint(dot(inv(kmesh2), B.vecs)).astype(int) if cost(Mtemp, B, type) < lowcost: lowcost = cost(M, B, type) print 'New lowcost', lowcost M = Mtemp print 'M' print Mtemp print 'Packing fraction', pf_pf2fcc, 'vs original B', pfB print else: print ' Packing fraction too small' else: print ' Fails to improve mesh' delcost = cost(M, B, type) - oldcost # Summary pfs = [pfB] pftypes = ['B_latt'] ks = [B.vecs / a] if not (sym_minsv or sym_sv2fcc or sym_maxpf or pf_pf2fcc or sym_orth or sym_orth2fcc): meshtype = 'B_latt_revert' #status += 'MHPrevert;' K.vecs = B.vecs / a K.det = abs(det(K.vecs)) K.Nmesh = abs(B.det / K.det) pfmax = packingFraction(K.vecs) else: if sym_orth: pfs.append(pf_orth) pftypes.append('orth') ks.append(kvecs_orth) if sym_orth2fcc: pfs.append(pf_orth2fcc) pftypes.append('orth2fcc') ks.append(kvecs_orth2fcc) if sym_maxpf: pfs.append(pf_maxpf) pftypes.append('maxpf') ks.append(kvecs_maxpf) if sym_pf2fcc: pfs.append(pf_pf2fcc) pftypes.append('pf2fcc') ks.append(kvecs_pf2fcc) pfmax = max(pfs) meshtype = pftypes[argmax(pfs)] K.vecs = ks[argmax(pfs)] K.det = abs(det(K.vecs)) K.Nmesh = B.det / K.det # return [K.vecs, K.Nmesh, B.Nmesh, B.lattype, pfB, pf_orth, pf_orth2fcc, pf_maxpf, pf_minsv, pf_sv2fcc, pfmax, meshtype, fcctype(B),status] return [ K.vecs, K.Nmesh, B.Nmesh, B.lattype, pfB, pf_orth, pf_orth2fcc, pf_maxpf, pf_pf2fcc, pfmax, meshtype, fcctype(B), cbest, status ]
def bestmeshIter_vary_N(Blatt, Nmesh, path): '''The kmesh can be related to the reciprocal lattice B by B = KM, where M is an integer 3x3 matrix So K = B Inv(M). Change M one element at a time to minimize the errors in symmetry and the cost in S/V and Nmesh ''' ############################################################## ########################## Script ############################ vaspinputdir = '/fslhome/bch/cluster_expansion/alir/AFLOWDATAf1_50e/vaspinput/' M = zeros((3, 3), dtype=int) S = zeros((3, 3), dtype=fprec) B = lattice() A = lattice() K = lattice() status = '' pf_minsv = 0 pf_sv2fcc = 0 pf_maxpf = 0 pf_pf2fcc = 0 #kvecs_pf2fcc = identity(3) sym_maxpf = False sym_sv2fcc = False sym_minsv = False sym_pf2fcc = False a = rint(Nmesh**(1 / 3.0)) f = int(Nmesh / a / a) print 'Target mesh number', Nmesh B.vecs = Blatt / 2 / pi #Don't use 2pi constants in reciprocal lattice here # B.pftarget = 0.7405 #default best packing fraction #############End BCT lattice eps = 1.0e-6 B.Nmesh = Nmesh print 'B vectors (differ by 2pi from traditional)' print B.vecs # #print 'B transpose'; print transpose(B.vecs) B.det = det(B.vecs) print 'Det of B', B.det print 'Orth Defect of B', orthdef(B.vecs) print 'Surf/vol of B', surfvol(B.vecs) pfB = packingFraction(B.vecs) print 'Packing fraction of B:', pfB [B.symops, B.nops] = getGroup(B.vecs) B.msymops = intsymops(B) #integer sym operations in B basis # print'Symmetry operators in basis of B' # for i in range: # print B.msymops[:,:,i];print # printops_eigs(B) B.lattype = latticeType(B.nops) print 'Lattice type:', B.lattype A = lattice() A.vecs = trimSmall(inv(transpose(B.vecs))) [A.symops, A.nops] = getGroup(A.vecs) A.msymops = intsymops(A) print 'Real space lattice A' print A.vecs print 'Det A', det(A.vecs) pfA = packingFraction(A.vecs) print 'Packing fraction of A:', pfA meshesfile = open('meshesfile', 'a') meshesfile.write('N target %i\n' % B.Nmesh) meshesfile.write('Format: pf then Nmesh then kmesh\n\n') pflist = [] # M0 = array([[2, 2, 2,], # [2, 2, -2], # [-2, 2, -2]]) # # 0.74050000 64.000 #-5 1 -3 #6 2 2 #3 1 -3 M0 = array([[ -5, 1, -3, ], [6, 2, 2], [3, 1, -3]]) # for div in [256,128,64,32,16,8,4,2,1]: # print '\nDivisor',div # nMP = rint((Nmesh/div)**(1/3.0)) # M = array([[nMP,0,0],[0,nMP,0],[0,0,nMP]]); for fac in [1, 2, 3, 4, 5, 6, 7, 8]: print '\nMultiplier', fac M = fac * M0 # M = array([[4,12,-4], # [-11,4,-26], # [-26,-4,-11]]); K = lattice() K.vecs = trimSmall(dot(B.vecs, inv(M))) K.det = abs(det(K.vecs)) K.Nmesh = B.det / K.det print 'Number of points', det(M) print 'Check M' print M print 'Check K' print K.vecs print 'Check B' print B.vecs print 'Check pf' print packingFraction(K.vecs) #create a dir and prepare for vasp run newdir = str(K.Nmesh) newpath = path + newdir + '/' if not os.path.isdir(newpath): os.system('mkdir %s' % newpath) os.chdir(newpath) os.system('cp %s* %s' % (vaspinputdir, newpath)) os.system('cp %sPOSCAR %s' % (path, newpath)) writekpts_vasp_M(newpath, B, M, K) # writekpts_vasp_pf(newpath,K.vecs,pf_maxpf,K.Nmesh) writejobfile(newpath) # print 'submitting job' subprocess.call(['sbatch', 'vaspjob']) #!!!!!!! Submit jobs os.chdir(path)
def enerGrad(self,indComps): '''restrict the energy sum to the pairs that contain independent points''' # print 'oldindvecs',self.oldindVecs indVecs = indComps.reshape((self.nIndIn,3)) self.oldindVecs = indVecs #update all positions by symmetry and translation self.oldPoints = deepcopy(self.points) self.updatePoints(indVecs) #indVecs now cannot be used for current points because they might be out of cell. # print 'movement' # for i in range(self.npoints): # # print 'old',i,self.oldPoints[i]['pos'] # # print 'new',i,self.points[i]['pos'] # # print # move = norm(self.points[i]['pos']-self.oldPoints[i]['pos']) # if move > 1e-6 : # print i,move ener = 0.0 self.power = 2.0 # scale = 1 for ipos in range(self.nIndIn): force = zeros(3) rs = zeros(self.npoints,dtype = [('r', 'float'),('rij', '3float'),('force', '3float')]) nearest = -1 rnearest = 100.0 for jpos in range(self.npoints): rij = self.points[jpos]['pos'] - self.points[ipos]['pos'] r = norm([rij]) if r > 1e-4*self.rmin: if r<rnearest: nearest = jpos rnearest = r # # epair = r**2 #attractive springs...dumb because those farthest away influence most # force += rij #attractive springs) epair = (self.ravg/r)**self.power forcepair = -self.power*epair/r * rij/r force += forcepair # print 'jpos',jpos,r,forcepair ener += epair rs[jpos]['r'] = r rs[jpos]['rij'] = rij rs[jpos]['force'] = forcepair self.points[ipos]['force'] = trimSmall(force) if ipos in self.indIn: rs =sort(rs, order='r') # print ipos, rs[:20]['r'] # print rs[:20]['rij'] print ipos, 'pos', self.points[ipos]['pos'] print 'nerst',self.points[nearest]['pos'],nearest,rnearest print 'vectr', trimSmall(self.points[nearest]['pos'] - self.points[ipos]['pos']) print 'force', ipos, self.points[ipos]['force'] ener = ener/self.nIndIn grad = -self.points[:self.nIndIn]['force'].flatten()/self.nIndIn print 'energy:',self.count, ener print # if self.count == 19: # self.plotPoints(self.points,'pos') self.count += 1 #now update all the dependent positions # ! Note: need to update the positions at each step! Do we have to get inside # return ener# return ener, grad
def writekpts_vasp_M(path, B, M, K): '''write out kpoints file with IBZKPTS format. This will specify all the kpoints and their weights. No shift is allowed for now''' #Fill a 1st brilloun zone with mesh points. We will choose the 1st BZ to be that given by the parallepiped of (B0, B1, B2) #Since B = KM. The first column of M determines the first column of B (B0) We run trial mesh points over a grid made by the maximum and minimum values of columns of M and the three directions # of K. The first row of M gives the first k direction (first column of K) eps = 1e-4 Kv = K.vecs Bv = B.vecs # nBZpt = 0 # Binv = inv(Bv) # #Dummy set up Monkhorst Pack: # nMP = rint(det(M)**(1/3.0)) # M = array([[nMP,0,0],[0,nMP,0],[0,0,nMP]]); # Kv = dot(Bv,inv(M)) #end dummy print 'M in writekpts_vasp_M' print(M) print 'Kvecs in writekpts_vasp_M' print(Kv) # print 'transpose(Bvecs)in writekpts_vasp_M';print transpose(Bv)*100 print 'det of M', det(M) npts = -1 ktryB = zeros((3, rint(det(M) * 2))) # kpts = zeros((3, rint(det(M) * 2))) #The rows of M determine how each vector (column) of K is used in the sum. #The 1BZ parallelpiped must go from (0,0,0) to each of the other vertices #the close vertices are at B1,B2,B3. So each element of each row must be considered. #The far verictecs are at for these three vectors taken in paris. #To reach the diagonal point of the parallelpiped, #which means that the sums of the rows must be part of the limits. #To reach the three far vertices (not the tip), we have to take the columns of M in pairs:, #which means that we check the limits of the pairs among the elements of each row. #in other words, the limits on the search for each row i of (coefficients of grid basis vector Ki) are the partial sums #of the elements of each row: min(0,a,b,c,a+b,a+c,b+c,a+b+c), max(0,a,b,c,a+b,a+c,b+c,a+b+c) Msums = zeros((3, 8), dtype=int) for i in range(3): a = M[i, 0] b = M[i, 1] c = M[i, 2] Msums[i, 0] = 0 Msums[i, 1] = a Msums[i, 2] = b Msums[i, 3] = c Msums[i, 4] = a + b Msums[i, 5] = a + c Msums[i, 6] = b + c Msums[i, 7] = a + b + c ntry = 0 for i2 in range( amin(Msums[2, :]) - 1, amax(Msums[2, :]) + 1 ): #The rows of M determine how each vector (column) of M is used in the sum for i1 in range(amin(Msums[1, :]) - 1, amax(Msums[1, :]) + 1): for i0 in range(amin(Msums[0, :]) - 1, amax(Msums[0, :]) + 1): ntry += 1 ktry = i0 * Kv[:, 0] + i1 * Kv[:, 1] + i2 * Kv[:, 2] ktryB1 = trimSmall(dot(inv(Bv), transpose(ktry))) #test whether it is in 1st BZ. Transform first to basis of B: #it's in the parallelpiped if its components are all less than one and positive eps = 1e-4 if min(ktryB1) > 0 - eps and max(ktryB1) < 1 - eps: npts += 1 #translate to traditional 1BZ for i in range(3): if ktryB1[i] > 0.5 + eps: ktryB1[i] = ktryB1[i] - 1 if ktryB1[i] < -0.5 + eps: ktryB1[i] = ktryB1[i] + 1 #convert back to cartesian ktry = trimSmall(dot(Bv, transpose(ktryB1))) kpts[:, npts] = ktry npts = npts + 1 #from starting at -1 print 'Grid points tested', ntry print 'Points in 1BZ', npts if not areEqual(npts, rint(det(M))): print det(M) sys.exit( 'Stop. Number of grid points in the 1BZ is not equal to det(M)') #Apply symmetry operations and see which are identical to others. All in Cartesian coords kptssymm = zeros((3, npts)) weights = zeros((npts), dtype=int) #record the first point kptssymm[:, 0] = kpts[:, 0] weights[0] = 1 nksymm = 1 for i in range(1, npts): kB = trimSmall(dot(inv(Bv), transpose(kpts[:, i]))) #rotate found = False for iop in range(B.nops): krot = dot(B.symops[:, :, iop], kpts[:, i]) kB2 = trimSmall(dot(inv(Bv), transpose(krot))) #test whether it matches any we have saved. for iksymm in range(nksymm): if areEqual(krot[0], kptssymm[0, iksymm]) and areEqual( krot[1], kptssymm[1, iksymm]) and areEqual( krot[2], kptssymm[2, iksymm]): # print 'Found equivalent point' weights[iksymm] += 1 found = True # It better be equivalent to only one saved point break if found: break if not found: kptssymm[:, nksymm] = kpts[:, i] weights[nksymm] += 1 nksymm += 1 # print 'symm new point',nksymm print 'Points in reduced 1BZ', nksymm print 'Total weights', sum(weights) print 'Vol BZ/ vol irredBZ', npts / float(nksymm) #convert to basis of B lattice vectors for i in range(nksymm): kptssymm[:, i] = trimSmall(dot(inv(Bv), transpose(kptssymm[:, i]))) # #write POSCAR for vmd: put B vectors in lattice, and kmesh in atomic positions # scale = 10 # poscar = open('POSCARk','w') # poscar.write('Cs I kpoints vs B'+'\n') #different sizes from this label # poscar.write('1.0\n') # for i in [0,1,2]: # poscar.write('%20.15f %20.15f %20.15f \n' % (scale*Bv[0,i], scale*Bv[1,i], scale*Bv[2,i])) # poscar.write('1 %i\n' %npts) # poscar.write('Cartesian\n') # poscar.write('0.0 0.0 0.0\n') # for i in range(npts): # poscar.write('%20.15f %20.15f %20.15f \n' % (scale*kpts[0,i],scale*kpts[1,i],scale*kpts[2,i])) # poscar.close() #write POSCAR with irred BZ. for vmd: put B vectors in lattice, and kmesh in atomic positions scale = 10 poscar = open('POSCARkred', 'w') poscar.write('Cs I kpoints vs B' + '\n') #different sizes from this label poscar.write('1.0\n') for i in [0, 1, 2]: poscar.write('%20.15f %20.15f %20.15f \n' % (scale * Bv[0, i], scale * Bv[1, i], scale * Bv[2, i])) poscar.write('1 %i\n' % nksymm) poscar.write('Cartesian\n') poscar.write('0.0 0.0 0.0\n') for i in range(nksymm): poscar.write('%20.15f %20.15f %20.15f %20.15f \n' % (scale * kptssymm[0, i], scale * kptssymm[1, i], scale * kptssymm[2, i], weights[i])) poscar.close() poscar = open('KPOINTS', 'w') poscar.write('BCH generated via bestmeshiter' + '\n') #different sizes from this label poscar.write('%i\n' % nksymm) poscar.write('Reciprocal lattice units\n') for i in range(nksymm): poscar.write( '%20.15f %20.15f %20.15f %i\n' % (kptssymm[0, i], kptssymm[1, i], kptssymm[2, i], weights[i])) poscar.close()
def bestmeshIter(Blatt,Nmesh): '''The kmesh can be related to the reciprocal lattice B by B = KM, where M is an integer 3x3 matrix So K = B Inv(M). Change M one element at a time to minimize the errors in symmetry and the cost in S/V and Nmesh ''' ############################################################## ########################## Script ############################ M = zeros((3,3),dtype = int) S = zeros((3,3),dtype = fprec) B = lattice() A = lattice() K = lattice() status = '' pf_minsv = 0; pf_sv2fcc = 0; pf_maxpf = 0; pf_pf2fcc = 0; #kvecs_pf2fcc = identity(3) sym_maxpf = False; sym_sv2fcc = False; sym_minsv = False; sym_pf2fcc = False a = rint(Nmesh**(1/3.0)); f = int(Nmesh/a/a) print 'Target mesh number', Nmesh B.vecs = Blatt/2/pi #Don't use 2pi constants in reciprocal lattice here # B.pftarget = 0.7405 #default best packing fraction B.pftarget = 0.35 #############End BCT lattice eps = 1.0e-6 B.Nmesh = Nmesh print 'B vectors (differ by 2pi from traditional)';print B.vecs # #print 'B transpose'; print transpose(B.vecs) B.det = det(B.vecs) print 'Det of B', B.det print 'Orth Defect of B', orthdef(B.vecs) print 'Surf/vol of B', surfvol(B.vecs) pfB = packingFraction(B.vecs) print 'Packing fraction of B:', pfB [B.symops,B.nops] = getGroup(B.vecs) B.msymops = intsymops(B) #integer sym operations in B basis # printops_eigs(B) B.lattype = latticeType(B.nops) print 'Lattice type:', B.lattype A = lattice() A.vecs = trimSmall(inv(transpose(B.vecs))) [A.symops,A.nops] = getGroup(A.vecs) A.msymops = intsymops(A) print 'Real space lattice A'; print A.vecs print 'Det A', det(A.vecs) pfA = packingFraction(A.vecs) print 'Packing fraction of A:', pfA pf_orth=0; pf_orth2fcc=0; sym_orth = False; sym_orth2fcc = False if B.lattype in ['Orthorhombic', 'Tetragonal','Cubic']: cbest = '' #need for passing other structures' results to main program [kvecs_orth,pf_orth,sym_orth] = orthsuper(B) M = rint(dot(inv(kvecs_orth),B.vecs)).astype(int) print; print 'Try orth2FCC substitution.', kmesh2 = zeros((3,3),dtype = float) scale = 2/4**(1/3.0) kmesh2[:,0] = kvecs_orth[:,1]/scale + kvecs_orth[:,2]/scale kmesh2[:,1] = kvecs_orth[:,2]/scale + kvecs_orth[:,0]/scale kmesh2[:,2] = kvecs_orth[:,0]/scale + kvecs_orth[:,1]/scale sym_orth2fcc = checksymmetry(kmesh2,B) if sym_orth2fcc: pf = packingFraction(kmesh2) print; print 'Packing fraction', pf, 'vs original B', pfB if pf>pf_orth: M = rint(dot(inv(kmesh2),B.vecs)).astype(int) print 'M';print M else: ' Packing fraction too small' kvecs_orth2fcc = kmesh2 pf_orth2fcc = pf else: print' It fails symmetry test' # sys.exit('stop') else: #'--------------------------------------------------------------------------------------------------------' #'--------------------------------------------------------------------------------------------------------' M = zeros((3,3),dtype=int) ctest = [] type = 'maxpfsym'; print type ctrials = [3] for c in ctrials: M = array([[-a+2, a/c , a/c],[a/c,-a,a/c],[a/c,a/c,-a-2]]) #bcc like best avg pf on 50: 0.66 # M = array([[2, a/c , a/c],[a/c,0,a/c],[a/c,a/c,-2]]) #fcc like best avg pf on 50: 0.59 M = rint(M * (B.Nmesh/abs(det(M)))**(1/3.0)) print 'Start mesh trial'; print M [M,K] = findmin(M,B,type) print 'Test trial M'; print M ctest.append(cost(M,B,type)) # print'Trial costs',ctest cbest = ctrials[argmin(ctest)] # print'Best c', cbest iternpf = 0 itermaxnpf = 10 itermaxsym = 5 # bestpf = 100 # NPFcost = 100;delNPFcost = -1 #initial values type = 'maxpfsym'; print type delcost = -1; lowcost = 1000 #initialize #### while iternpf<itermaxnpf and delNPFcost <0 and abs(delNPFcost)>0.1 : while iternpf<itermaxnpf and delcost < -0.1: oldcost = cost(M,B,type) # NPFcost = cost(M,B,'maxpf') # delNPFcost = (NPFcost-oldNPFcost)/NPFcost : '''Here we let M vary in the search, but record pf and kvecs when we find min cost''' # print 'cost(N,PF):', cost(M,B,type) # while not symm and and iternpf<itermax: M = rint(M * (B.Nmesh/abs(det(M)))**(1/3.0)) print 'Scaled M';print M iternpf += 1 print 'Iteration',type,iternpf, '**********' [M,K] = findmin(M,B,type) print M itersym = 0 symm = False while not symm and itersym <itermaxsym: itersym += 1 print 'Symmetry iteration', itersym, '-------' # print 'Nmesh', abs(det(M)), 'packing', packingFraction(dot(B.vecs,inv(M))) M = minkM(M,B)#; print'Mink reduced M'; print M for iop in range(B.nops): M = findmin_i(M,B,iop) if abs(det(M)-B.Nmesh)/B.Nmesh > 0.15: #how far off from target N M = rint(M * (B.Nmesh/abs(det(M)))**(1/3.0)) print 'Scaled M';print M K = lattice();K.vecs = trimSmall(dot(B.vecs,inv(M)));K.det = abs(det(K.vecs)); K.Nmesh = B.det/K.det symm = checksymmetry(K.vecs,B) print 'Symmetry check', symm if symm: newcost = cost(M,B,type) if newcost - lowcost < 0: lowcost = newcost; print'New lowcost',newcost pf_maxpf = packingFraction(K.vecs) sym_maxpf = True kvecs_maxpf = K.vecs # if pf_maxpf<bestpf: bestpf = pf_maxpf; bestM = M print 'Packing fraction', pf_maxpf, 'vs original B', pfB print 'Nmesh', K.Nmesh, 'vs target', B.Nmesh print; print 'Try FCC-like substitution.' kmesh2 = zeros((3,3),dtype = float) scale = 2/4**(1/3.0) kmesh2[:,0] = K.vecs[:,1]/scale + K.vecs[:,2]/scale kmesh2[:,1] = K.vecs[:,2]/scale + K.vecs[:,0]/scale kmesh2[:,2] = K.vecs[:,0]/scale + K.vecs[:,1]/scale # M = rint(dot(inv(kmesh2),B.vecs)).astype(int) #set this for maxpf run if checksymmetry(kmesh2,B): sym_pf2fcc = True kvecs_pf2fcc = kmesh2 pf_pf2fcc = packingFraction(kmesh2) Mtemp = rint(dot(inv(kmesh2),B.vecs)).astype(int) if cost(Mtemp,B,type) < lowcost: lowcost = cost(M,B,type);print'New lowcost',lowcost M = Mtemp print 'M';print Mtemp print 'Packing fraction', pf_pf2fcc, 'vs original B', pfB print; else: print ' Packing fraction too small' else: print ' Fails to improve mesh' delcost = cost(M,B,type) - oldcost # Summary pfs = [pfB] pftypes = ['B_latt'] ks = [B.vecs/a] if not (sym_minsv or sym_sv2fcc or sym_maxpf or pf_pf2fcc or sym_orth or sym_orth2fcc): meshtype = 'B_latt_revert' ; #status += 'MHPrevert;' K.vecs = B.vecs/a; K.det = abs(det(K.vecs)); K.Nmesh = abs(B.det/K.det) pfmax = packingFraction(K.vecs) else: if sym_orth: pfs.append(pf_orth) pftypes.append('orth') ks.append(kvecs_orth) if sym_orth2fcc: pfs.append(pf_orth2fcc) pftypes.append('orth2fcc') ks.append(kvecs_orth2fcc) if sym_maxpf: pfs.append(pf_maxpf) pftypes.append('maxpf') ks.append(kvecs_maxpf) if sym_pf2fcc: pfs.append(pf_pf2fcc) pftypes.append('pf2fcc') ks.append(kvecs_pf2fcc) pfmax = max(pfs) meshtype = pftypes[argmax(pfs)] K.vecs = ks[argmax(pfs)]; K.det = abs(det(K.vecs)); K.Nmesh = B.det/K.det # return [K.vecs, K.Nmesh, B.Nmesh, B.lattype, pfB, pf_orth, pf_orth2fcc, pf_maxpf, pf_minsv, pf_sv2fcc, pfmax, meshtype, fcctype(B),status] return [K.vecs, K.Nmesh, B.Nmesh, B.lattype, pfB, pf_orth, pf_orth2fcc, pf_maxpf, pf_pf2fcc, pfmax, meshtype, fcctype(B),cbest,status]
print B.vecs print 'B transpose' print transpose(B.vecs) print 'Det of B', B.det print 'Orth Defect of B', orthdef(B.vecs) print 'Surf/vol of B', surfvol(B.vecs) [B.symops, B.nops] = getGroup(B.vecs) print 'Number of symmetry operations', B.nops #print 'symmetry operations of B\n' #for j in range(nopsB): # print j # op = matrix(symopsB[:,:,j]) # print op #find real lattice A.vecs = trimSmall(transpose(inv(B.vecs))) A.det = det(A.vecs) A.Nmesh = Nmesh print 'A vectors' print A.vecs print 'Det of A', A.det print 'Orth Defect of A', orthdef(A.vecs) print 'Surf/vol of A', surfvol(A.vecs) [A.symops, A.nops] = getGroup(A.vecs) if A.nops != B.nops: sys.exit('Number of operations different for A and B; stop') print 'symmetry operations R of A\n' testvecs = [] oplist = []
print 'Fcc mesh compatibility for fcc lattice):' print 'detL*bccsq*trans(inv(L))'; print dL*dot(bccsq,transpose(inv(L))) scaleposcar(scale) #inserts length scale into appropriate spot. writefile([str(dL)],finalDir+dir+'detL') writefile([lattype],finalDir+dir+'lattype') os.system ('cp %s* %s' % (vaspinputdir,'.')) os.system ('rm slurm*') n = m*dL; shift = '0.00' if meshtype == 'cub': M = n*transpose(inv(A)) print 'M matrix for cubic mesh'; print M print 'det M (kpoints in unreduced 1BZ)', det(M) writekpts_cubic_n(n,shift) if meshtype == 'fcc': M = trimSmall(n*dot(bccsq,transpose(inv(L)))) print 'test K';print trimSmall(dot(B,inv(M))) # print 'test Bo';print transpose(inv(platt)) print 'M matrix for fcc mesh'; print M print 'det M (kpoints in unreduced 1BZ)', det(M) writekpts_fcc_n(n,shift) writefile([str(abs(det(M)))],finalDir+dir+'detM') # writekpts_vasp_M(finalDir+dir,B,M,Bnops,Bsymops) #define K's explicitly!!! writejobfile(finalDir+dir) if n <= nmax:#(don't submit the biggest jobs '' subprocess.call(['sbatch', 'vaspjob']) #!!!!!!! Submit jobs
def bestmeshEigen(Blatt, Nmesh): '''The kmesh can be related to the reciprocal lattice B by B = KM, where M is an integer 3x3 matrix So K = B Inv(M) . Work in the inverse space of this problem, where we can work with M instead of Inv(M). T(InvK) = T(InvB)T(M). Define S = T(InvK), and the real lattice A = T(InvB). So S = A T(M) is a superlattice on the real lattice. Minimization scheme Nothing calls this routine''' ############################################################## ########################## Script ############################ M = zeros((3, 3), dtype=int) S = zeros((3, 3), dtype=fprec) B = lattice() A = lattice() K = lattice() B.vecs = Blatt / 2 / pi #Don't use 2pi constants in RL here. #############End BCT lattice eps = 1.0e-6 B.det = det(B.vecs) B.Nmesh = Nmesh print 'B vectors' print B.vecs # #print 'B transpose'; print transpose(B.vecs) print 'Det of B', B.det print 'Orth Defect of B', orthdef(B.vecs) print 'Surf/vol of B', surfvol(B.vecs) [B.symops, B.nops] = getGroup(B.vecs) print 'Number of symmetry operations', B.nops eigendirs = zeros([3, 3, B.nops], dtype=int) #print 'symmetry operations of B\n' #for j in range(nopsB): # print j # op = array(symopsB[:,:,j]) # print op #find real lattice A.vecs = transpose(inv(B.vecs)) A.det = det(A.vecs) A.Nmesh = Nmesh print print 'A vectors' print A.vecs print 'Det of A', A.det print 'Orth Defect of A', orthdef(A.vecs) print 'Surf/vol of A', surfvol(A.vecs) [A.symops, A.nops] = getGroup(A.vecs) if A.nops != B.nops: sys.exit('Number of operations different for A and B; stop') testvecs = [] testindices = [] # print 'symmetry operations R of A\n' for k in range(A.nops): print print k op = array(A.symops[:, :, k]) print 'symop R of A' print trimSmall(op) m = trimSmall(dot(dot(inv(A.vecs), A.symops[:, :, k]), A.vecs)) print 'symop m' print m # print 'det(m)', det(m) 'Take eigenvectors in cartesian space' [vals, vecs] = eig(op) print 'eigen of m', vals print 'eigenvecs are calculated in cartesian space' print vecs #transform to m space for i in range(3): vecs[:, i] = dot(inv(A.vecs), vecs[:, i]) print 'eigenvecs in m space' print vecs print 'scaled to integers' for i in range(3): vecs[:, i] = vecs[:, i] / abs(vecs[:, i])[nonzero(vecs[:, i])].min() vecs = rint(vecs) print vecs eigendirs[:, :, k] = vecs #find operations with nondegenerate real eigenvalues print 'nonDegen', nonDegen(vals) for i in nonDegen(vals): if not matchDirection(transpose(vecs[:, i]), testvecs): #keep only unique directions testvecs.append(vecs[:, i].real / abs(vecs[:, i])[nonzero(vecs[:, i])].min()) testindices.append([k, i]) #print; print oplist; print 'testvecs' print testvecs #print testindices MT = zeros((3, 3), dtype=fprec) if len(testvecs) == 0: print 'No eigen directions' [M, K.vecs] = unconstrainedSVsearch(B) if det(K.vecs) == 0: sys.exit('Det(K) is zero after unconstrained search! Stop') if not checksymmetry(K.vecs, B): sys.exit('Symmetry missing in mesh! Stop') # MT = unconstrainedmin(B.vecs) if len(testvecs) == 1: print 'Only 1 eigen direction' #Choose this one and the other two in the plane perpendicular to this. MT[:, 0] = testvecs[0] # print 'testindices',testindices kop = testindices[0][0] #useful operator ieigen = testindices[0][1] #index of the only eigendirection op = array(A.symops[:, :, kop]) # print trimSmall(op) # find one other direction in the plane perp to the eigendireation; either degenerate eigenvalue will do. otherindices = nonzero(array([0, 1, 2]) - ieigen) print eigendirs[:, :, otherindices[0][0]] MT[:, 1] = eigendirs[:, :, kop][:, otherindices[0][0]] #Make 3rd vector perp as possible to the other two ur0 = dot(A.vecs, MT[:, 0]) / norm(dot( A.vecs, MT[:, 0])) #unit vectors in real space ur1 = dot(A.vecs, MT[:, 1]) / norm(dot(A.vecs, MT[:, 1])) ur2 = cross(ur0, ur1) print ur0 print ur1 print ur2 print 'ur2 transformed to m space' print dot(inv(A.vecs), ur2) mvec = dot(inv(A.vecs), ur2) #transformed to M space, but real mvec = rint( mvec / abs(mvec[nonzero(mvec)]).min()) #Scale so smallest comp is 1 MT[:, 2] = mvec print 'MT from single operator' print MT print 'starting superlattice' print dot(A.vecs, MT) # Q2 = MT2mesh_three_ns(MT,B) Q2 = MT2mesh(MT, B, A) if checksymmetry(Q2, B): SV = surfvol(Q2) # print round(surfvol(Q2),4),round(orthdef(Q2),4),'SV of Q2,','OD' K.vecs = Q2 else: print 'Q from single operator fails symmetry' if len(testvecs) == 2: print 'Only 2 eigen directions' MT[:, 0] = testvecs[0] MT[:, 1] = testvecs[1] #Make 3rd vector perp as possible to the other two ur0 = dot(A.vecs, MT[:, 0]) / norm(dot( A.vecs, MT[:, 0])) #unit vector in real space ur1 = dot(A.vecs, MT[:, 1]) / norm(dot(A.vecs, MT[:, 1])) ur2 = cross(ur0, ur1) MT[:, 2] = rint(dot(inv(A.vecs), ur2)) print 'MT from two eigen directions' print MT # Q2 = MT2mesh_three_ns(MT,B) Q2 = MT2mesh(MT, B) if checksymmetry(Q2, B): SV = surfvol(Q2) print round(surfvol(Q2), 4), round(orthdef(Q2), 4), 'SV of Q2,', 'OD' K.vecs = Q2 else: print 'Q fails symmetry' if len(testvecs) >= 3: print 'MT from three eigen directions' testvecstrials = [list(x) for x in combinations(testvecs, 3)] print testvecstrials bestindex = -1 bestcost = 1000 for i, vecs in enumerate(testvecstrials): print print 'trial', i print vecs MT[:, 0] = vecs[0] MT[:, 1] = vecs[1] MT[:, 2] = vecs[2] print 'MT' print MT print 'det MT', det(MT) if not areEqual(det(MT), 0): Q2 = MT2mesh(MT, B) if checksymmetry(Q2, B): Nscale = 1 * .8 Ncost = Nscale * abs((B.det / det(Q2)) - B.Nmesh) / B.Nmesh cost = surfvol(Q2) * (1 + Ncost) print cost if cost < bestcost: bestcost = cost bestindex = i K.vecs = Q2 print round(surfvol(Q2), 4), round(orthdef(Q2), 4), 'SV of Q2,', 'OD' else: print 'Q from trial %i fails symmetry' % i print '___________ Best mesh ___________' print 'trial', bestindex if checksymmetry(K.vecs, B): print K.vecs K.det = abs(det(K.vecs)) print 'N of mesh', B.det / K.det SV = surfvol(K.vecs) print round(surfvol(K.vecs), 4), round(orthdef(K.vecs), 4), 'SV of Q2,', 'OD' else: print 'K mesh fails symmetry'
def writekpts_vasp_M(path,Bv,M,nops,symmops): '''write out kpoints file with IBZKPTS format. This will specify all the kpoints and their weights. No shift is allowed for now. The symmops are those of B''' #Fill a 1st brilloun zone with mesh points. We will choose the 1st BZ to be that given by the parallepiped of (B0, B1, B2) #Since B = KM. The first column of M determines the first column of B (B0) We run trial mesh points over a grid made by the maximum and minimum values of columns of M and the three directions # of K. The first row of M gives the first k direction (first column of K) eps = 1e-4 M = M * sign(det(M)) # want positive determinants Kv = dot(B,inv(M)) nBZpt = 0 Binv = inv(Bv) print 'M in writekpts_vasp_M';print (M) print 'Kvecs in writekpts_vasp_M';print (Kv) # print 'transpose(Bvecs)in writekpts_vasp_M';print transpose(Bv)*100 print 'det of M', det(M) npts = -1 ktryB = zeros((3,rint(det(M)*2))) kpts = zeros((3,rint(det(M)*2))) #all the kpoints in the entire 1BZ #The rows of M determine how each vector (column) of K is used in the sum. #The 1BZ parallelpiped must go from (0,0,0) to each of the other vertices #the close vertices are at B1,B2,B3. So each element of each row must be considered. #The far vertices are at for these three vectors taken in pairs. #To reach the diagonal point of the parallelpiped, #which means that the sums of the rows must be part of the limits. #To reach the three far vertices (not the tip), we have to take the columns of M in pairs:, #which means that we check the limits of the pairs among the elements of each row. #in other words, the limits on the search for each row i of (coefficients of grid basis vector Ki) are the partial sums #of the elements of each row: min(0,a,b,c,a+b,a+c,b+c,a+b+c), max(0,a,b,c,a+b,a+c,b+c,a+b+c) Msums = zeros((3,8),dtype = int) for i in range(3): a = M[i,0]; b = M[i,1];c = M[i,2]; Msums[i,0]=0; Msums[i,1]=a; Msums[i,2]=b;Msums[i,3]=c; Msums[i,4]=a+b; Msums[i,5]=a+c; Msums[i,6]=b+c; Msums[i,7]=a+b+c ntry =0 for i2 in range(amin(Msums[2,:])-1,amax(Msums[2,:])+1): #The rows of M determine how each vector (column) of M is used in the sum for i1 in range(amin(Msums[1,:])-1,amax(Msums[1,:])+1): for i0 in range(amin(Msums[0,:])-1,amax(Msums[0,:])+1): ntry += 1 ktry = i0*Kv[:,0] + i1*Kv[:,1] + i2*Kv[:,2] ktryB1 = trimSmall(dot(inv(Bv),transpose(ktry))) #test whether it is in 1st BZ. Transform first to basis of B: #it's in the parallelpiped if its components are all less than one and positive eps = 1e-4 if min(ktryB1)>0-eps and max(ktryB1)<1-eps : npts += 1 # print i0,i1,i2, trimSmall(ktryB1) #translate to traditional 1BZ for i in range(3): if ktryB1[i]>0.5+eps: ktryB1[i] = ktryB1[i] - 1 if ktryB1[i]<-0.5+eps: ktryB1[i] = ktryB1[i] + 1 #convert back to cartesian ktry = trimSmall(dot(Bv,transpose(ktryB1))) kpts[:,npts] = ktry npts = npts+1 #from starting at -1 print 'Grid points tested',ntry print 'Points in 1BZ',npts if not areEqual(npts,rint(det(M))): print det(M) sys.exit('Stop. Number of grid points in the 1BZ is not equal to det(M)') #Apply symmetry operations and see which are identical to others. All in Cartesian coords kptssymm = zeros((3,npts)) #the kpoints in irreducible 1BZ weights = zeros((npts),dtype = int) #record the first point print '0'; print kpts[:,0] kptssymm[:,0] = kpts[:,0] weights[0] = 1 nksymm = 1 for i in range(1,npts): #test all print; print i;print kpts[:,i] kB = trimSmall(dot(inv(Bv),transpose(kpts[:,i])))#now in the basis of B vectors print kB, 'in recip cords' # if areEqual(kB[0],0.5) or areEqual(kB[1],0.5) or areEqual(kB[2],0.5) : # print'Boundary point', kB #rotate found = False for iop in range(nops): krot = dot(symops[:,:,iop],kpts[:,i]) kB2 = trimSmall(dot(inv(Bv),transpose(krot))) # if areEqual(kB[0],0.5) or areEqual(kB[1],0.5) or areEqual(kB[2],0.5) : # print kB2 #test whether it matches any we have saved. for iksymm in range(nksymm): if areEqual(krot[0],kptssymm[0,iksymm]) and areEqual(krot[1],kptssymm[1,iksymm]) and areEqual(krot[2],kptssymm[2,iksymm]) : print 'Found equivalent point',iksymm;print kptssymm[:,iksymm] weights[iksymm] += 1 found = True # It better be equivalent to only one point in irreducible 1BZ break if found: break if not found: kptssymm[:,nksymm] = kpts[:,i] weights[nksymm] += 1 nksymm += 1 print 'symm new point',nksymm print 'Points in reduced 1BZ',nksymm print 'Total weights',sum(weights) print 'Vol BZ/ vol irredBZ', npts/float(nksymm) #convert to basis of B lattice vectors for i in range(nksymm): kptssymm[:,i] = trimSmall(dot(inv(Bv),transpose(kptssymm[:,i]))) # #write POSCAR for vmd: put B vectors in lattice, and kmesh in atomic positions # scale = 10 # poscar = open('POSCARk','w') # poscar.write('Cs I kpoints vs B'+'\n') #different sizes from this label # poscar.write('1.0\n') # for i in [0,1,2]: # poscar.write('%20.15f %20.15f %20.15f \n' % (scale*Bv[0,i], scale*Bv[1,i], scale*Bv[2,i])) # poscar.write('1 %i\n' %npts) # poscar.write('Cartesian\n') # poscar.write('0.0 0.0 0.0\n') # for i in range(npts): # poscar.write('%20.15f %20.15f %20.15f \n' % (scale*kpts[0,i],scale*kpts[1,i],scale*kpts[2,i])) # poscar.close() #write POSCAR with irred BZ. for vmd: put B vectors in lattice, and kmesh in atomic positions scale = 10 poscar = open('POSCARkred','w') poscar.write('Kpoints in BZ'+'\n') #different sizes from this label poscar.write('1.0\n') for i in [0,1,2]: poscar.write('%20.15f %20.15f %20.15f \n' % (scale*Bv[0,i], scale*Bv[1,i], scale*Bv[2,i])) poscar.write('1 %i\n' %nksymm) poscar.write('Cartesian\n') poscar.write('0.0 0.0 0.0\n') for i in range(nksymm): poscar.write('%20.15f %20.15f %20.15f %20.15f \n' % (scale*kptssymm[0,i],scale*kptssymm[1,i],scale*kptssymm[2,i], weights[i])) poscar.close() kpoints = open('KPOINTS','w') kpoints.write('BCH generated'+'\n') #different sizes from this label kpoints.write('%i\n' % nksymm) kpoints.write('Reciprocal lattice units\n') for i in range(nksymm): kpoints.write('%20.15f %20.15f %20.15f %i\n' % (kptssymm[0,i],kptssymm[1,i],kptssymm[2,i], weights[i])) kpoints.close()
def bestmeshIter_vary_pf(Blatt, Nmesh, path): '''The kmesh can be related to the reciprocal lattice B by B = KM, where M is an integer 3x3 matrix So K = B Inv(M). Change M one element at a time to minimize the errors in symmetry and the cost in S/V and Nmesh ''' ############################################################## ########################## Script ############################ # print path.split('/') npathsegs = len(path.split('/')) # print npathsegs vaspinputdir = '/'.join( path.split('/')[0:npathsegs - 3] ) + '/vaspinput/' #up two levels, 2 are for spaces at beg and end # print vaspinputdir M = zeros((3, 3), dtype=int) S = zeros((3, 3), dtype=fprec) B = lattice() A = lattice() K = lattice() status = '' pf_minsv = 0 pf_sv2fcc = 0 pf_maxpf = 0 pf_pf2fcc = 0 #kvecs_pf2fcc = identity(3) sym_maxpf = False sym_sv2fcc = False sym_minsv = False sym_pf2fcc = False print 'Target mesh number', Nmesh B.vecs = Blatt / 2 / pi #Don't use 2pi constants in reciprocal lattice here # B.pftarget = 0.7405 #default best packing fraction #############End BCT lattice eps = 1.0e-6 B.Nmesh = Nmesh print 'B vectors (differ by 2pi from traditional)' print B.vecs # #print 'B transpose'; print transpose(B.vecs) B.det = det(B.vecs) print 'Det of B', B.det print 'Orth Defect of B', orthdef(B.vecs) print 'Surf/vol of B', surfvol(B.vecs) pfB = packingFraction(B.vecs) print 'Packing fraction of B:', pfB [B.symops, B.nops] = getGroup(B.vecs) B.msymops = intsymops(B) #integer sym operations in B basis # print'Symmetry operators in basis of B' # for i in range: # print B.msymops[:,:,i];print # printops_eigs(B) B.lattype = latticeType(B.nops) print 'Lattice type:', B.lattype A = lattice() A.vecs = trimSmall(inv(transpose(B.vecs))) [A.symops, A.nops] = getGroup(A.vecs) A.msymops = intsymops(A) print 'Real space lattice A' print A.vecs print 'Det A', det(A.vecs) pfA = packingFraction(A.vecs) print 'Packing fraction of A:', pfA # print 'current dir for meshesfile', os.getcwd() meshesfile = open('meshesfile', 'w') # meshesfile = open('meshesfile2','w') meshesfile.write('N target %i\n' % B.Nmesh) meshesfile.write('Format: pf then Nmesh then kmesh\n\n') pflist = [] # for pftry in frange(pfB/2,0.75,0.005): for pftry in frange(pfB / 2, 0.75, 0.01): # for pftry in frange(.3,0.505,0.005): print '\nPacking fraction target', pftry B.pftarget = pftry pf_orth = 0 pf_orth2fcc = 0 sym_orth = False sym_orth2fcc = False #'--------------------------------------------------------------------------------------------------------' #'--------------------------------------------------------------------------------------------------------' M = zeros((3, 3), dtype=int) ctest = [] type = 'maxpfsym' print type ctrials = [3] a = rint(Nmesh**(1 / 3.0)) # f = int(Nmesh/a/a) randnums = zeros(9) print 'M scale a', a for c in ctrials: # ri = [randint(5) for i in range(9)] # M = array([[-a+ri[0], a/c +ri[1] , a/c+ri[2]],[a/c+ri[3],-a+ri[4],a/c+ri[5]],\ # [a/c+ri[6],a/c+ri[7],-a+ri[8]]]) #bcc like best avg pf on 50: 0.66 #HNF:::::: M = array([[a, 0 , 0], [a/c,a,0],\ [a/c,a/c,a]]) #bcc like best avg pf on 50: 0.66 # # M = array([[-a+1, a/c , a/c],[a/c,-a,a/c],[a/c,a/c,-a-1]]) #bcc like best avg pf on 50: 0.66 # M = array([[a, 0,0],[0,a,0],[0,0,a+3]]) # M = array([[-16 , 1 , 5 ], # [6 , -10 , 5], # [-6 , -1 , 6 ]]) # M = array([[5, a/c , a/c],[a/c,0,a/c],[a/c,a/c,-5]]) #fcc like best avg pf on 50: 0.59 M = rint(M * (B.Nmesh / abs(det(M)))**(1 / 3.0)) print 'Start mesh trial' print M # [M,K] = findmin(M,B,type) # print 'Test trial M'; print M ctest.append(cost(M, B, type)) # print'Trial costs',ctest cbest = ctrials[argmin(ctest)] # print'Best c', cbest iternpf = 0 itermaxnpf = 10 itermaxsym = 5 # bestpf = 100 # NPFcost = 100;delNPFcost = -1 #initial values type = 'maxpfsym' print type delcost = -1 lowcost = 1000 #initialize #### while iternpf<itermaxnpf and delNPFcost <0 and abs(delNPFcost)>0.1 : while iternpf < itermaxnpf and delcost < -0.1: oldcost = cost(M, B, type) # NPFcost = cost(M,B,'maxpf') # delNPFcost = (NPFcost-oldNPFcost)/NPFcost : '''Here we let M vary in the search, but record pf and kvecs when we find min cost''' # print 'cost(N,PF):', cost(M,B,type) # while not symm and and iternpf<itermax: M = rint(M * (B.Nmesh / abs(det(M)))**(1 / 3.0)) print 'Scaled M' print M iternpf += 1 print 'Iteration', type, iternpf, '**********' [M, K] = findmin(M, B, type) M = rint(M) itersym = 0 symm = False while not symm and itersym < itermaxsym: itersym += 1 print 'Symmetry iteration', itersym, '-------' # print 'Nmesh', abs(det(M)), 'packing', packingFraction(dot(B.vecs,inv(M))) # M = rint(minkM(M,B))#; print'Mink reduced M'; print M for iop in range(B.nops): M = rint(findmin_i(M, B, iop)) # M = rint(minkM(M,B))#; print'Mink reduced M'; print M if abs(det(M) - B.Nmesh ) / B.Nmesh > 0.15: #how far off from target N M = rint(M * (B.Nmesh / abs(det(M)))**(1 / 3.0)) print 'Scaled M' print M K = lattice() K.vecs = trimSmall(dot(B.vecs, inv(M))) K.det = abs(det(K.vecs)) K.Nmesh = B.det / K.det symm = checksymmetry(K.vecs, B) print 'Symmetry check', symm if symm: newcost = cost(M, B, type) if newcost - lowcost < 0: lowcost = newcost print 'New lowcost', newcost pf_maxpf = packingFraction(K.vecs) sym_maxpf = True kvecs_maxpf = K.vecs # if pf_maxpf<bestpf: bestpf = pf_maxpf; bestM = M print 'Packing fraction', pf_maxpf, 'vs original B', pfB print 'Nmesh', K.Nmesh, 'vs target', B.Nmesh delcost = cost(M, B, type) - oldcost #write to files # meshesfile.write('Packing fraction target %f\n' % pftry) if symm and pf_maxpf not in pflist: pflist.append(pf_maxpf) # meshesfile.write('Packing fraction achieved %f\n' % pf_maxpf) meshesfile.write('%12.8f %8.3f \n' % (pf_maxpf, K.Nmesh)) # meshesfile.write('M\n') # for i in range(3): # for j in range(3): # meshesfile.write('%i6' %M[i,j]) # meshesfile.write('\n') ## meshesfile.write('\n') # meshesfile.write('k mesh\n') M = rint(dot(inv(K.vecs), B.vecs)) for i in range(3): for j in range(3): meshesfile.write('%i ' % int(rint(M[i, j]))) meshesfile.write('\n') meshesfile.write('\n') meshesfile.flush() M = rint(dot(inv(K.vecs), B.vecs) ) #We assign K only when M is ideal, so remake the best M print 'Check M' print M print 'Check K' print K.vecs print 'Check B' print B.vecs print 'Check pf' print packingFraction(K.vecs) #create a dir and prepare for vasp run newdir = str(round(pf_maxpf, 4)) newpath = path + newdir + '/' if not os.path.isdir(newpath): os.system('mkdir %s' % newpath) os.chdir(newpath) os.system('cp %s* %s' % (vaspinputdir, newpath)) os.system('cp %sPOSCAR %s' % (path, newpath)) print 'SKIPPING writekpts_vasp_M AND submission' # writekpts_vasp_M(newpath,B,M,K) # writekpts_vasp_pf(newpath,K.vecs,pf_maxpf,K.Nmesh) writejobfile(newpath) # subprocess.call(['sbatch', 'vaspjob']) #!!!!!!! Submit jobs os.chdir(path) else: 'do nothing' # meshesfile.write('Failed symmetry\n\n') meshesfile.close() # Summary pfs = [pfB] pftypes = ['B_latt'] ks = [B.vecs / a] #one solutions is to simply divide B by an integer if not (sym_minsv or sym_sv2fcc or sym_maxpf or pf_pf2fcc or sym_orth or sym_orth2fcc): meshtype = 'B_latt_revert' #status += 'MHPrevert;' K.vecs = B.vecs / a K.det = abs(det(K.vecs)) K.Nmesh = abs(B.det / K.det) pfmax = packingFraction(K.vecs) else: if sym_orth: pfs.append(pf_orth) pftypes.append('orth') ks.append(kvecs_orth) if sym_orth2fcc: pfs.append(pf_orth2fcc) pftypes.append('orth2fcc') ks.append(kvecs_orth2fcc) if sym_maxpf: pfs.append(pf_maxpf) pftypes.append('maxpf') ks.append(kvecs_maxpf) if sym_pf2fcc: pfs.append(pf_pf2fcc) pftypes.append('pf2fcc') ks.append(kvecs_pf2fcc) pfmax = max(pfs) meshtype = pftypes[argmax(pfs)] K.vecs = ks[argmax(pfs)] K.det = abs(det(K.vecs)) K.Nmesh = B.det / K.det # return [K.vecs, K.Nmesh, B.Nmesh, B.lattype, pfB, pf_orth, pf_orth2fcc, pf_maxpf, pf_minsv, pf_sv2fcc, pfmax, meshtype, fcctype(B),status] return [ K.vecs, K.Nmesh, B.Nmesh, B.lattype, pfB, pf_orth, pf_orth2fcc, pf_maxpf, pf_pf2fcc, pfmax, meshtype, fcctype(B), cbest, status ]
def bestmeshIter_vary_N(Blatt,Nmesh,path): '''The kmesh can be related to the reciprocal lattice B by B = KM, where M is an integer 3x3 matrix So K = B Inv(M). Change M one element at a time to minimize the errors in symmetry and the cost in S/V and Nmesh ''' ############################################################## ########################## Script ############################ vaspinputdir = '/fslhome/bch/cluster_expansion/alir/AFLOWDATAf1_50e/vaspinput/' M = zeros((3,3),dtype = int) S = zeros((3,3),dtype = fprec) B = lattice() A = lattice() K = lattice() status = '' pf_minsv = 0; pf_sv2fcc = 0; pf_maxpf = 0; pf_pf2fcc = 0; #kvecs_pf2fcc = identity(3) sym_maxpf = False; sym_sv2fcc = False; sym_minsv = False; sym_pf2fcc = False a = rint(Nmesh**(1/3.0)); f = int(Nmesh/a/a) print 'Target mesh number', Nmesh B.vecs = Blatt/2/pi #Don't use 2pi constants in reciprocal lattice here # B.pftarget = 0.7405 #default best packing fraction #############End BCT lattice eps = 1.0e-6 B.Nmesh = Nmesh print 'B vectors (differ by 2pi from traditional)';print B.vecs # #print 'B transpose'; print transpose(B.vecs) B.det = det(B.vecs) print 'Det of B', B.det print 'Orth Defect of B', orthdef(B.vecs) print 'Surf/vol of B', surfvol(B.vecs) pfB = packingFraction(B.vecs) print 'Packing fraction of B:', pfB [B.symops,B.nops] = getGroup(B.vecs) B.msymops = intsymops(B) #integer sym operations in B basis # print'Symmetry operators in basis of B' # for i in range: # print B.msymops[:,:,i];print # printops_eigs(B) B.lattype = latticeType(B.nops) print 'Lattice type:', B.lattype A = lattice() A.vecs = trimSmall(inv(transpose(B.vecs))) [A.symops,A.nops] = getGroup(A.vecs) A.msymops = intsymops(A) print 'Real space lattice A'; print A.vecs print 'Det A', det(A.vecs) pfA = packingFraction(A.vecs) print 'Packing fraction of A:', pfA meshesfile = open('meshesfile','a') meshesfile.write('N target %i\n' % B.Nmesh) meshesfile.write('Format: pf then Nmesh then kmesh\n\n') pflist = [] # M0 = array([[2, 2, 2,], # [2, 2, -2], # [-2, 2, -2]]) # # 0.74050000 64.000 #-5 1 -3 #6 2 2 #3 1 -3 M0 = array([[-5, 1, -3,], [6, 2, 2], [3, 1, -3]]) # for div in [256,128,64,32,16,8,4,2,1]: # print '\nDivisor',div # nMP = rint((Nmesh/div)**(1/3.0)) # M = array([[nMP,0,0],[0,nMP,0],[0,0,nMP]]); for fac in [1,2,3,4,5,6,7,8]: print '\nMultiplier',fac M = fac*M0 # M = array([[4,12,-4], # [-11,4,-26], # [-26,-4,-11]]); K = lattice();K.vecs = trimSmall(dot(B.vecs,inv(M)));K.det = abs(det(K.vecs)); K.Nmesh = B.det/K.det print 'Number of points',det(M) print 'Check M' print M print 'Check K' print K.vecs print 'Check B' print B.vecs print 'Check pf' print packingFraction(K.vecs) #create a dir and prepare for vasp run newdir = str(K.Nmesh) newpath = path + newdir + '/' if not os.path.isdir(newpath): os.system('mkdir %s' % newpath) os.chdir(newpath) os.system ('cp %s* %s' % (vaspinputdir,newpath)) os.system ('cp %sPOSCAR %s' % (path,newpath)) writekpts_vasp_M(newpath,B,M,K) # writekpts_vasp_pf(newpath,K.vecs,pf_maxpf,K.Nmesh) writejobfile(newpath) # print 'submitting job' subprocess.call(['sbatch', 'vaspjob']) #!!!!!!! Submit jobs os.chdir(path)