예제 #1
0
def findmin(M,B,run): #normal routine for varying a single element at a time. 
    '''Finds minimum cost for the lattice by varying the integers of m, in the element that gives steepest descent
    The 'run' indicates the cost function to use'''
    maxsteps = 10000
    istep = 1
    M = minkM(M,B)#;print'Mink reduced M'; print M
    
    while istep<maxsteps:

#        sys.exit('stop')
        bestindex = changewhich(M,B,run)
        if bestindex[2]==0:#found minimum
#            newcost = cost(M,B,run)
            break
        else:
            M[bestindex[0],bestindex[1]] += bestindex[2]
#            newcost = cost(M,B,run)
            if run == 'minsvsym' and B.Nmesh/float(det(M))>1.2: M = M*2 # open up search space when when det(M) gets too low
#            print; print M;print newcost

        istep += 1
    if istep < maxsteps:
#        print 'Found minimum after %i steps' % istep
#        print 'Best M'; print M
        K = lattice();K.vecs = trimSmall(dot(B.vecs,inv(M)));K.det = abs(det(K.vecs)); K.Nmesh = B.det/K.det             
    else:
        print 'Ended without minimum after maximum %i steps' % istep
        sys.exit('Stop')
    return [trimSmall(M),K]
예제 #2
0
def findmin_i(M,B,iop):
    '''Finds minimum cost for the lattice by varying the integers of m, in the element that gives steepest descent
    The 'run' indicates the cost function to use'''
    maxsteps = 200
    istep = 1
#    print 'M in findmin'; print M
    while istep<maxsteps:
        bestindex = changewhich_i(M,B,iop)
#        print 'bestindex',bestindex
        if bestindex[2]==0:#found minimum
            newcost = costi(M,B,iop)
#            print 'newcost',newcost
            break
        else:
            M[bestindex[0],bestindex[1]] += bestindex[2]
#            print 'M altered in findmin_i';print M
            newcost = costi(M,B,iop)
#            print; print M;print newcost
        istep += 1
    if istep < maxsteps:
        'go on'
#        print 'Found minimum after %i steps' % istep
#        print 'Best M'; print M
    else:
        print 'Ended without minimum after %i steps' % istep
#        sys.exit('Stop')
    return trimSmall(M)
예제 #3
0
def findmin_i(M, B, iop):
    '''Finds minimum cost for the lattice by varying the integers of m, in the element that gives steepest descent
    The 'run' indicates the cost function to use'''
    maxsteps = 200
    istep = 1
    #    print 'M in findmin'; print M
    while istep < maxsteps:
        bestindex = changewhich_i(M, B, iop)
        #        print 'bestindex',bestindex
        if bestindex[2] == 0:  #found minimum
            newcost = costi(M, B, iop)
            #            print 'newcost',newcost
            break
        else:
            M[bestindex[0], bestindex[1]] += bestindex[2]
            #            print 'M altered in findmin_i';print M
            newcost = costi(M, B, iop)
#            print; print M;print newcost
        istep += 1
    if istep < maxsteps:
        'go on'
#        print 'Found minimum after %i steps' % istep
#        print 'Best M'; print M
    else:
        print 'Ended without minimum after %i steps' % istep


#        sys.exit('Stop')
    return trimSmall(M)
예제 #4
0
def findmin_i(M, B, iop):
    '''Finds minimum cost for the lattice by varying the integers of m, in the element that gives steepest descent
    The 'run' indicates the cost function to use'''
    maxsteps = 200
    istep = 1
    #    print 'M in findmin'; print M
    while istep < maxsteps:
        bestindex = changewhich_i(M, B, iop)
        #        print 'bestindex',bestindex
        if bestindex[2] == 0:  #found minimum
            newcost = costi(M, B, iop)
            #            print 'newcost',newcost
            break
        else:
            #            print 'M before change';print M
            #            print bestindex[0],bestindex[1]
            M[bestindex[0], bestindex[1]] += bestindex[2]
            print 'M altered in findmin_i'
            print M
            newcost = costi(M, B, iop)
#            print; print M;print newcost
        istep += 1
    if istep < maxsteps:
        'go on'
#        print 'Found minimum after %i steps' % istep
#        print 'Best M'; print M
    else:
        print 'Ended without minimum after %i steps' % istep


#        print 'Restart with different M'
#        a = B.Nmesh**(1/3.0); c = 3;
#        M = array([[-a+5, a/c , a/c],[a/c,-a,a/c],[a/c,a/c,-a-5]])
#        sys.exit('Stop')
    return trimSmall(M)
예제 #5
0
def findmin_i(M,B,iop):
    '''Finds minimum cost for the lattice by varying the integers of m, in the element that gives steepest descent
    The 'run' indicates the cost function to use'''
    maxsteps = 200
    istep = 1
#    print 'M in findmin'; print M
    while istep<maxsteps:
        bestindex = changewhich_i(M,B,iop)
#        print 'bestindex',bestindex
        if bestindex[2]==0:#found minimum
            newcost = costi(M,B,iop)
#            print 'newcost',newcost
            break
        else:
#            print 'M before change';print M
#            print bestindex[0],bestindex[1]
            M[bestindex[0],bestindex[1]] += bestindex[2]
            print 'M altered in findmin_i';print M
            newcost = costi(M,B,iop)
#            print; print M;print newcost
        istep += 1
    if istep < maxsteps:
        'go on'
#        print 'Found minimum after %i steps' % istep
#        print 'Best M'; print M
    else:
        print 'Ended without minimum after %i steps' % istep
#        print 'Restart with different M'
#        a = B.Nmesh**(1/3.0); c = 3;
#        M = array([[-a+5, a/c , a/c],[a/c,-a,a/c],[a/c,a/c,-a-5]])
#        sys.exit('Stop')
    return trimSmall(M)
예제 #6
0
def costi(M, B, iop):
    '''Here the symmetry cost is that due to only one symm operation,iop'''
    if det(M) < 1: return 1000
    kvecs = dot(B.vecs, inv(M))
    #    print 'iop in costi'; print B.symops[:,:,iop]
    mmat = trimSmall(dot(dot(inv(kvecs), B.symops[:, :, iop]), kvecs))
    #    print 'mmat in costi';print mmat
    operr = 0.0
    for i in range(3):
        for j in range(3):
            if abs(rint(mmat[i, j]) - mmat[i, j]) > 1.0e-4:
                operr += abs(rint(mmat[i, j]) - mmat[i, j])


#                    print iop, 'Symmetry failed for mmat[i,j]',mmat[i,j]
#                    print 'Cartesian operator'
#                    print parentlatt.symops[:,:,iop]
#                    print 'Cartesian Lattice'
#                    print lmat
#        Nscale =0*.05#.05;
#        Ncost = Nscale * abs((B.det/det(kvecs))-B.Nmesh)/B.Nmesh
#        shapescale = 0 * 0.01; shapecost = shapescale * surfvol(kvecs)
        cost = operr  #+ Ncost + shapecost

    return cost
예제 #7
0
def three_perp_eigs(A):
    testvecs = []
    testindices = []
    svecs = zeros((3, 3), dtype=float)
    for k in range(A.nops):
        #        print; print k
        op = array(A.symops[:, :, k])
        [vals, vecs] = eig(op)
        vecs = array(vecs)
        #find operations with nondegenerate real eigenvalues
        #        print k, nonDegen(vals)
        for i in nonDegen(vals):
            if not matchDirection(transpose(vecs[:, i]),
                                  testvecs):  #keep only unique directions
                testvecs.append(real(vecs[:, i]))
                testindices.append([k, i])
    if len(testvecs) >= 3:
        testvecstrials = [list(x) for x in combinations(testvecs, 3)]
        #        print testvecstrials
        for trial in testvecstrials:
            #find superlattice
            for i in range(3):
                #                print; print 'trial u',trial[i]
                svecs[i, :] = lattvec_u(A.vecs, trial[i])


#                print svecs[i,:]
#                print 'lattice m for lattice vector', dot(inv(A.vecs),transpose(svecs[i,:]))
#            print 'cosvecs', cosvecs(svecs[0,:],svecs[1,:]) , cosvecs(svecs[1,:],svecs[2,:]) , cosvecs(svecs[2,:],svecs[0,:])
#            print arenormal(svecs[0,:],svecs[1,:]) , arenormal(svecs[1,:],svecs[2,:]) , arenormal(svecs[2,:],svecs[0,:])
            if arenormal(svecs[0, :], svecs[1, :]) and arenormal(
                    svecs[1, :], svecs[2, :]) and arenormal(
                        svecs[2, :], svecs[0, :]):
                S = transpose(array([svecs[0, :], svecs[1, :], svecs[2, :]]))
                #                print 'found 3 perp'; print unique_anorms(S)
                #                print S; print norm(S[:,0]); print norm(S[:,1]); print norm(S[:,2])
                #                print unique_anorms(S).count(True); print A.lattype
                if A.lattype == 'Cubic' and unique_anorms(S).count(True) == 0:
                    return trimSmall(S)
                if A.lattype == 'Tetragonal' and unique_anorms(S).count(
                        True) <= 1:
                    return trimSmall(S)
                if A.lattype == 'Orthorhombic':  #and unique_anorms(S).count(True) == 3:
                    return trimSmall(S)
    sys.exit('error in three_perp_eigs')
예제 #8
0
def minkM(M,B):
    '''Transform to M on same lattice, but minked''' 
    kvecs = dot(B.vecs,inv(M))
#    print det(kvecs); print kvecs
    if det(kvecs) < 0.1: #do reduction in inverse space so we don't run into small number problems
        A = transpose(inv(B.vecs))
        S = dot(A,transpose(M))
        S = transpose(mink_reduce(transpose(S), 1e-4))
        M = transpose(dot(inv(A),S))
    else:
        kvecs = transpose(mink_reduce(transpose(kvecs), 1e-4)) #fortran routines use vectors as rows
        M = rint(dot(inv(kvecs),B.vecs))
    return trimSmall(M)
예제 #9
0
def three_perp_eigs(A):
    testvecs = []; testindices = []
    svecs = zeros((3,3),dtype = float)
    for k in range(A.nops):
#        print; print k
        op = array(A.symops[:,:,k])
        [vals,vecs]=eig(op); vecs = array(vecs)      
        #find operations with nondegenerate real eigenvalues
#        print k, nonDegen(vals)
        for i in nonDegen(vals):
            if not matchDirection(transpose(vecs[:,i]),testvecs): #keep only unique directions    
                testvecs.append(real(vecs[:,i]))
                testindices.append([k,i])
    if len(testvecs) >= 3:
        testvecstrials = [list(x) for x in combinations(testvecs,3)]
#        print testvecstrials
        for trial in testvecstrials:
            #find superlattice
            for i in range(3):
#                print; print 'trial u',trial[i]
                svecs[i,:] = lattvec_u(A.vecs,trial[i])
#                print svecs[i,:]
#                print 'lattice m for lattice vector', dot(inv(A.vecs),transpose(svecs[i,:]))
#            print 'cosvecs', cosvecs(svecs[0,:],svecs[1,:]) , cosvecs(svecs[1,:],svecs[2,:]) , cosvecs(svecs[2,:],svecs[0,:])
#            print arenormal(svecs[0,:],svecs[1,:]) , arenormal(svecs[1,:],svecs[2,:]) , arenormal(svecs[2,:],svecs[0,:])           
            if arenormal(svecs[0,:],svecs[1,:]) and arenormal(svecs[1,:],svecs[2,:]) and arenormal(svecs[2,:],svecs[0,:]):
                S = transpose(array([svecs[0,:],svecs[1,:],svecs[2,:]]))
#                print 'found 3 perp'; print unique_anorms(S)
#                print S; print norm(S[:,0]); print norm(S[:,1]); print norm(S[:,2])
#                print unique_anorms(S).count(True); print A.lattype
                if A.lattype == 'Cubic' and unique_anorms(S).count(True) == 0:
                    return trimSmall(S) 
                if A.lattype == 'Tetragonal' and unique_anorms(S).count(True) <= 1:
                    return trimSmall(S) 
                if A.lattype == 'Orthorhombic': #and unique_anorms(S).count(True) == 3:
                    return trimSmall(S)
    sys.exit('error in three_perp_eigs')
예제 #10
0
def findmin(M, B,
            run):  #normal routine for varying a single element at a time.
    '''Finds minimum cost for the lattice by varying the integers of m, in the element that gives steepest descent
    The 'run' indicates the cost function to use'''
    maxsteps = 10000
    istep = 1
    #    M = minkM(M,B)#;print'Mink reduced M'; print M
    while istep < maxsteps:

        #        sys.exit('stop')
        bestindex = changewhich(M, B, run)
        #        print 'bestindex',bestindex
        if bestindex[2] == 0:  #found minimum
            #            newcost = cost(M,B,run)
            break
        else:
            M[bestindex[0], bestindex[1]] += bestindex[2]


#            print 'M altered in findmin';print M
#            newcost = cost(M,B,run)
#            if run == 'minsvsym' and B.Nmesh/float(det(M))>1.2: M = M*2 # open up search space when when det(M) gets too low
#            print; print M;print newcost

        istep += 1
    if istep < maxsteps:
        #        print 'Found minimum after %i steps' % istep
        #        print 'Best M'; print M
        K = lattice()
        K.vecs = trimSmall(dot(B.vecs, inv(M)))
        K.det = abs(det(K.vecs))
        K.Nmesh = B.det / K.det
    else:
        print 'Ended without minimum after maximum %i steps' % istep
        sys.exit('Stop')
    return [trimSmall(M), K]
예제 #11
0
def minkM(M, B):
    '''Transform to M on same lattice, but minked'''
    kvecs = dot(B.vecs, inv(M))
    #    print det(kvecs); print kvecs
    if det(
            kvecs
    ) < 0.1:  #do reduction in inverse space so we don't run into small number problems
        A = transpose(inv(B.vecs))
        S = dot(A, transpose(M))
        S = transpose(mink_reduce(transpose(S), 1e-4))
        M = transpose(dot(inv(A), S))
    else:
        kvecs = transpose(mink_reduce(
            transpose(kvecs), 1e-4))  #fortran routines use vectors as rows
        M = rint(dot(inv(kvecs), B.vecs))
    return trimSmall(M)
예제 #12
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]
예제 #13
0
def unconstrainedSVsearch(B):
    K = lattice()
    K.vecs = zeros((3, 3), dtype=float)
    Nmesh = B.Nmesh
    M = zeros((3, 3), dtype=np_int)
    #    print 'Target N kpoints', Nmesh
    a = rint(Nmesh ** (1 / 3.0))
    c = a
    f = int(Nmesh / a / c)
    M[0, 0] = a
    M[1, 1] = c
    M[2, 2] = f
    print "Starting M"
    print M
    maxsteps = 1000
    istep = 1
    while istep < maxsteps:
        bestindex = changewhich(M, B)
        if bestindex[2] == 0:  # found minimum
            newcost = cost(M, B)
            break
        else:
            M[bestindex[0], bestindex[1]] += bestindex[2]
            newcost = cost(M, B)
        istep += 1
    if istep < maxsteps:
        print
        print "Found minimum after %i steps" % istep
        #        print 'Best M'; print M
        K = lattice()
        K.vecs = trimSmall(dot(B.vecs, inv(M)))

    #        K.det = det(K.vecs)
    #        print 'Best K mesh\n', K.vecs
    #        print 'Number of mesh points', B.det/K.det
    #        print 'Minimum cost', newcost
    #        print 'Orth defect',orthdef(K.vecs)
    #        print 'Surface/vol', surfvol(K.vecs)
    #        print 'Mesh vector lengths', norm(K.vecs[:,0]),norm(K.vecs[:,1]),norm(K.vecs[:,2])

    else:
        print "Ended without minimum after maximum %i steps" % istep
    return [M, K.vecs]
예제 #14
0
def unconstrainedSVsearch(B):
    K = lattice()
    K.vecs = zeros((3, 3), dtype=float)
    Nmesh = B.Nmesh
    M = zeros((3, 3), dtype=np_int)
    #    print 'Target N kpoints', Nmesh
    a = rint(Nmesh**(1 / 3.0))
    c = a
    f = int(Nmesh / a / c)
    M[0, 0] = a
    M[1, 1] = c
    M[2, 2] = f
    print 'Starting M'
    print M
    maxsteps = 1000
    istep = 1
    while istep < maxsteps:
        bestindex = changewhich(M, B)
        if bestindex[2] == 0:  #found minimum
            newcost = cost(M, B)
            break
        else:
            M[bestindex[0], bestindex[1]] += bestindex[2]
            newcost = cost(M, B)
        istep += 1
    if istep < maxsteps:
        print
        print 'Found minimum after %i steps' % istep
        #        print 'Best M'; print M
        K = lattice()
        K.vecs = trimSmall(dot(B.vecs, inv(M)))

#        K.det = det(K.vecs)
#        print 'Best K mesh\n', K.vecs
#        print 'Number of mesh points', B.det/K.det
#        print 'Minimum cost', newcost
#        print 'Orth defect',orthdef(K.vecs)
#        print 'Surface/vol', surfvol(K.vecs)
#        print 'Mesh vector lengths', norm(K.vecs[:,0]),norm(K.vecs[:,1]),norm(K.vecs[:,2])

    else:
        print 'Ended without minimum after maximum %i steps' % istep
    return [M, K.vecs]
예제 #15
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]
예제 #16
0
def costi(M,B,iop):
    '''Here the symmetry cost is that due to only one symm operation,iop'''
    if det(M)<1: return 1000
    kvecs = dot(B.vecs,inv(M))
#    print 'iop in costi'; print B.symops[:,:,iop]
    mmat = trimSmall(dot(dot(inv(kvecs),B.symops[:,:,iop]),kvecs))
#    print 'mmat in costi';print mmat
    operr = 0.0
    for i in range(3):
        for j in range(3):
            if abs(rint(mmat[i,j])-mmat[i,j])>1.0e-4:
                operr += abs(rint(mmat[i,j])-mmat[i,j])
#                    print iop, 'Symmetry failed for mmat[i,j]',mmat[i,j]
#                    print 'Cartesian operator' 
#                    print parentlatt.symops[:,:,iop] 
#                    print 'Cartesian Lattice'
#                    print lmat
        Nscale =0*.05#.05; 
        Ncost = Nscale * abs((B.det/det(kvecs))-B.Nmesh)/B.Nmesh 
        shapescale = 0 * 0.01; shapecost = shapescale * surfvol(kvecs)
        cost = operr  + Ncost + shapecost

    return cost
예제 #17
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]
예제 #18
0
B.Nmesh = Nmesh
print 'B vectors';print B.vecs
print 'B transpose'; print transpose(B.vecs)
print 'Det of B', B.det
print 'Orth Defect of B', orthdef(B.vecs)
print 'Surf/vol of B', surfvol(B.vecs)

[B.symops,B.nops] = getGroup(B.vecs)
print 'Number of symmetry operations', B.nops
#print 'symmetry operations of B\n'
#for j in range(nopsB):
#    print j
#    op = matrix(symopsB[:,:,j])
#    print op
#find real lattice
A.vecs = trimSmall(transpose(inv(B.vecs)))
A.det = det(A.vecs)
A.Nmesh = Nmesh
print 'A vectors';print A.vecs
print 'Det of A', A.det
print 'Orth Defect of A', orthdef(A.vecs)
print 'Surf/vol of A', surfvol(A.vecs)

[A.symops,A.nops] = getGroup(A.vecs)
if A.nops != B.nops: 
    sys.exit('Number of operations different for A and B; stop')

print 'symmetry operations R of A\n'
testvecs = [];oplist = []
for k in range(A.nops):
    print; print k
예제 #19
0
        scaleposcar(scale)  #inserts length scale into appropriate spot.
        writefile([str(dL)], finalDir + dir + 'detL')
        writefile([lattype], finalDir + dir + 'lattype')
        os.system('cp %s* %s' % (vaspinputdir, '.'))
        os.system('rm slurm*')
        n = m * dL
        shift = '0.00'
        if meshtype == 'cub':
            M = n * transpose(inv(A))
            print 'M matrix for cubic mesh'
            print M
            print 'det M (kpoints in unreduced 1BZ)', det(M)
            writekpts_cubic_n(n, shift)
        if meshtype == 'fcc':
            M = trimSmall(n * dot(bccsq, transpose(inv(L))))
            print 'test K'
            print trimSmall(dot(B, inv(M)))
            #            print 'test Bo';print transpose(inv(platt))
            print 'M matrix for fcc mesh'
            print M
            print 'det M (kpoints in unreduced 1BZ)', det(M)

            writekpts_fcc_n(n, shift)
        writefile([str(abs(det(M)))], finalDir + dir + 'detM')

        #        writekpts_vasp_M(finalDir+dir,B,M,Bnops,Bsymops) #define K's explicitly!!!

        writejobfile(finalDir + dir)
        if n <= nmax:  #(don't submit the biggest jobs
            ''
예제 #20
0
    def enerGrad(self, indComps):
        '''restrict the energy sum to the pairs that contain independent points'''
        #         print 'oldindvecs',self.oldindVecs
        indVecs = indComps.reshape((self.nIndIn, 3))
        self.oldindVecs = indVecs
        #update all positions by symmetry and translation
        self.oldPoints = deepcopy(self.points)
        self.updatePoints(indVecs)
        #indVecs now cannot be used for current points because they might be out of cell.
        #         print 'movement'
        #         for i in range(self.npoints):
        # #             print 'old',i,self.oldPoints[i]['pos']
        # #             print 'new',i,self.points[i]['pos']
        # #             print
        #             move = norm(self.points[i]['pos']-self.oldPoints[i]['pos'])
        #             if move > 1e-6 :
        #                 print i,move

        ener = 0.0
        self.power = 2.0
        #         scale = 1
        for ipos in range(self.nIndIn):
            force = zeros(3)
            rs = zeros(self.npoints,
                       dtype=[('r', 'float'), ('rij', '3float'),
                              ('force', '3float')])

            nearest = -1
            rnearest = 100.0
            for jpos in range(self.npoints):
                rij = self.points[jpos]['pos'] - self.points[ipos]['pos']
                r = norm([rij])
                if r > 1e-4 * self.rmin:
                    if r < rnearest:
                        nearest = jpos
                        rnearest = r
#
#                     epair = r**2 #attractive springs...dumb because those farthest away influence most
#                     force += rij #attractive springs)

                    epair = (self.ravg / r)**self.power
                    forcepair = -self.power * epair / r * rij / r
                    force += forcepair
                    #                     print 'jpos',jpos,r,forcepair
                    ener += epair
                    rs[jpos]['r'] = r
                    rs[jpos]['rij'] = rij
                    rs[jpos]['force'] = forcepair

            self.points[ipos]['force'] = trimSmall(force)

            if ipos in self.indIn:
                rs = sort(rs, order='r')
                #                 print ipos, rs[:20]['r']
                #                 print rs[:20]['rij']
                print ipos, 'pos', self.points[ipos]['pos']
                print 'nerst', self.points[nearest]['pos'], nearest, rnearest
                print 'vectr', trimSmall(self.points[nearest]['pos'] -
                                         self.points[ipos]['pos'])
                print 'force', ipos, self.points[ipos]['force']
        ener = ener / self.nIndIn
        grad = -self.points[:self.nIndIn]['force'].flatten() / self.nIndIn
        print 'energy:', self.count, ener
        print
        #         if self.count == 19:
        #             self.plotPoints(self.points,'pos')
        self.count += 1
        #now update all the dependent positions
        #  ! Note:  need to update the positions at each step!  Do we have to get inside
        #         return ener#
        return ener, grad
예제 #21
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'    
예제 #22
0
B.Nmesh = Nmesh
print 'B vectors';print B.vecs
#print 'B transpose'; print transpose(B.vecs)
print 'Det of B', B.det
print 'Orth Defect of B', orthdef(B.vecs)
print 'Surf/vol of B', surfvol(B.vecs)

[B.symops,B.nops] = getGroup(B.vecs)
print 'Number of symmetry operations', B.nops
#print 'symmetry operations of B\n'
#for j in range(nopsB):
#    print j
#    op = array(symopsB[:,:,j])
#    print op
#find real lattice
A.vecs = trimSmall(transpose(inv(B.vecs)))
A.det = det(A.vecs)
A.Nmesh = Nmesh
print;print 'A vectors';print A.vecs
print 'Det of A', A.det
print 'Orth Defect of A', orthdef(A.vecs)
print 'Surf/vol of A', surfvol(A.vecs)

[A.symops,A.nops] = getGroup(A.vecs)
if A.nops != B.nops: 
    sys.exit('Number of operations different for A and B; stop')

print 'symmetry operations R of A\n'
testvecs = [];testindices = []
for k in range(A.nops):
    print; print k
예제 #23
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
    ]
예제 #24
0
def bestmeshIter_vary_N(Blatt, Nmesh, path):
    '''The kmesh can be related to the reciprocal lattice B by  B = KM, where M is an integer 3x3 matrix
    So K = B Inv(M).  Change M one element at a time to minimize the errors in symmetry and the cost in S/V and Nmesh '''

    ##############################################################
    ########################## Script ############################
    vaspinputdir = '/fslhome/bch/cluster_expansion/alir/AFLOWDATAf1_50e/vaspinput/'
    M = zeros((3, 3), dtype=int)
    S = zeros((3, 3), dtype=fprec)
    B = lattice()
    A = lattice()
    K = lattice()
    status = ''
    pf_minsv = 0
    pf_sv2fcc = 0
    pf_maxpf = 0
    pf_pf2fcc = 0
    #kvecs_pf2fcc = identity(3)
    sym_maxpf = False
    sym_sv2fcc = False
    sym_minsv = False
    sym_pf2fcc = False
    a = rint(Nmesh**(1 / 3.0))
    f = int(Nmesh / a / a)
    print 'Target mesh number', Nmesh

    B.vecs = Blatt / 2 / pi  #Don't use 2pi constants in reciprocal lattice here
    #    B.pftarget = 0.7405 #default best packing fraction

    #############End BCT lattice
    eps = 1.0e-6

    B.Nmesh = Nmesh
    print 'B vectors (differ by 2pi from traditional)'
    print B.vecs  #
    #print 'B transpose'; print transpose(B.vecs)
    B.det = det(B.vecs)
    print 'Det of B', B.det
    print 'Orth Defect of B', orthdef(B.vecs)
    print 'Surf/vol of B', surfvol(B.vecs)
    pfB = packingFraction(B.vecs)
    print 'Packing fraction of B:', pfB
    [B.symops, B.nops] = getGroup(B.vecs)
    B.msymops = intsymops(B)  #integer sym operations in B basis
    #    print'Symmetry operators in basis of B'
    #    for i in range:
    #        print B.msymops[:,:,i];print
    #    printops_eigs(B)
    B.lattype = latticeType(B.nops)
    print 'Lattice type:', B.lattype
    A = lattice()
    A.vecs = trimSmall(inv(transpose(B.vecs)))
    [A.symops, A.nops] = getGroup(A.vecs)
    A.msymops = intsymops(A)
    print 'Real space lattice A'
    print A.vecs
    print 'Det A', det(A.vecs)
    pfA = packingFraction(A.vecs)
    print 'Packing fraction of A:', pfA

    meshesfile = open('meshesfile', 'a')
    meshesfile.write('N target %i\n' % B.Nmesh)
    meshesfile.write('Format: pf then Nmesh then kmesh\n\n')

    pflist = []
    #    M0 = array([[2,   2,   2,],
    #                    [2,   2,   -2],
    #                    [-2,   2,   -2]])
    #
    #      0.74050000    64.000
    #-5   1   -3
    #6   2   2
    #3   1   -3
    M0 = array([[
        -5,
        1,
        -3,
    ], [6, 2, 2], [3, 1, -3]])

    #    for div in [256,128,64,32,16,8,4,2,1]:
    #        print '\nDivisor',div
    #        nMP = rint((Nmesh/div)**(1/3.0))
    #        M = array([[nMP,0,0],[0,nMP,0],[0,0,nMP]]);

    for fac in [1, 2, 3, 4, 5, 6, 7, 8]:
        print '\nMultiplier', fac

        M = fac * M0
        #        M = array([[4,12,-4],
        #                   [-11,4,-26],
        #                   [-26,-4,-11]]);
        K = lattice()
        K.vecs = trimSmall(dot(B.vecs, inv(M)))
        K.det = abs(det(K.vecs))
        K.Nmesh = B.det / K.det
        print 'Number of points', det(M)
        print 'Check M'
        print M
        print 'Check K'
        print K.vecs
        print 'Check B'
        print B.vecs
        print 'Check pf'
        print packingFraction(K.vecs)
        #create a dir and prepare for vasp run
        newdir = str(K.Nmesh)
        newpath = path + newdir + '/'
        if not os.path.isdir(newpath):
            os.system('mkdir %s' % newpath)
        os.chdir(newpath)
        os.system('cp %s* %s' % (vaspinputdir, newpath))
        os.system('cp %sPOSCAR %s' % (path, newpath))
        writekpts_vasp_M(newpath, B, M, K)
        #             writekpts_vasp_pf(newpath,K.vecs,pf_maxpf,K.Nmesh)
        writejobfile(newpath)

        #            print 'submitting job'
        subprocess.call(['sbatch', 'vaspjob'])  #!!!!!!! Submit jobs
        os.chdir(path)
예제 #25
0
    def enerGrad(self,indComps):
        '''restrict the energy sum to the pairs that contain independent points'''
#         print 'oldindvecs',self.oldindVecs
        indVecs = indComps.reshape((self.nIndIn,3))
        self.oldindVecs = indVecs
        #update all positions by symmetry and translation
        self.oldPoints = deepcopy(self.points)
        self.updatePoints(indVecs)
        #indVecs now cannot be used for current points because they might be out of cell.
#         print 'movement'
#         for i in range(self.npoints):
# #             print 'old',i,self.oldPoints[i]['pos']
# #             print 'new',i,self.points[i]['pos']
# #             print
#             move = norm(self.points[i]['pos']-self.oldPoints[i]['pos'])
#             if move > 1e-6 :
#                 print i,move
        
        ener = 0.0
        self.power = 2.0
#         scale = 1
        for ipos in range(self.nIndIn):
            force = zeros(3)
            rs = zeros(self.npoints,dtype = [('r', 'float'),('rij', '3float'),('force', '3float')])
                      
            nearest = -1
            rnearest = 100.0
            for jpos in range(self.npoints):
                rij = self.points[jpos]['pos'] - self.points[ipos]['pos']
                r = norm([rij])
                if r > 1e-4*self.rmin:
                    if r<rnearest:
                        nearest = jpos
                        rnearest = r
#                    
#                     epair = r**2 #attractive springs...dumb because those farthest away influence most
#                     force += rij #attractive springs)
                    
                    epair = (self.ravg/r)**self.power
                    forcepair = -self.power*epair/r * rij/r
                    force += forcepair
#                     print 'jpos',jpos,r,forcepair
                    ener += epair
                    rs[jpos]['r'] = r
                    rs[jpos]['rij'] = rij
                    rs[jpos]['force'] = forcepair
              
                    
            self.points[ipos]['force'] = trimSmall(force)
            
            if ipos in self.indIn:
                rs =sort(rs, order='r') 
#                 print ipos, rs[:20]['r'] 
#                 print rs[:20]['rij']
                print ipos, 'pos', self.points[ipos]['pos']
                print 'nerst',self.points[nearest]['pos'],nearest,rnearest 
                print 'vectr', trimSmall(self.points[nearest]['pos'] - self.points[ipos]['pos'])
                print 'force', ipos, self.points[ipos]['force']    
        ener = ener/self.nIndIn
        grad = -self.points[:self.nIndIn]['force'].flatten()/self.nIndIn 
        print 'energy:',self.count, ener
        print
#         if self.count == 19:
#             self.plotPoints(self.points,'pos')
        self.count += 1
        #now update all the dependent positions
      #  ! Note:  need to update the positions at each step!  Do we have to get inside
#         return ener#         
        return ener, grad
예제 #26
0
def writekpts_vasp_M(path, B, M, K):
    '''write out kpoints file with IBZKPTS format.  This will specify all the kpoints and their weights. 
    No shift is allowed for now'''
    #Fill a 1st brilloun zone with mesh points.  We will choose the 1st BZ to be that given by the parallepiped of (B0, B1, B2)
    #Since B = KM.  The first column of M determines the first column of B (B0) We run trial mesh points over a grid made by the maximum and minimum values of columns of M and the three directions
    # of K.  The first row of M  gives the first k direction (first column of K)
    eps = 1e-4
    Kv = K.vecs
    Bv = B.vecs
    #    nBZpt = 0
    #    Binv = inv(Bv)
    #    #Dummy set up Monkhorst Pack:
    #    nMP = rint(det(M)**(1/3.0))
    #    M = array([[nMP,0,0],[0,nMP,0],[0,0,nMP]]);
    #    Kv = dot(Bv,inv(M))
    #end dummy
    print 'M in writekpts_vasp_M'
    print(M)
    print 'Kvecs in writekpts_vasp_M'
    print(Kv)
    #    print 'transpose(Bvecs)in writekpts_vasp_M';print transpose(Bv)*100
    print 'det of M', det(M)
    npts = -1
    ktryB = zeros((3, rint(det(M) * 2)))  #
    kpts = zeros((3, rint(det(M) * 2)))
    #The rows of M determine how each vector (column) of K is used in the sum.
    #The 1BZ parallelpiped must go from (0,0,0) to each of the other vertices
    #the close vertices are at B1,B2,B3.  So each element of each row must be considered.
    #The far verictecs are at  for these three vectors taken in paris.
    #To reach the diagonal point of the parallelpiped,
    #which means that the sums of the rows must be part of the limits.
    #To reach the three far vertices (not the tip), we have to take the columns of M in pairs:,
    #which means that we check the limits of the pairs among the elements of each row.
    #in other words, the limits on the search for each row i of (coefficients of grid basis vector Ki) are the partial sums
    #of the elements of each row:  min(0,a,b,c,a+b,a+c,b+c,a+b+c), max(0,a,b,c,a+b,a+c,b+c,a+b+c)
    Msums = zeros((3, 8), dtype=int)

    for i in range(3):
        a = M[i, 0]
        b = M[i, 1]
        c = M[i, 2]
        Msums[i, 0] = 0
        Msums[i, 1] = a
        Msums[i, 2] = b
        Msums[i, 3] = c
        Msums[i, 4] = a + b
        Msums[i, 5] = a + c
        Msums[i, 6] = b + c
        Msums[i, 7] = a + b + c
    ntry = 0
    for i2 in range(
            amin(Msums[2, :]) - 1,
            amax(Msums[2, :]) + 1
    ):  #The rows of M determine how each vector (column) of M is used in the sum
        for i1 in range(amin(Msums[1, :]) - 1, amax(Msums[1, :]) + 1):
            for i0 in range(amin(Msums[0, :]) - 1, amax(Msums[0, :]) + 1):
                ntry += 1
                ktry = i0 * Kv[:, 0] + i1 * Kv[:, 1] + i2 * Kv[:, 2]
                ktryB1 = trimSmall(dot(inv(Bv), transpose(ktry)))
                #test whether it is in 1st BZ.  Transform first to basis of B:
                #it's in the parallelpiped if its components are all less than one and positive
                eps = 1e-4
                if min(ktryB1) > 0 - eps and max(ktryB1) < 1 - eps:
                    npts += 1
                    #translate to traditional 1BZ
                    for i in range(3):
                        if ktryB1[i] > 0.5 + eps:
                            ktryB1[i] = ktryB1[i] - 1
                        if ktryB1[i] < -0.5 + eps:
                            ktryB1[i] = ktryB1[i] + 1
                    #convert back to cartesian
                    ktry = trimSmall(dot(Bv, transpose(ktryB1)))
                    kpts[:, npts] = ktry
    npts = npts + 1  #from starting at -1
    print 'Grid points tested', ntry
    print 'Points in 1BZ', npts
    if not areEqual(npts, rint(det(M))):
        print det(M)
        sys.exit(
            'Stop. Number of grid points in the 1BZ is not equal to det(M)')
    #Apply symmetry operations and see which are identical to others.  All in Cartesian coords
    kptssymm = zeros((3, npts))
    weights = zeros((npts), dtype=int)
    #record the first point
    kptssymm[:, 0] = kpts[:, 0]
    weights[0] = 1
    nksymm = 1

    for i in range(1, npts):
        kB = trimSmall(dot(inv(Bv), transpose(kpts[:, i])))
        #rotate
        found = False
        for iop in range(B.nops):
            krot = dot(B.symops[:, :, iop], kpts[:, i])
            kB2 = trimSmall(dot(inv(Bv), transpose(krot)))
            #test whether it matches any we have saved.
            for iksymm in range(nksymm):
                if areEqual(krot[0], kptssymm[0, iksymm]) and areEqual(
                        krot[1], kptssymm[1, iksymm]) and areEqual(
                            krot[2], kptssymm[2, iksymm]):
                    #                    print 'Found equivalent point'
                    weights[iksymm] += 1
                    found = True  # It better be equivalent to only one saved point
                    break
            if found:
                break
        if not found:
            kptssymm[:, nksymm] = kpts[:, i]
            weights[nksymm] += 1
            nksymm += 1
#            print 'symm new point',nksymm
    print 'Points in reduced 1BZ', nksymm
    print 'Total weights', sum(weights)
    print 'Vol BZ/ vol irredBZ', npts / float(nksymm)
    #convert to basis of B lattice vectors
    for i in range(nksymm):
        kptssymm[:, i] = trimSmall(dot(inv(Bv), transpose(kptssymm[:, i])))

#    #write POSCAR for vmd:  put B vectors in lattice, and kmesh in atomic positions
#    scale = 10
#    poscar = open('POSCARk','w')
#    poscar.write('Cs I kpoints vs B'+'\n') #different sizes from this label
#    poscar.write('1.0\n')
#    for i in [0,1,2]:
#        poscar.write('%20.15f %20.15f %20.15f \n' % (scale*Bv[0,i], scale*Bv[1,i], scale*Bv[2,i]))
#    poscar.write('1 %i\n' %npts)
#    poscar.write('Cartesian\n')
#    poscar.write('0.0 0.0 0.0\n')
#    for i in range(npts):
#        poscar.write('%20.15f %20.15f %20.15f \n' % (scale*kpts[0,i],scale*kpts[1,i],scale*kpts[2,i]))
#    poscar.close()

#write POSCAR with irred BZ.  for vmd:  put B vectors in lattice, and kmesh in atomic positions
    scale = 10
    poscar = open('POSCARkred', 'w')
    poscar.write('Cs I kpoints vs B' + '\n')  #different sizes from this label
    poscar.write('1.0\n')
    for i in [0, 1, 2]:
        poscar.write('%20.15f %20.15f %20.15f \n' %
                     (scale * Bv[0, i], scale * Bv[1, i], scale * Bv[2, i]))
    poscar.write('1 %i\n' % nksymm)
    poscar.write('Cartesian\n')
    poscar.write('0.0 0.0 0.0\n')
    for i in range(nksymm):
        poscar.write('%20.15f %20.15f %20.15f %20.15f \n' %
                     (scale * kptssymm[0, i], scale * kptssymm[1, i],
                      scale * kptssymm[2, i], weights[i]))
    poscar.close()

    poscar = open('KPOINTS', 'w')
    poscar.write('BCH generated via bestmeshiter' +
                 '\n')  #different sizes from this label
    poscar.write('%i\n' % nksymm)
    poscar.write('Reciprocal lattice units\n')
    for i in range(nksymm):
        poscar.write(
            '%20.15f %20.15f %20.15f      %i\n' %
            (kptssymm[0, i], kptssymm[1, i], kptssymm[2, i], weights[i]))
    poscar.close()
예제 #27
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]
예제 #28
0
print B.vecs
print 'B transpose'
print transpose(B.vecs)
print 'Det of B', B.det
print 'Orth Defect of B', orthdef(B.vecs)
print 'Surf/vol of B', surfvol(B.vecs)

[B.symops, B.nops] = getGroup(B.vecs)
print 'Number of symmetry operations', B.nops
#print 'symmetry operations of B\n'
#for j in range(nopsB):
#    print j
#    op = matrix(symopsB[:,:,j])
#    print op
#find real lattice
A.vecs = trimSmall(transpose(inv(B.vecs)))
A.det = det(A.vecs)
A.Nmesh = Nmesh
print 'A vectors'
print A.vecs
print 'Det of A', A.det
print 'Orth Defect of A', orthdef(A.vecs)
print 'Surf/vol of A', surfvol(A.vecs)

[A.symops, A.nops] = getGroup(A.vecs)
if A.nops != B.nops:
    sys.exit('Number of operations different for A and B; stop')

print 'symmetry operations R of A\n'
testvecs = []
oplist = []
예제 #29
0
            print 'Fcc mesh compatibility for fcc lattice):'
            print 'detL*bccsq*trans(inv(L))'; print dL*dot(bccsq,transpose(inv(L)))
            
        scaleposcar(scale) #inserts length scale into appropriate spot.
        writefile([str(dL)],finalDir+dir+'detL')
        writefile([lattype],finalDir+dir+'lattype')
        os.system ('cp %s* %s' % (vaspinputdir,'.'))
        os.system ('rm slurm*')
        n = m*dL; shift = '0.00'       
        if meshtype == 'cub':
            M = n*transpose(inv(A))
            print 'M matrix for cubic mesh'; print M 
            print 'det M (kpoints in unreduced 1BZ)', det(M)            
            writekpts_cubic_n(n,shift)           
        if meshtype == 'fcc':
            M = trimSmall(n*dot(bccsq,transpose(inv(L))))
            print 'test K';print trimSmall(dot(B,inv(M)))
#            print 'test Bo';print transpose(inv(platt))
            print 'M matrix for fcc mesh'; print M
            print 'det M (kpoints in unreduced 1BZ)', det(M)
            
            writekpts_fcc_n(n,shift)
        writefile([str(abs(det(M)))],finalDir+dir+'detM')
        
#        writekpts_vasp_M(finalDir+dir,B,M,Bnops,Bsymops) #define K's explicitly!!!

        writejobfile(finalDir+dir)
        if n <= nmax:#(don't submit the biggest jobs
            ''
            
            subprocess.call(['sbatch', 'vaspjob']) #!!!!!!! Submit jobs
예제 #30
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'
예제 #31
0
def writekpts_vasp_M(path,Bv,M,nops,symmops):
    '''write out kpoints file with IBZKPTS format.  This will specify all the kpoints and their weights. 
    No shift is allowed for now.  The symmops are those of B'''
    #Fill a 1st brilloun zone with mesh points.  We will choose the 1st BZ to be that given by the parallepiped of (B0, B1, B2)
    #Since B = KM.  The first column of M determines the first column of B (B0) We run trial mesh points over a grid made by the maximum and minimum values of columns of M and the three directions 
    # of K.  The first row of M  gives the first k direction (first column of K)
    eps = 1e-4
    M = M * sign(det(M)) # want positive determinants
    Kv = dot(B,inv(M))
    nBZpt = 0
    Binv = inv(Bv)
    print 'M in writekpts_vasp_M';print (M)
    print 'Kvecs in writekpts_vasp_M';print (Kv)
#    print 'transpose(Bvecs)in writekpts_vasp_M';print transpose(Bv)*100
    print 'det of M', det(M)    
    npts = -1
    ktryB = zeros((3,rint(det(M)*2))) 
    kpts =  zeros((3,rint(det(M)*2))) #all the kpoints in the entire 1BZ
    
    #The rows of M determine how each vector (column) of K is used in the sum.    
    #The 1BZ parallelpiped must go from (0,0,0) to each of the other vertices 
    #the close vertices are at B1,B2,B3.  So each element of each row must be considered.
    #The far vertices are at for these three vectors taken in pairs. 
    #To reach the diagonal point of the parallelpiped, 
    #which means that the sums of the rows must be part of the limits.
    #To reach the three far vertices (not the tip), we have to take the columns of M in pairs:, 
    #which means that we check the limits of the pairs among the elements of each row.
    #in other words, the limits on the search for each row i of (coefficients of grid basis vector Ki) are the partial sums
    #of the elements of each row:  min(0,a,b,c,a+b,a+c,b+c,a+b+c), max(0,a,b,c,a+b,a+c,b+c,a+b+c)
    Msums = zeros((3,8),dtype = int)

    for i in range(3):
        a = M[i,0]; b = M[i,1];c = M[i,2];
        Msums[i,0]=0; Msums[i,1]=a; Msums[i,2]=b;Msums[i,3]=c;
        Msums[i,4]=a+b; Msums[i,5]=a+c; Msums[i,6]=b+c;  Msums[i,7]=a+b+c
    ntry =0
    for i2 in range(amin(Msums[2,:])-1,amax(Msums[2,:])+1): #The rows of M determine how each vector (column) of M is used in the sum
        for i1 in range(amin(Msums[1,:])-1,amax(Msums[1,:])+1):
            for i0 in range(amin(Msums[0,:])-1,amax(Msums[0,:])+1):
                ntry += 1
                ktry = i0*Kv[:,0] + i1*Kv[:,1] + i2*Kv[:,2]              
                ktryB1 = trimSmall(dot(inv(Bv),transpose(ktry)))
               #test whether it is in 1st BZ.  Transform first to basis of B:
               #it's in the parallelpiped if its components are all less than one and positive             
                eps = 1e-4
                if min(ktryB1)>0-eps and max(ktryB1)<1-eps :
                    npts += 1
#                    print i0,i1,i2, trimSmall(ktryB1)
                    #translate to traditional 1BZ
                    for i in range(3):
                        if ktryB1[i]>0.5+eps: 
                            ktryB1[i] = ktryB1[i] - 1
                        if ktryB1[i]<-0.5+eps: 
                            ktryB1[i] = ktryB1[i] + 1
                    #convert back to cartesian
                    ktry = trimSmall(dot(Bv,transpose(ktryB1)))
                    kpts[:,npts] = ktry
    npts = npts+1 #from starting at -1    
    print 'Grid points tested',ntry     
    print 'Points in 1BZ',npts
    if not areEqual(npts,rint(det(M))): 
        print det(M)
        sys.exit('Stop. Number of grid points in the 1BZ is not equal to det(M)')
    #Apply symmetry operations and see which are identical to others.  All in Cartesian coords
    kptssymm = zeros((3,npts)) #the kpoints in irreducible 1BZ
    weights = zeros((npts),dtype = int)
    #record the first point
    print '0'; print kpts[:,0]
    kptssymm[:,0] = kpts[:,0]
    weights[0] = 1
    nksymm = 1
    
    for i in range(1,npts): #test all 
        print; print i;print kpts[:,i]
        kB = trimSmall(dot(inv(Bv),transpose(kpts[:,i])))#now in the basis of B vectors
        print kB, 'in recip cords'
#        if areEqual(kB[0],0.5) or  areEqual(kB[1],0.5) or areEqual(kB[2],0.5)  :
#            print'Boundary point', kB
        #rotate
        found = False
        for iop in range(nops):
            krot = dot(symops[:,:,iop],kpts[:,i])
            kB2 = trimSmall(dot(inv(Bv),transpose(krot)))
#            if areEqual(kB[0],0.5) or  areEqual(kB[1],0.5) or areEqual(kB[2],0.5)  :
#                print kB2            
            #test whether it matches any we have saved. 
            for iksymm in range(nksymm):      
                if  areEqual(krot[0],kptssymm[0,iksymm]) and areEqual(krot[1],kptssymm[1,iksymm]) and areEqual(krot[2],kptssymm[2,iksymm]) :
                    print 'Found equivalent point',iksymm;print kptssymm[:,iksymm]
                    weights[iksymm] += 1
                    found = True # It better be equivalent to only one point in irreducible 1BZ
                    break
            if found: 
                break
        if not found:
            kptssymm[:,nksymm] = kpts[:,i]                
            weights[nksymm] += 1
            nksymm += 1  
            print 'symm new point',nksymm  
    print 'Points in reduced 1BZ',nksymm 
    print 'Total weights',sum(weights)   
    print 'Vol BZ/ vol irredBZ', npts/float(nksymm)
    #convert to basis of B lattice vectors
    for i in range(nksymm):
        kptssymm[:,i] = trimSmall(dot(inv(Bv),transpose(kptssymm[:,i])))             
                                
#    #write POSCAR for vmd:  put B vectors in lattice, and kmesh in atomic positions
#    scale = 10       
#    poscar = open('POSCARk','w')
#    poscar.write('Cs I kpoints vs B'+'\n') #different sizes from this label
#    poscar.write('1.0\n')
#    for i in [0,1,2]:
#        poscar.write('%20.15f %20.15f %20.15f \n' % (scale*Bv[0,i], scale*Bv[1,i], scale*Bv[2,i])) 
#    poscar.write('1 %i\n' %npts)      
#    poscar.write('Cartesian\n')
#    poscar.write('0.0 0.0 0.0\n') 
#    for i in range(npts):
#        poscar.write('%20.15f %20.15f %20.15f \n' % (scale*kpts[0,i],scale*kpts[1,i],scale*kpts[2,i]))
#    poscar.close()
    
    #write POSCAR with irred BZ.  for vmd:  put B vectors in lattice, and kmesh in atomic positions
    scale = 10       
    poscar = open('POSCARkred','w')
    poscar.write('Kpoints in BZ'+'\n') #different sizes from this label
    poscar.write('1.0\n')
    for i in [0,1,2]:
        poscar.write('%20.15f %20.15f %20.15f \n' % (scale*Bv[0,i], scale*Bv[1,i], scale*Bv[2,i])) 
    poscar.write('1 %i\n' %nksymm)      
    poscar.write('Cartesian\n')
    poscar.write('0.0 0.0 0.0\n') 
    for i in range(nksymm):
        poscar.write('%20.15f %20.15f %20.15f %20.15f \n' % (scale*kptssymm[0,i],scale*kptssymm[1,i],scale*kptssymm[2,i], weights[i]))
    poscar.close()

    
    kpoints = open('KPOINTS','w')
    kpoints.write('BCH generated'+'\n') #different sizes from this label
    kpoints.write('%i\n' % nksymm)
    kpoints.write('Reciprocal lattice units\n')
    for i in range(nksymm):
        kpoints.write('%20.15f %20.15f %20.15f      %i\n' % (kptssymm[0,i],kptssymm[1,i],kptssymm[2,i], weights[i]))
    kpoints.close()
예제 #32
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
    ]
예제 #33
0
def bestmeshIter_vary_N(Blatt,Nmesh,path):
    '''The kmesh can be related to the reciprocal lattice B by  B = KM, where M is an integer 3x3 matrix
    So K = B Inv(M).  Change M one element at a time to minimize the errors in symmetry and the cost in S/V and Nmesh '''
    
    ##############################################################
    ########################## Script ############################
    vaspinputdir = '/fslhome/bch/cluster_expansion/alir/AFLOWDATAf1_50e/vaspinput/'
    M = zeros((3,3),dtype = int)
    S = zeros((3,3),dtype = fprec)
    B = lattice()
    A = lattice()
    K = lattice()
    status = ''
    pf_minsv = 0; pf_sv2fcc = 0; pf_maxpf = 0; pf_pf2fcc = 0; #kvecs_pf2fcc = identity(3)
    sym_maxpf = False;  sym_sv2fcc = False; sym_minsv = False; sym_pf2fcc = False
    a = rint(Nmesh**(1/3.0)); f = int(Nmesh/a/a)
    print 'Target mesh number', Nmesh
       
    B.vecs = Blatt/2/pi  #Don't use 2pi constants in reciprocal lattice here
#    B.pftarget = 0.7405 #default best packing fraction

    #############End BCT lattice
    eps = 1.0e-6

    B.Nmesh = Nmesh
    print 'B vectors (differ by 2pi from traditional)';print B.vecs #
    #print 'B transpose'; print transpose(B.vecs)
    B.det = det(B.vecs)
    print 'Det of B', B.det
    print 'Orth Defect of B', orthdef(B.vecs)
    print 'Surf/vol of B', surfvol(B.vecs)
    pfB = packingFraction(B.vecs)
    print 'Packing fraction of B:', pfB  
    [B.symops,B.nops] = getGroup(B.vecs)
    B.msymops = intsymops(B) #integer sym operations in B basis
#    print'Symmetry operators in basis of B'
#    for i in range:
#        print B.msymops[:,:,i];print 
#    printops_eigs(B)
    B.lattype = latticeType(B.nops)
    print 'Lattice type:', B.lattype
    A = lattice()
    A.vecs = trimSmall(inv(transpose(B.vecs)))
    [A.symops,A.nops] = getGroup(A.vecs)    
    A.msymops = intsymops(A)
    print 'Real space lattice A'; print A.vecs
    print 'Det A', det(A.vecs)
    pfA = packingFraction(A.vecs)
    print 'Packing fraction of A:', pfA    
    
    meshesfile = open('meshesfile','a')
    meshesfile.write('N target %i\n' % B.Nmesh)
    meshesfile.write('Format: pf then Nmesh then kmesh\n\n')    
    
    pflist = []
#    M0 = array([[2,   2,   2,],
#                    [2,   2,   -2],
#                    [-2,   2,   -2]])
#    
#      0.74050000    64.000 
#-5   1   -3   
#6   2   2   
#3   1   -3   
    M0 = array([[-5,   1, -3,],
                    [6,   2,   2],
                    [3,   1,   -3]])
    
#    for div in [256,128,64,32,16,8,4,2,1]:
#        print '\nDivisor',div
#        nMP = rint((Nmesh/div)**(1/3.0))
#        M = array([[nMP,0,0],[0,nMP,0],[0,0,nMP]]);
 

    for fac in [1,2,3,4,5,6,7,8]: 
        print '\nMultiplier',fac       
        
        M = fac*M0
#        M = array([[4,12,-4],
#                   [-11,4,-26],
#                   [-26,-4,-11]]);
        K = lattice();K.vecs = trimSmall(dot(B.vecs,inv(M)));K.det = abs(det(K.vecs)); K.Nmesh = B.det/K.det             
        print 'Number of points',det(M)
        print 'Check M'
        print M
        print 'Check K'
        print K.vecs 
        print 'Check B'
        print B.vecs
        print 'Check pf'
        print packingFraction(K.vecs) 
        #create a dir and prepare for vasp run
        newdir = str(K.Nmesh)
        newpath = path + newdir + '/'
        if not os.path.isdir(newpath):
            os.system('mkdir %s' % newpath)
        os.chdir(newpath)
        os.system ('cp %s* %s' % (vaspinputdir,newpath))
        os.system ('cp %sPOSCAR %s' % (path,newpath))  
        writekpts_vasp_M(newpath,B,M,K)
#             writekpts_vasp_pf(newpath,K.vecs,pf_maxpf,K.Nmesh)
        writejobfile(newpath)

#            print 'submitting job'            
        subprocess.call(['sbatch', 'vaspjob']) #!!!!!!! Submit jobs
        os.chdir(path)