Beispiel #1
0
def newton(mf):
    from pyscf.soscf import newton_ah
    from pyscf.pbc import scf as pscf
    if not isinstance(mf, pscf.khf.KSCF):
        # Note for single k-point other than gamma point (mf.kpt != 0) mf object,
        # orbital hessian is approximated by gamma point hessian.
        return newton_ah.newton(mf)

    if isinstance(mf, newton_ah._CIAH_SOSCF):
        return mf

    if mf.__doc__ is None:
        mf_doc = ''
    else:
        mf_doc = mf.__doc__

    class SecondOrderKRHF(mf.__class__, newton_ah._CIAH_SOSCF):
        __doc__ = mf_doc + newton_ah._CIAH_SOSCF.__doc__
        __init__ = newton_ah._CIAH_SOSCF.__init__
        dump_flags = newton_ah._CIAH_SOSCF.dump_flags
        build = newton_ah._CIAH_SOSCF.build
        kernel = newton_ah._CIAH_SOSCF.kernel

        gen_g_hop = gen_g_hop_rhf

        def update_rotate_matrix(self, dx, mo_occ, u0=1, mo_coeff=None):
            p0 = 0
            u = []
            for k, occ in enumerate(mo_occ):
                occidx = occ > 0
                viridx = ~occidx
                nocc = occidx.sum()
                nvir = viridx.sum()
                nmo = nocc + nvir
                dr = numpy.zeros((nmo, nmo), dtype=dx.dtype)
                dr[viridx[:, None] & occidx] = dx[p0:p0 + nocc * nvir]
                dr = dr - dr.conj().T
                p0 += nocc * nvir

                u1 = newton_ah.expmat(dr)
                if isinstance(u0, int) and u0 == 1:
                    u.append(u1)
                else:
                    u.append(numpy.dot(u0[k], u1))
            return lib.asarray(u)

        def rotate_mo(self, mo_coeff, u, log=None):
            return lib.asarray(
                [numpy.dot(mo, u[k]) for k, mo in enumerate(mo_coeff)])

    if isinstance(mf, pscf.kuhf.KUHF):

        class SecondOrderKUHF(mf.__class__, newton_ah._CIAH_SOSCF):
            __doc__ = mf_doc + newton_ah._CIAH_SOSCF.__doc__
            __init__ = newton_ah._CIAH_SOSCF.__init__
            dump_flags = newton_ah._CIAH_SOSCF.dump_flags
            build = newton_ah._CIAH_SOSCF.build
            kernel = newton_ah._CIAH_SOSCF.kernel

            gen_g_hop = gen_g_hop_uhf

            def update_rotate_matrix(self, dx, mo_occ, u0=1, mo_coeff=None):
                nkpts = len(mo_occ[0])
                p0 = 0
                u = []
                for occ in mo_occ:
                    ua = []
                    for k in range(nkpts):
                        occidx = occ[k] > 0
                        viridx = ~occidx
                        nocc = occidx.sum()
                        nvir = viridx.sum()
                        nmo = nocc + nvir
                        dr = numpy.zeros((nmo, nmo), dtype=dx.dtype)
                        dr[viridx[:, None] & occidx] = dx[p0:p0 + nocc * nvir]
                        dr = dr - dr.conj().T
                        p0 += nocc * nvir
                        u1 = newton_ah.expmat(dr)
                        if isinstance(u0, int) and u0 == 1:
                            ua.append(u1)
                        else:
                            ua.append(numpy.dot(u0[k], u1))
                    u.append(ua)
                return lib.asarray(u)

            def rotate_mo(self, mo_coeff, u, log=None):
                mo = ([
                    numpy.dot(mo, u[0][k]) for k, mo in enumerate(mo_coeff[0])
                ], [
                    numpy.dot(mo, u[1][k]) for k, mo in enumerate(mo_coeff[1])
                ])
                return lib.asarray(mo)

        return SecondOrderKUHF(mf)

    elif isinstance(mf, pscf.krohf.KROHF):

        class SecondOrderKROHF(SecondOrderKRHF):
            gen_g_hop = gen_g_hop_rohf

        return SecondOrderKROHF(mf)

    elif isinstance(mf, pscf.kghf.KGHF):
        raise NotImplementedError

    else:
        return SecondOrderKRHF(mf)
Beispiel #2
0
def newton(mf):
    from pyscf.soscf import newton_ah
    return newton_ah.newton(mf)
Beispiel #3
0
def newton(mf):
    from pyscf.soscf import newton_ah
    return newton_ah.newton(mf)