示例#1
0
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]
示例#4
0
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
    ]
示例#6
0
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'    
示例#7
0
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
    ]
示例#8
0
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'
示例#9
0
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
示例#11
0
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]