Source code for pyscf.ci.ucisd

#!/usr/bin/env python
# Copyright 2014-2021 The PySCF Developers. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Author: Qiming Sun <osirpt.sun@gmail.com>
#

'''
Unrestricted CISD
'''

import numpy
from pyscf import lib
from pyscf.lib import logger
from pyscf.cc import uccsd
from pyscf.cc import uccsd_rdm
from pyscf.ci import cisd
from pyscf.fci import cistring
from pyscf.cc.ccsd import _unpack_4fold

[docs] def make_diagonal(myci, eris): nocca, noccb = eris.nocc nmoa = eris.focka.shape[0] nmob = eris.fockb.shape[1] nvira = nmoa - nocca nvirb = nmob - noccb jdiag_aa = numpy.zeros((nmoa,nmoa)) jdiag_ab = numpy.zeros((nmoa,nmob)) jdiag_bb = numpy.zeros((nmob,nmob)) jdiag_aa[:nocca,:nocca] = numpy.einsum('iijj->ij', eris.oooo) jdiag_aa[:nocca,nocca:] = numpy.einsum('iijj->ij', eris.oovv) jdiag_aa[nocca:,:nocca] = jdiag_aa[:nocca,nocca:].T jdiag_ab[:nocca,:noccb] = numpy.einsum('iijj->ij', eris.ooOO) jdiag_ab[:nocca,noccb:] = numpy.einsum('iijj->ij', eris.ooVV) jdiag_ab[nocca:,:noccb] = numpy.einsum('iijj->ji', eris.OOvv) jdiag_bb[:noccb,:noccb] = numpy.einsum('iijj->ij', eris.OOOO) jdiag_bb[:noccb,noccb:] = numpy.einsum('iijj->ij', eris.OOVV) jdiag_bb[noccb:,:noccb] = jdiag_bb[:noccb,noccb:].T kdiag_aa = numpy.zeros((nmoa,nmoa)) kdiag_bb = numpy.zeros((nmob,nmob)) kdiag_aa[:nocca,:nocca] = numpy.einsum('ijji->ij', eris.oooo) kdiag_aa[:nocca,nocca:] = numpy.einsum('ijji->ij', eris.ovvo) kdiag_aa[nocca:,:nocca] = kdiag_aa[:nocca,nocca:].T kdiag_bb[:noccb,:noccb] = numpy.einsum('ijji->ij', eris.OOOO) kdiag_bb[:noccb,noccb:] = numpy.einsum('ijji->ij', eris.OVVO) kdiag_bb[noccb:,:noccb] = kdiag_bb[:noccb,noccb:].T # if eris.vvvv is not None and eris.vvVV is not None and eris.VVVV is not None: # def diag_idx(n): # idx = numpy.arange(n) # return idx * (idx + 1) // 2 + idx # jdiag_aa[nocca:,nocca:] = eris.vvvv[diag_idx(nvira)[:,None],diag_idx(nvira)] # jdiag_ab[nocca:,noccb:] = eris.vvVV[diag_idx(nvira)[:,None],diag_idx(nvirb)] # jdiag_bb[noccb:,noccb:] = eris.VVVV[diag_idx(nvirb)[:,None],diag_idx(nvirb)] # kdiag_aa[nocca:,nocca:] = lib.unpack_tril(eris.vvvv.diagonal()) # kdiag_bb[noccb:,noccb:] = lib.unpack_tril(eris.VVVV.diagonal()) jkdiag_aa = jdiag_aa - kdiag_aa jkdiag_bb = jdiag_bb - kdiag_bb mo_ea = eris.focka.diagonal() mo_eb = eris.fockb.diagonal() ehf = (mo_ea[:nocca].sum() + mo_eb[:noccb].sum() - jkdiag_aa[:nocca,:nocca].sum() * .5 - jdiag_ab[:nocca,:noccb].sum() - jkdiag_bb[:noccb,:noccb].sum() * .5) dia_a = lib.direct_sum('a-i->ia', mo_ea[nocca:], mo_ea[:nocca]) dia_a -= jkdiag_aa[:nocca,nocca:] dia_b = lib.direct_sum('a-i->ia', mo_eb[noccb:], mo_eb[:noccb]) dia_b -= jkdiag_bb[:noccb,noccb:] e1diag_a = dia_a + ehf e1diag_b = dia_b + ehf e2diag_aa = lib.direct_sum('ia+jb->ijab', dia_a, dia_a) e2diag_aa += ehf e2diag_aa += jkdiag_aa[:nocca,:nocca].reshape(nocca,nocca,1,1) e2diag_aa -= jkdiag_aa[:nocca,nocca:].reshape(nocca,1,1,nvira) e2diag_aa -= jkdiag_aa[:nocca,nocca:].reshape(1,nocca,nvira,1) e2diag_aa += jkdiag_aa[nocca:,nocca:].reshape(1,1,nvira,nvira) e2diag_ab = lib.direct_sum('ia+jb->ijab', dia_a, dia_b) e2diag_ab += ehf e2diag_ab += jdiag_ab[:nocca,:noccb].reshape(nocca,noccb,1,1) e2diag_ab += jdiag_ab[nocca:,noccb:].reshape(1,1,nvira,nvirb) e2diag_ab -= jdiag_ab[:nocca,noccb:].reshape(nocca,1,1,nvirb) e2diag_ab -= jdiag_ab[nocca:,:noccb].T.reshape(1,noccb,nvira,1) e2diag_bb = lib.direct_sum('ia+jb->ijab', dia_b, dia_b) e2diag_bb += ehf e2diag_bb += jkdiag_bb[:noccb,:noccb].reshape(noccb,noccb,1,1) e2diag_bb -= jkdiag_bb[:noccb,noccb:].reshape(noccb,1,1,nvirb) e2diag_bb -= jkdiag_bb[:noccb,noccb:].reshape(1,noccb,nvirb,1) e2diag_bb += jkdiag_bb[noccb:,noccb:].reshape(1,1,nvirb,nvirb) return amplitudes_to_cisdvec(ehf, (e1diag_a, e1diag_b), (e2diag_aa, e2diag_ab, e2diag_bb))
[docs] def contract(myci, civec, eris): nocca, noccb = eris.nocc nmoa = eris.focka.shape[0] nmob = eris.fockb.shape[0] nvira = nmoa - nocca nvirb = nmob - noccb c0, (c1a,c1b), (c2aa,c2ab,c2bb) = \ cisdvec_to_amplitudes(civec, (nmoa,nmob), (nocca,noccb), copy=False) #:t2 += 0.5*einsum('ijef,abef->ijab', c2, eris.vvvv) #:eris_vvvv = ao2mo.restore(1, eris.vvvv, nvira) #:eris_vvVV = ucisd_slow._restore(eris.vvVV, nvira, nvirb) #:eris_VVVV = ao2mo.restore(1, eris.VVVV, nvirb) #:t2aa += lib.einsum('ijef,aebf->ijab', c2aa, eris_vvvv) #:t2bb += lib.einsum('ijef,aebf->ijab', c2bb, eris_VVVV) #:t2ab += lib.einsum('iJeF,aeBF->iJaB', c2ab, eris_vvVV) t2aa, t2ab, t2bb = myci._add_vvvv(None, (c2aa,c2ab,c2bb), eris) t2aa *= .25 t2bb *= .25 fooa = eris.focka[:nocca,:nocca] foob = eris.fockb[:noccb,:noccb] fova = eris.focka[:nocca,nocca:] fovb = eris.fockb[:noccb,noccb:] fvoa = eris.focka[nocca:,:nocca] fvob = eris.fockb[noccb:,:noccb] fvva = eris.focka[nocca:,nocca:] fvvb = eris.fockb[noccb:,noccb:] t0 = 0 t1a = 0 t1b = 0 eris_oovv = _cp(eris.oovv) eris_ooVV = _cp(eris.ooVV) eris_OOvv = _cp(eris.OOvv) eris_OOVV = _cp(eris.OOVV) eris_ovov = _cp(eris.ovov) eris_ovOV = _cp(eris.ovOV) eris_OVOV = _cp(eris.OVOV) #:t2 += eris.oovv * c0 t2aa += .25 * c0 * eris_ovov.conj().transpose(0,2,1,3) t2aa -= .25 * c0 * eris_ovov.conj().transpose(0,2,3,1) t2bb += .25 * c0 * eris_OVOV.conj().transpose(0,2,1,3) t2bb -= .25 * c0 * eris_OVOV.conj().transpose(0,2,3,1) t2ab += c0 * eris_ovOV.conj().transpose(0,2,1,3) #:t0 += numpy.einsum('ijab,ijab', eris.oovv, c2) * .25 t0 += numpy.einsum('iajb,ijab', eris_ovov, c2aa) * .25 t0 -= numpy.einsum('jaib,ijab', eris_ovov, c2aa) * .25 t0 += numpy.einsum('iajb,ijab', eris_OVOV, c2bb) * .25 t0 -= numpy.einsum('jaib,ijab', eris_OVOV, c2bb) * .25 t0 += numpy.einsum('iajb,ijab', eris_ovOV, c2ab) eris_ovov = eris_ovOV = eris_OVOV = None #:tmp = einsum('imae,mbej->ijab', c2, eris.ovvo) #:tmp = tmp - tmp.transpose(0,1,3,2) #:t2 += tmp - tmp.transpose(1,0,2,3) eris_ovvo = _cp(eris.ovvo) eris_ovVO = _cp(eris.ovVO) eris_OVVO = _cp(eris.OVVO) ovvo = eris_ovvo - eris_oovv.transpose(0,3,2,1) OVVO = eris_OVVO - eris_OOVV.transpose(0,3,2,1) t2aa += lib.einsum('imae,jbem->ijab', c2aa, ovvo) t2aa += lib.einsum('iMaE,jbEM->ijab', c2ab, eris_ovVO) t2bb += lib.einsum('imae,jbem->ijab', c2bb, OVVO) t2bb += lib.einsum('mIeA,meBJ->IJAB', c2ab, eris_ovVO) t2ab += lib.einsum('imae,meBJ->iJaB', c2aa, eris_ovVO) t2ab += lib.einsum('iMaE,MEBJ->iJaB', c2ab, OVVO) t2ab += lib.einsum('IMAE,jbEM->jIbA', c2bb, eris_ovVO) t2ab += lib.einsum('mIeA,jbem->jIbA', c2ab, ovvo) t2ab -= lib.einsum('iMeA,JMeb->iJbA', c2ab, eris_OOvv) t2ab -= lib.einsum('mIaE,jmEB->jIaB', c2ab, eris_ooVV) #:t1 += einsum('nf,nafi->ia', c1, eris.ovvo) t1a += numpy.einsum('nf,nfai->ia', c1a, eris_ovvo) t1a -= numpy.einsum('nf,nifa->ia', c1a, eris_oovv) t1b += numpy.einsum('nf,nfai->ia', c1b, eris_OVVO) t1b -= numpy.einsum('nf,nifa->ia', c1b, eris_OOVV) t1b += numpy.einsum('nf,nfai->ia', c1a, eris_ovVO) t1a += numpy.einsum('nf,iafn->ia', c1b, eris_ovVO) #:t1 -= 0.5*einsum('mnae,mnie->ia', c2, eris.ooov) eris_ovoo = _cp(eris.ovoo) eris_OVOO = _cp(eris.OVOO) eris_OVoo = _cp(eris.OVoo) eris_ovOO = _cp(eris.ovOO) t1a += lib.einsum('mnae,meni->ia', c2aa, eris_ovoo) t1b += lib.einsum('mnae,meni->ia', c2bb, eris_OVOO) t1a -= lib.einsum('nMaE,MEni->ia', c2ab, eris_OVoo) t1b -= lib.einsum('mNeA,meNI->IA', c2ab, eris_ovOO) #:tmp = einsum('ma,mbij->ijab', c1, eris.ovoo) #:t2 -= tmp - tmp.transpose(0,1,3,2) t2aa -= lib.einsum('ma,jbmi->jiba', c1a, eris_ovoo) t2bb -= lib.einsum('ma,jbmi->jiba', c1b, eris_OVOO) t2ab -= lib.einsum('ma,JBmi->iJaB', c1a, eris_OVoo) t2ab -= lib.einsum('MA,ibMJ->iJbA', c1b, eris_ovOO) #:#:t1 -= 0.5*einsum('imef,maef->ia', c2, eris.ovvv) #:eris_ovvv = _cp(eris.ovvv) #:eris_OVVV = _cp(eris.OVVV) #:eris_ovVV = _cp(eris.ovVV) #:eris_OVvv = _cp(eris.OVvv) #:t1a += lib.einsum('mief,mefa->ia', c2aa, eris_ovvv) #:t1b += lib.einsum('MIEF,MEFA->IA', c2bb, eris_OVVV) #:t1a += lib.einsum('iMfE,MEaf->ia', c2ab, eris_OVvv) #:t1b += lib.einsum('mIeF,meAF->IA', c2ab, eris_ovVV) #:#:tmp = einsum('ie,jeba->ijab', c1, numpy.asarray(eris.ovvv).conj()) #:#:t2 += tmp - tmp.transpose(1,0,2,3) #:t2aa += lib.einsum('ie,mbae->imab', c1a, eris_ovvv) #:t2bb += lib.einsum('ie,mbae->imab', c1b, eris_OVVV) #:t2ab += lib.einsum('ie,MBae->iMaB', c1a, eris_OVvv) #:t2ab += lib.einsum('IE,maBE->mIaB', c1b, eris_ovVV) mem_now = lib.current_memory()[0] max_memory = max(0, lib.param.MAX_MEMORY - mem_now) if nvira > 0 and nocca > 0: blksize = max(int(max_memory*1e6/8/(nvira**2*nocca*2)), 2) for p0,p1 in lib.prange(0, nvira, blksize): ovvv = eris.get_ovvv(slice(None), slice(p0,p1)) t1a += lib.einsum('mief,mefa->ia', c2aa[:,:,p0:p1], ovvv) t2aa[:,:,p0:p1] += lib.einsum('mbae,ie->miba', ovvv, c1a) ovvv = None if nvirb > 0 and noccb > 0: blksize = max(int(max_memory*1e6/8/(nvirb**2*noccb*2)), 2) for p0,p1 in lib.prange(0, nvirb, blksize): OVVV = eris.get_OVVV(slice(None), slice(p0,p1)) t1b += lib.einsum('MIEF,MEFA->IA', c2bb[:,:,p0:p1], OVVV) t2bb[:,:,p0:p1] += lib.einsum('mbae,ie->miba', OVVV, c1b) OVVV = None if nvirb > 0 and nocca > 0: blksize = max(int(max_memory*1e6/8/(nvirb**2*nocca*2)), 2) for p0,p1 in lib.prange(0, nvira, blksize): ovVV = eris.get_ovVV(slice(None), slice(p0,p1)) t1b += lib.einsum('mIeF,meAF->IA', c2ab[:,:,p0:p1], ovVV) t2ab[:,:,p0:p1] += lib.einsum('maBE,IE->mIaB', ovVV, c1b) ovVV = None if nvira > 0 and noccb > 0: blksize = max(int(max_memory*1e6/8/(nvira**2*noccb*2)), 2) for p0,p1 in lib.prange(0, nvirb, blksize): OVvv = eris.get_OVvv(slice(None), slice(p0,p1)) t1a += lib.einsum('iMfE,MEaf->ia', c2ab[:,:,:,p0:p1], OVvv) t2ab[:,:,:,p0:p1] += lib.einsum('MBae,ie->iMaB', OVvv, c1a) OVvv = None #:t1 = einsum('ie,ae->ia', c1, fvv) t1a += lib.einsum('ie,ae->ia', c1a, fvva) t1b += lib.einsum('ie,ae->ia', c1b, fvvb) #:t1 -= einsum('ma,mi->ia', c1, foo) t1a -= lib.einsum('ma,mi->ia', c1a, fooa) t1b -= lib.einsum('ma,mi->ia', c1b, foob) #:t1 += einsum('imae,me->ia', c2, fov) t1a += numpy.einsum('imae,me->ia', c2aa, fova) t1a += numpy.einsum('imae,me->ia', c2ab, fovb) t1b += numpy.einsum('imae,me->ia', c2bb, fovb) t1b += numpy.einsum('miea,me->ia', c2ab, fova) #:tmp = einsum('ijae,be->ijab', c2, fvv) #:t2 = tmp - tmp.transpose(0,1,3,2) t2aa += lib.einsum('ijae,be->ijab', c2aa, fvva*.5) t2bb += lib.einsum('ijae,be->ijab', c2bb, fvvb*.5) t2ab += lib.einsum('iJaE,BE->iJaB', c2ab, fvvb) t2ab += lib.einsum('iJeA,be->iJbA', c2ab, fvva) #:tmp = einsum('imab,mj->ijab', c2, foo) #:t2 -= tmp - tmp.transpose(1,0,2,3) t2aa -= lib.einsum('imab,mj->ijab', c2aa, fooa*.5) t2bb -= lib.einsum('imab,mj->ijab', c2bb, foob*.5) t2ab -= lib.einsum('iMaB,MJ->iJaB', c2ab, foob) t2ab -= lib.einsum('mIaB,mj->jIaB', c2ab, fooa) #:tmp = numpy.einsum('ia,bj->ijab', c1, fvo) #:tmp = tmp - tmp.transpose(0,1,3,2) #:t2 += tmp - tmp.transpose(1,0,2,3) t2aa += numpy.einsum('ia,bj->ijab', c1a, fvoa) t2bb += numpy.einsum('ia,bj->ijab', c1b, fvob) t2ab += numpy.einsum('ia,bj->ijab', c1a, fvob) t2ab += numpy.einsum('ia,bj->jiba', c1b, fvoa) t2aa = t2aa - t2aa.transpose(0,1,3,2) t2aa = t2aa - t2aa.transpose(1,0,2,3) t2bb = t2bb - t2bb.transpose(0,1,3,2) t2bb = t2bb - t2bb.transpose(1,0,2,3) #:t2 += 0.5*einsum('mnab,mnij->ijab', c2, eris.oooo) eris_oooo = _cp(eris.oooo) eris_OOOO = _cp(eris.OOOO) eris_ooOO = _cp(eris.ooOO) t2aa += lib.einsum('mnab,minj->ijab', c2aa, eris_oooo) t2bb += lib.einsum('mnab,minj->ijab', c2bb, eris_OOOO) t2ab += lib.einsum('mNaB,miNJ->iJaB', c2ab, eris_ooOO) #:t1 += fov.conj() * c0 t1a += fova.conj() * c0 t1b += fovb.conj() * c0 #:t0 = numpy.einsum('ia,ia', fov, c1) t0 += numpy.einsum('ia,ia', fova, c1a) t0 += numpy.einsum('ia,ia', fovb, c1b) return amplitudes_to_cisdvec(t0, (t1a,t1b), (t2aa,t2ab,t2bb))
[docs] def amplitudes_to_cisdvec(c0, c1, c2): c1a, c1b = c1 c2aa, c2ab, c2bb = c2 nocca, nvira = c1a.shape noccb, nvirb = c1b.shape def trilidx(n): idx = numpy.tril_indices(n, -1) return idx[0] * n + idx[1] ooidxa = trilidx(nocca) vvidxa = trilidx(nvira) ooidxb = trilidx(noccb) vvidxb = trilidx(nvirb) size = (1, nocca*nvira, noccb*nvirb, nocca*noccb*nvira*nvirb, len(ooidxa)*len(vvidxa), len(ooidxb)*len(vvidxb)) loc = numpy.cumsum(size) civec = numpy.empty(loc[-1], dtype=c2ab.dtype) civec[0] = c0 civec[loc[0]:loc[1]] = c1a.ravel() civec[loc[1]:loc[2]] = c1b.ravel() civec[loc[2]:loc[3]] = c2ab.ravel() lib.take_2d(c2aa.reshape(nocca**2,nvira**2), ooidxa, vvidxa, out=civec[loc[3]:loc[4]]) lib.take_2d(c2bb.reshape(noccb**2,nvirb**2), ooidxb, vvidxb, out=civec[loc[4]:loc[5]]) return civec
[docs] def cisdvec_to_amplitudes(civec, nmo, nocc, copy=True): norba, norbb = nmo nocca, noccb = nocc nvira = norba - nocca nvirb = norbb - noccb nooa = nocca * (nocca-1) // 2 nvva = nvira * (nvira-1) // 2 noob = noccb * (noccb-1) // 2 nvvb = nvirb * (nvirb-1) // 2 size = (1, nocca*nvira, noccb*nvirb, nocca*noccb*nvira*nvirb, nooa*nvva, noob*nvvb) loc = numpy.cumsum(size) c0 = civec[0] cp = lambda x: (x.copy() if copy else x) c1a = cp(civec[loc[0]:loc[1]].reshape(nocca,nvira)) c1b = cp(civec[loc[1]:loc[2]].reshape(noccb,nvirb)) c2ab = cp(civec[loc[2]:loc[3]].reshape(nocca,noccb,nvira,nvirb)) c2aa = _unpack_4fold(civec[loc[3]:loc[4]], nocca, nvira) c2bb = _unpack_4fold(civec[loc[4]:loc[5]], noccb, nvirb) return c0, (c1a,c1b), (c2aa,c2ab,c2bb)
[docs] def to_fcivec(cisdvec, norb, nelec, frozen=None): '''Convert CISD coefficients to FCI coefficients''' if isinstance(nelec, (int, numpy.number)): nelecb = nelec//2 neleca = nelec - nelecb else: neleca, nelecb = nelec frozena_mask = numpy.zeros(norb, dtype=bool) frozenb_mask = numpy.zeros(norb, dtype=bool) if frozen is None: nfroza = nfrozb = 0 elif isinstance(frozen, (int, numpy.integer)): nfroza = nfrozb = frozen frozena_mask[:frozen] = True frozenb_mask[:frozen] = True else: nfroza = len(frozen[0]) nfrozb = len(frozen[1]) frozena_mask[frozen[0]] = True frozenb_mask[frozen[1]] = True # if nfroza != nfrozb: # raise NotImplementedError nocca = numpy.count_nonzero(~frozena_mask[:neleca]) noccb = numpy.count_nonzero(~frozenb_mask[:nelecb]) nmo = nmoa, nmob = norb - nfroza, norb - nfrozb nocc = nocca, noccb nvira, nvirb = nmoa - nocca, nmob - noccb c0, c1, c2 = cisdvec_to_amplitudes(cisdvec, nmo, nocc, copy=False) c1a, c1b = c1 c2aa, c2ab, c2bb = c2 t1addra, t1signa = cisd.tn_addrs_signs(nmoa, nocca, 1) t1addrb, t1signb = cisd.tn_addrs_signs(nmob, noccb, 1) na = cistring.num_strings(nmoa, nocca) nb = cistring.num_strings(nmob, noccb) fcivec = numpy.zeros((na,nb)) fcivec[0,0] = c0 fcivec[t1addra,0] = c1a.ravel() * t1signa fcivec[0,t1addrb] = c1b.ravel() * t1signb c2ab = c2ab.transpose(0,2,1,3).reshape(nocca*nvira,-1) c2ab = numpy.einsum('i,j,ij->ij', t1signa, t1signb, c2ab) fcivec[t1addra[:,None],t1addrb] = c2ab if nocca > 1 and nvira > 1: ooidx = numpy.tril_indices(nocca, -1) vvidx = numpy.tril_indices(nvira, -1) c2aa = c2aa[ooidx][:,vvidx[0],vvidx[1]] t2addra, t2signa = cisd.tn_addrs_signs(nmoa, nocca, 2) fcivec[t2addra,0] = c2aa.ravel() * t2signa if noccb > 1 and nvirb > 1: ooidx = numpy.tril_indices(noccb, -1) vvidx = numpy.tril_indices(nvirb, -1) c2bb = c2bb[ooidx][:,vvidx[0],vvidx[1]] t2addrb, t2signb = cisd.tn_addrs_signs(nmob, noccb, 2) fcivec[0,t2addrb] = c2bb.ravel() * t2signb if nfroza == nfrozb == 0: return fcivec assert (norb < 63) strsa = cistring.gen_strings4orblist(range(norb), neleca) strsb = cistring.gen_strings4orblist(range(norb), nelecb) na = len(strsa) nb = len(strsb) count_a = numpy.zeros(na, dtype=int) count_b = numpy.zeros(nb, dtype=int) parity_a = numpy.zeros(na, dtype=bool) parity_b = numpy.zeros(nb, dtype=bool) core_a_mask = numpy.ones(na, dtype=bool) core_b_mask = numpy.ones(nb, dtype=bool) for i in range(norb): if frozena_mask[i]: if i < neleca: core_a_mask &= (strsa & (1 <<i )) != 0 parity_a ^= (count_a & 1) == 1 else: core_a_mask &= (strsa & (1 << i)) == 0 else: count_a += (strsa & (1 << i)) != 0 if frozenb_mask[i]: if i < nelecb: core_b_mask &= (strsb & (1 <<i )) != 0 parity_b ^= (count_b & 1) == 1 else: core_b_mask &= (strsb & (1 << i)) == 0 else: count_b += (strsb & (1 << i)) != 0 sub_strsa = strsa[core_a_mask & (count_a == nocca)] sub_strsb = strsb[core_b_mask & (count_b == noccb)] addrsa = cistring.strs2addr(norb, neleca, sub_strsa) addrsb = cistring.strs2addr(norb, nelecb, sub_strsb) fcivec1 = numpy.zeros((na,nb)) fcivec1[addrsa[:,None],addrsb] = fcivec fcivec1[parity_a,:] *= -1 fcivec1[:,parity_b] *= -1 return fcivec1
[docs] def from_fcivec(ci0, norb, nelec, frozen=None): '''Extract CISD coefficients from FCI coefficients''' if not (frozen is None or frozen == 0): raise NotImplementedError if isinstance(nelec, (int, numpy.number)): nelecb = nelec//2 neleca = nelec - nelecb else: neleca, nelecb = nelec norba = norbb = norb nocca, noccb = neleca, nelecb nvira = norba - nocca nvirb = norbb - noccb t1addra, t1signa = cisd.tn_addrs_signs(norba, nocca, 1) t1addrb, t1signb = cisd.tn_addrs_signs(norbb, noccb, 1) na = cistring.num_strings(norba, nocca) nb = cistring.num_strings(norbb, noccb) ci0 = ci0.reshape(na,nb) c0 = ci0[0,0] c1a = (ci0[t1addra,0] * t1signa).reshape(nocca,nvira) c1b = (ci0[0,t1addrb] * t1signb).reshape(noccb,nvirb) c2ab = numpy.einsum('i,j,ij->ij', t1signa, t1signb, ci0[t1addra[:,None],t1addrb]) c2ab = c2ab.reshape(nocca,nvira,noccb,nvirb).transpose(0,2,1,3) t2addra, t2signa = cisd.tn_addrs_signs(norba, nocca, 2) t2addrb, t2signb = cisd.tn_addrs_signs(norbb, noccb, 2) c2aa = (ci0[t2addra,0] * t2signa).reshape(nocca*(nocca-1)//2, nvira*(nvira-1)//2) c2aa = _unpack_4fold(c2aa, nocca, nvira) c2bb = (ci0[0,t2addrb] * t2signb).reshape(noccb*(noccb-1)//2, nvirb*(nvirb-1)//2) c2bb = _unpack_4fold(c2bb, noccb, nvirb) return amplitudes_to_cisdvec(c0, (c1a,c1b), (c2aa,c2ab,c2bb))
[docs] def overlap(cibra, ciket, nmo, nocc, s=None): '''Overlap between two CISD wavefunctions. Args: s : a list of 2D arrays The overlap matrix of non-orthogonal one-particle basis ''' if s is None: return numpy.dot(cibra, ciket, nmo, nocc) if isinstance(nmo, (int, numpy.integer)): nmoa = nmob = nmo else: nmoa, nmob = nmo nocca, noccb = nocc nvira, nvirb = nmoa - nocca, nmob - noccb bra0, bra1, bra2 = cisdvec_to_amplitudes(cibra, (nmoa,nmob), nocc, copy=False) ket0, ket1, ket2 = cisdvec_to_amplitudes(ciket, (nmoa,nmob), nocc, copy=False) ooidx = numpy.tril_indices(nocca, -1) vvidx = numpy.tril_indices(nvira, -1) bra2aa = lib.take_2d(bra2[0].reshape(nocca**2,nvira**2), ooidx[0]*nocca+ooidx[1], vvidx[0]*nvira+vvidx[1]) ket2aa = lib.take_2d(ket2[0].reshape(nocca**2,nvira**2), ooidx[0]*nocca+ooidx[1], vvidx[0]*nvira+vvidx[1]) ooidx = numpy.tril_indices(noccb, -1) vvidx = numpy.tril_indices(nvirb, -1) bra2bb = lib.take_2d(bra2[2].reshape(noccb**2,nvirb**2), ooidx[0]*noccb+ooidx[1], vvidx[0]*nvirb+vvidx[1]) ket2bb = lib.take_2d(ket2[2].reshape(noccb**2,nvirb**2), ooidx[0]*noccb+ooidx[1], vvidx[0]*nvirb+vvidx[1]) nova = nocca * nvira novb = noccb * nvirb occlist0a = numpy.arange(nocca).reshape(1,nocca) occlist0b = numpy.arange(noccb).reshape(1,noccb) occlistsa = numpy.repeat(occlist0a, 1+nova+bra2aa.size, axis=0) occlistsb = numpy.repeat(occlist0b, 1+novb+bra2bb.size, axis=0) occlist0a = occlistsa[:1] occlist1a = occlistsa[1:1+nova] occlist2a = occlistsa[1+nova:] occlist0b = occlistsb[:1] occlist1b = occlistsb[1:1+novb] occlist2b = occlistsb[1+novb:] ia = 0 for i in range(nocca): for a in range(nocca, nmoa): occlist1a[ia,i] = a ia += 1 ia = 0 for i in range(noccb): for a in range(noccb, nmob): occlist1b[ia,i] = a ia += 1 ia = 0 for i in range(nocca): for j in range(i): for a in range(nocca, nmoa): for b in range(nocca, a): occlist2a[ia,i] = a occlist2a[ia,j] = b ia += 1 ia = 0 for i in range(noccb): for j in range(i): for a in range(noccb, nmob): for b in range(noccb, a): occlist2b[ia,i] = a occlist2b[ia,j] = b ia += 1 na = len(occlistsa) trans_a = numpy.empty((na,na)) for i, idx in enumerate(occlistsa): s_sub = s[0][idx].T.copy() minors = s_sub[occlistsa] trans_a[i,:] = numpy.linalg.det(minors) nb = len(occlistsb) trans_b = numpy.empty((nb,nb)) for i, idx in enumerate(occlistsb): s_sub = s[1][idx].T.copy() minors = s_sub[occlistsb] trans_b[i,:] = numpy.linalg.det(minors) # Mimic the transformation einsum('ab,ap->pb', FCI, trans). # The wavefunction FCI has the [excitation_alpha,excitation_beta] # representation. The zero blocks like FCI[S_alpha,D_beta], # FCI[D_alpha,D_beta], are explicitly excluded. bra_mat = numpy.zeros((na,nb)) bra_mat[0,0] = bra0 bra_mat[1:1+nova,0] = bra1[0].ravel() bra_mat[0,1:1+novb] = bra1[1].ravel() bra_mat[1+nova:,0] = bra2aa.ravel() bra_mat[0,1+novb:] = bra2bb.ravel() bra_mat[1:1+nova,1:1+novb] = bra2[1].transpose(0,2,1,3).reshape(nova,novb) c_s = lib.einsum('ab,ap,bq->pq', bra_mat, trans_a, trans_b) ovlp = c_s[0,0] * ket0 ovlp += numpy.dot(c_s[1:1+nova,0], ket1[0].ravel()) ovlp += numpy.dot(c_s[0,1:1+novb], ket1[1].ravel()) ovlp += numpy.dot(c_s[1+nova:,0] , ket2aa.ravel()) ovlp += numpy.dot(c_s[0,1+novb:] , ket2bb.ravel()) ovlp += numpy.einsum('ijab,iajb->', ket2[1], c_s[1:1+nova,1:1+novb].reshape(nocca,nvira,noccb,nvirb)) return ovlp
[docs] def make_rdm1(myci, civec=None, nmo=None, nocc=None, ao_repr=False): r''' One-particle spin density matrices dm1a, dm1b in MO basis (the occupied-virtual blocks due to the orbital response contribution are not included). dm1a[p,q] = <q_alpha^\dagger p_alpha> dm1b[p,q] = <q_beta^\dagger p_beta> The convention of 1-pdm is based on McWeeney's book, Eq (5.4.20). ''' if civec is None: civec = myci.ci if nmo is None: nmo = myci.nmo if nocc is None: nocc = myci.nocc d1 = _gamma1_intermediates(myci, civec, nmo, nocc) return uccsd_rdm._make_rdm1(myci, d1, with_frozen=True, ao_repr=ao_repr)
[docs] def make_rdm2(myci, civec=None, nmo=None, nocc=None, ao_repr=False): r''' Two-particle spin density matrices dm2aa, dm2ab, dm2bb in MO basis dm2aa[p,q,r,s] = <q_alpha^\dagger s_alpha^\dagger r_alpha p_alpha> dm2ab[p,q,r,s] = <q_alpha^\dagger s_beta^\dagger r_beta p_alpha> dm2bb[p,q,r,s] = <q_beta^\dagger s_beta^\dagger r_beta p_beta> (p,q correspond to one particle and r,s correspond to another particle) Two-particle density matrix should be contracted to integrals with the pattern below to compute energy E = numpy.einsum('pqrs,pqrs', eri_aa, dm2_aa) E+= numpy.einsum('pqrs,pqrs', eri_ab, dm2_ab) E+= numpy.einsum('pqrs,rspq', eri_ba, dm2_ab) E+= numpy.einsum('pqrs,pqrs', eri_bb, dm2_bb) where eri_aa[p,q,r,s] = (p_alpha q_alpha | r_alpha s_alpha ) eri_ab[p,q,r,s] = ( p_alpha q_alpha | r_beta s_beta ) eri_ba[p,q,r,s] = ( p_beta q_beta | r_alpha s_alpha ) eri_bb[p,q,r,s] = ( p_beta q_beta | r_beta s_beta ) ''' if civec is None: civec = myci.ci if nmo is None: nmo = myci.nmo if nocc is None: nocc = myci.nocc d1 = _gamma1_intermediates(myci, civec, nmo, nocc) d2 = _gamma2_intermediates(myci, civec, nmo, nocc) return uccsd_rdm._make_rdm2(myci, d1, d2, with_dm1=True, with_frozen=True, ao_repr=ao_repr)
def _gamma1_intermediates(myci, civec, nmo, nocc): nmoa, nmob = nmo nocca, noccb = nocc c0, c1, c2 = cisdvec_to_amplitudes(civec, nmo, nocc, copy=False) c1a, c1b = c1 c2aa, c2ab, c2bb = c2 dvoa = c0.conj() * c1a.T dvob = c0.conj() * c1b.T dvoa += numpy.einsum('jb,ijab->ai', c1a.conj(), c2aa) dvoa += numpy.einsum('jb,ijab->ai', c1b.conj(), c2ab) dvob += numpy.einsum('jb,ijab->ai', c1b.conj(), c2bb) dvob += numpy.einsum('jb,jiba->ai', c1a.conj(), c2ab) dova = dvoa.T.conj() dovb = dvob.T.conj() dooa =-numpy.einsum('ia,ka->ik', c1a.conj(), c1a) doob =-numpy.einsum('ia,ka->ik', c1b.conj(), c1b) dooa -= numpy.einsum('ijab,ikab->jk', c2aa.conj(), c2aa) * .5 dooa -= numpy.einsum('jiab,kiab->jk', c2ab.conj(), c2ab) doob -= numpy.einsum('ijab,ikab->jk', c2bb.conj(), c2bb) * .5 doob -= numpy.einsum('ijab,ikab->jk', c2ab.conj(), c2ab) dvva = numpy.einsum('ia,ic->ac', c1a, c1a.conj()) dvvb = numpy.einsum('ia,ic->ac', c1b, c1b.conj()) dvva += numpy.einsum('ijab,ijac->bc', c2aa, c2aa.conj()) * .5 dvva += numpy.einsum('ijba,ijca->bc', c2ab, c2ab.conj()) dvvb += numpy.einsum('ijba,ijca->bc', c2bb, c2bb.conj()) * .5 dvvb += numpy.einsum('ijab,ijac->bc', c2ab, c2ab.conj()) return (dooa, doob), (dova, dovb), (dvoa, dvob), (dvva, dvvb) def _gamma2_intermediates(myci, civec, nmo, nocc): nmoa, nmob = nmo nocca, noccb = nocc c0, c1, c2 = cisdvec_to_amplitudes(civec, nmo, nocc, copy=False) c1a, c1b = c1 c2aa, c2ab, c2bb = c2 goovv = c0 * c2aa.conj() * .5 goOvV = c0 * c2ab.conj() gOOVV = c0 * c2bb.conj() * .5 govvv = numpy.einsum('ia,ikcd->kadc', c1a, c2aa.conj()) * .5 gOvVv = numpy.einsum('ia,ikcd->kadc', c1a, c2ab.conj()) goVvV = numpy.einsum('ia,kidc->kadc', c1b, c2ab.conj()) gOVVV = numpy.einsum('ia,ikcd->kadc', c1b, c2bb.conj()) * .5 gooov = numpy.einsum('ia,klac->klic', c1a, c2aa.conj()) *-.5 goOoV =-numpy.einsum('ia,klac->klic', c1a, c2ab.conj()) gOoOv =-numpy.einsum('ia,lkca->klic', c1b, c2ab.conj()) gOOOV = numpy.einsum('ia,klac->klic', c1b, c2bb.conj()) *-.5 goooo = numpy.einsum('ijab,klab->ijkl', c2aa.conj(), c2aa) * .25 goOoO = numpy.einsum('ijab,klab->ijkl', c2ab.conj(), c2ab) gOOOO = numpy.einsum('ijab,klab->ijkl', c2bb.conj(), c2bb) * .25 gvvvv = numpy.einsum('ijab,ijcd->abcd', c2aa, c2aa.conj()) * .25 gvVvV = numpy.einsum('ijab,ijcd->abcd', c2ab, c2ab.conj()) gVVVV = numpy.einsum('ijab,ijcd->abcd', c2bb, c2bb.conj()) * .25 goVoV = numpy.einsum('jIaB,kIaC->jCkB', c2ab.conj(), c2ab) gOvOv = numpy.einsum('iJbA,iKcA->JcKb', c2ab.conj(), c2ab) govvo = numpy.einsum('ijab,ikac->jcbk', c2aa.conj(), c2aa) govvo+= numpy.einsum('jIbA,kIcA->jcbk', c2ab.conj(), c2ab) goVvO = numpy.einsum('jIbA,IKAC->jCbK', c2ab.conj(), c2bb) goVvO+= numpy.einsum('ijab,iKaC->jCbK', c2aa.conj(), c2ab) gOVVO = numpy.einsum('ijab,ikac->jcbk', c2bb.conj(), c2bb) gOVVO+= numpy.einsum('iJaB,iKaC->JCBK', c2ab.conj(), c2ab) govvo+= numpy.einsum('ia,jb->ibaj', c1a.conj(), c1a) goVvO+= numpy.einsum('ia,jb->ibaj', c1a.conj(), c1b) gOVVO+= numpy.einsum('ia,jb->ibaj', c1b.conj(), c1b) dovov = goovv.transpose(0,2,1,3) - goovv.transpose(0,3,1,2) doooo = goooo.transpose(0,2,1,3) - goooo.transpose(0,3,1,2) dvvvv = gvvvv.transpose(0,2,1,3) - gvvvv.transpose(0,3,1,2) dovvo = govvo.transpose(0,2,1,3) dooov = gooov.transpose(0,2,1,3) - gooov.transpose(1,2,0,3) dovvv = govvv.transpose(0,2,1,3) - govvv.transpose(0,3,1,2) doovv =-dovvo.transpose(0,3,2,1) dvvov = None dOVOV = gOOVV.transpose(0,2,1,3) - gOOVV.transpose(0,3,1,2) dOOOO = gOOOO.transpose(0,2,1,3) - gOOOO.transpose(0,3,1,2) dVVVV = gVVVV.transpose(0,2,1,3) - gVVVV.transpose(0,3,1,2) dOVVO = gOVVO.transpose(0,2,1,3) dOOOV = gOOOV.transpose(0,2,1,3) - gOOOV.transpose(1,2,0,3) dOVVV = gOVVV.transpose(0,2,1,3) - gOVVV.transpose(0,3,1,2) dOOVV =-dOVVO.transpose(0,3,2,1) dVVOV = None dovOV = goOvV.transpose(0,2,1,3) dooOO = goOoO.transpose(0,2,1,3) dvvVV = gvVvV.transpose(0,2,1,3) dovVO = goVvO.transpose(0,2,1,3) dooOV = goOoV.transpose(0,2,1,3) dovVV = goVvV.transpose(0,2,1,3) dooVV = goVoV.transpose(0,2,1,3) dooVV = -(dooVV + dooVV.transpose(1,0,3,2).conj()) * .5 dvvOV = None dOVov = None dOOoo = None dVVvv = None dOVvo = dovVO.transpose(3,2,1,0).conj() dOOov = gOoOv.transpose(0,2,1,3) dOVvv = gOvVv.transpose(0,2,1,3) dOOvv = gOvOv.transpose(0,2,1,3) dOOvv =-(dOOvv + dOOvv.transpose(1,0,3,2).conj()) * .5 dVVov = None return ((dovov, dovOV, dOVov, dOVOV), (dvvvv, dvvVV, dVVvv, dVVVV), (doooo, dooOO, dOOoo, dOOOO), (doovv, dooVV, dOOvv, dOOVV), (dovvo, dovVO, dOVvo, dOVVO), (dvvov, dvvOV, dVVov, dVVOV), (dovvv, dovVV, dOVvv, dOVVV), (dooov, dooOV, dOOov, dOOOV))
[docs] def trans_rdm1(myci, cibra, ciket, nmo=None, nocc=None): r''' One-particle spin density matrices dm1a, dm1b in MO basis (the occupied-virtual blocks due to the orbital response contribution are not included). dm1a[p,q] = <q_alpha^\dagger p_alpha> dm1b[p,q] = <q_beta^\dagger p_beta> The convention of 1-pdm is based on McWeeney's book, Eq (5.4.20). ''' if nmo is None: nmo = myci.nmo if nocc is None: nocc = myci.nocc c0bra, c1bra, c2bra = myci.cisdvec_to_amplitudes(cibra, nmo, nocc, copy=False) c0ket, c1ket, c2ket = myci.cisdvec_to_amplitudes(ciket, nmo, nocc, copy=False) nmoa, nmob = nmo nocca, noccb = nocc bra1a, bra1b = c1bra bra2aa, bra2ab, bra2bb = c2bra ket1a, ket1b = c1ket ket2aa, ket2ab, ket2bb = c2ket dvoa = c0bra.conj() * ket1a.T dvob = c0bra.conj() * ket1b.T dvoa += numpy.einsum('jb,ijab->ai', bra1a.conj(), ket2aa) dvoa += numpy.einsum('jb,ijab->ai', bra1b.conj(), ket2ab) dvob += numpy.einsum('jb,ijab->ai', bra1b.conj(), ket2bb) dvob += numpy.einsum('jb,jiba->ai', bra1a.conj(), ket2ab) dova = c0ket * bra1a.conj() dovb = c0ket * bra1b.conj() dova += numpy.einsum('jb,ijab->ia', ket1a.conj(), bra2aa) dova += numpy.einsum('jb,ijab->ia', ket1b.conj(), bra2ab) dovb += numpy.einsum('jb,ijab->ia', ket1b.conj(), bra2bb) dovb += numpy.einsum('jb,jiba->ia', ket1a.conj(), bra2ab) dooa =-numpy.einsum('ia,ka->ik', bra1a.conj(), ket1a) doob =-numpy.einsum('ia,ka->ik', bra1b.conj(), ket1b) dooa -= numpy.einsum('ijab,ikab->jk', bra2aa.conj(), ket2aa) * .5 dooa -= numpy.einsum('jiab,kiab->jk', bra2ab.conj(), ket2ab) doob -= numpy.einsum('ijab,ikab->jk', bra2bb.conj(), ket2bb) * .5 doob -= numpy.einsum('ijab,ikab->jk', bra2ab.conj(), ket2ab) dvva = numpy.einsum('ia,ic->ac', ket1a, bra1a.conj()) dvvb = numpy.einsum('ia,ic->ac', ket1b, bra1b.conj()) dvva += numpy.einsum('ijab,ijac->bc', ket2aa, bra2aa.conj()) * .5 dvva += numpy.einsum('ijba,ijca->bc', ket2ab, bra2ab.conj()) dvvb += numpy.einsum('ijba,ijca->bc', ket2bb, bra2bb.conj()) * .5 dvvb += numpy.einsum('ijab,ijac->bc', ket2ab, bra2ab.conj()) dm1a = numpy.empty((nmoa,nmoa), dtype=dooa.dtype) dm1a[:nocca,:nocca] = dooa dm1a[:nocca,nocca:] = dova dm1a[nocca:,:nocca] = dvoa dm1a[nocca:,nocca:] = dvva norm = numpy.dot(cibra, ciket) dm1a[numpy.diag_indices(nocca)] += norm dm1b = numpy.empty((nmob,nmob), dtype=dooa.dtype) dm1b[:noccb,:noccb] = doob dm1b[:noccb,noccb:] = dovb dm1b[noccb:,:noccb] = dvob dm1b[noccb:,noccb:] = dvvb dm1b[numpy.diag_indices(noccb)] += norm if myci.frozen is not None: nmoa = myci.mo_occ[0].size nmob = myci.mo_occ[1].size nocca = numpy.count_nonzero(myci.mo_occ[0] > 0) noccb = numpy.count_nonzero(myci.mo_occ[1] > 0) rdm1a = numpy.zeros((nmoa,nmoa), dtype=dm1a.dtype) rdm1b = numpy.zeros((nmob,nmob), dtype=dm1b.dtype) rdm1a[numpy.diag_indices(nocca)] = norm rdm1b[numpy.diag_indices(noccb)] = norm moidx = myci.get_frozen_mask() moidxa = numpy.where(moidx[0])[0] moidxb = numpy.where(moidx[1])[0] rdm1a[moidxa[:,None],moidxa] = dm1a rdm1b[moidxb[:,None],moidxb] = dm1b dm1a = rdm1a dm1b = rdm1b return dm1a, dm1b
[docs] class UCISD(cisd.CISD):
[docs] def vector_size(self): norba, norbb = self.nmo nocca, noccb = self.nocc nvira = norba - nocca nvirb = norbb - noccb nooa = nocca * (nocca-1) // 2 nvva = nvira * (nvira-1) // 2 noob = noccb * (noccb-1) // 2 nvvb = nvirb * (nvirb-1) // 2 size = (1 + nocca*nvira + noccb*nvirb + nocca*noccb*nvira*nvirb + nooa*nvva + noob*nvvb) return size
get_nocc = uccsd.get_nocc get_nmo = uccsd.get_nmo get_frozen_mask = uccsd.get_frozen_mask
[docs] def get_init_guess(self, eris=None, nroots=1, diag=None): if eris is None: eris = self.ao2mo(self.mo_coeff) nocca, noccb = self.nocc mo_ea, mo_eb = eris.mo_energy eia_a = mo_ea[:nocca,None] - mo_ea[None,nocca:] eia_b = mo_eb[:noccb,None] - mo_eb[None,noccb:] t1a = eris.focka[:nocca,nocca:].conj() / eia_a t1b = eris.fockb[:noccb,noccb:].conj() / eia_b eris_ovov = _cp(eris.ovov) eris_ovOV = _cp(eris.ovOV) eris_OVOV = _cp(eris.OVOV) t2aa = eris_ovov.transpose(0,2,1,3) - eris_ovov.transpose(0,2,3,1) t2bb = eris_OVOV.transpose(0,2,1,3) - eris_OVOV.transpose(0,2,3,1) t2ab = eris_ovOV.transpose(0,2,1,3).copy() t2aa = t2aa.conj() t2ab = t2ab.conj() t2bb = t2bb.conj() t2aa /= lib.direct_sum('ia+jb->ijab', eia_a, eia_a) t2ab /= lib.direct_sum('ia+jb->ijab', eia_a, eia_b) t2bb /= lib.direct_sum('ia+jb->ijab', eia_b, eia_b) emp2 = numpy.einsum('iajb,ijab', eris_ovov, t2aa) * .25 emp2 -= numpy.einsum('jaib,ijab', eris_ovov, t2aa) * .25 emp2 += numpy.einsum('iajb,ijab', eris_OVOV, t2bb) * .25 emp2 -= numpy.einsum('jaib,ijab', eris_OVOV, t2bb) * .25 emp2 += numpy.einsum('iajb,ijab', eris_ovOV, t2ab) self.emp2 = emp2.real logger.info(self, 'Init t2, MP2 energy = %.15g', self.emp2) if abs(emp2) < 1e-3 and (abs(t1a).sum()+abs(t1b).sum()) < 1e-3: t1a = 1e-1 / eia_a t1b = 1e-1 / eia_b ci_guess = amplitudes_to_cisdvec(1, (t1a,t1b), (t2aa,t2ab,t2bb)) if nroots > 1: civec_size = ci_guess.size ci1_size = t1a.size + t1b.size dtype = ci_guess.dtype nroots = min(ci1_size+1, nroots) if diag is None: idx = range(1, nroots) else: idx = diag[:ci1_size+1].argsort()[1:nroots] # exclude HF determinant ci_guess = [ci_guess] for i in idx: g = numpy.zeros(civec_size, dtype) g[i] = 1.0 ci_guess.append(g) return self.emp2, ci_guess
contract = contract make_diagonal = make_diagonal _dot = None _add_vvvv = uccsd._add_vvvv
[docs] def ao2mo(self, mo_coeff=None): nmoa, nmob = self.get_nmo() nao = self.mo_coeff[0].shape[0] nmo_pair = nmoa * (nmoa+1) // 2 nao_pair = nao * (nao+1) // 2 mem_incore = (max(nao_pair**2, nmoa**4) + nmo_pair**2) * 8/1e6 mem_now = lib.current_memory()[0] if (self._scf._eri is not None and (mem_incore+mem_now < self.max_memory) or self.mol.incore_anyway): return uccsd._make_eris_incore(self, mo_coeff) elif getattr(self._scf, 'with_df', None): return uccsd._make_df_eris_outcore(self, mo_coeff) else: return uccsd._make_eris_outcore(self, mo_coeff)
[docs] def to_fcivec(self, cisdvec, nmo=None, nocc=None): return to_fcivec(cisdvec, nmo, nocc)
[docs] def from_fcivec(self, fcivec, nmo=None, nocc=None): return from_fcivec(fcivec, nmo, nocc)
[docs] def amplitudes_to_cisdvec(self, c0, c1, c2): return amplitudes_to_cisdvec(c0, c1, c2)
[docs] def cisdvec_to_amplitudes(self, civec, nmo=None, nocc=None, copy=True): if nmo is None: nmo = self.nmo if nocc is None: nocc = self.nocc return cisdvec_to_amplitudes(civec, nmo, nocc, copy=copy)
make_rdm1 = make_rdm1 make_rdm2 = make_rdm2 trans_rdm1 = trans_rdm1
[docs] def nuc_grad_method(self): from pyscf.grad import ucisd return ucisd.Gradients(self)
CISD = UCISD from pyscf import scf scf.uhf.UHF.CISD = lib.class_as_method(CISD) def _cp(a): return numpy.array(a, copy=False, order='C')