Пример #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')
Пример #2
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)
Пример #3
0
plt.show()

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

# In[38]:

from pymatgen import Molecule

# In[39]:

adsorbate = Molecule("H", [[0, 0, 0]])

# In[40]:

ads_sructs = asf.generate_adsorption_structures(adsorbate,
                                                repeat=[1, 1, 1],
                                                find_args={"distance": 1.6})

# In[41]:

fig = plt.figure(figsize=[15, 60])
for n, ads_struct in enumerate(ads_sructs):
    ax = fig.add_subplot(1, 4, n + 1)
    plot_slab(ads_struct, ax, adsorption_sites=False)
    ax.set_title(n + 1)
    ax.set_xticks([])
    ax.set_yticks([])
    ax.set_xlim(0.5)
    ax.set_ylim(-1, 4)
plt.show()
Пример #4
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')