Exemplo n.º 1
0
    def get_interstitials(self):

        evaluator = ValenceIonicRadiusEvaluator(
            self.structure)  # computes site valence and ionic radii using bond valence analyser.
        # note this uses the sites, periodic table, bond valence, composition and local env packages! (as well as structure)
        radii = evaluator.radii
        valences = evaluator.valences

        #get the voronoi sites
        interstitial = Interstitial(self.structure, radii = radii, valences = valences,
                                         symmetry_flag = self.settings_obj.sym_dist)
        # this evaluates the structure and uses radii and valence to generate voronoi sites depending on whether vertex,
        # facecenter or edge center is selected.
        # note: not sure if hsould set oxi_state = False. By default it is true and it then uses ionic radii in the calculation,
        #  shouldnt really change centres? Returns and interstitial object. ._defect_sites returns the coordinates and labels of
        #  all intersittial sites which were found from the voronoi nodes/edges/faces/all depending on settings.
        # sym if False so we get all sites, including symmetry inequivalent sites!

        # structure the list of interstitial sites as a tuple with the voronoi radius in there
        interstitial_sites = [
            ([site._fcoords[0], site._fcoords[1], site._fcoords[2]], site.properties.get('voronoi_radius', None))
            for site in interstitial._defect_sites]  # this creates a list of tuples: [ (array of site location
        # fractional coordinates, Voronoi radius') ]

        # shift vornoi sites up if they were previously shifted down
        interstitial_sites = [([i[0][0] * self.structure.lattice.a - self.downwards_shifts[0][0],
                                     i[0][1] * self.structure.lattice.b - self.downwards_shifts[1][1],
                                     i[0][2] * self.structure.lattice.c - self.downwards_shifts[2][2]],
                                    i[1]) for i in
                                   interstitial_sites]  # shift it and convert to cart coords at the same time

        return interstitial_sites
Exemplo n.º 2
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
Exemplo n.º 3
0
    def featurize(self, s, cutoff=None, dr=0.05):
        """
        Get ReDF of input structure.

        Args:
            s: input Structure object.
            cutoff: (float) distance up to which the ReDF is to be
                    calculated (default: longest diagaonal in
                    primitive cell).
            dr: (float) width of bins ("x"-axis) of ReDF (default: 0.05 A).

        Returns: (dict) a copy of the electronic radial distribution
                functions (ReDF) as a dictionary. The distance list
                ("x"-axis values of ReDF) can be accessed via key
                'distances'; the ReDF itself is accessible via key
                'redf'.
        """
        if dr <= 0:
            raise ValueError("width of bins for ReDF must be >0")

        # Make structure primitive.
        struct = SpacegroupAnalyzer(s).find_primitive() or s

        # Add oxidation states.
        struct = ValenceIonicRadiusEvaluator(struct).structure

        if cutoff is None:
            # Set cutoff to longest diagonal.
            a = struct.lattice.matrix[0]
            b = struct.lattice.matrix[1]
            c = struct.lattice.matrix[2]
            cutoff = max([
                np.linalg.norm(a + b + c),
                np.linalg.norm(-a + b + c),
                np.linalg.norm(a - b + c),
                np.linalg.norm(a + b - c)
            ])

        nbins = int(cutoff / dr) + 1
        redf_dict = {
            "distances": np.array([(i + 0.5) * dr for i in range(nbins)]),
            "redf": np.zeros(nbins, dtype=np.float)
        }

        for site in struct.sites:
            this_charge = float(site.specie.oxi_state)
            neighs_dists = struct.get_neighbors(site, cutoff)
            for neigh, dist in neighs_dists:
                neigh_charge = float(neigh.specie.oxi_state)
                bin_index = int(dist / dr)
                redf_dict["redf"][bin_index] += (
                    this_charge * neigh_charge) / (struct.num_sites * dist)

        return redf_dict
Exemplo n.º 4
0
    def featurize(self, s, cutoff=10.0):
        """
        Get minimum relative distances of all sites of the input structure.
    
        Args:
            s: Pymatgen Structure object.

        Returns:
            min_rel_dists: (list of floats) list of all minimum relative
                    distances (i.e., for all sites).
        """
        vire = ValenceIonicRadiusEvaluator(s)
        min_rel_dists = []
        for site in vire.structure:
            min_rel_dists.append(min([dist / (
                vire.radii[site.species_string] +
                vire.radii[neigh.species_string]) for neigh, dist in \
                                      vire.structure.get_neighbors(site, self.cutoff)]))
        return [min_rel_dists[:]]
Exemplo n.º 5
0
    def featurize(self, s, cutoff=10.0):
        """
        Get minimum relative distances of all sites of the input structure.
    
        Args:
            s: Pymatgen Structure object.
            cutoff: (float) (absolute) distance up to which tentative
                    closest neighbors (on the basis of relative distances)
                    are to be determined.

        Returns:
            min_rel_dists: (list of floats) list of all minimum relative
                    distances (i.e., for all sites).
        """
        vire = ValenceIonicRadiusEvaluator(s)
        min_rel_dists = []
        for site in vire.structure:
            min_rel_dists.append(min([dist / (
                    vire.radii[site.species_string] +
                    vire.radii[neigh.species_string]) for neigh, dist in \
                    vire.structure.get_neighbors(site, cutoff)]))
        return min_rel_dists[:]
Exemplo n.º 6
0
    def apply_transformation(self, structure, return_ranked_list=False):
        """
        :param structure:
        :param return_ranked_list (Logical or integer): Use big enough
         number to return all defect structures
        :return:
            scs: Supercells with one interstitial defect in each structure.
        """
        if not return_ranked_list:
            raise ValueError("InterstitialTransformation has no single best "
                             "structure output. Must use return_ranked_list.")
        try:
            num_to_return = int(return_ranked_list)
        except ValueError:
            num_to_return = 1

        if self.radii:
            inter = Interstitial(structure, self.valences, self.radii)
        else:
            s = structure.copy()
            valrad_eval = ValenceIonicRadiusEvaluator(s)
            s = valrad_eval.structure
            val = valrad_eval.valences
            rad = valrad_eval.radii
            inter = Interstitial(s, val, rad, oxi_state=True)

        scs = inter.make_supercells_with_defects(self.supercell_dim,
                                                 self.inter_specie)

        #if num_to_return < len(scs)-1:
        #    raise ValueError("InterstitialTransformation has no ordering "
        #            "of best structures. Must increase return_ranked_list.")

        structures = []
        num_to_return = min(num_to_return, len(scs) - 1)
        for sc in scs[1:num_to_return + 1]:
            structures.append({'structure': sc})
        return structures
Exemplo n.º 7
0
def vac_antisite_def_struct_gen(c_size=15, mpid='', struct=None):
    def_str = []
    if struct == None:
        with MPRester() as mp:
            struct = mp.get_structure_by_material_id(mpid)
        if mpid == '':
            print("Provide 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)
    prim_struct_sites = len(struct.sites)
    struct = SpacegroupAnalyzer(struct).get_conventional_standard_structure()
    conv_struct_sites = len(struct.sites)
    conv_prim_rat = 1 + 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)
    #print ('scssssss',scs[0].make_supercell([1,1,1]))

    for i in range(len(scs)):
        sc = scs[i]
        mpvis = MPRelaxSet(sc)  #VaspInputSet(struct)
        #print ('sccccc',sc,type(sc[0]))
        tmp = struct.copy()
        poscar = mpvis.poscar
        #kpoints = Kpoints.automatic_density(sc,kpoint_den)
        #incar = mpvis.get_incar(sc)
        #print ('big pos',poscar)
        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)
            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)
            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)
                mpvis = MPRelaxSet(anti_struct)  #VaspInputSet(struct)
                print('anti_struct', anti_struct)
                poscar = mpvis.poscar
                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)
                poscar.write_file('POSCAR-' + str(as_dir) + str(".vasp"))

    return def_str
Exemplo n.º 8
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
Exemplo n.º 9
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
Exemplo n.º 10
0
def get_neighbors_of_site_with_index(struct, n, p=None):
    """
    Determine the neighbors around the site that has index n in the input
    Structure object struct, given the approach defined by parameters
    p.  All supported neighbor-finding approaches and listed and
    explained in the following.  All approaches start by creating a
    tentative list of neighbors using a large cutoff radius defined in
    parameter dictionary p via key "cutoff".
    "min_dist": find nearest neighbor and its distance d_nn; consider all
            neighbors which are within a distance of d_nn * (1 + delta),
            where delta is an additional parameter provided in the
            dictionary p via key "delta".
    "scaled_VIRE": compute the radii, r_i, of all sites on the basis of
            the valence-ionic radius evaluator (VIRE); consider all
            neighbors for which the distance to the central site is less
            than the sum of the radii multiplied by an a priori chosen
            parameter, delta,
            (i.e., dist < delta * (r_central + r_neighbor)).
    "min_relative_VIRE": same approach as "min_dist", except that we
            use relative distances (i.e., distances divided by the sum of the
            atom radii from VIRE).
    "min_relative_OKeeffe": same approach as "min_relative_VIRE", except
            that we use the bond valence parameters from O'Keeffe's bond valence
            method (J. Am. Chem. Soc. 1991, 3226-3229) to calculate
            relative distances.
    Args:
        struct (Structure): input structure.
        n (int): index of site in Structure object for which
                neighbors are to be determined.
        p (dict): specification (via "approach" key; default is "min_dist")
                and parameters of neighbor-finding approach.
                Default cutoff radius is 6 Angstrom (key: "cutoff").
                Other default parameters are as follows.
                min_dist: "delta": 0.15;
                min_relative_OKeeffe: "delta": 0.05;
                min_relative_VIRE: "delta": 0.05;
                scaled_VIRE: "delta": 2.
    Returns: ([site]) list of sites that are considered to be nearest
            neighbors to site with index n in Structure object struct.
    """
    warnings.warn(
        'This function will be removed as soon as the equivalent function in Pymatgen works with the new near neighbor-finding classes.')

    sites = []
    if p is None:
        p = {"approach": "min_dist", "delta": 0.1,
             "cutoff": 6}

    if p["approach"] not in [
        "min_relative_OKeeffe", "min_dist", "min_relative_VIRE", \
            "scaled_VIRE"]:
        raise RuntimeError("Unsupported neighbor-finding approach"
                           " (\"{}\")".format(p["approach"]))

    if p["approach"] == "min_relative_OKeeffe" or p["approach"] == "min_dist":
        neighs_dists = struct.get_neighbors(struct[n], p["cutoff"])
        try:
            eln = struct[n].specie.element
        except:
            eln = struct[n].species_string
    elif p["approach"] == "scaled_VIRE" or p["approach"] == "min_relative_VIRE":
        vire = ValenceIonicRadiusEvaluator(struct)
        if np.linalg.norm(struct[n].coords - vire.structure[n].coords) > 1e-6:
            raise RuntimeError("Mismatch between input structure and VIRE structure.")
        neighs_dists = vire.structure.get_neighbors(vire.structure[n], p["cutoff"])
        rn = vire.radii[vire.structure[n].species_string]

    reldists_neighs = []
    for neigh, dist in neighs_dists:
        if p["approach"] == "scaled_VIRE":
            dscale = p["delta"] * (vire.radii[neigh.species_string] + rn)
            if dist < dscale:
                sites.append(neigh)
        elif p["approach"] == "min_relative_VIRE":
            reldists_neighs.append([dist / (
                vire.radii[neigh.species_string] + rn), neigh])
        elif p["approach"] == "min_relative_OKeeffe":
            try:
                el2 = neigh.specie.element
            except:
                el2 = neigh.species_string
            reldists_neighs.append([dist / get_okeeffe_distance_prediction(
                eln, el2), neigh])
        elif p["approach"] == "min_dist":
            reldists_neighs.append([dist, neigh])

    if p["approach"] == "min_relative_VIRE" or \
                    p["approach"] == "min_relative_OKeeffe" or \
                    p["approach"] == "min_dist":
        min_reldist = min([reldist for reldist, neigh in reldists_neighs])
        for reldist, neigh in reldists_neighs:
            if reldist / min_reldist < 1.0 + p["delta"]:
                sites.append(neigh)

    return sites
Exemplo n.º 11
0
def inject_ions(structure, ion, atomic_fraction):
    """
    Adds ions to a percentage of interstitial sites into a structure
    that results in an at% less than or equal to the specified
    atomic_fraction. Starts by filling interstitial sites with the
    largest voronoi radius, and then works downward.

    Args:
        structure (Structure): Pymatgen Structure object to
            intercalate into.
        ion (str): name of atom to intercalate, e.g. 'Li', or 'Mg'.
        atomic_fraction (int): This fraction of the final intercalated
            structure will be intercalated atoms. Must be < 1.0.

    Returns:
        structure. Includes intercalated atoms.
    """

    specie = Element(ion)

    # If the structure isn't big enough to accomodate such a small
    # atomic fraction, multiply it in the x direction.
    n_ions = 1.
    while not n_ions / structure.num_sites <= atomic_fraction:
        structure.make_supercell([2, 1, 1])

    evaluator = ValenceIonicRadiusEvaluator(structure)
    interstitial = Interstitial(structure, radii=evaluator.radii,
                                valences=evaluator.valences)

    interstitial_sites = [
        (site._fcoords, site.properties.get('voronoi_radius', None))
        for site in interstitial._defect_sites]

    # Sort the interstitial sites by their voronoi radii.
    interstitial_sites.sort(key=operator.itemgetter(1))
    interstitial_sites.reverse()

    i = 0
    while n_ions / (structure.num_sites + 1) <= atomic_fraction:
        try:
            structure.append(species=specie, coords=interstitial_sites[i][0],
                             validate_proximity=True)
            n_ions += 1
            i += 1

            evaluator = ValenceIonicRadiusEvaluator(structure)
            interstitial = Interstitial(structure, radii=evaluator.radii,
                                        valences=evaluator.valences)

            interstitial_sites = [
                (site._fcoords, site.properties.get('voronoi_radius', None))
                for site in interstitial._defect_sites]

            # Sort the interstitial sites by their voronoi radii.
            interstitial_sites.sort(key=operator.itemgetter(1))
            interstitial_sites.reverse()

        except ValueError:
            i += 1

        except IndexError:
            raise ValueError('The atomic_fraction specified exceeds the '
                             'number of available interstitial sites in this '
                             'structure. Please choose a smaller '
                             'atomic_fraction.')

    return structure
Exemplo n.º 12
0
    def __init__(
        self,
        settings_obj,
    ):
        self.settings_obj = settings_obj

        try:
            if self.settings_obj.poscar_path:
                self.structure = Structure.from_file(
                    self.settings_obj.poscar_path)
            else:
                self.structure = Structure.from_file('POSCAR')
        except FileNotFoundError as e:
            print(e)
            print(
                'The given filepath for the poscar did not find a poscar file, ensure POSCAR is at the end '
                'e.g. /POSCAR. if no filepath was given then no poscar was found in the current directory.'
            )

        self.no_ions = int(self.settings_obj.int_dens *
                           self.structure.num_sites)

        try:
            if self.settings_obj.locpot_path:
                self.vasp_pot, self.NGX, self.NGY, self.NGZ, self.lattice = md.read_vasp_density(
                    self.settings_obj.locpot_path)
            else:
                self.vasp_pot, self.NGX, self.NGY, self.NGZ, self.lattice = md.read_vasp_density(
                    'LOCPOT')
            self.grid_pot, self.electrons = md.density_2_grid(
                self.vasp_pot, self.NGX, self.NGY,
                self.NGZ)  # generate the grid of potentials

        except FileNotFoundError as e:
            print(e)
            print(
                'The given filepath for the locpot did not find a locpot file, ensure LOCPOT is at the end '
                'e.g. /LOCPOT. if no filepath was given then no locpot was found in the current directory.'
            )

        # then run as normal, once voronoi done and cells found, convert back and carry on
        if not self.check_orthog_lat():
            print('exiting prog')
            sys.exit()
        self.find_vacuums(
        )  #this changes structure to one without vacuum. copies the old structure as self.orig_struct

        self.evaluator = ValenceIonicRadiusEvaluator(
            self.structure
        )  #computes site valence and ionic radii using bond valence analyser.
        # note this uses the sites, periodic table, bond valence, composition and local env packages! (as well as structure)
        self.radii = self.evaluator.radii
        self.valences = self.evaluator.valences

        self.interstitial = Interstitial(
            self.structure,
            radii=self.radii,
            valences=self.valences,
            symmetry_flag=self.settings_obj.sym_dist)
        # this evaluates the structure and uses radii and valence to generate voronoi sites depending on whether vertex,
        # facecenter or edge center is selected.
        # note: not sur eif hsould set oxi_state = False. By default it is true and it then uses ionic radii in the calculation,
        #  shouldnt really change centres? Returns and interstitial object. ._defect_sites returns the coordinates and labels of
        #  all intersittial sites which were found from the voronoi nodes/edges/faces/all depending on settings.
        # sym if False so we get all sites, including symmetry inequivalent sites!

        print('\n')
        self.interstitial_sites = [
            ([site._fcoords[0], site._fcoords[1],
              site._fcoords[2]], site.properties.get('voronoi_radius', None))
            for site in self.interstitial._defect_sites
        ]  # this creates a list of tuples: [ (array of site location
        # fractional coordinates, Voronoi radius') ]
        #  replaced  with self.get_nearest_neighbour_dist(site)

        # shift vornoi up if shifted!
        self.interstitial_sites = [
            ([
                i[0][0] * self.structure.lattice.a -
                self.downwards_shifts[0][0],
                i[0][1] * self.structure.lattice.b -
                self.downwards_shifts[1][1],
                i[0][2] * self.structure.lattice.c -
                self.downwards_shifts[2][2]
            ], i[1]) for i in self.interstitial_sites
        ]  #shift it and convert to cart coords at the same time

        # go back to the original, unshifted structure
        self.shifted_structure = self.structure.copy()
        self.structure = self.orig_struct.copy()
        self.interstitial_sites = [([
            i[0][0] / self.structure.lattice.a,
            i[0][1] / self.structure.lattice.b,
            i[0][2] / self.structure.lattice.c
        ], i[1]) for i in self.interstitial_sites
                                   ]  # convert it back to fractional coords