Exemplo n.º 1
0
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
Exemplo n.º 2
0
 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)
Exemplo n.º 3
0
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
Exemplo n.º 4
0
        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)
Exemplo n.º 5
0
 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)
Exemplo n.º 6
0
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)
Exemplo n.º 7
0
 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))
Exemplo n.º 8
0
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)