Exemple #1
0
    def setUp(self):

        module_dir = os.path.dirname(os.path.abspath(__file__))
        with open(os.path.join(module_dir, "surface_samples.json")) as data_file:
            surface_properties = json.load(data_file)

        surface_energies, miller_indices = {}, {}
        for mpid in surface_properties.keys():
            e_surf_list, miller_list = [], []
            for surface in surface_properties[mpid]["surfaces"]:
                e_surf_list.append(surface["surface_energy"])
                miller_list.append(surface["miller_index"])
            surface_energies[mpid] = e_surf_list
            miller_indices[mpid] = miller_list

        # In the case of a high anisotropy material
        # Nb: mp-8636
        latt_Nb = Lattice.cubic(2.992)
        # In the case of an fcc material
        # Ir: mp-101
        latt_Ir = Lattice.cubic(3.8312)
        # In the case of a hcp material
        # Ti: mp-72
        latt_Ti = Lattice.hexagonal(4.6000, 2.8200)
        self.ucell_Nb = Structure(
            latt_Nb,
            ["Nb", "Nb", "Nb", "Nb"],
            [[0, 0, 0], [0, 0.5, 0.5], [0.5, 0, 0.5], [0.5, 0.5, 0]],
        )
        self.wulff_Nb = WulffShape(
            latt_Nb, miller_indices["mp-8636"], surface_energies["mp-8636"]
        )

        self.ucell_Ir = Structure(
            latt_Nb,
            ["Ir", "Ir", "Ir", "Ir"],
            [[0, 0, 0], [0, 0.5, 0.5], [0.5, 0, 0.5], [0.5, 0.5, 0]],
        )
        self.wulff_Ir = WulffShape(
            latt_Ir, miller_indices["mp-101"], surface_energies["mp-101"]
        )

        self.ucell_Ti = Structure(
            latt_Ti,
            ["Ti", "Ti", "Ti"],
            [[0, 0, 0], [0.333333, 0.666667, 0.5], [0.666667, 0.333333, 0.5]],
        )
        self.wulff_Ti = WulffShape(
            latt_Ti, miller_indices["mp-72"], surface_energies["mp-72"]
        )
        self.cube = WulffShape(Lattice.cubic(1), [(1, 0, 0)], [1])
        self.hex_prism = WulffShape(
            Lattice.hexagonal(2.63, 5.21), [(0, 0, 1), (1, 0, 0)], [0.35, 0.53]
        )

        self.surface_properties = surface_properties
Exemple #2
0
    def get_wulff_shape(self, material_id):
        """
        Constructs a Wulff shape for a material.

        Args:
            material_id (str): Materials Project material_id, e.g. 'mp-123'.
        Returns:
            pymatgen.analysis.wulff.WulffShape
        """
        from pymatgen.analysis.wulff import WulffShape
        from pymatgen.symmetry.analyzer import SpacegroupAnalyzer

        structure = self.get_structure_by_material_id(material_id)
        surfaces = self.get_surface_data(material_id)["surfaces"]
        lattice = (
            SpacegroupAnalyzer(structure).get_conventional_standard_structure().lattice
        )
        miller_energy_map = {}
        for surf in surfaces:
            miller = tuple(surf["miller_index"])
            # Prefer reconstructed surfaces, which have lower surface energies.
            if (miller not in miller_energy_map) or surf["is_reconstructed"]:
                miller_energy_map[miller] = surf["surface_energy"]
        millers, energies = zip(*miller_energy_map.items())
        return WulffShape(lattice, millers, energies)
    def wulff_shape_from_chempot(self, chempot, symprec=1e-5):
        """
        Method to get the Wulff shape at a specific chemical potential.
        Args:
            chempot (float): The chemical potential the Wulff Shape exist in.
        """

        # Check if the user provided chemical potential is within the
        # predetermine range of chemical potential. If not, raise a warning
        if not max(self.chempot_range) >= chempot >= min(self.chempot_range):
            warnings.warn("The provided chemical potential is outside the range "
                          "of chemical potential (%s to %s). The resulting Wulff "
                          "shape might not be reasonable." %(min(self.chempot_range),
                                                             max(self.chempot_range)))

        latt = SpacegroupAnalyzer(self.ucell_entry.structure).\
            get_conventional_standard_structure().lattice

        miller_list = self.vasprun_dict.keys()
        e_surf_list = []
        for hkl in miller_list:
            # At each possible configuration, we calculate surface energy as a
            # function of u and take the lowest surface energy (corresponds to
            # the most stable slab termination at that particular u)
            surf_e_range_list = [self.calculate_gamma(vasprun)
                                 for vasprun in self.vasprun_dict[hkl]]
            e_list = []
            for e_range in surf_e_range_list:
                slope, intercept = self.get_slope_and_intercept(e_range)
                e_list.append(slope * chempot + intercept)
            e_surf_list.append(min(e_list))

        return WulffShape(latt, miller_list, e_surf_list, symprec=symprec)
Exemple #4
0
def wulff(st, miller_list=None, e_surf_list=None, show=0):

    from pymatgen.core.structure import Structure
    stpm = st.convert2pymatgen()

    lat = stpm.lattice

    recp_lattice = stpm.lattice.reciprocal_lattice_crystallographic

    recp = Structure(recp_lattice, ["H"], [[0, 0, 0]])
    dire = Structure(stpm.lattice, ["H"], [[0, 0, 0]])

    print(dire.get_space_group_info())
    print(recp.get_space_group_info())
    # print(lat)
    from pymatgen.analysis.wulff import WulffShape
    WS = WulffShape(lat, miller_list, e_surf_list)
    # print(dir(WS))
    anisotropy = WS.anisotropy
    weighted_surface_energy = WS.weighted_surface_energy
    if show:
        WS.show()
    return anisotropy, weighted_surface_energy
Exemple #5
0
    def Wullff(self,
               formate,
               surface_energy,
               pic_name,
               directions=(3, 4, 4),
               x=0.47,
               y=-16):
        from pymatgen.core.surface import SlabGenerator, generate_all_slabs, Structure, Lattice
        # Import the neccesary tools for making a Wulff shape
        from pymatgen.analysis.wulff import WulffShape
        from pymatgen.ext.matproj import MPRester
        from pymatgen.io.cif import CifParser
        import matplotlib.pyplot as plt
        import matplotlib.image as mpimg
        import pandas as pd
        import os
        if 'cif' in str(formate):

            os.chdir(r"D:\Desktop\VASP practical\Cif library")
            print(os.getcwd())
            structure = CifParser(str(pic_name) + '.cif')
            struct = structure.get_structures()[0]
        else:
            mpr = MPRester()

            mp_id = formate
            struct = mpr.get_structure_by_material_id(mp_id)
        surface_energies = surface_energy
        miller_list = surface_energies.keys()
        e_surf_list = surface_energies.values()
        font2 = {
            'family': 'Times New Roman',
            'fontsize': '40',
            'weight': 'bold',
        }
        wulffshape = WulffShape(struct.lattice, miller_list, e_surf_list)
        print(wulffshape.area_fraction_dict)
        os.chdir(self.dire)
        dict1 = wulffshape.area_fraction_dict
        xx = []
        yy = []
        for key, value in dict1.items():
            xx.append(key)
            yy.append(value)

        cc = wulffshape.effective_radius
        bb = wulffshape.volume
        dd = wulffshape.shape_factor
        print(wulffshape.effective_radius)
        res = pd.DataFrame({'Slab': xx, 'area': yy})  #构造原始数据文件
        df = res.sort_values(by='area', ascending=True)
        with open(str(pic_name) + '.txt', 'w') as f:

            f.write('effective radius:' + str(cc) + '         ' + "volume:" +
                    str(bb) + '         ' + "shape factor:" + str(dd))
        print(cc)
        # os.chdir(r"D:\Desktop\VASP practical\workdir")
        df.to_excel(str(pic_name) + ".xlsx")  #生成Excel文件,并存到指定文件路径下
        wulffshape.get_plot(bar_on=True,
                            aspect_ratio=(8, 8),
                            bar_pos=[0, 0.85, 1.1, 0.045],
                            direction=directions)

        plt.title(str(pic_name), font2, x=x, y=y)

        plt.savefig(str(pic_name) + ".png",
                    bbox_inches='tight',
                    transparent=True,
                    dpi=600,
                    format='png')

        plt.show
        os.chdir(r"D:\Desktop\VASP practical\workdir")
        print('finished')
Exemple #6
0
    (2, 1, 0): 2.3969,
    (3, 3, 2): 2.0944,
    (1, 0, 0): 2.2084,
    (2, 1, 1): 2.2353,
    (3, 2, 2): 2.1242,
    (3, 2, 1): 2.3183,
    (2, 2, 1): 2.1732,
    (3, 3, 1): 2.2288,
    (3, 1, 1): 2.3039,
    (1, 1, 1): 1.9235
}
miller_list = surface_energies_Ni.keys()
e_surf_list = surface_energies_Ni.values()

# We can now construct a Wulff shape with an accuracy up to a max Miller index of 3
wulffshape = WulffShape(Ni.lattice, miller_list, e_surf_list)

# Let's get some useful information from our wulffshape object
print("shape factor: %.3f, anisotropy: \
%.3f, weighted surface energy: %.3f J/m^2" %
      (wulffshape.shape_factor, wulffshape.anisotropy,
       wulffshape.weighted_surface_energy))

# If we want to see what our Wulff shape looks like
wulffshape.show()
# Lets try something a little more complicated, say LiFePO4
from pymatgen.util.testing import PymatgenTest
# Get the LiFePO4 structure
LiFePO4 = PymatgenTest.get_structure("LiFePO4")

# Let's add some oxidation states to LiFePO4, this will be
Exemple #7
0
# all_slabs = slabgen.get_slabs()
# print("The Ni(111) slab only has %s termination." %(len(all_slabs)))

# Now let's assume that we then calculated the surface energies for these slabs

# Surface energy values in J/m^2
surface_energies_Ni = {
    (0, 0, 1): 2.3869,
    (2, 0, 1): 2.2862,
    (1, -1, 0): 2.3964,
    (0, 2, 0): 2.0944,
    (-2, -2, 1): 0.9353,
    (2, -2, 0): 2.3183,
    (-1, 1, 1): 2.2288,
    (0, 2, 2): 1.9235
}
miller_list = surface_energies_Ni.keys()
e_surf_list = surface_energies_Ni.values()

# We can now construct a Wulff shape with an accuracy up to a max Miller index of 3
wulffshape = WulffShape(struct.lattice, miller_list, e_surf_list)

# Let's get some useful information from our wulffshape object
# print("shape factor: %.3f, anisotropy: \
# %.3f, weighted surface energy: %.3f J/m^2" %(wulffshape.shape_factor,
#                                        wulffshape.anisotropy,
#                                        wulffshape.weighted_surface_energy))

# If we want to see what our Wulff shape looks like
wulffshape.show()