Example #1
0
def ftsolver(h1e,g2e,norb,nelec,T,mu=0,symm='UHF', Tmin=1.e-3,\
                dcompl=False,**kwargs):

    if symm is 'RHF':
        from pyscf.fci import direct_spin1 as fcisolver
        h1e = h1e[0]
        g2e = g2e[1]
    elif symm is 'SOC':
        from pyscf.fci import fci_slow_spinless as fcisolver
        dcompl = True
    elif symm is 'UHF':
        from pyscf.fci import direct_uhf as fcisolver
    else:
        from pyscf.fci import direct_spin1 as fcisolver

    if isinstance(nelec, (int, np.integer)):
        nelecb = nelec // 2
        neleca = nelec - nelecb
    else:
        neleca, nelecb = nelec

    na = cistring.num_strings(norb, neleca)
    nb = cistring.num_strings(norb, nelecb)
    nelec = (neleca, nelecb)
    ne = neleca + nelecb
    ndim = na * nb

    if T < Tmin:
        e, v = fcisolver.kernel(h1e, g2e, norb, nelec)
        RDM1, RDM2 = fcisolver.make_rdm12s(v, norb, nelec)
        z = np.exp(-(e - mu * ne) / T)
        return np.asarray(RDM1) * ndim, np.asarray(RDM2) * ndim, e * ndim

    ew, ev = diagH(h1e, g2e, norb, nelec, fcisolver)
    rdm1, rdm2 = [], []
    RDM1 = np.zeros((2, norb, norb))
    RDM2 = np.zeros((3, norb, norb, norb, norb))

    Z = np.sum(np.exp(-(ew - mu * ne) / T))
    E = np.sum(np.exp(-(ew - mu * ne) / T) * ew)  # not normalized
    #print Z, E

    for i in range(ndim):
        dm1, dm2 = fcisolver.make_rdm12s(ev[:, i].copy(), norb, nelec)
        RDM1 += np.asarray(dm1) * np.exp(-(ew[i] - mu * ne) / T)
        RDM2 += np.asarray(dm2) * np.exp(-(ew[i] - mu * ne) / T)

    if symm is not 'UHF' and len(RDM1.shape) == 3:
        RDM1 = np.sum(RDM1, axis=0)
        RDM2 = np.sum(RDM2, axis=0)

    RDM1 /= Z
    RDM2 /= Z
    E /= Z

    return RDM1, RDM2, E
Example #2
0
def spin_square(fcivec, norb, nelec, mo_coeff=None, ovlp=1):
    r'''General spin square operator.

    ... math::

        <CI|S_+*S_-|CI> &= n_\alpha + \delta_{ik}\delta_{jl}Gamma_{i\alpha k\beta ,j\beta l\alpha } \\
        <CI|S_-*S_+|CI> &= n_\beta + \delta_{ik}\delta_{jl}Gamma_{i\beta k\alpha ,j\alpha l\beta } \\
        <CI|S_z*S_z|CI> &= \delta_{ik}\delta_{jl}(Gamma_{i\alpha k\alpha ,j\alpha l\alpha }
                         - Gamma_{i\alpha k\alpha ,j\beta l\beta }
                         - Gamma_{i\beta k\beta ,j\alpha l\alpha}
                         + Gamma_{i\beta k\beta ,j\beta l\beta})
                         + (n_\alpha+n_\beta)/4

    Given the overlap betwen non-degenerate alpha and beta orbitals, this
    function can compute the expectation value spin square operator for
    UHF-FCI wavefunction
    '''
    from pyscf.fci import direct_spin1

    if isinstance(mo_coeff, numpy.ndarray) and mo_coeff.ndim == 2:
        mo_coeff = (mo_coeff, mo_coeff)
    elif mo_coeff is None:
        mo_coeff = (numpy.eye(norb), ) * 2


# projected overlap matrix elements for partial trace
    if isinstance(ovlp, numpy.ndarray):
        ovlpaa = reduce(numpy.dot, (mo_coeff[0].T, ovlp, mo_coeff[0]))
        ovlpbb = reduce(numpy.dot, (mo_coeff[1].T, ovlp, mo_coeff[1]))
        ovlpab = reduce(numpy.dot, (mo_coeff[0].T, ovlp, mo_coeff[1]))
        ovlpba = reduce(numpy.dot, (mo_coeff[1].T, ovlp, mo_coeff[0]))
    else:
        ovlpaa = numpy.dot(mo_coeff[0].T, mo_coeff[0])
        ovlpbb = numpy.dot(mo_coeff[1].T, mo_coeff[1])
        ovlpab = numpy.dot(mo_coeff[0].T, mo_coeff[1])
        ovlpba = numpy.dot(mo_coeff[1].T, mo_coeff[0])

    # if ovlp=1, ssz = (neleca-nelecb)**2 * .25
    (dm1a, dm1b), (dm2aa, dm2ab, dm2bb) = \
            direct_spin1.make_rdm12s(fcivec, norb, nelec)
    ssz =(_bi_trace(dm2aa, ovlpaa, ovlpaa)
        - _bi_trace(dm2ab, ovlpaa, ovlpbb)
        + _bi_trace(dm2bb, ovlpbb, ovlpbb)
        - _bi_trace(dm2ab, ovlpaa, ovlpbb)) * .25 \
        +(_trace(dm1a, ovlpaa)
        + _trace(dm1b, ovlpbb)) *.25

    dm2baab = _make_rdm2_baab(fcivec, norb, nelec)
    dm2abba = _make_rdm2_abba(fcivec, norb, nelec)
    dm2baab = rdm.reorder_rdm(dm1b, dm2baab, inplace=True)[1]
    dm2abba = rdm.reorder_rdm(dm1a, dm2abba, inplace=True)[1]
    ssxy =(_bi_trace(dm2abba, ovlpab, ovlpba)
         + _bi_trace(dm2baab, ovlpba, ovlpab) \
         + _trace(dm1a, ovlpaa)
         + _trace(dm1b, ovlpbb)) * .5
    ss = ssxy + ssz

    s = numpy.sqrt(ss + .25) - .5
    multip = s * 2 + 1
    return ss, multip
Example #3
0
    def test_rdm(self):
        norb, nelec = 10, 4
        strs = cistring.gen_strings4orblist(range(norb), nelec)
        numpy.random.seed(11)
        mask = numpy.random.random(len(strs)) > .6
        strsa = strs[mask]
        mask = numpy.random.random(len(strs)) > .7
        strsb = strs[mask]
        ci_strs = (strsa, strsb)
        ci_coeff = select_ci._as_SCIvector(
            numpy.random.random((len(strsa), len(strsb))), ci_strs)
        ci0 = select_ci.to_fci(ci_coeff, norb, (nelec, nelec))
        dm1ref, dm2ref = direct_spin1.make_rdm12s(ci0, norb, (nelec, nelec))
        dm1 = select_ci.make_rdm1s(ci_coeff, norb, (nelec, nelec))
        self.assertAlmostEqual(abs(dm1[0] - dm1ref[0]).sum(), 0, 9)
        self.assertAlmostEqual(abs(dm1[1] - dm1ref[1]).sum(), 0, 9)
        dm2 = select_ci.make_rdm2s(ci_coeff, norb, (nelec, nelec))
        self.assertAlmostEqual(abs(dm2[0] - dm2ref[0]).sum(), 0, 9)
        self.assertAlmostEqual(abs(dm2[1] - dm2ref[1]).sum(), 0, 9)
        self.assertAlmostEqual(abs(dm2[2] - dm2ref[2]).sum(), 0, 9)

        ci1_coeff = select_ci._as_SCIvector(
            numpy.random.random((len(strsa), len(strsb))), ci_strs)
        ci1 = select_ci.to_fci(ci1_coeff, norb, (nelec, nelec))
        dm1ref, dm2ref = direct_spin1.trans_rdm12s(ci1, ci0, norb,
                                                   (nelec, nelec))
        dm1 = select_ci.trans_rdm1s(ci1_coeff, ci_coeff, norb, (nelec, nelec))
        self.assertAlmostEqual(abs(dm1[0] - dm1ref[0]).sum(), 0, 9)
        self.assertAlmostEqual(abs(dm1[1] - dm1ref[1]).sum(), 0, 9)
Example #4
0
def spin_square(fcivec, norb, nelec, mo_coeff=None, ovlp=1):
    from pyscf.fci import direct_spin1
    if mo_coeff is None:
        mo_coeff = (numpy.eye(norb), ) * 2

    (dm1a, dm1b), (dm2aa, dm2ab, dm2bb) = \
            direct_spin1.make_rdm12s(fcivec, norb, nelec)

    return spin_square_general(dm1a, dm1b, dm2aa, dm2ab, dm2bb, mo_coeff, ovlp)
Example #5
0
def rdm12s_ft_smpl(h1e, g2e, norb, nelec, T, \
        m=50, nsmpl=20000, Tmin=1e-3, symm='RHF', **kwargs):

    if symm is 'RHF':
        from pyscf.fci import direct_spin1 as fcisolver
    elif symm is 'SOC':
        from pyscf.fci import fci_slow_spinless as fcisolver
    elif symm is 'UHF':
        from pyscf.fci import direct_uhf as fcisolver
    else:
        from pyscf.fci import direct_spin1 as fcisolver

    if T < Tmin:
        e, c = fcisolver.kernel(h1e, g2e, norb, nelec)
        dm1, dm2 = fcisolver.make_rdm12s(c, norb, nelec)
        dm1 = numpy.asarray(dm1)
        dm2 = numpy.asarray(dm2)
    else:
        h2e = fcisolver.absorb_h1e(h1e, g2e, norb, nelec, .5)
        if symm is 'SOC':
            na = cistring.num_strings(norb, nelec)
            ci0 = numpy.random.randn(na)
        else:
            na = cistring.num_strings(norb, nelec // 2)
            ci0 = numpy.random.randn(na * na)

        hdiag = fcisolver.make_hdiag(h1e, g2e, norb, nelec)

        hdiag = hdiag - hdiag[0]
        disp = numpy.exp(T) * 0.5
        ci0 = ci0 / numpy.linalg.norm(ci0)

        def hop(c):
            hc = fcisolver.contract_2e(h2e, c, norb, nelec)
            return hc.reshape(-1)

        def qud(v1):
            dm1, dm2 = fcisolver.make_rdm12s(v1, norb, nelec)
            return dm1, dm2

        dm1, dm2, e = ftsmpl.ft_smpl_rdm12s(qud,
                                            hop,
                                            ci0,
                                            T,
                                            norb,
                                            nsamp=nsmpl,
                                            M=m)

    if symm is 'UHF':
        return dm1, dm2, e
    elif len(dm1.shape) == 3:
        return numpy.sum(dm1, axis=0), numpy.sum(dm2, axis=0), e
    else:
        return dm1, dm2, e
Example #6
0
def make_rdm12s(fcivec, norb, nelec, link_index=None, reorder=True):
    return direct_spin1.make_rdm12s(fcivec, norb, nelec, link_index, reorder)
Example #7
0
def make_rdm2_abba(fcivec, norb, nelec):
    from pyscf.fci import direct_spin1
    dm2aa, dm2ab, dm2bb = direct_spin1.make_rdm12s(fcivec, norb, nelec)[1]
    dm2abba = -dm2ab.transpose(0, 3, 2, 1)
    return dm2abba
Example #8
0
def make_rdm2_baab(fcivec, norb, nelec):
    from pyscf.fci import direct_spin1
    dm2aa, dm2ab, dm2bb = direct_spin1.make_rdm12s(fcivec, norb, nelec)[1]
    dm2baab = -dm2ab.transpose(2, 1, 0, 3)
    return dm2baab
Example #9
0
def rdm12s_fted(h1e,g2e,norb,nelec,T,symm='RHF',Tmin=1.e-3,\
                dcompl=False,**kwargs):

    if symm is 'RHF':
        from pyscf.fci import direct_spin1 as fcisolver
    elif symm is 'SOC':
        from pyscf.fci import fci_slow_spinless as fcisolver
        dcompl = True
    elif symm is 'UHF':
        from pyscf.fci import direct_uhf as fcisolver
    else:
        from pyscf.fci import direct_spin1 as fcisolver
    ew, ev = diagH(h1e, g2e, norb, nelec, fcisolver)
    ndim = len(ew)
    rdm1, rdm2 = [], []

    RDM1, RDM2 = fcisolver.make_rdm12s(ev[:, 0].copy(), norb, nelec)
    RDM1 = np.asarray(RDM1, dtype=np.complex128)
    RDM2 = np.asarray(RDM2, dtype=np.complex128)

    if T < Tmin:
        if symm is not 'UHF' and len(RDM1.shape) == 3:
            RDM1 = np.sum(RDM1, axis=0)
            RDM2 = np.sum(RDM2, axis=0)
        if not dcompl:
            return RDM1.real, RDM2.real, ew[0].real
        return RDM1, RDM2, ew[0]
    ew -= ew[0]

    Z = np.sum(np.exp(-ew / T))
    E = np.sum(np.exp(-ew / T) * ew) / Z

    for i in range(ndim):
        dm1, dm2 = fcisolver.make_rdm12s(ev[:, i].copy(), norb, nelec)
        rdm1.append(np.asarray(dm1, dtype=np.complex128))
        rdm2.append(np.asarray(dm2, dtype=np.complex128))


#   rdm1 = np.asarray(rdm1)
#   rdm2 = np.asarray(rdm2)

#   RDM1 = np.sum(rdm1*np.exp(-1.j*ew/T))/Z
#   RDM2 = np.sum(rdm2*np.exp(-1.j*ew/T))/Z
    RDM1 *= 0.
    RDM2 *= 0.
    for i in range(ndim):
        RDM1 += rdm1[i] * np.exp(-ew[i] / T)
        RDM2 += rdm2[i] * np.exp(-ew[i] / T)

    RDM1 /= Z
    RDM2 /= Z

    if symm is not 'UHF' and len(RDM1.shape) == 3:
        RDM1 = np.sum(RDM1, axis=0)
        RDM2 = np.sum(RDM2, axis=0)

    if not dcompl:
        E = (E + ew[0]).real
        RDM1 = RDM1.real
        RDM2 = RDM2.real

    return RDM1, RDM2, E
Example #10
0
def rdm12s_fted(h1e,g2e,norb,nelec,T,symm='RHF',Tmin=1.e-3,\
                dcompl=False,**kwargs):

    if symm is 'RHF':
        from pyscf.fci import direct_spin1 as fcisolver
    elif symm is 'SOC':
        from pyscf.fci import fci_slow_spinless as fcisolver
        dcompl = True
    elif symm is 'UHF':
        from pyscf.fci import direct_uhf as fcisolver
    else:
        from pyscf.fci import direct_spin1 as fcisolver

    ew, ev = diagH(h1e, g2e, norb, nelec, fcisolver)
    RDM1, RDM2 = fcisolver.make_rdm12s(ev[:, 0].copy(), norb, nelec)
    RDM1 = np.asarray(RDM1, dtype=np.complex128)
    RDM2 = np.asarray(RDM2, dtype=np.complex128)
    if T < Tmin:
        if symm is not 'UHF' and len(RDM1.shape) == 3:
            RDM1 = np.sum(RDM1, axis=0)
            RDM2 = np.sum(RDM2, axis=0)
        if not dcompl:
            return RDM1.real, RDM2.real, ew[0].real
        return RDM1, RDM2, ew[0]

    ews, evs = solve_spectrum(h1e, g2e, norb, fcisolver)
    mu = solve_mu(h1e, g2e, norb, nelec, fcisolver, T, mu0=0., ews=ews)

    Z = 0.
    E = 0.
    RDM1 *= 0.
    RDM2 *= 0.

    for na in range(0, norb + 1):
        for nb in range(0, norb + 1):
            ne = na + nb
            ndim = len(ews[na, nb])
            Z += np.sum(np.exp((-ews[na, nb] + mu * ne) / T))
            E += np.sum(np.exp((-ews[na, nb] + mu * ne) / T) * ews[na, nb])

            for i in range(ndim):
                dm1, dm2 = fcisolver.make_rdm12s(evs[na, nb][:, i].copy(),
                                                 norb, (na, nb))
                dm1 = np.asarray(dm1, dtype=np.complex128)
                dm2 = np.asarray(dm2, dtype=np.complex128)
                RDM1 += dm1 * np.exp((ne * mu - ews[na, nb][i]) / T)
                RDM2 += dm2 * np.exp((ne * mu - ews[na, nb][i]) / T)

    E /= Z
    RDM1 /= Z
    RDM2 /= Z

    if symm is not 'UHF' and len(RDM1.shape) == 3:
        RDM1 = np.sum(RDM1, axis=0)
        RDM2 = np.sum(RDM2, axis=0)

    if not dcompl:
        E = E.real
        RDM1 = RDM1.real
        RDM2 = RDM2.real
    return RDM1, RDM2, E
Example #11
0
def rdm12s_fted(h1e,g2e,norb,nelec,beta,mu=0.0,bmax=1e3, \
                dcompl=False,**kwargs):
    '''
    Return the expectation values of energy, RDM1 and RDM2 at temperature T.
    '''

    # make sure the Hamiltonians have the correct shape
    #    if (type(h1e) is tuple) or (type(h1e) is list):
    #        h1e = h1e[0]
    #        g2e = g2e[0]

    Z = 0.
    E = 0.
    RDM1 = np.zeros((norb, norb))
    RDM2_0 = np.zeros((norb, norb, norb, norb))
    RDM2_1 = np.zeros((norb, norb, norb, norb))

    if beta > bmax:
        e, v = fcisolver.kernel(h1e, g2e, norb, nelec)
        RDM1, RDM2 = fcisolver.make_rdm12s(v, norb, nelec)
        return np.asarray(RDM1), np.asarray(RDM2), e

    # check for overflow
    e0, _ = fcisolver.kernel(h1e, g2e, norb, norb)
    exp_max = (-e0 + mu * norb) * beta
    if (exp_max > 700):
        exp_shift = exp_max - 500
    else:
        exp_shift = 0

    # Calculating E, RDM1, Z
    N = 0
    # na =/= nb
    for na in range(0, norb + 1):
        for nb in range(na + 1, norb + 1):
            ne = na + nb
            ew, ev = diagH(h1e, g2e, norb, (na, nb), fcisolver)
            exp_ = (-ew + mu * (na + nb)) * beta
            exp_ -= exp_shift
            ndim = len(ew)
            Z += np.sum(np.exp(exp_)) * 2
            E += np.sum(np.exp(exp_) * ew) * 2
            N += ne * np.sum(np.exp(exp_)) * 2

            for i in range(ndim):
                dm1, dm2 = fcisolver.make_rdm12s(ev[:, i].copy(), norb,
                                                 (na, nb))
                RDM1 += (dm1[0] + dm1[1]) * np.exp(exp_[i])
                RDM2_0 += (dm2[0] + dm2[2]) * np.exp(exp_[i])
                RDM2_1 += (dm2[1] + np.transpose(dm2[1],
                                                 (2, 3, 0, 1))) * np.exp(
                                                     exp_[i])

    for na in range(0, norb + 1):
        nb = na
        ne = na + nb
        ew, ev = diagH(h1e, g2e, norb, (na, nb), fcisolver)
        exp_ = (-ew + mu * (na + nb)) * beta
        exp_ -= exp_shift
        ndim = len(ew)
        Z += np.sum(np.exp(exp_))
        E += np.sum(np.exp(exp_) * ew)
        N += ne * np.sum(np.exp(exp_))

        for i in range(ndim):
            dm1, dm2 = fcisolver.make_rdm12s(ev[:, i].copy(), norb, (na, nb))
            RDM1 += dm1[0] * np.exp(exp_[i])
            RDM2_0 += dm2[0] * np.exp(exp_[i])
            RDM2_1 += dm2[1] * np.exp(exp_[i])

    E /= Z
    N /= Z
    RDM1 /= Z
    RDM2_0 /= Z
    RDM2_1 /= Z

    log.result("The expectation of electron number:")
    log.result("N(total) = %10.10f" % N)

    RDM1 = np.asarray([RDM1, RDM1])
    RDM2 = np.asarray([RDM2_0, RDM2_1, RDM2_0])
    log.result("FTED energy: %10.12f" % E)

    # RDM2 order: aaaa, aabb, bbbb
    return RDM1, RDM2, E
Example #12
0
 def qud(v1):
     dm1, dm2 = fcisolver.make_rdm12s(v1, norb, nelec)
     return dm1, dm2
Example #13
0
def make_dm12(ci0, norb, nelec):
    def des(ci0, norb, nelec, ap_id, spin):
        if spin == 0:
            ci1 = addons.des_a(ci0, norb, nelec, ap_id)
            ne = nelec[0] - 1, nelec[1]
        else:
            ci1 = addons.des_b(ci0, norb, nelec, ap_id)
            ne = nelec[0], nelec[1] - 1
        return ci1, ne

    def cre(ci0, norb, nelec, ap_id, spin):
        if spin == 0:
            ci1 = addons.cre_a(ci0, norb, nelec, ap_id)
            ne = nelec[0] + 1, nelec[1]
        else:
            ci1 = addons.cre_b(ci0, norb, nelec, ap_id)
            ne = nelec[0], nelec[1] + 1
        return ci1, ne

    dm1 = numpy.zeros((norb, 2, norb, 2))
    for i in range(norb):
        for j in range(norb):
            for i1 in range(2):
                for j1 in range(2):
                    if i1 == j1:
                        ne = nelec
                        ci1, ne = des(ci0, norb, ne, j, j1)
                        ci1, ne = cre(ci1, norb, ne, i, i1)
                        dm1[i, i1, j, j1] = numpy.dot(ci0.ravel(), ci1.ravel())

    dm2 = numpy.zeros((norb, 2, norb, 2, norb, 2, norb, 2))
    for i in range(norb):
        for j in range(norb):
            for k in range(norb):
                for l in range(norb):
                    for i1 in range(2):
                        for j1 in range(2):
                            for k1 in range(2):
                                for l1 in range(2):
                                    if i1 + j1 == k1 + l1:
                                        ci1, ne = ci0, nelec
                                        ci1, ne = des(ci1, norb, ne, k, k1)
                                        ci1, ne = des(ci1, norb, ne, l, l1)
                                        ci1, ne = cre(ci1, norb, ne, j, j1)
                                        ci1, ne = cre(ci1, norb, ne, i, i1)
                                        dm2[i, i1, j, j1, k, k1, l,
                                            l1] = numpy.dot(
                                                ci0.ravel(), ci1.ravel())
    if 0:
        dm1a = numpy.einsum('iajb->ij', dm1)
        dm2a = numpy.einsum('iajbkalb->ijkl', dm2)
        print abs(numpy.einsum('ipjp->ij', dm2a) / (sum(nelec) - 1) -
                  dm1a).sum()
        (dm1a, dm1b), (dm2aa, dm2ab, dm2bb) = \
                direct_spin1.make_rdm12s(ci0, norb, nelec)
        print abs(dm1a - dm1[:, 0, :, 0]).sum()
        print abs(dm2aa -
                  dm2[:, 0, :, 0, :, 0, :, 0].transpose(0, 2, 1, 3)).sum()
        print abs(dm2ab -
                  dm2[:, 0, :, 1, :, 0, :, 1].transpose(0, 2, 1, 3)).sum()
        print abs(
            dm2ab.transpose(2, 3, 0, 1) -
            dm2[:, 1, :, 0, :, 1, :, 0].transpose(0, 2, 1, 3)).sum()
        print abs(dm2bb -
                  dm2[:, 1, :, 1, :, 1, :, 1].transpose(0, 2, 1, 3)).sum()
        dm2baab = spin_op.make_rdm2_baab(ci0, norb, nelec)
        dm2abba = spin_op.make_rdm2_abba(ci0, norb, nelec)
        print abs(dm2baab -
                  dm2[:, 1, :, 0, :, 0, :, 1].transpose(0, 2, 1, 3)).sum()
        print abs(dm2abba -
                  dm2[:, 0, :, 1, :, 1, :, 0].transpose(0, 2, 1, 3)).sum()
    return dm1, dm2
Example #14
0
            one_sf, two_sf = find_full_casscf_12rdm(mc.fcisolver, mf.mo_coeff,
                                                    'spinfree_TwoRDM.1', norb,
                                                    nelec)
            assert (numpy.allclose(
                two_sf[:n_occorbs, :n_occorbs, :n_occorbs, :n_occorbs],
                spinfree_2))

    mc2 = mcscf.CASCI(mf, 6, 6)
    #    mc2.canonicalization = False
    mc2.fcisolver = direct_spin1.FCISolver(mol)
    emc2, e_cas2, fcivec2 = mc2.kernel()[:3]
    #ss_tot = spin_op.spin_square(fcivec2, norb, nelec)[0]
    #    print 'ss_tot exact: ',ss_tot
    (dm1a_, dm1b_), (dm2aa_, dm2ab_,
                     dm2bb_) = direct_spin1.make_rdm12s(fcivec2,
                                                        norb,
                                                        nelec,
                                                        reorder=False)

    #f_dbg = dbg_ss_frac(dm1, dm2, norb, mo_cas, ovlp)
    # dm2baab(pq,rs) = <p(beta)* q(alpha) r(alpha)* s(beta)
    dm2baab_ = spin_op._make_rdm2_baab(fcivec2, norb, nelec)
    # dm2abba(pq,rs) = <q(alpha)* p(beta) s(beta)* r(alpha)
    dm2abba_ = spin_op._make_rdm2_abba(fcivec2, norb, nelec)
    ss_tot = spin_op.spin_square(fcivec2, norb, nelec)[0]

    f_opt_act = opt_ss_frac(dm1a_, dm1b_, dm2aa_, dm2ab_, dm2bb_, dm2baab_,
                            dm2abba_, norb, nelec, mo_cas, ovlp)
    f_mag_act = opt_mag_frac(dm1a_, dm1b_, norb, nelec, mo_cas, ovlp)
    if DoNECI:
        f_opt_full = opt_ss_frac(dm1a, dm1b, dm2aa, dm2ab, dm2bb, dm2baab,
                                 dm2abba, n_occorbs, nelec_full, occorbs, ovlp)
Example #15
0
def rdm12s_ftfci(h1e,g2e,norb,nelec,T,mu,m=50,Tmin=1e-3,\
                   dcompl=False,symm='RHF',**kwargs):

    if symm is 'RHF':
        from pyscf.fci import direct_spin1 as fcisolver
    elif symm is 'SOC':
        from pyscf.fci import fci_slow_spinless as fcisolver
        dcompl = True
    elif symm is 'UHF':
        from pyscf.fci import direct_uhf as fcisolver
    else:
        from pyscf.fci import direct_spin1 as fcisolver

    if symm != 'UHF' and isinstance(h1e, tuple):
        h1e = h1e[0]
        g2e = g2e[1]

    if T < Tmin:  # only for half-filling
        e, v = fcisolver.kernel(h1e, g2e, norb, nelec)
        RDM1, RDM2 = fcisolver.make_rdm12s(v, norb, nelec)
        return numpy.asarray(RDM1), numpy.asarray(RDM2), e

    # loop over na and nb
    Z = 0.
    E = 0.
    RDM1 = numpy.zeros((2, norb, norb), dtype=numpy.complex128)
    RDM2 = numpy.zeros((3, norb, norb, norb, norb), dtype=numpy.complex128)
    #for ns in range(1):
    #    rdm1,rdm2,e,z = lanczos_grand.ft_solver(h1e,g2e,fcisolver,norb,nelec,T,mu=0,m=m)
    #    RDM1 += rdm1
    #    RDM2 += rdm2
    #    E    += e
    #    Z    += z

    # calculate the number of states
    nstate = 0.

    dN = 0
    for na in range(norb / 2 - dN, norb / 2 + dN + 1):
        for nb in range(norb / 2 - dN, norb / 2 + dN + 1):
            nstate += cistring.num_strings(norb, na) * cistring.num_strings(
                norb, nb)

    for na in range(norb / 2 - dN, norb / 2 + dN + 1):
        for nb in range(na, norb / 2 + dN + 1):
            ne = (na, nb)
            ntot = na + nb
            nci = cistring.num_strings(norb, na) * cistring.num_strings(
                norb, nb)
            factor = numpy.exp(0 * (ntot - norb) / T)
            if nci < 1e2:
                rdm1, rdm2, e, z = ed_canonical.ftsolver(h1e,
                                                         g2e,
                                                         fcisolver,
                                                         norb,
                                                         ne,
                                                         T,
                                                         mu,
                                                         symm='UHF')
                Z += z / nstate * factor
                E += e / nstate * factor
                RDM1 += rdm1 / nstate * factor
                RDM2 += rdm2 / nstate * factor

            else:
                rdm1, rdm2, e, z = lanczos_grand.ft_solver(
                    h1e, g2e, fcisolver, norb, ne, T, mu)
                Z += z * (nci / nstate) * factor
                E += e * (nci / nstate) * factor
                RDM1 += rdm1 * (nci / nstate) * factor
                RDM2 += rdm2 * (nci / nstate) * factor
                #if nb > na:
                #    Z += 2*(nci/nstate)*z*factor
                #    E += 2*(nci/nstate)*e*factor
                #    RDM1 += (nci/nstate)*rdm1*factor
                #    RDM1 += (nci/nstate)*permute_rdm1(rdm1)*factor
                #    RDM2 += 2*(nci/nstate)*rdm2*factor
                #else:
                #    Z += (nci/nstate)*z*factor
                #    E += (nci/nstate)*e*factor
                #    RDM1 += (nci/nstate)*rdm1*factor
                #    #RDM1 += (nci/nstate)*permute_rdm1(rdm1)*factor/2.
                #    RDM2 += (nci/nstate)*rdm2*factor
                #

    E /= Z
    RDM1 /= Z
    RDM2 /= Z

    if not dcompl:
        E = E.real
        RDM1 = RDM1.real
        RDM2 = RDM2.real
    return RDM1, RDM2, E
Example #16
0
if __name__ == '__main__':

    from pyscf.fci import direct_uhf as fcisolver
    norb = 12
    nelec = (norb / 2, norb / 2)
    u = 4.0
    T = 0.05
    mu = 2
    h1e = numpy.zeros((norb, norb))
    for i in range(norb):
        h1e[i, (i + 1) % norb] = -1.0
        h1e[i, (i - 1) % norb] = -1.0
    #h1e[0,-1] = 0.
    #h1e[-1,0] = 0.
    g2e_ = numpy.zeros((norb, ) * 4)
    for i in range(norb):
        g2e_[i, i, i, i] = u
    h1e = (h1e, h1e)
    g2e = (numpy.zeros((norb, ) * 4), g2e_, numpy.zeros((norb, ) * 4))
    rdm1, rdm2, e = rdm12s_ftfci(h1e,g2e,norb,nelec,T,mu,m=200,Tmin=1e-3,\
                   dcompl=False,symm='UHF')

    e0, v = fcisolver.kernel(h1e, g2e, norb, nelec, nroots=1)
    rdm10, rdm20 = fcisolver.make_rdm12s(v, norb, nelec)

    print e / norb - e0 / norb
    print numpy.linalg.norm(rdm1 - rdm10)
    print numpy.linalg.norm(rdm2 - rdm20)
    print rdm1[0][:4, :4]
    print rdm10[0][:4, :4]