def find_gb_local(theta,phi,system, fm_width, n_orbitals=2, delta=0.01, omega=0, topo=True): """ Find localized Gilbert Damping as function of theta,phi for individual atomic sites. """ n_layers = system.n_layers u_theta = np.array([[np.cos(theta/2), 1*np.sin(theta/2)],[-1*np.sin(theta/2),np.cos(theta/2)]], dtype=np.complex_) u_phi = np.array([[np.exp(1.j*phi/2),0],[0,np.exp(-1.j*phi/2)]], dtype=np.complex_) u = np.dot(u_theta,u_phi) u_dag = calc.hermitian(u) v = sparse.kron(np.identity(n_orbitals*system.sites),np.dot(u_dag,np.dot(np.array([[0,1],[0,0]], dtype=np.complex_),u))).toarray() v_array = np.zeros((n_layers, n_layers), dtype=np.complex_) for num in range(fm_width): v_array[num,num] = 1 v_array = sparse.kron(v_array,v).toarray() img = (system.greens_ret - calc.hermitian(system.greens_ret)) / 2.j system.update_energy(system.energy+omega) img_2 =(system.greens_ret - calc.hermitian(system.greens_ret)) / 2.j d = (delta**2)*np.diag(np.dot(img,np.dot(v_array,np.dot(img_2,calc.hermitian(v_array))))) if topo: lgb = d[1::4] + d[::4]+d[2::4]+d[3::4] dos = np.diag(img) ldos_maj = dos[::4] + dos[2::4] ldos_min = dos[1::4] + dos[3::4] else: lgb = d[1::2] + d[::2] dos = np.diag(img) ldos_maj = dos[::2] ldos_min = dos[1::2] return [np.real(lgb),np.real(ldos_maj),np.real(ldos_min),np.real(dos)]
def inf_rashba_integrand(k,energy,layers=20,so_strength=0.0, theta=0.0, randomize=False,rando_strength=0.0, collector=[]): """ Integrand function for infinite Rashba plane k-integration. """ sigma_0 = 1.e-4+1.e-4j sites = 1 mag = 100 ener = energy delt = 0.1 on_site = -0.067+0.j rashba_sys = build_rashba(on_site,1,1,so_strength,sigma_0, 500, 0.5, sites, 1,ener+0.j) ras = rashba_sys[0] if randomize: ras = gd.randomize_hamil(ras,rando_strength,orbitals=1) t_x = rashba_sys[1] hamil_new = ras.hamil + ras.t_y * np.exp((k)*1.j) + calc.hermitian(ras.t_y) * np.exp((-k)*1.j) hamil_se = sparse.kron(on_site,np.identity(2)) + ras.t_y * np.exp((k)*1.j) + calc.hermitian(ras.t_y) * np.exp((-k)*1.j) hamil_new = calc.build_fm_island(calc.make_hamil_layers(hamil_new, layers, t_x,sites),theta,0,delt+0.j,sites,layers,padding=False,topo=False) off_diag = np.diag(hamil_new,1) print(off_diag) ras.update_hamil_2(hamil_new, sites, layers,no_mag_leads = True, hamil_sub = hamil_se) gb = gd.find_gb_local(theta,0,ras,fm_width=layers,n_orbitals=1,topo=False,delta=delt) gil = gb[0] s = 0 for i in range(gil.shape[0]): s+=gil[i] print("k = " + str(k)) print("s = " + str(s)) if randomize: collector.append(s) return s
def update_energy(self, E_new): self.energy = E_new self.e_array = sparse.kron(np.identity(self.hamil.shape[0]), E_new).toarray() self.self_energy_l = calc.self_energy(E_new, self.hamil_l, self.t_x, self.sigma_0, self.mixing, self.iterations, self.sites) self.self_energy_r = calc.self_energy(E_new, self.hamil_r, calc.hermitian(self.t_x), self.sigma_0, self.mixing, self.iterations, self.sites) self.sigma_l = calc.construct_sigma_l(self.self_energy_l, self.n_layers) self.sigma_r = calc.construct_sigma_r(self.self_energy_r, self.n_layers) self.greens_ret = self.combine(self.hamil, self.e_array, self.sigma_l, self.sigma_r, self.sites, self.n_layers) self.greens_adv = calc.hermitian(self.greens_ret) self.cond = self.conductance(self.sigma_l,self.sigma_r,self.greens_ret,self.greens_adv)
def conductance(self, sigma_l, sigma_r, greens_ret, greens_adv): """ Finds the conductance of the system using the retarded and advanced Green's functions and the sigma_l and sigma_r self-energy matrix elements. """ sigma_l_diff = sigma_l - calc.hermitian(sigma_l) sigma_r_diff = sigma_r - calc.hermitian(sigma_r) l_side = np.dot(greens_ret, sigma_l_diff) r_side = np.dot(greens_adv, sigma_r_diff) final = np.dot(l_side,r_side) return np.trace(final)
def update_hamil_layers(self,hamil_layers,num_on_site): self.hamil_layers = hamil_layers self.hamil_l = hamil_layers[:num_on_site*self.sites,:num_on_site*self.sites] self.hamil_r = hamil_layers[num_on_site*self.sites*(self.n_layers-1):,num_on_site*self.sites*(self.n_layers-1):] self.e_array = sparse.kron(np.identity(self.hamil_layers.shape[0]), self.energy).toarray() self.self_energy_l = calc.self_energy(self.energy, self.hamil_l, self.t_x, self.sigma_0, self.mixing, self.iterations, self.sites) self.self_energy_r = calc.self_energy(self.energy, self.hamil_r, calc.hermitian(self.t_x), self.sigma_0, self.mixing, self.iterations, self.sites) if np.array_equal(self.self_energy_l,self.self_energy_r): print("equal self energies") self.sigma_l = calc.construct_sigma_l(self.self_energy_l, self.n_layers) self.sigma_r = calc.construct_sigma_r(self.self_energy_r, self.n_layers) self.greens_ret = self.combine(self.hamil_layers, self.e_array, self.sigma_l, self.sigma_r, self.sites, self.n_layers) self.greens_adv = calc.hermitian(self.greens_ret) self.cond = self.conductance(self.sigma_l,self.sigma_r,self.greens_ret,self.greens_adv)
def gb_integrand(energy, omega, system, efermi, temp): """ Gilbert damping as function of energy & omega """ result_list = [] system.update_energy(energy) greens_up = system.greens_ret[::2,::2] img_1 = (greens_up - calc.hermitian(greens_up)) / 1.j system.update_energy(energy+omega) greens_down = system.greens_ret[1::2,1::2] img_2 = (greens_down - calc.hermitian(greens_down)) / 1.j r_side = np.trace(np.dot(img_1,img_2)) l_side = fermi_dist(energy+omega,efermi,temp) - fermi_dist(energy,efermi,temp) integrand = np.dot(l_side,r_side) return integrand
def update_hamil_mr(self,hamil_l_new,hamil_r_new,t_x): self.hamil = hamil_l_new self.n_layers = 2. self.hamil_layers = calc.make_hamil_layers_2([hamil_l_new,hamil_r_new], t_x,self.sites) self.hamil_r = hamil_r_new self.hamil_l = hamil_l_new self.e_array = sparse.kron(np.identity(self.hamil_layers.shape[0]), self.energy).toarray() self.self_energy_l = calc.self_energy(self.energy, hamil_l_new, self.t_x, self.sigma_0, self.mixing, self.iterations, self.sites) self.self_energy_r = calc.self_energy(self.energy, hamil_r_new, calc.hermitian(self.t_x), self.sigma_0, self.mixing, self.iterations, self.sites) if np.array_equal(self.self_energy_l,self.self_energy_r): print("equal self energies") self.sigma_l = calc.construct_sigma_l(self.self_energy_l, self.n_layers) self.sigma_r = calc.construct_sigma_r(self.self_energy_r, self.n_layers) self.greens_ret = self.combine(self.hamil_layers, self.e_array, self.sigma_l, self.sigma_r, self.sites, self.n_layers) self.greens_adv = calc.hermitian(self.greens_ret) self.cond = self.conductance(self.sigma_l,self.sigma_r,self.greens_ret,self.greens_adv)
def find_gb_theta_phi(theta,phi,system, fm_width=20, n_orbitals=2, delta=0.02, omega=0): """ Find Gilbert Damping as function of theta,phi. Turns entire system into a ferromagnet. """ n_layers = system.n_layers u_theta = np.array([[np.cos(theta/2), 1*np.sin(theta/2)],[-1*np.sin(theta/2),np.cos(theta/2)]], dtype=np.complex_) u_phi = np.array([[np.exp(1.j*phi/2),0],[0,np.exp(-1.j*phi/2)]], dtype=np.complex_) u = np.dot(u_theta,u_phi) u_dag = calc.hermitian(u) v = sparse.kron(np.identity(n_orbitals*system.sites),np.dot(u_dag,np.dot(np.array([[0,1],[0,0]], dtype=np.complex_),u))).toarray() v_array = np.zeros((n_layers, n_layers), dtype=np.complex_) for num in range(fm_width): v_array[num,num] = 1 v_array = sparse.kron(v_array,v).toarray() img = (system.greens_ret - calc.hermitian(system.greens_ret)) / 2.j return (delta**2)*np.trace(np.dot(img,np.dot(v_array,np.dot(img,calc.hermitian(v_array)))))
def generate_plot(): h_bar = 6.582E-16 q = 1 a = 1E-10 t = 1 c = 3.0E8 g = -2.002 N = 1 E = -1 Ez = 1000 eta = 0.01 + (0.01)*1.j sigma_x = np.array([[0,1],[1,0]]) sigma_y = np.array([[0, -1.j],[1.j,0]]) kxs = [] alphas = [] stxs = [] stys = [] for kx in pl.frange(0, 2*np.pi, 0.1): kxs.append(kx) kys = [] alphas_row = [] stxs_row = [] stys_row = [] for ky in pl.frange(0, 2*np.pi, 0.1): coeff = (-1)*g*q*(1/(h_bar**2))*(a**2)*(t**2)*(1/(2*c**2)) #print(coeff) hamil = sparse.kron(np.identity(2, dtype=np.complex_), t*(np.cos(kx)+np.cos(ky))) hamil += coeff*(np.cos(kx) + np.cos(ky))*(Ez*np.sin(ky)*sigma_x - Ez*np.sin(kx)*sigma_y) E_arr = sparse.kron(np.identity(2, dtype=np.complex_),E).toarray() greens = linalg.inv(E_arr-hamil-eta) img = (greens - calc.hermitian(greens))/(2.j) stxs_row.append(np.trace(np.dot(img,sigma_x))/2) stys_row.append(np.trace(np.dot(img,sigma_y))/2) kys.append(ky) alpha = np.trace(img)/2 alphas_row.append(alpha) #print(stxs_row) alphas.append(alphas_row) stxs.append(stxs_row) stys.append(stys_row) print(kx) print('loop over') x, y = np.meshgrid(kxs, kys) print('here') #print(alphas) alphas = np.array(alphas) stxs = np.array(stxs) stys = np.array(stys) print(stxs) #print(alphas) #fig = plt.figure() plt.pcolormesh(x, y, alphas) #plt.pcolormesh(x,y,stxs) plt.quiver(x, y, stxs, stys, color='red', angles='xy', scale_units='xy', scale=1) #plt.quiver(x, y, stys, color='red', headlength=10) print('mesh complete') #plt.colorbar() plt.show()
def inf_rashba_integrand_cond(k, energy, second=False,layers=20): """ Integrand for calculating conductance of infinite Rashba Plane """ sigma_0 = 1.e-4+1.e-4j sites = 1 so_strength = 0.00 mag = 100 delt = 0.1 on_site = -0.067+0.j rashba_sys = build_rashba(on_site,1,1,so_strength,sigma_0, 500, 0.5, sites, 1,energy+0.j) ras = rashba_sys[0] t_x = rashba_sys[1] hamil_new = ras.hamil + ras.t_y * np.exp((k)*1.j) + calc.hermitian(ras.t_y) * np.exp((-k)*1.j) hamil_se = sparse.kron(np.identity(2),on_site) + ras.t_y * np.exp((k)*1.j) + calc.hermitian(ras.t_y) * np.exp((-k)*1.j) hamil_new = calc.build_fm_island(calc.make_hamil_layers(hamil_new, layers, t_x,sites),np.radians(45),0,delt+0.j,sites,layers,padding=False,topo=False) ras.update_hamil_2(hamil_new, sites, layers,no_mag_leads = True, hamil_sub = hamil_se) cond = -ras.cond return cond
def update_hamil_2(self, hamil_layers, N, n_layers, no_mag_leads=False,hamil_sub=[]): #self.hamil = hamil_new self.n_layers = n_layers self.hamil_layers = hamil_layers #self.hamil_sep = np.hsplit(np.vsplit(hamil_layers, N),N) if not no_mag_leads: self.hamil_r = np.hsplit(np.vsplit(hamil_layers, self.n_layers)[-1],self.n_layers)[-1] self.hamil_l = np.hsplit(np.vsplit(hamil_layers, self.n_layers)[0],self.n_layers)[0] else: self.hamil_r = hamil_sub self.hamil_l = hamil_sub self.e_array = sparse.kron(np.identity(hamil_layers.shape[0]), self.energy).toarray() self.self_energy_l = calc.self_energy(self.energy, self.hamil_l, self.t_x, self.sigma_0, self.mixing, self.iterations, self.sites) self.self_energy_r = calc.self_energy(self.energy, self.hamil_r, calc.hermitian(self.t_x), self.sigma_0, self.mixing, self.iterations, self.sites) self.sigma_l = calc.construct_sigma_l(self.self_energy_l, n_layers) self.sigma_r = calc.construct_sigma_r(self.self_energy_r, n_layers) self.greens_ret = self.combine(self.hamil_layers, self.e_array, self.sigma_l, self.sigma_r, self.sites, 1) self.greens_adv = calc.hermitian(self.greens_ret) self.cond = self.conductance(self.sigma_l,self.sigma_r,self.greens_ret,self.greens_adv)
def __init__(self,E,h,t_y,sigma_0,a,iterations,N, n_layers, t_x): """ The Constructor class takes the inputs: int E -> energy int h -> value of Hamiltonian at each atomic site np.complex_ sigma_0 -> starting value for sigma convergence function int a -> mixing coefficient for sigma convergence int iterations -> number of iterations in sigma convergence loop int N -> number of sites in supercell int n_layers -> number of layers (supercells) in system int t_y -> width of supercell (in y-direction) int t_x -> hopping matrix for transport direction (x-direction) """ self.runtimes = [] #hamil_time_i = time.time() self.hamil = calc.hamiltonian(h,t_y,N) #hamil_time_o = time.time() self.hamil_layers = self.hamil self.hamil_l = self.hamil self.hamil_r = self.hamil self.t_y = t_y self.energy = E self.e_array = sparse.kron(np.identity(self.hamil.shape[0]), self.energy).toarray() self.sites = N self.n_layers = n_layers self.sigma_0 = sigma_0 self.iterations = iterations self.mixing = a self.t_x = t_x #selfe_time_i = time.time() self.self_energy_l = calc.self_energy(self.energy, self.hamil_l, t_x, sigma_0, a, iterations, N) self.self_energy_r = calc.self_energy(self.energy, self.hamil_r, calc.hermitian(t_x), sigma_0, a, iterations, N) self.sigma_l = calc.construct_sigma_l(self.self_energy_l, self.n_layers) self.sigma_r = calc.construct_sigma_r(self.self_energy_r, self.n_layers) selfe_time_o = time.time() #greens_time_i = time.time() self.greens_ret = self.combine(self.hamil, self.e_array, self.sigma_l, self.sigma_r, self.sites, self.n_layers) self.greens_adv = calc.hermitian(self.greens_ret) greens_time_o = time.time() #cond_time_i = time.time() self.cond = self.conductance(self.sigma_l,self.sigma_r,self.greens_ret,self.greens_adv)
def self_energy_vs_location(): """ Plot the self-energy of the system versus site location. """ sigma_0 = 1.e-4+1.e-4j sites = 5 so_strength = 0.01 mag = 100 delt = 0.1 on_site = -0.067+0.j layers = 20 rashba_sys = build_rashba(on_site,1,1,so_strength,sigma_0, 500, 0.5, sites, 1,energy+0.j) ras = rashba_sys[0] t_x = rashba_sys[1] hamil_new = ras.hamil + ras.t_y * np.exp((k)*1.j) + calc.hermitian(ras.t_y) * np.exp((-k)*1.j) hamil_se = sparse.kron(np.identity(2),on_site) + ras.t_y * np.exp((k)*1.j) + calc.hermitian(ras.t_y) * np.exp((-k)*1.j) hamil_new = calc.build_fm_island(calc.make_hamil_layers(hamil_new, layers, t_x,sites),np.radians(45),0,delt+0.j,sites,layers,padding=False,topo=False) ras.update_hamil_2(hamil_new, sites, layers,no_mag_leads = True, hamil_sub = hamil_se) greens = ras.greens_ret self_e = self_energy_integrand(greens, 0, 0, delta) print(self_e)
def expand_y(self, t_y,E, k_y): """ Expands the conductance function in the y-direction using a Fourier Transform. t_y is the value assigned to the y-direction connection between layers. """ if t_y == 0: return self.cond else: t_y_array = np.zeros((self.sites,self.sites)) t_y_array[0,self.sites-1] = 1.0 t_y_array = sparse.kron(t_y_array,t_y) t_y_array_dag = calc.hermitian(t_y_array) exponent = (1j)*(k_y) hamil_y = self.hamil + np.multiply(t_y_array, np.exp(exponent)).toarray() + np.multiply(t_y_array_dag, np.exp((-1)*exponent)).toarray() self_energy_y = calc.self_energy(self.energy, hamil_y, t_y, self.sigma_0, self.mixing, self.iterations, self.sites) sigma_l_y = calc.construct_sigma_l(self_energy_y, self.n_layers) sigma_r_y = calc.construct_sigma_r(self_energy_y, self.n_layers) e_array_y = sparse.kron(np.identity(hamil_y.shape[0]), E).toarray() greens_ret_y = self.combine(hamil_y, e_array_y, sigma_l_y, sigma_r_y, self.sites, self.n_layers) greens_adv_y = calc.hermitian(greens_ret_y) cond_y = self.conductance(sigma_l_y,sigma_r_y,greens_ret_y,greens_adv_y) return cond_y