Пример #1
0
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
Пример #2
0
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')
Пример #3
0
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