def orthog(q, qs, **kwargs): "Orthonormalize vector q to set of vectors qs" nbasis, nvec = qs.shape north = kwargs.get('north', nvec) #if north==-1: north = nvec #north = min(north,nvec) for i in xrange(north): olap = dot(q, qs[:, i]) q -= olap * qs[:, i] norm = sqrt(dot(q, q)) return norm
def orthog(q,qs,**kwargs): "Orthonormalize vector q to set of vectors qs" nbasis,nvec = qs.shape north = kwargs.get('north',nvec) #if north==-1: north = nvec #north = min(north,nvec) for i in xrange(north): olap = dot(q,qs[:,i]) q -= olap*qs[:,i] norm = sqrt(dot(q,q)) return norm
def orthogonalize(orbs,S): nbf,norb = orbs.shape Smax = 0 for i in xrange(norb): for j in xrange(i): Sij = dot(orbs[:,j],dot(S,orbs[:,i])) Smax = max(Smax,abs(Sij)) orbs[:,i] -= Sij*orbs[:,j] Sii = dot(orbs[:,i],dot(S,orbs[:,i])) orbs[:,i] /= sqrt(Sii) print "Max orthogonalized element = ",Smax return
def get_energy(self,b): self.iter += 1 ba = b[:self.nbf] bb = b[self.nbf:] self.Hoepa = get_Hoep(ba,self.H0,self.Gij) self.Hoepb = get_Hoep(bb,self.H0,self.Gij) self.orbea,self.orbsa = geigh(self.Hoepa,self.S) self.orbeb,self.orbsb = geigh(self.Hoepb,self.S) if self.etemp: self.Da,entropya = mkdens_fermi(2*self.nalpha,self.orbea,self.orbsa, self.etemp) self.Db,entropyb = mkdens_fermi(2*self.nbeta,self.orbeb,self.orbsb, self.etemp) self.entropy = 0.5*(entropya+entropyb) else: self.Da = mkdens(self.orbsa,0,self.nalpha) self.Db = mkdens(self.orbsb,0,self.nbeta) self.entropy=0 J = getJ(self.Ints,self.Da+self.Db) Ka = getK(self.Ints,self.Da) Kb = getK(self.Ints,self.Db) self.Fa = self.h + J - Ka self.Fb = self.h + J - Kb self.energy = 0.5*(trace2(self.h+self.Fa,self.Da) + trace2(self.h+self.Fb,self.Db))\ + self.Enuke + self.entropy if self.iter == 1 or self.iter % 10 == 0: logging.debug("%4d %10.5f %10.5f" % (self.iter,self.energy,dot(b,b))) return self.energy
def get_exx_energy(b,nbf,nel,nocc,ETemp,Enuke,S,h,Ints,H0,Gij,**opts): """Computes the energy for the OEP/HF functional Options: return_flag 0 Just return the energy 1 Return energy, orbe, orbs 2 Return energy, orbe, orbs, F """ return_flag = opts.get('return_flag',0) Hoep = get_Hoep(b,H0,Gij) orbe,orbs = geigh(Hoep,S) 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) F = get_fock(D,Ints,h) energy = trace2(h+F,D)+Enuke if ETemp: energy += entropy iref = nel/2 gap = 627.51*(orbe[iref]-orbe[iref-1]) logging.debug("EXX Energy, B, Gap: %10.5f %10.5f %10.5f" % (energy,sqrt(dot(b,b)),gap)) #logging.debug("%s" % orbe) if return_flag == 1: return energy,orbe,orbs elif return_flag == 2: return energy,orbe,orbs,F return energy
def get_exx_energy(b, nbf, nel, nocc, ETemp, Enuke, S, h, Ints, H0, Gij, **opts): """Computes the energy for the OEP/HF functional Options: return_flag 0 Just return the energy 1 Return energy, orbe, orbs 2 Return energy, orbe, orbs, F """ return_flag = opts.get('return_flag', 0) Hoep = get_Hoep(b, H0, Gij) orbe, orbs = geigh(Hoep, S) 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) F = get_fock(D, Ints, h) energy = trace2(h + F, D) + Enuke if ETemp: energy += entropy iref = nel / 2 gap = 627.51 * (orbe[iref] - orbe[iref - 1]) logging.debug("EXX Energy, B, Gap: %10.5f %10.5f %10.5f" % (energy, sqrt(dot(b, b)), gap)) #logging.debug("%s" % orbe) if return_flag == 1: return energy, orbe, orbs elif return_flag == 2: return energy, orbe, orbs, F return energy
def get_energy(self, b): self.iter += 1 ba = b[:self.nbf] bb = b[self.nbf:] self.Hoepa = get_Hoep(ba, self.H0, self.Gij) self.Hoepb = get_Hoep(bb, self.H0, self.Gij) self.orbea, self.orbsa = geigh(self.Hoepa, self.S) self.orbeb, self.orbsb = geigh(self.Hoepb, self.S) if self.etemp: self.Da, entropya = mkdens_fermi(2 * self.nalpha, self.orbea, self.orbsa, self.etemp) self.Db, entropyb = mkdens_fermi(2 * self.nbeta, self.orbeb, self.orbsb, self.etemp) self.entropy = 0.5 * (entropya + entropyb) else: self.Da = mkdens(self.orbsa, 0, self.nalpha) self.Db = mkdens(self.orbsb, 0, self.nbeta) self.entropy = 0 J = getJ(self.Ints, self.Da + self.Db) Ka = getK(self.Ints, self.Da) Kb = getK(self.Ints, self.Db) self.Fa = self.h + J - Ka self.Fb = self.h + J - Kb self.energy = 0.5*(trace2(self.h+self.Fa,self.Da) + trace2(self.h+self.Fb,self.Db))\ + self.Enuke + self.entropy if self.iter == 1 or self.iter % 10 == 0: logging.debug("%4d %10.5f %10.5f" % (self.iter, self.energy, dot(b, b))) return self.energy
def getF(self, F, D): n, m = F.shape err = matrixmultiply(F,matrixmultiply(D,self.S)) -\ matrixmultiply(self.S,matrixmultiply(D,F)) err = ravel(err) maxerr = max(abs(err)) if maxerr < self.errcutoff and not self.started: if VERBOSE: print "Starting DIIS: Max Err = ", maxerr self.started = 1 if not self.started: # Do simple averaging until DIIS starts if self.Fold: Freturn = 0.5 * F + 0.5 * self.Fold else: Freturn = F self.Fold = F return Freturn elif not self.errold: Freturn = 0.5 * F + 0.5 * self.Fold self.errold = err return Freturn a = zeros((3, 3), 'd') b = zeros(3, 'd') a[0, 0] = dot(self.errold, self.errold) a[1, 0] = dot(self.errold, err) a[0, 1] = a[1, 0] a[1, 1] = dot(err, err) a[:, 2] = -1 a[2, :] = -1 a[2, 2] = 0 b[2] = -1 c = solve(a, b) # Handle a few special cases: alpha = c[1] print alpha, c #if alpha < 0: alpha = 0 #if alpha > 1: alpha = 1 F = (1 - alpha) * self.Fold + alpha * F self.errold = err self.Fold = F return F
def getF(self, F, D): n, m = F.shape err = matrixmultiply(F, matrixmultiply(D, self.S)) - matrixmultiply(self.S, matrixmultiply(D, F)) err = ravel(err) maxerr = max(abs(err)) if maxerr < self.errcutoff and not self.started: if VERBOSE: print "Starting DIIS: Max Err = ", maxerr self.started = 1 if not self.started: # Do simple averaging until DIIS starts if self.Fold: Freturn = 0.5 * F + 0.5 * self.Fold else: Freturn = F self.Fold = F return Freturn elif not self.errold: Freturn = 0.5 * F + 0.5 * self.Fold self.errold = err return Freturn a = zeros((3, 3), "d") b = zeros(3, "d") a[0, 0] = dot(self.errold, self.errold) a[1, 0] = dot(self.errold, err) a[0, 1] = a[1, 0] a[1, 1] = dot(err, err) a[:, 2] = -1 a[2, :] = -1 a[2, 2] = 0 b[2] = -1 c = solve(a, b) # Handle a few special cases: alpha = c[1] print alpha, c # if alpha < 0: alpha = 0 # if alpha > 1: alpha = 1 F = (1 - alpha) * self.Fold + alpha * F self.errold = err self.Fold = F return F
def getK(Ints,D): "Form the exchange operator corresponding to a density matrix D" nbf = D.shape[0] D1d = reshape(D,(nbf*nbf,)) #1D version of Dens K = zeros((nbf,nbf),'d') for i in xrange(nbf): for j in xrange(i+1): if sorted: temp = kints[i,j] else: temp = fetch_kints(Ints,i,j,nbf) K[i,j] = dot(temp,D1d) K[j,i] = K[i,j] return K
def get2JmK(Ints,D): "Form the 2J-K integrals corresponding to a density matrix D" nbf = D.shape[0] D1d = reshape(D,(nbf*nbf,)) #1D version of Dens G = zeros((nbf,nbf),'d') for i in xrange(nbf): for j in xrange(i+1): if sorted: temp = 2*jints[i,j]-kints[i,j] else: temp = 2*fetch_jints(Ints,i,j,nbf)-fetch_kints(Ints,i,j,nbf) G[i,j] = dot(temp,D1d) G[j,i] = G[i,j] return G
def getJ(Ints,D): "Form the Coulomb operator corresponding to a density matrix D" nbf = D.shape[0] D1d = reshape(D,(nbf*nbf,)) #1D version of Dens J = zeros((nbf,nbf),'d') for i in xrange(nbf): for j in xrange(i+1): if sorted: temp = jints[i,j] else: temp = fetch_jints(Ints,i,j,nbf) J[i,j] = dot(temp,D1d) J[j,i] = J[i,j] return J
def getF(self, F, D): n, m = F.shape err = matrixmultiply(F,matrixmultiply(D,self.S)) -\ matrixmultiply(self.S,matrixmultiply(D,F)) err = ravel(err) maxerr = max(abs(err)) self.maxerr = maxerr if maxerr < self.errcutoff and not self.started: if VERBOSE: print "Starting DIIS: Max Err = ", maxerr self.started = 1 if not self.started: # Do simple averaging until DIIS starts if self.Fold != None: Freturn = 0.5 * F + 0.5 * self.Fold self.Fold = F else: self.Fold = F Freturn = F return Freturn self.Fs.append(F) self.Errs.append(err) nit = len(self.Errs) a = zeros((nit + 1, nit + 1), 'd') b = zeros(nit + 1, 'd') for i in xrange(nit): for j in xrange(nit): a[i, j] = dot(self.Errs[i], self.Errs[j]) for i in xrange(nit): a[nit, i] = a[i, nit] = -1.0 b[i] = 0 #mtx2file(a,'A%d.dat' % nit) a[nit, nit] = 0 b[nit] = -1.0 # The try loop makes this a bit more stable. # Thanks to John Kendrick! try: c = solve(a, b) except: self.Fold = F return F F = zeros((n, m), 'd') for i in xrange(nit): F += c[i] * self.Fs[i] return F
def getF(self, F, D): n, m = F.shape err = matrixmultiply(F, matrixmultiply(D, self.S)) - matrixmultiply(self.S, matrixmultiply(D, F)) err = ravel(err) maxerr = max(abs(err)) self.maxerr = maxerr if maxerr < self.errcutoff and not self.started: if VERBOSE: print "Starting DIIS: Max Err = ", maxerr self.started = 1 if not self.started: # Do simple averaging until DIIS starts if self.Fold != None: Freturn = 0.5 * F + 0.5 * self.Fold self.Fold = F else: self.Fold = F Freturn = F return Freturn self.Fs.append(F) self.Errs.append(err) nit = len(self.Errs) a = zeros((nit + 1, nit + 1), "d") b = zeros(nit + 1, "d") for i in range(nit): for j in range(nit): a[i, j] = dot(self.Errs[i], self.Errs[j]) for i in range(nit): a[nit, i] = a[i, nit] = -1.0 b[i] = 0 # mtx2file(a,'A%d.dat' % nit) a[nit, nit] = 0 b[nit] = -1.0 # The try loop makes this a bit more stable. # Thanks to John Kendrick! try: c = solve(a, b) except: self.Fold = F return F F = zeros((n, m), "d") for i in range(nit): F += c[i] * self.Fs[i] return F
def get_energy(self,b): self.iter += 1 self.Hoep = get_Hoep(b,self.H0,self.Gij) self.orbe,self.orbs = geigh(self.Hoep,self.S) if self.etemp: self.D,self.entropy = mkdens_fermi(self.nel,self.orbe,self.orbs, self.etemp) else: self.D = mkdens(self.orbs,0,self.nclosed) self.entropy=0 self.F = get_fock(self.D,self.Ints,self.h) self.energy = trace2(self.h+self.F,self.D)+self.Enuke + self.entropy if self.iter == 1 or self.iter % 10 == 0: logging.debug("%4d %10.5f %10.5f" % (self.iter,self.energy,dot(b,b))) return self.energy
def get_energy(self, b): self.iter += 1 self.Hoep = get_Hoep(b, self.H0, self.Gij) self.orbe, self.orbs = geigh(self.Hoep, self.S) if self.etemp: self.D, self.entropy = mkdens_fermi(self.nel, self.orbe, self.orbs, self.etemp) else: self.D = mkdens(self.orbs, 0, self.nclosed) self.entropy = 0 self.F = get_fock(self.D, self.Ints, self.h) self.energy = trace2(self.h + self.F, self.D) + self.Enuke + self.entropy if self.iter == 1 or self.iter % 10 == 0: logging.debug("%4d %10.5f %10.5f" % (self.iter, self.energy, dot(b, b))) return self.energy
def dot1d(a, b): return dot(ravel(a), ravel(b))