Spin representation for \(C_{3v}\)#

[1]:
from __future__ import annotations

import numpy as np

import spgrep
from spgrep import get_crystallographic_pointgroup_spinor_irreps_from_symmetry
from spgrep.representation import get_character
from spgrep.pointgroup import pg_dataset

print(f"spgrep=={spgrep.__version__}")
spgrep==0.3.2.dev5+ga44d231

Prepare point-group operations#

[2]:
# Hexagonal lattice
a = 2.0
c = 3.0
lattice = np.array(
    [
        [a, 0, 0],
        [-0.5 * a, np.sqrt(3) / 2 * a, 0],
        [0, 0, c],
    ]
)
[3]:
# C3v (3m1)
rotations = np.array(pg_dataset["3m"][0])

Unitary matrices for spinor#

We can enumerate irreps of a point group for spinor by get_crystallographic_pointgroup_spinor_irreps_from_symmetry.

[4]:
# We need ``lattice`` to convert rotations into Cartesian coordinates
(
    irreps,
    factor_system,
    unitary_rotations,
) = get_crystallographic_pointgroup_spinor_irreps_from_symmetry(
    lattice,
    rotations,
)

We write rotations[i] as \(\mathbf{R}_{i}\) and unitary_rotations[i] as \(\mathbf{U}_{i}\) for clarity. Be careful that unitary_rotations live in \(\mathrm{SU}(2)\). For example, while the third power of \(\mathbf{R}_{1}\) gives the identity, that of \mathbf{U}_{1} gives \(-\mathbf{1}\):

[5]:
rotations[1] @ rotations[1] @ rotations[1]
[5]:
array([[1, 0, 0],
       [0, 1, 0],
       [0, 0, 1]])
[6]:
np.around(unitary_rotations[1] @ unitary_rotations[1] @ unitary_rotations[1], 8)
[6]:
array([[-1.-0.j,  0.+0.j],
       [ 0.+0.j, -1.+0.j]])

Such an ambiguity is reflected in factor_system. For another example, while \(\mathbf{R}_{1} \mathbf{R}_{3} = \mathbf{R}_{5}\), we obtain \(\mathbf{U}_{1} \mathbf{U}_{3} = -\mathbf{U}_{5}\) in our convention:

[7]:
assert np.allclose(
    unitary_rotations[1] @ unitary_rotations[3],
    -unitary_rotations[5],
)

The corresponding multiplier \(z(\mathbf{R}_{1}, \mathbf{R}_{3})\) is given in factor_system,

[8]:
factor_system[1, 3]
[8]:
(-1+0j)

Enumerate spin representations from factor system#

[9]:
for irrep in irreps:
    print(get_character(irrep))
[2.+0.j 1.+0.j 1.+0.j 0.+0.j 0.+0.j 0.+0.j]
[ 1.+0.j -1.+0.j -1.+0.j  0.+1.j  0.-1.j  0.+1.j]
[ 1.+0.j -1.+0.j -1.+0.j  0.-1.j  0.+1.j  0.-1.j]