def test_selfenergy_interpolation(atoms, ntk, filename, begin, end, base, scale, direction=0): from gpaw.transport.sparse_matrix import Banded_Sparse_HSD, CP_Sparse_HSD, Se_Sparse_Matrix from gpaw.transport.selfenergy import LeadSelfEnergy from gpaw.transport.contour import Contour hl_skmm, sl_kmm = get_hs(atoms) dl_skmm = get_lcao_density_matrix(atoms.calc) fermi = atoms.calc.get_fermi_level() wfs = atoms.calc.wfs hl_spkmm, sl_pkmm, dl_spkmm, \ hl_spkcmm, sl_pkcmm, dl_spkcmm = get_pk_hsd(2, ntk, wfs.kd.ibzk_qc, hl_skmm, sl_kmm, dl_skmm, None, wfs.dtype, direction=direction) my_npk = len(wfs.kd.ibzk_qc) / ntk my_nspins = len(wfs.kpt_u) / ( my_npk * ntk) lead_hsd = Banded_Sparse_HSD(wfs.dtype, my_nspins, my_npk) lead_couple_hsd = CP_Sparse_HSD(wfs.dtype, my_nspins, my_npk) for pk in range(my_npk): lead_hsd.reset(0, pk, sl_pkmm[pk], 'S', init=True) lead_couple_hsd.reset(0, pk, sl_pkcmm[pk], 'S', init=True) for s in range(my_nspins): lead_hsd.reset(s, pk, hl_spkmm[s, pk], 'H', init=True) lead_hsd.reset(s, pk, dl_spkmm[s, pk], 'D', init=True) lead_couple_hsd.reset(s, pk, hl_spkcmm[s, pk], 'H', init=True) lead_couple_hsd.reset(s, pk, dl_spkcmm[s, pk], 'D', init=True) lead_se = LeadSelfEnergy(lead_hsd, lead_couple_hsd) begin += fermi end += fermi ee = np.linspace(begin, end, base) cmp_ee = np.linspace(begin, end, base * scale) se = [] cmp_se = [] from scipy import interpolate for e in ee: se.append(lead_se(e).recover()) se = np.array(se) ne, ny, nz= se.shape nie = len(cmp_ee) data = np.zeros([nie, ny, nz], se.dtype) for yy in range(ny): for zz in range(nz): ydata = se[:, yy, zz] f = interpolate.interp1d(ee, ydata) data[:, yy, zz] = f(cmp_ee) inter_se_linear = data for e in cmp_ee: cmp_se.append(lead_se(e).recover()) fd = file(filename, 'w') cPickle.dump((cmp_se, inter_se_linear, ee, cmp_ee), fd, 2) fd.close() for i,e in enumerate(cmp_ee): print(e, np.max(abs(cmp_se[i] - inter_se_linear[i])), 'linear', np.max(abs(cmp_se[i])))
def initialize_selfenergy_and_green_function(self, tp): self.selfenergies = [] if tp.use_lead: for i in range(tp.lead_num): self.selfenergies.append( LeadSelfEnergy(tp.lead_hsd[i], tp.lead_couple_hsd[i])) self.selfenergies[i].set_bias(tp.bias[i])
def generate_selfenergy_database(atoms, ntk, filename, direction=0, kt=0.1, bias=[-3, 3], depth=3, comm=None): from gpaw.transport.sparse_matrix import Banded_Sparse_HSD, CP_Sparse_HSD, Se_Sparse_Matrix from gpaw.transport.selfenergy import LeadSelfEnergy from gpaw.transport.contour import Contour hl_skmm, sl_kmm = get_hs(atoms) dl_skmm = get_lcao_density_matrix(atoms.calc) fermi = atoms.calc.get_fermi_level() wfs = atoms.calc.wfs hl_spkmm, sl_pkmm, dl_spkmm, \ hl_spkcmm, sl_pkcmm, dl_spkcmm = get_pk_hsd(2, ntk, wfs.ibzk_qc, hl_skmm, sl_kmm, dl_skmm, None, wfs.dtype, direction=direction) my_npk = len(wfs.ibzk_qc) / ntk my_nspins = len(wfs.kpt_u) / (my_npk * ntk) lead_hsd = Banded_Sparse_HSD(wfs.dtype, my_nspins, my_npk) lead_couple_hsd = CP_Sparse_HSD(wfs.dtype, my_nspins, my_npk) for pk in range(my_npk): lead_hsd.reset(0, pk, sl_pkmm[pk], 'S', init=True) lead_couple_hsd.reset(0, pk, sl_pkcmm[pk], 'S', init=True) for s in range(my_nspins): lead_hsd.reset(s, pk, hl_spkmm[s, pk], 'H', init=True) lead_hsd.reset(s, pk, dl_spkmm[s, pk], 'D', init=True) lead_couple_hsd.reset(s, pk, hl_spkcmm[s, pk], 'H', init=True) lead_couple_hsd.reset(s, pk, dl_spkcmm[s, pk], 'D', init=True) lead_se = LeadSelfEnergy(lead_hsd, lead_couple_hsd) contour = Contour(kt, [fermi] * 2, bias, depth, comm=comm) path = contour.get_plot_path(ex=True) for nid, energy in zip(path.my_nids, path.my_energies): for kpt in wfs.kpt_u: if kpt.q % ntk == 0: flag = str(kpt.k // ntk) + '_' + str(nid) lead_se.s = kpt.s lead_se.pk = kpt.q // ntk data = lead_se(energy) fd = file(flag, 'w') cPickle.dump(data, fd, 2) fd.close()
def path_selfenergy(atoms, ntk, filename, begin, end, num=257, direction=0): from gpaw.transport.sparse_matrix import Banded_Sparse_HSD, CP_Sparse_HSD, Se_Sparse_Matrix from gpaw.transport.selfenergy import LeadSelfEnergy from gpaw.transport.contour import Contour hl_skmm, sl_kmm = get_hs(atoms) dl_skmm = get_lcao_density_matrix(atoms.calc) fermi = atoms.calc.get_fermi_level() wfs = atoms.calc.wfs hl_spkmm, sl_pkmm, dl_spkmm, \ hl_spkcmm, sl_pkcmm, dl_spkcmm = get_pk_hsd(2, ntk, wfs.ibzk_qc, hl_skmm, sl_kmm, dl_skmm, None, wfs.dtype, direction=direction) my_npk = len(wfs.ibzk_qc) / ntk my_nspins = len(wfs.kpt_u) / (my_npk * ntk) lead_hsd = Banded_Sparse_HSD(wfs.dtype, my_nspins, my_npk) lead_couple_hsd = CP_Sparse_HSD(wfs.dtype, my_nspins, my_npk) for pk in range(my_npk): lead_hsd.reset(0, pk, sl_pkmm[pk], 'S', init=True) lead_couple_hsd.reset(0, pk, sl_pkcmm[pk], 'S', init=True) for s in range(my_nspins): lead_hsd.reset(s, pk, hl_spkmm[s, pk], 'H', init=True) lead_hsd.reset(s, pk, dl_spkmm[s, pk], 'D', init=True) lead_couple_hsd.reset(s, pk, hl_spkcmm[s, pk], 'H', init=True) lead_couple_hsd.reset(s, pk, dl_spkcmm[s, pk], 'D', init=True) lead_se = LeadSelfEnergy(lead_hsd, lead_couple_hsd) begin += fermi end += fermi ee = np.linspace(begin, end, num) se = [] for e in ee: se.append(lead_se(e).recover()) se = np.array(se) fd = file(filename + '_' + str(world.rank), 'w') cPickle.dump((se, ee), fd, 2) fd.close()
def initialize(self, srf_atoms, tip_atoms, srf_coupling_atoms, tip_coupling_atoms, srf_pl_atoms, tip_pl_atoms, energies, bias=0): """ srf_atoms: the atom index of onsite surface atoms tip_atoms: the atom index of onsite tip atoms energies: list of energies, for which the transmission function should be evaluated bias: will be used to precalculate the greenfunctions of surface and tip """ self.bias = bias self.energies = energies self.tip_atoms = tip_atoms self.srf_atoms = srf_atoms self.srf_coupling_atoms = srf_coupling_atoms self.tip_coupling_atoms = tip_coupling_atoms #align potentials for onsite surface, onsite tip and tip principle layers according to surface_pl srf_alignv = self.align_v(calc1 = self.srf_pl, index1=srf_pl_atoms[0], calc2=self.srf, index2=srf_atoms[0]) tip_alignv = srf_alignv + self.tip.get_fermi_level() - self.srf.get_fermi_level() #- bias tip_pl_alignv = self.align_v(calc1=self.tip, index1=tip_atoms[-1], calc2=self.tip_pl, index2=tip_pl_atoms[-1]) tip_pl_alignv += tip_alignv self.srf_alignv = srf_alignv self.tip_alignv = tip_alignv #hamiltoian and overlap matrix of onsite tip and srf self.h1, self.s1 = Lead_HS(calc = self.tip, atom_list = tip_atoms, shift = srf_alignv-bias).get_HS() print 'shape of onsite tip', np.shape(self.h1), np.shape(self.s1) self.h2, self.s2 = Lead_HS(calc = self.srf, atom_list = srf_atoms, shift = tip_alignv).get_HS() print 'shape of onsite srf', np.shape(self.h2), np.shape(self.s2) #hamiltoian and overlap matrix of two tip and srf principle layers self.h10, self.s10 = Lead_HS(calc = self.tip_pl, atom_list = tip_pl_atoms, shift = tip_pl_alignv).get_HS() #2 and only 2 principle layers print 'shape of pl tip', np.shape(self.h10), np.shape(self.s10) self.h20, self.s20 = Lead_HS(calc = self.srf_pl, atom_list = srf_pl_atoms, shift = -bias).get_HS() #2 and only 2 principle layers print 'shape of pl srf', np.shape(self.h20), np.shape(self.s20) nbf1, nbf2 = len(self.h1), len(self.h2) #No. of basis functions of onsite tip and surface atoms pl1, pl2 = len(self.h10)/2, len(self.h20)/2 #No. of basis functions per principle layer of tip and srf nenergies = len(energies) #periodic part of the tip hs1_dii = self.h10[:pl1, :pl1], self.s10[:pl1, :pl1] hs1_dij = self.h10[:pl1, pl1:2*pl1], self.s10[:pl1, pl1:2*pl1] #coupling betwen per. and non. per part of the tip h1_im = np.zeros((pl1, nbf1), complex) s1_im = np.zeros((pl1, nbf1), complex) h1_im[:pl1, :pl1], s1_im[:pl1, :pl1] = hs1_dij hs1_dim = [h1_im, s1_im] #periodic part the surface hs2_dii = self.h20[:pl2, :pl2], self.s20[:pl2, :pl2] hs2_dij = self.h20[pl2:2*pl2, :pl2], self.s20[pl2:2*pl2, :pl2] #coupling betwen per. and non. per part of the surface h2_im = np.zeros((pl2, nbf2), complex) s2_im = np.zeros((pl2, nbf2), complex) h2_im[-pl2:, -pl2:], s2_im[-pl2:, -pl2:] = hs2_dij hs2_dim = [h2_im, s2_im] #tip and surface greenfunction self.selfenergy1 = LeadSelfEnergy(hs1_dii, hs1_dij, hs1_dim) self.selfenergy2 = LeadSelfEnergy(hs2_dii, hs2_dij, hs2_dim) self.greenfunction1 = GreenFunction(self.h1, self.s1,[self.selfenergy1]) self.greenfunction2 = GreenFunction(self.h2, self.s2,[self.selfenergy2]) #print 'shape of greenfunction tip:', np.shape(self.greenfunction1) #print 'shape of greenfunction srf:', np.shape(self.greenfunction2) #shift the bands due to the bias self.selfenergy1.set_bias(0.0) self.selfenergy2.set_bias(bias) # extend the surface potentials and basis functions self.setup_stm() #tip and surface greenfunction matrices. nbf1_small = self.ni #XXX Change this for efficiency in the future nbf2_small = self.nj #XXX -||- coupling_list1 = range(nbf1-nbf1_small,nbf1)# XXX -||- coupling_list2 = range(0,nbf2_small)# XXX -||- self.gft1_emm = np.zeros((nenergies, nbf1_small, nbf1_small), complex) self.gft2_emm = np.zeros((nenergies, nbf2_small, nbf2_small), complex) for e, energy in enumerate(self.energies): gft1_mm = self.greenfunction1(energy)[coupling_list1] gft1_mm = np.take(gft1_mm, coupling_list1, axis=1) gft2_mm = self.greenfunction2(energy)[coupling_list2] gft2_mm = np.take(gft2_mm, coupling_list2, axis=1) self.gft1_emm[e] = gft1_mm self.gft2_emm[e] = gft2_mm