Exemple #1
0
 def test_get_voronoi_nodes(self):
     vor_node_struct, vor_ec_struct, vor_fc_struct = \
         get_high_accuracy_voronoi_nodes(self.structure, self.rad_dict)
     self.assertIsInstance(vor_node_struct, Structure)
     self.assertIsInstance(vor_ec_struct, Structure)
     self.assertIsInstance(vor_fc_struct, Structure)
     print(len(vor_node_struct.sites))
     print(len(vor_fc_struct.sites))
Exemple #2
0
 def test_get_voronoi_nodes(self):
     #vor_node_struct, vor_ec_struct, vor_fc_struct = \
     #    get_high_accuracy_voronoi_nodes(self.structure, self.rad_dict)
     vor_node_struct = \
         get_high_accuracy_voronoi_nodes(self.structure, self.rad_dict)
     self.assertIsInstance(vor_node_struct, Structure)
     #self.assertIsInstance(vor_ec_struct, Structure)
     #self.assertIsInstance(vor_fc_struct, Structure)
     print(len(vor_node_struct.sites))
def symmetry_reduced_voronoi_nodes(
        structure, rad_dict, high_accuracy_flag=False, symm_flag=True):
    """
    Obtain symmetry reduced voronoi nodes using Zeo++ and
    pymatgen.symmetry.finder.SymmetryFinder

    Args:
        strucutre: pymatgen Structure object
        rad_dict: Dictionary containing radii of spcies in the structure
        high_accuracy_flag: Flag denotting whether to use high accuracy version of Zeo++
        symm_flag: Flag denoting whether to return symmetrically distinct sites only

    Returns:
        Symmetrically distinct voronoi nodes as pymatgen Strucutre
    """

    def add_closest_equiv_site(dist_sites, equiv_sites):
        if not dist_sites:
            dist_sites.append(equiv_sites[0])
        else:
            avg_dists = []
            for site in equiv_sites:
                dists = [site.distance(dst_site, jimage=[0, 0, 0])
                         for dst_site in dist_sites]
                avg_dist = sum(dists) / len(dist_sites)
                avg_dists.append(avg_dist)

            min_avg_dist = min(avg_dists)
            ind = avg_dists.index(min_avg_dist)
            dist_sites.append(equiv_sites[ind])

    def cmp_memoize_last_site(f): #Compares and stores last site
        def not_duplicates(site1, site2):
            if site1.distance(site2) < 1e-5:
                return False
            else:
                return True

        cmp_memoize_last_site.cache = None
        def helper(x):
            if not cmp_memoize_last_site.cache: 
                cmp_memoize_last_site.cache = f(x)
                return True
            y = f(x)
            if not_duplicates(cmp_memoize_last_site.cache, y):
                cmp_memoize_last_site.cache = y
                return True
            else:
                return False
        return helper

    @cmp_memoize_last_site
    def check_not_duplicates(site):
        return site


    if not symm_flag:
        if not high_accuracy_flag:
            vor_node_struct, vor_facecenter_struct  = get_voronoi_nodes(
                        structure, rad_dict)
            return vor_node_struct.sites, vor_facecenter_struct.sites
        else:
            # Only the nodes are from high accuracy voronoi decomposition
            vor_node_struct, vor_facecenter_struct  = \
                    get_high_accuracy_voronoi_nodes(structure, rad_dict)
            # Before getting the symmetry, remove the duplicates
            vor_node_struct.sites.sort(key = lambda site: site.voronoi_radius)
            #print type(vor_node_struct.sites[0])
            dist_sites = filter(check_not_duplicates, vor_node_struct.sites)
            return dist_sites, vor_facecenter_struct.sites


    if not high_accuracy_flag:
        vor_node_struct, vor_facecenter_struct  = get_voronoi_nodes(
                        structure, rad_dict)
        vor_node_symmetry_finder = SymmetryFinder(vor_node_struct, symprec=1e-1)
        vor_node_symm_struct = vor_node_symmetry_finder.get_symmetrized_structure()
        node_equiv_sites_list = vor_node_symm_struct.equivalent_sites

        node_dist_sites = []
        for equiv_sites in node_equiv_sites_list:
            add_closest_equiv_site(node_dist_sites, equiv_sites)

        vor_fc_symmetry_finder = SymmetryFinder(
                        vor_facecenter_struct, symprec=1e-1)
        vor_fc_symm_struct = vor_fc_symmetry_finder.get_symmetrized_structure()
        facecenter_equiv_sites_list = vor_fc_symm_struct.equivalent_sites

        facecenter_dist_sites = []
        for equiv_sites in facecenter_equiv_sites_list:
            add_closest_equiv_site(facecenter_dist_sites, equiv_sites)
        if not facecenter_equiv_sites_list:     # Fix this so doesn't arise
            facecenter_dist_sites = vor_facecenter_struct.sites

        return node_dist_sites, facecenter_dist_sites
    else:
        # Only the nodes are from high accuracy voronoi decomposition
        vor_node_struct, vor_facecenter_struct  = \
                get_high_accuracy_voronoi_nodes(structure, rad_dict)

        # Before getting the symmetry, remove the duplicates
        vor_node_struct.sites.sort(key = lambda site: site.voronoi_radius)
        #print type(vor_node_struct.sites[0])
        dist_sites = filter(check_not_duplicates, vor_node_struct.sites)
        # Increase the symmetry precision to 0.25
        spg = SymmetryFinder(structure,symprec=2.5e-1).get_spacegroup()
        
        # Remove symmetrically equivalent sites
        i = 0
        while (i < len(dist_sites)-1):
            sites1 = [dist_sites[i]]
            sites2 = [dist_sites[i+1]]
            if spg.are_symmetrically_equivalent(sites1,sites2):
                del dist_sites[i+1]
            else:
                i = i+1


        node_dist_sites = dist_sites

        vor_fc_symmetry_finder = SymmetryFinder(
                        vor_facecenter_struct, symprec=1e-1)
        vor_fc_symm_struct = vor_fc_symmetry_finder.get_symmetrized_structure()
        facecenter_equiv_sites_list = vor_fc_symm_struct.equivalent_sites

        facecenter_dist_sites = []
        for equiv_sites in facecenter_equiv_sites_list:
            add_closest_equiv_site(facecenter_dist_sites, equiv_sites)
        if not facecenter_equiv_sites_list:     # Fix this so doesn't arise
            facecenter_dist_sites = vor_facecenter_struct.sites

        return node_dist_sites, facecenter_dist_sites
def symmetry_reduced_voronoi_nodes(structure,
                                   rad_dict,
                                   high_accuracy_flag=False,
                                   symm_flag=True):
    """
    Obtain symmetry reduced voronoi nodes using Zeo++ and
    pymatgen.symmetry.finder.SymmetryFinder

    Args:
        strucutre: pymatgen Structure object
        rad_dict: Dictionary containing radii of spcies in the structure
        high_accuracy_flag: Flag denotting whether to use high accuracy version of Zeo++
        symm_flag: Flag denoting whether to return symmetrically distinct sites only

    Returns:
        Symmetrically distinct voronoi nodes as pymatgen Strucutre
    """
    def add_closest_equiv_site(dist_sites, equiv_sites):
        if not dist_sites:
            dist_sites.append(equiv_sites[0])
        else:
            avg_dists = []
            for site in equiv_sites:
                dists = [
                    site.distance(dst_site, jimage=[0, 0, 0])
                    for dst_site in dist_sites
                ]
                avg_dist = sum(dists) / len(dist_sites)
                avg_dists.append(avg_dist)

            min_avg_dist = min(avg_dists)
            ind = avg_dists.index(min_avg_dist)
            dist_sites.append(equiv_sites[ind])

    def cmp_memoize_last_site(f):  #Compares and stores last site
        def not_duplicates(site1, site2):
            if site1.distance(site2) < 1e-5:
                return False
            else:
                return True

        cmp_memoize_last_site.cache = None

        def helper(x):
            if not cmp_memoize_last_site.cache:
                cmp_memoize_last_site.cache = f(x)
                return True
            y = f(x)
            if not_duplicates(cmp_memoize_last_site.cache, y):
                cmp_memoize_last_site.cache = y
                return True
            else:
                return False

        return helper

    @cmp_memoize_last_site
    def check_not_duplicates(site):
        return site

    if not symm_flag:
        if not high_accuracy_flag:
            vor_node_struct, vor_facecenter_struct = get_voronoi_nodes(
                structure, rad_dict)
            return vor_node_struct.sites, vor_facecenter_struct.sites
        else:
            # Only the nodes are from high accuracy voronoi decomposition
            vor_node_struct, vor_facecenter_struct  = \
                    get_high_accuracy_voronoi_nodes(structure, rad_dict)
            # Before getting the symmetry, remove the duplicates
            vor_node_struct.sites.sort(key=lambda site: site.voronoi_radius)
            #print type(vor_node_struct.sites[0])
            dist_sites = filter(check_not_duplicates, vor_node_struct.sites)
            return dist_sites, vor_facecenter_struct.sites

    if not high_accuracy_flag:
        vor_node_struct, vor_facecenter_struct = get_voronoi_nodes(
            structure, rad_dict)
        vor_node_symmetry_finder = SymmetryFinder(vor_node_struct,
                                                  symprec=1e-1)
        vor_node_symm_struct = vor_node_symmetry_finder.get_symmetrized_structure(
        )
        node_equiv_sites_list = vor_node_symm_struct.equivalent_sites

        node_dist_sites = []
        for equiv_sites in node_equiv_sites_list:
            add_closest_equiv_site(node_dist_sites, equiv_sites)

        vor_fc_symmetry_finder = SymmetryFinder(vor_facecenter_struct,
                                                symprec=1e-1)
        vor_fc_symm_struct = vor_fc_symmetry_finder.get_symmetrized_structure()
        facecenter_equiv_sites_list = vor_fc_symm_struct.equivalent_sites

        facecenter_dist_sites = []
        for equiv_sites in facecenter_equiv_sites_list:
            add_closest_equiv_site(facecenter_dist_sites, equiv_sites)
        if not facecenter_equiv_sites_list:  # Fix this so doesn't arise
            facecenter_dist_sites = vor_facecenter_struct.sites

        return node_dist_sites, facecenter_dist_sites
    else:
        # Only the nodes are from high accuracy voronoi decomposition
        vor_node_struct, vor_facecenter_struct  = \
                get_high_accuracy_voronoi_nodes(structure, rad_dict)

        # Before getting the symmetry, remove the duplicates
        vor_node_struct.sites.sort(key=lambda site: site.voronoi_radius)
        #print type(vor_node_struct.sites[0])
        dist_sites = filter(check_not_duplicates, vor_node_struct.sites)
        # Increase the symmetry precision to 0.25
        spg = SymmetryFinder(structure, symprec=2.5e-1).get_spacegroup()

        # Remove symmetrically equivalent sites
        i = 0
        while (i < len(dist_sites) - 1):
            sites1 = [dist_sites[i]]
            sites2 = [dist_sites[i + 1]]
            if spg.are_symmetrically_equivalent(sites1, sites2):
                del dist_sites[i + 1]
            else:
                i = i + 1

        node_dist_sites = dist_sites

        vor_fc_symmetry_finder = SymmetryFinder(vor_facecenter_struct,
                                                symprec=1e-1)
        vor_fc_symm_struct = vor_fc_symmetry_finder.get_symmetrized_structure()
        facecenter_equiv_sites_list = vor_fc_symm_struct.equivalent_sites

        facecenter_dist_sites = []
        for equiv_sites in facecenter_equiv_sites_list:
            add_closest_equiv_site(facecenter_dist_sites, equiv_sites)
        if not facecenter_equiv_sites_list:  # Fix this so doesn't arise
            facecenter_dist_sites = vor_facecenter_struct.sites

        return node_dist_sites, facecenter_dist_sites