def abi_sanitize(self, symprec=1e-3, primitive=True): """ Returns a new structure in which: * Oxidation states are removed. * Structure is refined. * Reduced to primitive settings. * Lattice vectors are exchanged if the triple product is negative Args: symprec: Symmetry precision used to refine the structure. if `symprec` is None, so structure refinement is peformed. primitive (bool): Whether to convert to a primitive cell. """ from pymatgen.transformations.standard_transformations import OxidationStateRemovalTransformation, \ PrimitiveCellTransformation, SupercellTransformation # Remove oxidation states. remove_ox = OxidationStateRemovalTransformation() structure = remove_ox.apply_transformation(self) # Refine structure if symprec is not None: sym_finder = SpacegroupAnalyzer(structure=structure, symprec=symprec) structure = sym_finder.get_refined_structure() # Convert to primitive structure. if primitive: get_prim = PrimitiveCellTransformation() structure = get_prim.apply_transformation(structure) # Exchange last two lattice vectors if triple product is negative. m = structure.lattice.matrix x_prod = np.dot(np.cross(m[0], m[1]), m[2]) if x_prod < 0: trans = SupercellTransformation(((1, 0, 0), (0, 0, 1), (0, 1, 0))) structure = trans.apply_transformation(structure) m = structure.lattice.matrix x_prod = np.dot(np.cross(m[0], m[1]), m[2]) if x_prod < 0: raise RuntimeError("x_prod is still negative!") return structure
def refine_structure(structure, symprec=1e-3): remove_ox = OxidationStateRemovalTransformation() structure = remove_ox.apply_transformation(structure) sym_finder = SpacegroupAnalyzer(structure=structure, symprec=symprec) structure = sym_finder.get_refined_structure() get_prim = PrimitiveCellTransformation() structure = get_prim.apply_transformation(structure) m = structure.lattice.matrix x_prod = np.dot(np.cross(m[0], m[1]), m[2]) if x_prod < 0: print(x_prod) trans = SupercellTransformation(((1, 0, 0), (0, 0, 1), (0, 1, 0))) structure = trans.apply_transformation(structure) m = structure.lattice.matrix x_prod = np.dot(np.cross(m[0], m[1]), m[2]) print(x_prod) if x_prod < 0: raise RuntimeError return structure
def test_apply_transformation(self): t = OxidationStateRemovalTransformation() coords = [] coords.append([0, 0, 0]) coords.append([0.75, 0.75, 0.75]) coords.append([0.5, 0.5, 0.5]) coords.append([0.25, 0.25, 0.25]) lattice = Lattice([ [3.8401979337, 0.00, 0.00], [1.9200989668, 3.3257101909, 0.00], [0.00, -2.2171384943, 3.1355090603], ]) struct = Structure(lattice, ["Li+", "Li+", "O2-", "O2-"], coords) s = t.apply_transformation(struct) self.assertEqual(s[0].species_string, "Li") self.assertEqual(s[2].species_string, "O") d = t.as_dict() self.assertEqual( type(OxidationStateRemovalTransformation.from_dict(d)), OxidationStateRemovalTransformation, )