示例#1
0
 def test_pbc_all_distances(self):
     fcoords = np.array([[0.3, 0.3, 0.5], [0.1, 0.1, 0.3], [0.9, 0.9, 0.8],
                         [0.1, 0.0, 0.5], [0.9, 0.7, 0.0]])
     lattice = Lattice.from_lengths_and_angles([8, 8, 4], [90, 76, 58])
     expected = np.array([[0.000, 3.015, 4.072, 3.519, 3.245],
                          [3.015, 0.000, 3.207, 1.131, 4.453],
                          [4.072, 3.207, 0.000, 2.251, 1.788],
                          [3.519, 1.131, 2.251, 0.000, 3.852],
                          [3.245, 4.453, 1.788, 3.852, 0.000]])
     output = pbc_all_distances(lattice, fcoords, fcoords)
     self.assertArrayAlmostEqual(output, expected, 3)
     #test just one input point
     output2 = pbc_all_distances(lattice, fcoords[0], fcoords)
     self.assertArrayAlmostEqual(output2, [expected[0]], 2)
     #test distance when initial points are not in unit cell
     f1 = [0, 0, 17]
     f2 = [0, 0, 10]
     self.assertEqual(pbc_all_distances(lattice, f1, f2)[0, 0], 0)
示例#2
0
 def test_pbc_all_distances(self):
     fcoords = np.array([[0.3, 0.3, 0.5],
                         [0.1, 0.1, 0.3],
                         [0.9, 0.9, 0.8],
                         [0.1, 0.0, 0.5],
                         [0.9, 0.7, 0.0]])
     lattice = Lattice.from_lengths_and_angles([8, 8, 4],
                                               [90, 76, 58])
     expected = np.array([[0.000, 3.015, 4.072, 3.519, 3.245],
                          [3.015, 0.000, 3.207, 1.131, 4.453],
                          [4.072, 3.207, 0.000, 2.251, 1.788],
                          [3.519, 1.131, 2.251, 0.000, 3.852],
                          [3.245, 4.453, 1.788, 3.852, 0.000]])
     output = pbc_all_distances(lattice, fcoords, fcoords)
     self.assertArrayAlmostEqual(output, expected, 3)
     #test just one input point
     output2 = pbc_all_distances(lattice, fcoords[0], fcoords)
     self.assertArrayAlmostEqual(output2, [expected[0]], 2)
     #test distance when initial points are not in unit cell
     f1 = [0, 0, 17]
     f2 = [0, 0, 10]
     self.assertEqual(pbc_all_distances(lattice, f1, f2)[0, 0], 0)
    def test_subset(self):
        sm = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5,
                              primitive_cell=False, scale=True,
                              attempt_supercell=False,
                              allow_subset=True)
        l = Lattice.orthorhombic(10, 20, 30)
        s1 = Structure(l, ['Si', 'Si', 'Ag'],
                       [[0,0,0.1],[0,0,0.2],[.7,.4,.5]])
        s2 = Structure(l, ['Si', 'Ag'],
                       [[0,0.1,0],[-.7,.5,.4]])
        result = sm.get_s2_like_s1(s1, s2)
        
        self.assertEqual(len(find_in_coord_list_pbc(result.frac_coords,
                                                    [0,0,0.1])), 1)
        self.assertEqual(len(find_in_coord_list_pbc(result.frac_coords,
                                                    [0.7,0.4,0.5])), 1)

        #test with fewer species in s2
        s1 = Structure(l, ['Si', 'Ag', 'Si'],
                       [[0,0,0.1],[0,0,0.2],[.7,.4,.5]])
        s2 = Structure(l, ['Si', 'Si'],
                       [[0,0.1,0],[-.7,.5,.4]])
        result = sm.get_s2_like_s1(s1, s2)
        mindists = np.min(pbc_all_distances(s1.lattice, s1.frac_coords, 
                                       result.frac_coords), axis=0)
        self.assertLess(np.max(mindists), 1e-6)

        self.assertEqual(len(find_in_coord_list_pbc(result.frac_coords,
                                                    [0,0,0.1])), 1)
        self.assertEqual(len(find_in_coord_list_pbc(result.frac_coords,
                                                    [0.7,0.4,0.5])), 1)

        #test with not enough sites in s1
        #test with fewer species in s2
        s1 = Structure(l, ['Si', 'Ag', 'Cl'],
                       [[0,0,0.1],[0,0,0.2],[.7,.4,.5]])
        s2 = Structure(l, ['Si', 'Si'],
                       [[0,0.1,0],[-.7,.5,.4]])
        self.assertEqual(sm.get_s2_like_s1(s1, s2), None)
示例#4
0
    def parse_oxide(self):
        """
        Determines if an oxide is a peroxide/superoxide/ozonide/normal oxide

        Returns:
            oxide_type:
                Type of oxide - ozonide/peroxide/superoxide/hydroxide/None
            nbonds:
                Number of peroxide/superoxide/hydroxide bonds in structure
        """

        structure = self.structure
        relative_cutoff = self.relative_cutoff
        o_sites_frac_coords = []
        h_sites_frac_coords = []
        lattice = structure.lattice

        if isinstance(structure.composition.elements[0], Element):
            comp = structure.composition
        elif isinstance(structure.composition.elements[0], Specie):
            elmap = collections.defaultdict(float)
            for site in structure:
                for species, occu in site.species_and_occu.items():
                    elmap[species.element] += occu
            comp = Composition(elmap)
        if Element("O") not in comp or comp.is_element:
            return "None", 0

        for site in structure:
            syms = [sp.symbol for sp in site.species_and_occu.keys()]
            if "O" in syms:
                o_sites_frac_coords.append(site.frac_coords)
            if "H" in syms:
                h_sites_frac_coords.append(site.frac_coords)

        if h_sites_frac_coords:
            dist_matrix = pbc_all_distances(lattice, o_sites_frac_coords,
                                            h_sites_frac_coords)
            if np.any(dist_matrix < relative_cutoff * 0.93):
                return "hydroxide", len(
                    np.where(dist_matrix < relative_cutoff * 0.93)[0]) / 2.0
        dist_matrix = pbc_all_distances(lattice, o_sites_frac_coords,
                                        o_sites_frac_coords)
        np.fill_diagonal(dist_matrix, 1000)
        is_superoxide = False
        is_peroxide = False
        is_ozonide = False
        if np.any(dist_matrix < relative_cutoff * 1.35):
            bond_atoms = np.where(dist_matrix < relative_cutoff * 1.35)[0]
            is_superoxide = True
        elif np.any(dist_matrix < relative_cutoff * 1.49):
            is_peroxide = True
            bond_atoms = np.where(dist_matrix < relative_cutoff * 1.49)[0]
        if is_superoxide:
            if len(bond_atoms) > len(set(bond_atoms)):
                is_superoxide = False
                is_ozonide = True
        try:
            nbonds = len(set(bond_atoms))
        except UnboundLocalError:
            nbonds = 0.0
        if is_ozonide:
            str_oxide = "ozonide"
        elif is_superoxide:
            str_oxide = "superoxide"
        elif is_peroxide:
            str_oxide = "peroxide"
        else:
            str_oxide = "oxide"
        return str_oxide, nbonds
示例#5
0
    def parse_oxide(self):
        """
        Determines if an oxide is a peroxide/superoxide/ozonide/normal oxide
        Returns:
            oxide_type:
                Type of oxide - ozonide/peroxide/superoxide/hydroxide/None
            nbonds:
                Number of peroxide/superoxide/hydroxide bonds in structure
        """

        structure = self.structure
        relative_cutoff = self.relative_cutoff
        o_sites_frac_coords = []
        h_sites_frac_coords = []
        lattice = structure.lattice

        if isinstance(structure.composition.elements[0], Element):
            comp = structure.composition
        elif isinstance(structure.composition.elements[0], Specie):
            elmap = collections.defaultdict(float)
            for site in structure:
                for species, occu in site.species_and_occu.items():
                    elmap[species.element] += occu
            comp = Composition(elmap)
        if Element("O") not in comp or comp.is_element:
            return "None", 0

        for site in structure:
            syms = [sp. symbol for sp in site.species_and_occu.keys()]
            if "O" in syms:
                o_sites_frac_coords.append(site.frac_coords)
            if "H" in syms:
                h_sites_frac_coords.append(site.frac_coords)

        if h_sites_frac_coords:
            dist_matrix = pbc_all_distances(lattice, o_sites_frac_coords,
                                            h_sites_frac_coords)
            if np.any(dist_matrix < relative_cutoff * 0.93):
                return "hydroxide", len(np.where(dist_matrix < relative_cutoff * 0.93)[0]) / 2.0
        dist_matrix = pbc_all_distances(lattice, o_sites_frac_coords,
                                        o_sites_frac_coords)
        np.fill_diagonal(dist_matrix, 1000)
        is_superoxide = False
        is_peroxide = False
        is_ozonide = False
        if np.any(dist_matrix < relative_cutoff * 1.35):
            bond_atoms = np.where(dist_matrix < relative_cutoff * 1.35)[0]
            is_superoxide = True
        elif np.any(dist_matrix < relative_cutoff * 1.49):
            is_peroxide = True
            bond_atoms = np.where(dist_matrix < relative_cutoff * 1.49)[0]
        if is_superoxide:
            if len(bond_atoms) > len(set(bond_atoms)):
                is_superoxide = False
                is_ozonide = True
        try:
            nbonds = len(set(bond_atoms))
        except UnboundLocalError:
            nbonds = 0.0
        if is_ozonide:
            str_oxide = "ozonide"
        elif is_superoxide:
            str_oxide = "superoxide"
        elif is_peroxide:
            str_oxide = "peroxide"
        else:
            str_oxide = "oxide"
        return str_oxide, nbonds
def oxide_type(structure, relative_cutoff=1.2):
    """
    Determines if an oxide is a peroxide/superoxide/ozonide/normal oxide
    
    Args:
        structure:
            Input structure.
        relative_cutoff:
            Relative_cutoff * act. cutoff stipulates the max. distance two 
            O atoms must be from each other. 
    """

    o_sites_frac_coords = []
    h_sites_frac_coords = []
    lattice = structure.lattice

#    Check if H2O/O2/H2O2/non-oxide is being checked
    el_other_than_OH = [el.symbol for el in structure.composition.elements if el.symbol not in ["H", "O"]]
    if (not el_other_than_OH) | (len(el_other_than_OH) == len(structure.composition.elements)):
        return "None"

    for site in structure:
        syms = [sp. symbol for sp in site.species_and_occu.keys()]
        if "O" in syms:
            o_sites_frac_coords.append(site.frac_coords)
        if "H" in syms:
            h_sites_frac_coords.append(site.frac_coords)

#   We are not correcting hydrides
    if not o_sites_frac_coords:
        return "None"

    if h_sites_frac_coords:
        dist_matrix = pbc_all_distances(lattice, o_sites_frac_coords, h_sites_frac_coords)
        if np.any(dist_matrix < relative_cutoff * 0.93):
            return "hydroxide"
    dist_matrix = pbc_all_distances(lattice, o_sites_frac_coords, o_sites_frac_coords)
    np.fill_diagonal(dist_matrix, 1000)
    is_superoxide = False
    is_peroxide = False
    is_ozonide = False
    if np.any(dist_matrix < relative_cutoff * 1.35):
        is_superoxide = True
    elif np.any(dist_matrix < relative_cutoff * 1.49):
        is_peroxide = True
    if is_superoxide:
        if (int(structure.composition["O"] / structure.composition.get_reduced_composition_and_factor()[1]) % 3 == 0):
            sum = 0
            for elt in [el for el in structure.composition.elements if el is not Element("O")]:
                sum += structure.composition[elt.symbol]
            if sum / structure.composition.get_reduced_composition_and_factor()[1] <= 1:
                is_superoxide = False
                is_ozonide = True
    if is_ozonide: 
        return "ozonide"
    elif is_superoxide:
        return "superoxide"
    elif is_peroxide:
        return "peroxide"
    else:
        return "oxide"