Exemple #1
0
def make_nacl(latconst=1.0, specorder=None):
    if specorder is None:
        specorder = ['Na', 'Cl']
    if len(specorder) < 2:
        specorder = ['Na', 'Cl']
        print('Since len(specorder) < 2, specorder is reset to ', specorder)

    s = NAPSystem(specorder=specorder)
    #...lattice
    a1 = np.array([1.0, 0.0, 0.0])
    a2 = np.array([0.0, 1.0, 0.0])
    a3 = np.array([0.0, 0.0, 1.0])
    s.set_lattice(latconst, a1, a2, a3)
    poss = [
        [0.00, 0.00, 0.00],
        [0.50, 0.00, 0.00],
        [0.00, 0.50, 0.00],
        [0.00, 0.00, 0.50],
        [0.50, 0.50, 0.00],
        [0.50, 0.00, 0.50],
        [0.00, 0.50, 0.50],
        [0.50, 0.50, 0.50],
    ]
    symbols = ['Na', 'Cl', 'Cl', 'Cl', 'Na', 'Na', 'Na', 'Cl']
    vels = [[0., 0., 0.] for i in range(len(poss))]
    frcs = [[0., 0., 0.] for i in range(len(poss))]
    s.add_atoms(symbols, poss, vels, frcs)
    return s
Exemple #2
0
def make_zincblend(latconst=1.0, specorder=None):
    """
    Make a cell of diamond structure.
    """
    if specorder is None:
        specorder = ['Ga', 'N']
    if len(specorder) < 2:
        specorder = ['Ga', 'N']
        print('Since len(specorder) < 2, specorder is reset to ', specorder)

    s = NAPSystem(specorder=specorder)
    #...lattice
    a1 = np.array([1.0, 0.0, 0.0])
    a2 = np.array([0.0, 1.0, 0.0])
    a3 = np.array([0.0, 0.0, 1.0])
    s.set_lattice(latconst, a1, a2, a3)
    poss = [[0.00, 0.00, 0.00], [0.50, 0.50, 0.00], [0.50, 0.00, 0.50],
            [0.00, 0.50, 0.50], [0.25, 0.25, 0.25], [0.75, 0.75, 0.25],
            [0.75, 0.25, 0.75], [0.25, 0.75, 0.75]]
    symbols = [
        specorder[0] if i < 4 else specorder[1] for i in range(len(poss))
    ]
    vels = [[0., 0., 0.] for i in range(len(poss))]
    frcs = [[0., 0., 0.] for i in range(len(poss))]
    s.add_atoms(symbols, poss, vels, frcs)
    return s
Exemple #3
0
def make_wurtzite(latconst=1.0, specorder=None, celltype='conventional'):
    """
    Make a cell of wurtzite structure.

    - celltype: conventional or primitive
    """
    if specorder is None:
        specorder = ['Ga', 'N']
    if len(specorder) < 2:
        specorder = ['Ga', 'N']
        print('Since len(specorder) < 2, specorder is reset to ', specorder)

    s = NAPSystem(specorder=specorder)
    if celltype[0] == 'c':
        #...conventional cell
        a1 = np.array([1.00, 0.00, 0.00])
        a2 = np.array([0.00, np.sqrt(3.0), 0.00])
        a3 = np.array([0.00, 0.00, 1.633])
        s.set_lattice(latconst, a1, a2, a3)
        poss = [
            [0.00, 0.00, 0.00],
            [0.50, 0.50, 0.00],
            [0.50, 0.5 / 3, 0.50],
            [0.00, 0.5 / 3 + 0.5, 0.50],
            [0.50, 0.5 / 3, 0.125],
            [0.00, 0.5 / 3 + 0.5, 0.125],
            [0.00, 0.00, 0.625],
            [0.50, 0.50, 0.625],
        ]
        symbols = [
            specorder[0] if i < 4 else specorder[1] for i in range(len(poss))
        ]
    elif cenlltype[0] == 'p':
        #...primitive cell
        a1 = np.array([1.0, 0.0, 0.0])
        a2 = np.array([-0.5, np.sqrt(3.0) / 2, 0.0])
        a3 = np.array([0.0, 0.0, 1.633])
        s.set_lattice(latconst, a1, a2, a3)
        poss = [
            [0.00, 0.00, 0.00],
            [2.0 / 3, 1.0 / 3, 0.125],
            [2.0 / 3, 1.0 / 3, 0.50],
            [0.00, 0.00, 0.625],
        ]
        symbols = [
            specorder[0] if i < 2 else specorder[1] for i in range(len(poss))
        ]
    vels = [[0., 0., 0.] for i in range(len(poss))]
    frcs = [[0., 0., 0.] for i in range(len(poss))]
    s.add_atoms(symbols, poss, vels, frcs)
    return s
Exemple #4
0
def make_sc(latconst=1.0):
    """
    Make a cell of simple cubic structure.
    """
    s = NAPSystem(specorder=_default_specorder)
    #...lattice
    a1 = np.array([1.0, 0.0, 0.0])
    a2 = np.array([0.0, 1.0, 0.0])
    a3 = np.array([0.0, 0.0, 1.0])
    s.set_lattice(latconst, a1, a2, a3)
    symbol = _default_specorder[0]
    symbols = [symbol]
    poss = [[0.00, 0.00, 0.00]]
    vels = [[0., 0., 0.]]
    frcs = [[0., 0., 0.]]
    s.add_atoms(symbols, poss, vels, frcs)
    return s
Exemple #5
0
def make_hcp(latconst=1.0):
    """
    Make a cell of hcp structure.
    """
    s = NAPSystem(specorder=_default_specorder)
    #...lattice
    a1 = np.array([1.0, 0.0, 0.0])
    a2 = np.array([-0.5, np.sqrt(3.0) / 2, 0.0])
    a3 = np.array([0.0, 0.0, 1.633])
    s.set_lattice(latconst, a1, a2, a3)
    poss = [[0.00, 0.00, 0.00], [1.0 / 3, 2.0 / 3, 0.50]]
    symbol = _default_specorder[0]
    symbols = [symbol for i in range(len(poss))]
    vels = [[0., 0., 0.] for i in range(len(poss))]
    frcs = [[0., 0., 0.] for i in range(len(poss))]
    s.add_atoms(symbols, poss, vels, frcs)
    return s
Exemple #6
0
def make_bcc110(latconst=1.0):
    """                                                  
    Make a cell of bcc structure with z along [110].
    """
    s = NAPSystem(specorder=_default_specorder)
    #...lattice
    a1 = np.array([1.0, 0.0, 0.0])
    a2 = np.array([0.0, 1.414, 0.0])
    a3 = np.array([0.0, 0.0, 1.414])
    s.set_lattice(latconst, a1, a2, a3)
    symbol = _default_specorder[0]
    symbols = [symbol, symbol, symbol, symbol]
    poss = [[0.00, 0.00, 0.00], [0.00, 0.50, 0.50], [0.50, 0.50, 0.00],
            [0.50, 0.00, 0.50]]
    vels = [[0., 0., 0.] for i in range(4)]
    frcs = [[0., 0., 0.] for i in range(4)]
    s.add_atoms(symbols, poss, vels, frcs)
    return s
Exemple #7
0
def make_sc(latconst=1.0, specorder=None):
    """
    Make a cell of simple cubic structure.
    """
    if specorder is None:
        raise ValueError('specorder must be given.')
    s = NAPSystem(specorder=specorder)
    #...lattice
    a1 = np.array([1.0, 0.0, 0.0])
    a2 = np.array([0.0, 1.0, 0.0])
    a3 = np.array([0.0, 0.0, 1.0])
    s.set_lattice(latconst, a1, a2, a3)
    symbols = [specorder[0]]
    poss = [[0.00, 0.00, 0.00]]
    vels = [[0., 0., 0.]]
    frcs = [[0., 0., 0.]]
    s.add_atoms(symbols, poss, vels, frcs)
    return s
Exemple #8
0
def make_bcc(latconst=1.0, specorder=None):
    """
    Make a cell of bcc structure with z along [001].
    """
    if specorder is None:
        specorder = ['Fe']
    s = NAPSystem(specorder=specorder)
    #...lattice
    a1 = np.array([1.0, 0.0, 0.0])
    a2 = np.array([0.0, 1.0, 0.0])
    a3 = np.array([0.0, 0.0, 1.0])
    s.set_lattice(latconst, a1, a2, a3)
    poss = [[0.00, 0.00, 0.00], [0.50, 0.50, 0.50]]
    symbol = _default_specorder[0]
    symbols = [symbol for i in range(len(poss))]
    vels = [[0., 0., 0.] for i in range(len(poss))]
    frcs = [[0., 0., 0.] for i in range(len(poss))]
    s.add_atoms(symbols, poss, vels, frcs)
    return s
Exemple #9
0
def make_diamond(latconst=1.0):
    """
    Make a cell of diamond structure.
    """
    s = NAPSystem(specorder=_default_specorder)
    #...lattice
    a1 = np.array([1.0, 0.0, 0.0])
    a2 = np.array([0.0, 1.0, 0.0])
    a3 = np.array([0.0, 0.0, 1.0])
    s.set_lattice(latconst, a1, a2, a3)
    poss = [[0.00, 0.00, 0.00], [0.50, 0.50, 0.00], [0.50, 0.00, 0.50],
            [0.00, 0.50, 0.50], [0.25, 0.25, 0.25], [0.75, 0.75, 0.25],
            [0.75, 0.25, 0.75], [0.25, 0.75, 0.75]]
    symbol = _default_specorder[0]
    symbols = [symbol for i in range(len(poss))]
    vels = [[0., 0., 0.] for i in range(len(poss))]
    frcs = [[0., 0., 0.] for i in range(len(poss))]
    s.add_atoms(symbols, poss, vels, frcs)
    return s
Exemple #10
0
def make_bcc111(latconst=1.0):
    """
    Make a cell of bcc structure with z along [111].
    """
    s = NAPSystem(specorder=_default_specorder)
    #...lattice
    a1 = np.array([1.414, 0.0, 0.0])
    a2 = np.array([0.0, 2.449, 0.0])
    a3 = np.array([0.0, 0.0, 1.732])
    s.set_lattice(latconst, a1, a2, a3)
    symbol = _default_specorder[0]
    poss = [[0.00, 0.00, 0.00], [0.00, 0.00, 0.50], [0.00, 0.333, 0.167],
            [0.00, 0.333, 0.667], [0.00, 0.667, 0.333], [0.00, 0.667, 0.833],
            [0.50, 0.167, 0.333], [0.50, 0.167, 0.833], [0.50, 0.50, 0.00],
            [0.50, 0.50, 0.50], [0.50, 0.833, 0.167], [0.50, 0.833, 0.667]]
    symbols = [symbol for i in range(len(poss))]
    vels = [[0., 0., 0.] for i in range(len(poss))]
    frcs = [[0., 0., 0.] for i in range(len(poss))]
    s.add_atoms(symbols, poss, vels, frcs)
    return s
Exemple #11
0
def make_2D_triangle(latconst=3.8, size=(1, 1, 1)):
    """
    Make 2D triangle lattice on x-z plane. 
    Note that it is not x-y plane.
    """
    specorder = ['Ar']
    s = NAPSystem(specorder=specorder)
    #...lattice
    a1 = np.array([1.0, 0.0, 0.0])
    a2 = np.array([0.0, 10.0, 0.0])
    a3 = np.array([0.0, 0.0, np.sqrt(3.0)])
    s.set_lattice(latconst, a1, a2, a3)
    poss = [[0.00, 0.50, 0.00], [0.50, 0.50, 0.50]]
    symbol = _default_specorder[0]
    symbols = [symbol for i in range(len(poss))]
    vels = [[0., 0., 0.] for i in range(len(poss))]
    frcs = [[0., 0., 0.] for i in range(len(poss))]
    s.add_atoms(symbols, poss, vels, frcs)

    s.repeat(*size)
    s.add_vacuum(2. * latconst, 0.0, 10. * latconst * np.sqrt(3))
    return s
Exemple #12
0
def make_polycrystal(grns,uc,n1,n2,n3,two_dim=False):
    """
    THIS ROUTINE IS NOT THAT UNIVERSAL.
    Each grain has to have neighboring grains within a supercell,
    otherwise there will be some unexpecting grain boundries.
    In order to do so, the system should be large enough and
    the number of grains should be large enough.
    """
    #...Calc the minimum bond distance in unit cell and use it as penetration depth
    dmin = 1.0e+30
    for i in range(uc.num_atoms()-1):
        for j in range(i+1,uc.num_atoms()):
            dij = uc.get_distance(i,j)
            dmin = min(dij,dmin)
    print(' Minimum bond distance in the unitcell: ',dmin)
    dmin = dmin *DMIN_RATE
    penetration_depth = dmin*2
    print(' Minimum bond distance allowed in the new system: ',dmin)
            
    sv,nsv= shift_vector(two_dim)
    # print(' nsv =',nsv)
    # for i in range(nsv):
    #     print(' i,sv[i]=',i,sv[i])
    nsys= NAPSystem(specorder=uc.specorder)
    nsys.set_lattice(uc.alc,uc.a1*n1,uc.a2*n2,uc.a3*n3)
    hmat = nsys.get_hmat()
    hmati = nsys.get_hmat_inv()
    nmax = n1*n2*n3 *uc.num_atoms()
    sidsl = np.zeros(nmax,dtype=int)
    symsl = []
    possl = np.zeros((nmax,3))
    velsl = np.zeros((nmax,3))
    frcsl = np.zeros((nmax,3))
    ix0 = -n1/2-1
    ix1 =  n1/2+2
    iy0 = -n2/2-1
    iy1 =  n2/2+2
    iz0 = -n3/2-1
    iz1 =  n3/2+2
    if two_dim:
        if n3 != 1:
            raise ValueError('n3 should be 1 in case two_dim is ON.')
        iz0 = 0
        iz1 = 1
    print(' x range = ',ix0,ix1)
    print(' y range = ',iy0,iy1)
    print(' z range = ',iz0,iz1)
    inc = 0
    for ig in range(len(grns)):
        grain= grns[ig]
        rmat= grain.rmat  # Rotation matrix of the grain
        pi= grain.point   # Grain center in reduced coordinate
        api= np.dot(hmat,pi)  # Grain center in Cartessian coordinate
        print(' grain-ID = ',ig+1)
        for ix in range(ix0,ix1):
            # print('ix=',ix)
            for iy in range(iy0,iy1):
                for iz in range(iz0,iz1):
                    for m in range(uc.num_atoms()):
                        sidt = uc.get_atom_attr(m,'sid')
                        rt= np.zeros((3,))
                        pm = uc.get_atom_attr(m,'pos')
                        rt[0]= (pm[0]+ix)/n1
                        rt[1]= (pm[1]+iy)/n2
                        rt[2]= (pm[2]+iz)/n3
                        #...rt to absolute position
                        art= np.dot(hmat,rt)
                        #...Rotate
                        ari= np.dot(rmat,art)
                        #...Shift origin to the grain center
                        ari[0]= ari[0]+api[0]
                        ari[1]= ari[1]+api[1]
                        ari[2]= ari[2]+api[2]
                        #...check distance from all the grain points
                        di= distance(ari,api,two_dim)
                        isOutside= False
                        for jg in range(len(grns)):
                            gj= grns[jg]
                            for isv in range(nsv):
                                pj= gj.point
                                if jg == ig:
                                    if not two_dim and isv == 13:
                                        continue
                                    elif two_dim and isv == 4:
                                        continue
                                svi= sv[isv]
                                pj= pj +svi
                                apj = np.dot(hmat,pj)
                                dj= distance(ari,apj,two_dim)
                                if dj +penetration_depth < di:  # Allow some penetration here
                                    isOutside= True
                                    break
                            if isOutside:
                                break
                        if isOutside:
                            break
                        #...here ri is inside this grain, register it
                        #...Cartessian coord to reduced coord
                        ri = np.dot(hmati,ari)
                        ri[0]= pbc(ri[0])
                        ri[1]= pbc(ri[1])
                        ri[2]= pbc(ri[2])
                        sidsl[inc] = sidt
                        possl[inc] = ri
                        velsl[inc,:] = 0.0
                        frcsl[inc,:] = 0.0
                        symsl.append(nsys.specorder[sidt-1])
                        inc += 1
                        if inc > nmax:
                            raise ValueError('inc > nmax')
    #...Create filled arrays from non-filled ones
    poss = np.array(possl[:inc])
    vels = np.array(velsl[:inc])
    frcs = np.array(frcsl[:inc])
    nsys.add_atoms(symsl,poss,vels,frcs)

    #...remove too-close atoms at the grain boundaries
    print(' Making pair list in order to remove close atoms...')
    print(' Number of atoms: ',nsys.num_atoms())
    nsys.make_pair_list(RCUT)
    nsys.write('POSCAR_orig')
    short_pairs = []
    # dmin2= dmin**2
    # xij= np.zeros((3,))
    print(' Making the list of SHORT pairs...')
    for ia in range(nsys.num_atoms()):
        lst= nsys.get_atom_attr(ia,'lspr')
        for j in range(len(lst)):
            ja= lst[j]
            if ja > ia:
                continue
            dij = nsys.get_distance(ia,ja)
            if dij < dmin:
                short_pairs.append((ia,ja,dij))

    print(' Number of short pairs: ',len(short_pairs))

    #...Remove only relevant atoms, not all the atoms in the short_pairs.
    ls_remove = []
    ls_not_remove = []
    for pair in short_pairs:
        ia = pair[0]
        ja = pair[1]
        if ia not in ls_not_remove and ja not in ls_not_remove:
            ls_remove.append(ia)
            ls_not_remove.append(ja)
        elif ia not in ls_not_remove:
            ls_remove.append(ia)
        elif ja not in ls_not_remove:
            ls_remove.append(ja)
        else:  # Both atoms are already in not_remove list, which should be avoided.
            ls_not_remove.remove(ia)
            ls_remove.append(ia)
            ls_not_remove.append(ja)
    #...Remove double registered IDs
    ls_remove = uniq(ls_remove)
    print(' Number of to be removed atoms: ',len(ls_remove))

    nsys.remove_atoms(*ls_remove)
    return nsys