Spin texture

In this tutorial, we demonstrate the usage of SpinTexture class by calculating the spin texture of graphene with Rashba and Kane-Mele spin-orbital coupling. The spin texture is defined as the the expectation of Pauli operator \(\sigma_i\), which can be considered as a function of band index \(n\) and \(\mathbf{k}\)-point

\[s_i(n, \mathbf{k}) = \langle \psi_{n,\mathbf{k}} | \sigma_i | \psi_{n,\mathbf{k}} \rangle\]

where \(i \in {x, y, z}\) are components of the Pauli operator. The spin texture can be evaluated for given band index \(n\) or fixed energy, while in this tutorial we will focus on the former case. The script is located at examples/prim_cell/spin_texture/spin_texture.py. As in other tutorials, we begin with importing the tbplas package:

import tbplas as tb

Evaluation of spin texture

We evaluation of spin texture in the following manner:

 1# Import the model and define some parameters
 2cell = tb.make_graphene_soc(is_qsh=True)
 3ib = 2
 4spin_major = False
 5
 6# Evaluate expectation of sigma_z
 7k_grid = 2 * tb.gen_kmesh((240, 240, 1)) - 1
 8spin_texture = tb.SpinTexture(cell, k_grid, spin_major)
 9k_cart = spin_texture.k_cart
10sz = spin_texture.eval("z")
11vis = tb.Visualizer()
12vis.plot_scalar(x=k_cart[:, 0], y=k_cart[:, 1], z=sz[:, ib],
13                num_grid=(480, 480), cmap="jet")
14
15# Evaluate expectation of sigma_x and sigma_y
16k_grid = 2 * tb.gen_kmesh((48, 48, 1)) - 1
17spin_texture.k_grid = k_grid
18k_cart = spin_texture.k_cart
19sx = spin_texture.eval("x")
20sy = spin_texture.eval("y")
21vis.plot_vector(x=k_cart[:, 0], y=k_cart[:, 1], u=sx[:, ib], v=sy[:, ib],
22                cmap="jet")

In line 2 we import the graphene model with Rashba and Kane-Mele SOC with the make_graphene_soc() function. In line 3-4 we define the band index and whether the orbitals are sorted in spin-major order, which will be discussed in more details in the next section. To plot the expectation of \(\sigma_i\) as function of \(\mathbf k\)-point, we need to generate a uniform meshgrid in the Brillouin zone. As the gen_kmesh() function generates k-grid on \([0, 1]\), so we need to multiply the result by a factor of 2, then extract 1 from it such that the k-grid will be on \([-1, 1]\) which is enough to cover the first Brillouin zone. Then we create a SpinTexture object in line 8. In line 9-10 we get the Cartesian coordinates of k-grid and the expectation of \(\sigma_z\), and visualize it in line 11-13 as colormap using the plot_scalar method. The argument ib specifies the band index \(n\) to plot. The result is shown in Fig. 1(a).

The evaluation of \(\sigma_x\) and \(\sigma_y\) is similar. In line 16-17 we assign a more sparse k-grid to the SpinTexture object since we are going to plot the expectation as vector field. In 18-20 we get the Cartesian coordinates of k-grid and the expectation of \(\sigma_x\) and \(\sigma_y\), and plot them as vector field in line 21-22. The output is shown in Fig. 1(b).

../../_images/spin_texture1.png

Plot of expectation of (a) \(\sigma_z\) and (b) \(\sigma_x\) and \(\sigma_y\).

Orbital order

The order of spin-polarized orbitals determines how the spin-up and spin-down components are extracted from the eigenstates. There are two popular orders: spin-major and orbital-major. For example, there are two \(p_z\) orbitals in the two-band model of monolayer graphene in the spin-unpolarized case, which can be denoted as \(\{\phi_1, \phi_2\}\). When spin has been taken into consideration, the orbitals become \(\{\phi_1^{\uparrow}, \phi_2^{\uparrow}, \phi_1^{\downarrow}, \phi_2^{\downarrow}\}\). In spin-major order they are sorted as \([\phi_1^{\uparrow}, \phi_2^{\uparrow}, \phi_1^{\downarrow}, \phi_2^{\downarrow}]\), while in orbital-major order they are sorted as \([\phi_1^{\uparrow}, \phi_1^{\downarrow}, \phi_2^{\uparrow}, \phi_2^{\downarrow}]\). The split_spin method of SpinTexture class extracts the spin-up and spin-down components as following:

 1def split_spin(self, state: np.ndarray) -> Tuple[np.ndarray, np.ndarray]:
 2    """
 3    Split spin-up and spin-down components for wave function at given
 4    k-point and band.
 5
 6    Two kinds of orbital orders are implemented:
 7    spin major: psi_{0+}, psi_{1+}, psi_{0-}, psi_{1-}
 8    orbital major: psi_{0+}, psi_{0-}, psi_{1+}, psi_{1-}
 9
10    If the orbitals are sorted in neither spin nor orbital major,
11    derive a new class from SpinTexture and overwrite this method.
12
13    :param state: (num_orb,) complex128 array
14        wave function at given k-point and band
15    :return: (u, d)
16        u: (num_orb//2,) complex128 array
17        d: (num_orb//2,) complex128 array
18        spin-up and spin-down components of the wave function
19    """
20    num_orb = self.num_orb // 2
21    if self._spin_major:
22        u, d = state[:num_orb], state[num_orb:]
23    else:
24        u, d = state[0::2], state[1::2]
25    return u, d

If the spin-polarized orbitals follow other user-defined orders, then the users should derive their own class from SpinTexture and overload the split_spin method.