def surface_vectors(lattice, miller):
    ''' Given the xtal as defined with a (3x3) cell uses the ase surface module to cut the required surface.
	Args:
	    lattice : ase Atoms object
	    miller  : miller indices of the surface, a tuple of integers, length 3.
	Returns:
	    vectors[0/1] : the surface vectors (u,v), list of real numbers.
    '''
    surf = surface.surface(lattice, miller, layers=1)
    vectors = surf.cell[0:2]
    return vectors[0], vectors[1]
Exemplo n.º 2
0
def surface_vectors(lattice,miller):
    ''' Given the xtal as defined with a (3x3) cell uses the ase surface module to cut the required surface.
	Args:
	    lattice : ase Atoms object
	    miller  : miller indices of the surface, a tuple of integers, length 3.
	Returns:
	    vectors[0/1] : the surface vectors (u,v), list of real numbers.
    '''
    surf = surface.surface(lattice,miller,layers=1)
    vectors = surf.cell[0:2]
    return vectors[0],vectors[1]
Exemplo n.º 3
0
def make_super_cell_pymatgen(jdata):
    make_unit_cell(jdata)

    out_dir = jdata['out_dir']
    path_uc = os.path.join(out_dir, global_dirname_02)
    from_path = path_uc
    from_file = os.path.join(from_path, 'POSCAR.unit')
    ss = Structure.from_file(from_file)
    # ase only support X type  element
    for i in range(len(ss)):
        ss[i] = 'X'
    ss = AseAtomsAdaptor.get_atoms(ss)

    all_millers = jdata['millers']
    path_sc = os.path.join(out_dir, global_dirname_02)
    #z_min = jdata['z_min']
    layer_numb = jdata['layer_numb']
    super_cell = jdata['super_cell']

    cwd = os.getcwd()
    path_work = (path_sc)
    path_work = os.path.abspath(path_work)
    os.chdir(path_work)
    for miller in all_millers:
        miller_str = ""
        for ii in miller:
            miller_str += str(ii)
        path_cur_surf = create_path('surf-' + miller_str)
        os.chdir(path_cur_surf)
        #slabgen = SlabGenerator(ss, miller, z_min, 1e-3)
        slab = general_surface.surface(ss,
                                       indices=miller,
                                       vacuum=1e-3,
                                       layers=layer_numb)
        #all_slabs = slabgen.get_slabs()
        dlog.info(os.getcwd())
        #dlog.info("Miller %s: The slab has %s termination, use the first one" %(str(miller), len(all_slabs)))
        #all_slabs[0].to('POSCAR', 'POSCAR')
        slab.write('POSCAR', vasp5=True)
        if super_cell[0] > 1 or super_cell[1] > 1:
            st = Structure.from_file('POSCAR')
            st.make_supercell([super_cell[0], super_cell[1], 1])
            st.to('POSCAR', 'POSCAR')
        os.chdir(path_work)
    os.chdir(cwd)
Exemplo n.º 4
0
def surfaces_with_termination(lattice,
                              indices,
                              layers,
                              vacuum=None,
                              tol=1e-10,
                              termination=None,
                              return_all=False,
                              verbose=False):
    """Create surface from a given lattice and Miller indices with a given
        termination

        Parameters
        ==========
        lattice: Atoms object or str
            Bulk lattice structure of alloy or pure metal.  Note that the
            unit-cell must be the conventional cell - not the primitive cell.
            One can also give the chemical symbol as a string, in which case the
            correct bulk lattice will be generated automatically.
        indices: sequence of three int
            Surface normal in Miller indices (h,k,l).
        layers: int
            Number of equivalent layers of the slab. (not the same as the layers
            you choose from for terminations)
        vacuum: float
            Amount of vacuum added on both sides of the slab.
        termination: str
            the atoms you wish to be in the top layer. There may be many such
            terminations, this function returns all terminations with the same
            atomic composition.
            e.g. 'O' will return oxygen terminated surfaces.
            e.g.'TiO' will return surfaces terminated with layers containing both O
            and Ti
        Returns:
        return_surfs: List
            a list of surfaces that match the specifications given

    """
    lats = translate_lattice(lattice, indices)
    return_surfs = []
    check = []
    check2 = []
    for item in lats:
        too_similar = False
        surf = surface(item, indices, layers, vacuum=vacuum, tol=tol)
        surf.wrap(pbc=[True] * 3)  # standardize slabs

        positions = surf.get_scaled_positions().flatten()
        for i, value in enumerate(positions):
            if value >= 1 - tol:  # move things closer to zero within tol
                positions[i] -= 1
        surf.set_scaled_positions(np.reshape(positions, (len(surf), 3)))
        #rep = find_z_layers(surf)
        z_layers, hs = get_layers(surf, (0, 0, 1))  # just z layers matter
        # get the indicies of the atoms in the highest layer
        top_layer = [
            i for i, val in enumerate(z_layers == max(z_layers)) if val
        ]

        if termination is not None:
            comp = [surf.get_chemical_symbols()[a] for a in top_layer]
            term = string2symbols(termination)
            # list atoms in top layer and not in requested termination
            check = [a for a in comp if a not in term]
            # list of atoms in requested termination and not in top layer
            check2 = [a for a in term if a not in comp]
        if len(return_surfs) > 0:
            pos_diff = [
                a.get_positions() - surf.get_positions() for a in return_surfs
            ]
            for i, su in enumerate(pos_diff):
                similarity_test = su.flatten() < tol * 1000
                if similarity_test.all():
                    # checks if surface is too similar to another surface
                    too_similar = True
        if too_similar:
            continue
        if return_all is True:
            pass
        elif check != [] or check2 != []:
            continue
        return_surfs.append(surf)
    return return_surfs
Exemplo n.º 5
0
def make_super_cell_pymatgen(jdata):

    make_unit_cell(jdata)
    out_dir = jdata['out_dir']
    path_uc = os.path.join(out_dir, global_dirname_02)

    elements = [Element(ii) for ii in jdata['elements']]
    if 'vacuum_min' in jdata:
        vacuum_min = jdata['vacuum_min']
    else:
        vacuum_min = max([float(ii.atomic_radius) for ii in elements])

    from_poscar = jdata.get('from_poscar', False)

    if from_poscar:
        from_poscar_path = jdata['from_poscar_path']
        poscar_name = os.path.basename(from_poscar_path)
        ss = Structure.from_file(poscar_name)
    else:
        from_path = path_uc
        from_file = os.path.join(from_path, 'POSCAR.unit')
        ss = Structure.from_file(from_file)
        # ase only support X type  element
        for i in range(len(ss)):
            ss[i] = 'X'

    ss = AseAtomsAdaptor.get_atoms(ss)

    all_millers = jdata['millers']
    path_sc = os.path.join(out_dir, global_dirname_02)

    user_layer_numb = None  # set default value
    z_min = None
    if 'layer_numb' in jdata:
        user_layer_numb = jdata['layer_numb']
    else:
        z_min = jdata['z_min']

    super_cell = jdata['super_cell']

    cwd = os.getcwd()
    path_work = (path_sc)
    path_work = os.path.abspath(path_work)
    os.chdir(path_work)
    for miller in all_millers:
        miller_str = ""
        for ii in miller:
            miller_str += str(ii)
        path_cur_surf = create_path('surf-' + miller_str)
        os.chdir(path_cur_surf)
        #slabgen = SlabGenerator(ss, miller, z_min, 1e-3)
        if user_layer_numb:
            slab = general_surface.surface(ss,
                                           indices=miller,
                                           vacuum=vacuum_min,
                                           layers=user_layer_numb)
        else:
            # build slab according to z_min value
            for layer_numb in range(1, max_layer_numb + 1):
                slab = general_surface.surface(ss,
                                               indices=miller,
                                               vacuum=vacuum_min,
                                               layers=layer_numb)
                if slab.cell.lengths()[-1] >= z_min:
                    break
                if layer_numb == max_layer_numb:
                    raise RuntimeError("can't build the required slab")
        #all_slabs = slabgen.get_slabs()
        dlog.info(os.getcwd())
        #dlog.info("Miller %s: The slab has %s termination, use the first one" %(str(miller), len(all_slabs)))
        #all_slabs[0].to('POSCAR', 'POSCAR')
        slab.write('POSCAR', vasp5=True)
        if super_cell[0] > 1 or super_cell[1] > 1:
            st = Structure.from_file('POSCAR')
            st.make_supercell([super_cell[0], super_cell[1], 1])
            st.to('POSCAR', 'POSCAR')
        os.chdir(path_work)
    os.chdir(cwd)