Ejemplo n.º 1
0
def gen_vind(mf, mo_coeff, mo_occ):
    '''Induced potential'''
    vresp = _gen_uhf_response(mf, with_j=False, hermi=0)
    occidxa = mo_occ[0] > 0
    occidxb = mo_occ[1] > 0
    orboa = mo_coeff[0][:, occidxa]
    orbva = mo_coeff[0][:, ~occidxa]
    orbob = mo_coeff[1][:, occidxb]
    orbvb = mo_coeff[1][:, ~occidxb]
    nocca = orboa.shape[1]
    noccb = orbob.shape[1]
    nvira = orbva.shape[1]
    nvirb = orbvb.shape[1]
    nova = nocca * nvira
    novb = noccb * nvirb
    mo_va_oa = numpy.asarray(numpy.hstack((orbva, orboa)), order='F')
    mo_vb_ob = numpy.asarray(numpy.hstack((orbvb, orbob)), order='F')

    def vind(mo1):
        mo1a = mo1.reshape(-1, nova + novb)[:, :nova].reshape(-1, nvira, nocca)
        mo1b = mo1.reshape(-1, nova + novb)[:, nova:].reshape(-1, nvirb, noccb)
        nset = mo1a.shape[0]
        dm1a = _dm1_mo2ao(mo1a, orbva, orboa)
        dm1b = _dm1_mo2ao(mo1b, orbvb, orbob)
        dm1 = numpy.vstack(
            [dm1a - dm1a.transpose(0, 2, 1), dm1b - dm1b.transpose(0, 2, 1)])
        v1 = vresp(dm1)
        v1a = _ao2mo.nr_e2(v1[:nset], mo_va_oa,
                           (0, nvira, nvira, nvira + nocca))
        v1b = _ao2mo.nr_e2(v1[nset:], mo_vb_ob,
                           (0, nvirb, nvirb, nvirb + noccb))
        v1mo = numpy.hstack((v1a.reshape(nset, -1), v1b.reshape(nset, -1)))
        return v1mo.ravel()

    return vind
Ejemplo n.º 2
0
    def gen_vind(self, mo1):
        '''Induced potential'''
        vresp = _gen_uhf_response(self._scf, hermi=2)
        mo_coeff = self._scf.mo_coeff
        mo_occ = self._scf.mo_occ
        occidxa = mo_occ[0] > 0
        occidxb = mo_occ[1] > 0
        orboa = mo_coeff[0][:, occidxa]
        orbob = mo_coeff[1][:, occidxb]
        nocca = orboa.shape[1]
        noccb = orbob.shape[1]
        nao, nmo = mo_coeff[0].shape
        nvira = nmo - nocca

        def vind(mo1):
            #direct_scf_bak, self._scf.direct_scf = self._scf.direct_scf, False
            mo1a = mo1.reshape(3, -1)[:, :nocca * nmo].reshape(3, nmo, nocca)
            mo1b = mo1.reshape(3, -1)[:, nocca * nmo:].reshape(3, nmo, noccb)
            dm1a = [
                reduce(numpy.dot, (mo_coeff[0], x, orboa.T.conj()))
                for x in mo1a
            ]
            dm1b = [
                reduce(numpy.dot, (mo_coeff[1], x, orbob.T.conj()))
                for x in mo1b
            ]
            dm1 = numpy.asarray(
                ([d1 - d1.conj().T
                  for d1 in dm1a], [d1 - d1.conj().T for d1 in dm1b]))
            v1ao = vresp(dm1)
            v1a = [
                reduce(numpy.dot, (mo_coeff[0].T.conj(), x, orboa))
                for x in v1ao[0]
            ]
            v1b = [
                reduce(numpy.dot, (mo_coeff[1].T.conj(), x, orbob))
                for x in v1ao[1]
            ]
            v1mo = numpy.hstack((numpy.asarray(v1a).reshape(3, -1),
                                 numpy.asarray(v1b).reshape(3, -1)))
            #self._scf.direct_scf = direct_scf_bak
            return v1mo.ravel()

        return vind
Ejemplo n.º 3
0
def _gen_hop_uhf_external(mf, with_symmetry=True, verbose=None):
    mol = mf.mol
    mo_coeff = mf.mo_coeff
    mo_energy = mf.mo_energy
    mo_occ = mf.mo_occ
    occidxa = numpy.where(mo_occ[0]>0)[0]
    occidxb = numpy.where(mo_occ[1]>0)[0]
    viridxa = numpy.where(mo_occ[0]==0)[0]
    viridxb = numpy.where(mo_occ[1]==0)[0]
    nocca = len(occidxa)
    noccb = len(occidxb)
    nvira = len(viridxa)
    nvirb = len(viridxb)
    orboa = mo_coeff[0][:,occidxa]
    orbob = mo_coeff[1][:,occidxb]
    orbva = mo_coeff[0][:,viridxa]
    orbvb = mo_coeff[1][:,viridxb]

    if with_symmetry and mol.symmetry:
        orbsyma, orbsymb = uhf_symm.get_orbsym(mol, mo_coeff)
        sym_forbida = orbsyma[viridxa].reshape(-1,1) != orbsyma[occidxa]
        sym_forbidb = orbsymb[viridxb].reshape(-1,1) != orbsymb[occidxb]
        sym_forbid1 = numpy.hstack((sym_forbida.ravel(), sym_forbidb.ravel()))

    h1e = mf.get_hcore()
    dm0 = mf.make_rdm1(mo_coeff, mo_occ)
    fock_ao = h1e + mf.get_veff(mol, dm0)
    focka = reduce(numpy.dot, (mo_coeff[0].T, fock_ao[0], mo_coeff[0]))
    fockb = reduce(numpy.dot, (mo_coeff[1].T, fock_ao[1], mo_coeff[1]))
    fooa = focka[occidxa[:,None],occidxa]
    fvva = focka[viridxa[:,None],viridxa]
    foob = fockb[occidxb[:,None],occidxb]
    fvvb = fockb[viridxb[:,None],viridxb]

    h_diaga =(focka[viridxa,viridxa].reshape(-1,1) - focka[occidxa,occidxa])
    h_diagb =(fockb[viridxb,viridxb].reshape(-1,1) - fockb[occidxb,occidxb])
    hdiag1 = numpy.hstack((h_diaga.reshape(-1), h_diagb.reshape(-1)))
    if with_symmetry and mol.symmetry:
        hdiag1[sym_forbid1] = 0

    mem_now = lib.current_memory()[0]
    max_memory = max(2000, mf.max_memory*.8-mem_now)

    vrespz = _gen_uhf_response(mf, with_j=False, hermi=2)
    def hop_real2complex(x1):
        if with_symmetry and mol.symmetry:
            x1 = x1.copy()
            x1[sym_forbid1] = 0
        x1a = x1[:nvira*nocca].reshape(nvira,nocca)
        x1b = x1[nvira*nocca:].reshape(nvirb,noccb)
        x2a = numpy.einsum('pr,rq->pq', fvva, x1a)
        x2a-= numpy.einsum('sq,ps->pq', fooa, x1a)
        x2b = numpy.einsum('pr,rq->pq', fvvb, x1b)
        x2b-= numpy.einsum('qs,ps->pq', foob, x1b)

        d1a = reduce(numpy.dot, (orbva, x1a, orboa.T.conj()))
        d1b = reduce(numpy.dot, (orbvb, x1b, orbob.T.conj()))
        dm1 = numpy.array((d1a-d1a.T.conj(), d1b-d1b.T.conj()))

        v1 = vrespz(dm1)
        x2a += reduce(numpy.dot, (orbva.T.conj(), v1[0], orboa))
        x2b += reduce(numpy.dot, (orbvb.T.conj(), v1[1], orbob))
        x2 = numpy.hstack((x2a.ravel(), x2b.ravel()))
        if with_symmetry and mol.symmetry:
            x2[sym_forbid1] = 0
        return x2

    if with_symmetry and mol.symmetry:
        orbsyma, orbsymb = uhf_symm.get_orbsym(mol, mo_coeff)
        sym_forbidab = orbsyma[viridxa].reshape(-1,1) != orbsymb[occidxb]
        sym_forbidba = orbsymb[viridxb].reshape(-1,1) != orbsyma[occidxa]
        sym_forbid2 = numpy.hstack((sym_forbidab.ravel(), sym_forbidba.ravel()))
    hdiagab = fvva.diagonal().reshape(-1,1) - foob.diagonal()
    hdiagba = fvvb.diagonal().reshape(-1,1) - fooa.diagonal()
    hdiag2 = numpy.hstack((hdiagab.ravel(), hdiagba.ravel()))
    if with_symmetry and mol.symmetry:
        hdiag2[sym_forbid2] = 0

    vresp1 = _gen_uhf_response(mf, with_j=False, hermi=0)
    # Spin flip GHF solution is not considered
    def hop_uhf2ghf(x1):
        if with_symmetry and mol.symmetry:
            x1 = x1.copy()
            x1[sym_forbid2] = 0
        x1ab = x1[:nvira*noccb].reshape(nvira,noccb)
        x1ba = x1[nvira*noccb:].reshape(nvirb,nocca)
        x2ab = numpy.einsum('pr,rq->pq', fvva, x1ab)
        x2ab-= numpy.einsum('sq,ps->pq', foob, x1ab)
        x2ba = numpy.einsum('pr,rq->pq', fvvb, x1ba)
        x2ba-= numpy.einsum('qs,ps->pq', fooa, x1ba)

        d1ab = reduce(numpy.dot, (orbva, x1ab, orbob.T.conj()))
        d1ba = reduce(numpy.dot, (orbvb, x1ba, orboa.T.conj()))
        dm1 = numpy.array((d1ab+d1ba.T.conj(), d1ba+d1ab.T.conj()))
        v1 = vresp1(dm1)
        x2ab += reduce(numpy.dot, (orbva.T.conj(), v1[0], orbob))
        x2ba += reduce(numpy.dot, (orbvb.T.conj(), v1[1], orboa))
        x2 = numpy.hstack((x2ab.ravel(), x2ba.ravel()))
        if with_symmetry and mol.symmetry:
            x2[sym_forbid2] = 0
        return x2

    return hop_real2complex, hdiag1, hop_uhf2ghf, hdiag2
Ejemplo n.º 4
0
def solve_mo1_fc(sscobj, h1):
    cput1 = (time.clock(), time.time())
    log = logger.Logger(sscobj.stdout, sscobj.verbose)
    mol = sscobj.mol
    mo_energy = sscobj._scf.mo_energy
    mo_coeff = sscobj._scf.mo_coeff
    mo_occ = sscobj._scf.mo_occ
    h1aa, h1ab, h1ba, h1bb = h1
    nset = len(h1aa)
    eai_aa = 1. / lib.direct_sum('a-i->ai', mo_energy[0][mo_occ[0]==0], mo_energy[0][mo_occ[0]>0])
    eai_ab = 1. / lib.direct_sum('a-i->ai', mo_energy[0][mo_occ[0]==0], mo_energy[1][mo_occ[1]>0])
    eai_ba = 1. / lib.direct_sum('a-i->ai', mo_energy[1][mo_occ[1]==0], mo_energy[0][mo_occ[0]>0])
    eai_bb = 1. / lib.direct_sum('a-i->ai', mo_energy[1][mo_occ[1]==0], mo_energy[1][mo_occ[1]>0])

    mo1_fc = (numpy.asarray(h1aa) * -eai_aa,
              numpy.asarray(h1ab) * -eai_ab,
              numpy.asarray(h1ba) * -eai_ba,
              numpy.asarray(h1bb) * -eai_bb)
    h1aa = h1ab = h1ba = h1bb = None
    if not sscobj.cphf:
        return mo1_fc

    orboa = mo_coeff[0][:,mo_occ[0]> 0]
    orbva = mo_coeff[0][:,mo_occ[0]==0]
    orbob = mo_coeff[1][:,mo_occ[1]> 0]
    orbvb = mo_coeff[1][:,mo_occ[1]==0]
    nocca = orboa.shape[1]
    nvira = orbva.shape[1]
    noccb = orbob.shape[1]
    nvirb = orbvb.shape[1]
    p1 = nvira * nocca
    p2 = p1 + nvira * noccb
    p3 = p2 + nvirb * nocca
    def _split_mo1(mo1):
        mo1 = mo1.reshape(nset,-1)
        mo1aa = mo1[:,  :p1].reshape(nset,nvira,nocca)
        mo1ab = mo1[:,p1:p2].reshape(nset,nvira,noccb)
        mo1ba = mo1[:,p2:p3].reshape(nset,nvirb,nocca)
        mo1bb = mo1[:,p3:  ].reshape(nset,nvirb,noccb)
        return mo1aa, mo1ab, mo1ba, mo1bb

    mo1_fc = numpy.hstack((mo1_fc[0].reshape(nset,-1),
                           mo1_fc[1].reshape(nset,-1),
                           mo1_fc[2].reshape(nset,-1),
                           mo1_fc[3].reshape(nset,-1)))

    vresp = _gen_uhf_response(mf, with_j=False, hermi=1)
    mo_va_oa = numpy.asarray(numpy.hstack((orbva,orboa)), order='F')
    mo_va_ob = numpy.asarray(numpy.hstack((orbva,orbob)), order='F')
    mo_vb_oa = numpy.asarray(numpy.hstack((orbvb,orboa)), order='F')
    mo_vb_ob = numpy.asarray(numpy.hstack((orbvb,orbob)), order='F')
    def vind(mo1):
        mo1aa, mo1ab, mo1ba, mo1bb = _split_mo1(mo1)
        dm1aa = _dm1_mo2ao(mo1aa, orbva, orboa)
        dm1ab = _dm1_mo2ao(mo1ab, orbva, orbob)
        dm1ba = _dm1_mo2ao(mo1ba, orbvb, orboa)
        dm1bb = _dm1_mo2ao(mo1bb, orbvb, orbob)
        dm1 = numpy.vstack([dm1aa+dm1aa.transpose(0,2,1),
                            dm1ab+dm1ba.transpose(0,2,1),
                            dm1ba+dm1ab.transpose(0,2,1),
                            dm1bb+dm1bb.transpose(0,2,1)])
        v1 = vresp(dm1)
        v1aa = _ao2mo.nr_e2(v1[      :nset  ], mo_va_oa, (0,nvira,nvira,nvira+nocca))
        v1ab = _ao2mo.nr_e2(v1[nset*1:nset*2], mo_va_ob, (0,nvira,nvira,nvira+noccb))
        v1ba = _ao2mo.nr_e2(v1[nset*2:nset*3], mo_vb_oa, (0,nvirb,nvirb,nvirb+nocca))
        v1bb = _ao2mo.nr_e2(v1[nset*3:      ], mo_vb_ob, (0,nvirb,nvirb,nvirb+noccb))
        v1aa = v1aa.reshape(nset,nvira,nocca)
        v1ab = v1ab.reshape(nset,nvira,noccb)
        v1ba = v1ba.reshape(nset,nvirb,nocca)
        v1bb = v1bb.reshape(nset,nvirb,noccb)
        v1aa *= eai_aa
        v1ab *= eai_ab
        v1ba *= eai_ba
        v1bb *= eai_bb
        v1mo = numpy.hstack((v1aa.reshape(nset,-1), v1ab.reshape(nset,-1),
                             v1ba.reshape(nset,-1), v1bb.reshape(nset,-1)))
        return v1mo.ravel()

    mo1 = lib.krylov(vind, mo1_fc.ravel(), tol=1e-9, max_cycle=20, verbose=log)
    log.timer('solving FC CPHF eqn', *cput1)
    mo1_fc = _split_mo1(mo1)
    return mo1_fc
Ejemplo n.º 5
0
    def get_vind(self, mf):
        '''
        [ A  B][X]
        [-B -A][Y]
        '''
        wfnsym = self.wfnsym
        singlet = self.singlet

        mol = mf.mol
        mo_coeff = mf.mo_coeff
        assert (mo_coeff[0].dtype == numpy.double)
        mo_energy = mf.mo_energy
        mo_occ = mf.mo_occ
        nao, nmo = mo_coeff[0].shape
        occidxa = numpy.where(mo_occ[0] > 0)[0]
        occidxb = numpy.where(mo_occ[1] > 0)[0]
        viridxa = numpy.where(mo_occ[0] == 0)[0]
        viridxb = numpy.where(mo_occ[1] == 0)[0]
        nocca = len(occidxa)
        noccb = len(occidxb)
        nvira = len(viridxa)
        nvirb = len(viridxb)
        orboa = mo_coeff[0][:, occidxa]
        orbob = mo_coeff[1][:, occidxb]
        orbva = mo_coeff[0][:, viridxa]
        orbvb = mo_coeff[1][:, viridxb]

        if wfnsym is not None and mol.symmetry:
            orbsyma, orbsymb = uhf_symm.get_orbsym(mol, mo_coeff)
            sym_forbida = (orbsyma[viridxa].reshape(-1, 1)
                           ^ orbsyma[occidxa]) != wfnsym
            sym_forbidb = (orbsymb[viridxb].reshape(-1, 1)
                           ^ orbsymb[occidxb]) != wfnsym
            sym_forbid = numpy.hstack(
                (sym_forbida.ravel(), sym_forbidb.ravel()))

        e_ai_a = mo_energy[0][viridxa].reshape(-1, 1) - mo_energy[0][occidxa]
        e_ai_b = mo_energy[1][viridxb].reshape(-1, 1) - mo_energy[1][occidxb]
        e_ai = hdiag = numpy.hstack((e_ai_a.reshape(-1), e_ai_b.reshape(-1)))
        if wfnsym is not None and mol.symmetry:
            hdiag[sym_forbid] = 0
        hdiag = numpy.hstack((hdiag.ravel(), hdiag.ravel()))
        mo_a = numpy.asarray(numpy.hstack((orboa, orbva)), order='F')
        mo_b = numpy.asarray(numpy.hstack((orbob, orbvb)), order='F')

        mem_now = lib.current_memory()[0]
        max_memory = max(2000, self.max_memory * .8 - mem_now)
        vresp = _gen_uhf_response(mf, hermi=0, max_memory=max_memory)

        def vind(xys):
            nz = len(xys)
            if wfnsym is not None and mol.symmetry:
                # shape(nz,2,-1): 2 ~ X,Y
                xys = numpy.copy(zs).reshape(nz, 2, -1)
                xys[:, :, :, sym_forbid] = 0
            dms = numpy.empty((2, nz, nao, nao))  # 2 ~ alpha,beta
            for i in range(nz):
                x, y = xys[i].reshape(2, -1)
                xa = x[:nocca * nvira].reshape(nvira, nocca)
                xb = x[nocca * nvira:].reshape(nvirb, noccb)
                ya = y[:nocca * nvira].reshape(nvira, nocca)
                yb = y[nocca * nvira:].reshape(nvirb, noccb)
                dmx = reduce(numpy.dot, (orbva, xa, orboa.T))
                dmy = reduce(numpy.dot, (orboa, ya.T, orbva.T))
                dms[0, i] = dmx + dmy  # AX + BY
                dmx = reduce(numpy.dot, (orbvb, xb, orbob.T))
                dmy = reduce(numpy.dot, (orbob, yb.T, orbvb.T))
                dms[1, i] = dmx + dmy  # AX + BY

            v1ao = vresp(dms)
            v1avo = _ao2mo.nr_e2(v1ao[0], mo_a, (nocca, nmo, 0, nocca))
            v1bvo = _ao2mo.nr_e2(v1ao[1], mo_b, (noccb, nmo, 0, noccb))
            v1aov = _ao2mo.nr_e2(v1ao[0], mo_a, (0, nocca, nocca, nmo))
            v1bov = _ao2mo.nr_e2(v1ao[1], mo_b, (0, noccb, noccb, nmo))
            hx = numpy.empty((nz, 2, nvira * nocca + nvirb * noccb),
                             dtype=v1avo.dtype)
            for i in range(nz):
                x, y = xys[i].reshape(2, -1)
                hx[i, 0, :nvira * nocca] = v1avo[i].ravel()
                hx[i, 0, nvira * nocca:] = v1bvo[i].ravel()
                hx[i, 0] += e_ai * x  # AX
                hx[i, 1, :nvira *
                   nocca] = -v1aov[i].reshape(nocca, nvira).T.ravel()
                hx[i, 1,
                   nvira * nocca:] = -v1bov[i].reshape(noccb, nvirb).T.ravel()
                hx[i, 1] -= e_ai * y  #-AY

            if wfnsym is not None and mol.symmetry:
                hx[:, :, sym_forbid] = 0
            return hx.reshape(nz, -1)

        return vind, hdiag
Ejemplo n.º 6
0
def gen_tda_hop(mf, fock_ao=None, wfnsym=None, max_memory=2000):
    '''(A+B)x
    
    Kwargs:
        wfnsym : int
            Point group symmetry for excited CIS wavefunction.
    '''
    mol = mf.mol
    mo_coeff = mf.mo_coeff
    assert (mo_coeff[0].dtype == numpy.double)
    mo_energy = mf.mo_energy
    mo_occ = mf.mo_occ
    nao, nmo = mo_coeff[0].shape
    occidxa = numpy.where(mo_occ[0] > 0)[0]
    occidxb = numpy.where(mo_occ[1] > 0)[0]
    viridxa = numpy.where(mo_occ[0] == 0)[0]
    viridxb = numpy.where(mo_occ[1] == 0)[0]
    nocca = len(occidxa)
    noccb = len(occidxb)
    nvira = len(viridxa)
    nvirb = len(viridxb)
    orboa = mo_coeff[0][:, occidxa]
    orbob = mo_coeff[1][:, occidxb]
    orbva = mo_coeff[0][:, viridxa]
    orbvb = mo_coeff[1][:, viridxb]

    if wfnsym is not None and mol.symmetry:
        orbsyma, orbsymb = uhf_symm.get_orbsym(mol, mo_coeff)
        sym_forbida = (orbsyma[viridxa].reshape(-1, 1)
                       ^ orbsyma[occidxa]) != wfnsym
        sym_forbidb = (orbsymb[viridxb].reshape(-1, 1)
                       ^ orbsymb[occidxb]) != wfnsym
        sym_forbid = numpy.hstack((sym_forbida.ravel(), sym_forbidb.ravel()))

    e_ai_a = mo_energy[0][viridxa].reshape(-1, 1) - mo_energy[0][occidxa]
    e_ai_b = mo_energy[1][viridxb].reshape(-1, 1) - mo_energy[1][occidxb]
    e_ai = hdiag = numpy.hstack((e_ai_a.reshape(-1), e_ai_b.reshape(-1)))
    if wfnsym is not None and mol.symmetry:
        hdiag[sym_forbid] = 0
    mo_a = numpy.asarray(numpy.hstack((orboa, orbva)), order='F')
    mo_b = numpy.asarray(numpy.hstack((orbob, orbvb)), order='F')

    mem_now = lib.current_memory()[0]
    max_memory = max(2000, max_memory * .8 - mem_now)
    vresp = _gen_uhf_response(mf, hermi=0, max_memory=max_memory)

    def vind(zs):
        nz = len(zs)
        if wfnsym is not None and mol.symmetry:
            zs = numpy.copy(zs)
            zs[:, sym_forbid] = 0
        dmvo = numpy.empty((2, nz, nao, nao))
        for i, z in enumerate(zs):
            za = z[:nocca * nvira].reshape(nvira, nocca)
            zb = z[nocca * nvira:].reshape(nvirb, noccb)
            dmvo[0, i] = reduce(numpy.dot, (orbva, za, orboa.T))
            dmvo[1, i] = reduce(numpy.dot, (orbvb, zb, orbob.T))

        v1ao = vresp(dmvo)
        v1a = _ao2mo.nr_e2(v1ao[0], mo_a,
                           (nocca, nmo, 0, nocca)).reshape(-1, nvira, nocca)
        v1b = _ao2mo.nr_e2(v1ao[1], mo_b,
                           (noccb, nmo, 0, noccb)).reshape(-1, nvirb, noccb)
        for i, z in enumerate(zs):
            za = z[:nocca * nvira].reshape(nvira, nocca)
            zb = z[nocca * nvira:].reshape(nvirb, noccb)
            v1a[i] += numpy.einsum('ai,ai->ai', e_ai_a, za)
            v1b[i] += numpy.einsum('ai,ai->ai', e_ai_b, zb)
        hx = numpy.hstack((v1a.reshape(nz, -1), v1b.reshape(nz, -1)))
        if wfnsym is not None and mol.symmetry:
            hx[:, sym_forbid] = 0
        return hx

    return vind, hdiag