# Tutorial 2.2.3. Building the same system with less code # ======================================================= # # Physics background # ------------------ # Conductance of a quantum wire; subbands # # Kwant features highlighted # -------------------------- # - Using iterables and builder.HoppingKind for making systems # - introducing `reversed()` for the leads # # Note: Does the same as tutorial1a.py, but using other features of Kwant. import kwant # For plotting from matplotlib import pyplot # For matrix support import tinyarray #import numpy from numpy import * # define Pauli-matrices for convenience sigma_0 = tinyarray.array([[1, 0], [0, 1]]) sigma_x = tinyarray.array([[0, 1], [1, 0]]) sigma_y = tinyarray.array([[0, -1j], [1j, 0]]) sigma_z = tinyarray.array([[1, 0], [0, -1]]) def make_system(a=1, t=1.0, alpha=0.0, e_z=0.0, e_x=0.0, e_y=0.0, W=20, L=20): # Start with an empty tight-binding system and a single square lattice. # `a` is the lattice constant (by default set to 1 for simplicity. lat = kwant.lattice.square(a) sys = kwant.Builder() #### Define the scattering region. #### sys[(lat(x, y) for x in range(L) for y in range(W))] = \ 4 * t * sigma_0 + e_z * sigma_z + e_y * sigma_y + e_x * sigma_x # hoppings in x-direction sys[kwant.builder.HoppingKind((1, 0), lat, lat)] = \ -t * sigma_0 - 1j * alpha * sigma_y # hoppings in y-directions sys[kwant.builder.HoppingKind((0, 1), lat, lat)] = \ -t * sigma_0 + 1j * alpha * sigma_x #### Define and attach the leads. #### # Construct the left lead, index 0 lead = kwant.Builder(kwant.TranslationalSymmetry((-a, 0))) lead[(lat(0, j) for j in xrange(W))] = \ 4 * t * sigma_0 + e_z * sigma_z + e_x * sigma_x + e_y * sigma_y # hoppings in x-direction lead[kwant.builder.HoppingKind((1, 0), lat, lat)] = \ -t * sigma_0 - 1j * alpha * sigma_y # hoppings in y-directions lead[kwant.builder.HoppingKind((0, 1), lat, lat)] = \ -t * sigma_0 + 1j * alpha * sigma_x # Attach the left lead. sys.attach_lead(lead) # Construct the bottom lead, index 1 lead = kwant.Builder(kwant.TranslationalSymmetry((0, -a))) lead[(lat(j, 0) for j in xrange(L))] = \ 4 * t * sigma_0 + e_z * sigma_z + e_x * sigma_x + e_y * sigma_y # hoppings in x-direction lead[kwant.builder.HoppingKind((1, 0), lat, lat)] = \ -t * sigma_0 - 1j * alpha * sigma_y # hoppings in y-directions lead[kwant.builder.HoppingKind((0, 1), lat, lat)] = \ -t * sigma_0 + 1j * alpha * sigma_x # Attach the bottom lead and its reversed copy (top, index 2). sys.attach_lead(lead) sys.attach_lead(lead.reversed()) return sys def plot_conductance(sys, energies): # Compute conductance data = [] for energy in energies: smatrix = kwant.smatrix(sys, energy) data.append(smatrix.transmission(1, 0)) pyplot.figure() pyplot.plot(energies, data) pyplot.xlabel("energy [t]") pyplot.ylabel("conductance [e^2/h]") pyplot.show() def plot_ldos(sys, energy): # Compute local dos local_dos = kwant.ldos(sys, energy) # Calculate ldos per site, by summing spin up and spin down components local_dos = sum(local_dos.reshape(-1, 2), axis=1) kwant.plotter.map(sys, local_dos, num_lead_cells=5) def plot_ldos_up_down(sys, energy): # Compute local dos local_dos = kwant.ldos(sys, energy) # Calculate ldos_up and _down per site Nsites = local_dos.shape[0] / 2 local_dos_up = zeros((Nsites,)) local_dos_down = zeros((Nsites,)) for i in xrange(Nsites): local_dos_up[i] = local_dos[i * 2] local_dos_down[i] = local_dos[i * 2 + 1] # Plot kwant.plotter.map(sys, local_dos_up, num_lead_cells=5) kwant.plotter.map(sys, local_dos_down, num_lead_cells=5) def plot_Si(sys, energy, n_lead): # Compute wave function psi = kwant.wave_function(sys, energy) # print psi(n_lead) psi_n = psi(n_lead).sum(axis=0) # print psi_n # Calculate per site Nsites = psi_n.shape[0] / 2 sx = zeros((Nsites,)) sy = zeros((Nsites,)) sz = zeros((Nsites,)) psi_i = array([[0.0], [0.0]]) for i in xrange(Nsites): psi_i = array([[psi_n[i * 2]], [psi_n[i * 2 + 1]]]) sx[i] = abs(dot(psi_i.conj().T, dot(sigma_x, psi_i)))[0, 0] sy[i] = abs(dot(psi_i.conj().T, dot(sigma_y, psi_i)))[0, 0] sz[i] = abs(dot(psi_i.conj().T, dot(sigma_z, psi_i)))[0, 0] # Plot kwant.plotter.map(sys, sx, num_lead_cells=5) kwant.plotter.map(sys, sy, num_lead_cells=5) kwant.plotter.map(sys, sz, num_lead_cells=5) kwant.plotter.map(sys, sx+sy+sz, num_lead_cells=5) def main(): # sys = make_system() # Check that the system looks as intended. kwant.plot(sys) # Finalize the system. sys = sys.finalized() # We should see conductance steps. plot_conductance(sys, energies=[0.005 * i for i in xrange(-60, 120)]) plot_ldos(sys, energy=0.1) # plot_ldos_up_down(sys, energy=0.0) plot_Si(sys, energy=0.1, n_lead=0) # Call the main function if the script gets executed (as opposed to imported). # See . if __name__ == '__main__': main()