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)
def newton(mf): from pyscf.soscf import newton_ah return newton_ah.newton(mf)