def main(options): CF.CreatePipeOutput(options.DestDir+'/'+options.Logfile) CF.PrintMainHeader('Phonons',vinfo,options) # Determine SIESTA input fdf files in FCruns fdf = glob.glob(options.FCwildcard+'/RUN.fdf') print 'Phonons.Analyze: This run uses' FCfirst,FClast = min(options.DynamicAtoms),max(options.DynamicAtoms) print ' ... FCfirst = %4i, FClast = %4i, Dynamic atoms = %4i'\ %(FCfirst,FClast,len(options.DynamicAtoms)) print ' ... DeviceFirst = %4i, DeviceLast = %4i, Device atoms = %4i'\ %(options.DeviceFirst,options.DeviceLast,options.DeviceLast-options.DeviceFirst+1) print ' ... PBC First = %4i, PBC Last = %4i, Device atoms = %4i'\ %(options.PBCFirst,options.PBCLast,options.PBCLast-options.PBCFirst+1) print '\nSetting array type to %s\n'%options.atype # Build Dynamical Matrix DM = DynamicalMatrix(fdf,options.DynamicAtoms) DM.SetMasses(options.Isotopes) # Compute modes DM.ComputePhononModes(DM.mean) # Compute e-ph coupling if options.CalcCoupl: DM.PrepareGradients(options.onlySdir,options.kpoint,options.DeviceFirst,options.DeviceLast,options.AbsEref,options.atype) DM.ComputeEPHcouplings(options.PBCFirst,options.PBCLast,options.EPHAtoms,options.Restart,options.CheckPointNetCDF, WriteGradients=options.WriteGradients) # Write data to files DM.WriteOutput(options.DestDir+'/Output',options.SinglePrec,options.GammaPoint) CF.PrintMainFooter('Phonons') return DM.h0,DM.s0,DM.hw,DM.heph else: DM.WriteOutput(options.DestDir+'/Output',options.SinglePrec,options.GammaPoint) CF.PrintMainFooter('Phonons') return DM.hw
def main(options): CF.CreatePipeOutput(options.DestDir + '/' + options.Logfile) VC.OptionsCheck(options, 'EigenChannels') CF.PrintMainHeader('EigenChannels', vinfo, 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, EigT = DevGF.ECleft, DevGF.EigTleft 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, EigT = DevGF.ECright, DevGF.EigTright 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 file = open(fn, 'w') file.write('# Device region = [%i,%i], units in eV\n' % (options.DeviceFirst, options.DeviceLast)) for i in range(len(ev)): file.write('%i %.8f\n' % (i, ev[i])) file.close() # Compute selected eigenstates for ii in range(len(ev)): if N.abs(ev[ii]) < options.MolStates: fn = options.DestDir + '/' + options.systemlabel + '.S%.3i.E%.3f' % ( ii, ev[ii]) 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' CF.PrintMainFooter('EigenChannels')
def main(options): CF.CreatePipeOutput(options.DestDir+'/'+options.Logfile) VC.OptionsCheck(options,'Inelastica') CF.PrintMainHeader('Inelastica',vinfo,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