Made by Dongwook Go (d.go@fz-juelich.de)
Let's first import life-saving libraries:
import numpy as np
import matplotlib.pyplot as plt
The DFT band structure of PbTiO3 can be found in Wannier/data/PbTiO3/bands.1
. Let's import this to a numpy array.
band_raw = np.genfromtxt('PbTiO3/bands.1')
Then let's re-arrange it into a two-dimensional array, whose indices represent kpoint and band number, respectively.
N_kpts = 240
N_band = int(len(band_raw)/N_kpts)
band = np.zeros((N_kpts, N_band))
for n in range(0,N_band):
band[:,n] = band_raw[n*N_kpts:(n+1)*N_kpts,1]
While you can make a very quick plot out of this, let's add high-symmetry points of the Brillouin zone. This information has been taken from band.gnu
file which you get from the FLEUR band mode.
xticks_pos = [0.00000, 0.42834, 0.85668, 1.46244, 1.86350, 2.29184, 2.72018, 3.32594]
xticks_label = [r'$\Gamma$', r'$\mathrm{X}$', r'$\mathrm{M}$', r'$\Gamma$', r'$\mathrm{Z}$', r'$\mathrm{R}$', r'$\mathrm{A}$',r'$\mathrm{Z}$']
kpts = np.linspace(0.00000, np.max(xticks_pos), N_kpts)
Now let's plot the band structure.
fig1, ax = plt.subplots()
ax.set_title('Band structure of PbTiO3')
ax.set_xlim(np.min(xticks_pos), np.max(xticks_pos))
ax.set_ylim(-8,8)
for q in range(0,len(xticks_pos)):
ax.plot([xticks_pos[q],xticks_pos[q]], [-8, 8], linewidth=0.7, color='k')
for n in range(0,N_band):
ax.plot(kpts, band[:,n], color='C0', linewidth=1.5)
ax.set_xticks(xticks_pos)
ax.set_xticklabels(xticks_label)
ax.set_ylabel(r'$E_{n\mathbf{k}} - E_\mathrm{F}\ [\mathrm{eV}]$')
plt.show()
The DOS of PbTiO3 can be found in Wannier/data/PbTiO3/Local.1
. Let's import this into a numpy array.
DOS_raw = np.genfromtxt('PbTiO3/Local.1')
And we put them into separate one-dimensional arrays for each orbital character.
Energy = DOS_raw[:,0]
DOS_Pb_s = DOS_raw[:,4]
DOS_Pb_p = DOS_raw[:,5]
DOS_Pb_d = DOS_raw[:,6]
DOS_Ti_s = DOS_raw[:,8]
DOS_Ti_p = DOS_raw[:,9]
DOS_Ti_d = DOS_raw[:,10]
DOS_O1_s = DOS_raw[:,12]
DOS_O1_p = DOS_raw[:,13]
DOS_O2_s = DOS_raw[:,16]
DOS_O2_p = DOS_raw[:,17]
Now let's make subplots for each elements.
fig2, (ax1, ax2, ax3) = plt.subplots(1,3)
ax1.set_title('Pb')
ax1.set_ylim(-8,8)
ax1.set_xlim(0,1.3)
ax1.set_ylabel(r'$E_{n\mathbf{k}} - E_\mathrm{F}\ [\mathrm{eV}]$')
plt_Pb_s, = ax1.plot(DOS_Pb_s, Energy, '-')
plt_Pb_p, = ax1.plot(DOS_Pb_p, Energy, '--')
plt_Pb_d, = ax1.plot(DOS_Pb_d, Energy, '-.')
ax1.legend([plt_Pb_s, plt_Pb_p, plt_Pb_d], ['s', 'p', 'd'])
ax1.set_ylabel(r'$E_{n\mathbf{k}} - E_\mathrm{F}\ [\mathrm{eV}]$')
ax1.set_xlabel('DOS [a.u.]')
ax2.set_title('Ti')
ax2.set_ylim(-8,8)
ax2.set_xlim(0,3.5)
ax2.set_ylabel(r'$E_{n\mathbf{k}} - E_\mathrm{F}\ [\mathrm{eV}]$')
plt_Ti_s, = ax2.plot(DOS_Ti_s, Energy, '-')
plt_Ti_p, = ax2.plot(DOS_Ti_p, Energy, '--')
plt_Ti_d, = ax2.plot(DOS_Ti_d, Energy, '-.')
ax2.legend([plt_Ti_s, plt_Ti_p, plt_Ti_d], ['s', 'p', 'd'])
ax2.set_ylabel(r'$E_{n\mathbf{k}} - E_\mathrm{F}\ [\mathrm{eV}]$')
ax2.set_xlabel('DOS [a.u.]')
ax3.set_title('O')
ax3.set_ylim(-8,8)
ax3.set_xlim(0,1.5)
ax3.set_ylabel(r'$E_{n\mathbf{k}} - E_\mathrm{F}\ [\mathrm{eV}]$')
plt_O_s, = ax3.plot(DOS_O1_s + DOS_O2_s, Energy, '-')
plt_O_p, = ax3.plot(DOS_O1_p + DOS_O2_p, Energy, '--')
ax3.legend([plt_O_s, plt_O_p], ['s', 'p'])
ax3.set_ylabel(r'$E_{n\mathbf{k}} - E_\mathrm{F}\ [\mathrm{eV}]$')
ax3.set_xlabel('DOS [a.u.]')
plt.tight_layout()
plt.show()
We see clearly that a group of bands located from -5 eV to 0 eV mainly have O p-orbital character, which justifes our choice if the initial projection for the WFs.
Having obtained the band structure from the Wannier Hamiltonian, let's compare the DFT and Wannier band structures to see if they agree well. First import WF1_band.dat
into an array.
band_WF_raw = np.genfromtxt('wann/WF1_band.dat')
Fermi_energy = np.max(band_WF_raw[:,1]) # Fermi energy is the maximum of the conduction band for insulators (FLEUR)
N_wann = 9
kpts_wann_raw = np.genfromtxt('wann/WF1_band.kpt', skip_header=1)
N_kpts_wann = len(kpts_wann_raw)
band_WF = np.zeros((N_kpts_wann, N_wann))
for n in range(0,N_wann):
band_WF[:,n] = band_WF_raw[n*N_kpts_wann:(n+1)*N_kpts_wann,1] - Fermi_energy
kpts_wann = np.linspace(0.00000, np.max(xticks_pos), N_kpts_wann)
and make a plot
fig0, ax0 = plt.subplots()
ax0.set_title('Comparison of the band structures')
ax0.set_xlim(np.min(xticks_pos), np.max(xticks_pos))
ax0.set_ylim(-8,8)
for q in range(0,len(xticks_pos)):
ax0.plot([xticks_pos[q],xticks_pos[q]], [-8, 8], linewidth=0.7, color='k')
for n in range(0,N_band):
plt_DFT, = ax0.plot(kpts, band[:,n], color='C0', linewidth=1.5)
for n in range(0,N_wann):
plt_wan, = ax0.plot(kpts_wann, band_WF[:,n], '--', color='C1', linewidth=1.5)
ax0.legend([plt_DFT, plt_wan], ['DFT', 'Wannier'])
ax0.set_xticks(xticks_pos)
ax0.set_xticklabels(xticks_label)
ax0.set_ylabel(r'$E_{n\mathbf{k}} - E_\mathrm{F}\ [\mathrm{eV}]$')
plt.show()
If you see perfect agreement between the DFT and Wannier band structures, congrats!