def fcctype(B): '''See if an fcc-like mesh has the lattice symmetry''' latt2 = zeros((3,3),dtype = float) latt2[:,0] = B.vecs[:,1]/2 + B.vecs[:,2]/2 latt2[:,1] = B.vecs[:,2]/2 + B.vecs[:,0]/2 latt2[:,2] = B.vecs[:,0]/2 + B.vecs[:,1]/2 return checksymmetry(latt2,B)
def fcctype(B): '''See if an fcc-like mesh has the lattice symmetry''' latt2 = zeros((3, 3), dtype=float) latt2[:, 0] = B.vecs[:, 1] / 2 + B.vecs[:, 2] / 2 latt2[:, 1] = B.vecs[:, 2] / 2 + B.vecs[:, 0] / 2 latt2[:, 2] = B.vecs[:, 0] / 2 + B.vecs[:, 1] / 2 return checksymmetry(latt2, B)
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 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 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 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'
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 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 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 '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 testindices MT = zeros((3,3),dtype = int) if len(testvecs) == 0: print 'No eigen directions' 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. #Since all symmetry operators will be diagonal in this mesh representaion #of eigenvectors of , # MT[:,0] = testvecs[0] k = testindices[0][0] op = array(A.symops[:,:,k]) # print trimSmall(op) m = trimSmall(dot(dot(inv(A.vecs[:,:]), A.symops[:,:,k]),A.vecs[:,:]) ) [vals,vecs]=eig(m); vecs = array(vecs) # print vecs
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]