Qsymm Basics¶
See also
The complete source code of this example can be found in basics.py. A Jupyter notebook can be found in basics.ipynb.
Getting started with Qsymm is as simple as importing it:
import qsymm
To make effective use of Qsymm we’ll also need a few other utilities: numpy
handling numeric arrays, and sympy
for symbolic mathematics:
import numpy as np
import sympy
In all the following tutorials we will use these standard imports, and they won’t be explicitly shown
Defining a Qsymm model¶
Let’s start by defining a 3D Rashba Hamiltonian symbolically as a Python string:
ham = ("hbar^2 / (2 * m) * (k_x**2 + k_y**2 + k_z**2) * eye(2) +" +
"alpha * sigma_x * k_x + alpha * sigma_y * k_y + alpha * sigma_z * k_z")
We can then create a Qsymm Model
directly from this symbolic Hamiltonian:
H = qsymm.Model(ham)
We can then directly inspect the contents by printing the Model
:
print(H)
{alpha*k_z:
[[ 1.+0.j 0.+0.j]
[ 0.+0.j -1.+0.j]],
hbar**2*k_x**2/m:
[[0.5+0.j 0. +0.j]
[0. +0.j 0.5+0.j]],
hbar**2*k_y**2/m:
[[0.5+0.j 0. +0.j]
[0. +0.j 0.5+0.j]],
hbar**2*k_z**2/m:
[[0.5+0.j 0. +0.j]
[0. +0.j 0.5+0.j]],
alpha*k_x:
[[0.+0.j 1.+0.j]
[1.+0.j 0.+0.j]],
alpha*k_y:
[[0.+0.j 0.-1.j]
[0.+1.j 0.+0.j]],
}
We can also extract a more readable representation by using the tosympy
method, which
converts the Model
to a sympy
expression:
H.tosympy(nsimplify=True)
The argument nsimplify=True
makes the output more readable by forcing sympy
to elide
factors of 1.0
that multiply each term. Note that Qsymm automatically interprets the symbols
sigma_x
, sigma_y
and sigma_z
as the Pauli matrices, and eye(2)
as the 2x2
identity matrix.
Model
as a momenta
attribute that specifies which symbols are considered the
momentum variables:
H.momenta
(k_x, k_y, k_z)
By default Qsymm assumes that your model is written in 3D (even if it does not include all 3 momenta). To define a lower-dimensional model you must explicitly specify the momentum variables, e.g:
ham2D = ("hbar^2 / (2 * m) * (k_x**2 + k_z**2) * eye(2) +" +
"alpha * sigma_x * k_x + alpha * sigma_y * k_z")
H2D = qsymm.Model(ham2D, momenta=['k_x', 'k_z'])
H2D.tosympy(nsimplify=True)
H2D.momenta
(k_x, k_z)
Defining group elements¶
Qsymm is all about finding and generating symmetries of models, so it is unsurprising that it contains utilities for defining group elements.
Below are a few examples of the sorts of things you can define with Qsymm:
# Identity in 3D
E = qsymm.identity(3)
# Inversion in 3D
I = qsymm.inversion(3)
# 4-fold rotation around the x-axis
C4 = qsymm.rotation(1/4, [1, 0, 0])
# 3-fold rotation around the [1, 1, 1] axis
C3 = qsymm.rotation(1/3, [1, 1, 1])
# Time reversal
TR = qsymm.time_reversal(3)
# Particle-hole
PH = qsymm.particle_hole(3)
The documentation page of the qsymm.groups
module contains an exhaustive list
of what can be generated.
As with other Qsymm objects we can get a readable representation of these group elements:
C4
TR
Given a set of group generators we can also generate a group:
cubic_gens = {I, C4, C3, TR, PH}
cubic_group = qsymm.groups.generate_group(cubic_gens)
print(len(cubic_group))
192
Group elements can be multiplied and inverted, as we would expect:
C3 * C4
C3**-1
We can also apply group elements to the Model
that we defined
in the previous section:
H_with_TR = TR.apply(H)
H_with_TR.tosympy(nsimplify=True)
Defining continuous group generators¶
In addition to the group elements we can also define generators of continuous groups
using qsymm.groups.ContinuousGroupGenerator
:
sz = qsymm.ContinuousGroupGenerator(None, np.array([[1, 0], [0, -1]]))
The first argument to ContinuousGroupGenerator
is the realspace rotation generator;
by specifying None
we indicate that we want the rotation part to be zero. The second
argument is the unitary action of the generator on the Hilbert space as a Hermitian matrix.
Applying a ContinuousGroupGenerator
to a Model
calculates the commutator:
sz.apply(H).tosympy(nsimplify=True)
For the 3D Rashba Hamiltonian we defined at the start of the tutorial spin-z is not conserved, hence the commutator is non-zero.
Finding symmetries¶
The function symmetries
allows us to find the symmetries of a
Model
. Let us find out whether the 3D Rashba Hamiltonian defined earlier
has cubic group symmetry:
discrete_symm, continuous_symm = qsymm.symmetries(H, cubic_group)
print(len(discrete_symm), len(continuous_symm))
48 0
It has 48 discrete symmetries (cubic group without inversion and time-reversal) and no continuous symmetries (conserved quantities).
For more detailed examples see Finding Symmetries and Finding symmetries of the Kekule-Y continuum model.
Generating Hamiltonians from symmetry constraints¶
The qsymm.hamiltonian_generator
module contains algorithms for generating Hamiltonians from
symmetry constraints.
For example let us generate all 2-band \(k \cdot p\) Hamiltonians with the same discrete symmetries as the Rashba Hamiltonian that we found in the previous section:
family = qsymm.continuum_hamiltonian(discrete_symm, dim=3, total_power=2, prettify=True)
qsymm.display_family(family)
It is exactly the Hamiltonian family we started with.
For more detailed examples see Generating k \cdot p models, Generating tight-binding models and Finding symmetries of the Kekule-Y continuum model.