예제 #1
0
    def from_structure(cls, structure, has_timerev=True, symprec=1e-5, angle_tolerance=5):
        """
        Takes a `Structure` object. Uses pyspglib to perform various symmetry finding operations.

        Args:
            structure:
                Structure object
            has_timerev:
                True is time-reversal symmetry is included.
            symprec:
                Tolerance for symmetry finding
            angle_tolerance:
                Angle tolerance for symmetry finding.

        .. warning::
            AFM symmetries are not supported.
        """
        # Call spglib to get the list of symmetry operations.
        finder = SymmetryFinder(structure, symprec=symprec, angle_tolerance=angle_tolerance)
        data = finder.get_symmetry_dataset()

        symrel = data["rotations"],

        return cls(spgid=data["number"],
                   symrel=symrel,
                   tnons=data["translations"],
                   symafm=len(symrel) * [1],
                   has_timerev=has_timerev,
                   inord="C")
예제 #2
0
파일: feffio.py 프로젝트: isayev/pymatgen
 def __init__(self, struct, source='', comment=''):
     """
     Args:
         struct:
             Structure object, See pymatgen.core.structure.Structure.
         source:
             User supplied identifier, i.e. for Materials Project this
             would be the material ID number
         comment:
             comment for first header line
     """
     if struct.is_ordered:
         self._struct = struct
         self._source = source
         self._site_symbols = []
         self._natoms = []
         sym = SymmetryFinder(struct)
         data = sym.get_symmetry_dataset()
         self._space_number = data["number"]
         self._space_group = data["international"]
         syms = [site.specie.symbol for site in struct]
         for (s, data) in itertools.groupby(syms):
             self._site_symbols.append(s)
             self._natoms.append(len(tuple(data)))
         if comment == '':
             self._comment = 'None Given'
         else:
             self._comment = comment
     else:
         raise ValueError("Structure with partial occupancies cannot be "
                          "converted into atomic coordinates!")
예제 #3
0
 def __init__(self, struct, source='', comment=''):
     """
     Args:
         struct:
             Structure object, See pymatgen.core.structure.Structure.
         source:
             User supplied identifier, i.e. for Materials Project this
             would be the material ID number
         comment:
             comment for first header line
     """
     if struct.is_ordered:
         self._struct = struct
         self._source = source
         self._site_symbols = []
         self._natoms = []
         sym = SymmetryFinder(struct)
         data = sym.get_symmetry_dataset()
         self._space_number = data["number"]
         self._space_group = data["international"]
         syms = [site.specie.symbol for site in struct]
         for (s, data) in itertools.groupby(syms):
             self._site_symbols.append(s)
             self._natoms.append(len(tuple(data)))
         if comment == '':
             self._comment = 'None Given'
         else:
             self._comment = comment
     else:
         raise ValueError("Structure with partial occupancies cannot be "
                          "converted into atomic coordinates!")
예제 #4
0
    def from_structure(cls,
                       structure,
                       has_timerev=True,
                       symprec=1e-5,
                       angle_tolerance=5):
        """
        Takes a :class:`Structure` object. Uses pyspglib to perform various symmetry finding operations.

        Args:
            structure: :class:`Structure` object
            has_timerev: True is time-reversal symmetry is included.
            symprec: Tolerance for symmetry finding
            angle_tolerance: Angle tolerance for symmetry finding.

        .. warning::

            AFM symmetries are not supported.
        """
        # Call spglib to get the list of symmetry operations.
        finder = SymmetryFinder(structure,
                                symprec=symprec,
                                angle_tolerance=angle_tolerance)
        data = finder.get_symmetry_dataset()

        symrel = data["rotations"],

        return cls(spgid=data["number"],
                   symrel=symrel,
                   tnons=data["translations"],
                   symafm=len(symrel) * [1],
                   has_timerev=has_timerev,
                   inord="C")
예제 #5
0
파일: cif2spg.py 프로젝트: gmrigna/abipy
def main():
    def str_examples():
        examples = """
    Usage example:\n
        cif2spg.py silicon.cif     => Open CIF file and visualize info on the spacegroup.
        cif2spg.py -g silicon.cif  => Same as above but use the GUI. 
    """
        return examples

    def show_examples_and_exit(err_msg=None, error_code=1):
        """Display the usage of the script."""
        sys.stderr.write(str_examples())
        if err_msg: 
            sys.stderr.write("Fatal Error\n" + err_msg + "\n")

        sys.exit(error_code)


    parser = argparse.ArgumentParser(epilog=str_examples(), formatter_class=argparse.RawDescriptionHelpFormatter)

    parser.add_argument('cif_file', nargs=1, help="CIF File")

    parser.add_argument('-g', '--gui', action="store_true", help="Enable GUI")

    # Parse command line.
    try:
        options = parser.parse_args()
    except: 
        show_examples_and_exit(error_code=1)

    cif_file = options.cif_file[0]
    structure = abilab.Structure.from_file(cif_file)
    #print(structure.to_abivars())

    finder = SymmetryFinder(structure, symprec=1e-5, angle_tolerance=5)

    data = finder.get_symmetry_dataset()
    from pprint import pprint

    if not options.gui:
        pprint(data)

    else:
        from StringIO import StringIO
        import wx
        from abipy.gui.editor import SimpleTextViewer

        stream = StringIO()
        pprint(data, stream=stream)
        stream.seek(0)
        text = "".join(stream)
        app = wx.App()
        frame = SimpleTextViewer(None, text=text)
        frame.Show()
        app.MainLoop()

    return 0
예제 #6
0
    def get_structure(vasp_run,
                      outcar=None,
                      initial_structure=False,
                      additional_info=False):
        """
        Process structure for static calculations from previous run.

        Args:
            vasp_run:
                Vasprun object that contains the final structure from previous
                run.
            outcar:
                Outcar object that contains the magnetization info from
                previous run.
            initial_structure:
                Whether to return the structure from previous run. Default is
                False.
            additional_info:
                Whether to return additional symmetry info related to the
                structure. If True, return a list of the refined structure (
                conventional cell), the conventional standard structure,
                the symmetry dataset and symmetry operations of the structure
                (see SymmetryFinder doc for details)

        Returns:
            Returns the magmom-decorated structure that can be passed to get
            Vasp input files, e.g. get_kpoints.
        """
        #TODO: fix magmom for get_*_structures
        if vasp_run.is_spin:
            if outcar and outcar.magnetization:
                magmom = {"magmom": [i['tot'] for i in outcar.magnetization]}
            else:
                magmom = {
                    "magmom": vasp_run.to_dict['input']['parameters']['MAGMOM']
                }
        else:
            magmom = None
        structure = vasp_run.final_structure
        if magmom:
            structure = structure.copy(site_properties=magmom)
        sym_finder = SymmetryFinder(structure, symprec=0.01)
        if initial_structure:
            return structure
        elif additional_info:
            info = [
                sym_finder.get_refined_structure(),
                sym_finder.get_conventional_standard_structure(),
                sym_finder.get_symmetry_dataset(),
                sym_finder.get_symmetry_operations()
            ]
            return [sym_finder.get_primitive_standard_structure(), info]
        else:
            return sym_finder.get_primitive_standard_structure()
예제 #7
0
    def get_structure(vasp_run, outcar=None, initial_structure=False,
                      additional_info=False):
        """
        Process structure for static calculations from previous run.

        Args:
            vasp_run:
                Vasprun object that contains the final structure from previous
                run.
            outcar:
                Outcar object that contains the magnetization info from
                previous run.
            initial_structure:
                Whether to return the structure from previous run. Default is
                False.
            additional_info:
                Whether to return additional symmetry info related to the
                structure. If True, return a list of the refined structure (
                conventional cell), the conventional standard structure,
                the symmetry dataset and symmetry operations of the structure
                (see SymmetryFinder doc for details)

        Returns:
            Returns the magmom-decorated structure that can be passed to get
            Vasp input files, e.g. get_kpoints.
        """
        #TODO: fix magmom for get_*_structures
        if vasp_run.is_spin:
            if outcar and outcar.magnetization:
                magmom = {"magmom": [i['tot'] for i in outcar.magnetization]}
            else:
                magmom = {
                    "magmom": vasp_run.to_dict['input']['parameters']
                    ['MAGMOM']}
        else:
            magmom = None
        structure = vasp_run.final_structure
        if magmom:
            structure = structure.copy(site_properties=magmom)
        sym_finder = SymmetryFinder(structure, symprec=0.01)
        if initial_structure:
            return structure
        elif additional_info:
            info = [sym_finder.get_refined_structure(),
                    sym_finder.get_conventional_standard_structure(),
                    sym_finder.get_symmetry_dataset(),
                    sym_finder.get_symmetry_operations()]
            return [sym_finder.get_primitive_standard_structure(),
                    info]
        else:
            return sym_finder.get_primitive_standard_structure()
예제 #8
0
 def _make_struc_file(self, file_name):
     sym = SymmetryFinder(self._bs._structure, symprec=0.01)
     with open(file_name, "w") as f:
         f.write(self._bs._structure.composition.formula + " " + str(sym.get_spacegroup_symbol()) + "\n")
         for i in range(3):
             line = ""
             for j in range(3):
                 line += "%12.5f" % (Length(self._bs._structure.lattice.matrix[i][j], "ang").to("bohr"))
             f.write(line + "\n")
         ops = sym.get_symmetry_dataset()["rotations"]
         f.write(str(len(ops)) + "\n")
         for c in ops:
             f.write("\n".join([" ".join([str(int(i)) for i in row]) for row in c]))
             f.write("\n")
예제 #9
0
def parse_symmetry(args):

    tolerance = float(args.tolerance[0])

    for filename in args.filenames:
        s = read_structure(filename)
        if args.spacegroup:
            finder = SymmetryFinder(s, tolerance)
            dataset = finder.get_symmetry_dataset()
            print filename
            print "Spacegroup  : {}".format(dataset["international"])
            print "Int number  : {}".format(dataset["number"])
            print "Hall symbol : {}".format(dataset["hall"])
            print
예제 #10
0
def parse_symmetry(args):

    tolerance = float(args.tolerance[0])

    for filename in args.filenames:
        s = read_structure(filename)
        if args.spacegroup:
            finder = SymmetryFinder(s, tolerance)
            dataset = finder.get_symmetry_dataset()
            print filename
            print "Spacegroup  : {}".format(dataset["international"])
            print "Int number  : {}".format(dataset["number"])
            print "Hall symbol : {}".format(dataset["hall"])
            print
예제 #11
0
 def _make_struc_file(self, file_name):
     sym = SymmetryFinder(self._bs._structure, symprec=0.01)
     with open(file_name, 'w') as f:
         f.write(self._bs._structure.composition.formula+" " +
                 str(sym.get_spacegroup_symbol())+"\n")
         for i in range(3):
             line = ''
             for j in range(3):
                 line += "%12.5f" % (
                     Length(self._bs._structure.lattice.matrix[i][j],
                            "ang").to("bohr"))
             f.write(line+'\n')
         ops = sym.get_symmetry_dataset()['rotations']
         f.write(str(len(ops))+"\n")
         for c in ops:
             f.write('\n'.join([' '.join([str(int(i)) for i in row])
                                for row in c]))
             f.write('\n')
예제 #12
0
 def __init__(self, struct, source='', comment=''):
     if struct.is_ordered:
         self._struct = struct
         self._source = source
         self._site_symbols = []
         self._natoms = []
         sym = SymmetryFinder(struct)
         data = sym.get_symmetry_dataset()
         self._space_number = data["number"]
         self._space_group = data["international"]
         syms = [site.specie.symbol for site in struct]
         for (s, data) in itertools.groupby(syms):
             self._site_symbols.append(s)
             self._natoms.append(len(tuple(data)))
         if comment == '':
             self._comment = 'None Given'
         else:
             self._comment = comment
     else:
         raise ValueError("Structure with partial occupancies cannot be "
                          "converted into atomic coordinates!")
예제 #13
0
 def __init__(self, struct, source='', comment=''):
     if struct.is_ordered:
         self._struct = struct
         self._source = source
         self._site_symbols = []
         self._natoms = []
         sym = SymmetryFinder(struct)
         data = sym.get_symmetry_dataset()
         self._space_number = data["number"]
         self._space_group = data["international"]
         syms = [site.specie.symbol for site in struct]
         for (s, data) in itertools.groupby(syms):
             self._site_symbols.append(s)
             self._natoms.append(len(tuple(data)))
         if comment == '':
             self._comment = 'None Given'
         else:
             self._comment = comment
     else:
         raise ValueError("Structure with partial occupancies cannot be "
                          "converted into atomic coordinates!")
예제 #14
0
파일: cif2spg.py 프로젝트: GkAntonius/abipy
def main():
    parser = argparse.ArgumentParser(epilog=str_examples(), formatter_class=argparse.RawDescriptionHelpFormatter)

    parser.add_argument('cif_file', nargs=1, help="CIF File")

    parser.add_argument('-g', '--gui', action="store_true", help="Enable GUI")

    # Parse command line.
    try:
        options = parser.parse_args()
    except: 
        show_examples_and_exit(error_code=1)

    cif_file = options.cif_file[0]
    structure = abilab.Structure.from_file(cif_file)
    #print(structure.to_abivars())

    finder = SymmetryFinder(structure, symprec=1e-5, angle_tolerance=5)

    data = finder.get_symmetry_dataset()
    from pprint import pprint

    if not options.gui:
        pprint(data)

    else:
        from StringIO import StringIO
        import wx
        from abipy.gui.editor import SimpleTextViewer

        stream = StringIO()
        pprint(data, stream=stream)
        stream.seek(0)
        text = "".join(stream)
        app = wx.App()
        frame = SimpleTextViewer(None, text=text)
        frame.Show()
        app.MainLoop()

    return 0
예제 #15
0
 def __init__(self, struct, comment=None):
     """
     Args:
         struct:
             Structure object, See pymatgen.core.structure.Structure.
         comment:
             comment for first header line
     """
     if struct.is_ordered:
         self._struct = struct
         self._site_symbols = []
         self._natoms = []
         sym = SymmetryFinder(struct)
         data = sym.get_symmetry_dataset()
         self._space_number = data["number"]
         self._space_group = data["international"]
         syms = [site.specie.symbol for site in struct]
         for (s, data) in itertools.groupby(syms):
             self._site_symbols.append(s)
             self._natoms.append(len(tuple(data)))
         self._comment = comment
     else:
         raise ValueError("Structure with partial occupancies cannot be "
                          "converted into atomic coordinates!")
예제 #16
0
class SymmetryFinderTest(unittest.TestCase):

    def setUp(self):
        p = Poscar.from_file(os.path.join(test_dir, 'POSCAR'))
        self.structure = p.structure
        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.structure.copy()
        site = s[0]
        del s[0]
        s.append(site.species_and_occu, site.frac_coords)
        self.sg3 = SymmetryFinder(s, 0.001)
        parser = CifParser(os.path.join(test_dir, 'Graphite.cif'))
        graphite = parser.get_structures()[0]
        graphite.add_site_property("magmom", [0.1] * len(graphite))
        self.sg4 = SymmetryFinder(graphite, 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")
        self.assertEqual(self.sg4.get_spacegroup_symbol(), "R-3m")

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

    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_point_group(), 'mmm')
        self.assertEqual(self.disordered_sg.get_point_group(), '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)
        parser = CifParser(os.path.join(test_dir, 'Li2O.cif'))
        s = parser.get_structures()[0]
        sg = SymmetryFinder(s, 0.001)
        self.assertEqual(sg.get_refined_structure().num_sites, 4 * s.num_sites)

    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)
        self.assertEqual(map(len, symm_struct.equivalent_sites), [16,4,8,4,2,8,8,8])
        s1 = symm_struct.equivalent_sites[1][1]
        s2 = symm_struct[symm_struct.equivalent_indices[1][1]]
        self.assertEqual(s1, s2)
        self.assertEqual(self.sg4.get_symmetrized_structure()[0].magmom, 0.1)

    def test_find_primitive(self):
        """
        F m -3 m Li2O testing of converting to primitive cell
        """
        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, 60)
        self.assertAlmostEqual(primitive_structure.lattice.beta, 60)
        self.assertAlmostEqual(primitive_structure.lattice.gamma, 60)
        self.assertAlmostEqual(primitive_structure.lattice.volume,
                               structure.lattice.volume / 4.0)

    def test_get_ir_reciprocal_mesh(self):
        grid=self.sg.get_ir_reciprocal_mesh()
        self.assertEquals(len(grid), 216)
        self.assertAlmostEquals(grid[1][0][0], 0.1)
        self.assertAlmostEquals(grid[1][0][1], 0.0)
        self.assertAlmostEquals(grid[1][0][2], 0.0)
        self.assertEquals(grid[1][1], 2)

    def test_get_conventional_standard_structure(self):
        parser = CifParser(os.path.join(test_dir, 'bcc_1927.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        conv = s.get_conventional_standard_structure()
        self.assertAlmostEqual(conv.lattice.alpha, 90)
        self.assertAlmostEqual(conv.lattice.beta, 90)
        self.assertAlmostEqual(conv.lattice.gamma, 90)
        self.assertAlmostEqual(conv.lattice.a, 9.1980270633769461)
        self.assertAlmostEqual(conv.lattice.b, 9.1980270633769461)
        self.assertAlmostEqual(conv.lattice.c, 9.1980270633769461)

        parser = CifParser(os.path.join(test_dir, 'btet_1915.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        conv = s.get_conventional_standard_structure()
        self.assertAlmostEqual(conv.lattice.alpha, 90)
        self.assertAlmostEqual(conv.lattice.beta, 90)
        self.assertAlmostEqual(conv.lattice.gamma, 90)
        self.assertAlmostEqual(conv.lattice.a, 5.0615106678044235)
        self.assertAlmostEqual(conv.lattice.b, 5.0615106678044235)
        self.assertAlmostEqual(conv.lattice.c, 4.2327080177761687)

        parser = CifParser(os.path.join(test_dir, 'orci_1010.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        conv = s.get_conventional_standard_structure()
        self.assertAlmostEqual(conv.lattice.alpha, 90)
        self.assertAlmostEqual(conv.lattice.beta, 90)
        self.assertAlmostEqual(conv.lattice.gamma, 90)
        self.assertAlmostEqual(conv.lattice.a, 2.9542233922299999)
        self.assertAlmostEqual(conv.lattice.b, 4.6330325651443296)
        self.assertAlmostEqual(conv.lattice.c, 5.373703587040775)

        parser = CifParser(os.path.join(test_dir, 'orcc_1003.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        conv = s.get_conventional_standard_structure()
        self.assertAlmostEqual(conv.lattice.alpha, 90)
        self.assertAlmostEqual(conv.lattice.beta, 90)
        self.assertAlmostEqual(conv.lattice.gamma, 90)
        self.assertAlmostEqual(conv.lattice.a, 4.1430033493799998)
        self.assertAlmostEqual(conv.lattice.b, 31.437979757624728)
        self.assertAlmostEqual(conv.lattice.c, 3.99648651)

        parser = CifParser(os.path.join(test_dir, 'monoc_1028.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        conv = s.get_conventional_standard_structure()
        self.assertAlmostEqual(conv.lattice.alpha, 90)
        self.assertAlmostEqual(conv.lattice.beta, 117.53832420192903)
        self.assertAlmostEqual(conv.lattice.gamma, 90)
        self.assertAlmostEqual(conv.lattice.a, 14.033435583000625)
        self.assertAlmostEqual(conv.lattice.b, 3.96052850731)
        self.assertAlmostEqual(conv.lattice.c, 6.8743926325200002)

        parser = CifParser(os.path.join(test_dir, 'rhomb_1170.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        conv = s.get_conventional_standard_structure()
        self.assertAlmostEqual(conv.lattice.alpha, 90)
        self.assertAlmostEqual(conv.lattice.beta, 90)
        self.assertAlmostEqual(conv.lattice.gamma, 120)
        self.assertAlmostEqual(conv.lattice.a, 3.699919902005897)
        self.assertAlmostEqual(conv.lattice.b, 3.699919902005897)
        self.assertAlmostEqual(conv.lattice.c, 6.9779585500000003)

    def test_get_primitive_standard_structure(self):
        parser = CifParser(os.path.join(test_dir, 'bcc_1927.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        prim = s.get_primitive_standard_structure()
        self.assertAlmostEqual(prim.lattice.alpha, 109.47122063400001)
        self.assertAlmostEqual(prim.lattice.beta, 109.47122063400001)
        self.assertAlmostEqual(prim.lattice.gamma, 109.47122063400001)
        self.assertAlmostEqual(prim.lattice.a, 7.9657251015812145)
        self.assertAlmostEqual(prim.lattice.b, 7.9657251015812145)
        self.assertAlmostEqual(prim.lattice.c, 7.9657251015812145)

        parser = CifParser(os.path.join(test_dir, 'btet_1915.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        prim = s.get_primitive_standard_structure()
        self.assertAlmostEqual(prim.lattice.alpha, 105.015053349)
        self.assertAlmostEqual(prim.lattice.beta, 105.015053349)
        self.assertAlmostEqual(prim.lattice.gamma, 118.80658411899999)
        self.assertAlmostEqual(prim.lattice.a, 4.1579321075608791)
        self.assertAlmostEqual(prim.lattice.b, 4.1579321075608791)
        self.assertAlmostEqual(prim.lattice.c, 4.1579321075608791)

        parser = CifParser(os.path.join(test_dir, 'orci_1010.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        prim = s.get_primitive_standard_structure()
        self.assertAlmostEqual(prim.lattice.alpha, 134.78923546600001)
        self.assertAlmostEqual(prim.lattice.beta, 105.856239333)
        self.assertAlmostEqual(prim.lattice.gamma, 91.276341676000001)
        self.assertAlmostEqual(prim.lattice.a, 3.8428217771014852)
        self.assertAlmostEqual(prim.lattice.b, 3.8428217771014852)
        self.assertAlmostEqual(prim.lattice.c, 3.8428217771014852)

        parser = CifParser(os.path.join(test_dir, 'orcc_1003.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        prim = s.get_primitive_standard_structure()
        self.assertAlmostEqual(prim.lattice.alpha, 90)
        self.assertAlmostEqual(prim.lattice.beta, 90)
        self.assertAlmostEqual(prim.lattice.gamma, 164.985257335)
        self.assertAlmostEqual(prim.lattice.a, 15.854897098324196)
        self.assertAlmostEqual(prim.lattice.b, 15.854897098324196)
        self.assertAlmostEqual(prim.lattice.c, 3.99648651)

        parser = CifParser(os.path.join(test_dir, 'monoc_1028.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        prim = s.get_primitive_standard_structure()
        self.assertAlmostEqual(prim.lattice.alpha, 63.579155761999999)
        self.assertAlmostEqual(prim.lattice.beta, 116.42084423747779)
        self.assertAlmostEqual(prim.lattice.gamma, 148.47965136208569)
        self.assertAlmostEqual(prim.lattice.a, 7.2908007159612325)
        self.assertAlmostEqual(prim.lattice.b, 7.2908007159612325)
        self.assertAlmostEqual(prim.lattice.c, 6.8743926325200002)

        parser = CifParser(os.path.join(test_dir, 'rhomb_1170.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        prim = s.get_primitive_standard_structure()
        self.assertAlmostEqual(prim.lattice.alpha, 90)
        self.assertAlmostEqual(prim.lattice.beta, 90)
        self.assertAlmostEqual(prim.lattice.gamma, 120)
        self.assertAlmostEqual(prim.lattice.a, 3.699919902005897)
        self.assertAlmostEqual(prim.lattice.b, 3.699919902005897)
        self.assertAlmostEqual(prim.lattice.c, 6.9779585500000003)
예제 #17
0
class SymmetryFinderTest(unittest.TestCase):
    def setUp(self):
        p = Poscar.from_file(os.path.join(test_dir, 'POSCAR'))
        self.structure = p.structure
        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.structure.copy()
        site = s[0]
        del s[0]
        s.append(site.species_and_occu, site.frac_coords)
        self.sg3 = SymmetryFinder(s, 0.001)
        parser = CifParser(os.path.join(test_dir, 'Graphite.cif'))
        graphite = parser.get_structures()[0]
        graphite.add_site_property("magmom", [0.1] * len(graphite))
        self.sg4 = SymmetryFinder(graphite, 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")
        self.assertEqual(self.sg4.get_spacegroup_symbol(), "R-3m")

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

    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_point_group(), 'mmm')
        self.assertEqual(self.disordered_sg.get_point_group(), '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)
        parser = CifParser(os.path.join(test_dir, 'Li2O.cif'))
        s = parser.get_structures()[0]
        sg = SymmetryFinder(s, 0.001)
        self.assertEqual(sg.get_refined_structure().num_sites, 4 * s.num_sites)

    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)
        self.assertEqual(map(len, symm_struct.equivalent_sites),
                         [16, 4, 8, 4, 2, 8, 8, 8])
        s1 = symm_struct.equivalent_sites[1][1]
        s2 = symm_struct[symm_struct.equivalent_indices[1][1]]
        self.assertEqual(s1, s2)
        self.assertEqual(self.sg4.get_symmetrized_structure()[0].magmom, 0.1)

    def test_find_primitive(self):
        """
        F m -3 m Li2O testing of converting to primitive cell
        """
        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, 60)
        self.assertAlmostEqual(primitive_structure.lattice.beta, 60)
        self.assertAlmostEqual(primitive_structure.lattice.gamma, 60)
        self.assertAlmostEqual(primitive_structure.lattice.volume,
                               structure.lattice.volume / 4.0)

    def test_get_ir_reciprocal_mesh(self):
        grid = self.sg.get_ir_reciprocal_mesh()
        self.assertEquals(len(grid), 216)
        self.assertAlmostEquals(grid[1][0][0], 0.1)
        self.assertAlmostEquals(grid[1][0][1], 0.0)
        self.assertAlmostEquals(grid[1][0][2], 0.0)
        self.assertEquals(grid[1][1], 2)

    def test_get_conventional_standard_structure(self):
        parser = CifParser(os.path.join(test_dir, 'bcc_1927.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        conv = s.get_conventional_standard_structure()
        self.assertAlmostEqual(conv.lattice.alpha, 90)
        self.assertAlmostEqual(conv.lattice.beta, 90)
        self.assertAlmostEqual(conv.lattice.gamma, 90)
        self.assertAlmostEqual(conv.lattice.a, 9.1980270633769461)
        self.assertAlmostEqual(conv.lattice.b, 9.1980270633769461)
        self.assertAlmostEqual(conv.lattice.c, 9.1980270633769461)

        parser = CifParser(os.path.join(test_dir, 'btet_1915.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        conv = s.get_conventional_standard_structure()
        self.assertAlmostEqual(conv.lattice.alpha, 90)
        self.assertAlmostEqual(conv.lattice.beta, 90)
        self.assertAlmostEqual(conv.lattice.gamma, 90)
        self.assertAlmostEqual(conv.lattice.a, 5.0615106678044235)
        self.assertAlmostEqual(conv.lattice.b, 5.0615106678044235)
        self.assertAlmostEqual(conv.lattice.c, 4.2327080177761687)

        parser = CifParser(os.path.join(test_dir, 'orci_1010.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        conv = s.get_conventional_standard_structure()
        self.assertAlmostEqual(conv.lattice.alpha, 90)
        self.assertAlmostEqual(conv.lattice.beta, 90)
        self.assertAlmostEqual(conv.lattice.gamma, 90)
        self.assertAlmostEqual(conv.lattice.a, 2.9542233922299999)
        self.assertAlmostEqual(conv.lattice.b, 4.6330325651443296)
        self.assertAlmostEqual(conv.lattice.c, 5.373703587040775)

        parser = CifParser(os.path.join(test_dir, 'orcc_1003.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        conv = s.get_conventional_standard_structure()
        self.assertAlmostEqual(conv.lattice.alpha, 90)
        self.assertAlmostEqual(conv.lattice.beta, 90)
        self.assertAlmostEqual(conv.lattice.gamma, 90)
        self.assertAlmostEqual(conv.lattice.a, 4.1430033493799998)
        self.assertAlmostEqual(conv.lattice.b, 31.437979757624728)
        self.assertAlmostEqual(conv.lattice.c, 3.99648651)

        parser = CifParser(os.path.join(test_dir, 'monoc_1028.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        conv = s.get_conventional_standard_structure()
        self.assertAlmostEqual(conv.lattice.alpha, 90)
        self.assertAlmostEqual(conv.lattice.beta, 117.53832420192903)
        self.assertAlmostEqual(conv.lattice.gamma, 90)
        self.assertAlmostEqual(conv.lattice.a, 14.033435583000625)
        self.assertAlmostEqual(conv.lattice.b, 3.96052850731)
        self.assertAlmostEqual(conv.lattice.c, 6.8743926325200002)

        parser = CifParser(os.path.join(test_dir, 'rhomb_1170.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        conv = s.get_conventional_standard_structure()
        self.assertAlmostEqual(conv.lattice.alpha, 90)
        self.assertAlmostEqual(conv.lattice.beta, 90)
        self.assertAlmostEqual(conv.lattice.gamma, 120)
        self.assertAlmostEqual(conv.lattice.a, 3.699919902005897)
        self.assertAlmostEqual(conv.lattice.b, 3.699919902005897)
        self.assertAlmostEqual(conv.lattice.c, 6.9779585500000003)

    def test_get_primitive_standard_structure(self):
        parser = CifParser(os.path.join(test_dir, 'bcc_1927.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        prim = s.get_primitive_standard_structure()
        self.assertAlmostEqual(prim.lattice.alpha, 109.47122063400001)
        self.assertAlmostEqual(prim.lattice.beta, 109.47122063400001)
        self.assertAlmostEqual(prim.lattice.gamma, 109.47122063400001)
        self.assertAlmostEqual(prim.lattice.a, 7.9657251015812145)
        self.assertAlmostEqual(prim.lattice.b, 7.9657251015812145)
        self.assertAlmostEqual(prim.lattice.c, 7.9657251015812145)

        parser = CifParser(os.path.join(test_dir, 'btet_1915.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        prim = s.get_primitive_standard_structure()
        self.assertAlmostEqual(prim.lattice.alpha, 105.015053349)
        self.assertAlmostEqual(prim.lattice.beta, 105.015053349)
        self.assertAlmostEqual(prim.lattice.gamma, 118.80658411899999)
        self.assertAlmostEqual(prim.lattice.a, 4.1579321075608791)
        self.assertAlmostEqual(prim.lattice.b, 4.1579321075608791)
        self.assertAlmostEqual(prim.lattice.c, 4.1579321075608791)

        parser = CifParser(os.path.join(test_dir, 'orci_1010.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        prim = s.get_primitive_standard_structure()
        self.assertAlmostEqual(prim.lattice.alpha, 134.78923546600001)
        self.assertAlmostEqual(prim.lattice.beta, 105.856239333)
        self.assertAlmostEqual(prim.lattice.gamma, 91.276341676000001)
        self.assertAlmostEqual(prim.lattice.a, 3.8428217771014852)
        self.assertAlmostEqual(prim.lattice.b, 3.8428217771014852)
        self.assertAlmostEqual(prim.lattice.c, 3.8428217771014852)

        parser = CifParser(os.path.join(test_dir, 'orcc_1003.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        prim = s.get_primitive_standard_structure()
        self.assertAlmostEqual(prim.lattice.alpha, 90)
        self.assertAlmostEqual(prim.lattice.beta, 90)
        self.assertAlmostEqual(prim.lattice.gamma, 164.985257335)
        self.assertAlmostEqual(prim.lattice.a, 15.854897098324196)
        self.assertAlmostEqual(prim.lattice.b, 15.854897098324196)
        self.assertAlmostEqual(prim.lattice.c, 3.99648651)

        parser = CifParser(os.path.join(test_dir, 'monoc_1028.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        prim = s.get_primitive_standard_structure()
        self.assertAlmostEqual(prim.lattice.alpha, 63.579155761999999)
        self.assertAlmostEqual(prim.lattice.beta, 116.42084423747779)
        self.assertAlmostEqual(prim.lattice.gamma, 148.47965136208569)
        self.assertAlmostEqual(prim.lattice.a, 7.2908007159612325)
        self.assertAlmostEqual(prim.lattice.b, 7.2908007159612325)
        self.assertAlmostEqual(prim.lattice.c, 6.8743926325200002)

        parser = CifParser(os.path.join(test_dir, 'rhomb_1170.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        prim = s.get_primitive_standard_structure()
        self.assertAlmostEqual(prim.lattice.alpha, 90)
        self.assertAlmostEqual(prim.lattice.beta, 90)
        self.assertAlmostEqual(prim.lattice.gamma, 120)
        self.assertAlmostEqual(prim.lattice.a, 3.699919902005897)
        self.assertAlmostEqual(prim.lattice.b, 3.699919902005897)
        self.assertAlmostEqual(prim.lattice.c, 6.9779585500000003)