Posts
The band structure of graphene
|0> to |1>: Why quantum technology is bound to rise.
Finite differences and second quantization
Dynamically adjustable HoppingAmplitudes using callbacks in TBTK
Retrieving the Hamiltonian from the Model in TBTK
Creating Models with complex geometries using an IndexFilter in TBTK
Direct access to wave function amplitudes and eigenvalues in TBTK
Using TBTK to calculate the density of states (DOS) of a 1D, 2D, and 3D square lattice
TBTK v1.0.0 released
Using TBTK to time C++ code
Introduction to TBTK – A software development kit for quantum mechanical calculations
The second quantum revolution

Using TBTK to calculate the density of states (DOS) of a 1D, 2D, and 3D square lattice

Kristofer Björnson
(23rd of October 2018)

Most recent TBTK release at the time of writing: v1.0.2 (Updated to work with: v2.0.0)

In this post we will walk through how to calculate and plot the density of state (DOS) of a 1D, 2D, and 3D square lattice, using TBTK. To achieve this we will first implement three functions for creating the corresponding models. We will then create a fourth function in which the DOS is calculated for each of the three models.

This example also provides a simple demonstration of how TBTK naturally support the creation of general purpose code, in this case the calculation of the DOS, that can be used independently of the details of the model.

1 Creating the Model

1.1 One dimension

In one dimension the Hamiltonian is given by

H1D =2tkxcos(kx)ckxckx, (1)

where t is a hopping parameter that we will set to one.

To create the model we loop over the summation index and feed each of the hopping amplitudes to the Model. Note how we let the numerical indices run over the positive discrete values 0 to 9999, while the argument of the cos function falls in the interval [π,π].

1Model createModel1D(){
2    //Parameters.
3    const int SIZE_X = 10000;
4    double t = 1;
5
6    //Create the Model.
7    Model model;
8    for(int kx = 0; kx < SIZE_X; kx++){
9        double KX = 2*M_PI*kx/(double)SIZE_X - M_PI;
10        model << HoppingAmplitude(
11            -2*t*cos(KX),
12            {kx},
13            {kx}
14        );
15    }
16
17    return model;
18}

1.2 Two dimensions

In two dimension the Hamiltonian is given by

H2D =2tkx,ky(cos(kx)+cos(ky))c𝐤c𝐤, (2)

where 𝐤=(kx,ky).

The corresponding Model is created as follows using a 500×500 grid.

1Model createModel2D(){
2    //Parameters.
3    const int SIZE_X = 500;
4    const int SIZE_Y = 500;
5    double t = 1;
6
7    //Create the Model.
8    Model model;
9    for(int kx = 0; kx < SIZE_X; kx++){
10        for(int ky = 0; ky < SIZE_Y; ky++){
11            double KX = 2*M_PI*kx/(double)SIZE_X;
12            double KY = 2*M_PI*ky/(double)SIZE_Y;
13
14            model << HoppingAmplitude(
15                -2*t*(cos(KX) + cos(KY)),
16                {kx, ky},
17                {kx, ky}
18            );
19        }
20    }
21
22    return model;
23}

1.3 Three dimensions

In three dimension the Hamiltonian is given by

H3D =2tkx,ky,kz(cos(kx)+cos(ky)+cos(kz))c𝐤c𝐤, (3)

where 𝐤=(kx,ky,kz).

The corresponding Model is created as follows using a 200×200×200 grid.

1Model createModel3D(){
2    //Parameters.
3    const int SIZE_X = 200;
4    const int SIZE_Y = 200;
5    const int SIZE_Z = 200;
6    double t = 1;
7
8    //Create the Model.
9    Model model;
10    for(int kx = 0; kx < SIZE_X; kx++){
11        for(int ky = 0; ky < SIZE_Y; ky++){
12            for(int ky = 0; ky < SIZE_Y; ky++){
13                double KX = 2*M_PI*kx/(double)SIZE_X;
14                double KY = 2*M_PI*ky/(double)SIZE_Y;
15                double KZ = 2*M_PI*kz/(double)SIZE_Z;
16
17                model << HoppingAmplitude(
18                    -2*t*(cos(KX) + cos(KY) + cos(KZ)),
19                    {kx, ky, kz},
20                    {kx, ky, kz}
21                );
22            }
23        }
24    }
25
26    return model;
27}

2 Calculating the DOS

We are now ready to implement the main function for calculating the DOS. To take advantage of that the Hamiltonian consists of independent blocks for each 𝐤 value, we will use the Solver::BlockDiagonalizer. Knowing that the density of states will lie in the interval [6,6] for all three Models, we next setup the PropertyExtractor to work on the energy interval [7,7] and calculate the DOS. Finally we plot the DOS, using gaussian smoothin with σ=0.05 and a convolution window of 101 energy points and save the results to file.

1int main(int argc){
2    //Initialize TBTK.
3    Initialize();
4
5    //Filenames to save the figures as.
6    string filenames[3] = {
7        ”figures/DOS_1D.png”,
8        ”figures/DOS_2D.png”,
9        ”figures/DOS_3D.png”,
10    };
11
12    //Loop over 1D, 2D, and 3D.
13    for(int n = 0; n < 3; n++){
14        //Create the Model.
15        Model model;
16        switch(n){
17        case 0:
18            model = createModel1D();
19            break;
20        case 1:
21            model = createModel2D();
22            break;
23        case 2:
24            model = createModel3D();
25            break;
26        default:
27            Streams::out << ”Error: Invalid case value.\n”;
28            exit(1);
29        }
30
31        //Setup and run the Solver.
32        Solver::BlockDiagonalizer solver;
33        solver.setModel(model);
34        solver.run();
35
36        //Setup the PropertyExtractor.
37        PropertyExtractor::BlockDiagonalizer propertyExtractor(solver);
38        propertyExtractor.setEnergyWindow(-7, 7, 1000);
39        Property::DOS dos = propertyExtractor.calculateDOS();
40
41        //Normalize the DOS.
42        for(unsigned int c = 0; c < dos.getResolution(); c++)
43                dos(c) = dos(c)/model.getBasisSize();
44
45        //Smooth the DOS.
46        const double SMOOTHING_SIGMA = 0.05;
47        const unsigned int SMOOTHING_WINDOW = 101;
48        dos = Smooth::gaussian(dos, SMOOTHING_SIGMA, SMOOTHING_WINDOW);
49
50        //Plot and save the result.
51        Plotter plotter;
52        plotter.plot(dos);
53        plotter.save(filenames[n]);
54    }
55
56    return 0;
57}

3 Results

Below we show the result of the calculation for the three different cases.

3.1 One dimensional

[Uncaptioned image]

3.2 Two dimensional

[Uncaptioned image]

3.3 Three dimensional

[Uncaptioned image]

4 Full code

Full code is available in src/main.cpp in the project 2018_10_23 of the Second Tech code package. See the README for instructions on how to build and run.