Пример #1
0
    def generate_defect_structure(self, supercell=(1, 1, 1)):
        """
        Returns Defective Substitution structure, decorated with charge.
        If bulk structure had any site properties, all of these properties are
        removed in the resulting defect structure.

        Args:
            supercell (int, [3x1], or [[]] (3x3)): supercell integer, vector, or scaling matrix
        """
        defect_structure = Structure( self.bulk_structure.copy().lattice,
                                      [site.specie for site in self.bulk_structure],
                                      [site.frac_coords for site in self.bulk_structure],
                                      to_unit_cell=True, coords_are_cartesian = False,
                                      site_properties = None) #remove all site_properties
        defect_structure.make_supercell(supercell)

        #create a trivial defect structure to find where supercell transformation moves the defect
        struct_for_defect_site = Structure( self.bulk_structure.copy().lattice,
                                            [self.site.specie],
                                            [self.site.frac_coords],
                                            to_unit_cell=True, coords_are_cartesian = False)
        struct_for_defect_site.make_supercell(supercell)
        defect_site = struct_for_defect_site[0]

        poss_deflist = sorted(
            defect_structure.get_sites_in_sphere(defect_site.coords, 0.1, include_index=True), key=lambda x: x[1])
        defindex = poss_deflist[0][2]

        subsite = defect_structure.pop(defindex)
        defect_structure.append(self.site.specie.symbol, subsite.coords, coords_are_cartesian=True,
                                properties = None)
        defect_structure.set_charge(self.charge)
        return defect_structure
Пример #2
0
    def get_string(self, radius=10.):
        """
        Returns a string representation of atomic shell coordinates to be used
        in the feff.inp file.

        Args:
            radius:
                Maximum atomic shell radius to include in atoms list

        Returns:
            String representation of Atomic Coordinate Shells.
        """
        nopts = len(self.struct.species)

        ptatoms = []
        for i in range(0, nopts):
            ptatoms.append(self.struct.species[i].symbol)

        index = ptatoms.index(self.central_atom)
        pt = self.struct.cart_coords[index]
        sphere = Structure.get_sites_in_sphere(self.struct, pt, radius)
        xshift = pt[0]
        yshift = pt[1]
        zshift = pt[2]
        end = len(sphere)
        row = []

        for i in range(end):
            atom = sphere[i][0]
            atm = re.sub(r"[^aA-zZ]+", "", atom.species_string)
            ipot = self.pot_dict[atm]
            x = atom.coords[0] - xshift
            y = atom.coords[1] - yshift
            z = atom.coords[2] - zshift
            distance = sphere[i][1]
            row.append(["{:f}".format(x), "{:f}".format(y), "{:f}".format(z),
                        ipot, atm, "{:f}".format(distance), i])

        row_sorted = sorted(row, key=itemgetter(5))
        row_sorted[0][3] = 0

        for i in range(end):
            row_sorted[i][6] = i

        row_sorted = str_aligned(row_sorted, ["*       x", "y", "z", "ipot",
                                              "Atom", "Distance", "Number"])
        atom_list = row_sorted.replace("--", "**")

        return ''.join(["ATOMS\n", atom_list, "\nEND\n"])
Пример #3
0
    def generate_defect_structure(self, supercell=(1, 1, 1)):
        """
        Returns Defective Substitution structure, decorated with charge.
        If bulk structure had any site properties, all of these properties are
        removed in the resulting defect structure.

        Args:
            supercell (int, [3x1], or [[]] (3x3)): supercell integer, vector, or scaling matrix
        """
        defect_structure = Structure(
            self.bulk_structure.copy().lattice,
            [site.specie for site in self.bulk_structure],
            [site.frac_coords for site in self.bulk_structure],
            to_unit_cell=True,
            coords_are_cartesian=False,
            site_properties=None,
        )  # remove all site_properties
        defect_structure.make_supercell(supercell)

        # create a trivial defect structure to find where supercell transformation moves the defect
        struct_for_defect_site = Structure(
            self.bulk_structure.copy().lattice,
            [self.site.specie],
            [self.site.frac_coords],
            to_unit_cell=True,
            coords_are_cartesian=False,
        )
        struct_for_defect_site.make_supercell(supercell)
        defect_site = struct_for_defect_site[0]

        poss_deflist = sorted(
            defect_structure.get_sites_in_sphere(defect_site.coords,
                                                 0.1,
                                                 include_index=True),
            key=lambda x: x[1],
        )
        defindex = poss_deflist[0][2]

        subsite = defect_structure.pop(defindex)
        defect_structure.append(
            self.site.specie.symbol,
            subsite.coords,
            coords_are_cartesian=True,
            properties=None,
        )
        defect_structure.set_charge(self.charge)
        return defect_structure
Пример #4
0
def perturb_neighboring_atoms(structure: Structure,
                              center: List[float],
                              cutoff: float,
                              distance: float,
                              inserted_atom_indices: List[int]
                              ) -> Tuple[Structure, list]:
    """ Return the structure with randomly perturbed atoms near the center

    Args:
        structure (Structure):
            pmg Structure class object
        center (list):
            Fractional coordinates of a central position.
        cutoff (float):
            Radius of a sphere in which atoms are perturbed.
        distance (float):
            Max displacement distance for the perturbation.
        inserted_atom_indices (list):
            Inserted atom indices, which will not be perturbed.

    Return:
        Tuple of perturbed Structure and list of perturbed atom indices.
    """
    perturbed_structure = structure.copy()
    cartesian_coords = structure.lattice.get_cartesian_coords(center)
    # neighbor is (PeriodicSite, distance, index)
    neighbors = structure.get_sites_in_sphere(
        pt=cartesian_coords, r=cutoff, include_index=True)
    if not neighbors:
        logger.warning(f"No neighbors withing the cutoff {cutoff}.")

    sites = []
    for i in neighbors:
        # not perturb inserted atoms
        if i[2] in inserted_atom_indices:
            continue
        # Since translate_sites accepts only one vector, iterate this.
        vector = normalized_random_3d_vector() * distance * np.random.random()
        site_index = i[2]
        sites.append(site_index)
        perturbed_structure.translate_sites(
            indices=site_index, vector=vector, frac_coords=False)

    return perturbed_structure, sites
Пример #5
0
    def get_string(self, radius=10.):
        """
        Returns a string representation of atomic shell coordinates to be used
        in the feff.inp file.

        Args:
            radius: Maximum atomic shell radius to include in atoms list

        Returns:
            String representation of Atomic Coordinate Shells.
        """

        #Internal variables:
        #
        #nopts      = number of potentials in unit cell used
        #ptatoms    = list of atom potential atom symbols in unit cell
        #index      = index number of absorbing atom in list
        #pt         = coordinates of absorbing atom
        #sphere     = sites around absorbing atom within radius
        #x,y,zshift = coordinate shift to place absorbing atom at (0,0,0)
        #atom       = site in sphere
        #atm        = atomic symbol string for atom at atom site
        #ipot       = index for that atom symbol in potential dictionary
        #distance   = distance of that atom site from absorbing atom

        nopts = len(self.struct.species)

        ptatoms = [self.struct.species[i].symbol for i in range(nopts)]

        index = ptatoms.index(self.central_atom)
        pt = self.struct.cart_coords[index]
        sphere = Structure.get_sites_in_sphere(self.struct, pt, radius)
        xshift = pt[0]
        yshift = pt[1]
        zshift = pt[2]
        end = len(sphere)
        row = []

        for i in range(end):
            atom = sphere[i][0]
            atm = re.sub(r"[^aA-zZ]+", "", atom.species_string)
            ipot = self.pot_dict[atm]
            x = atom.coords[0] - xshift
            y = atom.coords[1] - yshift
            z = atom.coords[2] - zshift
            distance = sphere[i][1]
            row.append(["{:f}".format(x), "{:f}".format(y), "{:f}".format(z),
                        ipot, atm, "{:f}".format(distance), i])

        #after this point table is built

        row_sorted = sorted(row, key=itemgetter(5))
        row_sorted[0][3] = 0

        for i in range(end):
            row_sorted[i][6] = i

        row_sorted = str_aligned(row_sorted, ["*       x", "y", "z", "ipot",
                                              "Atom", "Distance", "Number"])
        atom_list = row_sorted.replace("--", "**")

        return ''.join(["ATOMS\n", atom_list, "\nEND\n"])
Пример #6
0
    def get_string(self, radius=10.):
        """
        Returns a string representation of atomic shell coordinates to be used
        in the feff.inp file.

        Args:
            radius: Maximum atomic shell radius to include in atoms list

        Returns:
            String representation of Atomic Coordinate Shells.
        """

        #Internal variables:
        #
        #nopts      = number of potentials in unit cell used
        #ptatoms    = list of atom potential atom symbols in unit cell
        #index      = index number of absorbing atom in list
        #pt         = coordinates of absorbing atom
        #sphere     = sites around absorbing atom within radius
        #x,y,zshift = coordinate shift to place absorbing atom at (0,0,0)
        #atom       = site in sphere
        #atm        = atomic symbol string for atom at atom site
        #ipot       = index for that atom symbol in potential dictionary
        #distance   = distance of that atom site from absorbing atom

        nopts = len(self.struct.species)

        ptatoms = [self.struct.species[i].symbol for i in range(nopts)]

        index = ptatoms.index(self.central_atom)
        pt = self.struct.cart_coords[index]
        sphere = Structure.get_sites_in_sphere(self.struct, pt, radius)
        xshift = pt[0]
        yshift = pt[1]
        zshift = pt[2]
        end = len(sphere)
        row = []

        for i in range(end):
            atom = sphere[i][0]
            atm = re.sub(r"[^aA-zZ]+", "", atom.species_string)
            ipot = self.pot_dict[atm]
            x = atom.coords[0] - xshift
            y = atom.coords[1] - yshift
            z = atom.coords[2] - zshift
            distance = sphere[i][1]
            row.append([
                "{:f}".format(x), "{:f}".format(y), "{:f}".format(z), ipot,
                atm, "{:f}".format(distance), i
            ])

        #after this point table is built

        row_sorted = sorted(row, key=itemgetter(5))
        row_sorted[0][3] = 0

        for i in range(end):
            row_sorted[i][6] = i

        row_sorted = str_aligned(
            row_sorted,
            ["*       x", "y", "z", "ipot", "Atom", "Distance", "Number"])
        atom_list = row_sorted.replace("--", "**")

        return ''.join(["ATOMS\n", atom_list, "\nEND\n"])