Plots for PbTiO3¶

Made by Dongwook Go (d.go@fz-juelich.de)

Let's first import life-saving libraries:

In [ ]:
import numpy as np
import matplotlib.pyplot as plt

1. DFT band structure¶

The DFT band structure of PbTiO3 can be found in Wannier/data/PbTiO3/bands.1. Let's import this to a numpy array.

In [ ]:
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.

In [ ]:
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.

In [ ]:
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.

In [ ]:
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()

2. Orbital-resolved DOS¶

The DOS of PbTiO3 can be found in Wannier/data/PbTiO3/Local.1. Let's import this into a numpy array.

In [ ]:
DOS_raw = np.genfromtxt('PbTiO3/Local.1')

And we put them into separate one-dimensional arrays for each orbital character.

In [ ]:
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.

In [ ]:
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.

3. Comparison of the DFT and Wannier band structures¶

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.

In [ ]:
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

In [ ]:
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!