Analytical Hamiltonian

We have already demonstrated the derivation of analytical Hamiltonian of primitive cell in section Setting up the primitive cell In this tutorial, we show how to utilize analytical Hamiltonian in calculations. The utilization of analytical Hamiltonian is restrict to the C++ API only. The examples are available at tbplas-cpp/samples/speedtest/model.cpp and its header model.h, where we define the following model classes using analytical Hamiltonian:

 1/**
 2* @brief Analytical QAH model for testing Berry utilities.
 3* @note Ref: https://www.guanjihuan.com/archives/3932.
 4*/
 5class QAH : public AnalyticalModel {
 6public:
 7    QAH();
 8
 9    void build_ham_dense(
10        const Eigen::Vector3d& k_point,
11        Eigen::MatrixXcd& ham,
12        int convention = 1) const;
13
14    void build_ham_der_dense(
15        const Eigen::Vector3d& k_point,
16        Eigen::MatrixXcd& dh_dka,
17        Eigen::MatrixXcd& dh_dkb,
18        Eigen::MatrixXcd& dh_dkc,
19        int convention = 1) const;
20};
21
22/**
23* @brief Analytical CheckerBoard model for testing Berry utilities.
24* @note Ref: https://www.guanjihuan.com/archives/23989
25*/
26class CheckerBoard : public AnalyticalModel {
27public:
28    explicit CheckerBoard(int ny);
29
30    void build_ham_dense(
31        const Eigen::Vector3d& k_point,
32        Eigen::MatrixXcd& ham,
33        int convention = 1) const;
34
35private:
36    int ny_ = 5;
37};
38
39/**
40* @brief Analytical Haldane model for testing Berry utilities.
41* @note Ref: https://www.guanjihuan.com/archives/5133
42*/
43class Haldane : public AnalyticalModel {
44public:
45    Haldane();
46
47    void build_ham_dense(
48        const Eigen::Vector3d& k_point,
49        Eigen::MatrixXcd& ham,
50        int convention = 1) const;
51};

where the implementation can be found in model.cpp. Generally speaking, to utilize the analytical Hamiltonian, the users must derive their own model class from the AnalyticalModel class defined in tbplas-cpp/sources/builder/analytical.h and implement the proper member functions:

  • build_ham_dr_coo: required for AC conductivity calculation using Lindhard

  • build_ham_curr_csr: required for TBPM AC and DC conductivity calculations

  • build_ham_csr: required for general TBPM calculations

  • build_ham_dense: required for general exact diagonalization calculations

  • build_density_coeff: required for Lindhard and TBPM dynamic polarization calculations

  • build_ham_der_dense: required for Berry curvature calculation using analytical Hamiltonian derivatives

For example, the QAH class implements the build_ham_dense and build_ham_der_dense functions, so it can be utilized for general exact diagonalization and Berry curvature/Chern number calculations using analytical Hamiltonian derivatives. On the contrary, the CheckerBoard and Haldane class implement only the build_ham_dense method, so they can only be utilized for general exact diagonalization and Berry curvature/Chern number calculations using number Hamiltonian derivatives. The utilization of the models can be found in tbplas-cpp/samples/speedtest/diag.cpp:

 1void test_berry()
 2{
 3    // QAH model;
 4    // Berry<QAH> solver(model);
 5    // CheckerBoard model(20);
 6    // Berry<CheckerBoard> solver(model);
 7    // Haldane model;
 8    // Berry<Haldane> solver(model);
 9    model_t model = make_haldane();
10#ifdef WITH_OVERLAP
11    model_t overlap = make_overlap(model);
12    Berry<model_t> solver(model, overlap);
13#else
14    Berry<model_t> solver(model);
15#endif
16    solver.config.k_grid_size = { 100, 100, 1 };
17    solver.config.num_occ = 1;
18    solver.config.diag_algo = DIAG_ALGO;
19    solver.config.ham_deriv_analytical = true;
20    solver.config.convention = CONVENTION;
21
22    Timer timer;
23    timer.tic("berry");
24    solver.config.prefix = "haldane_kubo";
25    auto data_kubo = solver.calc_berry_curvature_kubo();
26    solver.config.prefix = "haldane_wilson";
27    auto data_wilson = solver.calc_berry_curvature_wilson();
28    timer.toc("berry");
29    if (solver.is_master()) {
30        timer.report_total_time();
31    }
32}

Firstly, we use the Haldane model produced by the make_haldane function, which is an object of C++ PrimitiveCell class. The output should look like:

(tbplas) yhli@n02:~/proj/tbplas-cpp/build$ ./bin/speedtest berry
Using Eigen backend for diagonalization.
Chern number for band 0: -1
Chern number for band 1: 1
Using Eigen backend for diagonalization.
Chern number for num_occ 1: -1
    berry:       0.371 sec.

Then use the analytical Haldane class:

 1void test_berry()
 2{
 3    // QAH model;
 4    // Berry<QAH> solver(model);
 5    // CheckerBoard model(20);
 6    // Berry<CheckerBoard> solver(model);
 7    Haldane model;
 8    Berry<Haldane> solver(model);
 9//     model_t model = make_haldane();
10// #ifdef WITH_OVERLAP
11//     model_t overlap = make_overlap(model);
12//     Berry<model_t> solver(model, overlap);
13// #else
14//     Berry<model_t> solver(model);
15// #endif
16    solver.config.k_grid_size = { 100, 100, 1 };
17    solver.config.num_occ = 1;
18    solver.config.diag_algo = DIAG_ALGO;
19    solver.config.ham_deriv_analytical = false;
20    solver.config.convention = CONVENTION;
21
22    Timer timer;
23    timer.tic("berry");
24    solver.config.prefix = "haldane_kubo";
25    auto data_kubo = solver.calc_berry_curvature_kubo();
26    solver.config.prefix = "haldane_wilson";
27    auto data_wilson = solver.calc_berry_curvature_wilson();
28    timer.toc("berry");
29    if (solver.is_master()) {
30        timer.report_total_time();
31    }
32}

Note that ham_deriv_analytical should be set to false since the Haldane class does not implement the build_ham_dense function. The output should look like:

1(tbplas) yhli@n02:~/proj/tbplas-cpp/build$ ./bin/speedtest berry
2Using Eigen backend for diagonalization.
3Chern number for band 0: 1
4Chern number for band 1: -1
5Using Eigen backend for diagonalization.
6Chern number for num_occ 1: 1
7    berry:       0.330 sec.

which is consistent with PrimitiveCell class, i.e., both bands are topologically non-trivial, and have opposite Chern number.