def uhf_external(mf, with_symmetry=True, verbose=None): log = logger.new_logger(mf, verbose) hop1, hdiag1, hop2, hdiag2 = _gen_hop_uhf_external(mf, with_symmetry) def precond(dx, e, x0): hdiagd = hdiag1 - e hdiagd[abs(hdiagd) < 1e-8] = 1e-8 return dx / hdiagd x0 = numpy.zeros_like(hdiag1) x0[hdiag1 > 1e-5] = 1. / hdiag1[hdiag1 > 1e-5] if not with_symmetry: # allow to break point group symmetry x0[numpy.argmin(hdiag1)] = 1 e1, v = lib.davidson(hop1, x0, precond, tol=1e-4, verbose=log) if e1 < -1e-5: log.note('UHF/UKS wavefunction has a real -> complex instablity') else: log.note( 'UHF/UKS wavefunction is stable in the real -> complex stability analysis' ) def precond(dx, e, x0): hdiagd = hdiag2 - e hdiagd[abs(hdiagd) < 1e-8] = 1e-8 return dx / hdiagd x0 = numpy.zeros_like(hdiag2) x0[hdiag2 > 1e-5] = 1. / hdiag2[hdiag2 > 1e-5] if not with_symmetry: # allow to break point group symmetry x0[numpy.argmin(hdiag2)] = 1 e3, v = lib.davidson(hop2, x0, precond, tol=1e-4, verbose=log) log.debug('uhf_external: lowest eigs of H = %s', e3) mo = scipy.linalg.block_diag(*mf.mo_coeff) if e3 < -1e-5: log.note('UHF/UKS wavefunction has an UHF/UKS -> GHF/GKS instablity.') occidxa = numpy.where(mf.mo_occ[0] > 0)[0] viridxa = numpy.where(mf.mo_occ[0] == 0)[0] occidxb = numpy.where(mf.mo_occ[1] > 0)[0] viridxb = numpy.where(mf.mo_occ[1] == 0)[0] nocca = len(occidxa) nvira = len(viridxa) noccb = len(occidxb) nvirb = len(viridxb) nmo = nocca + nvira dx = numpy.zeros((nmo * 2, nmo * 2)) dx[viridxa[:, None], nmo + occidxb] = v[:nvira * noccb].reshape(nvira, noccb) dx[nmo + viridxb[:, None], occidxa] = v[nvira * noccb:].reshape(nvirb, nocca) u = newton_ah.expmat(dx - dx.conj().T) mo = numpy.dot(mo, u) mo = numpy.hstack([ mo[:, :nocca], mo[:, nmo:nmo + noccb], mo[:, nocca:nmo], mo[:, nmo + noccb:] ]) else: log.note( 'UHF/UKS wavefunction is stable in the UHF/UKS -> GHF/GKS stability analysis' ) return mo
def update_rotate_matrix(self, dx, mo_occ, u0=1, mo_coeff=None): nmo = mo_occ.size nocc = numpy.count_nonzero(mo_occ) nvir = nmo - nocc dx = dx.reshape(nvir, nocc) dx_aa = dx[::2, ::2] dr_aa = hf.unpack_uniq_var(dx_aa.ravel(), mo_occ[::2]) u = numpy.zeros((nmo, nmo), dtype=dr_aa.dtype) # Allows only the rotation within the up-up space and down-down space u[::2, ::2] = u[1::2, 1::2] = newton_ah.expmat(dr_aa) return numpy.dot(u0, u)
def uhf_external(mf, with_symmetry=True, verbose=None): log = logger.new_logger(mf, verbose) hop1, hdiag1, hop2, hdiag2 = _gen_hop_uhf_external(mf, with_symmetry) def precond(dx, e, x0): hdiagd = hdiag1 - e hdiagd[abs(hdiagd)<1e-8] = 1e-8 return dx/hdiagd x0 = numpy.zeros_like(hdiag1) x0[hdiag1>1e-5] = 1. / hdiag1[hdiag1>1e-5] if not with_symmetry: # allow to break point group symmetry x0[numpy.argmin(hdiag1)] = 1 e1, v = lib.davidson(hop1, x0, precond, tol=1e-4, verbose=log) if e1 < -1e-5: log.note('UHF/UKS wavefunction has a real -> complex instablity') else: log.note('UHF/UKS wavefunction is stable in the real -> complex stability analysis') def precond(dx, e, x0): hdiagd = hdiag2 - e hdiagd[abs(hdiagd)<1e-8] = 1e-8 return dx/hdiagd x0 = numpy.zeros_like(hdiag2) x0[hdiag2>1e-5] = 1. / hdiag2[hdiag2>1e-5] if not with_symmetry: # allow to break point group symmetry x0[numpy.argmin(hdiag2)] = 1 e3, v = lib.davidson(hop2, x0, precond, tol=1e-4, verbose=log) log.debug('uhf_external: lowest eigs of H = %s', e3) mo = scipy.linalg.block_diag(*mf.mo_coeff) if e3 < -1e-5: log.note('UHF/UKS wavefunction has an UHF/UKS -> GHF/GKS instablity.') occidxa = numpy.where(mf.mo_occ[0]> 0)[0] viridxa = numpy.where(mf.mo_occ[0]==0)[0] occidxb = numpy.where(mf.mo_occ[1]> 0)[0] viridxb = numpy.where(mf.mo_occ[1]==0)[0] nocca = len(occidxa) nvira = len(viridxa) noccb = len(occidxb) nvirb = len(viridxb) nmo = nocca + nvira dx = numpy.zeros((nmo*2,nmo*2)) dx[viridxa[:,None],nmo+occidxb] = v[:nvira*noccb].reshape(nvira,noccb) dx[nmo+viridxb[:,None],occidxa] = v[nvira*noccb:].reshape(nvirb,nocca) u = newton_ah.expmat(dx - dx.conj().T) mo = numpy.dot(mo, u) mo = numpy.hstack([mo[:,:nocca], mo[:,nmo:nmo+noccb], mo[:,nocca:nmo], mo[:,nmo+noccb:]]) else: log.note('UHF/UKS wavefunction is stable in the UHF/UKS -> GHF/GKS stability analysis') return mo
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 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.T.conj() 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(mo_coeff, mo_occ, dx): dr = hf.unpack_uniq_var(dx, mo_occ) u = newton_ah.expmat(dr) return numpy.dot(mo_coeff, u)
def update_rotate_matrix(self, dx, mo_occ, u0=1, mo_coeff=None): dr = hf.unpack_uniq_var(dx, mo_occ) return numpy.dot(u0, newton_ah.expmat(dr))
def _rotate_mo(mo_coeff, mo_occ, dx): dr = hf.unpack_uniq_var(dx, mo_occ) u = newton_ah.expmat(dr) return numpy.dot(mo_coeff, u)