def e2n(N, tmpdir='/tmp', hfx=1, Sg=1, Sv=1): """ E[2]*N linear transformation: [k,F] = [k(pq)E(Sv)(pq), F(rs)E(rs)] = k(pq)F(rs) (E(ps)d(rq) - E(rq)d(ps)) = k(pq)F(ps)E(ps) - k(pq)F(rp)E(rq) = [k,F](pq)E(pq) = kF <[q,kF]> = <[E_{pq}, kF(rs)E(rs)]> = kF(rs) <E(ps)d(rq) - E(rq)d(ps)> = kF(qs)D(ps) - kF(rp)D(rq) = [D, kF.T](pq) kD = <[k, E(pq)]> = <[k(rs) E(rs), E(pq)]> = k(rs) (E(rq)d(ps) - E(ps)d(rq)) = k(rp)D(rq) - k(qs)D(ps) = [k.T, D](p,q) Fk = F[kD] """ SIRIFC = os.path.join(tmpdir, 'SIRIFC') AOONEINT = os.path.join(tmpdir, 'AOONEINT') AOTWOINT = os.path.join(tmpdir, 'AOTWOINT') LUINDF = os.path.join(tmpdir, 'LUINDF') ifc = sirifc.sirifc(SIRIFC) cmo = get_cmo(AOONEINT, SIRIFC) h = one.read('ONEHAMIL', filename=AOONEINT).unblock().unpack() S = one.read('OVERLAP', filename=AOONEINT).unblock().unpack().view(util.full.matrix) da, db = get_densities(SIRIFC) kN = rspvec.tomat(N, ifc, tmpdir=tmpdir).view(util.full.matrix).T kn = (cmo*kN*cmo.T).view(util.full.matrix) dak = (kn.T*S*da - da*S*kn.T) dbk = (kn.T*S*db - db*S*kn.T)*Sv (fa, fb), = two.fockab((da, db), filename=AOTWOINT, hfx=hfx) fa += h; fb += h (fak, fbk), = two.fockab((dak, dbk), filename=AOTWOINT, hfx=hfx) kfa = (S*kn*fa - fa*kn*S) kfb = (S*kn*fb - fb*kn*S)*Sv fa = fak + kfa fb = fbk + kfb gao = S*(da*fa.T + Sg*db*fb.T) - (fa.T*da + Sg*fb.T*db)*S gm = cmo.T*gao*cmo # sign convention <[q,[k,F]]> = -E[2]*N gv = - rspvec.tovec(gm, ifc) return gv
def setup(self): suppdir = pathlib.Path(__file__).with_suffix('.d') self.aooneint = suppdir / "AOONEINT" self.aotwoint = suppdir / "AOTWOINT" self.h1 = one.read("ONEHAMIL", self.aooneint).unpack().unblock() self.S = one.read("OVERLAP", self.aooneint).unpack().unblock() self.EN = one.readhead(self.aooneint)["potnuc"] self.na = 5 self.nb = 4
def s2n(N, tmpdir='/tmp', Sg=1, Sv=1): """ S[2]*N linear transformation: <[q,k]> = <[E(Sg)_{ij}, k_{kl}, E(Sv)_{kl}]> = = k_{kl} [E_{il}d(kj) - E(kj)d(il)] = k(jl)E(SgSv)(il) - k(ki)E(SgSv)(kj) = D(SgSv)k.T(ij) - k.TD(SgSv)(ij) = [D(SgSv), k.T](ij) """ SIRIFC = os.path.join(tmpdir, 'SIRIFC') AOONEINT = os.path.join(tmpdir, 'AOONEINT') AOTWOINT = os.path.join(tmpdir, 'AOTWOINT') LUINDF = os.path.join(tmpdir, 'LUINDF') ifc = sirifc.sirifc(SIRIFC) cmo = ifc.cmo.unblock() S = one.read('OVERLAP', filename=AOONEINT).unblock().unpack() da, db = dens.Dab(SIRIFC) kN = rspvec.tomat(N, ifc, tmpdir=tmpdir).T kn = cmo*kN*cmo.T dak = (kn.T*S*da - da*S*kn.T) dbk = (kn.T*S*db - db*S*kn.T)*Sv gv = -rspvec.tovec(cmo.T*S*(dak+Sg*dbk)*S*cmo, ifc) return gv
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 load_overlap_matrix(AOONEINT_file, number_basis_functions): S_total = one.read(label="OVERLAP", filename=AOONEINT_file).unpack() S_calculation = {} S_reference = {} S_mixed = {} for i in range(len(number_basis_functions)): numb_bf = number_basis_functions[i] S_calculation[i + 1] = np.array(S_total[i])[:numb_bf, :numb_bf:] S_reference[i + 1] = np.array(S_total[i])[numb_bf:, numb_bf:] S_mixed[i + 1] = np.array(S_total[i])[:numb_bf, numb_bf:] return S_calculation, S_reference, S_mixed
def main(*args, **kwargs): labs = args tmpdir = kwargs.get("tmpdir", ".") ranks = kwargs.get('rank', (0, 0, 0)) pars = [ (-1)**r for r in ranks] ifc = sirifc.sirifc(os.path.join(tmpdir, "SIRIFC")) cmo = ifc.cmo.unblock() AOONEINT = os.path.join(tmpdir, "AOONEINT") AOPROPER = os.path.join(tmpdir, "AOPROPER") RSPVEC = os.path.join(tmpdir, "RSPVEC") vecs = rspvec.read(*labs, propfile=RSPVEC)[0] kappa = [rspvec.tomat(vec, ifc).T for vec in vecs] kappa[0] = kappa[0].T a, b, c = [cmo.T*x*cmo for x in prop.read(*labs, filename=AOPROPER)] NA = vecs[0] kA, kB, kC = kappa pA, pB, pC = [{ "lab":lab, "rank":rank, 'kappa':k} for lab, rank, k in zip(labs, ranks, kappa)] da, db = dens.Dab(ifc_=ifc) d = da + db S = one.read(label = "OVERLAP", filename = AOONEINT).unblock().unpack() D = cmo.T*S*d*S*cmo E3BC = E3(pB, pC, ifc, tmpdir=tmpdir) AE3BC = -NA&E3BC B2C = (-(kA^(kC^b))&D) C2B = (-(kA^(kB^c))&D) A2B = (.5*(kC^(kB^a))&D) A2C = (.5*(kB^(kC^a))&D) #print "E3BC",E3BC val = AE3BC print("E3 %14.8f %14.8f" % (AE3BC, val)) val += B2C print("B2C %14.8f %14.8f" % (B2C, val)) val += C2B print("C2B %14.8f %14.8f" % (C2B, val)) val += A2B print("A2B %14.8f %14.8f" % (A2B, val)) val += A2C print("A2C %14.8f %14.8f" % (A2C, val)) return val
def A2B(*args, **kwargs): pA, pB, ifc = args tmpdir = kwargs.get("tmpdir", ".") AOONEINT = os.path.join(tmpdir, "AOONEINT") S = one.read(label = "OVERLAP", filename = AOONEINT).unblock().unpack() cmo = ifc.cmo.unblock() mA = pA["matrix"] kB = cmo*pB["kappa"]*cmo.T BA = S*kB*mA - mA*kB*S da, db = dens.Dab(ifc_=ifc) G = cmo.T*(S*(da*BA.T + db*BA.T) - (BA.T*da + BA.T*db)*S)*cmo Gv = rspvec.tovec(G, ifc) return Gv
def test_overlap(self): Sref = [ [ 1.00000000, 0.24836239, 1.00000000, 0.00000000, 0.00000000, 1.00000000, 0.00005599, 0.05942391, 0.10228506, 1.00000000, 0.07053810, 0.49046481, 0.53543774, 0.23670394, 1.00000000, -0.11599611, -0.37963762, -0.27726502, -0.00000000, 0.00000000, 1.00000000, 0.05926125, 0.64602901, -0.48763174, 0.00548289, 0.09221295, -0.09620875, 2.23843306, ], [1.00000000, 0.31956952, 1.00000000], [ 1.00000000, 0.31956952, 1.00000000, 0.48763174, 0.04810438, 1.76156694 ], ] S = one.read("OVERLAP", self.aooneint) np.testing.assert_almost_equal(np.array(S.subblock[0]), Sref[0]) np.testing.assert_almost_equal(np.array(S.subblock[1]), Sref[1]) np.testing.assert_almost_equal(np.array(S.subblock[2]), Sref[2])
def B2C(*args, **kwargs): pB, pC, ifc = args tmpdir = kwargs.get("tmpdir", ".") AOONEINT = os.path.join(tmpdir, "AOONEINT") S = one.read(label = "OVERLAP", filename = AOONEINT).unblock().unpack() cmo = ifc.cmo.unblock() mB = pB["matrix"] mC = pC["matrix"] kB = cmo*pB["kappa"]*cmo.T kC = cmo*pC["kappa"]*cmo.T kBmC = S*kB*mC - mC*kB*S kCmB = S*kC*mB - mB*kC*S BC = kBmC + kCmB da, db = dens.Dab(ifc_=ifc) G = cmo.T*(S*(da*BC.T + db*BC.T) - (BC.T*da + BC.T*db)*S)*cmo Gv = rspvec.tovec(G, ifc) return Gv
def setUp(self): n, e = os.path.splitext(__file__) self.suppdir = n + ".d" self.A = "XDIPLEN" self.B = "YDIPLEN" self.C = "XDIPLEN" AOONEINT = os.path.join(self.suppdir, 'AOONEINT') S = one.read(label="OVERLAP", filename=AOONEINT).unblock().unpack() SIRIFC = os.path.join(self.suppdir, 'SIRIFC') self.ifc = sirifc.sirifc(SIRIFC) cmo = self.ifc.cmo.unblock() da, db = dens.Dab(ifc_=self.ifc) self.D = cmo.T * S * (da + db) * S * cmo RSPVEC = os.path.join(self.suppdir, 'RSPVEC') rspvecs = rspvec.read(self.A, self.B, self.C, propfile=RSPVEC) self.NA = rspvecs[(self.A, 0)] self.NB = rspvecs[(self.B, 0)] self.NC = rspvecs[(self.C, 0)] self.kA = rspvec.tomat(self.NA, self.ifc, tmpdir=self.suppdir) self.kB = rspvec.tomat(self.NB, self.ifc, tmpdir=self.suppdir).T self.kC = rspvec.tomat(self.NC, self.ifc, tmpdir=self.suppdir).T AOPROPER = os.path.join(self.suppdir, 'AOPROPER') #a, b, c = [cmo.T*x*cmo for x in prop.read(A, B, C, filename=AOPROPER, unpack=True)] global pmat pmat = prop.read(self.A, self.B, self.C, filename=AOPROPER, unpack=True) self.a, self.b, self.c = [cmo.T * x * cmo for x in pmat]
def a2bc(A, B, C): AOONEINT = os.path.join(tmp, "AOONEINT") AOPROPER = os.path.join(tmp, "AOPROPER") RSPVEC = os.path.join(tmp, "RSPVEC") SIRIFC = os.path.join(tmp, "SIRIFC") NB = rspvec.read(B, RSPVEC) NC = rspvec.read(C, RSPVEC) ifc = sirifc.sirifc(SIRIFC) cmo = ifc.cmo.unblock() dc,do = dens.ifc(ifc=ifc) d = dc+do a = cmo.T*prop.read(A, AOPROPER).unpack()*cmo kB = rspvec.tomat(NB, ifc, tmpdir = tmp).T kC = rspvec.tomat(NC, ifc, tmpdir = tmp).T S = one.read(label = "OVERLAP", filename = AOONEINT).unblock().unpack() D = cmo.T*S*d*S*cmo A2B = (.5*(kC^(kB^a))&D) A2C = (.5*(kB^(kC^a))&D) return A2B + A2C
def S(self): """ Get overlap, nuclear charges and coordinates from AOONEINT """ S = one.read("OVERLAP", self.aooneint) return S.unpack().unblock()
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) 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()
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
def test_overlap(self): Sref = [ 1.00000000, 0.24836239, 1.00000000, 0.00000000, 0.00000000, 1.00000000, 0.00000000, 0.00000000, 0.00000000, 1.00000000, 0.00000000, 0.00000000, 0.00000000, 0.00000000, 1.00000000, 0.00000126, 0.03708896, -0.00354693, 0.06228751, -0.00200579, 1.00000000, 0.03664911, 0.36526353, -0.02523128, 0.44308559, -0.01426833, 0.23670394, 1.00000000, 0.00349314, 0.01832934, 0.21019458, 0.02979663, -0.00095952, 0.00000000, 0.00000000, 1.00000000, -0.06134287, -0.32188081, 0.02979663, -0.31136609, 0.01685004, 0.00000000, 0.00000000, 0.00000000, 1.00000000, 0.00197538, 0.01036527, -0.00095952, 0.01685004, 0.21134872, 0.00000000, 0.00000000, 0.00000000, 0.00000000, 1.00000000, 0.06072046, 0.48453953, 0.40747211, -0.22071478, 0.01058662, 0.00476429, 0.07308063, 0.04174833, -0.06972286, 0.00257806, 1.00000000, 0.06021809, 0.48250496, -0.38496913, -0.25590672, 0.00467693, 0.00488694, 0.07467580, -0.03512957, -0.07505408, 0.00206544, 0.14255017, 1.00000000, ] S = one.read("OVERLAP", self.aooneint) np.testing.assert_almost_equal(np.array(S.subblock[0]), Sref)
def get_one_el_hamiltonian(self): """Get one-electron Hamiltonian""" return one.read("ONEHAMIL", os.path.join(self.get_workdir(), "AOONEINT")).unpack().unblock()
def get_overlap(self): return one.read("OVERLAP", os.path.join(self.get_workdir(), "AOONEINT")).unpack().unblock()
def S(self): """ Get overlap, nuclear charges and coordinates from AOONEINT """ S = one.read("OVERLAP", self.aooneint) return S.unpack().unblock()
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 E3(pB, pC, ifc, **kwargs): """ Emulate the so called E3 contribution to a quadratic response function <<A; B, C>> = NA E3 (NB NC + NC NB) + A2 (NB NC + NC NB) + NA (B2 NC + C2 NB) Emulation of current Dalton implementation in terms of high spin fock matrices Closed and open shell matrices Dc = inactive Do = -active Fc = Fa+Q Fo = ? CHECK Formulas 1/2*[qa, [kb, [kc, H]]] + P(b,c) [kc, H] = (p~q|rs)H(Sc, 0) + (pq|r~s) H(0, Sc) [kb, [kc, H]] = (p~~q|rs)H(SbSc, 0) + (p~q|r~s) H(Sb, Sc) + (p~q|r~s)H(Sc, Sb) + (pq|r~~s) H(0, SbSc) and for H(S1, S2) generates Fock from (D(S1) g D(S2) - Da g Da - Db g Db F(S1, S2) = E(S1) g D(S2) - D(S1) g E(S2) - Ea g Da - Da g Ea - Eb g Db - Db g Eb = Ea [ g D(S2) - D(S1) g - g Da - Da g ] + Eb [ S1 g D(S2) - D(S1) g S2 - g Db - Db g ] """ tmpdir = kwargs.get('tmpdir', '/tmp') AOONEINT = os.path.join(tmpdir, "AOONEINT") h = one.read(label='ONEHAMIL', filename=AOONEINT).unpack().unblock() S = one.read(label='OVERLAP', filename=AOONEINT).unblock().unpack() AOTWOINT = os.path.join(tmpdir, "AOTWOINT") kwargs['filename'] = AOTWOINT cmo = ifc.cmo.unblock() kB = cmo*pB["kappa"]*cmo.T kC = cmo*pC["kappa"]*cmo.T kB_ = kB*S _kB = S*kB kC_ = kC*S _kC = S*kC sB = pB.get("spin", 1) sC = pC.get("spin", 1) # # Fock matrices # da, db = dens.Dab(ifc_=ifc) (fa, fb), = two.fockab((da, db), **kwargs) fa += h fb += h Bfa, Bfb = [_kB*f - f*kB_ for f in (fa, sB*fb)] Cfa, Cfb = [_kC*f - f*kC_ for f in (fa, sC*fb)] BCfa, BCfb = [_kB*Cf - Cf*kB_ for Cf in (Cfa, sB*Cfb)] CBfa, CBfb = [_kC*Bf - Bf*kC_ for Bf in (Bfa, sC*Bfb)] daB, dbB = [_kB.T*d - d*kB_.T for d in (da, sB*db)] (faB, fbB), = two.fockab((daB, dbB), **kwargs) CfaB, CfbB = [_kC*fB - fB*kC_ for fB in (faB, sC*fbB)] daC, dbC = [_kC.T*d - d*kC_.T for d in (da, sC*db)] (faC, fbC), = two.fockab((daC, dbC), **kwargs) BfaC, BfbC = [_kB*fC - fC*kB_ for fC in (faC, sB*fbC)] daBC, dbBC = (_kB.T*dC - dC*kB_.T for dC in (daC, sB*dbC)) daCB, dbCB = (_kC.T*dB - dB*kC_.T for dB in (daB, sC*dbB)) daBC = 0.5*(daBC + daCB) dbBC = 0.5*(dbBC + dbCB) (faBC, fbBC), = two.fockab((daBC, dbBC), **kwargs) # # Add all focks # fa = faBC + BfaC + CfaB + .5*(BCfa + CBfa) fb = fbBC + BfbC + CfbB + .5*(BCfb + CBfb) G = cmo.T*(S*(da*fa.T + db*fb.T) - (fa.T*da + fb.T*db)*S)*cmo #G = cmo.T*(S*da*fa.T - fa.T*da *S)*cmo + \ # cmo.T*(S*db*fb.T - fb.T*db *S)*cmo Gv = rspvec.tovec(G, ifc) #print Gv return Gv
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)