예제 #1
0
파일: krhf.py 프로젝트: yoshida-lab/pyscf
    def get_vind(self, mf):
        '''
        [ A   B ][X]
        [-B* -A*][Y]
        '''
        singlet = self.singlet
        cell = mf.cell
        kpts = mf.kpts

        mo_coeff = mf.mo_coeff
        mo_energy = mf.mo_energy
        mo_occ = mf.mo_occ
        nkpts = len(mo_occ)
        nao, nmo = mo_coeff[0].shape
        occidx = [numpy.where(mo_occ[k]==2)[0] for k in range(nkpts)]
        viridx = [numpy.where(mo_occ[k]==0)[0] for k in range(nkpts)]
        orbo = [mo_coeff[k][:,occidx[k]] for k in range(nkpts)]
        orbv = [mo_coeff[k][:,viridx[k]] for k in range(nkpts)]
        e_ia = _get_e_ia(mo_energy, mo_occ)
        hdiag = numpy.hstack([x.ravel() for x in e_ia])
        tot_x = hdiag.size
        hdiag = numpy.hstack((hdiag, hdiag))

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

        def vind(xys):
            nz = len(xys)
            z1xs = [_unpack(xy[:tot_x], mo_occ) for xy in xys]
            z1ys = [_unpack(xy[tot_x:], mo_occ) for xy in xys]
            dmov = numpy.empty((nz,nkpts,nao,nao), dtype=numpy.complex128)
            for i in range(nz):
                for k in range(nkpts):
                    # *2 for double occupancy
                    dmx = z1xs[i][k] * 2
                    dmy = z1ys[i][k] * 2
                    dmov[i,k] = reduce(numpy.dot, (orbo[k], dmx, orbv[k].T.conj()))
                    dmov[i,k]+= reduce(numpy.dot, (orbv[k], dmy.T, orbo[k].T.conj()))

            with lib.temporary_env(mf, exxdiv=None):
                v1ao = vresp(dmov)
            v1s = []
            for i in range(nz):
                dmx = z1xs[i]
                dmy = z1ys[i]
                v1xs = []
                v1ys = []
                for k in range(nkpts):
                    v1x = reduce(numpy.dot, (orbo[k].T.conj(), v1ao[i,k], orbv[k]))
                    v1y = reduce(numpy.dot, (orbv[k].T.conj(), v1ao[i,k], orbo[k])).T
                    v1x+= e_ia[k] * dmx[k]
                    v1y+= e_ia[k] * dmy[k]
                    v1xs.append(v1x.ravel())
                    v1ys.append(-v1y.ravel())
                v1s += v1xs + v1ys
            return lib.asarray(v1s).reshape(nz,-1)
        return vind, hdiag
예제 #2
0
def _gen_hop_rhf_external(mf, verbose=None):
    #FIXME: numerically unstable with small mesh?
    #TODO: Add a warning message for small mesh.
    from pyscf.pbc.dft import numint
    from pyscf.pbc.scf.newton_ah import _unpack
    cell = mf.cell
    kpts = mf.kpts

    mo_coeff = mf.mo_coeff
    mo_occ = mf.mo_occ
    nkpts = len(mo_occ)
    occidx = [numpy.where(mo_occ[k] == 2)[0] for k in range(nkpts)]
    viridx = [numpy.where(mo_occ[k] == 0)[0] for k in range(nkpts)]
    orbo = [mo_coeff[k][:, occidx[k]] for k in range(nkpts)]
    orbv = [mo_coeff[k][:, viridx[k]] for k in range(nkpts)]

    h1e = mf.get_hcore()
    dm0 = mf.make_rdm1(mo_coeff, mo_occ)
    fock_ao = h1e + mf.get_veff(cell, dm0)
    fock = [
        reduce(numpy.dot, (mo_coeff[k].T.conj(), fock_ao[k], mo_coeff[k]))
        for k in range(nkpts)
    ]
    foo = [fock[k][occidx[k][:, None], occidx[k]] for k in range(nkpts)]
    fvv = [fock[k][viridx[k][:, None], viridx[k]] for k in range(nkpts)]

    hdiag = [(fvv[k].diagonal().real[:, None] - foo[k].diagonal().real) * 2
             for k in range(nkpts)]
    hdiag = numpy.hstack([x.ravel() for x in hdiag])

    vresp1 = _gen_rhf_response(mf, singlet=False, hermi=1)

    def hop_rhf2uhf(x1):
        x1 = _unpack(x1, mo_occ)
        dmvo = []
        for k in range(nkpts):
            # *2 for double occupancy
            dm1 = reduce(numpy.dot, (orbv[k], x1[k] * 2, orbo[k].T.conj()))
            dmvo.append(dm1 + dm1.T.conj())
        dmvo = lib.asarray(dmvo)

        v1ao = vresp1(dmvo)
        x2 = [0] * nkpts
        for k in range(nkpts):
            x2[k] = numpy.einsum('ps,sq->pq', fvv[k], x1[k])
            x2[k] -= numpy.einsum('ps,rp->rs', foo[k], x1[k])
            x2[k] += reduce(numpy.dot, (orbv[k].T.conj(), v1ao[k], orbo[k]))

        # The displacement x2 corresponds to the response of rotation for bra.
        # Hessian*x also provides the rotation for ket which equals to
        # x2.T.conj(). The overall displacement is x2 + x2.T.conj(). This is
        # the reason of x2.real below
        return numpy.hstack([x.real.ravel() for x in x2])

    return hop_rhf2uhf, hdiag
예제 #3
0
파일: stability.py 프로젝트: chrinide/pyscf
def _gen_hop_rhf_external(mf, verbose=None):
#FIXME: numerically unstable with small mesh?
#TODO: Add a warning message for small mesh.
    from pyscf.pbc.dft import numint
    from pyscf.pbc.scf.newton_ah import _unpack
    cell = mf.cell
    kpts = mf.kpts

    mo_coeff = mf.mo_coeff
    mo_occ = mf.mo_occ
    nkpts = len(mo_occ)
    occidx = [numpy.where(mo_occ[k]==2)[0] for k in range(nkpts)]
    viridx = [numpy.where(mo_occ[k]==0)[0] for k in range(nkpts)]
    orbo = [mo_coeff[k][:,occidx[k]] for k in range(nkpts)]
    orbv = [mo_coeff[k][:,viridx[k]] for k in range(nkpts)]

    h1e = mf.get_hcore()
    dm0 = mf.make_rdm1(mo_coeff, mo_occ)
    fock_ao = h1e + mf.get_veff(cell, dm0)
    fock = [reduce(numpy.dot, (mo_coeff[k].T.conj(), fock_ao[k], mo_coeff[k]))
            for k in range(nkpts)]
    foo = [fock[k][occidx[k][:,None],occidx[k]] for k in range(nkpts)]
    fvv = [fock[k][viridx[k][:,None],viridx[k]] for k in range(nkpts)]

    hdiag = [(fvv[k].diagonal().real[:,None]-foo[k].diagonal().real) * 2
             for k in range(nkpts)]
    hdiag = numpy.hstack([x.ravel() for x in hdiag])

    vresp1 = _gen_rhf_response(mf, singlet=False, hermi=1)
    def hop_rhf2uhf(x1):
        x1 = _unpack(x1, mo_occ)
        dmvo = []
        for k in range(nkpts):
            # *2 for double occupancy
            dm1 = reduce(numpy.dot, (orbv[k], x1[k]*2, orbo[k].T.conj()))
            dmvo.append(dm1 + dm1.T.conj())
        dmvo = lib.asarray(dmvo)

        v1ao = vresp1(dmvo)
        x2 = [0] * nkpts
        for k in range(nkpts):
            x2[k] = numpy.einsum('ps,sq->pq', fvv[k], x1[k])
            x2[k]-= numpy.einsum('ps,rp->rs', foo[k], x1[k])
            x2[k]+= reduce(numpy.dot, (orbv[k].T.conj(), v1ao[k], orbo[k]))

        # The displacement x2 corresponds to the response of rotation for bra.
        # Hessian*x also provides the rotation for ket which equals to
        # x2.T.conj(). The overall displacement is x2 + x2.T.conj(). This is
        # the reason of x2.real below
        return numpy.hstack([x.real.ravel() for x in x2])

    return hop_rhf2uhf, hdiag
예제 #4
0
    def gen_vind(self, mf):
        singlet = self.singlet
        cell = mf.cell
        kpts = mf.kpts

        mo_coeff = mf.mo_coeff
        mo_energy = mf.mo_energy
        mo_occ = mf.mo_occ
        nkpts = len(mo_occ)
        nao, nmo = mo_coeff[0].shape
        occidx = [numpy.where(mo_occ[k] == 2)[0] for k in range(nkpts)]
        viridx = [numpy.where(mo_occ[k] == 0)[0] for k in range(nkpts)]
        orbo = [mo_coeff[k][:, occidx[k]] for k in range(nkpts)]
        orbv = [mo_coeff[k][:, viridx[k]] for k in range(nkpts)]
        e_ia = _get_e_ia(mo_energy, mo_occ)
        # FIXME: hdiag corresponds to the orbital energy with the exxdiv
        # correction. The integrals in A, B matrices do not have the
        # contribution from the exxdiv. Should the exchange correction be
        # removed from hdiag?
        hdiag = numpy.hstack([x.ravel() for x in e_ia])

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

        def vind(zs):
            nz = len(zs)
            z1s = [_unpack(z, mo_occ) for z in zs]
            dmov = numpy.empty((nz, nkpts, nao, nao), dtype=numpy.complex128)
            for i in range(nz):
                for k in range(nkpts):
                    # *2 for double occupancy
                    dm1 = z1s[i][k] * 2
                    dmov[i, k] = reduce(numpy.dot,
                                        (orbo[k], dm1, orbv[k].conj().T))

            with lib.temporary_env(mf, exxdiv=None):
                v1ao = vresp(dmov)
            v1s = []
            for i in range(nz):
                dm1 = z1s[i]
                for k in range(nkpts):
                    v1vo = reduce(numpy.dot,
                                  (orbo[k].conj().T, v1ao[i, k], orbv[k]))
                    v1vo += e_ia[k] * dm1[k]
                    v1s.append(v1vo.ravel())
            return lib.asarray(v1s).reshape(nz, -1)

        return vind, hdiag
예제 #5
0
def _gen_hop_rhf_external(mf, verbose=None):
    #FIXME: numerically unstable with small gs?
    #TODO: Add a warning message for small gs.
    from pyscf.pbc.dft import numint
    from pyscf.pbc.tddft.rhf import _unpack
    cell = mf.cell
    kpts = mf.kpts

    mo_coeff = mf.mo_coeff
    mo_energy = mf.mo_energy
    mo_occ = mf.mo_occ
    nkpts = len(mo_occ)
    occidx = [numpy.where(mo_occ[k] == 2)[0] for k in range(nkpts)]
    viridx = [numpy.where(mo_occ[k] == 0)[0] for k in range(nkpts)]
    orbo = [mo_coeff[k][:, occidx[k]] for k in range(nkpts)]
    orbv = [mo_coeff[k][:, viridx[k]] for k in range(nkpts)]

    h1e = mf.get_hcore()
    dm0 = mf.make_rdm1(mo_coeff, mo_occ)
    fock_ao = h1e + mf.get_veff(cell, dm0)
    fock = [
        reduce(numpy.dot, (mo_coeff[k].T.conj(), fock_ao[k], mo_coeff[k]))
        for k in range(nkpts)
    ]
    foo = [fock[k][occidx[k][:, None], occidx[k]] for k in range(nkpts)]
    fvv = [fock[k][viridx[k][:, None], viridx[k]] for k in range(nkpts)]

    hdiag = [(fvv[k].diagonal().reshape(-1, 1) - foo[k].diagonal()) * 2
             for k in range(nkpts)]
    hdiag = numpy.hstack([x.ravel() for x in hdiag])

    vresp1 = _gen_rhf_response(mf, singlet=False, hermi=1)

    def hop_rhf2uhf(x1):
        x1 = _unpack(x1, mo_occ)
        dmvo = []
        for k in range(nkpts):
            # *2 for double occupancy
            dm1 = reduce(numpy.dot, (orbv[k], x1[k] * 2, orbo[k].T.conj()))
            dmvo.append(dm1 + dm1.T.conj())
        dmvo = lib.asarray(dmvo)

        v1ao = vresp1(dmvo)
        x2 = [0] * nkpts
        for k in range(nkpts):
            x2[k] = numpy.einsum('ps,sq->pq', fvv[k], x1[k])
            x2[k] -= numpy.einsum('ps,rp->rs', foo[k], x1[k])
            x2[k] += reduce(numpy.dot, (orbv[k].T.conj(), v1ao[k], orbo[k]))
        return numpy.hstack([x.ravel() for x in x2])

    return hop_rhf2uhf, hdiag
예제 #6
0
    def get_vind(self, mf):
        singlet = self.singlet
        cell = mf.cell
        kpts = mf.kpts

        mo_coeff = mf.mo_coeff
        mo_energy = mf.mo_energy
        mo_occ = mf.mo_occ
        nkpts = len(mo_occ)
        nao, nmo = mo_coeff[0].shape
        occidx = [numpy.where(mo_occ[k] == 2)[0] for k in range(nkpts)]
        viridx = [numpy.where(mo_occ[k] == 0)[0] for k in range(nkpts)]
        orbo = [mo_coeff[k][:, occidx[k]] for k in range(nkpts)]
        orbv = [mo_coeff[k][:, viridx[k]] for k in range(nkpts)]
        eai = _get_eai(mo_energy, mo_occ)
        hdiag = numpy.hstack([x.ravel() for x in eai])

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

        def vind(zs):
            nz = len(zs)
            z1s = [_unpack(z, mo_occ) for z in zs]
            dmvo = numpy.empty((nz, nkpts, nao, nao), dtype=numpy.complex128)
            for i in range(nz):
                # *2 for double occupancy
                dm1 = z1s[i] * 2
                for k in range(nkpts):
                    dmvo[i, k] = reduce(numpy.dot,
                                        (orbv[k], dm1[k], orbo[k].T.conj()))

            v1ao = vresp(dmvo)
            v1s = []
            for i in range(nz):
                dm1 = z1s[i]
                for k in range(nkpts):
                    v1vo = reduce(numpy.dot,
                                  (orbv[k].T.conj(), v1ao[i, k], orbo[k]))
                    v1vo += eai[k] * dm1[k]
                    v1s.append(v1vo.ravel())
            return lib.asarray(v1s).reshape(nz, -1)

        return vind, hdiag