Exemple #1
0
 def proc_adsorb(cryst, mol, data):
     if data['method'] == 1:
         asf_slab = AdsorbateSiteFinder(cryst)
         ads_sites = asf_slab.find_adsorption_sites()
         ads_structs = asf_slab.generate_adsorption_structures(
             mol, repeat=data['repeat'])
         for i in range(len(ads_structs)):
             ads_struct = ads_structs[i]
             try:
                 miller_str = [str(j) for j in cryst.miller_index]
             except:
                 miller_str = ['adsorb']
             filename = '_'.join(miller_str) + '-' + str(i) + '.vasp'
             ads_struct.to(filename=filename, fmt='POSCAR')
     else:
         slabs = generate_all_slabs(cryst,
                                    max_index=data['max_index'],
                                    min_slab_size=data['min_slab'],
                                    min_vacuum_size=data['min_vacum'],
                                    lll_reduce=True)
         for slab in slabs:
             asf_slab = AdsorbateSiteFinder(slab)
             ads_sites = asf_slab.find_adsorption_sites()
             ads_structs = asf_slab.generate_adsorption_structures(
                 mol, repeat=data['repeat'])
             for i in range(len(ads_structs)):
                 ads_struct = ads_structs[i]
                 miller_str = [str(j) for j in slab.miller_index]
                 filename = 'adsorb' + '_'.join(miller_str) + '-' + str(
                     i) + '.vasp'
                 ads_struct.to(filename=filename, fmt='POSCAR')
Exemple #2
0
    def adsorbedSurface(self):
        """
		Adds adsorbates to bare surface
		"""
        from pymatgen.analysis.adsorption import AdsorbateSiteFinder, get_rot
        slab = copy.deepcopy(self.bareSurface())
        asf = AdsorbateSiteFinder(slab)

        b_sites = asf.find_adsorption_sites(distance=1.1,
                                            symm_reduce=0)['bridge']
        o_sites = asf.find_adsorption_sites(distance=1.1,
                                            symm_reduce=0)['ontop']
        h_sites = asf.find_adsorption_sites(distance=1.1,
                                            symm_reduce=0)['hollow']

        for ads, sites in self.adsorbates.items():
            a = molDict[ads]
            for (kind, num) in map(alphaNumSplit, sites):
                asf = AdsorbateSiteFinder(slab)
                if kind == 'B': slab = asf.add_adsorbate(a, b_sites[int(num)])
                elif kind == 'O':
                    slab = asf.add_adsorbate(a, o_sites[int(num)])
                elif kind == 'H':
                    slab = asf.add_adsorbate(a, h_sites[int(num)])
                else:
                    raise ValueError, "Bad site character in " + str(sites)
        return slab
Exemple #3
0
 def get_sites_dict(self, atoms, excludes=[]):
     '''
     get the surface site for adsorption
     1) for OER_pourbaix, ['O', 'N'] sites are generally excluded.
     2) for OER_site
             metal: Ti, La -> OH -> O -> OOH -> O2
             O:          O -> OOH -> O2 -> OH 
             H:          OH -> O -> OOH -> O2
     
     Return
     sites: dict
         e.g. {'Pt': [0.0, 0.0, 5.0]}
     '''
     from scipy.spatial.distance import squareform, pdist
     slabs = AseAtomsAdaptor.get_structure(atoms)
     asf_slabs = AdsorbateSiteFinder(slabs)
     ads_sites = asf_slabs.find_adsorption_sites(distance=0.0)
     sites = {}
     count = 0
     # view(atoms)
     for pos in ads_sites['ontop']:
         poss = atoms.get_positions()
         poss = np.append(poss, pos).reshape(-1, 3)
         ind = np.argsort(squareform(pdist(poss))[-1])[1] - 1
         # print(ind)
         symbol = atoms[ind].symbol
         if symbol in excludes: continue
         sites['site-%s-%s' % (count, symbol)] = pos + np.array([0, 0, 2.0])
     return sites
Exemple #4
0
def adsorbedSurface(surfpckl, facet, adsorbates):
    """
	Adds adsorbates to bare surface
	"""
    magmomInit = 3
    magElems = ['Fe', 'Mn', 'Cr', 'Co', 'Ni']
    initASE = pickle.loads(surfpckl)
    constrnts = initASE.constraints
    tags = initASE.get_tags().tolist()
    slab = makePMGSlabFromASE(initASE, facet)
    asf = AdsorbateSiteFinder(slab)

    b_sites = asf.find_adsorption_sites(distance=1.1, symm_reduce=0)['bridge']
    o_sites = asf.find_adsorption_sites(distance=1.1, symm_reduce=0)['ontop']
    h_sites = asf.find_adsorption_sites(distance=1.1, symm_reduce=0)['hollow']

    for ads, sites in adsorbates.items():
        a = gas.molDict[ads]
        for (kind, num) in [printParse.alphaNumSplit(x) for x in sites]:
            asf = AdsorbateSiteFinder(slab)
            if kind == 'B': slab = asf.add_adsorbate(a, b_sites[int(num) - 1])
            elif kind == 'O':
                slab = asf.add_adsorbate(a, o_sites[int(num) - 1])
            elif kind == 'H':
                slab = asf.add_adsorbate(a, h_sites[int(num) - 1])
            else:
                raise ValueError, "Bad site character in " + str(sites)

    aseSlab = AseAtomsAdaptor.get_atoms(slab)
    magmoms = [
        magmomInit if (magmomInit and e in magElems) else 0
        for e in aseSlab.get_chemical_symbols()
    ]

    newtags = np.zeros(len(aseSlab))

    for i, t in enumerate(tags):
        newtags[i] = t
    aseSlab.set_tags(newtags)
    aseSlab.set_constraint(constrnts)
    aseSlab.set_pbc([1, 1, 1])
    aseSlab.set_initial_magnetic_moments(magmoms)
    aseSlab.wrap()

    return aseSlab
def adsorbedSurface(baresurface,adsorbates): 
	"""
	Adds adsorbates to bare surface
	"""
	slab 	= baresurface.copy()
	asf 	= AdsorbateSiteFinder(slab)

	b_sites = asf.find_adsorption_sites(distance=1.1,symm_reduce=0)['bridge']
	o_sites = asf.find_adsorption_sites(distance=1.1,symm_reduce=0)['ontop']
	h_sites = asf.find_adsorption_sites(distance=1.1,symm_reduce=0)['hollow']

	for ads,sites in adsorbates.items():
		a = molDict[ads]
		for (kind,num) in [alphaNumSplit(x) for x in sites]:
			asf = AdsorbateSiteFinder(slab)
			if   kind == 'B': slab=asf.add_adsorbate(a,b_sites[int(num)-1])
			elif kind == 'O': slab=asf.add_adsorbate(a,o_sites[int(num)-1])
			elif kind == 'H': slab=asf.add_adsorbate(a,h_sites[int(num)-1])
			else: raise ValueError, "Bad site character in "+str(sites)
	return slab
Exemple #6
0
def adsorptionSites(slab, **kwargs):
    """

    :code:`AdsorptionSites` can help us visualize the position and tag of each adsorption sites, then we can determine
    where we want to put the adsorbates.

    :param slab: This is our slab, and we want to find how we can put the adsorbates on the slab.
    :type slab: aiida.orm.StructureData

    :param kwargs: * distance: the distance between adsorption site and the surface
                   * symm_reduce: the symmetry reduce (default = 0.01)
                   * near_reduce: the near reduce (default = 0.01)

    :returns: Dictionary contains the dictionary of adsorption sites.
    :rtype: aiida.orm.Dict object

    """

    # the inspiration for this function was from pymatgen.analysis.adsorption.AdsorbateSiteFinder.plot_slab()
    # function, which is really intuitive way of showing the structure and the adsorption sites.
    # since this function does not create any useful data, so it doesn't be decorated with @calfunction decorator

    # get the structure and adsorption sites
    slab = slab.get_pymatgen_structure()
    # end of the conversion

    asf = AdsorbateSiteFinder(slab, selective_dynamics=False)

    if 'distance' in kwargs.keys():
        distance = kwargs['distance']
    else:
        distance = 1.2

    if 'symm_reduce' in kwargs.keys():
        symm_reduce = kwargs['symm_reduce']
    else:
        symm_reduce = 0.01

    if 'near_reduce' in kwargs.keys():
        near_reduce = kwargs['near_reduce']
    else:
        near_reduce = 0.01

    adsorption_sites = asf.find_adsorption_sites(distance=distance,
                                                 symm_reduce=symm_reduce,
                                                 near_reduce=near_reduce)

    dictGenerator = Dict()
    dictGenerator.set_dict(adsorption_sites)

    return dictGenerator
Exemple #7
0
def generate_site_lst(slab, height=0.9):
    sf = AdsorbateSiteFinder(slab)
    #creates an AdsorbateSiteFinder object from pymatgen.analysis.adsorption 
    #to identify the possible sites for adsorbates    
    
    slab_corrected_surf = sf.assign_site_properties(slab, height=height)
    sf = AdsorbateSiteFinder(slab_corrected_surf)
    dict_ads_site = sf.find_adsorption_sites(distance=1.7, symm_reduce=False)
    #a dictionary with all possible adsorption sites on the surface
    
    site_lst = []
    
    for site_type in dict_ads_site.keys():
        i = 0
        if site_type != 'all':
#            if site_type != 'bridge':
            for site in dict_ads_site[site_type]:
                i += 1
                site_name = site_type + '_' + str(i)
                site_lst.append(site_name)
    #a list of all the sites with somewhat intuitive names, like hollow_1, ontop_2, or bridge_3
    return site_lst, dict_ads_site
def plot_slab(slab, ax, scale=0.8, repeat=3, window=1, decay=0.2):
    """
	Function that helps visualize the slab in a 2-D plot, for
	convenient viewing of output of AdsorbateSiteFinder.
	Args:
		slab (slab): 	Slab object to be visualized
		ax (axes): 		matplotlib axes with which to visualize
		scale (float): 	radius scaling for sites
		repeat (int): 	number of repeating unit cells to visualize
		window (float): window for setting the axes limits, is essentially a fraction of the unit cell limits
		decay (float): 	how the alpha-value decays along the z-axis
	"""

    orig_slab = slab.copy()
    slab = reorient_z(slab)
    orig_cell = slab.lattice.matrix.copy()
    if repeat: slab.make_supercell([repeat, repeat, 1])
    coords = np.array(sorted(slab.cart_coords, key=lambda x: x[2]))
    sites = sorted(slab.sites, key=lambda x: x.coords[2])
    alphas = 1 - decay * (np.max(coords[:, 2]) - coords[:, 2])
    alphas = alphas.clip(min=0)
    corner = [0, 0, cart_to_frac(slab.lattice, coords[-1])[-1]]
    corner = frac_to_cart(slab.lattice, corner)[:2]
    verts = orig_cell[:2, :2]
    lattsum = verts[0] + verts[1]
    # Draw circles at sites and stack them accordingly
    for n, coord in enumerate(coords):
        r = sites[n].specie.atomic_radius * scale
        ax.add_patch(
            patches.Circle(coord[:2] - lattsum * (repeat // 2),
                           r,
                           color='w',
                           zorder=2 * n))
        color = color_dict[sites[n].species_string]
        ax.add_patch(
            patches.Circle(coord[:2] - lattsum * (repeat // 2),
                           r,
                           facecolor=color,
                           alpha=alphas[n],
                           edgecolor='k',
                           lw=0.3,
                           zorder=2 * n + 1))
    # Adsorption sites
    asf = AdsorbateSiteFinder(orig_slab)
    ads_sites = asf.find_adsorption_sites(symm_reduce=0)['all']
    sop = get_rot(orig_slab)
    ads_sites = [sop.operate(ads_site)[:2].tolist() for ads_site in ads_sites]

    b_sites = asf.find_adsorption_sites(symm_reduce=0)['bridge']
    b_sites = [(sop.operate(ads_site)[:2].tolist(), 'B' + str(i))
               for i, ads_site in enumerate(b_sites)]
    o_sites = asf.find_adsorption_sites(symm_reduce=0)['ontop']
    o_sites = [(sop.operate(ads_site)[:2].tolist(), 'O' + str(i))
               for i, ads_site in enumerate(o_sites)]
    h_sites = asf.find_adsorption_sites(symm_reduce=0)['hollow']
    h_sites = [(sop.operate(ads_site)[:2].tolist(), 'H' + str(i))
               for i, ads_site in enumerate(h_sites)]

    for site in b_sites + o_sites + h_sites:
        ax.text(site[0][0],
                site[0][1],
                site[1],
                zorder=10000,
                ha='center',
                va='center')

    # Draw unit cell
    verts = np.insert(verts, 1, lattsum, axis=0).tolist()
    verts += [[0., 0.]]
    verts = [[0., 0.]] + verts
    codes = [
        Path.MOVETO, Path.LINETO, Path.LINETO, Path.LINETO, Path.CLOSEPOLY
    ]
    verts = [(np.array(vert) + corner).tolist() for vert in verts]
    path = Path(verts, codes)
    patch = patches.PathPatch(path,
                              facecolor='none',
                              lw=2,
                              alpha=0.5,
                              zorder=2 * n + 2)
    ax.add_patch(patch)

    ax.set_aspect("equal")
    center = corner + lattsum / 2.
    extent = np.max(lattsum)
    lim_array = [center - extent * window, center + extent * window]
    x_lim = [ele[0] for ele in lim_array]
    y_lim = [ele[1] for ele in lim_array]
    ax.set_xlim(x_lim)
    ax.set_ylim(y_lim)
    return ax
Exemple #9
0
    def enumerate_ads_chains(self,
                             adsorbate,
                             bond_length,
                             path_length,
                             percent_error=10,
                             include_cycles=True,
                             mode='exact',
                             symmetry_tol=0.01):

        bond_length = float(bond_length)
        asf = AdsorbateSiteFinder(self.blank_slab_pym)
        ads_sites = asf.find_adsorption_sites()

        site_list = []
        for stype in ads_sites:
            if stype != 'all':
                site_list.extend([s for s in ads_sites[stype]])

        duplications = self.duplications
        unit_cell = self.minimal_unit_cell
        repeat_unit_cell = self.blank_slab_ase.get_cell().T
        plane_string = ''.join(map(str, self.plane))

        dists = []
        for pair in itertools.combinations(site_list, 2):
            s0, s1 = pair
            s0 = np.dot(np.linalg.inv(unit_cell), s0)
            s1 = np.dot(np.linalg.inv(unit_cell), s1)
            fdist, sym = PBC3DF_sym(s0, s1)
            dist = np.round(np.linalg.norm(np.dot(unit_cell, fdist)), 3)
            dists.append((dist, pair))

        dists = [
            d for d in dists
            if abs(d[0] - bond_length) / bond_length * 100 < percent_error
        ]
        duplications = [[j for j in range(i)] for i in duplications]
        translation_vecs = list(
            itertools.product(duplications[0], duplications[1],
                              duplications[2]))

        path_dict = {}
        ptype_counter = 0

        for d in dists:
            ptype_counter += 1

            fingerprints = dict((s, dict((k, []) for k in range(1, 231)))
                                for s in range(path_length + 1))
            sg_counts = dict((k, 0) for k in range(1, 231))
            lattice = []

            for s in d[1]:
                for trans in translation_vecs:
                    trans = np.asarray(trans)
                    cart_trans = np.dot(unit_cell, trans)
                    lattice.append(s + cart_trans)

            G = nx.Graph()
            for i in range(len(lattice)):
                G.add_node(i, coords=lattice[i])

            for i in range(len(lattice)):
                s0 = lattice[i]
                for j in range(i + 1, len(lattice)):
                    s1 = lattice[j]
                    dist = np.linalg.norm(s0 - s1)
                    if np.round(dist, 3) == d[0]:
                        G.add_edge(i, j, length=dist)

            def neighborhood(G, node, n):
                path_lengths = nx.single_source_dijkstra_path_length(G, node)
                return [
                    node for node, length in path_lengths.items()
                    if length == n
                ]

            all_paths = []
            all_cycles = []
            used = []
            for i in G.nodes():

                used.append(i)
                nborhood = [
                    neighborhood(G, i, n) for n in range(path_length + 1)
                ]
                nborhood = [nbor for nbors in nborhood for nbor in nbors]

                for j in nborhood:
                    if j not in used:
                        paths = list(
                            nx.all_simple_paths(G,
                                                source=i,
                                                target=j,
                                                cutoff=path_length))
                        for p in paths:
                            if mode == 'leq':
                                if len(p) <= path_length:
                                    all_paths.append(p)
                            elif mode == 'exact':
                                if len(p) == path_length:
                                    all_paths.append(p)

            if include_cycles:

                G = G.to_directed()

                if mode == 'leq':
                    cycles = [
                        cy for cy in nx.simple_cycles(G)
                        if len(cy) <= path_length
                    ]
                elif mode == 'exact':
                    cycles = [
                        cy for cy in nx.simple_cycles(G)
                        if len(cy) == path_length
                    ]

                used = []
                for cy in cycles:
                    if len(cy) > 2:
                        cy_set = set(sorted(cy))
                        if cy_set not in used:
                            all_cycles.append(cy)
                            used.append(cy_set)

            all_paths = all_paths + cycles

            for path in all_paths:

                fp_dict = fingerprints[len(path)]

                path_coords = [
                    n[1]['coords'] for n in G.nodes(data=True) if n[0] in path
                ]
                adsorbate_combinations = itertools.product(adsorbate,
                                                           repeat=len(path))

                for ads_comb in adsorbate_combinations:

                    adsonly_positions = []
                    slab_coords = [(sl.symbol, sl.position)
                                   for sl in self.blank_slab_ase]

                    for p, a in zip(path_coords, ads_comb):

                        ads, shift_ind = a

                        elems = []
                        positions = []
                        for atom in ads:
                            elems.append(atom.symbol)
                            positions.append(atom.position)
                        elems = np.asarray(elems)
                        positions = np.asarray(positions)
                        trans = np.dot(unit_cell, np.asarray(s))
                        positions -= positions[shift_ind]
                        positions += p

                        for e, c in zip(elems, positions):
                            slab_coords.append((e, c))
                            adsonly_positions.append(c)

                    advance, index, sgs, sgn, dists, atoms, formula = redundancy_check(
                        slab_coords, adsonly_positions, fp_dict,
                        repeat_unit_cell, symmetry_tol)

                    if advance:
                        sg_counts[sgn] += 1
                        fp_dict[sgn].append(dists)

                    path_dict[formula + '_' + plane_string + '_' +
                              str(len(path)) + '_' + str(ptype_counter) + '_' +
                              sgs + '_' + index] = atoms

        self.path_configuration_dict = path_dict
Exemple #10
0
    def enumerate_ads_config(self,
                             adsorbate,
                             loading=1,
                             name='all',
                             interaction_dist=2.0,
                             symmetry_tol=0.01):

        asf = AdsorbateSiteFinder(self.blank_slab_pym)
        ads_sites = asf.find_adsorption_sites(distance=interaction_dist)

        duplications = self.duplications
        unit_cell = self.minimal_unit_cell
        repeat_unit_cell = self.blank_slab_ase.get_cell().T
        plane_string = ''.join(map(str, self.plane))

        duplications = [[j for j in range(i)] for i in duplications]
        translation_vecs = list(
            itertools.product(duplications[0], duplications[1],
                              duplications[2]))
        all_combinations = [
            s for s in itertools.combinations(translation_vecs, loading)
        ]

        site_list = []
        if name == 'all':
            for stype in ads_sites:
                if stype != 'all':
                    site_list.extend([s for s in ads_sites[stype]])
        else:
            site_list.extend([s for s in ads_sites[name]])

        ads_dict = {}
        atype_counter = 0

        fingerprints = dict((len(s), dict((k, []) for k in range(1, 231)))
                            for s in all_combinations)
        sg_counts = dict((k, 0) for k in range(1, 231))

        for pos in site_list:

            atype_counter += 1

            for subset in all_combinations:

                loading = len(subset)
                fp_dict = fingerprints[loading]

                adsorbate_combinations = itertools.product(adsorbate,
                                                           repeat=loading)

                for ads_comb in adsorbate_combinations:

                    adsonly_positions = []
                    slab_coords = [(sl.symbol, sl.position)
                                   for sl in self.blank_slab_ase]

                    for s, a in zip(subset, ads_comb):

                        ads, shift_ind = a

                        elems = []
                        positions = []
                        for atom in ads:
                            elems.append(atom.symbol)
                            positions.append(atom.position)
                        elems = np.asarray(elems)
                        positions = np.asarray(positions)
                        trans = np.dot(unit_cell, np.asarray(s))
                        positions -= positions[shift_ind]
                        positions += pos
                        positions += trans

                        for e, c in zip(elems, positions):
                            slab_coords.append((e, c))
                            adsonly_positions.append(c)

                    advance, index, sgs, sgn, dists, atoms, formula = redundancy_check(
                        slab_coords, adsonly_positions, fp_dict,
                        repeat_unit_cell, symmetry_tol)

                    if advance:
                        sg_counts[sgn] += 1
                        fp_dict[sgn].append(dists)

                    ads_dict[formula + '_' + plane_string + '_' +
                             str(loading) + '_' + name + str(atype_counter) +
                             '_' + sgs + '_' + index] = atoms

        self.adsorbate_configuration_dict = ads_dict
Exemple #11
0
    def fix_absorbed(self,
                     need_miller_index,
                     mole,
                     num,
                     selective_dynamic,
                     min_slab_size_1=8.0,
                     min_vacuum_size_1=15,
                     judge='fuchdi',
                     appendage=""):
        from pymatgen import Structure, Lattice, MPRester, Molecule
        import pymatgen.core.structure

        import pymatgen.core.sites
        from pymatgen.analysis.adsorption import AdsorbateSiteFinder, reorient_z, plot_slab
        from pymatgen.core.surface import generate_all_slabs
        from pymatgen.symmetry.analyzer import SpacegroupAnalyzer
        from matplotlib import pyplot as plt
        from pymatgen.ext.matproj import MPRester
        from pymatgen.io.vasp.inputs import Poscar
        from pymatgen.io.vasp.sets import MVLSlabSet
        from pymatgen.io.cif import CifWriter
        import os
        import shutil
        from openbabel import openbabel
        from pymatgen.core.surface import Slab, SlabGenerator, generate_all_slabs, Structure, Lattice, ReconstructionGenerator
        mp_id = self.mp_id
        os.chdir(r"F:\VASP practical\Input")
        print(os.getcwd())

        # Note that you must provide your own API Key, which can
        # be accessed via the Dashboard at materialsproject.org
        mpr = MPRester()
        struct = mpr.get_structure_by_material_id(mp_id)
        struct = SpacegroupAnalyzer(
            struct).get_conventional_standard_structure()
        # fcc_ni = Structure.from_spacegroup("Fm-3m", Lattice.cubic(3.5), ["Ni", "Ni"],
        # [[0, 0, 0], [0.5, 0.5, 0.5]])
        slab = SlabGenerator(struct,
                             miller_index=need_miller_index,
                             min_slab_size=min_slab_size_1,
                             min_vacuum_size=min_vacuum_size_1,
                             center_slab=True)

        for n, slabs in enumerate(slab.get_slabs()):
            if str(n) in str(num):
                slabs_bak = slabs.copy()  #可能的晶面
                slabs.make_supercell(self.supercell)
                print(n)
                #晶胞扩充

                asf_ni_111 = AdsorbateSiteFinder(
                    slabs, selective_dynamics=selective_dynamic)
                ads_sites = asf_ni_111.find_adsorption_sites()

                # print(ads_sites)
                assert len(ads_sites) == 4

                fig0 = plt.figure()
                ax = fig0.add_subplot(111)
                plot_slab(slabs, ax, adsorption_sites=False)

                fig1 = plt.figure()
                ax = fig1.add_subplot(111)
                os.chdir(r"D:\Desktop\VASP practical\Cif library")
                print(os.getcwd())
                obConversion = openbabel.OBConversion()
                obConversion.SetInAndOutFormats("pdb", "gjf")
                mol = openbabel.OBMol()
                print(mol)
                c = obConversion.ReadFile(mol, "CH3OH.pdb")
                obConversion.WriteFile(mol, "CH3OH.pdb" + '1.gjf')
                adsorbate = Molecule.from_file("CH3OH.pdb" + '.gjf')
                os.chdir(r"F:\VASP practical\Input")
                print(os.getcwd())

                print(adsorbate.sites)
                ads_structs = asf_ni_111.add_adsorbate(
                    adsorbate,
                    (20, 20, 20),
                    translate=False,
                )
                # ads_structs = asf_ni_111.generate_adsorption_structures(adsorbate,
                # repeat=[1, 1, 1])
                # A = Poscar(ads_structs[0])
                A = Poscar(reorient_z(ads_structs))  #将切面转换为Poscar
                open('POSCAR', 'w').write(str(A))
                p = Poscar.from_file('POSCAR')
                # w = CifWriter(A.struct)
                # w.write_file('mystructure.cif')
                path = r'F:\VASP practical\Input\POSCAR'  # 文件路径
                if os.path.exists(path):  # 如果文件存在
                    # 删除文件,可使用以下两种方法。
                    os.remove(path)
                #os.unlink(path)
                else:
                    print('no such file:%s' % my_file)  # 则返回文件不存在
                # w = CifWriter(A.struct)
                # w.write_file('mystructure.cif')

                relax = p.structure  #将Poscar 转换为结构信息
                custom_settings = {"NPAR": 4}  # 用户的INCAR 设置
                relaxs = MVLSlabSet(relax, user_incar_settings=custom_settings)
                # Vasp输入文件生成器
                dire = str(mp_id) + str(selective_dynamic) + str(mole) + str(
                    need_miller_index).replace(" ", "") + str(n)
                # print (relax)
                relaxs.write_input(dire)
                os.chdir("./" + dire)
                print(os.getcwd())
                fig0.savefig('slab.png',
                             bbox_inches='tight',
                             transparent=True,
                             dpi=600,
                             format='png')
                plot_slab(ads_structs, ax, adsorption_sites=False, decay=0.09)
                fig1.savefig('slab_adsobate.png',
                             bbox_inches='tight',
                             transparent=True,
                             dpi=600,
                             format='png')
                #定义一个更改当前目录的变量
                dire2 = './vaspstd_sub'
                #确立脚本名称
                shutil.copy(r"C:\Users\41958\.spyder-py3\vaspstd_sub", dire2)

                eb = appendage  #添加其他INCAR参数

                with open('INCAR', 'r') as f1:
                    lines = f1.readlines()

                with open('INCAR', 'w') as f2:
                    for line in lines:
                        if judge in line:
                            continue
                        f2.write(line)

                with open('INCAR', 'a') as f3:
                    f3.write(eb)

                # open('POSCAR001', 'w').write(str(Poscar(reorient_z(ads_structs[0]))))

                os.chdir(r"D:\Desktop\VASP practical\workdir")
                print(os.getcwd())
                print('finished')


# my_lattace = Lattace('mp-698074')#半水石膏
# # my_lattace.phase_out()#生成晶胞优化的输入文件
# go = my_lattace.phase_sol(66,judge='LWAVE',  appendage= '\nLWAVE = Ture')
# print('yoo')
Exemple #12
0
ax.set_yticks([])
plt.show()

# ### Verificando os locais de adsorção no plano e entre as camadas

# In[24]:

from pymatgen.analysis.adsorption import AdsorbateSiteFinder

# In[25]:

asf = AdsorbateSiteFinder(Cu_111)

# In[26]:

add_sites = asf.find_adsorption_sites()
add_sites

# In[27]:

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
plot_slab(Cu_111, ax, adsorption_sites=True)
ax.set_title("Cu (1, 1, 1) adsorption points")
ax.set_xticks([])
ax.set_yticks([])
plt.show()

# ### Importar moléculas para colocar nos sítios de adsorção

# In[38]:
Exemple #13
0
class AdsorbateSiteFinderTest(PymatgenTest):
    def setUp(self):
        self.structure = Structure.from_spacegroup("Fm-3m", Lattice.cubic(3.5), ["Ni"], [[0, 0, 0]])
        lattice = Lattice.cubic(3.010)
        frac_coords = [
            [0.00000, 0.00000, 0.00000],
            [0.00000, 0.50000, 0.50000],
            [0.50000, 0.00000, 0.50000],
            [0.50000, 0.50000, 0.00000],
            [0.50000, 0.00000, 0.00000],
            [0.50000, 0.50000, 0.50000],
            [0.00000, 0.00000, 0.50000],
            [0.00000, 0.50000, 0.00000],
        ]
        species = ["Mg", "Mg", "Mg", "Mg", "O", "O", "O", "O"]
        self.MgO = Structure(lattice, species, frac_coords)

        slabs = generate_all_slabs(
            self.structure,
            max_index=2,
            min_slab_size=6.0,
            min_vacuum_size=15.0,
            max_normal_search=1,
            center_slab=True,
        )
        self.slab_dict = {"".join([str(i) for i in slab.miller_index]): slab for slab in slabs}
        self.asf_211 = AdsorbateSiteFinder(self.slab_dict["211"])
        self.asf_100 = AdsorbateSiteFinder(self.slab_dict["100"])
        self.asf_111 = AdsorbateSiteFinder(self.slab_dict["111"])
        self.asf_110 = AdsorbateSiteFinder(self.slab_dict["110"])
        self.asf_struct = AdsorbateSiteFinder(Structure.from_sites(self.slab_dict["111"].sites))

    def test_init(self):
        AdsorbateSiteFinder(self.slab_dict["100"])
        AdsorbateSiteFinder(self.slab_dict["111"])

    def test_from_bulk_and_miller(self):
        # Standard site finding
        asf = AdsorbateSiteFinder.from_bulk_and_miller(self.structure, (1, 1, 1))
        sites = asf.find_adsorption_sites()
        self.assertEqual(len(sites["hollow"]), 2)
        self.assertEqual(len(sites["bridge"]), 1)
        self.assertEqual(len(sites["ontop"]), 1)
        self.assertEqual(len(sites["all"]), 4)
        asf = AdsorbateSiteFinder.from_bulk_and_miller(self.structure, (1, 0, 0))
        sites = asf.find_adsorption_sites()
        self.assertEqual(len(sites["all"]), 3)
        self.assertEqual(len(sites["bridge"]), 2)
        asf = AdsorbateSiteFinder.from_bulk_and_miller(self.structure, (1, 1, 0), undercoord_threshold=0.1)
        self.assertEqual(len(asf.surface_sites), 1)
        # Subsurface site finding
        asf = AdsorbateSiteFinder.from_bulk_and_miller(self.structure, (1, 1, 1))
        sites = asf.find_adsorption_sites(positions=["ontop", "subsurface", "bridge"])
        self.assertEqual(len(sites["all"]), 5)
        self.assertEqual(len(sites["subsurface"]), 3)

    def test_find_adsorption_sites(self):
        sites = self.asf_100.find_adsorption_sites()
        self.assertEqual(len(sites["all"]), 3)
        self.assertEqual(len(sites["hollow"]), 0)
        self.assertEqual(len(sites["bridge"]), 2)
        self.assertEqual(len(sites["ontop"]), 1)
        sites = self.asf_111.find_adsorption_sites()
        self.assertEqual(len(sites["all"]), 4)
        sites = self.asf_110.find_adsorption_sites()
        self.assertEqual(len(sites["all"]), 4)
        sites = self.asf_211.find_adsorption_sites()
        # Test on structure
        sites = self.asf_struct.find_adsorption_sites()

    def test_generate_adsorption_structures(self):
        co = Molecule("CO", [[0, 0, 0], [0, 0, 1.23]])
        structures = self.asf_111.generate_adsorption_structures(co, repeat=[2, 2, 1])
        self.assertEqual(len(structures), 4)
        sites = self.asf_111.find_adsorption_sites()
        # Check repeat functionality
        self.assertEqual(
            len([site for site in structures[0] if site.properties["surface_properties"] != "adsorbate"]),
            4 * len(self.asf_111.slab),
        )
        for n, structure in enumerate(structures):
            self.assertArrayAlmostEqual(structure[-2].coords, sites["all"][n])
        find_args = {"positions": ["hollow"]}
        structures_hollow = self.asf_111.generate_adsorption_structures(co, find_args=find_args)
        self.assertEqual(len(structures_hollow), len(sites["hollow"]))
        for n, structure in enumerate(structures_hollow):
            self.assertTrue(in_coord_list(sites["hollow"], structure[-2].coords, 1e-4))
        # Check molecule not changed after rotation when added to surface
        co = Molecule("CO", [[1.0, -0.5, 3], [0.8, 0.46, 3.75]])
        structures = self.asf_211.generate_adsorption_structures(co)
        self.assertEqual(co, Molecule("CO", [[1.0, -0.5, 3], [0.8, 0.46, 3.75]]))
        # Check translation
        sites = self.asf_211.find_adsorption_sites()
        ads_site_coords = sites["all"][0]
        c_site = structures[0].sites[-2]
        self.assertEqual(str(c_site.specie), "C")
        self.assertArrayAlmostEqual(c_site.coords, sites["all"][0])
        # Check no translation
        structures = self.asf_111.generate_adsorption_structures(co, translate=False)
        self.assertEqual(co, Molecule("CO", [[1.0, -0.5, 3], [0.8, 0.46, 3.75]]))
        sites = self.asf_111.find_adsorption_sites()
        ads_site_coords = sites["all"][0]
        c_site = structures[0].sites[-2]
        self.assertArrayAlmostEqual(c_site.coords, ads_site_coords + np.array([1.0, -0.5, 3]))

    def test_adsorb_both_surfaces(self):

        # Test out for monatomic adsorption
        o = Molecule("O", [[0, 0, 0]])
        adslabs = self.asf_100.adsorb_both_surfaces(o)
        adslabs_one = self.asf_100.generate_adsorption_structures(o)
        self.assertEqual(len(adslabs), len(adslabs_one))
        for adslab in adslabs:
            sg = SpacegroupAnalyzer(adslab)
            sites = sorted(adslab, key=lambda site: site.frac_coords[2])
            self.assertTrue(sites[0].species_string == "O")
            self.assertTrue(sites[-1].species_string == "O")
            self.assertTrue(sg.is_laue())

        # Test out for molecular adsorption
        oh = Molecule(["O", "H"], [[0, 0, 0], [0, 0, 1]])
        adslabs = self.asf_100.adsorb_both_surfaces(oh)
        adslabs_one = self.asf_100.generate_adsorption_structures(oh)
        self.assertEqual(len(adslabs), len(adslabs_one))
        for adslab in adslabs:
            sg = SpacegroupAnalyzer(adslab)
            sites = sorted(adslab, key=lambda site: site.frac_coords[2])
            self.assertTrue(sites[0].species_string in ["O", "H"])
            self.assertTrue(sites[-1].species_string in ["O", "H"])
            self.assertTrue(sg.is_laue())

    def test_generate_substitution_structures(self):

        # Test this for a low miller index halite structure
        slabs = generate_all_slabs(self.MgO, 1, 10, 10, center_slab=True, max_normal_search=1)
        for slab in slabs:
            adsgen = AdsorbateSiteFinder(slab)

            adslabs = adsgen.generate_substitution_structures("Ni")
            # There should be 2 configs (sub O and sub
            # Mg) for (110) and (100), 1 for (111)
            if tuple(slab.miller_index) != (1, 1, 1):
                self.assertEqual(len(adslabs), 2)
            else:
                self.assertEqual(len(adslabs), 1)

            # Test out whether it can correctly dope both
            # sides. Avoid (111) because it is not symmetric
            if tuple(slab.miller_index) != (1, 1, 1):
                adslabs = adsgen.generate_substitution_structures("Ni", sub_both_sides=True, target_species=["Mg"])
                # Test if default parameters dope the surface site
                for i, site in enumerate(adslabs[0]):
                    if adsgen.slab[i].surface_properties == "surface" and site.species_string == "Mg":
                        print(
                            adslabs[0][i].surface_properties,
                            adsgen.slab[i].surface_properties,
                        )
                        self.assertTrue(adslabs[0][i].surface_properties == "substitute")

                self.assertTrue(adslabs[0].is_symmetric())
                # Correctly dope the target species
                self.assertEqual(
                    adslabs[0].composition.as_dict()["Mg"],
                    slab.composition.as_dict()["Mg"] - 2,
                )
                # There should be one config (sub Mg)
                self.assertEqual(len(adslabs), 1)

    def test_functions(self):
        slab = self.slab_dict["111"]
        get_rot(slab)
        reorient_z(slab)
Exemple #14
0
    def absorbed(self,
                 millerindex_1,
                 absorbate_1,
                 absorba,
                 judge='',
                 appendage=""):

        from pymatgen import Structure, Lattice, MPRester, Molecule
        import pymatgen.core.structure

        import pymatgen.core.sites
        from pymatgen.analysis.adsorption import AdsorbateSiteFinder, reorient_z, plot_slab
        from pymatgen.core.surface import generate_all_slabs
        from pymatgen.symmetry.analyzer import SpacegroupAnalyzer
        from matplotlib import pyplot as plt
        from pymatgen.io.cif import CifParser
        from pymatgen.io.vasp.inputs import Poscar
        from pymatgen.io.vasp.sets import MVLSlabSet
        from pymatgen.io.cif import CifWriter
        import os
        import shutil

        ass = self.cif_route
        print(ass)
        # os.chdir(r"E:\VASP practical\Input")
        # print (os.getcwd())

        # Note that you must provide your own API Key, which can
        # be accessed via the Dashboard at materialsproject.org
        #mpr = MPRester()#密钥
        struct = CifParser(ass)
        structure = struct.get_structures()[0]
        print(structure)

        os.chdir(r"E:\VASP practical\Input")
        print(os.getcwd())
        # fcc_ni = Structure.from_spacegroup("Fm-3m", Lattice.cubic(3.5), ["Ni", "Ni"],
        # [[0, 0, 0], [0.5, 0.5, 0.5]])
        slabs = generate_all_slabs(structure,
                                   max_index=1,
                                   min_slab_size=8.0,
                                   min_vacuum_size=10.0)

        millerindex = millerindex_1
        struct_111 = [
            slab for slab in slabs if slab.miller_index == millerindex_1
        ][0]

        asf_ni_111 = AdsorbateSiteFinder(struct_111)
        ads_sites = asf_ni_111.find_adsorption_sites()

        # print(ads_sites)
        assert len(ads_sites) == 4

        fig = plt.figure()
        ax = fig.add_subplot(111)
        plot_slab(struct_111, ax, adsorption_sites=True)

        fig = plt.figure()
        ax = fig.add_subplot(111)

        adsorbate = Molecule(absorbate_1, absorba)
        ads_structs = asf_ni_111.generate_adsorption_structures(
            adsorbate, repeat=[1, 1, 1])
        A = Poscar(reorient_z(ads_structs[0]))  #将切面转换为Poscar
        open('POSCAR', 'w').write(str(A))
        p = Poscar.from_file('POSCAR')
        # w = CifWriter(A.struct)
        # w.write_file('mystructure.cif')
        path = r'E:\VASP practical\Input\POSCAR'  # 文件路径
        if os.path.exists(path):  # 如果文件存在
            # 删除文件,可使用以下两种方法。
            os.remove(path)
        #os.unlink(path)
        else:
            print('no such file:%s' % my_file)  # 则返回文件不存在
        # w = CifWriter(A.struct)
        # w.write_file('mystructure.cif')

        relax = p.structure  #将Poscar 转换为结构信息
        custom_settings = {"NPAR": 4}  # 用户的INCAR 设置
        relaxs = MVLSlabSet(relax, user_incar_settings=custom_settings)
        # Vasp输入文件生成器
        dire = str(ass) + "---" + str(absorbate_1) + str(millerindex_1)
        # print (relax)
        relaxs.write_input(dire)
        os.chdir("./" + dire)
        print(os.getcwd())
        #定义一个更改当前目录的变量
        dire2 = './vaspstd_sub'
        #确立脚本名称
        shutil.copy(r"C:\Users\41958\.spyder-py3\vaspstd_sub", dire2)

        eb = appendage  #添加其他INCAR参数

        with open('INCAR', 'r') as f1:
            lines = f1.readlines()

        with open('INCAR', 'w') as f2:
            for line in lines:
                if judge in line:
                    continue
                f2.write(line)

        with open('INCAR', 'a') as f3:
            f3.write(eb)

        plot_slab(ads_structs[0], ax, adsorption_sites=False, decay=0.09)
        # open('POSCAR001', 'w').write(str(Poscar(reorient_z(ads_structs[0]))))

        os.chdir(r"D:\Desktop\VASP practical\workdir")
        print(os.getcwd())
        print('finished')


# my_lattace = Lattace('mp-698074')#半水石膏
# # my_lattace.phase_out()#生成晶胞优化的输入文件
# go = my_lattace.phase_sol(66,judge='LWAVE',  appendage= '\nLWAVE = Ture')
# print('yoo')