Esempio n. 1
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
Esempio n. 2
0
def get_redf(struct, cutoff=None, dr=0.05):
    """
    This function permits the calculation of the crystal structure-inherent electronic radial distribution function
    (ReDF) according to Willighagen et al., Acta Cryst., 2005, B61, 29-36. The ReDF is a structure-integral RDF (i.e.,
    summed over all sites) in which the positions of neighboring sites are weighted by electrostatic interactions
    inferred from atomic partial charges. Atomic charges are obtained from the ValenceIonicRadiusEvaluator class.

    Args:
        struct (Structure): 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 via key 'redf'.
    """
    if dr <= 0:
        raise ValueError("width of bins for ReDF must be >0")

    # make primitive
    struct = SpacegroupAnalyzer(struct).find_primitive() or struct

    # 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
Esempio n. 3
0
def get_redf(struct, cutoff=None, dr=0.05):
    """
    This function permits the calculation of the crystal structure-inherent electronic radial
    distribution function (ReDF) according to Willighagen et al., Acta Cryst., 2005, B61, 29-36.
    The ReDF is a structure-integral RDF (i.e., summed over all sites) in which the positions of
    neighboring sites are weighted by electrostatic interactions inferred from atomic partial
    charges. Atomic charges are obtained from the ValenceIonicRadiusEvaluator class.

    Args:
        struct (Structure): 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 via key 'redf'.
    """
    if dr <= 0:
        raise ValueError("width of bins for ReDF must be >0")

    # make primitive
    struct = SpacegroupAnalyzer(struct).find_primitive() or struct

    # 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