コード例 #1
0
class SymmetryFinderTest(unittest.TestCase):

    def setUp(self):
        p = Poscar.from_file(os.path.join(test_dir, 'POSCAR'))
        self.structure = p.struct
        self.sg = SymmetryFinder(self.structure, 0.001)
        parser = CifParser(os.path.join(test_dir, 'Li10GeP2S12.cif'))
        self.disordered_structure = parser.get_structures()[0]
        self.disordered_sg = SymmetryFinder(self.disordered_structure, 0.001)
        s = p.struct
        editor = StructureEditor(p.struct)
        site = s[0]
        editor.delete_site(0)
        editor.append_site(site.species_and_occu, site.frac_coords)
        self.sg3 = SymmetryFinder(editor.modified_structure, 0.001)

    def test_get_space_symbol(self):
        self.assertEqual(self.sg.get_spacegroup_symbol(), "Pnma")
        self.assertEqual(self.disordered_sg.get_spacegroup_symbol(), "P4_2/nmc")
        self.assertEqual(self.sg3.get_spacegroup_symbol(), "Pnma")

    def test_get_space_number(self):
        self.assertEqual(self.sg.get_spacegroup_number(), 62)
        self.assertEqual(self.disordered_sg.get_spacegroup_number(), 137)

    def test_get_hall(self):
        self.assertEqual(self.sg.get_hall(), '-P 2ac 2n')
        self.assertEqual(self.disordered_sg.get_hall(), 'P 4n 2n -1n')

    def test_get_pointgroup(self):
        self.assertEqual(self.sg.get_pointgroup(), 'mmm')
        self.assertEqual(self.disordered_sg.get_pointgroup(), '4/mmm')

    def test_get_symmetry_dataset(self):
        ds = self.sg.get_symmetry_dataset()
        self.assertEqual(ds['international'], 'Pnma')

    def test_get_crystal_system(self):
        crystal_system = self.sg.get_crystal_system()
        self.assertEqual('orthorhombic', crystal_system)
        self.assertEqual('tetragonal', self.disordered_sg.get_crystal_system())

    def test_get_symmetry_operations(self):
        fracsymmops = self.sg.get_symmetry_operations()
        symmops = self.sg.get_symmetry_operations(True)
        self.assertEqual(len(symmops), 8)
        latt = self.structure.lattice
        for fop, op in zip(fracsymmops, symmops):
            for site in self.structure:
                newfrac = fop.operate(site.frac_coords)
                newcart = op.operate(site.coords)
                self.assertTrue(np.allclose(latt.get_fractional_coords(newcart), newfrac))
                found = False
                newsite = PeriodicSite(site.species_and_occu, newcart, latt, coords_are_cartesian=True)
                for testsite in self.structure:
                    if newsite.is_periodic_image(testsite, 1e-3):
                        found = True
                        break
                self.assertTrue(found)

    def test_get_refined_structure(self):
        for a in self.sg.get_refined_structure().lattice.angles:
            self.assertEqual(a, 90)
        refined = self.disordered_sg.get_refined_structure()
        for a in refined.lattice.angles:
            self.assertEqual(a, 90)
        self.assertEqual(refined.lattice.a , refined.lattice.b)

    def test_get_symmetrized_structure(self):
        symm_struct = self.sg.get_symmetrized_structure()
        for a in symm_struct.lattice.angles:
            self.assertEqual(a, 90)
        self.assertEqual(len(symm_struct.equivalent_sites), 5)

        symm_struct = self.disordered_sg.get_symmetrized_structure()
        self.assertEqual(len(symm_struct.equivalent_sites), 8)

    def test_get_primitive(self):
        """
        F m -3 m Li2O testing of converting to primitive cell
        """
        self.assertIsNone(self.sg.find_primitive())
        parser = CifParser(os.path.join(test_dir, 'Li2O.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure)
        primitive_structure = s.find_primitive()
        self.assertEqual(primitive_structure.formula, "Li2 O1")
        # This isn't what is expected. All the angles should be 60
        self.assertAlmostEqual(primitive_structure.lattice.alpha, 120)
        self.assertAlmostEqual(primitive_structure.lattice.beta, 60)
        self.assertAlmostEqual(primitive_structure.lattice.gamma, 120)
        self.assertAlmostEqual(primitive_structure.lattice.volume, structure.lattice.volume / 4.0)
コード例 #2
0
ファイル: structure_fitter.py プロジェクト: chenweis/pymatgen
    def __init__(
        self,
        structure_a,
        structure_b,
        tolerance_cell_misfit=0.1,
        tolerance_atomic_misfit=1.0,
        supercells_allowed=True,
        anonymized=False,
        fitting_accuracy=FAST_FIT,
        use_symmetry=False,
    ):
        """
        Fits two structures. All fitting parameters have been set with defaults 
        that should work in most cases. To use, initialize the structure fitter
        with parameters.
        E.g.,
        fitter = StructureFitter(a, b)
        print fitter.fit_found
        
        Args:
            structure_a : 
                First structure
            structure_b : 
                Second structure to try to match with first structure
            tolerance_cell_misfit : 
                Tolerance for cell misfit. Default = 0.1
            tolerance_atomic_misfit : 
                Tolerance for atomic misfit. Default = 1.0.
            supercells_allowed : 
                Whether supercell structures are allowed.  Default = True.
            anonymized : 
                Whether to attempt matching of different species.  Setting this
                to true will allow any two structures with the same framework,
                but different species to match to each other. Default = False.
            fitting_accuracy : 
                An integer setting for the fitting accuracy.  Corresponds to
                the max number of candidate rotations considered.  Use the
                static variables, 
                StructureFitter.FAST_FIT
                StructureFitter.NORMAL_FIT
                StructureFitter.ACCURATE_FIT
                to set the tradeoff between accuracy and speed.  The default, 
                FAST_FIT, should work reasonably well in most instances.
            use_symmetry:
                Whether to use pymatgen.spacegroup to determine the spacegroup
                first. Eliminates most non-fits. Defaults to True.
        """

        self._tolerance_cell_misfit = tolerance_cell_misfit
        self._tolerance_atomic_misfit = tolerance_atomic_misfit
        self._supercells_allowed = supercells_allowed
        self._anonymized = anonymized
        self._max_rotations = fitting_accuracy
        # Sort structures first so that they have the same arrangement of species
        self._structure_a = structure_a.get_sorted_structure()
        self._structure_b = structure_b.get_sorted_structure()
        if use_symmetry:
            from pymatgen.symmetry.spglib_adaptor import SymmetryFinder

            finder_a = SymmetryFinder(self._structure_a, symprec=0.1)
            finder_b = SymmetryFinder(self._structure_b, symprec=0.1)
            same_sg = finder_a.get_spacegroup_number() == finder_b.get_spacegroup_number()

        if not use_symmetry or same_sg:
            self._mapping_op = None
            if not self._anonymized:
                self.fit(self._structure_a, self._structure_b)
                if self.fit_found:
                    self.el_mapping = {el: el for el in self._structure_a.composition.elements}
            else:
                comp_a = structure_a.composition
                comp_b = structure_b.composition
                if len(comp_a.elements) == len(comp_b.elements):
                    el_a = comp_a.elements
                    # Create permutations of the specie/elements in structure A
                    for p in itertools.permutations(el_a):
                        # Create mapping of the specie/elements in structure B to that of A.
                        # Then create a modified structure with those elements and try to fit it.
                        el_mapping = dict(zip(comp_b.elements, p))
                        logger.debug("Using specie mapping " + str(el_mapping))
                        mod = StructureEditor(self._structure_b)
                        mod.replace_species(el_mapping)
                        self.fit(self._structure_a, mod.modified_structure)
                        if self._mapping_op != None:
                            # Store successful element mapping
                            self.el_mapping = {el_a: el_b for el_b, el_a in el_mapping.items()}
                            break
                else:
                    logger.debug("No. of elements in structures are unequal.")
        else:
            self._mapping_op = None
            logger.debug("Symmetry is different.")