def cost(M, B, run):
    if areEqual(det(M), 0):
        return 1000
    pftarget = B.pftarget

    K = lattice()
    K.vecs = dot(B.vecs, inv(M))
    K.det = abs(det(K.vecs))
    if run == 'minsv':
        Nscale = 1 * 1.0
        Ncost = Nscale * abs((B.det / K.det) - B.Nmesh) / B.Nmesh
        #        cost = surfvol(K.vecs)*(1+Ncost)
        cost = surfvol(K.vecs) + Ncost
    elif run == 'maxpf':
        #        K = lattice()
        #        K.vecs = dot(B.vecs,inv(M));K.det = abs(det(K.vecs))
        Nscale = 1 * .5
        Ncost = Nscale * abs((B.det / K.det) - B.Nmesh) / B.Nmesh
        pf = packingFraction(K.vecs)
        #        cost = (1/pf)*(1+Ncost)
        cost = 1 * abs(pftarget - pf) / pftarget + Ncost
    elif run == 'minsvsym':
        Nscale = 1 * .05  #.05;
        Ncost = Nscale * abs((B.det / K.det) - B.Nmesh) / B.Nmesh
        pfscale = 1 * 0.5
        pfcost = pfscale * surfvol(K.vecs)
        symerr = symmetryError(K.vecs, B)
        #        print symerr
        #        cost = symerr *(1+Ncost)*(1+shapecost)
        cost = symerr + Ncost + shapecost
    elif run == 'maxpfsym':
        Nscale = 1 * .2
        #*.2;
        Ncost = Nscale * abs((B.det / K.det) - B.Nmesh) / B.Nmesh
        pf = packingFraction(K.vecs)
        pfscale = 10
        pfcost = pfscale * abs(pftarget - pf) / pftarget
        symerr = symmetryError(K.vecs, B)
        #        print symerr
        #        cost = symerr *(1+Ncost)*(1+pfcost)
        cost = symerr + Ncost + pfcost
    elif run == 'sym':
        symerr = symmetryError(K.vecs, B)
        #        print symerr
        cost = symerr
    elif run == 'sym_sv':
        symerr = symmetryError(K.vecs, B)
        shapescale = 1 * 0.5
        shapecost = shapescale * surfvol(K.vecs)
        symerr = symmetryError(K.vecs, B)
        cost = symerr + shapecost
    else:
        sys.exit('Cost type not found in cost function. Stop')
    return (cost)
Example #2
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
Example #3
0
def cost(M,B,run):
    if areEqual(det(M),0):
        return 1000
    pftarget = B.pftarget
    
    K = lattice()
    K.vecs = dot(B.vecs,inv(M));K.det = abs(det(K.vecs))    
    if run == 'minsv':
        Nscale =1*1.0; Ncost = Nscale * abs((B.det/K.det)-B.Nmesh)/B.Nmesh 
#        cost = surfvol(K.vecs)*(1+Ncost)
        cost = surfvol(K.vecs) + Ncost
    elif run == 'maxpf':
#        K = lattice()
#        K.vecs = dot(B.vecs,inv(M));K.det = abs(det(K.vecs))
        Nscale =1*.5; Ncost = Nscale * abs((B.det/K.det)-B.Nmesh)/B.Nmesh 
        pf = packingFraction(K.vecs)
#        cost = (1/pf)*(1+Ncost) 
        cost = 1 * abs(pftarget - pf)/pftarget  + Ncost     
    elif run == 'minsvsym':
        Nscale =1*.05#.05; 
        Ncost = Nscale * abs((B.det/K.det)-B.Nmesh)/B.Nmesh 
        shapescale = 1 * 0.5; shapecost = shapescale * surfvol(K.vecs)
        symerr = symmetryError(K.vecs,B)
#        print symerr
#        cost = symerr *(1+Ncost)*(1+shapecost)
        cost = symerr  + Ncost + shapecost
    elif run == 'maxpfsym':
        Nscale =1*.2; #*.2;
        Ncost = Nscale * abs((B.det/K.det)-B.Nmesh)/B.Nmesh 
        pf = packingFraction(K.vecs)
        shapescale = 10 ; shapecost = shapescale * abs(pftarget - pf)/pftarget
        symerr = symmetryError(K.vecs,B)
#        print symerr          
#        cost = symerr *(1+Ncost)*(1+shapecost)
        cost = symerr  + Ncost + shapecost
    elif run == 'sym':   
        symerr = symmetryError(K.vecs,B)
#        print symerr
        cost = symerr 
    elif run == 'sym_sv':   
        symerr = symmetryError(K.vecs,B)
        shapescale = 1 * 0.5; shapecost = shapescale * surfvol(K.vecs)
        symerr = symmetryError(K.vecs,B)
        cost = symerr + shapecost        
    else:
       sys.exit('Cost type not found in cost function. Stop')      
    return(cost)  
def cost(M, B):
    if areEqual(det(M), 0):
        return 100
    #    if areEqual(K.det,0):
    #        return 100
    else:
        K = lattice()
        K.vecs = dot(B.vecs, inv(M))
        K.det = abs(det(K.vecs))
        Nscale = 1 * 0.05
        Ncost = Nscale * abs((B.det / K.det) - B.Nmesh) / B.Nmesh
        cost = surfvol(K.vecs) * (1 + Ncost)
        return cost
def cost(MT, A):
    if det(MT) == 0:
        print MT
        print sys.exit('Error det(MT)=0; stop in cost()')
    S = dot(A.vecs, MT)
    Nscale = 1 * .8
    Ncost = Nscale * abs((det(S) / A.det - A.Nmesh)) / A.Nmesh
    symmScale = 10
    symmCost = symmScale * symmetryErr(S, A)
    #    print 'Ncost, symmCost', Ncost, symmCost
    #    print 'for MT:'
    #    print MT
    cost = surfvol(S) * (1 + Ncost + symmCost)
    return cost
Example #6
0
def cost(M, B):
    if areEqual(det(M), 0):
        return 100


#    if areEqual(K.det,0):
#        return 100
    else:
        K = lattice()
        K.vecs = dot(B.vecs, inv(M))
        K.det = abs(det(K.vecs))
        Nscale = 1 * .05
        Ncost = Nscale * abs((B.det / K.det) - B.Nmesh) / B.Nmesh
        cost = surfvol(K.vecs) * (1 + Ncost)
        return (cost)
Example #7
0
def svmin_3rdvec(S,parentlatt):
    '''Multiply third vector of S by integers and find the minimum S/Volume metric'''
    from copy import copy 
    sv = 100 #initialize too large
    trymax = 1000
    vec3min = copy(S[:,2])
    #print 'vec3min', vec3min
    for m in range(1,trymax):
        S[:,2] = float(m) * vec3min
        sv2 = surfvol(S)
        #print; print 'mult,sv',m,sv2
        #print vec3min
        #print'S'; print trimSmall(S)

        if sv2 > sv: #the last one was a minimum
            S[:,2] = (m-1) * vec3min
            #print 'best mult', m-1, S[:,2]
            return S
        else:
            sv = sv2
    sys.exit('Error in svmin_3rdvec; stop')   #sv kept growing  
Example #8
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
def searchmin(S, A):
    '''MT is transpose(M) '''
    print '----------------------'
    default_length = rint(A.Nmesh**(1 / 3.0))
    MT = dot(inv(A.vecs), S)
    MTold = MT
    #determine how many full rows (known vectors) there are in S:
    if norm(MTold[:, 0]) == 0:
        knownvecs = 0
        MT[0, 0] = default_length  # Make first trial vector along "mx"
    elif norm(MTold[:, 0]) != 0 and norm(MTold[:, 1]) == 0:
        knownvecs = 1  #Make 2nd trial vector
    else:
        knownvecs = 2
    if norm(MT[:, 1]
            ) == 0:  #make arbitrary 2nd trial M vector nearly normal to first
        closestM_axis = argmax(
            MT[:, 0])  #find which axis the M vector is most inclined towards
        #choose arbitrary next axis in cyclic way, and make a unit vector in the plane of MT0 and (next axis)
        nextdir = zeros((3, 1), dtype=int)
        nextdir[icy(closestM_axis, 1)] = 1
        nextdir = default_length * nextdir
        print MT
        print 'nextdir', nextdir
        print 'norm2', norm(MT[:, 0])**2
        orthvec = nextdir - dot(transpose(MT[:, 0]),
                                nextdir)[0, 0] * MT[:, 0] / norm(MT[:, 0])**2
        print 'orth', orthvec
        unitvec = orthvec / norm(orthvec)
        print 'unit', unitvec
        MT[:, 1] = rint(default_length * unitvec)
    if norm(
            MT[:, 2]
    ) == 0:  #make arbitrary 3nd trial M vector nearly normal to first two
        orthvec = transpose(cross(transpose(MT[:, 0]), transpose(MT[:, 1])))
        unitvec = orthvec / norm(orthvec)
        MT[:, 2] = rint(default_length * unitvec)
#    print 'MT', MT
#    print 'det', det(MT)
#find the direction of steepest slope in the cost
    maxsteps = 10000
    istep = 1
    while istep < maxsteps:
        bestindex = changewhich(MT, knownvecs, A)
        print 'bestindex', bestindex
        if bestindex[1] == 0:  #found minimum at previous M
            newcost = cost(MT, A)
            break
        else:
            #            print 'value in MT to change', bestindex[0][0], MT[bestindex[0]]
            MT[bestindex[0][0], bestindex[0][1]] += bestindex[1]
            newcost = cost(MT, A)


#            oldcost = newcost
        istep += 1
    #    sys.exit('stop')
    if istep < maxsteps:
        S = dot(A.vecs, MT)
        K = lattice()
        K.vecs = inv(transpose(S))
        K.det = det(K.vecs)
        print
        print 'Found minimum after %i steps' % istep
        print 'Symmetry error', round(symmetryErr(S, A), 4)
        print 'An optimum transpose(M):'
        print MT
        print 'Number of mesh points', det(S) / A.det
        print 'An optimum superlattice S:'
        print S
        print 'An optimum K mesh\n', K.vecs
        print 'Orth defect', orthdef(K.vecs)
        print 'Surface/vol', surfvol(K.vecs)
        print 'Mesh vector lengths:'
        print norm(K.vecs[:, 0]), norm(K.vecs[:, 1]), norm(K.vecs[:, 2])
        #        k0 = K.vecs[:,0]; k1 = K.vecs[:,1]; k2 = K.vecs[:,2]
        #        cosgamma = k0.T*k1/norm(k0)/norm(k1)
        #        cosalpha = k1.T*k2/norm(k1)/norm(k2)
        #        cosbeta =  k2.T*k0/norm(k2)/norm(k0)
        #        print 'Mesh vector cosines:'; print cosalpha, cosbeta, cosgamma
        #        print 'Check B = KM   \n', K.vecs*M
        #        print '\n\n\nTranspose for use in VMD or POSCAR'
        #        print 'B'; print B.vecs.T
        #        print 'K'; print K.vecs.T
        print
    else:
        print 'Ended without minimum after maximum %i steps' % istep
    return MT
Example #10
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'
############## Any lattice

#crystal = [1,1,sqrt(2),90,90,120] # [a,b,c,alpha,beta,gamma]
#crystal = [2,3*sqrt(3),11*sqrt(2),90,90,20] # [a,b,c,alpha,beta,gamma]
#crystal = [2,2,2,80,80,80] # [a,b,c,alpha,beta,gamma]

#B.vecs = transpose(lattice_vecs(crystal))
#############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
#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)
def bestmeshIter_vary_N(Blatt, Nmesh, path):
    '''The kmesh can be related to the reciprocal lattice B by  B = KM, where M is an integer 3x3 matrix
    So K = B Inv(M).  Change M one element at a time to minimize the errors in symmetry and the cost in S/V and Nmesh '''

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

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

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

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

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

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

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

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

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

        #            print 'submitting job'
        subprocess.call(['sbatch', 'vaspjob'])  #!!!!!!! Submit jobs
        os.chdir(path)
def 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]
############## Any lattice

#crystal = [1,1,sqrt(2),90,90,120] # [a,b,c,alpha,beta,gamma]
#crystal = [1,1,2,50,50,50] # [a,b,c,alpha,beta,gamma]
#B.vecs = transpose(lattice_vecs(crystal))
#############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
#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
Example #15
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
    ]
Example #16
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]
Example #17
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'    
Example #18
0
#############End BCT lattice

############## Any lattice

#crystal = [1,1,sqrt(2),90,90,120] # [a,b,c,alpha,beta,gamma]
#crystal = [1,1,2,50,50,50] # [a,b,c,alpha,beta,gamma]
#B.vecs = transpose(lattice_vecs(crystal))
#############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
#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)
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)
def bestmeshIter_vary_pf(Blatt, Nmesh, path):
    '''The kmesh can be related to the reciprocal lattice B by  B = KM, where M is an integer 3x3 matrix
    So K = B Inv(M).  Change M one element at a time to minimize the errors in symmetry and the cost in S/V and Nmesh '''

    ##############################################################
    ########################## Script ############################
    #    print path.split('/')
    npathsegs = len(path.split('/'))
    #    print npathsegs
    vaspinputdir = '/'.join(
        path.split('/')[0:npathsegs - 3]
    ) + '/vaspinput/'  #up two levels, 2 are for spaces at beg and end
    #    print vaspinputdir
    M = zeros((3, 3), dtype=int)
    S = zeros((3, 3), dtype=fprec)
    B = lattice()
    A = lattice()
    K = lattice()
    status = ''
    pf_minsv = 0
    pf_sv2fcc = 0
    pf_maxpf = 0
    pf_pf2fcc = 0
    #kvecs_pf2fcc = identity(3)
    sym_maxpf = False
    sym_sv2fcc = False
    sym_minsv = False
    sym_pf2fcc = False
    print 'Target mesh number', Nmesh

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

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

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

    #    print 'current dir for meshesfile', os.getcwd()
    meshesfile = open('meshesfile', 'w')
    #    meshesfile = open('meshesfile2','w')
    meshesfile.write('N target %i\n' % B.Nmesh)
    meshesfile.write('Format: pf then Nmesh then kmesh\n\n')

    pflist = []
    #    for pftry in frange(pfB/2,0.75,0.005):
    for pftry in frange(pfB / 2, 0.75, 0.01):
        #    for pftry in frange(.3,0.505,0.005):
        print '\nPacking fraction target', pftry
        B.pftarget = pftry
        pf_orth = 0
        pf_orth2fcc = 0
        sym_orth = False
        sym_orth2fcc = False
        #'--------------------------------------------------------------------------------------------------------'
        #'--------------------------------------------------------------------------------------------------------'
        M = zeros((3, 3), dtype=int)
        ctest = []
        type = 'maxpfsym'
        print type
        ctrials = [3]
        a = rint(Nmesh**(1 / 3.0))
        # f = int(Nmesh/a/a)
        randnums = zeros(9)
        print 'M scale a', a
        for c in ctrials:
            #            ri = [randint(5) for i in range(9)]
            #            M = array([[-a+ri[0], a/c +ri[1] , a/c+ri[2]],[a/c+ri[3],-a+ri[4],a/c+ri[5]],\
            #                        [a/c+ri[6],a/c+ri[7],-a+ri[8]]])  #bcc like best avg pf on 50: 0.66

            #HNF::::::
            M = array([[a, 0 , 0],
                       [a/c,a,0],\
                        [a/c,a/c,a]])  #bcc like best avg pf on 50: 0.66

            #
            #            M = array([[-a+1, a/c , a/c],[a/c,-a,a/c],[a/c,a/c,-a-1]])  #bcc like best avg pf on 50: 0.66
            #            M = array([[a, 0,0],[0,a,0],[0,0,a+3]])
            #            M = array([[-16 ,  1 ,  5 ],
            #                [6 ,  -10 ,  5],
            #                [-6  , -1  , 6  ]])
            #            M = array([[5, a/c , a/c],[a/c,0,a/c],[a/c,a/c,-5]]) #fcc like best avg pf on 50: 0.59
            M = rint(M * (B.Nmesh / abs(det(M)))**(1 / 3.0))
            print 'Start mesh trial'
            print M
            #            [M,K] = findmin(M,B,type)
            #            print 'Test trial M'; print M
            ctest.append(cost(M, B, type))
#        print'Trial costs',ctest
        cbest = ctrials[argmin(ctest)]
        #        print'Best c', cbest
        iternpf = 0
        itermaxnpf = 10
        itermaxsym = 5
        #        bestpf = 100
        #        NPFcost = 100;delNPFcost = -1 #initial values
        type = 'maxpfsym'
        print type
        delcost = -1
        lowcost = 1000  #initialize
        ####       while iternpf<itermaxnpf and delNPFcost <0 and abs(delNPFcost)>0.1 :
        while iternpf < itermaxnpf and delcost < -0.1:
            oldcost = cost(M, B, type)
            #            NPFcost = cost(M,B,'maxpf')
            #            delNPFcost = (NPFcost-oldNPFcost)/NPFcost :
            '''Here we let M vary in the search, but record pf and kvecs when we find min cost'''
            #            print 'cost(N,PF):', cost(M,B,type)
            #        while not symm and and iternpf<itermax:
            M = rint(M * (B.Nmesh / abs(det(M)))**(1 / 3.0))
            print 'Scaled M'
            print M
            iternpf += 1
            print 'Iteration', type, iternpf, '**********'
            [M, K] = findmin(M, B, type)
            M = rint(M)
            itersym = 0
            symm = False
            while not symm and itersym < itermaxsym:
                itersym += 1
                print 'Symmetry iteration', itersym, '-------'
                #                print 'Nmesh', abs(det(M)), 'packing', packingFraction(dot(B.vecs,inv(M)))
                #                M = rint(minkM(M,B))#; print'Mink reduced M'; print M
                for iop in range(B.nops):
                    M = rint(findmin_i(M, B, iop))
                    #                    M = rint(minkM(M,B))#; print'Mink reduced M'; print M
                    if abs(det(M) - B.Nmesh
                           ) / B.Nmesh > 0.15:  #how far off from target N
                        M = rint(M * (B.Nmesh / abs(det(M)))**(1 / 3.0))
                        print 'Scaled M'
                        print M
                K = lattice()
                K.vecs = trimSmall(dot(B.vecs, inv(M)))
                K.det = abs(det(K.vecs))
                K.Nmesh = B.det / K.det
                symm = checksymmetry(K.vecs, B)
                print 'Symmetry check', symm
                if symm:
                    newcost = cost(M, B, type)
                    if newcost - lowcost < 0:
                        lowcost = newcost
                        print 'New lowcost', newcost
                        pf_maxpf = packingFraction(K.vecs)
                        sym_maxpf = True
                        kvecs_maxpf = K.vecs
    #                    if pf_maxpf<bestpf: bestpf = pf_maxpf; bestM = M
                    print 'Packing fraction', pf_maxpf, 'vs original B', pfB
                    print 'Nmesh', K.Nmesh, 'vs target', B.Nmesh
                delcost = cost(M, B, type) - oldcost
        #write to files

#        meshesfile.write('Packing fraction target %f\n' % pftry)
        if symm and pf_maxpf not in pflist:
            pflist.append(pf_maxpf)
            #            meshesfile.write('Packing fraction achieved %f\n' % pf_maxpf)
            meshesfile.write('%12.8f  %8.3f \n' % (pf_maxpf, K.Nmesh))
            #            meshesfile.write('M\n')
            #            for i in range(3):
            #                for j in range(3):
            #                    meshesfile.write('%i6' %M[i,j])
            #                meshesfile.write('\n')
            ##            meshesfile.write('\n')

            #            meshesfile.write('k mesh\n')
            M = rint(dot(inv(K.vecs), B.vecs))
            for i in range(3):
                for j in range(3):
                    meshesfile.write('%i   ' % int(rint(M[i, j])))
                meshesfile.write('\n')
            meshesfile.write('\n')
            meshesfile.flush()

            M = rint(dot(inv(K.vecs), B.vecs)
                     )  #We assign K only when M is ideal, so remake the best M
            print 'Check M'
            print M
            print 'Check K'
            print K.vecs
            print 'Check B'
            print B.vecs
            print 'Check pf'
            print packingFraction(K.vecs)
            #create a dir and prepare for vasp run
            newdir = str(round(pf_maxpf, 4))
            newpath = path + newdir + '/'
            if not os.path.isdir(newpath):
                os.system('mkdir %s' % newpath)
            os.chdir(newpath)
            os.system('cp %s* %s' % (vaspinputdir, newpath))
            os.system('cp %sPOSCAR %s' % (path, newpath))
            print 'SKIPPING writekpts_vasp_M AND submission'
            #            writekpts_vasp_M(newpath,B,M,K)
            #            writekpts_vasp_pf(newpath,K.vecs,pf_maxpf,K.Nmesh)
            writejobfile(newpath)

            #            subprocess.call(['sbatch', 'vaspjob']) #!!!!!!! Submit jobs
            os.chdir(path)
        else:
            'do nothing'
#            meshesfile.write('Failed symmetry\n\n')
    meshesfile.close()

    #  Summary
    pfs = [pfB]
    pftypes = ['B_latt']
    ks = [B.vecs / a]  #one solutions is to simply divide B by an integer
    if not (sym_minsv or sym_sv2fcc or sym_maxpf or pf_pf2fcc or sym_orth
            or sym_orth2fcc):
        meshtype = 'B_latt_revert'
        #status += 'MHPrevert;'
        K.vecs = B.vecs / a
        K.det = abs(det(K.vecs))
        K.Nmesh = abs(B.det / K.det)
        pfmax = packingFraction(K.vecs)
    else:

        if sym_orth:
            pfs.append(pf_orth)
            pftypes.append('orth')
            ks.append(kvecs_orth)
        if sym_orth2fcc:
            pfs.append(pf_orth2fcc)
            pftypes.append('orth2fcc')
            ks.append(kvecs_orth2fcc)
        if sym_maxpf:
            pfs.append(pf_maxpf)
            pftypes.append('maxpf')
            ks.append(kvecs_maxpf)
        if sym_pf2fcc:
            pfs.append(pf_pf2fcc)
            pftypes.append('pf2fcc')
            ks.append(kvecs_pf2fcc)
    pfmax = max(pfs)
    meshtype = pftypes[argmax(pfs)]
    K.vecs = ks[argmax(pfs)]
    K.det = abs(det(K.vecs))
    K.Nmesh = B.det / K.det
    #    return [K.vecs, K.Nmesh, B.Nmesh, B.lattype, pfB, pf_orth, pf_orth2fcc, pf_maxpf, pf_minsv, pf_sv2fcc, pfmax, meshtype, fcctype(B),status]

    return [
        K.vecs, K.Nmesh, B.Nmesh, B.lattype, pfB, pf_orth, pf_orth2fcc,
        pf_maxpf, pf_pf2fcc, pfmax, meshtype,
        fcctype(B), cbest, status
    ]
def bestmeshIter_vary_N(Blatt,Nmesh,path):
    '''The kmesh can be related to the reciprocal lattice B by  B = KM, where M is an integer 3x3 matrix
    So K = B Inv(M).  Change M one element at a time to minimize the errors in symmetry and the cost in S/V and Nmesh '''
    
    ##############################################################
    ########################## Script ############################
    vaspinputdir = '/fslhome/bch/cluster_expansion/alir/AFLOWDATAf1_50e/vaspinput/'
    M = zeros((3,3),dtype = int)
    S = zeros((3,3),dtype = fprec)
    B = lattice()
    A = lattice()
    K = lattice()
    status = ''
    pf_minsv = 0; pf_sv2fcc = 0; pf_maxpf = 0; pf_pf2fcc = 0; #kvecs_pf2fcc = identity(3)
    sym_maxpf = False;  sym_sv2fcc = False; sym_minsv = False; sym_pf2fcc = False
    a = rint(Nmesh**(1/3.0)); f = int(Nmesh/a/a)
    print 'Target mesh number', Nmesh
       
    B.vecs = Blatt/2/pi  #Don't use 2pi constants in reciprocal lattice here
#    B.pftarget = 0.7405 #default best packing fraction

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

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

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

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