Ejemplo n.º 1
0
    def test_thcl4(self):
        filename = "../poscars/POSCAR_ThCl4"

        atoms = read_vasp(filename)
        symmetry = UnfolderSymmetry(atoms)  # 88

        rotations = symmetry.get_pointgroup_operations()
        self.check_irreps(rotations, '4/m')
Ejemplo n.º 2
0
    def test_b_h(self):
        filename = "tests/poscars/POSCAR_WC"

        atoms = read_vasp(filename)
        symmetry = UnfolderSymmetry(atoms)

        rotations = symmetry.get_pointgroup_operations()
        self.check_irreps(rotations, '-6m2')
Ejemplo n.º 3
0
    def test_97(self):
        filename = "../poscars/POSCAR_NaGdCu2F8"

        atoms = read_vasp(filename)
        symmetry = UnfolderSymmetry(atoms)

        rotations = symmetry.get_pointgroup_operations()
        self.check_irreps(rotations, '422')
Ejemplo n.º 4
0
    def test_cl12pd6(self):
        filename = "../poscars/POSCAR_Cl12Pd6"

        atoms = read_vasp(filename)
        symmetry = UnfolderSymmetry(atoms)  # 148

        rotations = symmetry.get_pointgroup_operations()
        self.check_irreps(rotations, '-3')
Ejemplo n.º 5
0
    def __init__(self, atoms):
        """
        Decomposer of vectors according to rotations

        Parameters
        ----------
            atoms : Phonopy Atoms object.
        """
        self._atoms = atoms
        self._symmetry = UnfolderSymmetry(atoms)
Ejemplo n.º 6
0
    def test_a3(self):
        filename = "tests/poscars/POSCAR_A3"

        atoms = read_vasp(filename)
        symmetry = UnfolderSymmetry(atoms)

        rotations = symmetry.get_pointgroup_operations()
        self.check_irreps(rotations, '6/mmm')

        p = [0.0, 0.0, 0.5]  # A (6/mmm)
        rotations = symmetry.get_group_of_wave_vector(p)[0]
        self.check_irreps(rotations, '6/mmm')

        p = [1.0 / 3.0, 1.0 / 3.0, 0.0]  # K (-6m2)
        rotations = symmetry.get_group_of_wave_vector(p)[0]
        self.check_irreps(rotations, '-6m2')

        p = [0.5, 0.0, 0.0]  # M (mmm)
        rotations = symmetry.get_group_of_wave_vector(p)[0]
        self.check_irreps(rotations, 'mmm')

        p = [0.5, 0.0, 0.5]  # L (mmm)
        rotations = symmetry.get_group_of_wave_vector(p)[0]
        self.check_irreps(rotations, 'mmm')

        p = [0.0, 0.0, 0.25]  # DT (6mm)
        rotations = symmetry.get_group_of_wave_vector(p)[0]
        self.check_irreps(rotations, '6mm')

        p = [1.0 / 3.0, 1.0 / 3.0, 0.25]  # P (3m)
        rotations = symmetry.get_group_of_wave_vector(p)[0]
        self.check_irreps(rotations, '3m')
Ejemplo n.º 7
0
    def test_sc(self):
        filename = "../poscars/POSCAR_Sc"

        atoms = read_vasp(filename)
        symmetry = UnfolderSymmetry(atoms)  # 178

        rotations = symmetry.get_pointgroup_operations()
        self.check_irreps(rotations, '622')

        p = [1.0 / 3.0, 1.0 / 3.0, 0.0]  # K (32)
        rotations = symmetry.get_group_of_wave_vector(p)[0]
        self.check_irreps(rotations, '32')
Ejemplo n.º 8
0
    def test_a13(self):
        filename = "../poscars/POSCAR_A13"

        atoms = read_vasp(filename)
        symmetry = UnfolderSymmetry(atoms)  # 213

        rotations = symmetry.get_pointgroup_operations()
        self.check_irreps(rotations, '432')

        p = [0.0, 0.5, 0.5]  # X (422)
        rotations = symmetry.get_group_of_wave_vector(p)[0]
        self.check_irreps(rotations, '422')
Ejemplo n.º 9
0
    def test_b3(self):
        filename = "../poscars/POSCAR_B3_conv"

        atoms = read_vasp(filename)
        symmetry = UnfolderSymmetry(atoms)  # 216

        rotations = symmetry.get_pointgroup_operations()
        self.check_irreps(rotations, '-43m')

        p = [0.0, 0.5, 0.5]  # X (-42m)
        rotations = symmetry.get_group_of_wave_vector(p)[0]
        self.check_irreps(rotations, '-42m')
Ejemplo n.º 10
0
    def test_a3(self):
        filename = "../poscars/POSCAR_A3"

        atoms = read_vasp(filename)
        symmetry = UnfolderSymmetry(atoms)

        rotations = symmetry.get_pointgroup_operations()
        self.check_irreps(rotations, '6/mmm')

        p = [0.0, 0.0, 0.5]  # A (6/mmm)
        rotations = symmetry.get_group_of_wave_vector(p)[0]
        self.check_irreps(rotations, '6/mmm')

        p = [1.0 / 3.0, 1.0 / 3.0, 0.0]  # K (-6m2)
        rotations = symmetry.get_group_of_wave_vector(p)[0]
        self.check_irreps(rotations, '-6m2')

        p = [0.5, 0.0, 0.0]  # M (mmm)
        rotations = symmetry.get_group_of_wave_vector(p)[0]
        self.check_irreps(rotations, 'mmm')

        p = [0.5, 0.0, 0.5]  # L (mmm)
        rotations = symmetry.get_group_of_wave_vector(p)[0]
        self.check_irreps(rotations, 'mmm')

        p = [0.0, 0.0, 0.25]  # DT (6mm)
        rotations = symmetry.get_group_of_wave_vector(p)[0]
        self.check_irreps(rotations, '6mm')
Ejemplo n.º 11
0
    def test_fcc_prim(self):
        filename = "../poscars/POSCAR_fcc_prim"

        atoms = read_vasp(filename)
        symmetry = UnfolderSymmetry(atoms)

        rotations = symmetry.get_pointgroup_operations()
        check_irreps(rotations)

        rotations = symmetry.get_group_of_wave_vector([0.00, 0.25, -0.25])[0]
        check_irreps(rotations)

        rotations = symmetry.get_group_of_wave_vector([0.50, 0.25, 0.25])[0]
        check_irreps(rotations)

        rotations = symmetry.get_group_of_wave_vector([0.25, 0.50, 0.25])[0]
        check_irreps(rotations)

        rotations = symmetry.get_group_of_wave_vector([0.25, 0.25, 0.50])[0]
        check_irreps(rotations)
Ejemplo n.º 12
0
    def test_fcc_conv(self):
        filename = "../poscars/POSCAR_fcc"

        atoms = read_vasp(filename)
        symmetry = UnfolderSymmetry(atoms)

        rotations = symmetry.get_pointgroup_operations()
        self.check_irreps(rotations, 'm-3m')

        rotations = symmetry.get_group_of_wave_vector([0.00, 0.25, 0.25])[0]
        self.check_irreps(rotations, 'mm2')

        rotations = symmetry.get_group_of_wave_vector([0.25, 0.00, 0.25])[0]
        self.check_irreps(rotations, 'mm2')

        rotations = symmetry.get_group_of_wave_vector([0.25, 0.25, 0.00])[0]
        self.check_irreps(rotations, 'mm2')
Ejemplo n.º 13
0
    def test_fcc_conv(self):
        # np.set_printoptions(threshold=2304, linewidth=145)  # 48 * 48
        filename = "../poscars/POSCAR_fcc"

        atoms = read_vasp(filename)
        symmetry = UnfolderSymmetry(atoms)

        rotations = symmetry.get_pointgroup_operations()
        check_irreps(rotations)

        rotations = symmetry.get_group_of_wave_vector([0.00, 0.25, 0.25])[0]
        check_irreps(rotations)

        rotations = symmetry.get_group_of_wave_vector([0.25, 0.00, 0.25])[0]
        check_irreps(rotations)

        rotations = symmetry.get_group_of_wave_vector([0.25, 0.25, 0.00])[0]
        check_irreps(rotations)
Ejemplo n.º 14
0
    def test_mgnh(self):
        filename = "../poscars/POSCAR_MgNH"

        atoms = read_vasp(filename)
        symmetry = UnfolderSymmetry(atoms)  # 216

        rotations = symmetry.get_pointgroup_operations()
        self.check_irreps(rotations, '6/m')

        p = [1.0 / 3.0, 1.0 / 3.0, 0.0]  # K (-6)
        rotations = symmetry.get_group_of_wave_vector(p)[0]
        self.check_irreps(rotations, '-6')

        p = [0.0, 0.0, 0.25]  # DT (6)
        rotations = symmetry.get_group_of_wave_vector(p)[0]
        self.check_irreps(rotations, '6')

        p = [1.0 / 3.0, 1.0 / 3.0, 0.25]  # P (3)
        rotations = symmetry.get_group_of_wave_vector(p)[0]
        self.check_irreps(rotations, '3')
Ejemplo n.º 15
0
class RotationalProjector(object):
    def __init__(self, atoms):
        """
        Decomposer of vectors according to rotations

        Parameters
        ----------
            atoms : Phonopy Atoms object.
        """
        self._atoms = atoms
        self._symmetry = UnfolderSymmetry(atoms)

    def create_standard_rotations(self, kpoint):
        """
        Create standard rotations for IR labels

        Parameters
        ----------
        kpoint : 1d array
            Reciprocal space point in fractional coordinates for PC.
            This is the representative of the star.
            IR labels are determined using this.

        TODO
        ----
        To be modified for nonsymmorphic space groups.
        """
        symmetry = self._symmetry
        rotations, translations = symmetry.get_group_of_wave_vector(kpoint)
        self._create_irreps(rotations)
        self._standard_rotations = rotations

        # self.print_symmetry_operations(rotations, translations)

    @staticmethod
    def calculate_factor_system(rotations, translations, kpoint):
        """Calculate factor system

        Here the factor system is defined as

        .. math::
            e^{-i (\mathbf{R}_i^T \mathbf{k} - \mathbf{k}) \cdot \mathbf{w}_j,

        """
        nsyms = len(rotations)
        factor_system = np.zeros((nsyms, nsyms), dtype=complex)
        for i, rotation in enumerate(rotations):
            for j, translation in enumerate(translations):
                kdiff = np.dot(rotation.T, kpoint) - kpoint
                factor_system[i, j] = np.exp(-2.0j * np.pi *
                                             np.dot(kdiff, translation))
        return factor_system

    @staticmethod
    def print_factor_system(factor_system):
        nsyms = factor_system.shape[0]
        print('Factor system:')
        for i in range(nsyms):
            for j in range(nsyms):
                v = factor_system[i, j]
                print('({:10.6f}{:+10.6f}i) '.format(v.real, v.imag), end='')
            print()

    @staticmethod
    def is_trivial_factor_system(factor_system, prec=1e-6):
        if np.any(np.abs(factor_system - 1.0) > prec):
            return False
        return True

    @staticmethod
    def print_symmetry_operations(rotations, translations):
        print('Symmetry operations:')
        for r, t in zip(rotations, translations):
            for i in range(3):
                for j in range(3):
                    print('{:10.6f}'.format(r[i, j]), end='')
                print('  {:10.6f}'.format(t[i]))
            print()

    def _assign_characters_to_rotations(self, rotations, arm_transformation):
        irreps = self._irreps

        rotation_labels = self._assign_class_labels_to_rotations(
            rotations, arm_transformation)
        characters = irreps.assign_characters_to_rotations(rotation_labels)

        return characters

    def _assign_class_labels_to_rotations(self, rotations, arm_transformation):
        standard_rotation_labels = self._standard_rotation_labels

        modulated_standard_rotations = (
            self._modulate_standard_rotations(arm_transformation))

        rotation_labels = []
        for r in rotations:
            for i, sr in enumerate(modulated_standard_rotations):
                if np.all(r == sr):
                    rotation_labels.append(standard_rotation_labels[i])
                    break

        if len(rotation_labels) != len(standard_rotation_labels):
            raise ValueError("Rotation labels cannot be correctly assigned.")

        return rotation_labels

    def _modulate_standard_rotations(self, arm_transformation):
        standard_rotations = self._standard_rotations

        modulated_standard_rotations = np.zeros_like(standard_rotations)
        for i, r in enumerate(standard_rotations):
            modulated_standard_rotations[i] = (np.dot(
                np.dot(np.linalg.inv(arm_transformation), r),
                arm_transformation))

        return np.array(modulated_standard_rotations, dtype=int)

    def _create_mappings(self, rotations, translations):
        structure_analyzer = StructureAnalyzer(self._atoms)

        mappings = []
        for r, t in zip(rotations, translations):
            mapping = structure_analyzer.extract_mapping_for_symopr(r, t)
            mappings.append(mapping)
        self._mappings = np.array(mappings)
        self._mappings_modifier = MappingsModifier(mappings)

    def _invert_mappings(self):
        return self._mappings_modifier.invert_mappings()

    def _create_irreps(self, rotations):
        irreps = Irreps(rotations)
        character_table_data = irreps.get_character_table_data()

        self._ir_labels = character_table_data["ir_labels"]
        character_table = np.array(character_table_data["character_table"])
        self._ir_dimensions = character_table[:, 0]

        self._standard_rotation_labels = irreps.get_rotation_labels()

        self._irreps = irreps

    def _create_rotations_cart(self, rotations):
        rotations_cart = []
        cell = self._atoms.get_cell()
        for r in rotations:
            rotation_cart = np.dot(np.dot(cell.T, r), np.linalg.inv(cell.T))
            rotations_cart.append(rotation_cart)
        return np.array(rotations_cart)

    def project_vectors(self, vectors, kpoint, arm_transformation):
        """

        Parameters
        ----------
        vectors : Vectors without phase factors.
        kpoint : K point in fractional coordinates for SC.
        arm_transformation : 3 x 3 array
            Matrix to get "kpoint" from the representative of the star.

        TODO
        ----
        To be modified for nonsymmorphic space groups.
        """
        rotations, translations = self._symmetry.get_group_of_wave_vector(
            kpoint)

        factor_system = self.calculate_factor_system(rotations, translations,
                                                     kpoint)
        if not self.is_trivial_factor_system(factor_system):
            errmsg = (
                "The current factor system is not trivial.\n"
                "So far the code cannot treat nontrivial factor system correctly\n"
                "(even if it is p-equivalent to the trivial system).")
            raise ValueError(errmsg)

        self._create_mappings(rotations, translations)

        characters = self._assign_characters_to_rotations(
            rotations, arm_transformation)

        rotations_cart = self._create_rotations_cart(rotations)

        ir_dimensions = self._ir_dimensions

        natoms = self._atoms.get_number_of_atoms()
        ndim = kpoint.shape[0]  # The number of dimensions of space
        order = rotations.shape[0]

        expanded_mappings_inv = self._mappings_modifier.expand_mappings(
            ndim, is_inverse=True)

        # scaled_positions = self._atoms.get_scaled_positions()
        # phases = np.exp(2.0j * np.pi * np.dot(scaled_positions, kpoint))
        # phases = np.repeat(phases, ndim)

        shape = (len(ir_dimensions), ) + vectors.shape
        projected_vectors = np.zeros(shape, dtype=vectors.dtype)
        for i, (r, expanded_mapping_inv) in enumerate(
                zip(rotations_cart, expanded_mappings_inv)):
            tmp = vectors[..., expanded_mapping_inv, :]

            tmp2 = np.zeros_like(vectors)
            for iatom in range(natoms):
                tmp2[..., (3 * iatom):(3 * (iatom + 1)), :] = np.einsum(
                    'ij,...jk->...ik', r,
                    tmp[..., (3 * iatom):(3 * (iatom + 1)), :])

            projected_vectors += (tmp2[None].T * np.conj(characters[i, :])).T

        # projected_vectors *= phases[None, :, None]
        projected_vectors = (projected_vectors.T * ir_dimensions[:]).T
        projected_vectors /= order

        return projected_vectors

    def get_ir_labels(self):
        return self._ir_labels

    def get_num_irs(self):
        return len(self._ir_labels)

    def get_pointgroup_symbol(self):
        return self._irreps.get_pointgroup_symbol()
Ejemplo n.º 16
0
    def test_fcc_prim(self):
        filename = "../poscars/POSCAR_fcc_prim"

        atoms = read_vasp(filename)
        symmetry = UnfolderSymmetry(atoms)

        rotations = symmetry.get_pointgroup_operations()
        self.check_irreps(rotations, 'm-3m')

        rotations = symmetry.get_group_of_wave_vector([0.00, 0.25, -0.25])[0]
        self.check_irreps(rotations, 'mm2')

        p = [0.50, 0.25, 0.75]  # W (-42m)
        rotations = symmetry.get_group_of_wave_vector(p)[0]
        self.check_irreps(rotations, '-42m')

        rotations = symmetry.get_group_of_wave_vector([0.50, 0.25, 0.25])[0]
        self.check_irreps(rotations, 'mm2')

        rotations = symmetry.get_group_of_wave_vector([0.25, 0.50, 0.25])[0]
        self.check_irreps(rotations, 'mm2')

        rotations = symmetry.get_group_of_wave_vector([0.25, 0.25, 0.50])[0]
        self.check_irreps(rotations, 'mm2')

        p = [0.5, 0.3, 0.7]  # Q (2)
        rotations = symmetry.get_group_of_wave_vector(p)[0]
        self.check_irreps(rotations, '2')

        p = [0.4, 0.4, 0.1]  # C (m)
        rotations = symmetry.get_group_of_wave_vector(p)[0]
        self.check_irreps(rotations, 'm')

        p = [0.4, 0.2, 0.1]  # GP (1)
        rotations = symmetry.get_group_of_wave_vector(p)[0]
        self.check_irreps(rotations, '1')
Ejemplo n.º 17
0
class TestUnfolderSymmetry(unittest.TestCase):
    def setUp(self):
        atoms = read_vasp("POSCAR_sc")
        self._symmetry = UnfolderSymmetry(atoms)

    def test_000(self):
        kpoint = np.array([0.0, 0.0, 0.0])
        (rotations_kpoint,
         translations_kpoint) = self._symmetry.create_little_group(kpoint)

        self.assertEqual(len(rotations_kpoint), 48)

    def test_100(self):
        kpoint = np.array([0.5, 0.0, 0.0])  # X: D_4h
        (rotations_kpoint,
         translations_kpoint) = self._symmetry.create_little_group(kpoint)

        self.assertNotEqual(len(rotations_kpoint), 48)
        self.assertEqual(len(rotations_kpoint), 16)

    def test_110(self):
        kpoint = np.array([0.5, 0.5, 0.0])  # M: D_4h
        (rotations_kpoint,
         translations_kpoint) = self._symmetry.create_little_group(kpoint)

        self.assertNotEqual(len(rotations_kpoint), 48)
        self.assertEqual(len(rotations_kpoint), 16)

    def test_111(self):
        kpoint = np.array([0.5, 0.5, 0.5])  # R: O_h
        (rotations_kpoint,
         translations_kpoint) = self._symmetry.create_little_group(kpoint)

        self.assertEqual(len(rotations_kpoint), 48)

    def test_star_000(self):
        symmetry = self._symmetry
        prec = 1e-9
        kpoint = np.array([0.0, 0.0, 0.0])
        star, transformation_matrices = symmetry.create_star(kpoint)

        star_exp = [
            [0.0, 0.0, 0.0],
        ]

        self.assertTrue(np.all(np.abs(star - star_exp) < prec))

    def test_star_100(self):
        symmetry = self._symmetry
        prec = 1e-9
        kpoint = np.array([0.5, 0.0, 0.0])
        star, transformation_matrices = symmetry.create_star(kpoint)

        self.assertEqual(len(star), 6)

    def test_star_110(self):
        symmetry = self._symmetry
        prec = 1e-9
        kpoint = np.array([0.5, 0.5, 0.0])
        star, transformation_matrices = symmetry.create_star(kpoint)

        self.assertEqual(len(star), 12)

    def test_star_111(self):
        symmetry = self._symmetry
        prec = 1e-9
        kpoint = np.array([0.5, 0.5, 0.5])
        star, transformation_matrices = symmetry.create_star(kpoint)

        self.assertEqual(len(star), 8)
Ejemplo n.º 18
0
 def setUp(self):
     atoms = read_vasp("POSCAR_sc")
     self._symmetry = UnfolderSymmetry(atoms)
Ejemplo n.º 19
0
 def setUp(self):
     atoms = read_vasp(os.path.join(POSCAR_DIR, "POSCAR_A_h"))
     self._symmetry = UnfolderSymmetry(atoms)