Ejemplo n.º 1
0
def vac_antisite_def_struct_gen(c_size=15,
                                mpid="",
                                struct=None,
                                write_file=True):
    """
    Vacancy, antisite generator

    Args:
         c_size: cell size
         struct: Structure object or
         mpid: materials project id
    Returns:
            def_str: defect structures in Poscar object format
    """
    def_str = []
    if struct == None:
        with MPRester() as mp:
            struct = mp.get_structure_by_material_id(mpid)
        if mpid == "":
            print("Provide structure")
    c_size = c_size
    prim_struct_sites = len(struct.sites)
    struct = SpacegroupAnalyzer(struct).get_conventional_standard_structure()
    dim1 = int((float(c_size) / float(max(abs(struct.lattice.matrix[0]))))) + 1
    dim2 = int(float(c_size) / float(max(abs(struct.lattice.matrix[1])))) + 1
    dim3 = int(float(c_size) / float(max(abs(struct.lattice.matrix[2])))) + 1
    cellmax = max(dim1, dim2, dim3)
    conv_struct_sites = len(struct.sites)
    conv_prim_rat = int(conv_struct_sites / prim_struct_sites)
    sc_scale = [dim1, dim2, dim3]
    print("sc_scale", sc_scale)

    tmp = struct.copy()
    tmp.make_supercell(sc_scale)
    sc_tmp = tmp  # Poscar(tmp).structure .make_supercell(list(sc_scale))
    scs = list(VacancyGenerator(struct))
    supercell = Poscar(sc_tmp)
    supercell.comment = str("bulk") + str("@") + str("cellmax") + str(cellmax)
    def_str.append(supercell)
    if write_file == True:
        supercell.write_file("POSCAR-" + str("bulk") + str(".vasp"))

    for i in range(len(scs)):
        sc = scs[i].generate_defect_structure(sc_scale)
        poscar = Poscar(sc)  # mpvis.get_poscar(sc)
        pmg_name = str(scs[i].name).split("_")
        sitespecie = pmg_name[1]
        mult = pmg_name[2].split("mult")[1]
        name = (str("vacancy_") + str(i + 1) + str("_mult-") + str(mult) +
                str("_sitespecie-") + str(sitespecie) + str("@cellmax") +
                str(cellmax))
        poscar.comment = str(name)
        def_str.append(poscar)
        if write_file == True:
            filename = (str("POSCAR-") + str("vacancy_") + str(i + 1) +
                        str("_mult-") + str(mult) + str("_sitespecie-") +
                        str(sitespecie) + str(".vasp"))
            poscar.write_file(filename)

    return def_str
Ejemplo n.º 2
0
def surfer(mpid='',
           vacuum=15,
           layers=2,
           mat=None,
           max_index=1,
           write_file=True):
    """
    ASE surface bulder

    Args:
        vacuum: vacuum region
        mat: Structure object
        max_index: maximum miller index
        min_slab_size: minimum slab size

    Returns:
           structures: list of surface Structure objects
    """

    if mat == None:
        with MPRester() as mp:
            mat = mp.get_structure_by_material_id(mpid)
        if mpid == '':
            print('Provide structure')

    sg_mat = SpacegroupAnalyzer(mat)
    mat_cvn = sg_mat.get_conventional_standard_structure()
    mat_cvn.sort()
    indices = get_symmetrically_distinct_miller_indices(mat_cvn, max_index)
    ase_atoms = AseAtomsAdaptor().get_atoms(mat_cvn)

    structures = []
    pos = Poscar(mat_cvn)
    try:
        pos.comment = str('sbulk') + str('@') + str('vac') + str(vacuum) + str(
            '@') + str('layers') + str(layers)
    except:
        pass
    structures.append(pos)
    if write_file == True:
        mat_cvn.to(fmt='poscar',
                   filename=str('POSCAR-') + str('cvn') + str('.vasp'))
    for i in indices:
        ase_slab = surface(ase_atoms, i, layers)
        ase_slab.center(vacuum=vacuum, axis=2)
        slab_pymatgen = AseAtomsAdaptor().get_structure(ase_slab)
        slab_pymatgen.sort()
        surf_name = '_'.join(map(str, i))
        pos = Poscar(slab_pymatgen)
        try:
            pos.comment = str("Surf-") + str(surf_name) + str('@') + str(
                'vac') + str(vacuum) + str('@') + str('layers') + str(layers)
        except:
            pass
        if write_file == True:
            pos.write_file(filename=str('POSCAR-') + str("Surf-") +
                           str(surf_name) + str('.vasp'))
        structures.append(pos)

    return structures
Ejemplo n.º 3
0
def vac_intl(cellmax=2, mpid='', struct=None):
    """
    Vacancy and interstitial generator

    Args:
        cellmax: maximum cell size
        struct: Structure object
    Returns:
            def_str: defect structures
    """

    if struct == None:
        with MPRester() as mp:
            struct = mp.get_structure_by_material_id(mpid)
        if mpid == '':
            print("Provide structure")
    sg_mat = SpacegroupAnalyzer(struct)
    struct = sg_mat.get_conventional_standard_structure()
    def_str = []
    count = 0
    cell_arr = [cellmax, cellmax, cellmax]
    vac = Vacancy(struct, {}, {})
    for el in list(struct.symbol_set):

        scs = vac.make_supercells_with_defects(cell_arr, el)
        for i in range(len(scs)):
            if i == 0:
                pos = Poscar(scs[i])
                pos.comment = str('bulk') + str('.') + str('cellmax') + str(
                    cellmax)
                if count == 0:
                    def_str.append(pos)
                    count = count + 1
            else:
                pos = Poscar(scs[i])
                pos.comment = str('vac') + str('cellmax') + str(cellmax) + str(
                    '@') + str(vac.get_defectsite_multiplicity(i)) + str(
                        'Element') + str(el)
                if pos not in def_str:
                    def_str.append(pos)
    struct_valrad_eval = ValenceIonicRadiusEvaluator(struct)
    val = struct_valrad_eval.valences
    rad = struct_valrad_eval.radii
    struct_val = val
    struct_rad = rad
    intl = Interstitial(struct, val, rad)

    for el in struct.composition.elements:
        scs = intl.make_supercells_with_defects(cell_arr, el)
        for i in range(1, len(scs)):
            pos = Poscar(scs[i])
            pos.comment = str('intl') + str('cellmax') + str(cellmax) + str(
                '@') + str(intl.get_defectsite_coordination_number(
                    i - 1)) + str('Element') + str(el)
            if pos not in def_str:
                def_str.append(pos)
    print(len(def_str))
    return def_str
Ejemplo n.º 4
0
def pmg_surfer(mpid='', vacuum=15, mat=None, max_index=1, min_slab_size=15):
    if mat == None:
        with MPRester() as mp:
            mat = mp.get_structure_by_material_id(mpid)
        if mpid == '':
            print('Provide structure')

    sg_mat = SpacegroupAnalyzer(mat)
    mat_cvn = sg_mat.get_conventional_standard_structure()
    mat_cvn.sort()
    indices = get_symmetrically_distinct_miller_indices(mat_cvn, max_index)
    #ase_atoms = AseAtomsAdaptor().get_atoms(mat_cvn)

    structures = []
    pos = Poscar(mat_cvn)
    try:
        pos.comment = str('sbulk') + str('@') + str('vac') + str(vacuum) + str(
            '@') + str('size') + str(min_slab_size)
    except:
        pass
    structures.append(pos)
    mat_cvn.to(fmt='poscar',
               filename=str('POSCAR-') + str('cvn') + str('.vasp'))
    for i in indices:
        slab = SlabGenerator(initial_structure=mat_cvn,
                             miller_index=i,
                             min_slab_size=min_slab_size,
                             min_vacuum_size=vacuum,
                             lll_reduce=False,
                             center_slab=True,
                             primitive=False).get_slab()
        normal_slab = slab.get_orthogonal_c_slab()
        slab_pymatgen = Poscar(normal_slab).structure
        #ase_slab.center(vacuum=vacuum, axis=2)
        #slab_pymatgen = AseAtomsAdaptor().get_structure(ase_slab)
        xy_size = min_slab_size
        dim1 = int((float(xy_size) /
                    float(max(abs(slab_pymatgen.lattice.matrix[0]))))) + 1
        dim2 = int(
            float(xy_size) /
            float(max(abs(slab_pymatgen.lattice.matrix[1])))) + 1
        slab_pymatgen.make_supercell([dim1, dim2, 1])
        slab_pymatgen.sort()
        surf_name = '_'.join(map(str, i))
        pos = Poscar(slab_pymatgen)
        try:
            pos.comment = str("Surf-") + str(surf_name) + str('@') + str(
                'vac') + str(vacuum) + str('@') + str('size') + str(
                    min_slab_size)
        except:
            pass
        pos.write_file(filename=str('POSCAR-') + str("Surf-") +
                       str(surf_name) + str('.vasp'))
        structures.append(pos)

    return structures
Ejemplo n.º 5
0
def surfer(vacuum=15, layers=2, mat=None, max_index=1, write_file=True):
    """
    ASE surface bulder

    Args:
        vacuum: vacuum region
        mat: Structure object
        max_index: maximum miller index
        min_slab_size: minimum slab size

    Returns:
           structures: list of surface Structure objects
    """

    if mat == None:
        print("Provide structure")

    sg_mat = SpacegroupAnalyzer(mat)
    mat_cvn = sg_mat.get_conventional_standard_structure()
    mat_cvn.sort()
    indices = get_symmetrically_distinct_miller_indices(mat_cvn, max_index)
    ase_atoms = AseAtomsAdaptor().get_atoms(mat_cvn)

    structures = []
    pos = Poscar(mat_cvn)
    try:
        pos.comment = (str("sbulk") + str("@") + str("vac") + str(vacuum) +
                       str("@") + str("layers") + str(layers))
    except:
        pass
    structures.append(pos)
    if write_file == True:
        mat_cvn.to(fmt="poscar",
                   filename=str("POSCAR-") + str("cvn") + str(".vasp"))
    for i in indices:
        ase_slab = surface(ase_atoms, i, layers)
        ase_slab.center(vacuum=vacuum, axis=2)
        slab_pymatgen = AseAtomsAdaptor().get_structure(ase_slab)
        slab_pymatgen.sort()
        surf_name = "_".join(map(str, i))
        pos = Poscar(slab_pymatgen)
        try:
            pos.comment = (str("Surf-") + str(surf_name) + str("@") +
                           str("vac") + str(vacuum) + str("@") +
                           str("layers") + str(layers))
        except:
            pass
        if write_file == True:
            pos.write_file(filename=str("POSCAR-") + str("Surf-") +
                           str(surf_name) + str(".vasp"))
        structures.append(pos)

    return structures
Ejemplo n.º 6
0
def constrain(structs, fnames, atom_index, in_str=" "):
    #len(structs)==1
    mlog.debug("len(structs): {} ".format(len(structs)))
    mlog.debug("fnames: {} ".format(fnames[0]))
    for struct, fname in zip(structs, fnames):
        mlog.debug(fname)
        mlog.debug(struct)
        natom = struct.num_sites
        selective_dynamics = [[True for col in range(3)]
                              for row in range(natom)]
        for i in range(natom):
            if i in atom_index:
                selective_dynamics[i] = [False, False, False]
        tmp_struct = Structure(
            struct.lattice,
            struct.species,
            struct.frac_coords,
            site_properties={'selective_dynamics': selective_dynamics})
        poscar = Poscar(tmp_struct)
        poscar.comment = poscar.comment + ' |--> ' + in_str
        filename = 'Fixed_' + fname + '.vasp'
        poscar.write_file(filename)
Ejemplo n.º 7
0
def vac_antisite_def_struct_gen(c_size=15,
                                mpid='',
                                struct=None,
                                write_file=True):
    """
    Vacancy, antisite generator

    Args:
         c_size: cell size
         struct: Structure object or
         mpid: materials project id
    Returns:
            def_str: defect structures in Poscar object format
    """
    def_str = []
    if struct == None:
        with MPRester() as mp:
            struct = mp.get_structure_by_material_id(mpid)
        if mpid == '':
            print("Provide structure")
    c_size = c_size
    dim1 = int((float(c_size) / float(max(abs(struct.lattice.matrix[0]))))) + 1
    dim2 = int(float(c_size) / float(max(abs(struct.lattice.matrix[1])))) + 1
    dim3 = int(float(c_size) / float(max(abs(struct.lattice.matrix[2])))) + 1
    cellmax = max(dim1, dim2, dim3)
    prim_struct_sites = len(struct.sites)
    struct = SpacegroupAnalyzer(struct).get_conventional_standard_structure()
    conv_struct_sites = len(struct.sites)
    conv_prim_rat = int(conv_struct_sites / prim_struct_sites)
    sc_scale = [dim1, dim2, dim3]
    print("sc_scale", sc_scale)

    struct_valrad_eval = ValenceIonicRadiusEvaluator(struct)
    val = struct_valrad_eval.valences
    rad = struct_valrad_eval.radii
    struct_val = val
    struct_rad = rad

    vac = Vacancy(struct, {}, {})
    scs = vac.make_supercells_with_defects(sc_scale)

    for i in range(len(scs)):
        sc = scs[i]
        poscar = Poscar(sc)  #mpvis.get_poscar(sc)

        interdir = mpid
        if not i:
            fin_dir = os.path.join(interdir, 'bulk')
            poscar.comment = str('bulk') + str('@') + str('cellmax') + str(
                cellmax)
            def_str.append(poscar)
            if write_file == True:
                poscar.write_file('POSCAR-' + str('bulk') + str(".vasp"))
        else:
            blk_str_sites = set(scs[0].sites)
            vac_str_sites = set(sc.sites)
            vac_sites = blk_str_sites - vac_str_sites
            vac_site = list(vac_sites)[0]
            site_mult = int(
                vac.get_defectsite_multiplicity(i - 1) / conv_prim_rat)
            vac_site_specie = vac_site.specie
            vac_symbol = vac_site.specie.symbol

            vac_dir = 'vacancy_{}_mult-{}_sitespecie-{}'.format(
                str(i), site_mult, vac_symbol)
            fin_dir = os.path.join(interdir, vac_dir)
            try:
                poscar.comment = str(vac_dir) + str('@') + str(
                    'cellmax') + str(cellmax)
            except:
                pass
            pos = poscar
            def_str.append(pos)
            if write_file == True:
                poscar.write_file('POSCAR-' + str(vac_dir) + str(".vasp"))
            struct_species = scs[0].types_of_specie
            for specie in set(struct_species) - set([vac_site_specie]):
                subspecie_symbol = specie.symbol
                anti_struct = sc.copy()
                anti_struct.append(specie, vac_site.frac_coords)

                poscar = Poscar(anti_struct)
                as_dir = 'antisite_{}_mult-{}_sitespecie-{}_subspecie-{}'.format(
                    str(i), site_mult, vac_symbol, subspecie_symbol)
                fin_dir = os.path.join(interdir, as_dir)
                poscar.comment = str(as_dir) + str('@') + str('cellmax') + str(
                    cellmax)
                pos = poscar
                def_str.append(pos)
                if write_file == True:
                    poscar.write_file('POSCAR-' + str(as_dir) + str(".vasp"))

    return def_str
Ejemplo n.º 8
0
def vac_antisite_def_struct_gen(c_size=15,mpid='',struct=None):
    """
    Vacancy, antisite generator
    Args:
         c_size: cell size
         struct: Structure object or
         mpid: materials project id
    Returns:
            def_str: defect structures in Poscar object format
    """     
    def_str=[]
    if struct ==None:
        with MPRester() as mp:
                struct = mp.get_structure_by_material_id(mpid)
        if mpid == '':
           print ("Provide structure")
    c_size=c_size
    dim1=int((float(c_size)/float( max(abs(struct.lattice.matrix[0])))))+1
    dim2=int(float(c_size)/float( max(abs(struct.lattice.matrix[1]))))+1
    dim3=int(float(c_size)/float( max(abs(struct.lattice.matrix[2]))))+1
    cellmax=max(dim1,dim2,dim3)
    #print ("in vac_def cellmax=",cell
    prim_struct_sites = len(struct.sites)
    struct = SpacegroupAnalyzer(struct).get_conventional_standard_structure()
    conv_struct_sites = len(struct.sites)
    conv_prim_rat = int(conv_struct_sites/prim_struct_sites)
    #sc_scale = get_sc_scale(struct,cellmax)
    sc_scale=[dim1,dim2,dim3]
    #sc_scale=[cellmax,cellmax,cellmax]
    print ("sc_scale",sc_scale)
    #mpvis = MITRelaxSet #MPGGAVaspInputSet()

    # Begin defaults: All default settings.
    #blk_vasp_incar_param = {'IBRION':-1,'EDIFF':1e-4,'EDIFFG':0.001,'NSW':0,}
    #def_vasp_incar_param = {'ISIF':2,'NELM':99,'IBRION':2,'EDIFF':1e-6, 
    #                        'EDIFFG':0.001,'NSW':40,}
    #kpoint_den = 6000
    # End defaults
    
    #ptcr_flag = True
    #try:
    #    potcar = mpvis.get_potcar(struct)
    #except:
    #    print ("VASP POTCAR folder not detected.\n" \
    #          "Only INCAR, POSCAR, KPOINTS are generated.\n" \
    #          "If you have VASP installed on this system, \n" \
    #          "refer to pymatgen documentation for configuring the settings.")
    #    ptcr_flag = False





    struct_valrad_eval = ValenceIonicRadiusEvaluator(struct)
    val = struct_valrad_eval.valences
    rad = struct_valrad_eval.radii
    struct_val = val
    struct_rad = rad



    vac = Vacancy(struct, {}, {})
    scs = vac.make_supercells_with_defects(sc_scale)
    #site_no = scs[0].num_sites
    #if site_no > cellmax:
    #    max_sc_dim = max(sc_scale)
    #    i = sc_scale.index(max_sc_dim)
    #    sc_scale[i] -= 1
    #    scs = vac.make_supercells_with_defects(sc_scale)
    #print ('struct',scs)


    for i in range(len(scs)):
        sc = scs[i]
        #print (type(sc))
        poscar = Poscar(sc) #mpvis.get_poscar(sc)
        #kpoints = Kpoints.automatic_density(sc,kpoint_den)
        #incar = mpvis.get_incar(sc)
        #if ptcr_flag:
        #    potcar = mpvis.get_potcar(sc)

        interdir = mpid
        if not i:
            fin_dir = os.path.join(interdir,'bulk')
            #try:
            #    os.makedirs(fin_dir)
            #except:
            #    pass
            #incar.update(blk_vasp_incar_param)
            #incar.write_file(os.path.join(fin_dir,'INCAR'))
            #poscar.write_file(os.path.join(fin_dir,'POSCAR'))
            poscar.comment=str('bulk')+str('@')+str('cellmax')+str(cellmax)
            def_str.append(poscar)
            poscar.write_file('POSCAR-'+str('bulk')+str(".vasp"))
            #if ptcr_flag:
            #    potcar.write_file(os.path.join(fin_dir,'POTCAR'))
            #kpoints.write_file(os.path.join(fin_dir,'KPOINTS'))
        else:
            blk_str_sites = set(scs[0].sites)
            vac_str_sites = set(sc.sites)
            vac_sites = blk_str_sites - vac_str_sites
            vac_site = list(vac_sites)[0]
            site_mult = int(vac.get_defectsite_multiplicity(i-1)/conv_prim_rat)
            #try:
            #   site_mult = int(vac.get_defectsite_multiplicity(i-1)/conv_prim_rat)
            #except:
            #   site_mult=1
            #   pass
            vac_site_specie = vac_site.specie
            vac_symbol = vac_site.specie.symbol

            vac_dir ='vacancy_{}_mult-{}_sitespecie-{}'.format(str(i),
                    site_mult, vac_symbol)
            fin_dir = os.path.join(interdir,vac_dir)
            #try:
            #    os.makedirs(fin_dir)
            #except:
            #    pass
            #incar.update(def_vasp_incar_param)
            try:
                poscar.comment=str(vac_dir)+str('@')+str('cellmax')+str(cellmax)
            except:
                pass
            pos=poscar
            #pos=poscar.structure
            def_str.append(pos)
            #poscar.write_file(os.path.join(fin_dir,'POSCAR'))
            poscar.write_file('POSCAR-'+str(vac_dir)+str(".vasp"))
            #incar.write_file(os.path.join(fin_dir,'INCAR'))
            #if ptcr_flag:
            #    potcar.write_file(os.path.join(fin_dir,'POTCAR'))
            #kpoints.write_file(os.path.join(fin_dir,'KPOINTS'))

            # Antisite generation at all vacancy sites
            struct_species = scs[0].types_of_specie
            for specie in set(struct_species)-set([vac_site_specie]):
                subspecie_symbol = specie.symbol
                anti_struct = sc.copy()
                anti_struct.append(specie, vac_site.frac_coords)
                
                poscar = Poscar(anti_struct)
                #incar = mpvis.get_incar(anti_struct)
                #incar.update(def_vasp_incar_param)
                as_dir ='antisite_{}_mult-{}_sitespecie-{}_subspecie-{}'.format(
                        str(i), site_mult, vac_symbol, subspecie_symbol)
                fin_dir = os.path.join(interdir,as_dir)
                #try:
                #    os.makedirs(fin_dir)
                #except:
                #    pass
                poscar.comment=str(as_dir)+str('@')+str('cellmax')+str(cellmax)
                pos=poscar
                #pos=poscar.structure
                def_str.append(pos)
                #poscar.write_file(os.path.join(fin_dir,'POSCAR'))
                poscar.write_file('POSCAR-'+str(as_dir)+str(".vasp"))
                #incar.write_file(os.path.join(fin_dir,'INCAR'))
                #if ptcr_flag:
                #        potcar.write_file(os.path.join(fin_dir,'POTCAR'))
                #kpoints.write_file(os.path.join(fin_dir,'KPOINTS'))
    #try:
    #    struct.make_supercell(sc_scale) 
    #    intl = Interstitial(struct, val, rad)
    #    cell_arr=sc_scale
    #    for el in struct.composition.elements:
    #        scs = intl.make_supercells_with_defects(1,el)
    #        #scs = intl.make_supercells_with_defects(cell_arr,el)
    #        for i in range(1,len(scs)):
    #           pos=Poscar(scs[i])
    #           pos.comment=str('intl_')+str('cellmax')+str(cellmax)+str('@')+str(intl.get_defectsite_coordination_number(i-1))+str('Element')+str(el)
    #           def_str.append(pos)
    #           pos.write_file('POSCAR-'+str('intl_')+str('cellmax')+str(cellmax)+str('@')+str(intl.get_defectsite_coordination_number(i-1))+str('Element')+str(el))

    #except:
    #      pass

    return def_str
Ejemplo n.º 9
0
def twoD_operation():
    #sepline(ch='2D structure operation',sp='=')
    print('your choice ?')
    print('{} >>> {}'.format('1', 'build rippled structure'))
    print('{} >>> {}'.format('2', 'build multi-layered structure'))
    print('{} >>> {}'.format('3', 'split multi-layered structure'))
    print('{} >>> {}'.format('4', 'resize vacuum layer'))
    print('{} >>> {}'.format('5', 'center atomic-layer along z direction'))
    print('{} >>> {}'.format('6', 'apply strain along different direction'))
    print('{} >>> {}'.format('7', 'constrain atom in specific range'))
    print('{} >>> {}'.format('8',
                             'get a substrate for 2D material (online!!!)'))
    wait_sep()

    in_str = ""
    while in_str == "":
        in_str = input().strip()

    choice = int(in_str)
    if choice == 1:
        struct = readstructure()
        margin_dist = 1.0  #
        assert (struct.lattice.is_orthogonal)
        print("input the supercell scaling factor")
        print('for x direction can be: 10 1 1')
        print('for y direction can be: 1 10 1')
        wait_sep()
        scale_str = input()
        scaling = [int(x) for x in scale_str.split()]
        if (len(scaling) != 3):
            print('unknow format')
        else:
            if scaling[0] >= scaling[1]:
                direction = 0  # for x direction
            else:
                direction = 1  # for y direction
        print("input the strain range")
        print("example: 0.02:0.1:10 ")
        wait_sep()
        strain_str = input()
        tmp = [float(x) for x in strain_str.split(":")]
        strain = []
        if len(tmp) == 3:
            strain_range = np.linspace(tmp[0], tmp[1], int(tmp[2]))
        #     print(strain_range)
        else:
            print("unknow format")
            return
        print("input the index of atom need to be fixed")
        print("example: 1 10 11 20 ")
        print("0 means fix the atom automatically")
        wait_sep()
        atom_index_str = input()
        try:
            atom_index = [int(x) for x in strain_str.split("")]
            auto_fix = False
        except:
            atom_index = [int(atom_index_str)]
            auto_fix = True

        struct_sc = struct.copy()
        struct_sc.make_supercell(scaling)
        natom = struct_sc.num_sites
        min_z = np.min(struct_sc.cart_coords[:, 2])
        tmp_coords = np.ones((struct_sc.num_sites, 1)) * min_z
        cart_coords = struct_sc.cart_coords
        cart_coords[:, 2] = cart_coords[:, 2] - tmp_coords.T + 0.01
        frac_coords_new = np.dot(cart_coords,
                                 np.linalg.inv(struct_sc.lattice.matrix))
        for i_strain in strain_range:
            new_lat_matrix = struct_sc.lattice.matrix
            new_lat_matrix[direction, direction] = struct_sc.lattice.matrix[
                direction, direction] * (1 - i_strain)
            fname = "%10.5f" % (
                i_strain
            ) + '_wo.vasp'  # structure only applied with in-plan strain
            struct_wo_ripple = Structure(new_lat_matrix, struct_sc.species,
                                         frac_coords_new)
            struct_wo_ripple.to(filename=fname.strip(), fmt='poscar')
            frac_coords_new_cp = struct_wo_ripple.frac_coords.copy()
            cart_coords_new_cp = struct_wo_ripple.cart_coords.copy()
            nz = 0
            selective_dynamics = [[True for col in range(3)]
                                  for row in range(natom)]
            z_shift = np.zeros((natom, 3))
            for i_atom in range(natom):
                z_shift[i_atom,
                        2] = 40 * (2 * i_strain - 10 * i_strain**2) * np.sin(
                            cart_coords_new_cp[i_atom, direction] * np.pi /
                            new_lat_matrix[direction, direction])
                if cart_coords_new_cp[i_atom,
                                      direction] < nz or cart_coords_new_cp[
                                          i_atom, direction] > new_lat_matrix[
                                              direction, direction] - nz:
                    z_shift[i_atom, 2] = 0.0

                if auto_fix:
                    if struct_wo_ripple[i_atom].coords[direction]<margin_dist or \
                       struct_wo_ripple[i_atom].coords[direction] > new_lat_matrix[direction,direction]-margin_dist:
                        selective_dynamics[i_atom] = [False, False, False]
                else:
                    if i_atom in atom_index:
                        selective_dynamics[i_atom] = [False, False, False]

            struct_w_ripple=Structure(new_lat_matrix,struct_sc.species,cart_coords_new_cp+z_shift,coords_are_cartesian=True,\
                                     site_properties={'selective_dynamics':selective_dynamics})
            fname = "%10.5f" % (
                i_strain
            ) + '_w.vasp'  # structure  applied with in-plan strain  and ripple
            struct_w_ripple.to(filename=fname.strip(), fmt='poscar')
    elif choice == 2:
        struct = readstructure()
        print("input the number of layers")
        wait_sep()
        in_str = ""
        while in_str == "":
            in_str = input().strip()
        layer_number = int(in_str)

        print("input the layer distance")
        wait_sep()
        species = []
        in_str = ""
        while in_str == "":
            in_str = input().strip()
        layer_distance = float(in_str)

        new_struct = move_to_zcenter(struct)
        struct_thickness = np.max(new_struct.cart_coords[:, 2]) - np.min(
            new_struct.cart_coords[:, 2])
        natom = new_struct.num_sites
        new_cart_coords = np.zeros((natom * layer_number, 3))
        for i in range(layer_number):
            new_cart_coords[i * natom:(i + 1) * natom,
                            0:2] = new_struct.cart_coords[:, 0:2]
            new_cart_coords[i * natom:(i + 1) * natom,
                            2] = new_struct.cart_coords[:, 2] + i * (
                                layer_distance + struct_thickness)
            species.extend(new_struct.species)
        new_lat = new_struct.lattice.matrix
        new_lat[2, 2] = new_lat[2, 2] + layer_distance * layer_number
        tmp_struct = Structure(new_lat,
                               species,
                               new_cart_coords,
                               coords_are_cartesian=True)
        tmp1_struct = move_to_zcenter(tmp_struct)
        tmp2_struct = tmp1_struct.get_sorted_structure()
        tmp2_struct.to(filename='layer_' + str(layer_number) + '.vasp',
                       fmt='poscar')

    elif choice == 3:
        ProperDist = 3.5  # Ang
        struct = readstructure()
        (atom_index, in_str) = atom_selection(struct)
        print("input the splitting distance, 10 Ang is enough!")
        wait_sep()
        in_str = ""
        while in_str == "":
            in_str = input().strip()
        SplitDistance = float(in_str)
        print("numbers of splitting site, 50 sites are enough!")
        wait_sep()
        in_str = ""
        while in_str == "":
            in_str = input().strip()
        NumberSplitSite = int(in_str)
        DensityN = int(NumberSplitSite * 0.75)
        SparseN = NumberSplitSite - DensityN + 1
        #        print(DensityN,SparseN)
        dist = ProperDist / (DensityN - 1)
        SplitDistanceArray = np.zeros(NumberSplitSite + 1)
        for Nsite in range(DensityN):
            SplitDistanceArray[Nsite] = (Nsite) * dist

        dist = (SplitDistance - ProperDist) / SparseN
        for Nsite in range(SparseN):
            SplitDistanceArray[Nsite +
                               DensityN] = ProperDist + (Nsite + 1) * dist


#        print(SplitDistanceArray)
        coords = struct.cart_coords
        for Nsite in range(NumberSplitSite + 1):
            coords = struct.cart_coords
            for atom in atom_index:
                coords[atom, 2] = coords[atom, 2] + SplitDistanceArray[Nsite]
            tmp_struct = Structure(struct.lattice,
                                   struct.species,
                                   coords,
                                   coords_are_cartesian=True)
            fname = str(Nsite) + '.vasp'
            tmp_struct.to(filename=fname, fmt='poscar')
        data = np.zeros((NumberSplitSite + 1, 2))
        for i, j in enumerate(SplitDistanceArray):
            data[i][0] = i
            data[i][1] = j
        head_line = "#%(key1)+12s  %(key2)+12s" % {
            'key1': 'index',
            'key2': 'distance/Ang'
        }
        fmt = "%12d %12.6f" + '\n'
        write_col_data('split.dat', data, head_line, sp_fmt=fmt)
        return

    elif choice == 4:
        struct = readstructure()
        new_struct = move_to_zcenter(struct)
        struct_thickness = np.max(new_struct.cart_coords[:, 2]) - np.min(
            new_struct.cart_coords[:, 2])
        vac_layer_thickness = new_struct.lattice.c - struct_thickness
        print("current vacuum layer thickness is %6.3f Ang" %
              (vac_layer_thickness))
        print("input the new value of vacuum layer thickness")
        wait_sep()
        in_str = ""
        while in_str == "":
            in_str = input().strip()
        nvac_layer_thickness = float(in_str)

        assert (nvac_layer_thickness > struct_thickness)
        new_lat = new_struct.lattice.matrix
        new_lat[2, 2] = nvac_layer_thickness
        tmp_struct = Structure(new_lat,
                               new_struct.species,
                               new_struct.cart_coords,
                               coords_are_cartesian=True)
        center_struct = move_to_zcenter(tmp_struct)
        center_struct.to(filename='new_vacuum.vasp', fmt='poscar')
        return

    elif choice == 5:
        struct = readstructure()
        new_struct = move_to_zcenter(struct)
        new_struct.to(filename='z-center.vasp', fmt='poscar')
        return

    elif choice == 6:
        struct = readstructure()
        assert (struct.lattice.is_orthogonal)
        try:
            import sympy
        except:
            print("you must install sympy module")
            return

        new_struct = move_to_zcenter(struct)
        print("input the elastic of material by order : C11 C12 C22 C66")
        wait_sep()
        in_str = ""
        while in_str == "":
            in_str = input().strip().split()
        elastic_constant = [float(x) for x in in_str]
        if len(elastic_constant) != 4:
            print("you must input C11 C12 C22 C66")
            return
        C11 = elastic_constant[0]
        C12 = elastic_constant[1]
        C22 = elastic_constant[2]
        C66 = elastic_constant[3]
        print("input applied force: e.x. 1.0 GPa nm")
        wait_sep()
        in_str = ""
        while in_str == "":
            in_str = input().strip()
        sigma = float(in_str)
        orig_struct = new_struct.copy()
        new_struct = new_struct.copy()
        natom = orig_struct.num_sites
        lat = orig_struct.lattice.matrix
        pos = orig_struct.frac_coords
        nps = 37
        phi = np.linspace(0, 360, nps) * np.pi / 180
        vzz = C12 / C22
        temp_num = (C11 * C22 - C12**2) / (C22 * C66)
        d1 = C11 / C22 + 1.0 - temp_num
        d2 = -(2.0 * C12 / C22 - temp_num)
        d3 = C11 / C22
        F = sigma * C22 / (C11 * C22 - C12**2.0)
        Poisson=(vzz*(np.cos(phi))**4.0-d1*(np.cos(phi))**2.0*(np.sin(phi))**2.0+vzz*(np.sin(phi))**4.0)/\
                ((np.cos(phi))**4.0+d2*(np.cos(phi))**2.0*(np.sin(phi))**2.0+d3*(np.sin(phi))**4.0)

        eps_theta = F * ((np.cos(phi))**4 + d2 * (np.cos(phi))**2.0 *
                         (np.sin(phi))**2.0 + d3 * (np.sin(phi))**4.0)
        t = sympy.Symbol('t', real=True)
        e = sympy.Symbol('e', real=True)
        v = sympy.Symbol('v', real=True)
        eprim = sympy.Matrix([[e + 1, 0], [0, 1 - e * v]])
        R = sympy.Matrix([[sympy.cos(t), -sympy.sin(t)],
                          [sympy.sin(t), sympy.cos(t)]])
        eps_mat = R * eprim * R.adjugate()
        for k in range(len(phi)):
            cur__phi = phi[k] * 180 / np.pi
            Rot = eps_mat.subs({e: eps_theta[k], v: Poisson[k], t: phi[k]})
            fname = str(k) + '.vasp'
            final_lat = np.matrix(np.eye(3))
            final_lat[0, 0] = Rot[0, 0]
            final_lat[0, 1] = Rot[0, 1]
            final_lat[1, 0] = Rot[1, 0]
            final_lat[1, 1] = Rot[1, 1]
            lat_new = lat * final_lat
            tmp_struct = Structure(lat_new, new_struct.species, pos)
            tmp_struct.to(filename=fname, fmt='poscar')
        return

    elif choice == 7:
        struct = readstructure()
        natom = struct.num_sites
        atom_index, in_str = atom_selection(struct)
        selective_dynamics = [[True for col in range(3)]
                              for row in range(natom)]
        for i in range(natom):
            if i in atom_index:
                selective_dynamics[i] = [False, False, False]
        tmp_struct = Structure(
            struct.lattice,
            struct.species,
            struct.frac_coords,
            site_properties={'selective_dynamics': selective_dynamics})
        poscar = Poscar(tmp_struct)
        poscar.comment = poscar.comment + ' |--> ' + in_str
        poscar.write_file('Fixed.vasp')
        return

    elif choice == 8:
        print('your choice ?')
        print('{} >>> {}'.format('1', 'input 2D structure from local disk'))
        print('{} >>> {}'.format('2', 'get 2D structure online'))
        wait_sep()
        in_str = ""
        while in_str == "":
            in_str = input().strip()
        choice = int(in_str)

        if choice == 1:
            mpid = None
            struct = readstructure()
        else:
            print("input the mp-id for your structure")
            wait_sep()
            in_str = ""
            while in_str == "":
                in_str = input().strip()
            mpid = in_str
            struct = None

        film, substrates = make_connect(mpid=mpid, struct=struct)
        df = get_subs(film, substrates)
        df.to_csv('substrate.csv', sep=',', header=True, index=True)
        return
    else:
        print("unkonw choice")
        return
Ejemplo n.º 10
0
def pmg_surfer(vacuum=15,
               mat=None,
               max_index=1,
               min_slab_size=15,
               write_file=True):
    """
    Pymatgen surface builder for a Poscar

    Args:
        vacuum: vacuum region
        mat: Structure object
        max_index: maximum miller index
        min_slab_size: minimum slab size

    Returns:
           structures: list of surface Structure objects
    """

    if mat == None:
        print("Provide structure")

    sg_mat = SpacegroupAnalyzer(mat)
    mat_cvn = sg_mat.get_conventional_standard_structure()
    mat_cvn.sort()
    indices = get_symmetrically_distinct_miller_indices(mat_cvn, max_index)

    structures = []
    pos = Poscar(mat_cvn)
    try:
        pos.comment = (str("sbulk") + str("@") + str("vac") + str(vacuum) +
                       str("@") + str("size") + str(min_slab_size))
    except:
        pass
    structures.append(pos)
    if write_file == True:
        mat_cvn.to(fmt="poscar",
                   filename=str("POSCAR-") + str("cvn") + str(".vasp"))
    for i in indices:
        slab = SlabGenerator(
            initial_structure=mat_cvn,
            miller_index=i,
            min_slab_size=min_slab_size,
            min_vacuum_size=vacuum,
            lll_reduce=False,
            center_slab=True,
            primitive=False,
        ).get_slab()
        normal_slab = slab.get_orthogonal_c_slab()
        slab_pymatgen = Poscar(normal_slab).structure
        xy_size = min_slab_size
        dim1 = (int((float(xy_size) /
                     float(max(abs(slab_pymatgen.lattice.matrix[0]))))) + 1)
        dim2 = (int(
            float(xy_size) / float(max(abs(slab_pymatgen.lattice.matrix[1]))))
                + 1)
        slab_pymatgen.make_supercell([dim1, dim2, 1])
        slab_pymatgen.sort()
        surf_name = "_".join(map(str, i))
        pos = Poscar(slab_pymatgen)
        try:
            pos.comment = (str("Surf-") + str(surf_name) + str("@") +
                           str("vac") + str(vacuum) + str("@") + str("size") +
                           str(min_slab_size))
        except:
            pass
        if write_file == True:
            pos.write_file(filename=str("POSCAR-") + str("Surf-") +
                           str(surf_name) + str(".vasp"))
        structures.append(pos)

    return structures