def __iter__(self): """ Initial setup for SCF iterations """ self.na = (self.nel + 2 * self.ms) // 2 self.nb = (self.nel - 2 * self.ms) // 2 AOONEINT = os.path.join(self.tmpdir, 'AOONEINT') self.Z = one.readhead(AOONEINT)['potnuc'] self.h1 = one.read(label='ONEHAMIL', filename=AOONEINT).unpack().unblock() self.S = one.read(label='OVERLAP', filename=AOONEINT).unpack().unblock() if self.C is None: self.Ca = dens.cmo(self.h1, self.S) self.Cb = self.Ca self.C = (self.Ca, self.Cb) return self
def udiis( Ca, Cb, na, nb, iters=10, fock=jensen, hfx=1, threshold=1e-6, maxerr=2, unrest=False, wrkdir="/tmp", ): print(Ca, Cb) saveD = 1 saveC = 0 E = 0 aooneint = os.path.join(wrkdir, "AOONEINT") aotwoint = os.path.join(wrkdir, "AOTWOINT") potnuc = one.readhead(aooneint)["potnuc"] vecs = [] vecsa = [] vecsb = [] evecsa = [] evecsb = [] Eit = [] S = one.read("OVERLAP", aooneint).unpack().unblock() h = S.I @ one.read("ONEHAMIL", aooneint).unpack().unblock() Da = dens.C1D(Ca, na) @ S Db = dens.C1D(Cb, nb) @ S try: for i in range(iters): Da = dens.C1D(Ca, na) @ S Db = dens.C1D(Cb, nb) @ S print("D", (Da + Db) @ S.I) (Fa, Fb), = two.fockab((Da, Db), hfx=hfx, filename=aotwoint) Fa = h + S.I @ Fa Fb = h + S.I @ Fb E0 = E E = ((Da @ (h + Fa)) + (Db @ (h + Fb))).tr() / 2 + potnuc D = Da + Db print("hd", (h @ D).tr(), h & D, h & D.T) print("FD", Fa & Da) Eit.append(E) ga = Da @ Fa - Fa @ Da gb = Db @ Fb - Fb @ Db if unrest: g2 = -(ga @ ga + gb @ gb) else: g2 = -(ga + gb) @ (ga + gb) gn = math.sqrt(g2.tr()) print("%2d:E = %16.12f %16.5e %16.2e" % (i + 1, E, gn, E - E0)) if gn < threshold: raise Converged(gn) # if E > E0: # raise Exception("Energy increase") if unrest: Ca = dens.cmo(Fa) Cb = dens.cmo(Fb) # Ca = Ca*Ua # Cb = Cb*Ub else: Ca = dens.cmo(Feff(Da, Db, Fa, Fb), S) Cb = Ca[:, :] Da = dens.C1D(Ca, na) @ S Db = dens.C1D(Cb, nb) @ S if saveD: vecsa.append(Da) vecsb.append(Db) evecsa.append(ga @ Da - Da @ ga) evecsb.append(gb @ Db - Db @ gb) elif saveC: vecsa.append(Ca) vecsb.append(Cb) evecsa.append(ga) evecsb.append(gb) else: vecsa.append(Fa) vecsb.append(Fb) evecsa.append(ga) evecsb.append(gb) edim = min(len(evecsa), maxerr) eva = evecsa[-edim:] evb = evecsb[-edim:] fva = vecsa[-edim:] fvb = vecsb[-edim:] B = mkB3(eva, evb, unrest) rhs = full.matrix((edim + 1, 1)) rhs[-1, 0] = -1 c = rhs / B subvecsa = full.matrix(Fa.shape) subvecsb = full.matrix(Fb.shape) for j in range(edim): subvecsa += c[j, 0] * fva[j] subvecsb += c[j, 0] * fvb[j] if saveD: Da = subvecsa Db = subvecsb (Fa, Fb), = two.fockab((Da, Db), hfx=hfx, filename=aotwoint) Fa = h + S.I @ Fa Fb = h + S.I @ Fb vecsa[i] = Da vecsb[i] = Db elif saveC: Ca = subvecsa Cb = subvecsb Da = dens.C1D(Ca, na) @ S Db = dens.C1D(Cb, nb) @ S else: Fa = subvecsa Fb = subvecsb Da = dens.C1D(Ca, na) @ S Db = dens.C1D(Cb, nb) @ S except Converged: print("Converged after %d iterations\n" % (i + 1, )) except Increase: print("Ca Cb", Ca, Cb) print("Da Db", Da, Db) print("Na Nb", Da.tr(), Db.tr()) print("Fa Fb", Fa, Fb) print("E1", (h * (Da + Db)).tr()) print("E2", (Fa * Da + Fb * Db).tr() / 2 - (h * (Da + Db)).tr() / 2) print("E", E - potnuc)
def diis( C, nisht, nasht, iters=10, fock=jensen, hfx=1, threshold=1e-6, maxerr=2, wrkdir="/tmp", ): C1 = C E = 0 aooneint = pathlib.Path(wrkdir) / "AOONEINT" aotwoint = pathlib.Path(wrkdir) / "AOTWOINT" potnuc = one.readhead(aooneint)["potnuc"] vecs = [] evecs = [] h = one.read("ONEHAMIL", aooneint).unpack().unblock() S = one.read("OVERLAP", aooneint).unpack().unblock() try: for i in range(iters): Di, Da = dens.C2D(C, nisht, nasht) D = Di + Da Fc = h + two.fock(D, filename=aotwoint, hfx=hfx) Fo = two.fock(Da, hfc=0, filename=aotwoint) + Fc F = fock(S, Di, Da, Fc, Fo, C, h) E0 = E E = ((h + Fc) & D) / 2 + ((Fo - Fc) & Da) / 2 + potnuc g = grad(S, C1, Di, Da, Fc, Fo) # gao = gradao(S, C, Di, Da, Fc, Fo) gn = gradvec(S, C, Di, Da, Fc, Fo, nisht, nasht).norm2() gn /= math.sqrt(2) print("%2d:E = %16.12f %16.5e %16.2e" % (i + 1, E, gn, E - E0)) if gn < threshold: raise Converged(gn) vecs.append(F) evecs.append(g) edim = min(len(evecs), maxerr) ev = evecs[-edim:] fv = vecs[-edim:] B = mkB(ev) rhs = full.matrix((edim + 1, 1)) rhs[-1, 0] = 1 c = rhs / B subevecs = full.matrix(g.shape) subvecs = full.matrix(F.shape) for i in range(edim): subevecs += c[i, 0] * ev[i] subvecs += c[i, 0] * fv[i] update = -subevecs upd = update.lower() upd.anti = 0 update = upd.unpack() F = subvecs # +update C = dens.cmo(F, S) except Converged: print("-Converged-") except Stop: print("-STOP-")
def uroothan(Ca, Cb, na, nb, hfx=1, iters=10, threshold=1e-6, unrest=False, wrkdir="/tmp"): """ Open-shell Roothan iterations, restricted or unrestricted """ if unrest: print("Unrestricted HF Na=%d Nb=%d\n" % (na, nb)) else: print("Restricted RHF Na=%d Nb=%d\n" % (na, nb)) E0 = 0.0 aooneint = os.path.join(wrkdir, "AOONEINT") aotwoint = os.path.join(wrkdir, "AOTWOINT") h = one.read("ONEHAMIL", aooneint).unpack().unblock() S = one.read("OVERLAP", aooneint).unpack().unblock() potnuc = one.readhead(aooneint)["potnuc"] print(potnuc) iterinf = [] try: for i in range(iters): Da = dens.C1D(Ca, na) Db = dens.C1D(Cb, nb) (Fa, Fb), = fockab((Da, Db), hfx=hfx, filename=aotwoint) Fa += h Fb += h E = 0.5 * ((Da & (h + Fa)) + (Db & (h + Fb))) + potnuc ga = S @ Da @ Fa - Fa @ Da @ S gb = S @ Db @ Fb - Fb @ Db @ S g = ga + gb if unrest: g2 = -(ga @ ga + gb @ gb) else: g2 = (ga + gb) @ (S.I @ (ga + gb) @ S.I).T gn = sqrt(g2.tr()) gn = sqrt(2 * (ga + gb) & (S.I @ (ga + gb) @ S.I)) iterinf.append((E, gn)) print("%2d:E=%16.10f %16.5e %16.2e" % (i + 1, E, gn, E - E0)) if gn < threshold: raise Converged(gn) if unrest: Ca = dens.cmo(Fa, S) Cb = dens.cmo(Fb, S) else: D = Da + Db Ds = Da - Db Fs = Fa - Fb ID = S.I - D F0 = (Fa + Fb) / 2 V = sum(S @ P @ (g - F0) @ Q @ S for P, Q in combinations((Db, Da - Db, S.I - Da), 2)) V += V.T V = jensen(S, 2 * Db, Da - Db, F0, Fa) # F = ((Fa + Fb) + Ds @ Fs @ ID + ID @ Fs @ Ds) / 2 F = F0 + V F = S @ Feff(Da @ S, Db @ S, S.I @ Fa, S.I @ Fb) Ca = dens.cmo(F, S) Cb = Ca except Converged: print("-Converged-") if unrest: return (Ca, Cb) else: return Ca
print("Na Nb", Da.tr(), Db.tr()) print("Fa Fb", Fa, Fb) print("E1", (h * (Da + Db)).tr()) print("E2", (Fa * Da + Fb * Db).tr() / 2 - (h * (Da + Db)).tr() / 2) print("E", E - potnuc) if __name__ == "__main__": if 1: wrkdir = "tests/test_heh.d" aooneint = os.path.join(wrkdir, "AOONEINT") aotwoint = os.path.join(wrkdir, "AOTWOINT") potnuc = one.readhead(aooneint)["potnuc"] h = one.read("ONEHAMIL", aooneint).unpack().unblock() S = one.read("OVERLAP", aooneint).unpack().unblock() Ca = dens.cmo(h, S) Cb = Ca kwargs = dict(wrkdir=wrkdir, iters=20, threshold=1e-5) uroothan(Ca, Cb, 2, 1, unrest=False, **kwargs) diis(Ca, 2, 1, **kwargs) #udiis(Ca, Cb, 1, 1, **kwargs) if 0: wrkdir = "tests/test_h2.d" aooneint = os.path.join(wrkdir, "AOONEINT") aotwoint = os.path.join(wrkdir, "AOTWOINT") potnuc = one.readhead(aooneint)["potnuc"] h = one.read("ONEHAMIL", aooneint).unpack().unblock() S = one.read("OVERLAP", aooneint).unpack().unblock() Ca = dens.cmo(h, S)
def _update_mo(self): F = self.Feff() Ca = dens.cmo(F, self.S) Cb = Ca self.C = Ca, Cb
def update_mo(self): F = self.Fopt() Ca = dens.cmo(F, self.S) Cb = Ca self.C = Ca, Cb
def update_mo(self): Ca = dens.cmo(self.h1 + self.Fa, self.S)[:, :self.na] Cb = dens.cmo(self.h1 + self.Fb, self.S)[:, :self.nb] self.C = Ca, Cb
def test_h1diag_initial_mo(self): cmo = dens.cmo(self.h1, self.S) cmo = self.cmo() npt.assert_allclose(cmo, ref.C1)
def cmo(self): return dens.cmo(self.h1, self.S)