Quasi-eigenstates
The quasi-eigenstates are defined as
If the energy \(E\) equals to an eigenvalue \(E_i\), then the quasi-eigenstate is the exact
eigenstate corresonding to \(E_i\), or a superposition of degenerate eigenstates if \(E_i\)
is degenerate. In this tutorial, we will show how to calculate the quasi-eigenstates and compare them
with the exact eigenstates. The script can be found at examples/advanced/quasi_eigen.py
. We begin
with importing the necessary packages:
import numpy as np
import tbplas as tb
Exact eigenstates
We define the following function to calculate the exact eigenstates:
1def wfc_diag(sample: tb.Sample) -> None:
2 """
3 Calculate wave function using exact diagonalization.
4
5 :param sample: graphene sample
6 :return: None
7 """
8 k_points = np.array([[0.0, 0.0, 0.0]])
9 solver = tb.DiagSolver(model=sample)
10 bands, states = solver.calc_states(k_points)
11
12 i_b = sample.num_orb // 2
13 wfc = np.abs(states[0, i_b])**2
14 wfc /= wfc.max()
15 vis = tb.Visualizer()
16 vis.plot_wfc(sample, wfc, scatter=True, site_size=wfc*100, site_color="r",
17 with_model=True, model_style={"alpha": 0.25, "color": "gray"})
18 print(bands[0, i_b])
In line 8 we define the k-points on which the eigenstates will be calculated, where we consider the
\(\Gamma\) point. In line 9 we define a DiagSolver
object and call its calc_states
method in line 10 to get the eigenvalues and eigenstates, as returned in bands
and states
. After
that, we extract the eigenstate at the Fermi level and normalize it in line 12-14. To visualize the
eigenstate, we create a visualizer from the Visualizer
class and call its plot_wfc
method.
Note that we must use scatter plot by setting the scatter
argument to true. The eigenstate should be
passed as the site_size
argument, i.e., sizes of scatters will indicate the projection of eigenstate
on the sites. We also need to show the model alongside the eigenstate through the with_model
argument
and define its plotting style with the model_style
argument. Finally, we print the eigenvalue
corresonding to the eigenstate, which will be utilized to calcualte the quasi-eigenstate then.
The wfc_diag
function should be called by:
1def main():
2 # Build a graphene sample with a single vacancy
3 prim_cell = tb.make_graphene_diamond()
4 super_cell = tb.SuperCell(prim_cell, dim=(17, 17, 1),
5 pbc=(True, True, False))
6 super_cell.add_vacancies([(8, 8, 0, 0)])
7 sample = tb.Sample(super_cell)
8
9 # Calcuate and Visualize the eigenstate
10 wfc_diag(sample)
11
12
13if __name__ == "__main__":
14 main()
where we create a \(17\times17\times1\) graphene sample with a vacancy in the center in line 2-7. The output is shown in Fig. 1(b), where the eigenstate is localized around the vacancy and shows a 3-fold rotational symmtery.

Spatial distribution of (a) exact eigenstate and (b) quasi-eigenstate of graphene sample with a vacancy in the
center. The X
marks indicate the position of the vacancy.
Quasi-eigenstates
The quasi-eigenstate is evaluated and plotted in a similar approach:
1def wfc_tbpm(sample: tb.Sample) -> None:
2 """
3 Calculate wave function using TBPM.
4
5 :param sample: graphene sample
6 :return: None
7 """
8 sample.rescale_ham()
9 config = tb.Config()
10 config.generic['nr_random_samples'] = 1
11 config.generic['nr_time_steps'] = 1024
12 config.quasi_eigenstates['energies'] = [0.0]
13
14 solver = tb.Solver(sample, config)
15 qs = solver.calc_quasi_eigenstates()
16 wfc = np.abs(qs[0])**2
17 wfc /= wfc.max()
18 vis = tb.Visualizer()
19 vis.plot_wfc(sample, wfc, scatter=True, site_size=wfc*100, site_color="b",
20 with_model=True, model_style={"alpha": 0.25, "color": "gray"})
Evaluating quasi-eigenstates is a kind of TBPM calculation, so it follows the common procedure of
TBPM. We firstly rescale the Hamiltonian in line 8, then create a config
and a solver
in
line 9-14. Specially, the energy from the output of previous section should be specified in
config.quasi_eigenstates['energies']
. Then we call the calc_quasi_eigenstates
method of
solver
to get the eigenstates, normalize it, and visualize it in line 15-20.
We call wfc_tbom
by:
wfc_diag(sample)
The output is shown in Fig. 1(b), which is also localized around the vacancy and shows a 3-fold rotational symmtery, much similar to the exact eigenstate in Fig. 1(a).