Ejemplo n.º 1
0
def udft_fixed_occ(atoms,occa, occb, **kwargs):
    """\
    occa and occb represent the orbital occupation arrays for 
    the calculating spin orbitals with holes
    
    udft(atoms,**kwargs) - Unrestricted spin DFT driving routine

    atoms       A Molecule object containing the molecule

    Options:      Value   Description
    --------      -----   -----------
    verbose       False   Output terse information to stdout (default)
                  True    Print out additional information 
    ConvCriteria  1e-4    Convergence Criteria
    MaxIter       20      Maximum SCF iterations
    DoAveraging   True    Use DIIS for accelerated convergence (default)
                  False   No convergence acceleration
    ETemp         False   Use ETemp value for finite temperature DFT (default)
                  float   Use (float) for the electron temperature
    bfs           None    The basis functions to use. List of CGBF's
    basis_data    None    The basis data to use to construct bfs
    integrals     None    The one- and two-electron integrals to use
                          If not None, S,h,Ints
    orbs          None    If not none, the guess orbitals
    functional    SVWN    Use the SVWN (LDA) DFT functional (default)
                  S0      Use the Slater Xalpha DFT functional
                  BLYP    Use the BLYP GGA DFT functional
                  PBE     Use the PBE DFT functional
    grid_nrad     32      Number of radial shells per atom
    grid_fineness 1       Radial shell fineness. 0->coarse, 1->medium, 2->fine
    """
    verbose = kwargs.get('verbose',False) 
    ConvCriteria = kwargs.get('ConvCriteria',1e-4)
    MaxIter = kwargs.get('MaxIter',20)
    DoAveraging = kwargs.get('DoAveraging',True)
    averaging = kwargs.get('averaging',0.5)
    ETemp = kwargs.get('ETemp',False)
    functional = kwargs.get('functional','LDA') 
    #default to LDA which has no correlation since that is easier

    kwargs['do_grad_dens'] = need_gradients[functional]
    kwargs['do_spin_polarized'] = True

    bfs = kwargs.get('bfs',None)
    if not bfs:
        basis_data = kwargs.get('basis_data',None)
        bfs = getbasis(atoms,basis_data)

    integrals = kwargs.get('integrals',None)
    if integrals:
        S,h,Ints = integrals
    else:
        S,h,Ints = getints(bfs,atoms)

    nel = atoms.get_nel()
    enuke = atoms.get_enuke()

    # default medium mesh
    grid_nrad = kwargs.get('grid_nrad',32)
    grid_fineness = kwargs.get('grid_fineness',1)

    gr = MolecularGrid(atoms,grid_nrad,grid_fineness,**kwargs) 
    gr.set_bf_amps(bfs)

    # It would be nice to have a more intelligent treatment of the guess
    # so that I could pass in a density rather than a set of orbs.
    orbs = kwargs.get('orbs',None)
    if not orbs: orbe,orbs = geigh(h,S)
    orbsa = orbsb = orbs

    nalpha,nbeta = atoms.get_alphabeta()

    if verbose:
        print "UDFT calculation on %s using functional %s" % (
            atoms.name,functional)
        print "Nbf = %d" % len(bfs)
        print "Nalpha = %d" % nalpha
        print "Nbeta = %d" % nbeta
        
    eold = 0.

    # Converge the LDA density for the system:
    print "Optimization of DFT density"
    for i in xrange(MaxIter):
        Da = mk_auger_dens(orbsa, occa)
        Db = mk_auger_dens(orbsb, occb)
        Dab = Da + Db
        
        if DoAveraging:
            if i: 
                Da = averaging*Da + (1-averaging)*Da0
                Db = averaging*Db + (1-averaging)*Db0
            Da0 = Da
            Db0 = Db

        Ja = getJ(Ints,Da)
        Jb = getJ(Ints,Db)

        #remember we must use a functional that has no correlation energy
        gr.setdens(Da,Db)
        exca,XCa,XCb = getXC(gr,nel,**kwargs)
        
        Fa = h+Ja+Jb+XCa
        Fb = h+Ja+Jb+XCb
        
        orbea,orbsa = geigh(Fa,S)
        orbeb,orbsb = geigh(Fb,S)
        
        Eone = trace2(Dab,h)
        Ej   = 0.5*trace2(Dab,Ja+Jb)
        Exc = 0.5*exca + 0.5*excb
        
        energy = Eone + Ej + Exc + enuke
        
        print i+1,"   ",energy,"    ",Ej,"  ",Exc
        if verbose: 
            print "%d %10.4f %10.4f %10.4f" % (i,energy,Ej,Exc)
        if abs(energy-eold) < ConvCriteria: break
        eold = energy
    print "Final U%s energy for system %s is %f" % (
        functional,atoms.name,energy)
    return energy,(orbea,orbeb),(orbsa,orbsb)
Ejemplo n.º 2
0
def uhf_fixed_occ(atoms,occa, occb,**opts):
    """\
    occa and occb represent the orbital occupation arrays for 
    the calculating spin orbitals with holes
    
    uhf(atoms,**opts) - Unrestriced Open Shell Hartree Fock
    atoms       A Molecule object containing the molecule

    Options:      Value   Description
    --------      -----   -----------
    ConvCriteria  1e-4    Convergence Criteria
    MaxIter       20      Maximum SCF iterations
    DoAveraging   True    Use DIIS averaging for convergence acceleration
    bfs           None    The basis functions to use. List of CGBF's
    basis_data    None    The basis data to use to construct bfs
    integrals     None    The one- and two-electron integrals to use
                          If not None, S,h,Ints
    orbs          None    If not None, the guess orbitals
    """

    from biorthogonal import biorthogonalize,pad_out

    ConvCriteria = opts.get('ConvCriteria',1e-5)
    MaxIter = opts.get('MaxIter',40)
    DoAveraging = opts.get('DoAveraging',True)
    averaging = opts.get('averaging',0.5)
    ETemp = opts.get('ETemp',False)
    
    bfs = opts.get('bfs',None)
    if not bfs:
        basis_data = opts.get('basis_data',None)
        bfs = getbasis(atoms,basis_data)

    integrals = opts.get('integrals', None)
    if integrals:
        S,h,Ints = integrals
    else:
        S,h,Ints = getints(bfs,atoms)

    nel = atoms.get_nel()

    nalpha,nbeta = atoms.get_alphabeta() #pass in opts for multiplicity
    S,h,Ints = getints(bfs,atoms)

    orbsa = opts.get('orbsa',None)
    orbsb = opts.get('orbsb',None)
    if (orbsa!=None and orbsb!=None):
        orbsa = orbsa
        orbsb = orbsb
    else:
        orbe,orbs = geigh(h,S)
        orbea = orbeb = orbe
        orbsa = orbsb = orbs
    
    #print "A Trial Orbital Energies:\n", orbea

    print "A Trial Orbitals:\n"
    pad_out(orbsa)

    #print "B Trial Orbital Energies:\n",orbeb

    print "B Trial Orbitals:\n"
    pad_out(orbsb)
    
    enuke = atoms.get_enuke()
    eold = 0.

    for i in xrange(MaxIter):
        print "SCF Iteration:",i,"Starting Energy:",eold
        #save the starting orbitals
        oldorbs_a=orbsa
        oldorbs_b=orbsb

        Da = mk_auger_dens(orbsa,occa)
        Db = mk_auger_dens(orbsb,occb)
        #Da_std = mkdens(orbsa,0,nalpha)
        #Db_std = mkdens(orbsb,0,nbeta)
        #pad_out(Da - Da_std ) #use to test mk_aug_dens with ground state occupations
        #pad_out(Db - Db_std )
        
        
        Ja = getJ(Ints,Da)
        Jb = getJ(Ints,Db)
        Ka = getK(Ints,Da)
        Kb = getK(Ints,Db)
        Fa = h+Ja+Jb-Ka
        Fb = h+Ja+Jb-Kb

        orbea,orbsa = geigh(Fa,S)
        orbeb,orbsb = geigh(Fb,S)
        
        #save the new orbitals
        neworbs_a=orbsa
        neworbs_b=orbsb
        
        #now we biorthogonalize the new orbitals to the old ones
        #to setup occupation arrays for the next scf cycle
        orbsa = biorthogonalize(neworbs_a,oldorbs_a,S,nalpha,occa)
        orbsb = biorthogonalize(neworbs_b,oldorbs_b,S,nbeta,occb)
        
        energya = get_energy(h,Fa,Da)
        energyb = get_energy(h,Fb,Db)
        energy = (energya+energyb)/2+enuke
        Dab = Da+Db
        Eone = trace2(Dab,h)
        Ej = 0.5*trace2(Dab,Ja+Jb)
        Ek = -0.5*(trace2(Da,Ka)+trace2(Db,Kb))
        
        #print "%d %f %f %f %f" % (i,energy,Eone,Ej,Ek)
        
        logging.debug("%d %f %f %f %f" % (i,energy,Eone,Ej,Ek))
        if abs(energy-eold) < ConvCriteria: break
        eold = energy
        if i==(MaxIter-1):
            print "Warning: Reached maximum number of SCF cycles may want to rerun calculation with more SCF cycles"
    logger.info("Final UHF energy for system %s is %f" % (atoms.name,energy))
    return energy,(orbea,orbeb),(orbsa,orbsb)
Ejemplo n.º 3
0
def dft_fixed_occ(atoms,occs,**kwargs):
    """\
    dft(atoms,**kwargs) - DFT driving routine

    atoms       A Molecule object containing the molecule

    Options:      Value   Description
    --------      -----   -----------
    verbose       False   Output terse information to stdout (default)
                  True    Print out additional information 
    ConvCriteria  1e-4    Convergence Criteria
    MaxIter       20      Maximum SCF iterations
    DoAveraging   True    Use DIIS for accelerated convergence (default)
                  False   No convergence acceleration
    ETemp         False   Use ETemp value for finite temperature DFT (default)
                  float   Use (float) for the electron temperature
    bfs           None    The basis functions to use. List of CGBF's
    basis_data    None    The basis data to use to construct bfs
    integrals     None    The one- and two-electron integrals to use
                          If not None, S,h,Ints
    orbs          None    If not none, the guess orbitals
    functional    SVWN    Use the SVWN (LDA) DFT functional (default)
                  S0      Use the Slater Xalpha DFT functional
                  BLYP    Use the BLYP GGA DFT functional
                  PBE     Use the PBE DFT functional
    grid_nrad     32      Number of radial shells per atom
    grid_fineness 1       Radial shell fineness. 0->coarse, 1->medium, 2->fine
    spin_type     A       Average occupation method for open shell (default)
                  R       Restricted open shell (not implemented yet)
                  U       Unrestricted open shell (aka spin-polarized dft)
                          Only A works now. Stay tuned.
    """
    verbose = kwargs.get('verbose',False) 
    ConvCriteria = kwargs.get('ConvCriteria',1e-4)
    MaxIter = kwargs.get('MaxIter',20)
    DoAveraging = kwargs.get('DoAveraging',True)
    ETemp = kwargs.get('ETemp',False)
    functional = kwargs.get('functional','SVWN')
    kwargs['do_grad_dens'] = need_gradients[functional]

    bfs = kwargs.get('bfs',None)
    if not bfs:
        basis_data = kwargs.get('basis_data',None)
        bfs = getbasis(atoms,basis_data)

    integrals = kwargs.get('integrals',None)
    if integrals:
        S,h,Ints = integrals
    else:
        S,h,Ints = getints(bfs,atoms)

    nel = atoms.get_nel()
    enuke = atoms.get_enuke()

    # default medium mesh
    grid_nrad = kwargs.get('grid_nrad',32)
    grid_fineness = kwargs.get('grid_fineness',1)

    gr = MolecularGrid(atoms,grid_nrad,grid_fineness,**kwargs) 
    gr.set_bf_amps(bfs)

    # It would be nice to have a more intelligent treatment of the guess
    # so that I could pass in a density rather than a set of orbs.
    orbs = kwargs.get('orbs',None)
    if orbs is None: orbe,orbs = geigh(h,S)

    nclosed,nopen = atoms.get_closedopen()

    if verbose: 
        print "DFT calculation on %s using functional %s" % (
            atoms.name,functional)
        print "Nbf = %d" % len(bfs)
        print "Nclosed = %d" % nclosed
        print "Nopen = %d" % nclosed
        if nopen: print "Using spin-averaged dft for open shell calculation"

    eold = 0.
    if DoAveraging:
        print "Using DIIS averaging"
        avg=DIIS(S)

    # Converge the LDA density for the system:
    if verbose: print "Optimization of DFT density"
    for i in xrange(MaxIter):
        #print "SCF Iteration:",i,"Starting Energy:",eold
        #save the starting orbitals
        oldorbs=orbs
        if ETemp:
            efermi = get_efermi(nel,orbe,ETemp)
            occs = get_fermi_occs(efermi,orbe,ETemp)
            D = mkdens_occs(orbs,occs)
            entropy = get_entropy(occs,ETemp)
        else:
            D = mk_auger_dens(orbs, occs)
            #D = mkdens_spinavg(orbs,nclosed,nopen)
    
        gr.setdens(D)

        J = getJ(Ints,D)

        Exc,XC = getXC(gr,nel,**kwargs)
            
        F = h+2*J+XC
        if DoAveraging: F = avg.getF(F,D)
        
        orbe,orbs = geigh(F,S)
        #pad_out(orbs)
        #save the new eigenstates of the fock operator F
        neworbs=orbs
        #send oldorbs and neworbs to get biorthogonalized method
        #orbs = biorthog(neworbs, oldorbs, S, nel)
        
        Ej = 2*trace2(D,J)
        Eone = 2*trace2(D,h)
        energy = Eone + Ej + Exc + enuke
        print i+1,"   ",energy,"    ",Ej,"  ",Exc," ",enuke
        if ETemp: energy += entropy
        if verbose:
            print "%d %10.4f %10.4f %10.4f %10.4f %10.4f" % (
                i,energy,Eone,Ej,Exc,enuke)
        if abs(energy-eold) < ConvCriteria: break
        eold = energy
        
    print "Final %s energy for system %s is %f" % (functional,atoms.name,energy)
    return energy,orbe,orbs
Ejemplo n.º 4
0
def uhf_fixed_occ(atoms, occa, occb, **kwargs):
    """\
    occa and occb represent the orbital occupation arrays for 
    the calculating spin orbitals with holes
    
    uhf(atoms,**kwargs) - Unrestriced Open Shell Hartree Fock
    atoms       A Molecule object containing the molecule

    Options:      Value   Description
    --------      -----   -----------
    ConvCriteria  1e-4    Convergence Criteria
    MaxIter       20      Maximum SCF iterations
    DoAveraging   True    Use DIIS averaging for convergence acceleration
    bfs           None    The basis functions to use. List of CGBF's
    basis_data    None    The basis data to use to construct bfs
    integrals     None    The one- and two-electron integrals to use
                          If not None, S,h,Ints
    orbs          None    If not None, the guess orbitals
    """

    from biorthogonal import biorthogonalize, pad_out

    ConvCriteria = kwargs.get('ConvCriteria', settings.ConvergenceCriteria)
    MaxIter = kwargs.get('MaxIter', settings.MaxIters)
    DoAveraging = kwargs.get('DoAveraging', settings.Averaging)
    averaging = kwargs.get('averaging', settings.MixingFraction)
    ETemp = kwargs.get('ETemp', settings.ElectronTemperature)

    bfs = getbasis(atoms, **kwargs)

    S, h, Ints = getints(bfs, atoms, **kwargs)

    nel = atoms.get_nel()

    nalpha, nbeta = atoms.get_alphabeta()  #pass in kwargs for multiplicity

    orbsa = kwargs.get('orbsa')
    orbsb = kwargs.get('orbsb')
    if (orbsa == None or orbsb == None):
        orbe, orbs = geigh(h, S)
        orbea = orbeb = orbe
        orbsa = orbsb = orbs

    #print "A Trial Orbital Energies:\n", orbea

    print "A Trial Orbitals:\n"
    pad_out(orbsa)

    #print "B Trial Orbital Energies:\n",orbeb

    print "B Trial Orbitals:\n"
    pad_out(orbsb)

    enuke = atoms.get_enuke()
    eold = 0.

    for i in xrange(MaxIter):
        print "SCF Iteration:", i, "Starting Energy:", eold
        #save the starting orbitals
        oldorbs_a = orbsa
        oldorbs_b = orbsb

        Da = mk_auger_dens(orbsa, occa)
        Db = mk_auger_dens(orbsb, occb)
        #Da_std = mkdens(orbsa,0,nalpha)
        #Db_std = mkdens(orbsb,0,nbeta)
        #pad_out(Da - Da_std ) #use to test mk_aug_dens with ground state occupations
        #pad_out(Db - Db_std )

        Ja = getJ(Ints, Da)
        Jb = getJ(Ints, Db)
        Ka = getK(Ints, Da)
        Kb = getK(Ints, Db)
        Fa = h + Ja + Jb - Ka
        Fb = h + Ja + Jb - Kb

        orbea, orbsa = geigh(Fa, S)
        orbeb, orbsb = geigh(Fb, S)

        #save the new orbitals
        neworbs_a = orbsa
        neworbs_b = orbsb

        #now we biorthogonalize the new orbitals to the old ones
        #to setup occupation arrays for the next scf cycle
        orbsa = biorthogonalize(neworbs_a, oldorbs_a, S, nalpha, occa)
        orbsb = biorthogonalize(neworbs_b, oldorbs_b, S, nbeta, occb)

        energya = get_energy(h, Fa, Da)
        energyb = get_energy(h, Fb, Db)
        energy = (energya + energyb) / 2 + enuke
        Dab = Da + Db
        Eone = trace2(Dab, h)
        Ej = 0.5 * trace2(Dab, Ja + Jb)
        Ek = -0.5 * (trace2(Da, Ka) + trace2(Db, Kb))

        #print "%d %f %f %f %f" % (i,energy,Eone,Ej,Ek)

        logging.debug("%d %f %f %f %f" % (i, energy, Eone, Ej, Ek))
        if abs(energy - eold) < ConvCriteria: break
        eold = energy
        if i == (MaxIter - 1):
            print "Warning: Reached maximum number of SCF cycles may want to rerun calculation with more SCF cycles"
    logger.info("Final UHF energy for system %s is %f" % (atoms.name, energy))
    return energy, (orbea, orbeb), (orbsa, orbsb)
Ejemplo n.º 5
0
def uhf(atoms,**opts):
    """\
    uhf(atoms,**opts) - Unrestriced Open Shell Hartree Fock
    atoms       A Molecule object containing the molecule

    Options:      Value   Description
    --------      -----   -----------
    ConvCriteria  1e-4    Convergence Criteria
    MaxIter       20      Maximum SCF iterations
    DoAveraging   True    Use DIIS averaging for convergence acceleration
    bfs           None    The basis functions to use. List of CGBF's
    basis_data    None    The basis data to use to construct bfs
    integrals     None    The one- and two-electron integrals to use
                          If not None, S,h,Ints
    orbs          None    If not None, the guess orbitals
    """
    ConvCriteria = opts.get('ConvCriteria',1e-5)
    MaxIter = opts.get('MaxIter',40)
    DoAveraging = opts.get('DoAveraging',True)
    averaging = opts.get('averaging',0.5)
    ETemp = opts.get('ETemp',False)
    verbose = opts.get('verbose',False)

    bfs = opts.get('bfs',None)
    if not bfs:
        basis_data = opts.get('basis_data',None)
        bfs = getbasis(atoms,basis_data)

    integrals = opts.get('integrals', None)
    if integrals:
        S,h,Ints = integrals
    else:
        S,h,Ints = getints(bfs,atoms)

    nel = atoms.get_nel()

    nalpha,nbeta = atoms.get_alphabeta() #pass in opts for multiplicity
    S,h,Ints = getints(bfs,atoms)

    orbs = opts.get('orbs',None)
    if orbs!=None:
        #orbsa = orbsb = orbs
        orbsa = orbs[0]
        orbsb = orbs[1]
    else:
        orbe,orbs = geigh(h,S)
        orbea = orbeb = orbe
        orbsa = orbsb = orbs

    enuke = atoms.get_enuke()
    eold = 0.

    logger.info("UHF calculation on %s" % atoms.name)
    logger.info("Nbf = %d" % len(bfs))
    logger.info("Nalpha = %d" % nalpha)
    logger.info("Nbeta = %d" % nbeta)
    logger.info("Averaging = %s" % DoAveraging)
    logging.debug("Optimization of HF orbitals")
    for i in xrange(MaxIter):
        if verbose: print "SCF Iteration:",i,"Starting Energy:",eold
        if ETemp:
            # We have to multiply nalpha and nbeta by 2
            #  to get the Fermi energies to come out correct:
            efermia = get_efermi(2.0*nalpha,orbea,ETemp)
            occsa = get_fermi_occs(efermia,orbea,ETemp)
            #print "occsa = ",occsa
            Da = mkdens_occs(orbsa,occsa)
            efermib = get_efermi(2.0*nbeta,orbeb,ETemp)
            occsb = get_fermi_occs(efermib,orbeb,ETemp)
            #print "occsb = ",occsb
            Db = mkdens_occs(orbsb,occsb)
            entropy = 0.5*(get_entropy(occsa,ETemp)+get_entropy(occsb,ETemp))
        else:
            Da = mkdens(orbsa,0,nalpha)
            Db = mkdens(orbsb,0,nbeta)
        if DoAveraging:
            if i: 
                Da = averaging*Da + (1-averaging)*Da0
                Db = averaging*Db + (1-averaging)*Db0
            Da0 = Da
            Db0 = Db

        Ja = getJ(Ints,Da)
        Jb = getJ(Ints,Db)
        Ka = getK(Ints,Da)
        Kb = getK(Ints,Db)
        Fa = h+Ja+Jb-Ka
        Fb = h+Ja+Jb-Kb
        orbea,orbsa = geigh(Fa,S)
        orbeb,orbsb = geigh(Fb,S)
        energya = get_energy(h,Fa,Da)
        energyb = get_energy(h,Fb,Db)
        energy = (energya+energyb)/2+enuke
        Dab = Da+Db
        Eone = trace2(Dab,h)
        Ej = 0.5*trace2(Dab,Ja+Jb)
        Ek = -0.5*(trace2(Da,Ka)+trace2(Db,Kb))
        if ETemp: energy += entropy
        logger.debug("%d %f %f %f %f" % (i,energy,Eone,Ej,Ek))
        if abs(energy-eold) < ConvCriteria: break
        eold = energy
    logger.info("Final UHF energy for system %s is %f" % (atoms.name,energy))
    return energy,(orbea,orbeb),(orbsa,orbsb)
Ejemplo n.º 6
0
def uhf(atoms, **kwargs):
    """\
    uhf(atoms,**kwargs) - Unrestriced Open Shell Hartree Fock
    atoms       A Molecule object containing the molecule

    Options:      Value   Description
    --------      -----   -----------
    ConvCriteria  1e-4    Convergence Criteria
    MaxIter       20      Maximum SCF iterations
    DoAveraging   True    Use DIIS averaging for convergence acceleration
    bfs           None    The basis functions to use. List of CGBF's
    basis_data    None    The basis data to use to construct bfs
    integrals     None    The one- and two-electron integrals to use
                          If not None, S,h,Ints
    orbs          None    If not None, the guess orbitals
    """
    ConvCriteria = kwargs.get('ConvCriteria', settings.ConvergenceCriteria)
    MaxIter = kwargs.get('MaxIter', settings.MaxIters)
    DoAveraging = kwargs.get('DoAveraging', settings.Averaging)
    averaging = kwargs.get('averaging', settings.MixingFraction)
    ETemp = kwargs.get('ETemp', settings.ElectronTemperature)
    verbose = kwargs.get('verbose')

    bfs = getbasis(atoms, **kwargs)

    S, h, Ints = getints(bfs, atoms, **kwargs)

    nel = atoms.get_nel()

    nalpha, nbeta = atoms.get_alphabeta()  #pass in kwargs for multiplicity

    orbs = kwargs.get('orbs')
    if orbs != None:
        #orbsa = orbsb = orbs
        orbsa = orbs[0]
        orbsb = orbs[1]
    else:
        orbe, orbs = geigh(h, S)
        orbea = orbeb = orbe
        orbsa = orbsb = orbs

    enuke = atoms.get_enuke()
    eold = 0.

    logger.info("UHF calculation on %s" % atoms.name)
    logger.info("Nbf = %d" % len(bfs))
    logger.info("Nalpha = %d" % nalpha)
    logger.info("Nbeta = %d" % nbeta)
    logger.info("Averaging = %s" % DoAveraging)
    logging.debug("Optimization of HF orbitals")
    for i in xrange(MaxIter):
        if verbose: print "SCF Iteration:", i, "Starting Energy:", eold
        if ETemp:
            # We have to multiply nalpha and nbeta by 2
            #  to get the Fermi energies to come out correct:
            efermia = get_efermi(2.0 * nalpha, orbea, ETemp)
            occsa = get_fermi_occs(efermia, orbea, ETemp)
            #print "occsa = ",occsa
            Da = mkdens_occs(orbsa, occsa)
            efermib = get_efermi(2.0 * nbeta, orbeb, ETemp)
            occsb = get_fermi_occs(efermib, orbeb, ETemp)
            #print "occsb = ",occsb
            Db = mkdens_occs(orbsb, occsb)
            entropy = 0.5 * (get_entropy(occsa, ETemp) +
                             get_entropy(occsb, ETemp))
        else:
            Da = mkdens(orbsa, 0, nalpha)
            Db = mkdens(orbsb, 0, nbeta)
        if DoAveraging:
            if i:
                Da = averaging * Da + (1 - averaging) * Da0
                Db = averaging * Db + (1 - averaging) * Db0
            Da0 = Da
            Db0 = Db

        Ja = getJ(Ints, Da)
        Jb = getJ(Ints, Db)
        Ka = getK(Ints, Da)
        Kb = getK(Ints, Db)
        Fa = h + Ja + Jb - Ka
        Fb = h + Ja + Jb - Kb
        orbea, orbsa = geigh(Fa, S)
        orbeb, orbsb = geigh(Fb, S)
        energya = get_energy(h, Fa, Da)
        energyb = get_energy(h, Fb, Db)
        energy = (energya + energyb) / 2 + enuke
        Dab = Da + Db
        Eone = trace2(Dab, h)
        Ej = 0.5 * trace2(Dab, Ja + Jb)
        Ek = -0.5 * (trace2(Da, Ka) + trace2(Db, Kb))
        if ETemp: energy += entropy
        logger.debug("%d %f %f %f %f" % (i, energy, Eone, Ej, Ek))
        if abs(energy - eold) < ConvCriteria: break
        eold = energy
    logger.info("Final UHF energy for system %s is %f" % (atoms.name, energy))
    return energy, (orbea, orbeb), (orbsa, orbsb)
Ejemplo n.º 7
0
def udft(atoms,**kwargs):
    """\
    udft(atoms,**kwargs) - Unrestricted spin DFT driving routine

    atoms       A Molecule object containing the molecule

    Options:      Value   Description
    --------      -----   -----------
    verbose       False   Output terse information to stdout (default)
                  True    Print out additional information 
    ConvCriteria  1e-4    Convergence Criteria
    MaxIter       20      Maximum SCF iterations
    DoAveraging   True    Use DIIS for accelerated convergence (default)
                  False   No convergence acceleration
    ETemp         False   Use ETemp value for finite temperature DFT (default)
                  float   Use (float) for the electron temperature
    bfs           None    The basis functions to use. List of CGBF's
    basis_data    None    The basis data to use to construct bfs
    integrals     None    The one- and two-electron integrals to use
                          If not None, S,h,Ints
    orbs          None    If not none, the guess orbitals
    functional    SVWN    Use the SVWN (LDA) DFT functional (default)
                  S0      Use the Slater Xalpha DFT functional
                  BLYP    Use the BLYP GGA DFT functional
                  PBE     Use the PBE DFT functional
    grid_nrad     32      Number of radial shells per atom
    grid_fineness 1       Radial shell fineness. 0->coarse, 1->medium, 2->fine
    """
    verbose = kwargs.get('verbose')
    ConvCriteria = kwargs.get('ConvCriteria',settings.DFTConvergenceCriteria)
    MaxIter = kwargs.get('MaxIter',settings.MaxIter)
    DoAveraging = kwargs.get('DoAveraging',settings.DFTAveraging)
    ETemp = kwargs.get('ETemp',settings.DFT.ElectronTemperature)
    functional = kwargs.get('functional',settings.DFTFunctional)
    kwargs['do_grad_dens'] = need_gradients[functional]
    kwargs['do_spin_polarized'] = True

    bfs = getbasis(atoms,**kwargs)
    S,h,Ints = getints(bfs,atoms,**kwargs)
    nel = atoms.get_nel()
    enuke = atoms.get_enuke()

    # default medium mesh
    grid_nrad = kwargs.get('grid_nrad',settings.DFTGridRadii)
    grid_fineness = kwargs.get('grid_fineness',settings.DFTGridFineness)

    gr = MolecularGrid(atoms,grid_nrad,grid_fineness,**kwargs) 
    gr.set_bf_amps(bfs)

    # It would be nice to have a more intelligent treatment of the guess
    # so that I could pass in a density rather than a set of orbs.
    orbs = kwargs.get('orbs')
    if not orbs: orbe,orbs = geigh(h,S)
    orbsa = orbsb = orbs

    nalpha,nbeta = atoms.get_alphabeta()

    if verbose: 
        print "UDFT calculation on %s using functional %s" \
              % (atoms.name,functional)
        print "Nbf = %d" % len(bfs)
        print "Nalpha = %d" % nalpha
        print "Nbeta = %d" % nbeta
        
    eold = 0.

    # Converge the LDA density for the system:
    if verbose: print "Optimization of DFT density"
    for i in xrange(MaxIter):
        Da = mkdens(orbsa,0,nalpha)
        Db = mkdens(orbsb,0,nbeta)

        gr.setdens(Da,Db)

        Ja = getJ(Ints,Da)
        Jb = getJ(Ints,Db)

        Exc,XCa,XCb = getXC(gr,nel,**kwargs)
            
        Fa = h+Ja+Jb-Ka
        Fb = h+Ja+Jb-Kb
        
        orbea,orbsa = geigh(Fa,S)
        orbeb,orbsb = geigh(Fb,S)
        
        Eja = trace2(D,Ja)
        Ejb = trace2(D,Jb)
        Eone = 2*trace2(D,h)
        energy = Eone + Eja + Ejb + Exc + enuke
        if verbose:
            print "%d %10.4f %10.4f %10.4f %10.4f %10.4f" % (
                i,energy,Eone,Eja+Ejb,Exc,enuke)
        if abs(energy-eold) < ConvCriteria: break
        eold = energy
    print "Final U%s energy for system %s is %f" % (
        functional,atoms.name,energy)
    return energy,orbe,orbs
Ejemplo n.º 8
0
def udft_fixed_occ(atoms, occa, occb, **kwargs):
    """\
    occa and occb represent the orbital occupation arrays for 
    the calculating spin orbitals with holes
    
    udft(atoms,**kwargs) - Unrestricted spin DFT driving routine

    atoms       A Molecule object containing the molecule

    Options:      Value   Description
    --------      -----   -----------
    verbose       False   Output terse information to stdout (default)
                  True    Print out additional information 
    ConvCriteria  1e-4    Convergence Criteria
    MaxIter       20      Maximum SCF iterations
    DoAveraging   True    Use DIIS for accelerated convergence (default)
                  False   No convergence acceleration
    ETemp         False   Use ETemp value for finite temperature DFT (default)
                  float   Use (float) for the electron temperature
    bfs           None    The basis functions to use. List of CGBF's
    basis_data    None    The basis data to use to construct bfs
    integrals     None    The one- and two-electron integrals to use
                          If not None, S,h,Ints
    orbs          None    If not none, the guess orbitals
    functional    SVWN    Use the SVWN (LDA) DFT functional (default)
                  S0      Use the Slater Xalpha DFT functional
                  BLYP    Use the BLYP GGA DFT functional
                  PBE     Use the PBE DFT functional
    grid_nrad     32      Number of radial shells per atom
    grid_fineness 1       Radial shell fineness. 0->coarse, 1->medium, 2->fine
    """
    verbose = kwargs.get('verbose', False)
    ConvCriteria = kwargs.get('ConvCriteria', 1e-4)
    MaxIter = kwargs.get('MaxIter', 20)
    DoAveraging = kwargs.get('DoAveraging', True)
    averaging = kwargs.get('averaging', 0.5)
    ETemp = kwargs.get('ETemp', False)
    functional = kwargs.get('functional', 'LDA')
    #default to LDA which has no correlation since that is easier

    kwargs['do_grad_dens'] = need_gradients[functional]
    kwargs['do_spin_polarized'] = True

    bfs = kwargs.get('bfs', None)
    if not bfs:
        basis_data = kwargs.get('basis_data', None)
        bfs = getbasis(atoms, basis_data)

    integrals = kwargs.get('integrals', None)
    if integrals:
        S, h, Ints = integrals
    else:
        S, h, Ints = getints(bfs, atoms)

    nel = atoms.get_nel()
    enuke = atoms.get_enuke()

    # default medium mesh
    grid_nrad = kwargs.get('grid_nrad', 32)
    grid_fineness = kwargs.get('grid_fineness', 1)

    gr = MolecularGrid(atoms, grid_nrad, grid_fineness, **kwargs)
    gr.set_bf_amps(bfs)

    # It would be nice to have a more intelligent treatment of the guess
    # so that I could pass in a density rather than a set of orbs.
    orbs = kwargs.get('orbs', None)
    if not orbs: orbe, orbs = geigh(h, S)
    orbsa = orbsb = orbs

    nalpha, nbeta = atoms.get_alphabeta()

    if verbose:
        print "UDFT calculation on %s using functional %s" % (atoms.name,
                                                              functional)
        print "Nbf = %d" % len(bfs)
        print "Nalpha = %d" % nalpha
        print "Nbeta = %d" % nbeta

    eold = 0.

    # Converge the LDA density for the system:
    print "Optimization of DFT density"
    for i in xrange(MaxIter):
        Da = mk_auger_dens(orbsa, occa)
        Db = mk_auger_dens(orbsb, occb)
        Dab = Da + Db

        if DoAveraging:
            if i:
                Da = averaging * Da + (1 - averaging) * Da0
                Db = averaging * Db + (1 - averaging) * Db0
            Da0 = Da
            Db0 = Db

        Ja = getJ(Ints, Da)
        Jb = getJ(Ints, Db)

        #remember we must use a functional that has no correlation energy
        gr.setdens(Da, Db)
        exca, XCa, XCb = getXC(gr, nel, **kwargs)

        Fa = h + Ja + Jb + XCa
        Fb = h + Ja + Jb + XCb

        orbea, orbsa = geigh(Fa, S)
        orbeb, orbsb = geigh(Fb, S)

        Eone = trace2(Dab, h)
        Ej = 0.5 * trace2(Dab, Ja + Jb)
        Exc = 0.5 * exca + 0.5 * excb

        energy = Eone + Ej + Exc + enuke

        print i + 1, "   ", energy, "    ", Ej, "  ", Exc
        if verbose:
            print "%d %10.4f %10.4f %10.4f" % (i, energy, Ej, Exc)
        if abs(energy - eold) < ConvCriteria: break
        eold = energy
    print "Final U%s energy for system %s is %f" % (functional, atoms.name,
                                                    energy)
    return energy, (orbea, orbeb), (orbsa, orbsb)
Ejemplo n.º 9
0
def dft_fixed_occ(atoms, occs, **kwargs):
    """\
    dft(atoms,**kwargs) - DFT driving routine

    atoms       A Molecule object containing the molecule

    Options:      Value   Description
    --------      -----   -----------
    verbose       False   Output terse information to stdout (default)
                  True    Print out additional information 
    ConvCriteria  1e-4    Convergence Criteria
    MaxIter       20      Maximum SCF iterations
    DoAveraging   True    Use DIIS for accelerated convergence (default)
                  False   No convergence acceleration
    ETemp         False   Use ETemp value for finite temperature DFT (default)
                  float   Use (float) for the electron temperature
    bfs           None    The basis functions to use. List of CGBF's
    basis_data    None    The basis data to use to construct bfs
    integrals     None    The one- and two-electron integrals to use
                          If not None, S,h,Ints
    orbs          None    If not none, the guess orbitals
    functional    SVWN    Use the SVWN (LDA) DFT functional (default)
                  S0      Use the Slater Xalpha DFT functional
                  BLYP    Use the BLYP GGA DFT functional
                  PBE     Use the PBE DFT functional
    grid_nrad     32      Number of radial shells per atom
    grid_fineness 1       Radial shell fineness. 0->coarse, 1->medium, 2->fine
    spin_type     A       Average occupation method for open shell (default)
                  R       Restricted open shell (not implemented yet)
                  U       Unrestricted open shell (aka spin-polarized dft)
                          Only A works now. Stay tuned.
    """
    verbose = kwargs.get('verbose', False)
    ConvCriteria = kwargs.get('ConvCriteria', 1e-4)
    MaxIter = kwargs.get('MaxIter', 20)
    DoAveraging = kwargs.get('DoAveraging', True)
    ETemp = kwargs.get('ETemp', False)
    functional = kwargs.get('functional', 'SVWN')
    kwargs['do_grad_dens'] = need_gradients[functional]

    bfs = kwargs.get('bfs', None)
    if not bfs:
        basis_data = kwargs.get('basis_data', None)
        bfs = getbasis(atoms, basis_data)

    integrals = kwargs.get('integrals', None)
    if integrals:
        S, h, Ints = integrals
    else:
        S, h, Ints = getints(bfs, atoms)

    nel = atoms.get_nel()
    enuke = atoms.get_enuke()

    # default medium mesh
    grid_nrad = kwargs.get('grid_nrad', 32)
    grid_fineness = kwargs.get('grid_fineness', 1)

    gr = MolecularGrid(atoms, grid_nrad, grid_fineness, **kwargs)
    gr.set_bf_amps(bfs)

    # It would be nice to have a more intelligent treatment of the guess
    # so that I could pass in a density rather than a set of orbs.
    orbs = kwargs.get('orbs', None)
    if orbs is None: orbe, orbs = geigh(h, S)

    nclosed, nopen = atoms.get_closedopen()

    if verbose:
        print "DFT calculation on %s using functional %s" % (atoms.name,
                                                             functional)
        print "Nbf = %d" % len(bfs)
        print "Nclosed = %d" % nclosed
        print "Nopen = %d" % nclosed
        if nopen: print "Using spin-averaged dft for open shell calculation"

    eold = 0.
    if DoAveraging:
        print "Using DIIS averaging"
        avg = DIIS(S)

    # Converge the LDA density for the system:
    if verbose: print "Optimization of DFT density"
    for i in xrange(MaxIter):
        #print "SCF Iteration:",i,"Starting Energy:",eold
        #save the starting orbitals
        oldorbs = orbs
        if ETemp:
            efermi = get_efermi(nel, orbe, ETemp)
            occs = get_fermi_occs(efermi, orbe, ETemp)
            D = mkdens_occs(orbs, occs)
            entropy = get_entropy(occs, ETemp)
        else:
            D = mk_auger_dens(orbs, occs)
            #D = mkdens_spinavg(orbs,nclosed,nopen)

        gr.setdens(D)

        J = getJ(Ints, D)

        Exc, XC = getXC(gr, nel, **kwargs)

        F = h + 2 * J + XC
        if DoAveraging: F = avg.getF(F, D)

        orbe, orbs = geigh(F, S)
        #pad_out(orbs)
        #save the new eigenstates of the fock operator F
        neworbs = orbs
        #send oldorbs and neworbs to get biorthogonalized method
        #orbs = biorthog(neworbs, oldorbs, S, nel)

        Ej = 2 * trace2(D, J)
        Eone = 2 * trace2(D, h)
        energy = Eone + Ej + Exc + enuke
        print i + 1, "   ", energy, "    ", Ej, "  ", Exc, " ", enuke
        if ETemp: energy += entropy
        if verbose:
            print "%d %10.4f %10.4f %10.4f %10.4f %10.4f" % (i, energy, Eone,
                                                             Ej, Exc, enuke)
        if abs(energy - eold) < ConvCriteria: break
        eold = energy

    print "Final %s energy for system %s is %f" % (functional, atoms.name,
                                                   energy)
    return energy, orbe, orbs
Ejemplo n.º 10
0
def udft(atoms, **kwargs):
    """\
    udft(atoms,**kwargs) - Unrestricted spin DFT driving routine

    atoms       A Molecule object containing the molecule

    Options:      Value   Description
    --------      -----   -----------
    verbose       False   Output terse information to stdout (default)
                  True    Print out additional information 
    ConvCriteria  1e-4    Convergence Criteria
    MaxIter       20      Maximum SCF iterations
    DoAveraging   True    Use DIIS for accelerated convergence (default)
                  False   No convergence acceleration
    ETemp         False   Use ETemp value for finite temperature DFT (default)
                  float   Use (float) for the electron temperature
    bfs           None    The basis functions to use. List of CGBF's
    basis_data    None    The basis data to use to construct bfs
    integrals     None    The one- and two-electron integrals to use
                          If not None, S,h,Ints
    orbs          None    If not none, the guess orbitals
    functional    SVWN    Use the SVWN (LDA) DFT functional (default)
                  S0      Use the Slater Xalpha DFT functional
                  BLYP    Use the BLYP GGA DFT functional
                  PBE     Use the PBE DFT functional
    grid_nrad     32      Number of radial shells per atom
    grid_fineness 1       Radial shell fineness. 0->coarse, 1->medium, 2->fine
    """
    verbose = kwargs.get('verbose')
    ConvCriteria = kwargs.get('ConvCriteria', settings.DFTConvergenceCriteria)
    MaxIter = kwargs.get('MaxIter', settings.MaxIter)
    DoAveraging = kwargs.get('DoAveraging', settings.DFTAveraging)
    ETemp = kwargs.get('ETemp', settings.DFT.ElectronTemperature)
    functional = kwargs.get('functional', settings.DFTFunctional)
    kwargs['do_grad_dens'] = need_gradients[functional]
    kwargs['do_spin_polarized'] = True

    bfs = getbasis(atoms, **kwargs)
    S, h, Ints = getints(bfs, atoms, **kwargs)
    nel = atoms.get_nel()
    enuke = atoms.get_enuke()

    # default medium mesh
    grid_nrad = kwargs.get('grid_nrad', settings.DFTGridRadii)
    grid_fineness = kwargs.get('grid_fineness', settings.DFTGridFineness)

    gr = MolecularGrid(atoms, grid_nrad, grid_fineness, **kwargs)
    gr.set_bf_amps(bfs)

    # It would be nice to have a more intelligent treatment of the guess
    # so that I could pass in a density rather than a set of orbs.
    orbs = kwargs.get('orbs')
    if not orbs: orbe, orbs = geigh(h, S)
    orbsa = orbsb = orbs

    nalpha, nbeta = atoms.get_alphabeta()

    if verbose:
        print "UDFT calculation on %s using functional %s" \
              % (atoms.name,functional)
        print "Nbf = %d" % len(bfs)
        print "Nalpha = %d" % nalpha
        print "Nbeta = %d" % nbeta

    eold = 0.

    # Converge the LDA density for the system:
    if verbose: print "Optimization of DFT density"
    for i in xrange(MaxIter):
        Da = mkdens(orbsa, 0, nalpha)
        Db = mkdens(orbsb, 0, nbeta)

        gr.setdens(Da, Db)

        Ja = getJ(Ints, Da)
        Jb = getJ(Ints, Db)

        Exc, XCa, XCb = getXC(gr, nel, **kwargs)

        Fa = h + Ja + Jb - Ka
        Fb = h + Ja + Jb - Kb

        orbea, orbsa = geigh(Fa, S)
        orbeb, orbsb = geigh(Fb, S)

        Eja = trace2(D, Ja)
        Ejb = trace2(D, Jb)
        Eone = 2 * trace2(D, h)
        energy = Eone + Eja + Ejb + Exc + enuke
        if verbose:
            print "%d %10.4f %10.4f %10.4f %10.4f %10.4f" % (
                i, energy, Eone, Eja + Ejb, Exc, enuke)
        if abs(energy - eold) < ConvCriteria: break
        eold = energy
    print "Final U%s energy for system %s is %f" % (functional, atoms.name,
                                                    energy)
    return energy, orbe, orbs