示例#1
0
def fock_loop(agf2, eri, gf, se):
    ''' Self-consistent loop for the density matrix via the HF self-
        consistent field.

    Args:
        eri : _ChemistERIs
            Electronic repulsion integrals
        gf : GreensFunction
            Auxiliaries of the Green's function
        se : SelfEnergy
            Auxiliaries of the self-energy

    Returns:
        :class:`SelfEnergy`, :class:`GreensFunction` and a boolean
        indicating wheter convergence was successful.
    '''

    assert type(gf) is aux.GreensFunction
    assert type(se) is aux.SelfEnergy

    cput0 = cput1 = (logger.process_clock(), logger.perf_counter())
    log = logger.Logger(agf2.stdout, agf2.verbose)

    diis = lib.diis.DIIS(agf2)
    diis.space = agf2.fock_diis_space
    diis.min_space = agf2.fock_diis_min_space
    fock = agf2.get_fock(eri, gf)

    nelec = eri.nocc * 2
    nmo = eri.nmo
    naux = se.naux
    nqmo = nmo + naux
    buf = np.zeros((nqmo, nqmo))
    converged = False
    opts = dict(tol=agf2.conv_tol_nelec, maxiter=agf2.max_cycle_inner)
    rdm1_prev = 0

    for niter1 in range(1, agf2.max_cycle_outer + 1):
        se, opt = minimize_chempot(se, fock, nelec, x0=se.chempot, **opts)

        for niter2 in range(1, agf2.max_cycle_inner + 1):
            w, v = se.eig(fock, chempot=0.0, out=buf)
            se.chempot, nerr = binsearch_chempot((w, v), nmo, nelec)

            w, v = se.eig(fock, out=buf)
            gf = aux.GreensFunction(w, v[:nmo], chempot=se.chempot)

            fock = agf2.get_fock(eri, gf)
            rdm1 = agf2.make_rdm1(gf)
            fock = diis.update(fock, xerr=None)

            if niter2 > 1:
                derr = np.max(np.absolute(rdm1 - rdm1_prev))
                if derr < agf2.conv_tol_rdm1:
                    break

            rdm1_prev = rdm1.copy()

        log.debug1('fock loop %d  cycles = %d  dN = %.3g  |ddm| = %.3g',
                   niter1, niter2, nerr, derr)
        cput1 = log.timer_debug1('fock loop %d' % niter1, *cput1)

        if derr < agf2.conv_tol_rdm1 and abs(nerr) < agf2.conv_tol_nelec:
            converged = True
            break

    log.info('fock converged = %s  chempot = %.9g  dN = %.3g  |ddm| = %.3g',
             converged, se.chempot, nerr, derr)
    log.timer('fock loop', *cput0)

    return gf, se, converged
示例#2
0
文件: uagf2.py 项目: zhjiang-1/pyscf
def fock_loop(agf2, eri, gf, se):
    ''' Self-consistent loop for the density matrix via the HF self-
        consistent field.

    Args:
        eri : _ChemistsERIs
            Electronic repulsion integrals
        gf : tuple of GreensFunction
            Auxiliaries of the Green's function for each spin
        se : tuple of SelfEnergy
            Auxiliaries of the self-energy for each spin

    Returns:
        :class:`SelfEnergy`, :class:`GreensFunction` and a boolean
        indicating whether convergence was successful.
    '''

    assert type(gf[0]) is aux.GreensFunction
    assert type(gf[1]) is aux.GreensFunction
    assert type(se[0]) is aux.SelfEnergy
    assert type(se[1]) is aux.SelfEnergy

    cput0 = cput1 = (time.clock(), time.time())
    log = logger.Logger(agf2.stdout, agf2.verbose)

    diis = lib.diis.DIIS(agf2)
    diis.space = agf2.fock_diis_space
    diis.min_space = agf2.fock_diis_min_space
    focka, fockb = agf2.get_fock(eri, gf)
    sea, seb = se
    gfa, gfb = gf

    nalph, nbeta = agf2.nocc
    nmoa, nmob = eri.nmo
    nauxa, nauxb = sea.naux, seb.naux
    nqmoa, nqmob = nauxa+nmoa, nauxb+nmob
    bufa, bufb = np.zeros((nqmoa, nqmoa)), np.zeros((nqmob, nqmob))
    converged = False
    opts = dict(tol=agf2.conv_tol_nelec, maxiter=agf2.max_cycle_inner)

    for niter1 in range(1, agf2.max_cycle_outer+1):
        sea, opt = minimize_chempot(sea, focka, nalph, x0=sea.chempot, 
                                    occupancy=1, **opts)
        seb, opt = minimize_chempot(seb, fockb, nbeta, x0=seb.chempot,
                                    occupancy=1, **opts)

        for niter2 in range(1, agf2.max_cycle_inner+1):
            wa, va = sea.eig(focka, chempot=0.0, out=bufa)
            wb, vb = seb.eig(fockb, chempot=0.0, out=bufb)
            sea.chempot, nerra = \
                    binsearch_chempot((wa, va), nmoa, nalph, occupancy=1)
            seb.chempot, nerrb = \
                    binsearch_chempot((wb, vb), nmob, nbeta, occupancy=1)
            nerr = max(nerra, nerrb)

            wa, va = sea.eig(focka, out=bufa)
            wb, vb = seb.eig(fockb, out=bufb)
            gfa = aux.GreensFunction(wa, va[:nmoa], chempot=sea.chempot)
            gfb = aux.GreensFunction(wb, vb[:nmob], chempot=seb.chempot)

            gf = (gfa, gfb)
            focka, fockb = agf2.get_fock(eri, gf)
            rdm1a, rdm1b = agf2.make_rdm1(gf)
            focka, fockb = diis.update(np.array((focka, fockb)), xerr=None)

            if niter2 > 1:
                derra = np.max(np.absolute(rdm1a - rdm1a_prev))
                derrb = np.max(np.absolute(rdm1b - rdm1b_prev))
                derr = max(derra, derrb)

                if derr < agf2.conv_tol_rdm1:
                    break

            rdm1a_prev = rdm1a.copy()
            rdm1b_prev = rdm1b.copy()

        log.debug1('fock loop %d  cycles = %d  dN = %.3g  |ddm| = %.3g',
                   niter1, niter2, nerr, derr)
        cput1 = log.timer_debug1('fock loop %d'%niter1, *cput1)

        if derr < agf2.conv_tol_rdm1 and abs(nerr) < agf2.conv_tol_nelec:
            converged = True
            break

    se = (sea, seb)

    log.info('fock converged = %s' % converged)
    log.info(' alpha: chempot = %.9g  dN = %.3g  |ddm| = %.3g', 
             sea.chempot, nerra, derra)
    log.info(' beta:  chempot = %.9g  dN = %.3g  |ddm| = %.3g', 
             seb.chempot, nerrb, derrb)
    log.timer('fock loop', *cput0)

    return gf, se, converged