def scfopen(atoms, F0, nalpha, nbeta, **opts): "SCF procedure for open-shell molecules" verbose = opts.get("verbose", False) D = get_guess_D(atoms) Da = 0.5 * D Db = 0.5 * D Eold = 0 for i in xrange(10): F1a = get_F1_open(atoms, Da, Db) F1b = get_F1_open(atoms, Db, Da) F2a = get_F2_open(atoms, Da, Db) F2b = get_F2_open(atoms, Db, Da) Fa = F0 + F1a + F2a Fb = F0 + F1b + F2b Eel = 0.5 * trace2(Da, F0 + Fa) + 0.5 * trace2(Db, F0 + Fb) if verbose: print i, Eel if abs(Eel - Eold) < 0.001: break Eold = Eel orbea, orbsa = eigh(Fa) orbeb, orbsb = eigh(Fb) Da = mkdens(orbsa, 0, nalpha) Db = mkdens(orbsb, 0, nbeta) return Eel
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
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
def scfclosed(atoms, F0, nclosed, **opts): "SCF procedure for closed-shell molecules" verbose = opts.get("verbose", False) do_avg = opts.get("avg", False) maxiter = opts.get("maxiter", 50) D = get_guess_D(atoms) Eold = 0 if do_avg: avg = SimpleAverager(do_avg) for i in xrange(maxiter): if do_avg: D = avg.getD(D) F1 = get_F1(atoms, D) F2 = get_F2(atoms, D) F = F0 + F1 + F2 Eel = 0.5 * trace2(D, F0 + F) if verbose: print i + 1, Eel, get_Hf(atoms, Eel) # if verbose: print i+1,Eel if abs(Eel - Eold) < 0.001: if verbose: print "Exiting because converged", i + 1, Eel, Eold break Eold = Eel orbe, orbs = eigh(F) D = 2 * mkdens(orbs, 0, nclosed) return Eel
def scfopen(atoms,F0,nalpha,nbeta,**kwargs): "SCF procedure for open-shell molecules" verbose = kwargs.get('verbose') D = get_guess_D(atoms) Da = 0.5*D Db = 0.5*D Eold = 0 for i in xrange(10): F1a = get_F1_open(atoms,Da,Db) F1b = get_F1_open(atoms,Db,Da) F2a = get_F2_open(atoms,Da,Db) F2b = get_F2_open(atoms,Db,Da) Fa = F0+F1a+F2a Fb = F0+F1b+F2b Eel = 0.5*trace2(Da,F0+Fa)+0.5*trace2(Db,F0+Fb) if verbose: print i,Eel if abs(Eel-Eold) < 0.001: break Eold = Eel orbea,orbsa = eigh(Fa) orbeb,orbsb = eigh(Fb) Da = mkdens(orbsa,0,nalpha) Db = mkdens(orbsb,0,nbeta) return Eel
def mkdens_occs(c,occs,**kwargs): "Density matrix from a set of occupations (e.g. from FD expression)." tol = kwargs.get('tol',settings.FDOccTolerance) verbose = kwargs.get('verbose') # Determine how many orbs have occupations greater than 0 norb = 0 for fi in occs: if fi < tol: break norb += 1 if verbose: print "mkdens_occs: %d occupied orbitals found" % norb # Determine how many doubly occupied orbitals we have nclosed = 0 for i in xrange(norb): if abs(1.-occs[i]) > tol: break nclosed += 1 if verbose: print "mkdens_occs: %d closed-shell orbitals found" % nclosed D = mkdens(c,0,nclosed) for i in xrange(nclosed,norb): D = D + occs[i]*matrixmultiply(c[:,i:i+1],transpose(c[:,i:i+1])) return D
def scfclosed(atoms,F0,nclosed,**kwargs): "SCF procedure for closed-shell molecules" verbose = kwargs.get('verbose') do_avg = kwargs.get('avg',settings.MINDOAveraging) maxiter = kwargs.get('maxiter',settings.MaxIter) D = get_guess_D(atoms) Eold = 0 if do_avg: avg = SimpleAverager(do_avg) for i in xrange(maxiter): if do_avg: D = avg.getD(D) F1 = get_F1(atoms,D) F2 = get_F2(atoms,D) F = F0+F1+F2 Eel = 0.5*trace2(D,F0+F) if verbose: print i+1,Eel,get_Hf(atoms,Eel) #if verbose: print i+1,Eel if abs(Eel-Eold) < 0.001: if verbose: print "Exiting because converged",i+1,Eel,Eold break Eold = Eel orbe,orbs = eigh(F) D = 2*mkdens(orbs,0,nclosed) return Eel
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',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] 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: 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
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
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)
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
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)
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', 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] 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: 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