Beispiel #1
0
def test():
    from hartree_fock import rhf
    from Molecule import Molecule

    # Make a test molecule for the calculation
    h2 = Molecule('h2',[(1,(1.,0,0)),(1,(-1.,0,0))])

    # Get a basis set and compute the integrals.
    # normally the routine will do this automatically, but we
    # do it explicitly here so that we can pass the same set
    # of integrals into the CI code and thus not recompute them.
    bfs = getbasis(h2)
    S,h,Ints = getints(bfs,h2)

    # Compute the HF wave function for our molecule
    en,orbe,orbs = rhf(h2,
                       integrals=(S,h,Ints)
                       )
    print "SCF completed, E = ",en
    print " orbital energies ",orbe

    # Compute the occupied and unoccupied orbitals, used in the
    # CIS program to generate the excitations
    nclosed,nopen = h2.get_closedopen()
    nbf = len(bfs)
    nocc = nclosed+nopen
    nvirt = nbf-nocc

    # Call the CI program:
    Ecis = CIS(Ints,orbs,orbe,nocc,nvirt,en)
    print "Ecis = ",Ecis
Beispiel #2
0
def test_contr():
    from basis_sto3g import basis_data
    from Molecule import Molecule
    from Ints import getbasis
    from time import time

    r = 1 / 0.52918
    atoms = Molecule('h2o',
                     atomlist=[(8, (0, 0, 0)), (1, (r, 0, 0)), (1, (0, 0, r))])
    bfs = getbasis(atoms, basis_data)

    o_1s = bfs[0]
    o_2s = bfs[1]
    o_px = bfs[2]
    o_py = bfs[3]
    o_pz = bfs[4]
    h1_s = bfs[5]
    h2_s = bfs[6]

    t0 = time()
    val = \
        contr_coulomb(h2_s.pexps,h2_s.pcoefs,h2_s.pnorms,
                      h2_s.origin,h2_s.powers,
                      h2_s.pexps,h2_s.pcoefs,h2_s.pnorms,
                      h2_s.origin,h2_s.powers,
                      h2_s.pexps,h2_s.pcoefs,h2_s.pnorms,
                      h2_s.origin,h2_s.powers,
                      o_pz.pexps,o_pz.pcoefs,o_pz.pnorms,
                      o_pz.origin,o_pz.powers)
    t1 = time()
    print val, t1 - t0
Beispiel #3
0
def test():
    from Ints import getbasis, getints, get2JmK
    from hartree_fock import get_nel, get_enuke, get_energy
    from LA2 import geigh, mkdens
    from IO import mtx2file
    from Molecule import Molecule

    ConvCriteria = 0.00001
    MaxIt = 30
    h2o = Molecule("h2o", [(8, (0, 0, 0)), (1, (1.0, 0, 0)), (1, (0, 1.0, 0))], units="Angstrom")
    bfs = getbasis(h2o)
    S, h, Ints = getints(bfs, h2o)
    orbe, orbs = geigh(h, S)
    nel = get_nel(h2o)
    nocc = int(nel / 2)
    enuke = get_enuke(h2o)
    eold = 0.0
    avg = DIIS2(S)
    for i in range(30):
        D = mkdens(orbs, 0, nocc)
        mtx2file(D)
        G = get2JmK(Ints, D)
        F = h + G
        F = avg.getF(F, D)  # do the DIIS extrapolation
        orbe, orbs = geigh(F, S)
        energy = get_energy(h, F, D, enuke)
        print i + 1, energy
        if abs(energy - eold) < ConvCriteria:
            break
        eold = energy

    return
Beispiel #4
0
def test_contr():
    from basis_sto3g import basis_data
    from Molecule import Molecule
    from Ints import getbasis
    from time import time
    
    r = 1/0.52918
    atoms=Molecule('h2o',atomlist = [(8,(0,0,0)),(1,(r,0,0)),(1,(0,0,r))])
    bfs = getbasis(atoms,basis_data)
    
    o_1s = bfs[0]
    o_2s = bfs[1]
    o_px = bfs[2]
    o_py = bfs[3]
    o_pz = bfs[4]
    h1_s = bfs[5]
    h2_s = bfs[6]
    

    t0 = time()
    val = \
        contr_coulomb(h2_s.exps(),h2_s.coefs(),h2_s.pnorms(),
                      h2_s.origin(),h2_s.powers(),
                      h2_s.exps(),h2_s.coefs(),h2_s.pnorms(),
                      h2_s.origin(),h2_s.powers(),
                      h2_s.exps(),h2_s.coefs(),h2_s.pnorms(),
                      h2_s.origin(),h2_s.powers(),
                      o_pz.exps(),o_pz.coefs(),o_pz.pnorms(),
                      o_pz.origin(),o_pz.powers())
    t1 = time()
    print val,t1-t0
Beispiel #5
0
def test():
    from Ints import getbasis, getints, get2JmK
    from hartree_fock import get_nel, get_enuke, get_energy
    from LA2 import geigh, mkdens
    from IO import mtx2file
    from Molecule import Molecule

    ConvCriteria = 0.00001
    MaxIt = 30
    h2o = Molecule('h2o', [(8, (0, 0, 0)), (1, (1., 0, 0)), (1, (0, 1., 0))],
                   units='Angstrom')
    bfs = getbasis(h2o)
    S, h, Ints = getints(bfs, h2o)
    orbe, orbs = geigh(h, S)
    nel = get_nel(h2o)
    nocc = int(nel / 2)
    enuke = get_enuke(h2o)
    eold = 0.
    avg = DIIS2(S)
    for i in xrange(30):
        D = mkdens(orbs, 0, nocc)
        mtx2file(D)
        G = get2JmK(Ints, D)
        F = h + G
        F = avg.getF(F, D)  # do the DIIS extrapolation
        orbe, orbs = geigh(F, S)
        energy = get_energy(h, F, D, enuke)
        print i + 1, energy
        if abs(energy - eold) < ConvCriteria: break
        eold = energy

    return
Beispiel #6
0
def test():
    from Ints import getbasis, getints
    from hartree_fock import rhf
    from Molecule import Molecule

    # Make a test molecule for the calculation
    h2 = Molecule('h2', [(1, (1., 0, 0)), (1, (-1., 0, 0))])

    # Get a basis set and compute the integrals.
    # normally the routine will do this automatically, but we
    # do it explicitly here so that we can pass the same set
    # of integrals into the CI code and thus not recompute them.
    bfs = getbasis(h2)
    S, h, Ints = getints(bfs, h2)

    # Compute the HF wave function for our molecule
    en, orbe, orbs = rhf(h2, integrals=(S, h, Ints))
    print "SCF completed, E = ", en
    print " orbital energies ", orbe

    # Compute the occupied and unoccupied orbitals, used in the
    # CIS program to generate the excitations
    nclosed, nopen = h2.get_closedopen()
    nbf = len(bfs)
    nocc = nclosed + nopen
    nvirt = nbf - nocc

    # Call the CI program:
    Ecis = CIS(Ints, orbs, orbe, nocc, nvirt, en)
    print "Ecis = ", Ecis
Beispiel #7
0
def hf_force(mol,wf,bname):
# calculates Hartree-Fock derived atomic forces through
# analytic derivatives of the HF energy.  Stores the forces 
# the atom class which can later be accessed through 
# atomlist[j].forces[i] which would give you component i
# of the force on atom j
    bset = getbasis(mol.atoms,basis=bname)
     
    if wf.restricted:
        rhf_force(mol,wf,bset)
    if wf.unrestricted:
        uhf_force(mol,wf,bset)
    if wf.fixedocc:
        fixedocc_uhf_force(mol,wf,bset)
        
    return
Beispiel #8
0
def hf_force(mol, wf, bname):
    # calculates Hartree-Fock derived atomic forces through
    # analytic derivatives of the HF energy.  Stores the forces
    # the atom class which can later be accessed through
    # atomlist[j].forces[i] which would give you component i
    # of the force on atom j
    bset = getbasis(mol.atoms, basis=bname)

    if wf.restricted:
        rhf_force(mol, wf, bset)
    if wf.unrestricted:
        uhf_force(mol, wf, bset)
    if wf.fixedocc:
        fixedocc_uhf_force(mol, wf, bset)

    return
Beispiel #9
0
def HFGF(atoms, charge=0):
    nclosed, nopen = atoms.get_closedopen()
    if nopen: raise Exception("HFGF only works for closed shell cases")
    bfs = getbasis(atoms)
    nvirt = len(bfs) - nclosed
    S, h, Ints = getints(bfs, atoms)
    hf_energy, hf_orbe, hf_orbs = scf(atoms, S, h, Ints, charge)
    print_orbe(hf_orbe, nclosed, nvirt)

    sigma = Sigma2(hf_orbe, hf_orbs, Ints, len(bfs), nclosed)

    for i in [4, 5, 6, 7, 8, 9]:
        print "Correcting orbital %d, HF Eorb = %f" % (i + 1, hf_orbe[i])
        del0, dele = sigma.eval(i)
        print "-> Eorb = %f %f" % (hf_orbe[i] + del0, hf_orbe[i] + dele)

    return
Beispiel #10
0
def test():
    # Jaguar gets -0.0276516 h for this:
    from Ints import getbasis, getints
    from hartree_fock import scf
    from IO import mtx2file
    from Molecule import Molecule

    atoms = Molecule('h2', [(1, (1., 0, 0)), (1, (-1., 0, 0))])
    bfs = getbasis(atoms)
    S, h, Ints = getints(bfs, atoms)
    en, orbe, orbs = scf(atoms, S, h, Ints, 0, 0.0001, 10)
    print "SCF completed, E = ", en

    emp2 = MP2(Ints, orbs, orbe, 1, 9)
    print "MP2 correction = ", emp2
    print "Final energy = ", en + emp2
    return
Beispiel #11
0
def test():
    # Jaguar gets -0.0276516 h for this:
    from Ints import getbasis,getints
    from hartree_fock import scf
    from IO import mtx2file
    from Molecule import Molecule

    atoms = Molecule('h2',[(1,(1.,0,0)),(1,(-1.,0,0))])
    bfs = getbasis(atoms)
    S,h,Ints = getints(bfs,atoms)
    en,orbe,orbs = scf(atoms,S,h,Ints,0,0.0001,10)
    print "SCF completed, E = ",en

    emp2 = MP2(Ints,orbs,orbe,1,9)
    print "MP2 correction = ",emp2
    print "Final energy = ",en+emp2
    return
Beispiel #12
0
def HFGF(atoms,charge=0):
    nclosed,nopen = atoms.get_closedopen()
    if nopen: raise Exception("HFGF only works for closed shell cases")
    bfs = getbasis(atoms)
    nvirt = len(bfs)-nclosed
    S,h,Ints = getints(bfs,atoms)
    hf_energy,hf_orbe,hf_orbs = scf(atoms,S,h,Ints,charge)
    print_orbe(hf_orbe,nclosed,nvirt)

    sigma = Sigma2(hf_orbe,hf_orbs,Ints,len(bfs),nclosed)
    
    for i in [4,5,6,7,8,9]:
        print "Correcting orbital %d, HF Eorb = %f" % (i+1,hf_orbe[i])
        del0,dele = sigma.eval(i)
        print "-> Eorb = %f %f" % (hf_orbe[i]+del0,hf_orbe[i]+dele)

    return
Beispiel #13
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)
Beispiel #14
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
Beispiel #15
0
def rhf(atoms,**opts):
    """\
    rhf(atoms,**opts) - Closed-shell HF driving routine
    
    atoms       A Molecule object containing the molecule

    Options:      Value   Description
    --------      -----   -----------
    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
    """
    ConvCriteria = opts.get('ConvCriteria',1e-10)
    MaxIter = opts.get('MaxIter',20)
    DoAveraging = opts.get('DoAveraging',False)
    ETemp = opts.get('ETemp',False)
    
    logger.info("RHF calculation on %s" % atoms.name)

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

    nclosed,nopen = atoms.get_closedopen()
    nocc = nclosed
    assert(nopen == 0), "SCF currently only works for closed-shell systems"
    
    logger.info("Nbf = %d" % len(bfs))
    logger.info("Nclosed = %d" % nclosed)

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

    nel = atoms.get_nel()

    orbs = opts.get('orbs',None)
    if orbs is None: orbe,orbs = geigh(h,S)

    enuke = atoms.get_enuke()
    eold = 0.

    
    if DoAveraging:
        logger.info("Using DIIS averaging")
        avg = DIIS(S)
    logging.debug("Optimization of HF orbitals")
    for i in xrange(MaxIter):
        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 = mkdens(orbs,0,nocc)
        G = get2JmK(Ints,D)
        F = h+G
        if DoAveraging: F = avg.getF(F,D)
        orbe,orbs = geigh(F,S)
        energy = get_energy(h,F,D,enuke)
        if ETemp:
            energy += entropy
        logging.debug("%d %f" % (i,energy))
        if abs(energy-eold) < ConvCriteria: break
        logger.info("Iteration: %d    Energy: %f    EnergyVar: %f"%(i,energy,abs(energy-eold)))
        eold = energy
    if i < MaxIter:
        logger.info("PyQuante converged in %d iterations" % i)
    else:
        logger.warning("PyQuante failed to converge after %d iterations"
                            % MaxIter)
    logger.info("Final HF energy for system %s is %f" % (atoms.name,energy))
    return energy,orbe,orbs
Beispiel #16
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)
Beispiel #17
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)
Beispiel #18
0
def rhf(atoms, **kwargs):
    """\
    rhf(atoms,**kwargs) - Closed-shell HF driving routine
    
    atoms       A Molecule object containing the molecule

    Options:      Value   Description
    --------      -----   -----------
    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
    """
    ConvCriteria = kwargs.get('ConvCriteria', settings.ConvergenceCriteria)
    MaxIter = kwargs.get('MaxIter', settings.MaxIter)
    DoAveraging = kwargs.get('DoAveraging', settings.Averaging)
    ETemp = kwargs.get('ETemp', settings.ElectronTemperature)

    logger.info("RHF calculation on %s" % atoms.name)

    bfs = getbasis(atoms, **kwargs)

    nclosed, nopen = atoms.get_closedopen()
    nocc = nclosed
    assert (nopen == 0), "SCF currently only works for closed-shell systems"

    logger.info("Nbf = %d" % len(bfs))
    logger.info("Nclosed = %d" % nclosed)

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

    orbs = kwargs.get('orbs')
    if orbs is None: orbe, orbs = geigh(h, S)

    enuke = atoms.get_enuke()
    eold = 0.

    if DoAveraging:
        logger.info("Using DIIS averaging")
        avg = DIIS(S)
    logging.debug("Optimization of HF orbitals")
    for i in xrange(MaxIter):
        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 = mkdens(orbs, 0, nocc)
        G = get2JmK(Ints, D)
        F = h + G
        if DoAveraging: F = avg.getF(F, D)
        orbe, orbs = geigh(F, S)
        energy = get_energy(h, F, D, enuke)
        if ETemp:
            energy += entropy
        logging.debug("%d %f" % (i, energy))
        if abs(energy - eold) < ConvCriteria: break
        logger.info("Iteration: %d    Energy: %f    EnergyVar: %f" %
                    (i, energy, abs(energy - eold)))
        eold = energy
    if i < MaxIter:
        logger.info("PyQuante converged in %d iterations" % i)
    else:
        logger.warning("PyQuante failed to converge after %d iterations" %
                       MaxIter)
    logger.info("Final HF energy for system %s is %f" % (atoms.name, energy))
    return energy, orbe, orbs
Beispiel #19
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)
Beispiel #20
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
Beispiel #21
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
Beispiel #22
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)
Beispiel #23
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
Beispiel #24
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)