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.