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.Atom.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 main3(): import sys sys.path.insert(0, '/home/mk/TB_project/tb') import tb a = tb.Atom('A') a.add_orbital('s', -0.7) tb.Atom.orbital_sets = {'A': a} 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 = """1 H cell A1 0.0000000000 0.0000000000 0.0000000000 """ h = tb.Hamiltonian(xyz=xyz_file, nn_distance=2.1) h.initialize() h.set_periodic_bc([[0, 0, 1.0]]) h_l, h_0, h_r = h.get_coupling_hamiltonians() energy = np.linspace(-3.0, 1.5, 700) sgf_l = [] sgf_r = [] for E in energy: L, R, _, _, _ = surface_greens_function(E, h_l, h_0, h_r) # L, R = surface_greens_function_poles_Shur(E, h_l, h_0, h_r) 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=np.complex) for j, E in enumerate(energy): gf0 = np.matrix(gf[j, :, :]) gamma_l = 1j * (np.matrix(sgf_l[j, :, :]) - np.matrix(sgf_l[j, :, :]).H) gamma_r = 1j * (np.matrix(sgf_r[j, :, :]) - np.matrix(sgf_r[j, :, :]).H) tr[j] = np.real(np.trace(gamma_l * gf0 * gamma_r * gf0.H)) dos[j] = np.real(np.trace(1j * (gf0 - gf0.H))) print(sgf_l.shape)
def get_h_matrix(path): tb.Atom.orbital_sets = {'Si': 'SiliconSP3D5S', 'H': 'HydrogenS'} hamiltonian = tb.Hamiltonian(xyz=path, nn_distance=2.4) hamiltonian.initialize() a_si = 5.50 PRIMITIVE_CELL = [[0, 0, a_si]] hamiltonian.set_periodic_bc(PRIMITIVE_CELL) return hamiltonian.h_matrix
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.Atom('A') a.add_orbital( title='s', energy=site_energy1, ) b = tb.Atom('B') b.add_orbital( title='s', energy=site_energy2, ) tb.Atom.orbital_sets = {'A': a, 'B': b} 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() assert (h.is_hermitian(), True) 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 single_atom_chain(): """ Test set for a single-atom chain. :return: """ sys.path.insert(0, '/home/mk/TB_project/tb') a = tb.Atom('A') a.add_orbital('s', 0.7) tb.Atom.orbital_sets = {'A': a} 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_coupling_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 = tb.surface_greens_function(E, h_l, h_0, h_r) 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) gf = np.matrix(gf) gamma_l = 1j * (np.matrix(se_l) - np.matrix(se_l).H) gamma_r = 1j * (np.matrix(se_r) - np.matrix(se_r).H) tr[j] = np.real(np.trace(gamma_l * gf * gamma_r * gf.H)) dos[j] = np.real(np.trace(1j * (gf - gf.H))) sgf_l = np.array(sgf_l) sgf_r = np.array(sgf_r) return energy, dos, tr, h, sgf_l, sgf_r
def compute_tb_matrices(save=True): tb.Atom.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_coupling_hamiltonians() coords = h.get_site_coordinates() if save: np.save('h_l', h_l) np.save('h_0', h_0) np.save('h_r', h_r) np.save('coords', coords) return h_l, h_0, h_r, coords
def test_gf_single_atom_chain(): sys.path.insert(0, '/home/mk/TB_project/tb') a = tb.Atom('A') a.add_orbital('s', 0.7) tb.Atom.orbital_sets = {'A': a} 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_coupling_hamiltonians() energy = np.linspace(-3.0, 3.0, 300) sgf_l = [] sgf_r = [] for E in energy: L, R = tb.surface_greens_function(E, h_l, h_0, h_r) 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) np.testing.assert_allclose(sgf_l, sgf_r, atol=1e-5) expected = h_l * simple_chain_greens_function(energy, h_0, h_r) * h_r np.testing.assert_allclose(np.squeeze(sgf_r), np.squeeze(expected), atol=1e-5)
def test_simple_atomic_chain(): site_energy = -1.0 coupling = -1.0 l_const = 1.0 a = tb.Atom('A') a.add_orbital( title='s', energy=-1, ) tb.Atom.orbital_sets = {'A': a} 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() assert (h.is_hermitian(), True) 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 compute_tb_matrices(input_file, save=save_to): """ The script computes or load TB matrices from the disk. :param input_file: xyz-file for atomic system :param save: if is not None, save TB matrices into the directory specified by the parameter save :return: h_l, h_0, h_r, coords, path """ if os.path.isdir(input_file): h_l = np.load(os.path.join(input_file, 'h_l.npy')) h_0 = np.load(os.path.join(input_file, 'h_0.npy')) h_r = np.load(os.path.join(input_file, 'h_r.npy')) coords = np.load(os.path.join(input_file, 'coords.npy')) path = input_file else: tb.Atom.orbital_sets = {'Si': 'SiliconSP3D5S', 'H': 'HydrogenS'} h = tb.Hamiltonian(xyz=input_file, nn_distance=2.4) h.initialize() period = [0, 0, 5.50] h.set_periodic_bc([period]) h_l, h_0, h_r = h.get_coupling_hamiltonians() coords = h.get_site_coordinates() if save: sys_name = os.path.basename(input_file) # get the base name sys_name = os.path.splitext(sys_name)[0] # get rid of the extension path = os.path.join(save, sys_name) shutil.copy2(input_file, path) np.save(os.path.join(path, 'h_l'), h_l) np.save(os.path.join(path, 'h_0'), h_0) np.save(os.path.join(path, 'h_r'), h_r) np.save(os.path.join(path, 'coords'), coords) else: path = None return h_l, h_0, h_r, coords, path
def bs(path='c:\users\sammy\desktop\NanoNet\input_samples', kk=0, flag=True): """ This function computes the band gap / band structure for Silicon Nanowire :param path: directory path to where xyz input files are stored :param flag: boolean statements :return: band gap / band structure """ # define orbitals sets tb.Atom.orbital_sets = {'Si': 'SiliconSP3D5S', 'H': 'HydrogenS'} band_gaps = [] band_structures = [] for xyz_file in os.listdir(path): if xyz_file.endswith('xyz'): widths = [s for s in xyz_file if s.isdigit()] width = int(''.join(widths)) print(width) hamiltonian = tb.Hamiltonian(xyz=os.path.join(path, xyz_file), nn_distance=2.4) hamiltonian.initialize() if flag: plt.axis('off') plt.imshow(np.log(np.abs(hamiltonian.h_matrix))) plt.savefig('hamiltonian.pdf') plt.show() a_si = 5.50 PRIMITIVE_CELL = [[0, 0, a_si]] hamiltonian.set_periodic_bc(PRIMITIVE_CELL) num_points = len(kk) band_structure = [] for jj in xrange(num_points): print(jj) vals, _ = hamiltonian.diagonalize_periodic_bc([0, 0, kk[jj]]) band_structure.append(vals) band_structure = np.array(band_structure) band_structures.append(band_structure) cba = band_structure.copy() vba = band_structure.copy() cba[cba < 0] = 1000 vba[vba > 0] = -1000 band_gap = np.min(cba) - np.max(vba) band_gaps.append(band_gap) if flag: fig1, ax1 = plt.subplots() ax1.axes.set_xlim(0.0, 0.5) #ax1.axes.set_ylim(0.00, -0.04) ax1.axes.set_ylim(-0.3, 0.0) ax1.plot(kk, np.sort(np.real(vba))) ax1.set_xlabel(r'Wave vector ($\frac{\pi}{a}$)') ax1.set_ylabel(r'Energy (eV)') ax1.set_title('Valence band, NW width={} u.c.'.format(width)) fig1.tight_layout() plt.savefig('bs_vb.pdf') fig2, ax2 = plt.subplots() ax1.axes.set_xlim(0.0, 0.5) #ax2.axes.set_ylim(0.0, 0.06) ax2.axes.set_ylim(2.0, 2.5) ax2.plot(kk, np.sort(np.real(cba))) ax2.set_xlabel(r'Wave vector ($\frac{\pi}{a}$)') ax2.set_ylabel(r'Energy (eV)') ax2.set_title( 'Conduction band, NW width={} u.c.'.format(width)) fig2.tight_layout() plt.savefig('bs_cb.pdf') return band_gaps, band_structures
def test_gf_complex_chain(): sys.path.insert(0, '/home/mk/TB_project/tb') a = tb.Atom('A') a.add_orbital('s', -0.7) b = tb.Atom('B') b.add_orbital('s', -0.5) c = tb.Atom('C') c.add_orbital('s', -0.3) tb.Atom.orbital_sets = {'A': a, 'B': b, 'C': c} 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_coupling_hamiltonians() energy = np.linspace(-3.0, 1.5, 700) sgf_l = [] sgf_r = [] for E in energy: L, R = tb.surface_greens_function(E, h_l, h_0, h_r) 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) tr = np.zeros((energy.shape[0])) dos = np.zeros((energy.shape[0])) for j, E in enumerate(energy): gf0 = np.matrix(gf[j, :, :]) gamma_l = 1j * (np.matrix(sgf_l[j, :, :]) - np.matrix(sgf_l[j, :, :]).H) gamma_r = 1j * (np.matrix(sgf_r[j, :, :]) - np.matrix(sgf_r[j, :, :]).H) tr[j] = np.real(np.trace(gamma_l * gf0 * gamma_r * gf0.H)) dos[j] = np.real(np.trace(1j * (gf0 - gf0.H))) np.testing.assert_allclose(dos, expected_dos_of_complex_chain(), atol=1e-5) np.testing.assert_allclose(tr, expected_tr_of_complex_chain(), atol=1e-5)
def inverse_bs_problem(): import sys sys.path.insert(0, '/home/mk/TB_project/tb') import tb # a = tb.Atom('A') # a.add_orbital('s', -0.7) # b = tb.Atom('B') # b.add_orbital('s', -0.5) # c = tb.Atom('C') # c.add_orbital('s', -0.3) # # tb.Atom.orbital_sets = {'A': a, 'B': b, 'C': c} # # tb.set_tb_params(PARAMS_A_A={'ss_sigma': -0.5}, # PARAMS_B_B={'ss_sigma': -0.5}, # PARAMS_C_C={'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 = """6 # H cell # A1 0.0000000000 0.0000000000 0.0000000000 # B2 0.0000000000 0.0000000000 1.0000000000 # C3 0.0000000000 0.0000000000 2.0000000000 # A4 0.0000000000 1.0000000000 0.0000000000 # B5 0.0000000000 1.0000000000 1.0000000000 # C6 0.0000000000 1.0000000000 2.0000000000 # """ # # h = tb.Hamiltonian(xyz=xyz_file, nn_distance=1.1) # h.initialize() # h.set_periodic_bc([[0, 0, 3.0]]) tb.Atom.orbital_sets = {'Si': 'SiliconSP3D5S', 'H': 'HydrogenS'} h = tb.Hamiltonian(xyz='/home/mk/TB_project/input_samples/SiNW.xyz', nn_distance=2.4) h.initialize() h.set_periodic_bc([[0, 0, 5.50]]) h_l, h_0, h_r = h.get_coupling_hamiltonians() # energy = np.linspace(2.13, 2.15, 20) # energy = np.linspace(-2.1, 1.0, 50) energy = np.linspace(2.05, 2.5, 200) # energy = np.linspace(2.07, 2.3, 50) + 0.2 # energy = np.linspace(2.3950, 2.4050, 20) # energy = energy[20:] eigs = [] for E in energy: print(E) vals, vects = surface_greens_function_poles(E, h_l, h_0, h_r) vals = np.diag(vals) vals.setflags(write=1) for j, v in enumerate(vals): if np.abs(np.absolute(v) - 1.0) > 0.01: vals[j] = float('nan') else: vals[j] = np.angle(v) print("The element number is", j, vals[j]) eigs.append(vals) plt.plot(energy, np.array(eigs), 'o') plt.show()
def main1(): import sys sys.path.insert(0, '/home/mk/TB_project/tb') import tb tb.Atom.orbital_sets = {'Si': 'SiliconSP3D5S', 'H': 'HydrogenS'} h = tb.Hamiltonian(xyz='/home/mk/NEGF_project/SiNW.xyz', nn_distance=2.4) h.initialize() h.set_periodic_bc([[0, 0, 5.50]]) h_l, h_0, h_r = h.get_coupling_hamiltonians() # energy = np.linspace(2.07, 2.3, 50) # energy = np.linspace(2.07, 2.3, 50) + 0.2 # energy = np.linspace(-1.0, -0.3, 200) energy = np.concatenate((np.linspace(-0.8, -0.3, 100), np.linspace(2.05, 2.5, 100))) # energy = np.linspace(2.3950, 2.4050, 20) # energy = energy[20:35] sgf_l = [] sgf_r = [] factor = [] factor1 = [] factor2 = [] num_sites = h_0.shape[0] for j, E in enumerate(energy): # L, R = surface_greens_function_poles_Shur(j, E, h_l, h_0, h_r) L, R, _, _, _ = surface_greens_function(E, h_l, h_0, h_r) test_gf = E * np.identity(num_sites) - h_0 - L - R metrics = np.linalg.cond(test_gf) print("{} of {}: energy is {}, metrics is {}".format( j + 1, energy.shape[0], E, metrics)) # if metrics > 15000: # R = iterate_gf(E, h_0, h_l, h_r, R, 1) # L = iterate_gf(E, h_0, h_l, h_r, L, 1) sgf_l.append(L) sgf_r.append(R) # factor.append(phase) # factor1.append(phase1) # factor2.append(phase2) sgf_l = np.array(sgf_l) sgf_r = np.array(sgf_r) factor = np.array(factor) factor1 = np.array(factor1) factor2 = np.array(factor2) gf = np.linalg.pinv( np.multiply.outer(energy, np.identity(num_sites)) - h_0 - sgf_l - sgf_r) # gf = regularize_gf(gf) dos = -np.trace(np.imag(gf), axis1=1, axis2=2) tr = np.zeros((energy.shape[0]), dtype=np.complex) dos = np.zeros((energy.shape[0]), dtype=np.complex) for j, E in enumerate(energy): gf0 = np.matrix(gf[j, :, :]) gamma_l = 1j * (np.matrix(sgf_l[j, :, :]) - np.matrix(sgf_l[j, :, :]).H) gamma_r = 1j * (np.matrix(sgf_r[j, :, :]) - np.matrix(sgf_r[j, :, :]).H) dos[j] = np.real(np.trace(1j * (gf0 - gf0.H))) tr[j] = np.real(np.trace(gamma_l * gf0 * gamma_r * gf0.H)) ax = plt.axes() ax.set_xlabel('Energy (eV)') ax.set_ylabel('DOS') ax.plot(energy, dos) plt.show() ax = plt.axes() ax.set_xlabel('Energy (eV)') ax.set_ylabel('Transmission coefficient (a.u.)') ax.plot(energy, tr) plt.show() plt.plot(dos) plt.show() print(sgf_l.shape)