Beispiel #1
0
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
Beispiel #2
0
    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
Beispiel #3
0
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
Beispiel #4
0
    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
Beispiel #5
0
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
Beispiel #6
0
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
Beispiel #7
0
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
Beispiel #8
0
    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])
Beispiel #9
0
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
Beispiel #10
0
    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]
Beispiel #11
0
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
Beispiel #12
0
 def S(self):
     """
     Get overlap, nuclear charges and coordinates from AOONEINT
     """
     S = one.read("OVERLAP", self.aooneint)
     return  S.unpack().unblock()
Beispiel #13
0
        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()
Beispiel #14
0
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
Beispiel #15
0
    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)
Beispiel #16
0
 def get_one_el_hamiltonian(self):
     """Get one-electron Hamiltonian"""
     return one.read("ONEHAMIL",
                     os.path.join(self.get_workdir(),
                                  "AOONEINT")).unpack().unblock()
Beispiel #17
0
 def get_overlap(self):
     return one.read("OVERLAP",
                     os.path.join(self.get_workdir(),
                                  "AOONEINT")).unpack().unblock()
Beispiel #18
0
 def S(self):
     """
     Get overlap, nuclear charges and coordinates from AOONEINT
     """
     S = one.read("OVERLAP", self.aooneint)
     return S.unpack().unblock()
Beispiel #19
0
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-")
Beispiel #20
0
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
Beispiel #21
0
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)