对于简单晶格体系,需要手动给出实空间晶格常数,晶格矢量,倒格矢和高对称点坐标。同时需要解析推导出哈密顿量公式,当然也有办法完全自动化,但是需要写很多辅助代码。
def ham(miu, tij, la, k1):
det1 = la * np.array([3 / 2, np.sqrt(3) / 2])
det2 = la * np.array([3 / 2, -np.sqrt(3) / 2])
h1 = np.zeros((2, 2), dtype=complex)
h1[0, 0] = miu
h1[1, 1] = -miu
h1[0, 1] = -tij * cmath.exp(1j * np.dot(k1, det1)) + -tij * cmath.exp(1j * np.dot(k1, det2)) - tij
h1[1, 0] = h1[0, 1].conj()
return h1
然后沿着高对称点的路径均匀插值得到一系列K点(这里直接调用numpy.linspace函数),然后即可计算能带。
def One_dim_Band():
la = 1
tij = 1
miu = 0
n_step = 100
n_high_k = 3
gama = [0, 0]
m = (2 * np.pi / 3 / la) * np.array([1.0, 0.0])
k = (2 * np.pi / 3 / la) * np.array([1.0, (1 / np.sqrt(3))])
high_point = ("Gama", "M", "K", "Gama")
high_path = np.concatenate((gama, m, k, gama), axis=0)
high_path = high_path.reshape(n_high_k + 1, 2)
k_list = np.linspace(1, 10, n_high_k * n_step)
eig_list = np.zeros((n_high_k, n_step, 2))
for i in range(0, n_high_k):
k_path = np.linspace(high_path[i, :], high_path[i + 1, :], n_step) # 高对称路径坐标列表
for n in np.arange(0, n_step):
h = ham(miu, tij, la, k_path[n])
eig_list[i, n, :], vet = np.linalg.eigh(h)
eig_list = eig_list.reshape(n_high_k * n_step, 2)
Draw_1d(k_list, eig_list, high_point)
画能带图:
def Draw_1d(x, y, k_path):
"""画图函数"""
Ef = np.zeros(x.size) # 费米能
plt.plot(x, y, "b")
plt.plot(x, Ef, "r", linestyle='--') # 标记费米面而画的一条虚线
x_axis = np.linspace(1, 10, len(k_path))
plt.xticks(x_axis, k_path)
k_x = np.full(x.size, x_axis[2])
k_y = np.linspace(np.min(y), np.max(y), x.size)
plt.plot(k_x, k_y, "r", linestyle='--') # k_x和k_y是为了标记狄拉克点而画的一条虚线
plt.xlim(x_axis[0], x_axis[-1])
plt.ylim(np.min(y))
plt.ylabel("Energy")
plt.title("1D Band")
#plt.savefig("Graphene_1D_Band.jpg", dpi=300)
plt.show()