Exemplo n.º 1
0
def make_rdm12e(fcivec, nsite, nelec):
    '''1-electron and 2-electron density matrices
    dm_pq = <|p^+ q|>
    dm_{pqrs} = <|p^+ r^+ q s|>  (note 2pdm is ordered in chemist notation)
    '''
    neleca, nelecb = _unpack_nelec(nelec)
    link_indexa = cistring.gen_linkstr_index(range(nsite), neleca)
    link_indexb = cistring.gen_linkstr_index(range(nsite), nelecb)
    na = cistring.num_strings(nsite, neleca)
    nb = cistring.num_strings(nsite, nelecb)

    ci0 = fcivec.reshape(na,nb,-1)
    rdm1 = numpy.zeros((nsite,nsite))
    rdm2 = numpy.zeros((nsite,nsite,nsite,nsite))
    for str0 in range(na):
        t1 = numpy.zeros((nsite,nsite,nb)+ci0.shape[2:])
        for a, i, str1, sign in link_indexa[str0]:
            t1[i,a,:] += sign * ci0[str1,:]

        for k, tab in enumerate(link_indexb):
            for a, i, str1, sign in tab:
                t1[i,a,k] += sign * ci0[str0,str1]

        rdm1 += numpy.einsum('mp,ijmp->ij', ci0[str0], t1)
        # i^+ j|0> => <0|j^+ i, so swap i and j
        #:rdm2 += numpy.einsum('ijmp,klmp->jikl', t1, t1)
        tmp = lib.dot(t1.reshape(nsite**2,-1), t1.reshape(nsite**2,-1).T)
        rdm2 += tmp.reshape((nsite,)*4).transpose(1,0,2,3)
    rdm1, rdm2 = rdm.reorder_rdm(rdm1, rdm2, True)
    return rdm1, rdm2
Exemplo n.º 2
0
def make_hdiag(t, u, g, hpp, nsite, nelec, nphonon):
    neleca, nelecb = _unpack_nelec(nelec)
    link_indexa = cistring.gen_linkstr_index(range(nsite), neleca)
    link_indexb = cistring.gen_linkstr_index(range(nsite), nelecb)
    occslista = [tab[:neleca,0] for tab in link_indexa]
    occslistb = [tab[:nelecb,0] for tab in link_indexb]

    nelec_tot = neleca + nelecb

    # electron part
    cishape = make_shape(nsite, nelec, nphonon)
    hdiag = numpy.zeros(cishape)
    for ia, aocc in enumerate(occslista):
        for ib, bocc in enumerate(occslistb):
            e1 = t[aocc,aocc].sum() + t[bocc,bocc].sum()
            e2 = u * nelec_tot
            hdiag[ia,ib] = e1 + e2

    #TODO: electron-phonon part

    # phonon part
    for psite_id in range(nsite):
        for i in range(nphonon+1):
            slices0 = slices_for(psite_id, nsite, i)
            hdiag[slices0] += i+1

    return hdiag.ravel()
Exemplo n.º 3
0
def make_hdiag(h1e, eri, norb, nelec):
    neleca, nelecb = direct_spin1._unpack_nelec(nelec)
    h1e_a = numpy.ascontiguousarray(h1e[0])
    h1e_b = numpy.ascontiguousarray(h1e[1])
    g2e_aa = ao2mo.restore(1, eri[0], norb)
    g2e_ab = ao2mo.restore(1, eri[1], norb)
    g2e_bb = ao2mo.restore(1, eri[2], norb)

    strsa = numpy.asarray(cistring.gen_strings4orblist(range(norb), neleca))
    strsb = numpy.asarray(cistring.gen_strings4orblist(range(norb), nelecb))
    na = len(strsa)
    nb = len(strsb)

    hdiag = numpy.empty(na*nb)
    jdiag_aa = numpy.asarray(numpy.einsum('iijj->ij',g2e_aa), order='C')
    jdiag_ab = numpy.asarray(numpy.einsum('iijj->ij',g2e_ab), order='C')
    jdiag_bb = numpy.asarray(numpy.einsum('iijj->ij',g2e_bb), order='C')
    kdiag_aa = numpy.asarray(numpy.einsum('ijji->ij',g2e_aa), order='C')
    kdiag_bb = numpy.asarray(numpy.einsum('ijji->ij',g2e_bb), order='C')
    libfci.FCImake_hdiag_uhf(hdiag.ctypes.data_as(ctypes.c_void_p),
                             h1e_a.ctypes.data_as(ctypes.c_void_p),
                             h1e_b.ctypes.data_as(ctypes.c_void_p),
                             jdiag_aa.ctypes.data_as(ctypes.c_void_p),
                             jdiag_ab.ctypes.data_as(ctypes.c_void_p),
                             jdiag_bb.ctypes.data_as(ctypes.c_void_p),
                             kdiag_aa.ctypes.data_as(ctypes.c_void_p),
                             kdiag_bb.ctypes.data_as(ctypes.c_void_p),
                             ctypes.c_int(norb),
                             ctypes.c_int(na), ctypes.c_int(nb),
                             ctypes.c_int(neleca), ctypes.c_int(nelecb),
                             strsa.ctypes.data_as(ctypes.c_void_p),
                             strsb.ctypes.data_as(ctypes.c_void_p))
    return numpy.asarray(hdiag)
Exemplo n.º 4
0
def pspace(h1e, eri, norb, nelec, hdiag, np=400):
    neleca, nelecb = direct_spin1._unpack_nelec(nelec)
    h1e_a = numpy.ascontiguousarray(h1e[0])
    h1e_b = numpy.ascontiguousarray(h1e[1])
    g2e_aa = ao2mo.restore(1, eri[0], norb)
    g2e_ab = ao2mo.restore(1, eri[1], norb)
    g2e_bb = ao2mo.restore(1, eri[2], norb)
    link_indexa = cistring.gen_linkstr_index_trilidx(range(norb), neleca)
    link_indexb = cistring.gen_linkstr_index_trilidx(range(norb), nelecb)
    nb = link_indexb.shape[0]
    addr = numpy.argsort(hdiag)[:np]
    addra = addr // nb
    addrb = addr % nb
    stra = numpy.array([cistring.addr2str(norb,neleca,ia) for ia in addra],
                       dtype=numpy.long)
    strb = numpy.array([cistring.addr2str(norb,nelecb,ib) for ib in addrb],
                       dtype=numpy.long)
    np = len(addr)
    h0 = numpy.zeros((np,np))
    libfci.FCIpspace_h0tril_uhf(h0.ctypes.data_as(ctypes.c_void_p),
                                h1e_a.ctypes.data_as(ctypes.c_void_p),
                                h1e_b.ctypes.data_as(ctypes.c_void_p),
                                g2e_aa.ctypes.data_as(ctypes.c_void_p),
                                g2e_ab.ctypes.data_as(ctypes.c_void_p),
                                g2e_bb.ctypes.data_as(ctypes.c_void_p),
                                stra.ctypes.data_as(ctypes.c_void_p),
                                strb.ctypes.data_as(ctypes.c_void_p),
                                ctypes.c_int(norb), ctypes.c_int(np))

    for i in range(np):
        h0[i,i] = hdiag[addr[i]]
    h0 = lib.hermi_triu(h0)
    return addr, h0
Exemplo n.º 5
0
def contract_2e_hubbard(u, fcivec, norb, nelec, opt=None):
    neleca, nelecb = direct_spin1._unpack_nelec(nelec)
    u_aa, u_ab, u_bb = u

    strsa = numpy.asarray(cistring.gen_strings4orblist(range(norb), neleca))
    strsb = numpy.asarray(cistring.gen_strings4orblist(range(norb), nelecb))
    na = cistring.num_strings(norb, neleca)
    nb = cistring.num_strings(norb, nelecb)
    fcivec = fcivec.reshape(na,nb)
    fcinew = numpy.zeros_like(fcivec)

    if u_aa != 0:  # u * n_alpha^+ n_alpha
        for i in range(norb):
            maska = (strsa & (1<<i)) > 0
            fcinew[maska] += u_aa * fcivec[maska]
    if u_ab != 0:  # u * (n_alpha^+ n_beta + n_beta^+ n_alpha)
        for i in range(norb):
            maska = (strsa & (1<<i)) > 0
            maskb = (strsb & (1<<i)) > 0
            fcinew[maska[:,None]&maskb] += 2*u_ab * fcivec[maska[:,None]&maskb]
    if u_bb != 0:  # u * n_beta^+ n_beta
        for i in range(norb):
            maskb = (strsb & (1<<i)) > 0
            fcinew[:,maskb] += u_bb * fcivec[:,maskb]
    return fcinew
Exemplo n.º 6
0
def contract_2e(eri, fcivec, nsite, nelec, nphonon):
    neleca, nelecb = _unpack_nelec(nelec)
    link_indexa = cistring.gen_linkstr_index(range(nsite), neleca)
    link_indexb = cistring.gen_linkstr_index(range(nsite), nelecb)
    cishape = make_shape(nsite, nelec, nphonon)

    ci0 = fcivec.reshape(cishape)
    t1a = numpy.zeros((nsite,nsite)+cishape)
    t1b = numpy.zeros((nsite,nsite)+cishape)
    for str0, tab in enumerate(link_indexa):
        for a, i, str1, sign in tab:
            t1a[a,i,str1] += sign * ci0[str0]
    for str0, tab in enumerate(link_indexb):
        for a, i, str1, sign in tab:
            t1b[a,i,:,str1] += sign * ci0[:,str0]

    g2e_aa = ao2mo.restore(1, eri[0], nsite)
    g2e_ab = ao2mo.restore(1, eri[1], nsite)
    g2e_bb = ao2mo.restore(1, eri[2], nsite)
    t2a = numpy.dot(g2e_aa.reshape(nsite**2,-1), t1a.reshape(nsite**2,-1))
    t2a+= numpy.dot(g2e_ab.reshape(nsite**2,-1), t1b.reshape(nsite**2,-1))
    t2b = numpy.dot(g2e_ab.reshape(nsite**2,-1).T, t1a.reshape(nsite**2,-1))
    t2b+= numpy.dot(g2e_bb.reshape(nsite**2,-1), t1b.reshape(nsite**2,-1))

    t2a = t2a.reshape((nsite,nsite)+cishape)
    t2b = t2b.reshape((nsite,nsite)+cishape)
    fcinew = numpy.zeros(cishape)
    for str0, tab in enumerate(link_indexa):
        for a, i, str1, sign in tab:
            fcinew[str1] += sign * t2a[a,i,str0]
    for str0, tab in enumerate(link_indexb):
        for a, i, str1, sign in tab:
            fcinew[:,str1] += sign * t2b[a,i,:,str0]
    return fcinew.reshape(fcivec.shape)
Exemplo n.º 7
0
def _unpack(civec_strs, nelec, ci_strs=None, spin=None):
    neleca, nelecb = direct_spin1._unpack_nelec(nelec, spin)
    ci_strs = getattr(civec_strs, '_strs', ci_strs)
    if ci_strs is not None:
        strsa, strsb = ci_strs
        strsa = numpy.asarray(strsa)
        strsb = numpy.asarray(strsb)
        ci_strs = (strsa, strsb)
    return civec_strs, (neleca, nelecb), ci_strs
Exemplo n.º 8
0
def _id_wfnsym(cis, norb, nelec, wfnsym):
    if wfnsym is None:
        neleca, nelecb = direct_spin1._unpack_nelec(nelec)
        wfnsym = 0  # Ag, A1 or A
        for i in cis.orbsym[nelecb:neleca]:
            wfnsym ^= i
    elif isinstance(wfnsym, str):
        wfnsym = symm.irrep_name2id(cis.mol.groupname, wfnsym) % 10
    return wfnsym
Exemplo n.º 9
0
 def make_rdm12(self, civec_strs, norb, nelec, link_index=None, **kwargs):
     nelec = direct_spin1._unpack_nelec(nelec, self.spin)
     nelec_tot = sum(nelec)
     civec_strs = _as_SCIvector_if_not(civec_strs, self._strs)
     dm2 = make_rdm2(civec_strs, norb, nelec, link_index)
     if nelec_tot > 1:
         dm1 = numpy.einsum('iikl->kl', dm2) / (nelec_tot-1)
     else:
         dm1 = make_rdm1(civec_strs, norb, nelec, link_index)
     return dm1, dm2
Exemplo n.º 10
0
 def make_rdm12s(self, civec_strs, norb, nelec, link_index=None, **kwargs):
     neleca, nelecb = nelec = direct_spin1._unpack_nelec(nelec, self.spin)
     civec_strs = _as_SCIvector_if_not(civec_strs, self._strs)
     dm2aa, dm2ab, dm2bb = make_rdm2s(civec_strs, norb, nelec, link_index)
     if neleca > 1 and nelecb > 1:
         dm1a = numpy.einsum('iikl->kl', dm2aa) / (neleca-1)
         dm1b = numpy.einsum('iikl->kl', dm2bb) / (nelecb-1)
     else:
         dm1a, dm1b = make_rdm1s(civec_strs, norb, nelec, link_index)
     return (dm1a, dm1b), (dm2aa, dm2ab, dm2bb)
Exemplo n.º 11
0
 def large_ci(self, civec_strs, norb, nelec, tol=.1, return_strs=True):
     nelec = direct_spin1._unpack_nelec(nelec, self.spin)
     ci, _, (strsa, strsb) = _unpack(civec_strs, nelec, self._strs)
     addra, addrb = numpy.where(abs(ci) > tol)
     if return_strs:
         strsa = [bin(x) for x in strsa[addra]]
         strsb = [bin(x) for x in strsb[addrb]]
         return list(zip(ci[addra,addrb], strsa, strsb))
     else:
         occslsta = cistring._strs2occslst(strsa[addra], norb)
         occslstb = cistring._strs2occslst(strsb[addrb], norb)
         return list(zip(ci[addra,addrb], occslsta, occslstb))
Exemplo n.º 12
0
def contract_2e_hubbard(u, fcivec, nsite, nelec, nphonon):
    neleca, nelecb = _unpack_nelec(nelec)
    strsa = numpy.asarray(cistring.gen_strings4orblist(range(nsite), neleca))
    strsb = numpy.asarray(cistring.gen_strings4orblist(range(nsite), nelecb))
    cishape = make_shape(nsite, nelec, nphonon)
    ci0 = fcivec.reshape(cishape)
    fcinew = numpy.zeros(cishape)

    for i in range(nsite):
        maska = (strsa & (1<<i)) > 0
        maskb = (strsb & (1<<i)) > 0
        fcinew[maska[:,None]&maskb] += u * ci0[maska[:,None]&maskb]
    return fcinew.reshape(fcivec.shape)
Exemplo n.º 13
0
def kernel_fixed_space(myci, h1e, eri, norb, nelec, ci_strs, ci0=None,
                       tol=None, lindep=None, max_cycle=None, max_space=None,
                       nroots=None, davidson_only=None,
                       max_memory=None, verbose=None, ecore=0, **kwargs):
    if verbose is None:
        log = logger.Logger(myci.stdout, myci.verbose)
    elif isinstance(verbose, logger.Logger):
        log = verbose
    else:
        log = logger.Logger(myci.stdout, verbose)
    if tol is None: tol = myci.conv_tol
    if lindep is None: lindep = myci.lindep
    if max_cycle is None: max_cycle = myci.max_cycle
    if max_space is None: max_space = myci.max_space
    if max_memory is None: max_memory = myci.max_memory
    if nroots is None: nroots = myci.nroots
    if myci.verbose >= logger.WARN:
        myci.check_sanity()

    nelec = direct_spin1._unpack_nelec(nelec, myci.spin)
    ci0, nelec, ci_strs = _unpack(ci0, nelec, ci_strs)
    na = len(ci_strs[0])
    nb = len(ci_strs[1])
    h2e = direct_spin1.absorb_h1e(h1e, eri, norb, nelec, .5)
    h2e = ao2mo.restore(1, h2e, norb)

    link_index = _all_linkstr_index(ci_strs, norb, nelec)
    hdiag = myci.make_hdiag(h1e, eri, ci_strs, norb, nelec)

    if isinstance(ci0, _SCIvector):
        if ci0.size == na*nb:
            ci0 = [ci0.ravel()]
        else:
            ci0 = [x.ravel() for x in ci0]
    else:
        ci0 = myci.get_init_guess(ci_strs, norb, nelec, nroots, hdiag)

    def hop(c):
        hc = myci.contract_2e(h2e, _as_SCIvector(c, ci_strs), norb, nelec, link_index)
        return hc.reshape(-1)
    precond = lambda x, e, *args: x/(hdiag-e+1e-4)

    #e, c = lib.davidson(hop, ci0, precond, tol=myci.conv_tol)
    e, c = myci.eig(hop, ci0, precond, tol=tol, lindep=lindep,
                    max_cycle=max_cycle, max_space=max_space, nroots=nroots,
                    max_memory=max_memory, verbose=log, **kwargs)
    if nroots > 1:
        return e+ecore, [_as_SCIvector(ci.reshape(na,nb),ci_strs) for ci in c]
    else:
        return e+ecore, _as_SCIvector(c.reshape(na,nb), ci_strs)
Exemplo n.º 14
0
def contract_1e(h1e, fcivec, nsite, nelec, nphonon):
    neleca, nelecb = _unpack_nelec(nelec)
    link_indexa = cistring.gen_linkstr_index(range(nsite), neleca)
    link_indexb = cistring.gen_linkstr_index(range(nsite), nelecb)
    cishape = make_shape(nsite, nelec, nphonon)

    ci0 = fcivec.reshape(cishape)
    fcinew = numpy.zeros(cishape)
    for str0, tab in enumerate(link_indexa):
        for a, i, str1, sign in tab:
            fcinew[str1] += sign * ci0[str0] * h1e[a,i]
    for str0, tab in enumerate(link_indexb):
        for a, i, str1, sign in tab:
            fcinew[:,str1] += sign * ci0[:,str0] * h1e[a,i]
    return fcinew.reshape(fcivec.shape)
Exemplo n.º 15
0
 def gen_linkstr(self, norb, nelec, tril=True, spin=None, ci_strs=None):
     if spin is None:
         spin = self.spin
     if ci_strs is None:
         ci_strs = self._strs
     neleca, nelecb = direct_spin1._unpack_nelec(nelec, spin)
     if tril:
         cd_indexa = cre_des_linkstr_tril(ci_strs[0], norb, neleca)
         dd_indexa = des_des_linkstr_tril(ci_strs[0], norb, neleca)
         cd_indexb = cre_des_linkstr_tril(ci_strs[1], norb, nelecb)
         dd_indexb = des_des_linkstr_tril(ci_strs[1], norb, nelecb)
     else:
         cd_indexa = cre_des_linkstr(ci_strs[0], norb, neleca)
         dd_indexa = des_des_linkstr(ci_strs[0], norb, neleca)
         cd_indexb = cre_des_linkstr(ci_strs[1], norb, nelecb)
         dd_indexb = des_des_linkstr(ci_strs[1], norb, nelecb)
     return cd_indexa, dd_indexa, cd_indexb, dd_indexb
Exemplo n.º 16
0
 def gen_linkstr(self, norb, nelec, tril=True, spin=None, ci_strs=None):
     if spin is None:
         spin = self.spin
     if ci_strs is None:
         ci_strs = self._strs
     neleca, nelecb = direct_spin1._unpack_nelec(nelec, spin)
     if tril:
         cd_indexa = cre_des_linkstr_tril(ci_strs[0], norb, neleca)
         dd_indexa = des_des_linkstr_tril(ci_strs[0], norb, neleca)
         cd_indexb = cre_des_linkstr_tril(ci_strs[1], norb, nelecb)
         dd_indexb = des_des_linkstr_tril(ci_strs[1], norb, nelecb)
     else:
         cd_indexa = cre_des_linkstr(ci_strs[0], norb, neleca)
         dd_indexa = des_des_linkstr(ci_strs[0], norb, neleca)
         cd_indexb = cre_des_linkstr(ci_strs[1], norb, nelecb)
         dd_indexb = des_des_linkstr(ci_strs[1], norb, nelecb)
     return cd_indexa, dd_indexa, cd_indexb, dd_indexb
Exemplo n.º 17
0
def kernel_fixed_space(myci, h1e, eri, norb, nelec, ci_strs, ci0=None,
                       tol=None, lindep=None, max_cycle=None, max_space=None,
                       nroots=None, davidson_only=None,
                       max_memory=None, verbose=None, ecore=0, **kwargs):
    log = logger.new_logger(myci, verbose)
    if tol is None: tol = myci.conv_tol
    if lindep is None: lindep = myci.lindep
    if max_cycle is None: max_cycle = myci.max_cycle
    if max_space is None: max_space = myci.max_space
    if max_memory is None: max_memory = myci.max_memory
    if nroots is None: nroots = myci.nroots
    if myci.verbose >= logger.WARN:
        myci.check_sanity()

    nelec = direct_spin1._unpack_nelec(nelec, myci.spin)
    ci0, nelec, ci_strs = _unpack(ci0, nelec, ci_strs)
    na = len(ci_strs[0])
    nb = len(ci_strs[1])
    h2e = direct_spin1.absorb_h1e(h1e, eri, norb, nelec, .5)
    h2e = ao2mo.restore(1, h2e, norb)

    link_index = _all_linkstr_index(ci_strs, norb, nelec)
    hdiag = myci.make_hdiag(h1e, eri, ci_strs, norb, nelec)

    if isinstance(ci0, _SCIvector):
        if ci0.size == na*nb:
            ci0 = [ci0.ravel()]
        else:
            ci0 = [x.ravel() for x in ci0]
    else:
        ci0 = myci.get_init_guess(ci_strs, norb, nelec, nroots, hdiag)

    def hop(c):
        hc = myci.contract_2e(h2e, _as_SCIvector(c, ci_strs), norb, nelec, link_index)
        return hc.reshape(-1)
    precond = lambda x, e, *args: x/(hdiag-e+1e-4)

    #e, c = lib.davidson(hop, ci0, precond, tol=myci.conv_tol)
    e, c = myci.eig(hop, ci0, precond, tol=tol, lindep=lindep,
                    max_cycle=max_cycle, max_space=max_space, nroots=nroots,
                    max_memory=max_memory, verbose=log, **kwargs)
    if nroots > 1:
        return e+ecore, [_as_SCIvector(ci.reshape(na,nb),ci_strs) for ci in c]
    else:
        return e+ecore, _as_SCIvector(c.reshape(na,nb), ci_strs)
Exemplo n.º 18
0
 def __init__(self, fcibox, norb, nelec, nroots, idx_root, dtype=np.float64):
     # I'm not sure I need linkstrl
     self.linkstrl = fcibox.states_gen_linkstr (norb, nelec, tril=True)
     self.linkstr = fcibox.states_gen_linkstr (norb, nelec, tril=False)
     self.fcisolvers = [fcibox.fcisolvers[ix] for ix in idx_root]
     self.linkstrl = [self.linkstrl[ix] for ix in idx_root]
     self.linkstr = [self.linkstr[ix] for ix in idx_root]
     self.norb = norb
     self.nelec = nelec
     self.nroots = nroots
     self.ovlp = np.zeros ((nroots, nroots), dtype=dtype)
     self.nelec_r = [_unpack_nelec (fcibox._get_nelec (solver, nelec)) for solver in self.fcisolvers]
     self._h = [[[None for i in range (nroots)] for j in range (nroots)] for s in (0,1)]
     self._hh = [[[None for i in range (nroots)] for j in range (nroots)] for s in (-1,0,1)] 
     self._phh = [[[None for i in range (nroots)] for j in range (nroots)] for s in (0,1)]
     self._sm = [[None for i in range (nroots)] for j in range (nroots)]
     self.dm1 = [[None for i in range (nroots)] for j in range (nroots)]
     self.dm2 = [[None for i in range (nroots)] for j in range (nroots)]
Exemplo n.º 19
0
def contract_2e(eri, fcivec, norb, nelec, link_index=None, orbsym=None, wfnsym=0):
    if orbsym is None:
        return direct_spin0.contract_2e(eri, fcivec, norb, nelec, link_index)

    eri = ao2mo.restore(4, eri, norb)
    neleca, nelecb = direct_spin1._unpack_nelec(nelec)
    assert(neleca == nelecb)
    link_indexa = direct_spin0._unpack(norb, nelec, link_index)
    na, nlinka = link_indexa.shape[:2]
    eri_irs, rank_eri, irrep_eri = direct_spin1_symm.reorder_eri(eri, norb, orbsym)
    totirrep = len(eri_irs)

    strsa = numpy.asarray(cistring.gen_strings4orblist(range(norb), neleca))
    aidx, link_indexa = direct_spin1_symm.gen_str_irrep(strsa, orbsym, link_indexa,
                                                        rank_eri, irrep_eri, totirrep)

    Tirrep = ctypes.c_void_p*totirrep
    linka_ptr = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in link_indexa])
    eri_ptrs = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in eri_irs])
    dimirrep = (ctypes.c_int*totirrep)(*[x.shape[0] for x in eri_irs])
    fcivec_shape = fcivec.shape
    fcivec = fcivec.reshape((na,na), order='C')
    ci1new = numpy.zeros_like(fcivec)
    nas = (ctypes.c_int*8)(*[x.size for x in aidx])

    ci0 = []
    ci1 = []
    for ir in range(totirrep):
        ma, mb = aidx[ir].size, aidx[wfnsym^ir].size
        ci0.append(numpy.zeros((ma,mb)))
        ci1.append(numpy.zeros((ma,mb)))
        if ma > 0 and mb > 0:
            lib.take_2d(fcivec, aidx[ir], aidx[wfnsym^ir], out=ci0[ir])
    ci0_ptrs = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in ci0])
    ci1_ptrs = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in ci1])
    libfci.FCIcontract_2e_symm1(eri_ptrs, ci0_ptrs, ci1_ptrs,
                                ctypes.c_int(norb), nas, nas,
                                ctypes.c_int(nlinka), ctypes.c_int(nlinka),
                                linka_ptr, linka_ptr, dimirrep,
                                ctypes.c_int(totirrep), ctypes.c_int(wfnsym))
    for ir in range(totirrep):
        if ci0[ir].size > 0:
            lib.takebak_2d(ci1new, ci1[ir], aidx[ir], aidx[wfnsym^ir])
    return lib.transpose_sum(ci1new, inplace=True).reshape(fcivec_shape)
Exemplo n.º 20
0
 def check_transformer_cache(self):
     assert (isinstance(self.smult, (int, np.number)))
     neleca, nelecb = _unpack_nelec(self.nelec)
     if isinstance(self.wfnsym, str):
         wfnsym = symm.irrep_name2id(self.mol.groupname, self.wfnsym)
     else:
         wfnsym = self.wfnsym
     if self.transformer is None:
         self.transformer = CSFTransformer(self.norb,
                                           neleca,
                                           nelecb,
                                           self.smult,
                                           orbsym=self.orbsym,
                                           wfnsym=wfnsym)
     else:
         self.transformer._update_spin_cache(self.norb, neleca, nelecb,
                                             self.smult)
         self.transformer._update_symm_cache(self.orbsym)
         self.transformer.wfnsym = wfnsym
Exemplo n.º 21
0
def make_ints(las, ci, idx_root):
    fciboxes = las.fciboxes
    nfrags = len(fciboxes)
    nroots = idx_root.size
    nlas = las.ncas_sub
    nelelas = [sum(_unpack_nelec(ne)) for ne in las.nelecas_sub]
    hopping_index, zerop_index, onep_index = lst_hopping_index(
        fciboxes, nlas, nelelas, idx_root)
    ints = []
    for ifrag in range(nfrags):
        tdmint = LSTDMint1(fciboxes[ifrag], nlas[ifrag], nelelas[ifrag],
                           nroots, idx_root)
        t0 = tdmint.kernel(ci[ifrag], hopping_index[ifrag], zerop_index,
                           onep_index)
        lib.logger.timer(
            las, 'LAS-state TDM12s fragment {} intermediate crunching'.format(
                ifrag), *t0)
        ints.append(tdmint)
    return hopping_index, ints
Exemplo n.º 22
0
def contract_2e(eri, fcivec, norb, nelec, link_index=None, orbsym=None, wfnsym=0):
    if orbsym is None:
        return direct_spin0.contract_2e(eri, fcivec, norb, nelec, link_index)

    eri = ao2mo.restore(4, eri, norb)
    neleca, nelecb = direct_spin1._unpack_nelec(nelec)
    assert(neleca == nelecb)
    link_indexa = direct_spin0._unpack(norb, nelec, link_index)
    na, nlinka = link_indexa.shape[:2]
    eri_irs, rank_eri, irrep_eri = direct_spin1_symm.reorder_eri(eri, norb, orbsym)

    strsa = numpy.asarray(cistring.gen_strings4orblist(range(norb), neleca))
    aidx, link_indexa = direct_spin1_symm.gen_str_irrep(strsa, orbsym, link_indexa,
                                                        rank_eri, irrep_eri)

    Tirrep = ctypes.c_void_p*TOTIRREPS
    linka_ptr = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in link_indexa])
    eri_ptrs = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in eri_irs])
    dimirrep = (ctypes.c_int*TOTIRREPS)(*[x.shape[0] for x in eri_irs])
    fcivec_shape = fcivec.shape
    fcivec = fcivec.reshape((na,na), order='C')
    ci1new = numpy.zeros_like(fcivec)
    nas = (ctypes.c_int*TOTIRREPS)(*[x.size for x in aidx])

    ci0 = []
    ci1 = []
    for ir in range(TOTIRREPS):
        ma, mb = aidx[ir].size, aidx[wfnsym^ir].size
        ci0.append(numpy.zeros((ma,mb)))
        ci1.append(numpy.zeros((ma,mb)))
        if ma > 0 and mb > 0:
            lib.take_2d(fcivec, aidx[ir], aidx[wfnsym^ir], out=ci0[ir])
    ci0_ptrs = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in ci0])
    ci1_ptrs = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in ci1])
    libfci.FCIcontract_2e_symm1(eri_ptrs, ci0_ptrs, ci1_ptrs,
                                ctypes.c_int(norb), nas, nas,
                                ctypes.c_int(nlinka), ctypes.c_int(nlinka),
                                linka_ptr, linka_ptr, dimirrep,
                                ctypes.c_int(wfnsym))
    for ir in range(TOTIRREPS):
        if ci0[ir].size > 0:
            lib.takebak_2d(ci1new, ci1[ir], aidx[ir], aidx[wfnsym^ir])
    return lib.transpose_sum(ci1new, inplace=True).reshape(fcivec_shape)
Exemplo n.º 23
0
def make_rdm1e(fcivec, nsite, nelec):
    '''1-electron density matrix dm_pq = <|p^+ q|>'''
    neleca, nelecb = _unpack_nelec(nelec)
    link_indexa = cistring.gen_linkstr_index(range(nsite), neleca)
    link_indexb = cistring.gen_linkstr_index(range(nsite), nelecb)
    na = cistring.num_strings(nsite, neleca)
    nb = cistring.num_strings(nsite, nelecb)

    rdm1 = numpy.zeros((nsite,nsite))
    ci0 = fcivec.reshape(na,-1)
    for str0, tab in enumerate(link_indexa):
        for a, i, str1, sign in tab:
            rdm1[a,i] += sign * numpy.dot(ci0[str1],ci0[str0])

    ci0 = fcivec.reshape(na,nb,-1)
    for str0, tab in enumerate(link_indexb):
        for a, i, str1, sign in tab:
            rdm1[a,i] += sign * numpy.einsum('ax,ax->', ci0[:,str1],ci0[:,str0])
    return rdm1
Exemplo n.º 24
0
def _guess_nelec_f (fci, norb, nelec, norb_f, h1, h2):
    # Pick electron distribution by the lowest-energy single determinant
    nelec = direct_spin1._unpack_nelec (nelec)
    hdiag = fci.make_hdiag (h1, h2, norb, nelec)
    ndetb = cistring.num_strings (norb, nelec[1])
    addr_dp = np.divmod (np.argmin (hdiag), ndetb)
    str_dp = [cistring.addr2str (norb, n, c) for n,c in zip (nelec, addr_dp)]
    nelec_f = []
    for n in norb_f:
        ndet = 2**n
        c = np.zeros ((ndet, ndet))
        det = np.array ([str_dp[0] % ndet, str_dp[1] % ndet], dtype=np.integer)
        str_dp = [str_dp[0] // ndet, str_dp[1] // ndet]
        ne = [0,0]
        for spin in range (2):
            for iorb in range (n):
                ne[spin] += int (bool ((det[spin] & (1 << iorb))))
        nelec_f.append (ne)
    return nelec_f
Exemplo n.º 25
0
def make_rdm1e(fcivec, nsite, nelec):
    '''1-electron density matrix dm_pq = <|p^+ q|>'''
    neleca, nelecb = _unpack_nelec(nelec)
    link_indexa = cistring.gen_linkstr_index(range(nsite), neleca)
    link_indexb = cistring.gen_linkstr_index(range(nsite), nelecb)
    na = cistring.num_strings(nsite, neleca)
    nb = cistring.num_strings(nsite, nelecb)

    rdm1 = numpy.zeros((nsite,nsite))
    ci0 = fcivec.reshape(na,-1)
    for str0, tab in enumerate(link_indexa):
        for a, i, str1, sign in tab:
            rdm1[a,i] += sign * numpy.dot(ci0[str1],ci0[str0])

    ci0 = fcivec.reshape(na,nb,-1)
    for str0, tab in enumerate(link_indexb):
        for a, i, str1, sign in tab:
            rdm1[a,i] += sign * numpy.einsum('ax,ax->', ci0[:,str1],ci0[:,str0])
    return rdm1
Exemplo n.º 26
0
def ham(las, h1, h2, ci_fr, idx_root, orbsym=None, wfnsym=None):
    mol = las.mol
    norb_f = las.ncas_sub
    nelec_fr = [[
        _unpack_nelec(fcibox._get_nelec(solver, nelecas))
        for solver, ix in zip(fcibox.fcisolvers, idx_root) if ix
    ] for fcibox, nelecas in zip(las.fciboxes, las.nelecas_sub)]
    ci, nelec = ci_outer_product(ci_fr, norb_f, nelec_fr)
    solver = fci.solver(mol).set(orbsym=orbsym, wfnsym=wfnsym)
    norb = sum(norb_f)
    h2eff = solver.absorb_h1e(h1, h2, norb, nelec, 0.5)
    ham_ci = [solver.contract_2e(h2eff, c, norb, nelec) for c in ci]
    s2_ci = [contract_ss(c, norb, nelec) for c in ci]
    ham_eff = np.array([[c.ravel().dot(hc.ravel()) for hc in ham_ci]
                        for c in ci])
    s2_eff = np.array([[c.ravel().dot(s2c.ravel()) for s2c in s2_ci]
                       for c in ci])
    ovlp_eff = np.array([[bra.ravel().dot(ket.ravel()) for ket in ci]
                         for bra in ci])
    return ham_eff, s2_eff, ovlp_eff
Exemplo n.º 27
0
 def _debug_cispace(xci, label):
     xci_norm = [np.dot(c.ravel(), c.ravel()) for c in xci]
     try:
         xci_ss = self.base.fcisolver.states_spin_square(
             xci, self.base.ncas, self.base.nelecas)[0]
     except AttributeError:
         nelec = sum(_unpack_nelec(self.base.nelecas))
         xci_ss = [
             spin_square(x, self.base.ncas,
                         ((nelec + m) // 2, (nelec - m) // 2))[0]
             for x, m in zip(xci, self.spin_states)
         ]
     xci_ss = [x / max(y, 1e-8) for x, y in zip(xci_ss, xci_norm)]
     xci_multip = [np.sqrt(x + .25) - .5 for x in xci_ss]
     for ix, (norm, ss,
              multip) in enumerate(zip(xci_norm, xci_ss, xci_multip)):
         logger.debug(
             self,
             ' State {} {} norm = {:.7e} ; <S^2> = {:.7f} ; 2S+1 = {:.7f}'
             .format(ix, label, norm, ss, multip))
Exemplo n.º 28
0
def pspace(h1e, eri, norb, nelec, hdiag=None, np=400):
    neleca, nelecb = direct_spin1._unpack_nelec(nelec)
    h1e_a = numpy.ascontiguousarray(h1e[0])
    h1e_b = numpy.ascontiguousarray(h1e[1])
    g2e_aa = ao2mo.restore(1, eri[0], norb)
    g2e_ab = ao2mo.restore(1, eri[1], norb)
    g2e_bb = ao2mo.restore(1, eri[2], norb)
    link_indexa = cistring.gen_linkstr_index_trilidx(range(norb), neleca)
    link_indexb = cistring.gen_linkstr_index_trilidx(range(norb), nelecb)
    nb = link_indexb.shape[0]
    if hdiag is None:
        hdiag = make_hdiag(h1e, eri, norb, nelec)
    if hdiag.size < np:
        addr = numpy.arange(hdiag.size)
    else:
        try:
            addr = numpy.argpartition(hdiag, np - 1)[:np]
        except AttributeError:
            addr = numpy.argsort(hdiag)[:np]
    addra = addr // nb
    addrb = addr % nb
    stra = numpy.array([cistring.addr2str(norb, neleca, ia) for ia in addra],
                       dtype=numpy.long)
    strb = numpy.array([cistring.addr2str(norb, nelecb, ib) for ib in addrb],
                       dtype=numpy.long)
    np = len(addr)
    h0 = numpy.zeros((np, np))
    libfci.FCIpspace_h0tril_uhf(h0.ctypes.data_as(ctypes.c_void_p),
                                h1e_a.ctypes.data_as(ctypes.c_void_p),
                                h1e_b.ctypes.data_as(ctypes.c_void_p),
                                g2e_aa.ctypes.data_as(ctypes.c_void_p),
                                g2e_ab.ctypes.data_as(ctypes.c_void_p),
                                g2e_bb.ctypes.data_as(ctypes.c_void_p),
                                stra.ctypes.data_as(ctypes.c_void_p),
                                strb.ctypes.data_as(ctypes.c_void_p),
                                ctypes.c_int(norb), ctypes.c_int(np))

    for i in range(np):
        h0[i, i] = hdiag[addr[i]]
    h0 = lib.hermi_triu(h0)
    return addr, h0
Exemplo n.º 29
0
def las_symm_tuple(las):
    # This really should be much more modular
    # Symmetry tuple: neleca, nelecb, irrep
    statesym = []
    s2_states = []
    for iroot in range(las.nroots):
        neleca = 0
        nelecb = 0
        wfnsym = 0
        s = 0
        m = []
        for fcibox, nelec in zip(las.fciboxes, las.nelecas_sub):
            solver = fcibox.fcisolvers[iroot]
            na, nb = _unpack_nelec(fcibox._get_nelec(solver, nelec))
            neleca += na
            nelecb += nb
            s_frag = (solver.smult - 1) // 2
            s += s_frag * (s_frag + 1)
            m.append((na - nb) // 2)
            fragsym = getattr(solver, 'wfnsym',
                              0) or 0  # in case getattr returns "None"
            if isinstance(fragsym, str):
                fragsym = symm.irrep_name2id(solver.mol.groupname, fragsym)
            assert isinstance(fragsym, (int, np.integer)), '{} {}'.format(
                type(fragsym), fragsym)
            wfnsym ^= fragsym
        s += sum([2 * m1 * m2 for m1, m2 in combinations(m, 2)])
        s2_states.append(s)
        statesym.append((neleca, nelecb, wfnsym))
    lib.logger.info(las, 'Symmetry analysis of LAS states:')
    lib.logger.info(
        las, ' {:2s}  {:>16s}  {:6s}  {:6s}  {:6s}  {:6s}'.format(
            'ix', 'Energy', 'Neleca', 'Nelecb', '<S**2>', 'Wfnsym'))
    for ix, (e, sy, s2) in enumerate(zip(las.e_states, statesym, s2_states)):
        neleca, nelecb, wfnsym = sy
        wfnsym = symm.irrep_id2name(las.mol.groupname, wfnsym)
        lib.logger.info(
            las, ' {:2d}  {:16.10f}  {:6d}  {:6d}  {:6.3f}  {:>6s}'.format(
                ix, e, neleca, nelecb, s2, wfnsym))

    return statesym, np.asarray(s2_states)
Exemplo n.º 30
0
def get_dense_heff (psi, x, h, ifrag, nelec=None):
    uop, norb_f = psi.uop, psi.norb_f
    xconstr, xcc, xci = psi.unpack (x)
    uop.set_uniq_amps_(xcc)
    ci_f = psi.rotate_ci0 (xci)
    h = psi.constr_h (xconstr, h)
    ndet = 2**norb_f[ifrag]
    heff = np.zeros ((ndet,ndet,ndet,ndet), dtype=x.dtype)
    for ideta, idetb, c in psi.gen_frag_basis (ifrag, ci_f=ci_f, 
     nelec=nelec):
        psi.log.debug ("dense heff fragment %d: %d,%d / %d,%d", ifrag, 
            ideta, idetb, ndet, ndet)
        uhuc = uop (c)
        uhuc = psi.contract_h2 (h, uhuc)
        uhuc = uop (uhuc, transpose=True)
        heff[ideta,idetb,:,:] = psi.project_frag (ifrag, uhuc,
            ci0_f=ci_f)
    heff = LASUCCEffectiveHamiltonian (heff)
    if nelec is not None:
        nelec = _unpack_nelec (nelec)
        heff, idx = heff.get_number_block (nelec, nelec)
        return heff, np.squeeze (idx[0])
    return heff
Exemplo n.º 31
0
    def kernel(self, h1e, eri, norb, nelec, ci0=None,
               tol=None, lindep=None, max_cycle=None, max_space=None,
               nroots=None, davidson_only=None, pspace_size=None,
               orbsym=None, wfnsym=None, ecore=0, **kwargs):
        if nroots is None: nroots = self.nroots
        if orbsym is not None:
            self.orbsym, orbsym_bak = orbsym, self.orbsym
        if wfnsym is None:
            wfnsym = self.wfnsym
        if self.verbose >= logger.WARN:
            self.check_sanity()

        nelec = direct_spin1._unpack_nelec(nelec, self.spin)
        wfnsym_bak = self.wfnsym
        self.wfnsym = self.guess_wfnsym(norb, nelec, ci0, wfnsym, **kwargs)
        e, c = direct_spin1.kernel_ms1(self, h1e, eri, norb, nelec, ci0, None,
                                       tol, lindep, max_cycle, max_space, nroots,
                                       davidson_only, pspace_size, ecore=ecore,
                                       **kwargs)
        if orbsym is not None:
            self.orbsym = orbsym_bak
        self.wfnsym = wfnsym_bak
        return e, c
Exemplo n.º 32
0
def roots_make_rdm12s(las, ci_fr, idx_root, si, orbsym=None, wfnsym=None):
    mol = las.mol
    norb_f = las.ncas_sub
    nelec_fr = [[
        _unpack_nelec(fcibox._get_nelec(solver, nelecas))
        for solver, ix in zip(fcibox.fcisolvers, idx_root) if ix
    ] for fcibox, nelecas in zip(las.fciboxes, las.nelecas_sub)]
    ci_r, nelec = ci_outer_product(ci_fr, norb_f, nelec_fr)
    norb = sum(norb_f)
    solver = fci.solver(mol).set(orbsym=orbsym, wfnsym=wfnsym)
    nroots = len(ci_r)
    ci_r = np.tensordot(si.conj().T, np.stack(ci_r, axis=0), axes=1)
    rdm1s = np.zeros((nroots, 2, norb, norb), dtype=ci_r.dtype)
    rdm2s = np.zeros((nroots, 2, norb, norb, 2, norb, norb), dtype=ci_r.dtype)
    for ix, ci in enumerate(ci_r):
        d1s, d2s = solver.make_rdm12s(ci, norb, nelec)
        rdm1s[ix, 0, :, :] = d1s[0]
        rdm1s[ix, 1, :, :] = d1s[1]
        rdm2s[ix, 0, :, :, 0, :, :] = d2s[0]
        rdm2s[ix, 0, :, :, 1, :, :] = d2s[1]
        rdm2s[ix, 1, :, :, 0, :, :] = d2s[1].transpose(2, 3, 0, 1)
        rdm2s[ix, 1, :, :, 1, :, :] = d2s[2]
    return rdm1s, rdm2s
Exemplo n.º 33
0
def contract_ep(g, fcivec, nsite, nelec, nphonon):
    neleca, nelecb = _unpack_nelec(nelec)
    strsa = numpy.asarray(cistring.gen_strings4orblist(range(nsite), neleca))
    strsb = numpy.asarray(cistring.gen_strings4orblist(range(nsite), nelecb))
    cishape = make_shape(nsite, nelec, nphonon)
    na, nb = cishape[:2]
    ci0 = fcivec.reshape(cishape)
    fcinew = numpy.zeros(cishape)

    phonon_cre = numpy.sqrt(numpy.arange(1,nphonon+1))
    for i in range(nsite):
        maska = (strsa & (1<<i)) > 0
        maskb = (strsb & (1<<i)) > 0
        e_part = numpy.zeros((na,nb))
        e_part[maska,:] += 1
        e_part[:,maskb] += 1
        e_part[:] -= float(neleca+nelecb) / nsite
        for ip in range(nphonon):
            slices1 = slices_for_cre(i, nsite, ip)
            slices0 = slices_for    (i, nsite, ip)
            fcinew[slices1] += numpy.einsum('ij...,ij...->ij...', g*phonon_cre[ip]*e_part, ci0[slices0])
            fcinew[slices0] += numpy.einsum('ij...,ij...->ij...', g*phonon_cre[ip]*e_part, ci0[slices1])
    return fcinew.reshape(fcivec.shape)
Exemplo n.º 34
0
 def __init__(self, mc, state=None):
     self.__dict__.update (mc.__dict__)
     nmo = mc.mo_coeff.shape[-1]
     self.ngorb = np.count_nonzero (mc.uniq_var_indices (nmo, mc.ncore, mc.ncas, mc.frozen))
     self.nroots = mc.fcisolver.nroots
     neleca, nelecb = _unpack_nelec (mc.nelecas)
     self.spin_states = [neleca - nelecb,] * self.nroots
     self.na_states = [cistring.num_strings (mc.ncas, neleca),] * self.nroots
     self.nb_states = [cistring.num_strings (mc.ncas, nelecb),] * self.nroots
     if isinstance (mc.fcisolver, StateAverageMixFCISolver):
         self.nroots = p0 = 0
         for solver in mc.fcisolver.fcisolvers:
             self.nroots += solver.nroots
             nea, neb = mc.fcisolver._get_nelec (solver, (neleca, nelecb))
             self.spin_states[p0:self.nroots] = (nea - neb for x in range (solver.nroots))
             self.na_states[p0:self.nroots] = (cistring.num_strings (mc.ncas, nea) for x in range (solver.nroots))
             self.nb_states[p0:self.nroots] = (cistring.num_strings (mc.ncas, neb) for x in range (solver.nroots))
             p0 = self.nroots
     self.nci = sum ([na * nb for na, nb in zip (self.na_states, self.nb_states)])
     if state is not None:
         self.state = state
     elif hasattr (mc, 'nuc_grad_state'):
         self.state = mc.nuc_grad_state
     else:
         self.state = None
     self.eris = None
     self.weights = np.array ([1])
     try:
         self.e_states = np.asarray (mc.e_states)
     except AttributeError as e:
         self.e_states = np.asarray (mc.e_tot)
     if isinstance (mc, StateAverageMCSCFSolver):
         self.weights = np.asarray (mc.weights)
     assert (len (self.weights) == self.nroots), '{} {} {}'.format (mc.fcisolver.__class__, self.weights, self.nroots)
     lagrange.Gradients.__init__(self, mc, self.ngorb+self.nci)
     self.max_cycle = mc.max_cycle_macro
Exemplo n.º 35
0
def make_stdm12s(las, ci_fr, idx_root, orbsym=None, wfnsym=None):
    mol = las.mol
    norb_f = las.ncas_sub
    nelec_fr = [[
        _unpack_nelec(fcibox._get_nelec(solver, nelecas))
        for solver, ix in zip(fcibox.fcisolvers, idx_root) if ix
    ] for fcibox, nelecas in zip(las.fciboxes, las.nelecas_sub)]
    ci_r, nelec = ci_outer_product(ci_fr, norb_f, nelec_fr)
    norb = sum(norb_f)
    solver = fci.solver(mol).set(orbsym=orbsym, wfnsym=wfnsym)
    nroots = len(ci_r)
    stdm1s = np.zeros((nroots, nroots, 2, norb, norb),
                      dtype=ci_r[0].dtype).transpose(0, 2, 3, 4, 1)
    stdm2s = np.zeros((nroots, nroots, 2, norb, norb, 2, norb, norb),
                      dtype=ci_r[0].dtype).transpose(0, 2, 3, 4, 5, 6, 7, 1)
    for i, ci in enumerate(ci_r):
        rdm1s, rdm2s = solver.make_rdm12s(ci, norb, nelec)
        stdm1s[i, 0, :, :, i] = rdm1s[0]
        stdm1s[i, 1, :, :, i] = rdm1s[1]
        stdm2s[i, 0, :, :, 0, :, :, i] = rdm2s[0]
        stdm2s[i, 0, :, :, 1, :, :, i] = rdm2s[1]
        stdm2s[i, 1, :, :, 0, :, :, i] = rdm2s[1].transpose(2, 3, 0, 1)
        stdm2s[i, 1, :, :, 1, :, :, i] = rdm2s[2]
    for (i, ci_bra), (j, ci_ket) in combinations(enumerate(ci_r), 2):
        tdm1s, tdm2s = solver.trans_rdm12s(ci_bra, ci_ket, norb, nelec)
        # Transpose for 1TDM is backwards because of stupid PySCF convention
        stdm1s[i, 0, :, :, j] = tdm1s[0].T
        stdm1s[i, 1, :, :, j] = tdm1s[1].T
        stdm1s[j, 0, :, :, i] = tdm1s[0]
        stdm1s[j, 1, :, :, i] = tdm1s[1]
        for spin, tdm2 in enumerate(tdm2s):
            p = spin // 2
            q = spin % 2
            stdm2s[i, p, :, :, q, :, :, j] = tdm2
            stdm2s[j, p, :, :, q, :, :, i] = tdm2.transpose(1, 0, 3, 2)
    return stdm1s, stdm2s
Exemplo n.º 36
0
def contract_ep(g, fcivec, nsite, nelec, nphonon):
    neleca, nelecb = _unpack_nelec(nelec)
    strsa = numpy.asarray(cistring.gen_strings4orblist(range(nsite), neleca))
    strsb = numpy.asarray(cistring.gen_strings4orblist(range(nsite), nelecb))
    cishape = make_shape(nsite, nelec, nphonon)
    na, nb = cishape[:2]
    ci0 = fcivec.reshape(cishape)
    fcinew = numpy.zeros(cishape)
    nbar = float(neleca+nelecb) / nsite

    phonon_cre = numpy.sqrt(numpy.arange(1,nphonon+1))
    for i in range(nsite):
        maska = (strsa & (1<<i)) > 0
        maskb = (strsb & (1<<i)) > 0
        e_part = numpy.zeros((na,nb))
        e_part[maska,:] += 1
        e_part[:,maskb] += 1
        e_part[:] -= float(neleca+nelecb) / nsite
        for ip in range(nphonon):
            slices1 = slices_for_cre(i, nsite, ip)
            slices0 = slices_for    (i, nsite, ip)
            fcinew[slices1] += numpy.einsum('ij...,ij...->ij...', g*phonon_cre[ip]*e_part, ci0[slices0])
            fcinew[slices0] += numpy.einsum('ij...,ij...->ij...', g*phonon_cre[ip]*e_part, ci0[slices1])
    return fcinew.reshape(fcivec.shape)
Exemplo n.º 37
0
def kernel(myci, h1e, eri, norb, nelec, ci0=None,
           tol=None, lindep=None, max_cycle=None, max_space=None,
           nroots=None, davidson_only=None, 
           max_memory=None, verbose=None, ecore=0, **kwargs):

    if tol is None: tol = myci.conv_tol
    if lindep is None: lindep = myci.lindep
    if max_cycle is None: max_cycle = myci.max_cycle
    if max_space is None: max_space = myci.max_space
    if max_memory is None: max_memory = myci.max_memory
    if nroots is None: nroots = myci.nroots
    if verbose is None: verbose = logger.Logger(myci.stdout, myci.verbose)
    tol_residual = None #getattr(fci, 'conv_tol_residual', None)
    myci.dump_flags()

    nelec = direct_spin1._unpack_nelec(nelec, myci.spin)
    eri = ao2mo.restore(1, eri, norb)
    eri = eri.ravel()

    logger.info(myci, 'CI in the selected space')
    # Initial guess
    if ci0 is None:
        t_start = time.time()
        if (myci.model == 'fci'):
            dets = cistring.gen_full_space(range(norb), nelec) 
            ndets = dets.shape[0]
            if (myci.noise):
                numpy.random.seed()
                ci0 = [cistring.as_SCIvector(numpy.random.uniform(low=1e-3,high=1e-2,size=ndets), dets)]
                ci0[0][0] = 0.99
                ci0[0] *= 1./numpy.linalg.norm(ci0[0])
            else:
                ci0 = [cistring.as_SCIvector(numpy.zeros(ndets), dets)]
                ci0[0][0] = 1.0
        else:
            raise RuntimeError('''Unknown CI model''')
        t_current = time.time() - t_start
        #logger.info(myci, 'Initial CI vector = %s', ci0[0][:])
        logger.info(myci, 'Timing for generating strings: %10.3f', t_current)
    else:
        assert(nroots == len(ci0))

    def hop(c):
        hc = myci.contract_2e((h1e, eri), cistring.as_SCIvector(c, ci_strs), norb, nelec, hdiag)
        return hc.ravel()
    precond = lambda x, e, *args: x/(hdiag-e+myci.level_shift)

    ci_strs = ci0[0]._strs
    logger.info(myci, 'Number of CI configurations: %d', ci_strs.shape[0])
    t_start = time.time()
    hdiag = myci.make_hdiag(h1e, eri, ci_strs, norb, nelec)
    t_current = time.time() - t_start
    logger.info(myci, 'Timing for diagonal hamiltonian: %10.3f', t_current)

    t_start = time.time()
    with lib.with_omp_threads(myci.threads):
        #e, c = myci.eig(hop, ci0, precond, tol=tol, lindep=lindep,
        #                max_cycle=max_cycle, max_space=max_space, nroots=nroots,
        #                max_memory=max_memory, verbose=verbose, **kwargs)
        #
        e, c = myci.eig(hop, ci0, precond, tol=tol, lindep=lindep,
                       max_cycle=max_cycle, max_space=max_space, nroots=nroots,
                       max_memory=max_memory, verbose=verbose, follow_state=True,
                       tol_residual=tol_residual, **kwargs)
    t_current = time.time() - t_start
    logger.info(myci, 'Timing for solving the eigenvalue problem: %10.3f', t_current)
    if not isinstance(c, (tuple, list)):
        c = [c]
        e = [e]
    logger.info(myci, 'CI  E = %s', numpy.array(e)+ecore)
    #myci.eci = e+ecore
    #myci.ci = e
    #for i in range(nroots):
    #    norm = numpy.einsum('i,i->', ci0[i][:], ci0[i][:])
    #    s = myci.spin_square(ci0[i], norb, nelec)
    #    logger.info(myci, 'E(CI) = %10.5f, CI E = %10.5f, Norm = %1.3f, Spin = %s'\
    #    % (numpy.array(e[i]), numpy.array(e[i])+ecore, norm, s))
    #    #logger.info(myci, 'CI E = %s', numpy.array(e)+ecore)
    #    #logger.info(mc,"* Norm info for state %d : %s" % (i,norm))    
    #    #logger.info(mc,"* Spin info for state %d : %s" % (i,s))    

    return (numpy.array(e)+ecore), [cistring.as_SCIvector(ci, ci_strs) for ci in c]
Exemplo n.º 38
0
 def debug_lagrange(self,
                    Lvec,
                    bvec,
                    Aop,
                    Adiag,
                    iroot=None,
                    mo=None,
                    ci=None,
                    **kwargs):
     if iroot is None: iroot = self.iroot
     if mo is None: mo = self.base.mo_coeff
     if ci is None: ci = self.base.ci
     lib.logger.info(
         self,
         '{} gradient: iroot = {}'.format(self.base.__class__.__name__,
                                          iroot))
     ngorb = self.ngorb
     nci = self.nci
     nroots = self.nroots
     ndet = nci // nroots
     ncore = self.base.ncore
     ncas = self.base.ncas
     nelecas = self.base.nelecas
     nocc = ncore + ncas
     nlag = self.nlag
     ci = np.asarray(self.base.ci).reshape(nroots, -1)
     err = Aop(Lvec) + bvec
     eorb = self.base.unpack_uniq_var(err[:ngorb])
     eci = err[ngorb:].reshape(nroots, -1)
     borb = self.base.unpack_uniq_var(bvec[:ngorb])
     bci = bvec[ngorb:].reshape(nroots, -1)
     Lorb = self.base.unpack_uniq_var(Lvec[:ngorb])
     Lci = Lvec[ngorb:].reshape(nroots, ndet)
     Aci = Adiag[ngorb:].reshape(nroots, ndet)
     Lci_ci_ovlp = (
         np.asarray(ci).reshape(nroots, -1).conjugate() @ Lci.T).T
     Lci_Lci_ovlp = (Lci.conjugate() @ Lci.T).T
     eci_ci_ovlp = (
         np.asarray(ci).reshape(nroots, -1).conjugate() @ eci.T).T
     bci_ci_ovlp = (
         np.asarray(ci).reshape(nroots, -1).conjugate() @ bci.T).T
     ci_ci_ovlp = ci.conjugate() @ ci.T
     lib.logger.debug(
         self,
         "{} gradient RHS, inactive-active orbital rotations:\n{}".format(
             self.base.__class__.__name__, borb[:ncore, ncore:nocc]))
     lib.logger.debug(
         self,
         "{} gradient RHS, inactive-external orbital rotations:\n{}".format(
             self.base.__class__.__name__, borb[:ncore, nocc:]))
     lib.logger.debug(
         self,
         "{} gradient RHS, active-external orbital rotations:\n{}".format(
             self.base.__class__.__name__, borb[ncore:nocc, nocc:]))
     lib.logger.debug(
         self,
         "{} gradient residual, inactive-active orbital rotations:\n{}".
         format(self.base.__class__.__name__, eorb[:ncore, ncore:nocc]))
     lib.logger.debug(
         self,
         "{} gradient residual, inactive-external orbital rotations:\n{}".
         format(self.base.__class__.__name__, eorb[:ncore, nocc:]))
     lib.logger.debug(
         self,
         "{} gradient residual, active-external orbital rotations:\n{}".
         format(self.base.__class__.__name__, eorb[ncore:nocc, nocc:]))
     lib.logger.debug(
         self,
         "{} gradient Lagrange factor, inactive-active orbital rotations:\n{}"
         .format(self.base.__class__.__name__, Lorb[:ncore, ncore:nocc]))
     lib.logger.debug(
         self,
         "{} gradient Lagrange factor, inactive-external orbital rotations:\n{}"
         .format(self.base.__class__.__name__, Lorb[:ncore, nocc:]))
     lib.logger.debug(
         self,
         "{} gradient Lagrange factor, active-external orbital rotations:\n{}"
         .format(self.base.__class__.__name__, Lorb[ncore:nocc, nocc:]))
     '''
     lib.logger.debug (self, "{} gradient RHS, inactive-inactive orbital rotations (redundant!):\n{}".format (
         self.base.__class__.__name__, borb[:ncore,:ncore]))
     lib.logger.debug (self, "{} gradient RHS, active-active orbital rotations (redundant!):\n{}".format (
         self.base.__class__.__name__, borb[ncore:nocc,ncore:nocc]))
     lib.logger.debug (self, "{} gradient RHS, external-external orbital rotations (redundant!):\n{}".format (
         self.base.__class__.__name__, borb[nocc:,nocc:]))
     lib.logger.debug (self, "{} gradient Lagrange factor, inactive-inactive orbital rotations (redundant!):\n{}".format (
         self.base.__class__.__name__, Lorb[:ncore,:ncore]))
     lib.logger.debug (self, "{} gradient Lagrange factor, active-active orbital rotations (redundant!):\n{}".format (
         self.base.__class__.__name__, Lorb[ncore:nocc,ncore:nocc]))
     lib.logger.debug (self, "{} gradient Lagrange factor, external-external orbital rotations (redundant!):\n{}".format (
         self.base.__class__.__name__, Lorb[nocc:,nocc:]))
     '''
     lib.logger.debug(
         self,
         "{} gradient Lagrange factor, CI part overlap with true CI SA space:\n{}"
         .format(self.base.__class__.__name__, Lci_ci_ovlp))
     lib.logger.debug(
         self,
         "{} gradient Lagrange factor, CI part self overlap matrix:\n{}".
         format(self.base.__class__.__name__, Lci_Lci_ovlp))
     lib.logger.debug(
         self,
         "{} gradient Lagrange factor, CI vector self overlap matrix:\n{}".
         format(self.base.__class__.__name__, ci_ci_ovlp))
     lib.logger.debug(
         self,
         "{} gradient Lagrange factor, CI part response overlap with SA space:\n{}"
         .format(self.base.__class__.__name__, bci_ci_ovlp))
     lib.logger.debug(
         self,
         "{} gradient Lagrange factor, CI part residual overlap with SA space:\n{}"
         .format(self.base.__class__.__name__, eci_ci_ovlp))
     neleca, nelecb = _unpack_nelec(nelecas)
     spin = neleca - nelecb + 1
     csf = CSFTransformer(ncas, neleca, nelecb, spin)
     ecsf = csf.vec_det2csf(eci, normalize=False, order='C')
     err_norm_det = linalg.norm(err)
     err_norm_csf = linalg.norm(np.append(eorb, ecsf.ravel()))
     lib.logger.debug(
         self,
         "{} gradient: determinant residual = {}, CSF residual = {}".format(
             self.base.__class__.__name__, err_norm_det, err_norm_csf))
     ci_lbls, ci_csf = csf.printable_largest_csf(ci,
                                                 10,
                                                 isdet=True,
                                                 normalize=True,
                                                 order='C')
     bci_lbls, bci_csf = csf.printable_largest_csf(bci,
                                                   10,
                                                   isdet=True,
                                                   normalize=False,
                                                   order='C')
     eci_lbls, eci_csf = csf.printable_largest_csf(eci,
                                                   10,
                                                   isdet=True,
                                                   normalize=False,
                                                   order='C')
     Lci_lbls, Lci_csf = csf.printable_largest_csf(Lci,
                                                   10,
                                                   isdet=True,
                                                   normalize=False,
                                                   order='C')
     Aci_lbls, Aci_csf = csf.printable_largest_csf(Aci,
                                                   10,
                                                   isdet=True,
                                                   normalize=False,
                                                   order='C')
     ncsf = bci_csf.shape[1]
     for iroot in range(self.nroots):
         lib.logger.debug(
             self,
             "{} gradient Lagrange factor, CI part root {} spin square: {}".
             format(self.base.__class__.__name__, iroot,
                    spin_square0(Lci[iroot], ncas, nelecas)))
         lib.logger.debug(self, "Base CI vector")
         for icsf in range(ncsf):
             lib.logger.debug(
                 self, '{} {}'.format(ci_lbls[iroot, icsf], ci_csf[iroot,
                                                                   icsf]))
         lib.logger.debug(self, "CI gradient:")
         for icsf in range(ncsf):
             lib.logger.debug(
                 self, '{} {}'.format(bci_lbls[iroot, icsf], bci_csf[iroot,
                                                                     icsf]))
         lib.logger.debug(self, "CI residual:")
         for icsf in range(ncsf):
             lib.logger.debug(
                 self, '{} {}'.format(eci_lbls[iroot, icsf], eci_csf[iroot,
                                                                     icsf]))
         lib.logger.debug(self, "CI Lagrange vector:")
         for icsf in range(ncsf):
             lib.logger.debug(
                 self, '{} {}'.format(Lci_lbls[iroot, icsf], Lci_csf[iroot,
                                                                     icsf]))
         lib.logger.debug(self, "Diagonal of Hessian matrix CI part:")
         for icsf in range(ncsf):
             lib.logger.debug(
                 self, '{} {}'.format(Aci_lbls[iroot, icsf], Aci_csf[iroot,
                                                                     icsf]))
     '''
Exemplo n.º 39
0
def kernel(fci, h1e, eri, norb, nelec, smult=None, idx_sym=None, ci0=None,
           tol=None, lindep=None, max_cycle=None, max_space=None,
           nroots=None, davidson_only=None, pspace_size=None, max_memory=None,
           orbsym=None, wfnsym=None, ecore=0, transformer=None, **kwargs):
    t0 = (time.process_time (), time.time ())
    if 'verbose' in kwargs:
        verbose = kwargs['verbose']
        kwargs.pop ('verbose')
    else: verbose = lib.logger.Logger (stdout=fci.stdout, verbose=fci.verbose)
    if (isinstance (verbose, lib.logger.Logger) and verbose.verbose >= lib.logger.WARN) or (isinstance (verbose, int) and verbose >= lib.logger.WARN):
        fci.check_sanity()
    if nroots is None: nroots = fci.nroots
    if pspace_size is None: pspace_size = fci.pspace_size
    if davidson_only is None: davidson_only = fci.davidson_only
    if transformer is None: transformer = fci.transformer
    nelec = _unpack_nelec(nelec, fci.spin)
    neleca, nelecb = nelec
    t0 = lib.logger.timer (fci, "csf.kernel: throat-clearing", *t0)
    hdiag_det = fci.make_hdiag (h1e, eri, norb, nelec)
    t0 = lib.logger.timer (fci, "csf.kernel: hdiag_det", *t0)
    hdiag_csf = fci.make_hdiag_csf (h1e, eri, norb, nelec, hdiag_det=hdiag_det)
    t0 = lib.logger.timer (fci, "csf.kernel: hdiag_csf", *t0)
    ncsf_all = count_all_csfs (norb, neleca, nelecb, smult)
    if idx_sym is None:
        ncsf_sym = ncsf_all
    else:
        ncsf_sym = np.count_nonzero (idx_sym)
    nroots = min(ncsf_sym, nroots)
    if nroots is not None:
        assert (ncsf_sym >= nroots), "Can't find {} roots among only {} CSFs".format (nroots, ncsf_sym)
    link_indexa, link_indexb = _unpack(norb, nelec, None)
    na = link_indexa.shape[0]
    nb = link_indexb.shape[0]

    t0 = lib.logger.timer (fci, "csf.kernel: throat-clearing", *t0)
    addr, h0 = fci.pspace(h1e, eri, norb, nelec, idx_sym=idx_sym, hdiag_det=hdiag_det, hdiag_csf=hdiag_csf, npsp=max(pspace_size,nroots))
    lib.logger.debug (fci, 'csf.kernel: error of hdiag_csf: %s', np.amax (np.abs (hdiag_csf[addr]-np.diag (h0))))
    t0 = lib.logger.timer (fci, "csf.kernel: make pspace", *t0)
    if pspace_size > 0:
        pw, pv = fci.eig (h0)
    else:
        pw = pv = None

    if pspace_size >= ncsf_sym and not davidson_only:
        if ncsf_sym == 1:
            civec = transformer.vec_csf2det (pv[:,0].reshape (1,1))
            return pw[0]+ecore, civec
        elif nroots > 1:
            civec = np.empty((nroots,ncsf_all))
            civec[:,addr] = pv[:,:nroots].T
            civec = transformer.vec_csf2det (civec)
            return pw[:nroots]+ecore, [c.reshape(na,nb) for c in civec]
        elif abs(pw[0]-pw[1]) > 1e-12:
            civec = np.empty((ncsf_all))
            civec[addr] = pv[:,0]
            civec = transformer.vec_csf2det (civec)
            return pw[0]+ecore, civec.reshape(na,nb)

    t0 = lib.logger.timer (fci, "csf.kernel: throat-clearing", *t0)
    if idx_sym is None:
        precond = fci.make_precond(hdiag_csf, pw, pv, addr)
    else:
        addr_bool = np.zeros (ncsf_all, dtype=np.bool)
        addr_bool[addr] = True
        precond = fci.make_precond(hdiag_csf[idx_sym], pw, pv, addr_bool[idx_sym])
    t0 = lib.logger.timer (fci, "csf.kernel: make preconditioner", *t0)
    '''
    fci.eci, fci.ci = \
            kernel_ms1(fci, h1e, eri, norb, nelec, ci0, None,
                       tol, lindep, max_cycle, max_space, nroots,
                       davidson_only, pspace_size, ecore=ecore, **kwargs)
    '''
    h2e = fci.absorb_h1e(h1e, eri, norb, nelec, .5)
    t0 = lib.logger.timer (fci, "csf.kernel: h2e", *t0)
    def hop(x):
        x_det = transformer.vec_csf2det (x)
        hx = fci.contract_2e(h2e, x_det, norb, nelec, (link_indexa,link_indexb))
        return transformer.vec_det2csf (hx, normalize=False).ravel ()

    t0 = lib.logger.timer (fci, "csf.kernel: make hop", *t0)
    if ci0 is None:
        if hasattr(fci, 'get_init_guess'):
            def ci0 ():
                return transformer.vec_det2csf (fci.get_init_guess(norb, nelec, nroots, hdiag_csf))
                
                    
        else:
            def ci0():  # lazy initialization to reduce memory footprint
                x0 = []
                for i in range(nroots):
                    x = np.zeros(ncsf_sym)
                    x[addr[i]] = 1
                    x0.append(x)
                return x0
    else:
        if isinstance(ci0, np.ndarray) and ci0.size == na*nb:
            ci0 = [transformer.vec_det2csf (ci0.ravel ())]
        else:
            nrow = len (ci0)
            ci0 = np.asarray (ci0).reshape (nrow, -1, order='C')
            ci0 = np.ascontiguousarray (ci0)
            ci0 = transformer.vec_det2csf (ci0.ravel ())
            ci0 = [c for c in ci0.reshape (nrow, -1)]
    t0 = lib.logger.timer (fci, "csf.kernel: ci0 handling", *t0)

    if tol is None: tol = fci.conv_tol
    if lindep is None: lindep = fci.lindep
    if max_cycle is None: max_cycle = fci.max_cycle
    if max_space is None: max_space = fci.max_space
    if max_memory is None: max_memory = fci.max_memory
    tol_residual = getattr(fci, 'conv_tol_residual', None)

    #with lib.with_omp_threads(fci.threads):
        #e, c = lib.davidson(hop, ci0, precond, tol=fci.conv_tol, lindep=fci.lindep)
    e, c = fci.eig(hop, ci0, precond, tol=tol, lindep=lindep,
                       max_cycle=max_cycle, max_space=max_space, nroots=nroots,
                       max_memory=max_memory, verbose=verbose, follow_state=True,
                       tol_residual=tol_residual, **kwargs)
    t0 = lib.logger.timer (fci, "csf.kernel: running fci.eig", *t0)
    c = transformer.vec_csf2det (c, order='C')
    t0 = lib.logger.timer (fci, "csf.kernel: transforming final ci vector", *t0)
    if nroots > 1:
        return e+ecore, [ci.reshape(na,nb) for ci in c]
    else:
        return e+ecore, c.reshape(na,nb)
Exemplo n.º 40
0
 def trans_rdm1(self, cibra, ciket, norb, nelec, link_index=None):
     nelec = direct_spin1._unpack_nelec(nelec, self.spin)
     cibra = _as_SCIvector_if_not(cibra, self._strs)
     ciket = _as_SCIvector_if_not(ciket, self._strs)
     return trans_rdm1(cibra, ciket, norb, nelec, link_index)
Exemplo n.º 41
0
 def large_ci(self, civec_strs, norb, nelec, tol=.1):
     nelec = direct_spin1._unpack_nelec(nelec, self.spin)
     ci, _, (strsa, strsb) = _unpack(civec_strs, nelec, self._strs)
     return [(ci[i,j], bin(strsa[i]), bin(strsb[j]))
             for i,j in numpy.argwhere(abs(ci) > tol)]
Exemplo n.º 42
0
 def make_rdm1(self, civec_strs, norb, nelec, link_index=None):
     nelec = direct_spin1._unpack_nelec(nelec, self.spin)
     rdm1a, rdm1b = self.make_rdm1s(civec_strs, norb, nelec, link_index)
     return rdm1a + rdm1b
Exemplo n.º 43
0
def make_shape(nsite, nelec, nphonon):
    neleca, nelecb = _unpack_nelec(nelec)
    na = cistring.num_strings(nsite, neleca)
    nb = cistring.num_strings(nsite, nelecb)
    return (na, nb) + (nphonon + 1, ) * nsite
Exemplo n.º 44
0
 def make_rdm2(self, civec_strs, norb, nelec, link_index=None, **kwargs):
     nelec = direct_spin1._unpack_nelec(nelec, self.spin)
     civec_strs = _as_SCIvector_if_not(civec_strs, self._strs)
     return make_rdm2(civec_strs, norb, nelec, link_index)
Exemplo n.º 45
0
def get_init_guess(norb, nelec, nroots, hdiag, orbsym, wfnsym=0):
    neleca, nelecb = direct_spin1._unpack_nelec(nelec)
    strsa = numpy.asarray(cistring.gen_strings4orblist(range(norb), neleca))
    strsb = numpy.asarray(cistring.gen_strings4orblist(range(norb), nelecb))
    return _get_init_guess(strsa, strsb, nroots, hdiag, orbsym, wfnsym)
Exemplo n.º 46
0
 def trans_rdm1(self, cibra, ciket, norb, nelec, link_index=None):
     nelec = direct_spin1._unpack_nelec(nelec, self.spin)
     cibra = _as_SCIvector_if_not(cibra, self._strs)
     ciket = _as_SCIvector_if_not(ciket, self._strs)
     return trans_rdm1(cibra, ciket, norb, nelec, link_index)
Exemplo n.º 47
0
def kernel_float_space(myci, h1e, eri, norb, nelec, ci0=None,
                       tol=None, lindep=None, max_cycle=None, max_space=None,
                       nroots=None, davidson_only=None, max_iter=None,
                       max_memory=None, verbose=None, ecore=0, return_integrals=False, 
                       eri_sorted=None, jk=None, jk_sorted=None, **kwargs):
    if verbose is None:
        log = logger.Logger(myci.stdout, myci.verbose)
    elif isinstance(verbose, logger.Logger):
        log = verbose
    else:
        log = logger.Logger(myci.stdout, verbose)
    if tol is None: tol = myci.conv_tol
    if lindep is None: lindep = myci.lindep
    if max_cycle is None: max_cycle = myci.max_cycle
    if max_space is None: max_space = myci.max_space
    if max_memory is None: max_memory = myci.max_memory
    if nroots is None: nroots = myci.nroots
    if max_iter is None: max_iter = myci.max_iter
    if myci.verbose >= logger.WARN:
        myci.check_sanity()

    log.info('\nStarting heat-bath CI algorithm...\n')
    log.info('Selection threshold:                  %8.5e',    myci.select_cutoff)
    log.info('CI coefficient cutoff:                %8.5e',    myci.ci_coeff_cutoff)
    log.info('Energy convergence tolerance:         %8.5e',    tol)
    log.info('Number of determinants tolerance:     %8.5e',    myci.conv_ndet_tol)
    log.info('Number of electrons:                  %s',       nelec)
    log.info('Number of orbitals:                   %3d',      norb)
    log.info('Number of roots:                      %3d',    nroots)

    nelec = direct_spin1._unpack_nelec(nelec, myci.spin)
    eri = ao2mo.restore(1, eri, norb)

    # Avoid resorting the integrals by storing them in memory
    eri = eri.ravel()

    if eri_sorted is None and jk is None and jk_sorted is None:
        log.debug("\nSorting two-electron integrals...")
        t_start = time.time()
        eri_sorted = abs(eri).argsort()[::-1]
        jk = eri.reshape([norb]*4)
        jk = jk - jk.transpose(2,1,0,3)
        jk = jk.ravel()
        jk_sorted = abs(jk).argsort()[::-1]
        t_current = time.time() - t_start
        log.debug('Timing for sorting the integrals: %10.3f', t_current)

    # Initial guess
    if ci0 is None:
        hf_str = numpy.hstack([orblst2str(range(nelec[0]), norb), orblst2str(range(nelec[1]), norb)]).reshape(1,-1)
        ci0 = [as_SCIvector(numpy.ones(1), hf_str)]
    else:
        assert(nroots == len(ci0))

    ci0 = myci.enlarge_space(ci0, h1e, eri, jk, eri_sorted, jk_sorted, norb, nelec)

    def hop(c):
        hc = myci.contract_2e((h1e, eri), as_SCIvector(c, ci_strs), norb, nelec, hdiag)
        return hc.ravel()
    precond = lambda x, e, *args: x/(hdiag-e+myci.level_shift)

    e_last = 0
    float_tol = 3e-4
    conv = False
    for icycle in range(max_iter):
        ci_strs = ci0[0]._strs
        float_tol = max(float_tol*.3, tol*1e2)
        log.info('\nMacroiteration %d', icycle)
        log.info('Number of CI configurations: %d', ci_strs.shape[0])
        hdiag = myci.make_hdiag(h1e, eri, ci_strs, norb, nelec)
        t_start = time.time()
        e, ci0 = myci.eig(hop, ci0, precond, tol=float_tol, lindep=lindep,
                          max_cycle=max_cycle, max_space=max_space, nroots=nroots,
                          max_memory=max_memory, verbose=log, **kwargs)
        if not isinstance(ci0, (tuple, list)):
            ci0 = [ci0]
            e = [e]
        t_current = time.time() - t_start
        log.debug('Timing for solving the eigenvalue problem: %10.3f', t_current)
        ci0 = [as_SCIvector(c, ci_strs) for c in ci0]
        de, e_last = min(e)-e_last, min(e)
        log.info('Cycle %d  E = %s  dE = %.8g', icycle, numpy.array(e)+ecore, de)

        if abs(de) < tol*1e3:
            conv = True
            break

        last_ci0_size = float(len(ci_strs))
        t_start = time.time()
        ci0 = myci.enlarge_space(ci0, h1e, eri, jk, eri_sorted, jk_sorted, norb, nelec)
        t_current = time.time() - t_start
        log.debug('Timing for selecting configurations: %10.3f', t_current)
        if (((1 - myci.conv_ndet_tol) < len(ci0[0]._strs)/last_ci0_size < (1 + myci.conv_ndet_tol))):
            conv = True
            break

    ci_strs = ci0[0]._strs
    log.info('\nExtra CI in the final selected space')
    log.info('Number of CI configurations: %d', ci_strs.shape[0])
    hdiag = myci.make_hdiag(h1e, eri, ci_strs, norb, nelec)
    e, c = myci.eig(hop, ci0, precond, tol=tol, lindep=lindep,
                    max_cycle=max_cycle, max_space=max_space, nroots=nroots,
                    max_memory=max_memory, verbose=log, **kwargs)
    if not isinstance(c, (tuple, list)):
        c = [c]
        e = [e]
    log.info('\nSelected CI  E = %s', numpy.array(e)+ecore)

    if (return_integrals):
        return (numpy.array(e)+ecore), [as_SCIvector(ci, ci_strs) for ci in c], eri_sorted, jk, jk_sorted
    else:
        return (numpy.array(e)+ecore), [as_SCIvector(ci, ci_strs) for ci in c]
Exemplo n.º 48
0
def contract_2e(eri,
                fcivec,
                norb,
                nelec,
                link_index=None,
                orbsym=None,
                wfnsym=0):
    if orbsym is None:
        return direct_spin1.contract_2e(eri, fcivec, norb, nelec, link_index)

    eri = ao2mo.restore(4, eri, norb)
    neleca, nelecb = direct_spin1._unpack_nelec(nelec)
    link_indexa, link_indexb = direct_spin1._unpack(norb, nelec, link_index)
    na, nlinka = link_indexa.shape[:2]
    nb, nlinkb = link_indexb.shape[:2]
    eri_irs, rank_eri, irrep_eri = reorder_eri(eri, norb, orbsym)

    strsa = cistring.gen_strings4orblist(range(norb), neleca)
    aidx, link_indexa = gen_str_irrep(strsa, orbsym, link_indexa, rank_eri,
                                      irrep_eri)
    if neleca == nelecb:
        bidx, link_indexb = aidx, link_indexa
    else:
        strsb = cistring.gen_strings4orblist(range(norb), nelecb)
        bidx, link_indexb = gen_str_irrep(strsb, orbsym, link_indexb, rank_eri,
                                          irrep_eri)

    Tirrep = ctypes.c_void_p * TOTIRREPS
    linka_ptr = Tirrep(
        *[x.ctypes.data_as(ctypes.c_void_p) for x in link_indexa])
    linkb_ptr = Tirrep(
        *[x.ctypes.data_as(ctypes.c_void_p) for x in link_indexb])
    eri_ptrs = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in eri_irs])
    dimirrep = (ctypes.c_int * TOTIRREPS)(*[x.shape[0] for x in eri_irs])
    fcivec_shape = fcivec.shape
    fcivec = fcivec.reshape((na, nb), order='C')
    ci1new = numpy.zeros_like(fcivec)
    nas = (ctypes.c_int * TOTIRREPS)(*[x.size for x in aidx])
    nbs = (ctypes.c_int * TOTIRREPS)(*[x.size for x in bidx])

    # aa, ab
    ci0 = []
    ci1 = []
    for ir in range(TOTIRREPS):
        ma, mb = aidx[ir].size, bidx[wfnsym ^ ir].size
        ci0.append(numpy.zeros((ma, mb)))
        ci1.append(numpy.zeros((ma, mb)))
        if ma > 0 and mb > 0:
            lib.take_2d(fcivec, aidx[ir], bidx[wfnsym ^ ir], out=ci0[ir])
    ci0_ptrs = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in ci0])
    ci1_ptrs = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in ci1])
    libfci.FCIcontract_2e_symm1(eri_ptrs, ci0_ptrs, ci1_ptrs,
                                ctypes.c_int(norb), nas, nbs,
                                ctypes.c_int(nlinka), ctypes.c_int(nlinkb),
                                linka_ptr, linkb_ptr, dimirrep,
                                ctypes.c_int(wfnsym))
    for ir in range(TOTIRREPS):
        if ci0[ir].size > 0:
            lib.takebak_2d(ci1new, ci1[ir], aidx[ir], bidx[wfnsym ^ ir])


# bb, ba
    ci0T = []
    for ir in range(TOTIRREPS):
        mb, ma = bidx[ir].size, aidx[wfnsym ^ ir].size
        ci0T.append(numpy.zeros((mb, ma)))
        if ma > 0 and mb > 0:
            lib.transpose(ci0[wfnsym ^ ir], out=ci0T[ir])
    ci0, ci0T = ci0T, None
    ci1 = [numpy.zeros_like(x) for x in ci0]
    ci0_ptrs = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in ci0])
    ci1_ptrs = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in ci1])
    libfci.FCIcontract_2e_symm1(eri_ptrs, ci0_ptrs, ci1_ptrs,
                                ctypes.c_int(norb), nbs, nas,
                                ctypes.c_int(nlinkb), ctypes.c_int(nlinka),
                                linkb_ptr, linka_ptr, dimirrep,
                                ctypes.c_int(wfnsym))
    for ir in range(TOTIRREPS):
        if ci0[ir].size > 0:
            lib.takebak_2d(ci1new, lib.transpose(ci1[ir]), aidx[wfnsym ^ ir],
                           bidx[ir])
    return ci1new.reshape(fcivec_shape)
Exemplo n.º 49
0
def pspace (fci, h1e, eri, norb, nelec, transformer, hdiag_det=None, hdiag_csf=None, npsp=200):
    ''' Note that getting pspace for npsp CSFs is substantially more costly than getting it for npsp determinants,
    until I write code than can evaluate Hamiltonian matrix elements of CSFs directly. On the other hand
    a pspace of determinants contains many redundant degrees of freedom for the same reason. Therefore I have
    reduced the default pspace size by a factor of 2.'''
    if norb > 63:
        raise NotImplementedError('norb > 63')

    t0 = (time.process_time (), time.time ())
    neleca, nelecb = _unpack_nelec(nelec)
    h1e = np.ascontiguousarray(h1e)
    eri = ao2mo.restore(1, eri, norb)
    nb = cistring.num_strings(norb, nelecb)
    if hdiag_det is None:
        hdiag_det = fci.make_hdiag(h1e, eri, norb, nelec)
    if hdiag_csf is None:
        hdiag_csf = fci.make_hdiag_csf(h1e, eri, norb, nelec, hdiag_det=hdiag_det)
    csf_addr = np.arange (hdiag_csf.size, dtype=np.int)
    if transformer.wfnsym is None:
        ncsf_sym = hdiag_csf.size
    else:
        idx_sym = transformer.confsym[transformer.econf_csf_mask] == transformer.wfnsym
        ncsf_sym = np.count_nonzero (idx_sym)
        csf_addr = csf_addr[idx_sym]
    if ncsf_sym > npsp:
        try:
            csf_addr = csf_addr[np.argpartition(hdiag_csf[csf_addr], npsp-1)[:npsp]]
        except AttributeError:
            csf_addr = csf_addr[np.argsort(hdiag_csf[csf_addr])[:npsp]]

    # To build 
    econf_addr = np.unique (transformer.econf_csf_mask[csf_addr])
    det_addr = np.concatenate ([np.nonzero (transformer.econf_det_mask == conf)[0]
        for conf in econf_addr])
    lib.logger.debug (fci, ("csf.pspace: Lowest-energy %s CSFs correspond to %s configurations"
        " which are spanned by %s determinants"), npsp, econf_addr.size, det_addr.size)

    addra, addrb = divmod(det_addr, nb)
    stra = cistring.addrs2str(norb, neleca, addra)
    strb = cistring.addrs2str(norb, nelecb, addrb)
    npsp_det = len(det_addr)
    h0 = np.zeros((npsp_det,npsp_det))
    h1e_ab = unpack_h1e_ab (h1e)
    h1e_a = np.ascontiguousarray(h1e_ab[0])
    h1e_b = np.ascontiguousarray(h1e_ab[1])
    g2e = ao2mo.restore(1, eri, norb)
    g2e_ab = g2e_bb = g2e_aa = g2e
    _debug_g2e (fci, g2e, eri, norb) # Exploring g2e nan bug; remove later?
    t0 = lib.logger.timer (fci, "csf.pspace: index manipulation", *t0)
    libfci.FCIpspace_h0tril_uhf(h0.ctypes.data_as(ctypes.c_void_p),
                                h1e_a.ctypes.data_as(ctypes.c_void_p),
                                h1e_b.ctypes.data_as(ctypes.c_void_p),
                                g2e_aa.ctypes.data_as(ctypes.c_void_p),
                                g2e_ab.ctypes.data_as(ctypes.c_void_p),
                                g2e_bb.ctypes.data_as(ctypes.c_void_p),
                                stra.ctypes.data_as(ctypes.c_void_p),
                                strb.ctypes.data_as(ctypes.c_void_p),
                                ctypes.c_int(norb), ctypes.c_int(npsp_det))
    t0 = lib.logger.timer (fci, "csf.pspace: pspace Hamiltonian in determinant basis", *t0)

    for i in range(npsp_det):
        h0[i,i] = hdiag_det[det_addr[i]]
    h0 = lib.hermi_triu(h0)

    try:
        if fci.verbose >= lib.logger.DEBUG: evals_before = scipy.linalg.eigh (h0)[0]
    except ValueError as e:
        lib.logger.debug (fci, ("ERROR: h0 has {} infs, {} nans; h1e_a has {} infs, {} nans; "
            "h1e_b has {} infs, {} nans; g2e has {} infs, {} nans, norb = {}, npsp_det = {}").format (
            np.count_nonzero (np.isinf (h0)), np.count_nonzero (np.isnan (h0)),
            np.count_nonzero (np.isinf (h1e_a)), np.count_nonzero (np.isnan (h1e_a)),
            np.count_nonzero (np.isinf (h1e_b)), np.count_nonzero (np.isnan (h1e_b)),
            np.count_nonzero (np.isinf (g2e)), np.count_nonzero (np.isnan (g2e)),
            norb, npsp_det))
        evals_before = np.zeros (npsp_det)

    h0, csf_addr = transformer.mat_det2csf_confspace (h0, econf_addr)
    t0 = lib.logger.timer (fci, "csf.pspace: transform pspace Hamiltonian into CSF basis", *t0)

    if fci.verbose >= lib.logger.DEBUG:
        lib.logger.debug2 (fci, "csf.pspace: eigenvalues of h0 before transformation %s", evals_before)
        evals_after = scipy.linalg.eigh (h0)[0]
        lib.logger.debug2 (fci, "csf.pspace: eigenvalues of h0 after transformation %s", evals_after)
        idx = [np.argmin (np.abs (evals_before - ev)) for ev in evals_after]
        resid = evals_after - evals_before[idx]
        lib.logger.debug2 (fci, "csf.pspace: best h0 eigenvalue matching differences after transformation: %s", resid)
        lib.logger.debug (fci, "csf.pspace: if the transformation of h0 worked the following number will be zero: %s", np.max (np.abs(resid)))

    # We got extra CSFs from building the configurations most of the time.
    if csf_addr.size > npsp:
        try:
            csf_addr_2 = np.argpartition(np.diag (h0), npsp-1)[:npsp]
        except AttributeError:
            csf_addr_2 = np.argsort(np.diag (h0))[:npsp]
        csf_addr = csf_addr[csf_addr_2]
        h0 = h0[np.ix_(csf_addr_2,csf_addr_2)]
    npsp_csf = csf_addr.size
    lib.logger.debug (fci, "csf_solver.pspace: asked for %s-CSF pspace; found %s CSFs", npsp, npsp_csf)

    t0 = lib.logger.timer (fci, "csf.pspace wrapup", *t0)
    return csf_addr, h0
Exemplo n.º 50
0
def make_shape(nsite, nelec, nphonon):
    neleca, nelecb = _unpack_nelec(nelec)
    na = cistring.num_strings(nsite, neleca)
    nb = cistring.num_strings(nsite, nelecb)
    return (na,nb)+(nphonon+1,)*nsite
Exemplo n.º 51
0
def kernel_float_space(myci,
                       h1e,
                       eri,
                       norb,
                       nelec,
                       ci0=None,
                       tol=None,
                       lindep=None,
                       max_cycle=None,
                       max_space=None,
                       nroots=None,
                       davidson_only=None,
                       max_memory=None,
                       verbose=None,
                       ecore=0,
                       **kwargs):
    if verbose is None:
        log = logger.Logger(myci.stdout, myci.verbose)
    elif isinstance(verbose, logger.Logger):
        log = verbose
    else:
        log = logger.Logger(myci.stdout, verbose)
    if tol is None: tol = myci.conv_tol
    if lindep is None: lindep = myci.lindep
    if max_cycle is None: max_cycle = myci.max_cycle
    if max_space is None: max_space = myci.max_space
    if max_memory is None: max_memory = myci.max_memory
    if nroots is None: nroots = myci.nroots
    if myci.verbose >= logger.WARN:
        myci.check_sanity()

    nelec = direct_spin1._unpack_nelec(nelec, myci.spin)
    h2e = direct_spin1.absorb_h1e(h1e, eri, norb, nelec, .5)
    h2e = ao2mo.restore(1, h2e, norb)

    # TODO: initial guess from CISD
    if isinstance(ci0, _SCIvector):
        if ci0.size == len(ci0._strs[0]) * len(ci0._strs[1]):
            ci0 = [ci0.ravel()]
        else:
            ci0 = [x.ravel() for x in ci0]
    else:
        ci_strs = (numpy.asarray([int('1' * nelec[0], 2)]),
                   numpy.asarray([int('1' * nelec[1], 2)]))
        ci0 = _as_SCIvector(numpy.ones((1, 1)), ci_strs)
        ci0 = myci.enlarge_space(ci0, h2e, norb, nelec)
        if ci0.size < nroots:
            log.warn('''
  Selected-CI space generated from HF ground state (by double exciting) is not enough for excited states.
  H**O->LUMO excitations are included in the initial guess.
  NOTE: This may introduce excited states of different symmetry.\n''')
            corea = '1' * (nelec[0] - 1)
            coreb = '1' * (nelec[1] - 1)
            ci_strs = (numpy.asarray([
                int('1' + corea, 2), int('10' + corea, 2)
            ]), numpy.asarray([int('1' + coreb, 2),
                               int('10' + coreb, 2)]))
            ci0 = _as_SCIvector(numpy.ones((2, 2)), ci_strs)
            ci0 = myci.enlarge_space(ci0, h2e, norb, nelec)
        if ci0.size < nroots:
            raise RuntimeError('Not enough selected-CI space for %d states' %
                               nroots)
        ci_strs = ci0._strs
        hdiag = myci.make_hdiag(h1e, eri, ci_strs, norb, nelec)
        ci0 = myci.get_init_guess(ci_strs, norb, nelec, nroots, hdiag)

    def hop(c):
        hc = myci.contract_2e(h2e, _as_SCIvector(c, ci_strs), norb, nelec,
                              link_index)
        return hc.ravel()

    precond = lambda x, e, *args: x / (hdiag - e + myci.level_shift)

    namax = cistring.num_strings(norb, nelec[0])
    nbmax = cistring.num_strings(norb, nelec[1])
    e_last = 0
    float_tol = myci.start_tol
    tol_decay_rate = myci.tol_decay_rate
    conv = False
    for icycle in range(norb):
        ci_strs = ci0[0]._strs
        float_tol = max(float_tol * tol_decay_rate, tol * 1e2)
        log.debug('cycle %d  ci.shape %s  float_tol %g', icycle,
                  (len(ci_strs[0]), len(ci_strs[1])), float_tol)

        ci0 = [c.ravel() for c in ci0]
        link_index = _all_linkstr_index(ci_strs, norb, nelec)
        hdiag = myci.make_hdiag(h1e, eri, ci_strs, norb, nelec)
        #e, ci0 = lib.davidson(hop, ci0.reshape(-1), precond, tol=float_tol)
        e, ci0 = myci.eig(hop,
                          ci0,
                          precond,
                          tol=float_tol,
                          lindep=lindep,
                          max_cycle=max_cycle,
                          max_space=max_space,
                          nroots=nroots,
                          max_memory=max_memory,
                          verbose=log,
                          **kwargs)
        if nroots > 1:
            ci0 = [_as_SCIvector(c, ci_strs) for c in ci0]
            de, e_last = min(e) - e_last, min(e)
            log.info('cycle %d  E = %s  dE = %.8g', icycle, e + ecore, de)
        else:
            ci0 = [_as_SCIvector(ci0, ci_strs)]
            de, e_last = e - e_last, e
            log.info('cycle %d  E = %.15g  dE = %.8g', icycle, e + ecore, de)

        if ci0[0].shape == (namax, nbmax) or abs(de) < tol * 1e3:
            conv = True
            break

        last_ci0_size = float(len(ci_strs[0])), float(len(ci_strs[1]))
        ci0 = myci.enlarge_space(ci0, h2e, norb, nelec)
        na = len(ci0[0]._strs[0])
        nb = len(ci0[0]._strs[1])
        if ((.99 < na / last_ci0_size[0] < 1.01)
                and (.99 < nb / last_ci0_size[1] < 1.01)):
            conv = True
            break

    ci_strs = ci0[0]._strs
    log.debug('Extra CI in selected space %s',
              (len(ci_strs[0]), len(ci_strs[1])))
    ci0 = [c.ravel() for c in ci0]
    link_index = _all_linkstr_index(ci_strs, norb, nelec)
    hdiag = myci.make_hdiag(h1e, eri, ci_strs, norb, nelec)
    e, c = myci.eig(hop,
                    ci0,
                    precond,
                    tol=tol,
                    lindep=lindep,
                    max_cycle=max_cycle,
                    max_space=max_space,
                    nroots=nroots,
                    max_memory=max_memory,
                    verbose=log,
                    **kwargs)

    na = len(ci_strs[0])
    nb = len(ci_strs[1])
    if nroots > 1:
        for i, ei in enumerate(e + ecore):
            log.info('Selected CI state %d  E = %.15g', i, ei)
        return e + ecore, [
            _as_SCIvector(ci.reshape(na, nb), ci_strs) for ci in c
        ]
    else:
        log.info('Selected CI  E = %.15g', e + ecore)
        return e + ecore, _as_SCIvector(c.reshape(na, nb), ci_strs)
Exemplo n.º 52
0
 def spin_square(self, civec_strs, norb, nelec):
     nelec = direct_spin1._unpack_nelec(nelec, self.spin)
     return spin_square(_as_SCIvector_if_not(civec_strs, self._strs), norb,
                        nelec)
Exemplo n.º 53
0
 def make_rdm1(self, civec_strs, norb, nelec, link_index=None):
     nelec = direct_spin1._unpack_nelec(nelec, self.spin)
     rdm1a, rdm1b = self.make_rdm1s(civec_strs, norb, nelec, link_index)
     return rdm1a + rdm1b
Exemplo n.º 54
0
    mol.verbose = lib.logger.DEBUG
    mol.output = 'sa_lasscf_slow_ham.log'
    mol.build()
    mf = scf.RHF(mol).run()
    tol = 1e-6 if len(sys.argv) < 2 else float(sys.argv[1])
    las = LASSCF(mf, (4, 4), (4, 4)).set(conv_tol_grad=tol)
    mo = las.localize_init_guess((list(range(3)), list(range(9, 12))),
                                 mo_coeff=mf.mo_coeff)
    las.state_average_(weights=[0.5, 0.5], spins=[[0, 0], [2, -2]])
    h2eff_sub, veff = las.kernel(mo)[-2:]
    e_states = las.e_states

    ncore, ncas, nocc = las.ncore, las.ncas, las.ncore + las.ncas
    mo_coeff = las.mo_coeff
    mo_core = mo_coeff[:, :ncore]
    mo_cas = mo_coeff[:, ncore:nocc]
    e0 = las._scf.energy_nuc() + 2 * ((
        (las._scf.get_hcore() + veff.c / 2) @ mo_core) * mo_core).sum()
    h1 = mo_cas.conj().T @ (las._scf.get_hcore() + veff.c) @ mo_cas
    h2 = h2eff_sub[ncore:nocc].reshape(ncas * ncas, ncas * (ncas + 1) // 2)
    h2 = lib.numpy_helper.unpack_tril(h2).reshape(ncas, ncas, ncas, ncas)
    nelec_fr = []
    for fcibox, nelec in zip(las.fciboxes, las.nelecas_sub):
        ne = sum(nelec)
        nelec_fr.append([
            _unpack_nelec(fcibox._get_nelec(solver, ne))
            for solver in fcibox.fcisolvers
        ])
    ham_eff = slow_ham(las.mol, h1, h2, las.ci, las.ncas_sub, nelec_fr)[0]
    print(las.converged, e_states - (e0 + np.diag(ham_eff)))
Exemplo n.º 55
0
 def make_rdm2(self, civec_strs, norb, nelec, link_index=None, **kwargs):
     nelec = direct_spin1._unpack_nelec(nelec, self.spin)
     civec_strs = _as_SCIvector_if_not(civec_strs, self._strs)
     return make_rdm2(civec_strs, norb, nelec, link_index)
Exemplo n.º 56
0
def kernel_float_space(myci, h1e, eri, norb, nelec, ci0=None,
                       tol=None, lindep=None, max_cycle=None, max_space=None,
                       nroots=None, davidson_only=None,
                       max_memory=None, verbose=None, ecore=0, **kwargs):
    if verbose is None:
        log = logger.Logger(myci.stdout, myci.verbose)
    elif isinstance(verbose, logger.Logger):
        log = verbose
    else:
        log = logger.Logger(myci.stdout, verbose)
    if tol is None: tol = myci.conv_tol
    if lindep is None: lindep = myci.lindep
    if max_cycle is None: max_cycle = myci.max_cycle
    if max_space is None: max_space = myci.max_space
    if max_memory is None: max_memory = myci.max_memory
    if nroots is None: nroots = myci.nroots
    if myci.verbose >= logger.WARN:
        myci.check_sanity()

    nelec = direct_spin1._unpack_nelec(nelec, myci.spin)
    h2e = direct_spin1.absorb_h1e(h1e, eri, norb, nelec, .5)
    h2e = ao2mo.restore(1, h2e, norb)

# TODO: initial guess from CISD
    if isinstance(ci0, _SCIvector):
        if ci0.size == len(ci0._strs[0])*len(ci0._strs[1]):
            ci0 = [ci0.ravel()]
        else:
            ci0 = [x.ravel() for x in ci0]
    else:
        if isinstance(nelec, (int, numpy.integer)):
            nelecb = nelec//2
            neleca = nelec - nelecb
            nelec = neleca, nelecb
        ci_strs = (numpy.asarray([int('1'*nelec[0], 2)]),
                   numpy.asarray([int('1'*nelec[1], 2)]))
        ci0 = _as_SCIvector(numpy.ones((1,1)), ci_strs)
        ci0 = myci.enlarge_space(ci0, h2e, norb, nelec)
        if ci0.size < nroots:
            log.warn('''
  Selected-CI space generated from HF ground state (by double exciting) is not enough for excited states.
  H**O->LUMO excitations are included in the initial guess.
  NOTE: This may introduce excited states of different symmetry.\n''')
            corea = '1' * (nelec[0]-1)
            coreb = '1' * (nelec[1]-1)
            ci_strs = (numpy.asarray([int('1'+corea, 2), int('10'+corea, 2)]),
                       numpy.asarray([int('1'+coreb, 2), int('10'+coreb, 2)]))
            ci0 = _as_SCIvector(numpy.ones((2,2)), ci_strs)
            ci0 = myci.enlarge_space(ci0, h2e, norb, nelec)
        if ci0.size < nroots:
            raise RuntimeError('Not enough selected-CI space for %d states' % nroots)
        ci_strs = ci0._strs
        hdiag = myci.make_hdiag(h1e, eri, ci_strs, norb, nelec)
        ci0 = myci.get_init_guess(ci_strs, norb, nelec, nroots, hdiag)

    def hop(c):
        hc = myci.contract_2e(h2e, _as_SCIvector(c, ci_strs), norb, nelec, link_index)
        return hc.ravel()
    precond = lambda x, e, *args: x/(hdiag-e+myci.level_shift)

    namax = cistring.num_strings(norb, nelec[0])
    nbmax = cistring.num_strings(norb, nelec[1])
    e_last = 0
    float_tol = 3e-4
    conv = False
    for icycle in range(norb):
        ci_strs = ci0[0]._strs
        float_tol = max(float_tol*.3, tol*1e2)
        log.debug('cycle %d  ci.shape %s  float_tol %g',
                  icycle, (len(ci_strs[0]), len(ci_strs[1])), float_tol)

        ci0 = [c.ravel() for c in ci0]
        link_index = _all_linkstr_index(ci_strs, norb, nelec)
        hdiag = myci.make_hdiag(h1e, eri, ci_strs, norb, nelec)
        #e, ci0 = lib.davidson(hop, ci0.reshape(-1), precond, tol=float_tol)
        e, ci0 = myci.eig(hop, ci0, precond, tol=float_tol, lindep=lindep,
                          max_cycle=max_cycle, max_space=max_space, nroots=nroots,
                          max_memory=max_memory, verbose=log, **kwargs)
        if nroots > 1:
            ci0 = [_as_SCIvector(c, ci_strs) for c in ci0]
            de, e_last = min(e)-e_last, min(e)
            log.info('cycle %d  E = %s  dE = %.8g', icycle, e+ecore, de)
        else:
            ci0 = [_as_SCIvector(ci0, ci_strs)]
            de, e_last = e-e_last, e
            log.info('cycle %d  E = %.15g  dE = %.8g', icycle, e+ecore, de)

        if ci0[0].shape == (namax,nbmax) or abs(de) < tol*1e3:
            conv = True
            break

        last_ci0_size = float(len(ci_strs[0])), float(len(ci_strs[1]))
        ci0 = myci.enlarge_space(ci0, h2e, norb, nelec)
        na = len(ci0[0]._strs[0])
        nb = len(ci0[0]._strs[1])
        if ((.99 < na/last_ci0_size[0] < 1.01) and
            (.99 < nb/last_ci0_size[1] < 1.01)):
            conv = True
            break

    ci_strs = ci0[0]._strs
    log.debug('Extra CI in selected space %s', (len(ci_strs[0]), len(ci_strs[1])))
    ci0 = [c.ravel() for c in ci0]
    link_index = _all_linkstr_index(ci_strs, norb, nelec)
    hdiag = myci.make_hdiag(h1e, eri, ci_strs, norb, nelec)
    e, c = myci.eig(hop, ci0, precond, tol=tol, lindep=lindep,
                    max_cycle=max_cycle, max_space=max_space, nroots=nroots,
                    max_memory=max_memory, verbose=log, **kwargs)

    na = len(ci_strs[0])
    nb = len(ci_strs[1])
    if nroots > 1:
        for i, ei in enumerate(e+ecore):
            log.info('Selected CI state %d  E = %.15g', i, ei)
        return e+ecore, [_as_SCIvector(ci.reshape(na,nb),ci_strs) for ci in c]
    else:
        log.info('Selected CI  E = %.15g', e+ecore)
        return e+ecore, _as_SCIvector(c.reshape(na,nb), ci_strs)
Exemplo n.º 57
0
def kernel_float_space(
    myci,
    h1e,
    eri,
    norb,
    nelec,
    ci0=None,
    tol=None,
    lindep=None,
    max_cycle=None,
    max_space=None,
    nroots=None,
    davidson_only=None,
    max_memory=None,
    verbose=None,
    ecore=0,
    **kwargs
):
    if verbose is None:
        log = logger.Logger(myci.stdout, myci.verbose)
    elif isinstance(verbose, logger.Logger):
        log = verbose
    else:
        log = logger.Logger(myci.stdout, verbose)
    if tol is None:
        tol = myci.conv_tol
    if lindep is None:
        lindep = myci.lindep
    if max_cycle is None:
        max_cycle = myci.max_cycle
    if max_space is None:
        max_space = myci.max_space
    if max_memory is None:
        max_memory = myci.max_memory
    if nroots is None:
        nroots = myci.nroots
    if myci.verbose >= logger.WARN:
        myci.check_sanity()

    nelec = direct_spin1._unpack_nelec(nelec, myci.spin)
    h2e = direct_spin1.absorb_h1e(h1e, eri, norb, nelec, 0.5)
    h2e = ao2mo.restore(1, h2e, norb)

    # TODO: initial guess from CISD
    if isinstance(ci0, _SCIvector):
        if ci0.size == len(ci0._strs[0]) * len(ci0._strs[1]):
            ci0 = [ci0.ravel()]
        else:
            ci0 = [x.ravel() for x in ci0]
    else:
        if isinstance(nelec, (int, numpy.integer)):
            nelecb = nelec // 2
            neleca = nelec - nelecb
            nelec = neleca, nelecb
        ci_strs = (numpy.asarray([int("1" * nelec[0], 2)]), numpy.asarray([int("1" * nelec[1], 2)]))
        ci0 = _as_SCIvector(numpy.ones((1, 1)), ci_strs)
        ci0 = myci.enlarge_space(ci0, h2e, norb, nelec)
        ci_strs = ci0._strs
        hdiag = myci.make_hdiag(h1e, eri, ci_strs, norb, nelec)
        ci0 = myci.get_init_guess(ci_strs, norb, nelec, nroots, hdiag)

    def hop(c):
        hc = myci.contract_2e(h2e, _as_SCIvector(c, ci_strs), norb, nelec, link_index)
        return hc.ravel()

    precond = lambda x, e, *args: x / (hdiag - e + myci.level_shift)

    namax = cistring.num_strings(norb, nelec[0])
    nbmax = cistring.num_strings(norb, nelec[1])
    e_last = 0
    float_tol = 3e-4
    conv = False
    for icycle in range(norb):
        ci_strs = ci0[0]._strs
        float_tol = max(float_tol * 0.3, tol * 1e2)
        log.debug("cycle %d  ci.shape %s  float_tol %g", icycle, (len(ci_strs[0]), len(ci_strs[1])), float_tol)

        ci0 = [c.ravel() for c in ci0]
        link_index = _all_linkstr_index(ci_strs, norb, nelec)
        hdiag = myci.make_hdiag(h1e, eri, ci_strs, norb, nelec)
        # e, ci0 = lib.davidson(hop, ci0.reshape(-1), precond, tol=float_tol)
        e, ci0 = myci.eig(
            hop,
            ci0,
            precond,
            tol=float_tol,
            lindep=lindep,
            max_cycle=max_cycle,
            max_space=max_space,
            nroots=nroots,
            max_memory=max_memory,
            verbose=log,
            **kwargs
        )
        if nroots > 1:
            ci0 = [_as_SCIvector(c, ci_strs) for c in ci0]
            de, e_last = min(e) - e_last, min(e)
            log.info("cycle %d  E = %s  dE = %.8g", icycle, e + ecore, de)
        else:
            ci0 = [_as_SCIvector(ci0, ci_strs)]
            de, e_last = e - e_last, e
            log.info("cycle %d  E = %.15g  dE = %.8g", icycle, e + ecore, de)

        if ci0[0].shape == (namax, nbmax) or abs(de) < tol * 1e3:
            conv = True
            break

        last_ci0_size = float(len(ci_strs[0])), float(len(ci_strs[1]))
        ci0 = myci.enlarge_space(ci0, h2e, norb, nelec)
        na = len(ci0[0]._strs[0])
        nb = len(ci0[0]._strs[1])
        if (0.99 < na / last_ci0_size[0] < 1.01) and (0.99 < nb / last_ci0_size[1] < 1.01):
            conv = True
            break

    ci_strs = ci0[0]._strs
    log.debug("Extra CI in selected space %s", (len(ci_strs[0]), len(ci_strs[1])))
    ci0 = [c.ravel() for c in ci0]
    link_index = _all_linkstr_index(ci_strs, norb, nelec)
    hdiag = myci.make_hdiag(h1e, eri, ci_strs, norb, nelec)
    e, c = myci.eig(
        hop,
        ci0,
        precond,
        tol=tol,
        lindep=lindep,
        max_cycle=max_cycle,
        max_space=max_space,
        nroots=nroots,
        max_memory=max_memory,
        verbose=log,
        **kwargs
    )
    log.info("Select CI  E = %.15g", e + ecore)

    na = len(ci_strs[0])
    nb = len(ci_strs[1])
    if nroots > 1:
        return e + ecore, [_as_SCIvector(ci.reshape(na, nb), ci_strs) for ci in c]
    else:
        return e + ecore, _as_SCIvector(c.reshape(na, nb), ci_strs)
Exemplo n.º 58
0
def kernel_float_space(myci, h1e, eri, norb, nelec, ci0=None,
                       tol=None, lindep=None, max_cycle=None, max_space=None,
                       nroots=None, davidson_only=None, max_iter=None,
                       max_memory=None, verbose=None, ecore=0, return_integrals=False, 
                       eri_sorted=None, jk=None, jk_sorted=None, **kwargs):
    if verbose is None:
        log = logger.Logger(myci.stdout, myci.verbose)
    elif isinstance(verbose, logger.Logger):
        log = verbose
    else:
        log = logger.Logger(myci.stdout, verbose)
    if tol is None: tol = myci.conv_tol
    if lindep is None: lindep = myci.lindep
    if max_cycle is None: max_cycle = myci.max_cycle
    if max_space is None: max_space = myci.max_space
    if max_memory is None: max_memory = myci.max_memory
    if nroots is None: nroots = myci.nroots
    if max_iter is None: max_iter = myci.max_iter
    if myci.verbose >= logger.WARN:
        myci.check_sanity()

    log.info('\nStarting heat-bath CI algorithm...\n')
    log.info('Selection threshold:                  %8.5e',    myci.select_cutoff)
    log.info('CI coefficient cutoff:                %8.5e',    myci.ci_coeff_cutoff)
    log.info('Energy convergence tolerance:         %8.5e',    tol)
    log.info('Number of determinants tolerance:     %8.5e',    myci.conv_ndet_tol)
    log.info('Number of electrons:                  %s',       nelec)
    log.info('Number of orbitals:                   %3d',      norb)
    log.info('Number of roots:                      %3d',    nroots)

    nelec = direct_spin1._unpack_nelec(nelec, myci.spin)
    eri = ao2mo.restore(1, eri, norb)

    # Avoid resorting the integrals by storing them in memory
    eri = eri.ravel()

    if eri_sorted is None and jk is None and jk_sorted is None:
        log.debug("\nSorting two-electron integrals...")
        t_start = time.time()
        eri_sorted = abs(eri).argsort()[::-1]
        jk = eri.reshape([norb]*4)
        jk = jk - jk.transpose(2,1,0,3)
        jk = jk.ravel()
        jk_sorted = abs(jk).argsort()[::-1]
        t_current = time.time() - t_start
        log.debug('Timing for sorting the integrals: %10.3f', t_current)

    # Initial guess
    if ci0 is None:
        hf_str = numpy.hstack([orblst2str(range(nelec[0]), norb), orblst2str(range(nelec[1]), norb)]).reshape(1,-1)
        ci0 = [as_SCIvector(numpy.ones(1), hf_str)]
    else:
        assert(nroots == len(ci0))

    ci0 = myci.enlarge_space(ci0, h1e, eri, jk, eri_sorted, jk_sorted, norb, nelec)

    def hop(c):
        hc = myci.contract_2e((h1e, eri), as_SCIvector(c, ci_strs), norb, nelec, hdiag)
        return hc.ravel()
    precond = lambda x, e, *args: x/(hdiag-e+myci.level_shift)

    e_last = 0
    float_tol = 3e-4
    conv = False
    for icycle in range(max_iter):
        ci_strs = ci0[0]._strs
        float_tol = max(float_tol*.3, tol*1e2)
        log.info('\nMacroiteration %d', icycle)
        log.info('Number of CI configurations: %d', ci_strs.shape[0])
        hdiag = myci.make_hdiag(h1e, eri, ci_strs, norb, nelec)
        t_start = time.time()
        e, ci0 = myci.eig(hop, ci0, precond, tol=float_tol, lindep=lindep,
                          max_cycle=max_cycle, max_space=max_space, nroots=nroots,
                          max_memory=max_memory, verbose=log, **kwargs)
        if not isinstance(ci0, (tuple, list)):
            ci0 = [ci0]
            e = [e]
        t_current = time.time() - t_start
        log.debug('Timing for solving the eigenvalue problem: %10.3f', t_current)
        ci0 = [as_SCIvector(c, ci_strs) for c in ci0]
        de, e_last = min(e)-e_last, min(e)
        log.info('Cycle %d  E = %s  dE = %.8g', icycle, numpy.array(e)+ecore, de)

        if abs(de) < tol*1e3:
            conv = True
            break

        last_ci0_size = float(len(ci_strs))
        t_start = time.time()
        ci0 = myci.enlarge_space(ci0, h1e, eri, jk, eri_sorted, jk_sorted, norb, nelec)
        t_current = time.time() - t_start
        log.debug('Timing for selecting configurations: %10.3f', t_current)
        if (((1 - myci.conv_ndet_tol) < len(ci0[0]._strs)/last_ci0_size < (1 + myci.conv_ndet_tol))):
            conv = True
            break

    ci_strs = ci0[0]._strs
    log.info('\nExtra CI in the final selected space')
    log.info('Number of CI configurations: %d', ci_strs.shape[0])
    hdiag = myci.make_hdiag(h1e, eri, ci_strs, norb, nelec)
    e, c = myci.eig(hop, ci0, precond, tol=tol, lindep=lindep,
                    max_cycle=max_cycle, max_space=max_space, nroots=nroots,
                    max_memory=max_memory, verbose=log, **kwargs)
    if not isinstance(c, (tuple, list)):
        c = [c]
        e = [e]
    log.info('\nSelected CI  E = %s', numpy.array(e)+ecore)

    if (return_integrals):
        return (numpy.array(e)+ecore), [as_SCIvector(ci, ci_strs) for ci in c], eri_sorted, jk, jk_sorted
    else:
        return (numpy.array(e)+ecore), [as_SCIvector(ci, ci_strs) for ci in c]
Exemplo n.º 59
0
 def spin_square(self, civec_strs, norb, nelec):
     nelec = direct_spin1._unpack_nelec(nelec, self.spin)
     return spin_square(_as_SCIvector_if_not(civec_strs, self._strs), norb, nelec)