def main(options): """ Main routine to compute inelastic transport characteristics (dI/dV, d2I/dV2, IETS etc) Parameters ---------- options : an ``options`` instance """ CF.CreatePipeOutput(options.DestDir + '/' + options.Logfile) VC.OptionsCheck(options, 'Inelastica') CF.PrintMainHeader('Inelastica', options) options.XV = '%s/%s.XV' % (options.head, options.systemlabel) options.geom = MG.Geom(options.XV, BufferAtoms=options.buffer) # Voltage fraction over left-center interface VfracL = options.VfracL # default is 0.5 print 'Inelastica: Voltage fraction over left-center interface: VfracL =', VfracL # Set up electrodes and device Greens function elecL = NEGF.ElectrodeSelfEnergy(options.fnL, options.NA1L, options.NA2L, options.voltage * VfracL) elecL.scaling = options.scaleSigL elecL.semiinf = options.semiinfL elecR = NEGF.ElectrodeSelfEnergy(options.fnR, options.NA1R, options.NA2R, options.voltage * (VfracL - 1.)) elecR.scaling = options.scaleSigR elecR.semiinf = options.semiinfR # Read phonons NCfile = NC4.Dataset(options.PhononNetCDF, 'r') print 'Inelastica: Reading ', options.PhononNetCDF hw = NCfile.variables['hw'][:] # Work with GFs etc for positive (V>0: \mu_L>\mu_R) and negative (V<0: \mu_L<\mu_R) bias voltages GFp = NEGF.GF(options.TSHS, elecL, elecR, Bulk=options.UseBulk, DeviceAtoms=options.DeviceAtoms, BufferAtoms=options.buffer) # Prepare lists for various trace factors #GF.dGnout = [] #GF.dGnin = [] GFp.P1T = N.zeros(len(hw), N.float) # M.A.M.A (total e-h damping) GFp.P2T = N.zeros(len(hw), N.float) # M.AL.M.AR (emission) GFp.ehDampL = N.zeros(len(hw), N.float) # M.AL.M.AL (L e-h damping) GFp.ehDampR = N.zeros(len(hw), N.float) # M.AR.M.AR (R e-h damping) GFp.nHT = N.zeros(len(hw), N.float) # non-Hilbert/Isym factor GFp.HT = N.zeros(len(hw), N.float) # Hilbert/Iasym factor GFp.dIel = N.zeros(len(hw), N.float) GFp.dIinel = N.zeros(len(hw), N.float) GFp.dSel = N.zeros(len(hw), N.float) GFp.dSinel = N.zeros(len(hw), N.float) # GFm = NEGF.GF(options.TSHS, elecL, elecR, Bulk=options.UseBulk, DeviceAtoms=options.DeviceAtoms, BufferAtoms=options.buffer) GFm.P1T = N.zeros(len(hw), N.float) # M.A.M.A (total e-h damping) GFm.P2T = N.zeros(len(hw), N.float) # M.AL.M.AR (emission) GFm.ehDampL = N.zeros(len(hw), N.float) # M.AL.M.AL (L e-h damping) GFm.ehDampR = N.zeros(len(hw), N.float) # M.AR.M.AR (R e-h damping) GFm.nHT = N.zeros(len(hw), N.float) # non-Hilbert/Isym factor GFm.HT = N.zeros(len(hw), N.float) # Hilbert/Iasym factor GFm.dIel = N.zeros(len(hw), N.float) GFm.dIinel = N.zeros(len(hw), N.float) GFm.dSel = N.zeros(len(hw), N.float) GFm.dSinel = N.zeros(len(hw), N.float) # Calculate transmission at Fermi level GFp.calcGF(options.energy + options.eta * 1.0j, options.kpoint[0:2], ispin=options.iSpin, etaLead=options.etaLead, useSigNCfiles=options.signc, SpectralCutoff=options.SpectralCutoff) L = options.bufferL # Pad lasto with zeroes to enable basis generation... lasto = N.zeros((GFp.HS.nua + L + 1, ), N.int) lasto[L:] = GFp.HS.lasto basis = SIO.BuildBasis(options.fn, options.DeviceAtoms[0] + L, options.DeviceAtoms[1] + L, lasto) basis.ii -= L TeF = MM.trace(GFp.TT).real GFp.TeF = TeF GFm.TeF = TeF # Check consistency of PHrun vs TSrun inputs IntegrityCheck(options, GFp, basis, NCfile) # Calculate trace factors one mode at a time print 'Inelastica: LOEscale =', options.LOEscale if options.LOEscale == 0.0: # LOEscale=0.0 => Original LOE-WBA method, PRB 72, 201101(R) (2005) [cond-mat/0505473]. GFp.calcGF(options.energy + options.eta * 1.0j, options.kpoint[0:2], ispin=options.iSpin, etaLead=options.etaLead, useSigNCfiles=options.signc, SpectralCutoff=options.SpectralCutoff) GFm.calcGF(options.energy + options.eta * 1.0j, options.kpoint[0:2], ispin=options.iSpin, etaLead=options.etaLead, useSigNCfiles=options.signc, SpectralCutoff=options.SpectralCutoff) for ihw in (hw > options.modeCutoff).nonzero()[0]: calcTraces(options, GFp, GFm, basis, NCfile, ihw) calcTraces(options, GFm, GFp, basis, NCfile, ihw) writeFGRrates(options, GFp, hw, NCfile) else: # LOEscale=1.0 => Generalized LOE, PRB 89, 081405(R) (2014) [arXiv:1312.7625] for ihw in (hw > options.modeCutoff).nonzero()[0]: GFp.calcGF(options.energy + hw[ihw] * options.LOEscale * VfracL + options.eta * 1.0j, options.kpoint[0:2], ispin=options.iSpin, etaLead=options.etaLead, useSigNCfiles=options.signc, SpectralCutoff=options.SpectralCutoff) GFm.calcGF(options.energy + hw[ihw] * options.LOEscale * (VfracL - 1.) + options.eta * 1.0j, options.kpoint[0:2], ispin=options.iSpin, etaLead=options.etaLead, useSigNCfiles=options.signc, SpectralCutoff=options.SpectralCutoff) calcTraces(options, GFp, GFm, basis, NCfile, ihw) if VfracL != 0.5: GFp.calcGF(options.energy - hw[ihw] * options.LOEscale * (VfracL - 1.) + options.eta * 1.0j, options.kpoint[0:2], ispin=options.iSpin, etaLead=options.etaLead, useSigNCfiles=options.signc, SpectralCutoff=options.SpectralCutoff) GFm.calcGF(options.energy - hw[ihw] * options.LOEscale * VfracL + options.eta * 1.0j, options.kpoint[0:2], ispin=options.iSpin, etaLead=options.etaLead, useSigNCfiles=options.signc, SpectralCutoff=options.SpectralCutoff) calcTraces(options, GFm, GFp, basis, NCfile, ihw) # Multiply traces with voltage-dependent functions data = calcIETS(options, GFp, GFm, basis, hw) NCfile.close() NEGF.SavedSig.close() CF.PrintMainFooter('Inelastica') return data
def main(options): """ Main routine to compute elastic transmission probabilities etc. Parameters ---------- options : an ``options`` instance """ CF.CreatePipeOutput(options.DestDir + '/' + options.Logfile) VC.OptionsCheck(options, 'pyTBT') CF.PrintMainHeader('pyTBT', options) # K-points if options.Gk1 > 1: Nk1, t1 = options.Gk1, 'GK' else: Nk1, t1 = options.Nk1, 'LIN' if options.Gk2 > 1: Nk2, t2 = options.Gk2, 'GK' else: Nk2, t2 = options.Nk2, 'LIN' # Generate full k-mesh: mesh = Kmesh.kmesh(Nk1, Nk2, Nk3=1, meshtype=[t1, t2, 'LIN'], invsymmetry=not options.skipsymmetry) mesh.mesh2file( '%s/%s.%ix%i.mesh' % (options.DestDir, options.systemlabel, mesh.Nk[0], mesh.Nk[1])) # Setup self-energies and device GF elecL = NEGF.ElectrodeSelfEnergy(options.fnL, options.NA1L, options.NA2L, options.voltage / 2.) elecL.scaling = options.scaleSigL elecL.semiinf = options.semiinfL elecR = NEGF.ElectrodeSelfEnergy(options.fnR, options.NA1R, options.NA2R, -options.voltage / 2.) elecR.scaling = options.scaleSigR elecR.semiinf = options.semiinfR DevGF = NEGF.GF(options.TSHS, elecL, elecR, Bulk=options.UseBulk, DeviceAtoms=options.DeviceAtoms, BufferAtoms=options.buffer) nspin = DevGF.HS.nspin # k-sample only self-energies? if options.singlejunction: elecL.mesh = mesh mesh = Kmesh.kmesh(3, 3, 1) if options.dos: DOSL = N.zeros((nspin, len(options.Elist), DevGF.nuo), N.float) DOSR = N.zeros((nspin, len(options.Elist), DevGF.nuo), N.float) # MPSH projections? MPSHL = N.zeros((nspin, len(options.Elist), DevGF.nuo), N.float) MPSHR = N.zeros((nspin, len(options.Elist), DevGF.nuo), N.float) # evaluate eigenstates at Gamma import scipy.linalg as SLA DevGF.setkpoint(N.zeros(2)) ev0, es0 = SLA.eigh(DevGF.H, DevGF.S) print 'MPSH eigenvalues:', ev0 #print 'MPSH eigenvector normalizations:',N.diag(MM.mm(MM.dagger(es0),DevGF.S,es0)).real # right # Loop over spin for iSpin in range(nspin): # initialize transmission and shot noise arrays Tkpt = N.zeros((len(options.Elist), mesh.NNk, options.numchan + 1), N.float) SNkpt = N.zeros((len(options.Elist), mesh.NNk, options.numchan + 1), N.float) # prepare output files outFile = options.DestDir + '/%s.%ix%i' % (options.systemlabel, mesh.Nk[0], mesh.Nk[1]) if nspin < 2: thisspinlabel = outFile else: thisspinlabel = outFile + ['.UP', '.DOWN'][iSpin] fo = open(thisspinlabel + '.AVTRANS', 'write') fo.write('# Nk1(%s)=%i Nk2(%s)=%i eta=%.2e etaLead=%.2e\n' % (mesh.type[0], mesh.Nk[0], mesh.type[1], mesh.Nk[1], options.eta, options.etaLead)) fo.write('# E Ttot(E) Ti(E)(i=1-%i) RelErrorTtot(E)\n' % options.numchan) foSN = open(thisspinlabel + '.AVNOISE', 'write') foSN.write('# Nk1(%s)=%i Nk2(%s)=%i eta=%.2e etaLead=%.2e\n' % (mesh.type[0], mesh.Nk[0], mesh.type[1], mesh.Nk[1], options.eta, options.etaLead)) foSN.write('# E SNtot(E) SNi(E)(i=1-%i)\n' % options.numchan) foFF = open(thisspinlabel + '.FANO', 'write') foFF.write('# Nk1(%s)=%i Nk2(%s)=%i eta=%.2e etaLead=%.2e\n' % (mesh.type[0], mesh.Nk[0], mesh.type[1], mesh.Nk[1], options.eta, options.etaLead)) foFF.write('# E Fano factor \n') # Loop over energy for ie, ee in enumerate(options.Elist): Tavg = N.zeros((options.numchan + 1, len(mesh.w)), N.float) SNavg = N.zeros((options.numchan + 1, len(mesh.w)), N.float) AavL = N.zeros((DevGF.nuo, DevGF.nuo), N.complex) AavR = N.zeros((DevGF.nuo, DevGF.nuo), N.complex) # Loops over k-points for ik in range(mesh.NNk): DevGF.calcGF(ee + options.eta * 1.0j, mesh.k[ik, :2], ispin=iSpin, etaLead=options.etaLead, useSigNCfiles=options.signc, SpectralCutoff=options.SpectralCutoff) # Transmission and shot noise T, SN = DevGF.calcTEIG(options.numchan) for iw in range(len(mesh.w)): Tavg[:, iw] += T * mesh.w[iw, ik] SNavg[:, iw] += SN * mesh.w[iw, ik] Tkpt[ie, ik] = T SNkpt[ie, ik] = SN # DOS calculation: if options.dos: if options.SpectralCutoff > 0.0: AavL += mesh.w[0, ik] * MM.mm(DevGF.AL.L, DevGF.AL.R, DevGF.S) AavR += mesh.w[0, ik] * MM.mm(DevGF.AR.L, DevGF.AR.R, DevGF.S) else: AavL += mesh.w[0, ik] * MM.mm(DevGF.AL, DevGF.S) AavR += mesh.w[0, ik] * MM.mm(DevGF.AR, DevGF.S) # Print calculated quantities err = (N.abs(Tavg[0, 0] - Tavg[0, 1]) + N.abs(Tavg[0, 0] - Tavg[0, 2])) / 2 relerr = err / Tavg[0, 0] print 'ispin= %i, e= %.4f, Tavg= %.8f, RelErr= %.1e' % ( iSpin, ee, Tavg[0, 0], relerr) transline = '\n%.10f ' % ee noiseline = '\n%.10f ' % ee for ichan in range(options.numchan + 1): if ichan == 0: transline += '%.8e ' % Tavg[ichan, 0] noiseline += '%.8e ' % SNavg[ichan, 0] else: transline += '%.4e ' % Tavg[ichan, 0] noiseline += '%.4e ' % SNavg[ichan, 0] transline += '%.2e ' % relerr fo.write(transline) foSN.write(noiseline) foFF.write('\n%.10f %.8e' % (ee, SNavg[0, 0] / Tavg[0, 0])) # Partial density of states: if options.dos: DOSL[iSpin, ie, :] += N.diag(AavL).real / (2 * N.pi) DOSR[iSpin, ie, :] += N.diag(AavR).real / (2 * N.pi) MPSHL[iSpin, ie, :] += N.diag(MM.mm(MM.dagger(es0), AavL, es0)).real / (2 * N.pi) MPSHR[iSpin, ie, :] += N.diag(MM.mm(MM.dagger(es0), AavR, es0)).real / (2 * N.pi) print 'ispin= %i, e= %.4f, DOSL= %.4f, DOSR= %.4f' % ( iSpin, ee, N.sum(DOSL[iSpin, ie, :]), N.sum(DOSR[iSpin, ie, :])) fo.write('\n') fo.close() foSN.write('\n') foSN.close() foFF.write('\n') foFF.close() # Write k-point-resolved transmission fo = open(thisspinlabel + '.TRANS', 'write') for ik in range(mesh.NNk): w = mesh.w[:, ik] fo.write('\n\n# k = %f, %f w = %f %f %f %f' % (mesh.k[ik, 0], mesh.k[ik, 1], w[0], w[1], w[2], w[3])) for ie, ee in enumerate(options.Elist): transline = '\n%.10f ' % ee for ichan in range(options.numchan + 1): if ichan == 0: transline += '%.8e ' % Tkpt[ie, ik, ichan] else: transline += '%.4e ' % Tkpt[ie, ik, ichan] fo.write(transline) fo.write('\n') fo.close() # Write k-point-resolved shot noise fo = open(thisspinlabel + '.NOISE', 'write') for ik in range(mesh.NNk): w = mesh.w[:, ik] fo.write('\n\n# k = %f, %f w = %f %f %f %f' % (mesh.k[ik, 0], mesh.k[ik, 1], w[0], w[1], w[2], w[3])) for ie, ee in enumerate(options.Elist): noiseline = '\n%.10f ' % ee for ichan in range(options.numchan + 1): if ichan == 0: noiseline += '%.8e ' % SNkpt[ie, ik, ichan] else: noiseline += '%.4e ' % SNkpt[ie, ik, ichan] fo.write(noiseline) fo.write('\n') fo.close() # End loop over spin NEGF.SavedSig.close() # Make sure saved Sigma is written to file if options.dos: # Read basis L = options.bufferL # Pad lasto with zeroes to enable basis generation... lasto = N.zeros((DevGF.HS.nua + L + 1, ), N.int) lasto[L:] = DevGF.HS.lasto basis = SIO.BuildBasis(options.fn, 1 + L, DevGF.HS.nua + L, lasto) basis.ii -= L WritePDOS(outFile + '.PDOS.gz', options, DevGF, DOSL + DOSR, basis) WritePDOS(outFile + '.PDOSL.gz', options, DevGF, DOSL, basis) WritePDOS(outFile + '.PDOSR.gz', options, DevGF, DOSR, basis) WriteMPSH(outFile + '.MPSH.gz', options, DevGF, MPSHL + MPSHR, ev0) WriteMPSH(outFile + '.MPSHL.gz', options, DevGF, MPSHL, ev0) WriteMPSH(outFile + '.MPSHR.gz', options, DevGF, MPSHR, ev0) CF.PrintMainFooter('pyTBT')
def main(options): """ Main routine to compute eigenchannel scattering states Parameters ---------- options : an ``options`` instance """ Log.CreatePipeOutput(options) VC.OptionsCheck(options) Log.PrintMainHeader(options) # Read geometry XV = '%s/%s.XV' % (options.head, options.systemlabel) geom = MG.Geom(XV, BufferAtoms=options.buffer) # Set up device Greens function elecL = NEGF.ElectrodeSelfEnergy(options.fnL, options.NA1L, options.NA2L, options.voltage / 2.) elecL.scaling = options.scaleSigL elecL.semiinf = options.semiinfL elecR = NEGF.ElectrodeSelfEnergy(options.fnR, options.NA1R, options.NA2R, -options.voltage / 2.) elecR.scaling = options.scaleSigR elecR.semiinf = options.semiinfR DevGF = NEGF.GF(options.TSHS, elecL, elecR, Bulk=options.UseBulk, DeviceAtoms=options.DeviceAtoms, BufferAtoms=options.buffer) DevGF.calcGF(options.energy + options.eta * 1.0j, options.kpoint[0:2], ispin=options.iSpin, etaLead=options.etaLead, useSigNCfiles=options.signc, SpectralCutoff=options.SpectralCutoff) NEGF.SavedSig.close() # Make sure saved Sigma is written to file # Transmission print('Transmission Ttot(%.4feV) = %.16f' % (options.energy, N.trace(DevGF.TT).real)) # Build basis options.nspin = DevGF.HS.nspin L = options.bufferL # Pad lasto with zeroes to enable basis generation... lasto = N.zeros((DevGF.HS.nua + L + 1, ), N.int) lasto[L:] = DevGF.HS.lasto basis = SIO.BuildBasis(options.fn, options.DeviceAtoms[0] + L, options.DeviceAtoms[1] + L, lasto) basis.ii -= L # Calculate Eigenchannels DevGF.calcEigChan(options.numchan) # Compute bond currents? if options.kpoint[0] != 0.0 or options.kpoint[1] != 0.0: print( 'Warning: The current implementation of bond currents is only valid for the Gamma point (should be easy to fix)' ) BC = False else: BC = True # Eigenchannels from left ECleft = DevGF.ECleft for jj in range(options.numchan): options.iSide, options.iChan = 0, jj + 1 writeWavefunction(options, geom, basis, ECleft[jj]) if BC: Curr = calcCurrent(options, basis, DevGF.H, ECleft[jj]) writeCurrent(options, geom, Curr) # Calculate eigenchannels from right if options.bothsides: ECright = DevGF.ECright for jj in range(options.numchan): options.iSide, options.iChan = 1, jj + 1 writeWavefunction(options, geom, basis, ECright[jj]) if BC: Curr = calcCurrent(options, basis, DevGF.H, ECright[jj]) writeCurrent(options, geom, Curr) # Calculate total "bond currents" if BC: Curr = -calcCurrent(options, basis, DevGF.H, DevGF.AL) options.iChan, options.iSide = 0, 0 writeCurrent(options, geom, Curr) Curr = -calcCurrent(options, basis, DevGF.H, DevGF.AR) options.iSide = 1 writeCurrent(options, geom, Curr) # Calculate eigenstates of device Hamiltonian (MPSH) if options.MolStates > 0.0: try: import scipy.linalg as SLA ev, es = SLA.eigh(DevGF.H, DevGF.S) print( 'EigenChannels: Eigenvalues (in eV) of computed molecular eigenstates:' ) print(ev) # Write eigenvalues to file fn = options.DestDir + '/' + options.systemlabel + '.EIGVAL' print('EigenChannels: Writing', fn) fnfile = open(fn, 'w') fnfile.write('# Device region = [%i,%i], units in eV\n' % (options.DeviceFirst, options.DeviceLast)) for i, val in enumerate(ev): fnfile.write('%i %.8f\n' % (i, val)) fnfile.close() # Compute selected eigenstates for ii, val in enumerate(ev): if N.abs(val) < options.MolStates: fn = options.DestDir + '/' + options.systemlabel + '.S%.3i.E%.3f' % ( ii, val) writeWavefunction(options, geom, basis, es[:, ii], fn=fn) except: print( 'You need to install scipy to solve the generalized eigenvalue problem' ) print('for the molecular eigenstates in the nonorthogonal basis') Log.PrintMainFooter(options) return DevGF
def calcTSWF(options, ikpoint): kpoint = options.kpoints.k[ikpoint] def calcandwrite(A, txt, kpoint, ikpoint): if isinstance(A, MM.SpectralMatrix): A=A.full() A=A*PC.Rydberg2eV # Change to 1/Ryd ev, U = LA.eigh(A) Utilde = N.empty(U.shape, U.dtype) for jj, val in enumerate(ev): # Problems with negative numbers if val<0: val=0 Utilde[:, jj]=N.sqrt(val/(2*N.pi))*U[:, jj] indx2 = N.where(abs(abs(ev)>1e-4))[0] # Pick non-zero states ev=ev[indx2] Utilde=Utilde[:, indx2] indx=ev.real.argsort()[::-1] fn=options.DestDir+'/%i/'%(ikpoint)+options.systemlabel+'.%s'%(txt) path = './'+options.DestDir+'/' #FermiEnergy = SIO.HS(options.systemlabel+'.TSHS').ef def noWfs(side): tmp = len(glob.glob(path+str(ikpoint)+'/'+options.systemlabel+'.A'+side+'*')) return tmp if noWfs('L')==0 or noWfs('R')==0 and len(glob.glob(path+str(ikpoint)+'/FD*'))==0: print('Calculating localized-basis states from spectral function %s ...'%(txt)) tlb = time.clock() calcWF2(options, geom, options.DeviceAtoms, basis, Utilde[:, indx], [N1, N2, N3, minN3, maxN3], Fold=True, k=kpoint, fn=fn) times = N.round(time.clock()-tlb, 2); timem = N.round(times/60, 2) print('Finished in '+str(times)+' s = '+str(timem)+' min') if noWfs('L')>0 and noWfs('R')>0 and len(glob.glob(path+str(ikpoint)+'/FD*'))==0 and str('%s'%(txt))==str('AR'): print('\nLocalized-basis states are calculated in k point '+str(ikpoint)+'/.') print('------------------------------------------------------') print('Finite-difference calculation of vacuum states starts!') timeFD = time.clock() STMFD.main(options, kpoint, ikpoint) print('FD calculation in k-point folder '+str(ikpoint)+'/ done in '+str(N.round((time.clock()-timeFD)/60, 2))+' min.') print('------------------------------------------------------') if options.savelocwfs == False: os.system('rm -f '+path+str(ikpoint)+'/'+options.systemlabel+'*') #Read geometry XV = '%s/%s.XV'%(options.head, options.systemlabel) geom = MG.Geom(XV, BufferAtoms=options.buffer) #Set up device Greens function elecL = NEGF.ElectrodeSelfEnergy(options.fnL, options.NA1L, options.NA2L, options.voltage/2.) elecL.scaling = options.scaleSigL elecL.semiinf = options.semiinfL elecR = NEGF.ElectrodeSelfEnergy(options.fnR, options.NA1R, options.NA2R, -options.voltage/2.) elecR.scaling = options.scaleSigR elecR.semiinf = options.semiinfR DevGF = NEGF.GF(options.TSHS, elecL, elecR, Bulk=options.UseBulk, DeviceAtoms=options.DeviceAtoms, BufferAtoms=options.buffer) DevGF.calcGF(options.energy+options.eta*1.0j, kpoint[0:2], ispin=options.iSpin, etaLead=options.etaLead, useSigNCfiles=options.signc, SpectralCutoff=options.SpectralCutoff) NEGF.SavedSig.close() #Make sure saved Sigma is written to file #Transmission print('Transmission Ttot(%.4feV) = %.16f'%(options.energy, N.trace(DevGF.TT).real)) #Build basis options.nspin = DevGF.HS.nspin L = options.bufferL #Pad lasto with zeroes to enable basis generation... lasto = N.zeros((DevGF.HS.nua+L+1,), N.int) lasto[L:] = DevGF.HS.lasto basis = SIO.BuildBasis(options.fn, options.DeviceAtoms[0]+L, options.DeviceAtoms[1]+L, lasto) basis.ii -= L file = NC.Dataset('TotalPotential.grid.nc', 'r') N1, N2, N3 = len(file.dimensions['n1']), len(file.dimensions['n2']), len(file.dimensions['n3']) cell = file.variables['cell'][:] file.close() #Find device region in a3 axis U = LA.inv(N.array([cell[0]/N1, cell[1]/N2, cell[2]/N3]).transpose()) gridindx = N.dot(geom.xyz[options.DeviceAtoms[0]-1:options.DeviceAtoms[1]]/PC.Bohr2Ang, U) minN3, maxN3 = N.floor(N.min(gridindx[:, 2])).astype(N.int), N.ceil(N.max(gridindx[:, 2])).astype(N.int) if not N.allclose(geom.pbc, cell*PC.Bohr2Ang): print('Error: TotalPotential.grid.nc has different cell compared to geometry') sys.exit(1) print('\nk-point folder '+str(ikpoint)+'/') print('Checking/calculating localized-basis states ...') calcandwrite(DevGF.AL, 'AL', kpoint, ikpoint) calcandwrite(DevGF.AR, 'AR', kpoint, ikpoint)