def test_bulk_silicon(): """ """ a_si = 5.50 PRIMITIVE_CELL = [[0, 0.5 * a_si, 0.5 * a_si], [0.5 * a_si, 0, 0.5 * a_si], [0.5 * a_si, 0.5 * a_si, 0]] tb.Orbitals.orbital_sets = {'Si': 'SiliconSP3D5S'} xyz_file = """2 Si2 cell Si1 0.0000000000 0.0000000000 0.0000000000 Si2 1.3750000000 1.3750000000 1.3750000000 """ h = tb.Hamiltonian(xyz=xyz_file, nn_distance=2.5) h.initialize() h.set_periodic_bc(PRIMITIVE_CELL) sym_points = ['L', 'GAMMA', 'X'] num_points = [10, 25] k = tb.get_k_coords(sym_points, num_points, 'Si') band_sructure = [] vals = np.zeros((sum(num_points), h.h_matrix.shape[0]), dtype=np.complex) for jj, item in enumerate(k): vals[jj, :], _ = h.diagonalize_periodic_bc(item) band_structure = np.real(np.array(vals)) np.testing.assert_allclose(band_structure, expected_bulk_silicon_band_structure(), atol=1e-4)
def graphene_nanotube(): from ase.build.tube import nanotube from ase.visualize.plot import plot_atoms n = 10 m = 10 atoms = nanotube(n, m) atoms.wrap() period = np.array([list(atoms.get_cell()[2])]) period[:, [1, 2]] = period[:, [2, 1]] coord = atoms.get_positions() coord[:, [1, 2]] = coord[:, [2, 1]] coords = [] coords.append(str(len(coord))) coords.append('Nanoribbon') for j, item in enumerate(coord): coords.append('C' + str(j + 1) + ' ' + str(item[0]) + ' ' + str(item[1]) + ' ' + str(item[2])) coords = '\n'.join(coords) # --------------------------- Basis set -------------------------- s_orb = tb.Orbitals('C') s_orb.add_orbital("pz", energy=0, orbital=1, magnetic=0, spin=0) # s_orb.add_orbital("py", energy=0, orbital=1, magnetic=1, spin=0) # s_orb.add_orbital("px", energy=0, orbital=1, magnetic=-1, spin=0) # ------------------------ set TB parameters---------------------- t = 2.8 tb.set_tb_params(PARAMS_C_C={'pp_pi': t}) # --------------------------- Hamiltonian ------------------------- h = tb.Hamiltonian(xyz=coords, nn_distance=1.7, comp_angular_dep=False) h.initialize() h.set_periodic_bc(period) k_points = np.linspace(0.0, np.pi/period[0][1], 20) band_structure = np.zeros((len(k_points), h.h_matrix.shape[0])) for jj, item in enumerate(k_points): band_structure[jj, :], _ = h.diagonalize_periodic_bc([0.0, item, 0.0]) # visualize ax = plt.axes() ax.set_title('Band structure of carbon nanotube, ({0}, {1}) \n 1st nearest neighbour approximation'.format(n, m)) ax.set_ylabel('Energy (eV)') ax.set_xlabel(r'Wave vector ($\frac{\pi}{a}$)') ax.plot(k_points, np.sort(band_structure), 'k') ax.xaxis.grid() plt.show() ax1 = plot_atoms(atoms, show_unit_cell=2, rotation='10x,50y,30z') ax1.axis('off') plt.show()
def graphene_third_nearest_neighbour_with_overlaps(): """ All parameters are taken from Reich et al, Phys. Rev. B 66, 035412 (2002) Returns ------- """ coords = """2 Graphene C1 0.00 0.00 0.00 C2 {} 0.00 0.00 """.format(lat_const) # --------------------------- Basis set -------------------------- s_orb = tb.Orbitals('C') s_orb.add_orbital("pz", energy=-0.28, orbital=1, magnetic=0, spin=0) # ------------------------ set TB parameters---------------------- gamma0 = -2.97 gamma1 = -0.073 gamma2 = -0.33 s0 = 0.073 s1 = 0.018 s2 = 0.026 tb.set_tb_params(PARAMS_C_C1={'pp_pi': gamma0}, PARAMS_C_C2={'pp_pi': gamma1}, PARAMS_C_C3={'pp_pi': gamma2}, OV_C_C1={'pp_pi': s0}, OV_C_C2={'pp_pi': s1}, OV_C_C3={'pp_pi': s2}) # --------------------------- Hamiltonian ------------------------- h = tb.Hamiltonian(xyz=coords, nn_distance=3.1, comp_overlap=True) h.initialize(radial_dep) h.set_periodic_bc(period) band_structure = np.zeros((sum(num_points), h.h_matrix.shape[0])) for jj, item in enumerate(k_points): band_structure[jj, :], _ = h.diagonalize_periodic_bc(item) # visualize global fig_counter plt.figure(fig_counter) fig_counter += 1 ax = plt.axes() ax.set_title('Band structure of graphene, 3d NN \n after Reich et al, Phys. Rev. B 66, 035412 (2002)') ax.set_ylabel('Energy (eV)') ax.plot(np.sort(band_structure), 'k') ax.plot([0, band_structure.shape[0]], [0, 0], '--', color='k', linewidth=0.5) plt.xticks(np.insert(np.cumsum(num_points) - 1, 0, 0), labels=sym_points) ax.xaxis.grid() plt.show()
def single_atom_chain(): """Test set for a single-atom chain. :return: Parameters ---------- Returns ------- """ sys.path.insert(0, '/home/mk/TB_project/tb') a = tb.Orbitals('A') a.add_orbital('s', 0.7) tb.set_tb_params(PARAMS_A_A={'ss_sigma': 0.5}) xyz_file = """1 H cell A1 0.0000000000 0.0000000000 0.0000000000 """ h = tb.Hamiltonian(xyz=xyz_file, nn_distance=1.1) h.initialize() h.set_periodic_bc([[0, 0, 1.0]]) h_l, h_0, h_r = h.get_hamiltonians() num_sites = h_0.shape[0] energy = np.linspace(-3.0, 3.0, 300) tr = np.zeros((energy.shape[0])) dos = np.zeros((energy.shape[0])) sgf_l = [] sgf_r = [] for j, E in enumerate(energy): se_l, se_r = negf.surface_greens_function(E, h_l, h_0, h_r, iterate=False) sgf_l.append(se_l) sgf_r.append(se_r) gf = np.linalg.pinv(E * np.identity(num_sites) - h_0 - se_l - se_r) gamma_l = 1j * (se_l - se_l.conj().T) gamma_r = 1j * (se_r - se_r.conj().T) tr[j] = np.real(np.trace( gamma_l.dot(gf).dot(gamma_r).dot(gf.conj().T))) dos[j] = np.real(np.trace(1j * (gf - gf.conj().T))) sgf_l = np.array(sgf_l) sgf_r = np.array(sgf_r) return energy, dos, tr, h, sgf_l, sgf_r
def main(energy): # define the basis set - one s-type orbital orb = tb.Orbitals('A') orb.add_orbital('s', energy=-1.0) # set TB parameters tb.set_tb_params(PARAMS_A_A={"ss_sigma": 1.0}) # define atomic coordinates for the unit cell input_file = """4 Nanostrip A1 0.0 0.0 0.0 A2 0.0 1.0 0.0 A3 0.0 2.0 0.0 A4 0.0 3.0 0.0 """ # compute Hamiltonian matrices h = tb.Hamiltonian(xyz=input_file, nn_distance=1.4) h.initialize() period = [0, 0, 1.0] h.set_periodic_bc([period]) h_l, h_0, h_r = h.get_hamiltonians() # compute DOS and transmission using Green's functions dos = np.zeros((energy.shape[0])) tr = np.zeros((energy.shape[0])) for j, E in enumerate(energy): # compute surface Green's functions L, R = surface_greens_function(E, h_l, h_0, h_r) # recursive Green's functions g_trans, grd, grl, gru, gr_left = recursive_gf(E, [h_l], [h_0 + L + R], [h_r]) # compute DOS dos[j] = np.real(np.trace(1j * (grd[0] - grd[0].conj().T))) # compute left-lead coupling gamma_l = 1j * (L - L.conj().T) # compute right-lead coupling gamma_r = 1j * (R - R.conj().T) # compute transmission tr[j] = np.real( np.trace(gamma_l.dot(g_trans).dot(gamma_r).dot(g_trans.conj().T))) print("{} of {}: energy is {}".format(j + 1, energy.shape[0], E)) tr = np.array(tr) dos = np.array(dos) return dos, tr
def test_atomic_chain_two_kinds_of_atoms(): """ """ site_energy1 = -1.0 site_energy2 = -2.0 coupling = -1.0 l_const = 2.0 a = tb.Orbitals('A') a.add_orbital( title='s', energy=site_energy1, ) b = tb.Orbitals('B') b.add_orbital( title='s', energy=site_energy2, ) xyz_file = """2 H cell A 0.0000000000 0.0000000000 0.0000000000 B 0.0000000000 0.0000000000 1.0000000000 """ tb.set_tb_params(PARAMS_A_B={'ss_sigma': coupling}) h = tb.Hamiltonian(xyz=xyz_file, nn_distance=1.1) h.initialize() PRIMITIVE_CELL = [[0, 0, l_const]] h.set_periodic_bc(PRIMITIVE_CELL) num_points = 10 kk = np.linspace(0, 3.14 / 2, num_points, endpoint=True) band_structure = [] for jj in range(num_points): vals, _ = h.diagonalize_periodic_bc([0.0, 0.0, kk[jj]]) band_structure.append(vals) band_structure = np.array(band_structure) desired_value = np.zeros(band_structure.shape) b = site_energy1 + site_energy2 c = site_energy1 * site_energy2 - (2.0 * coupling * np.cos(0.5 * kk * l_const))**2 desired_value[:, 0] = 0.5 * (b - np.sqrt(b**2 - 4.0 * c)) desired_value[:, 1] = 0.5 * (b + np.sqrt(b**2 - 4.0 * c)) np.testing.assert_allclose(band_structure, desired_value, atol=1e-9)
def graphene_first_nearest_neighbour(): coords = """2 Graphene C1 0.00 0.00 0.00 C2 {} 0.00 0.00 """.format(lat_const) # --------------------------- Basis set -------------------------- s_orb = tb.Orbitals('C') s_orb.add_orbital("pz", energy=0, orbital=1, magnetic=0, spin=0) # ------------------------ set TB parameters---------------------- t = 2.8 tb.set_tb_params(PARAMS_C_C={'pp_pi': t}) # --------------------------- Hamiltonian ------------------------- h = tb.Hamiltonian(xyz=coords, nn_distance=1.5) h.initialize() h.set_periodic_bc(period) band_structure = np.zeros((sum(num_points), h.h_matrix.shape[0])) for jj, item in enumerate(k_points): band_structure[jj, :], _ = h.diagonalize_periodic_bc(item) # visualize global fig_counter plt.figure(fig_counter) fig_counter += 1 ax = plt.axes() ax.set_title(r'Band structure of graphene, 1st NN') ax.set_ylabel('Energy (eV)') ax.plot(np.sort(band_structure), 'k') ax.plot([0, band_structure.shape[0]], [0, 0], '--', color='k', linewidth=0.5) plt.xticks(np.insert(np.cumsum(num_points) - 1, 0, 0), labels=sym_points) ax.xaxis.grid() plt.show()
def test_simple_atomic_chain(): """ """ site_energy = -1.0 coupling = -1.0 l_const = 1.0 a = tb.Orbitals('A') a.add_orbital( title='s', energy=-1, ) xyz_file = """1 H cell A 0.0000000000 0.0000000000 0.0000000000 """ tb.set_tb_params(PARAMS_A_A={'ss_sigma': -1.0}) h = tb.Hamiltonian(xyz=xyz_file, nn_distance=1.1) h.initialize() PRIMITIVE_CELL = [[0, 0, l_const]] h.set_periodic_bc(PRIMITIVE_CELL) num_points = 10 kk = np.linspace(0, 3.14 / l_const, num_points, endpoint=True) band_structure = [] for jj in range(num_points): vals, _ = h.diagonalize_periodic_bc([0.0, 0.0, kk[jj]]) band_structure.append(vals) band_structure = np.array(band_structure) desired_value = site_energy + 2 * coupling * np.cos(l_const * kk) np.testing.assert_allclose(band_structure, desired_value[:, np.newaxis], atol=1e-9)
def complex_chain(): """ """ sys.path.insert(0, '/home/mk/TB_project/tb') a = tb.Orbitals('A') a.add_orbital('s', -0.7) b = tb.Orbitals('B') b.add_orbital('s', -0.5) c = tb.Orbitals('C') c.add_orbital('s', -0.3) tb.set_tb_params(PARAMS_A_A={'ss_sigma': -0.5}, PARAMS_B_B={'ss_sigma': -0.5}, PARAMS_A_B={'ss_sigma': -0.5}, PARAMS_B_C={'ss_sigma': -0.5}, PARAMS_A_C={'ss_sigma': -0.5}) xyz_file = """4 H cell A1 0.0000000000 0.0000000000 0.0000000000 B2 0.0000000000 0.0000000000 1.0000000000 A2 0.0000000000 1.0000000000 0.0000000000 B3 0.0000000000 1.0000000000 1.0000000000 """ h = tb.Hamiltonian(xyz=xyz_file, nn_distance=1.1) h.initialize() h.set_periodic_bc([[0, 0, 2.0]]) h_l, h_0, h_r = h.get_hamiltonians() energy = np.linspace(-3.0, 1.5, 700) sgf_l = [] sgf_r = [] for E in energy: left_se, right_se = negf.surface_greens_function(E, h_l, h_0, h_r, iterate=5) sgf_l.append(left_se) sgf_r.append(right_se) sgf_l = np.array(sgf_l) sgf_r = np.array(sgf_r) num_sites = h_0.shape[0] gf = np.linalg.pinv( np.multiply.outer(energy, np.identity(num_sites)) - h_0 - sgf_l - sgf_r) tr = np.zeros((energy.shape[0])) dos = np.zeros((energy.shape[0])) for j, E in enumerate(energy): gf0 = gf[j, :, :] gamma_l = 1j * (sgf_l[j, :, :] - sgf_l[j, :, :].conj().T) gamma_r = 1j * (sgf_r[j, :, :] - sgf_r[j, :, :].conj().T) tr[j] = np.real( np.trace(gamma_l.dot(gf0).dot(gamma_r).dot(gf0.conj().T))) dos[j] = np.real(np.trace(1j * (gf0 - gf0.conj().T))) return energy, dos, tr, h, sgf_l, sgf_r
def graphene_nanoribbons_armchair(): from ase.build.ribbon import graphene_nanoribbon from ase.visualize.plot import plot_atoms atoms = graphene_nanoribbon(11, 1, type='armchair') period = np.array([list(atoms.get_cell()[2])]) period[:, [1, 2]] = period[:, [2, 1]] coord = atoms.get_positions() coord[:, [1, 2]] = coord[:, [2, 1]] coords = [] coords.append(str(len(coord))) coords.append('Nanoribbon') for j, item in enumerate(coord): coords.append('C' + str(j+1) + ' ' + str(item[0]) + ' ' + str(item[1]) + ' ' + str(item[2])) coords = '\n'.join(coords) s_orb = tb.Orbitals('C') s_orb.add_orbital("pz", energy=-0.28, orbital=1, magnetic=0, spin=0) # ------------------------ set TB parameters---------------------- gamma0 = -2.97 gamma1 = -0.073 gamma2 = -0.33 s0 = 0.073 s1 = 0.018 s2 = 0.026 tb.set_tb_params(PARAMS_C_C1={'pp_pi': gamma0}, PARAMS_C_C2={'pp_pi': gamma1}, PARAMS_C_C3={'pp_pi': gamma2}, OV_C_C1={'pp_pi': s0}, OV_C_C2={'pp_pi': s1}, OV_C_C3={'pp_pi': s2}) # --------------------------- Hamiltonian ------------------------- h = tb.Hamiltonian(xyz=coords, nn_distance=3.1, comp_overlap=True) h.initialize(radial_dep) h.set_periodic_bc(period) k_points = np.linspace(0.0, np.pi/period[0][1], 20) band_structure = np.zeros((len(k_points), h.h_matrix.shape[0])) for jj, item in enumerate(k_points): band_structure[jj, :], _ = h.diagonalize_periodic_bc([0.0, item, 0.0]) # visualize ax = plt.axes() ax.set_title('Graphene nanoribbon, armchair 11') ax.set_ylabel('Energy (eV)') ax.set_xlabel(r'Wave vector ($\frac{\pi}{a}$)') ax.plot(k_points, np.sort(band_structure), 'k') ax.xaxis.grid() plt.show() ax1 = plot_atoms(atoms, show_unit_cell=2, rotation='90x,0y,00z') ax1.axis('off') plt.show()
A3 2.0000000000 0.0000000000 0.0000000000 A4 3.0000000000 0.0000000000 0.0000000000 A5 4.0000000000 0.0000000000 0.0000000000 A6 5.0000000000 0.0000000000 0.0000000000 A7 6.0000000000 0.0000000000 0.0000000000 A8 7.0000000000 0.0000000000 0.0000000000 A9 8.0000000000 0.0000000000 0.0000000000 A10 9.0000000000 0.0000000000 0.0000000000 A11 10.0000000000 0.0000000000 0.0000000000 A12 11.0000000000 0.0000000000 0.0000000000 A13 12.0000000000 0.0000000000 0.0000000000 A14 13.0000000000 0.0000000000 0.0000000000 A15 14.0000000000 0.0000000000 0.0000000000 """ h = tb.Hamiltonian(xyz=xyz_file, nn_distance=1.1) h.initialize() h.set_periodic_bc([[0, 0, 1.0]]) h_l, h_0, h_r = h.get_hamiltonians() # Now that the Hamiltonian is constructed within the TB # framework, we set our numerical parameters to be # examined. We choose two endpoints mu +/- dmu, # the temperature being evaluated, the relative tolerance # of the pole summation and the numerical integration Emin = -3.98 ChemPot = -3.91 kT = 0.005 reltol = 10**-10 p = np.ceil(-np.log(reltol)) # Integer number of kT away to get the desired relative tolerance.
import numpy as np import matplotlib.pyplot as plt import nanonet.tb as tb from nanonet.tb.reduced_mode_space import bs, reduce_mode_space import pickle if __name__ == '__main__': # make hamiltonian matrices tb.Orbitals.orbital_sets = {'Si': 'SiliconSP3D5S', 'H': 'HydrogenS'} h = tb.Hamiltonian(xyz='/home/mk/TB_project/input_samples/SiNW2.xyz', nn_distance=2.4) h.initialize() period = [0, 0, 5.50] h.set_periodic_bc([period]) h_l, h_0, h_r = h.get_hamiltonians() # compute band structure energy = np.linspace(1.4, 1.9, 30) h_l_reduced, h_0_reduced, h_r_reduced, vals_for_plot, a = reduce_mode_space( energy, h_l, h_0, h_r, 0.1) # vals = [] # vecs = [] # vals_for_plot = [] # # for E in energy: # print(E) # val, vec, val_for_plot = bs(E, h_l, h_0, h_r) # vals.append(val)
def main(surf_greens_fun): """ An example for the Green's function usage""" a = tb.Orbitals('A') a.add_orbital('s', -0.7) tb.Orbitals.orbital_sets = {'A': a} tb.set_tb_params(PARAMS_A_A={'ss_sigma': -0.5}) xyz_file = """1 A cell A1 0.0000000000 0.0000000000 0.0000000000 """ h = tb.Hamiltonian(xyz=xyz_file, nn_distance=1.1) h.initialize() h.set_periodic_bc([[0, 0, 1.0]]) h_l, h_0, h_r = h.get_hamiltonians() energy = np.linspace(-3.0, 1.5, 700) sgf_l = [] sgf_r = [] for E in energy: sf = surf_greens_fun(E, h_l, h_0, h_r, damp=0.001j) if isinstance(sf, tuple): L = sf[0] R = sf[1] else: L = sf R = surf_greens_fun(E, h_r, h_0, h_l, damp=0.001j) sgf_l.append(L) sgf_r.append(R) sgf_l = np.array(sgf_l) sgf_r = np.array(sgf_r) num_sites = h_0.shape[0] gf = np.linalg.pinv( np.multiply.outer(energy, np.identity(num_sites)) - h_0 - sgf_l - sgf_r) dos = -np.trace(np.imag(gf), axis1=1, axis2=2) tr = np.zeros((energy.shape[0]), dtype=complex) for j, E in enumerate(energy): gf0 = gf[j, :, :] gamma_l = 1j * (sgf_l[j, :, :] - sgf_l[j, :, :].conj().T) gamma_r = 1j * (sgf_r[j, :, :] - sgf_r[j, :, :].conj().T) tr[j] = np.real( np.trace(np.linalg.multi_dot([gamma_l, gf0, gamma_r, gf0.conj().T]))) dos[j] = np.real(np.trace(1j * (gf0 - gf0.conj().T))) fig, axs = plt.subplots(2, figsize=(5, 7)) fig.suptitle('Green\'s function technique') axs[0].plot(energy, dos, 'k') # axs[0].title.set_text('Density of states') axs[0].set_xlabel('Energy (eV)') axs[0].set_ylabel('DOS') axs[1].plot(energy, tr, 'k') # axs[1].title.set_text('Transmission function') axs[1].set_xlabel('Energy (eV)') axs[1].set_ylabel('Transmission probability') plt.show(block=False)