Esempio n. 1
0
    def init_gf(self, frozen=False):
        ''' Builds the Hartree-Fock Green's function.

        Returns:
            tuple of :class:`GreensFunction`, tuple of :class:`SelfEnergy`
        '''

        nmoa, nmob = self.nmo
        nocca, noccb = self.nocc

        energy = self.mo_energy
        coupling = (np.eye(nmoa), np.eye(nmob))

        focka = np.diag(energy[0])
        fockb = np.diag(energy[1])

        cpt_a = binsearch_chempot(focka, nmoa, nocca, occupancy=1)[0]
        cpt_b = binsearch_chempot(fockb, nmob, noccb, occupancy=1)[1]

        if frozen:
            mask = get_frozen_mask(self)
            energy = (energy[0][mask[0]], energy[1][mask[1]])
            coupling = (coupling[0][:, mask[0]], coupling[1][:, mask[1]])

        gf_a = aux.GreensFunction(energy[0], coupling[0], chempot=cpt_a)
        gf_b = aux.GreensFunction(energy[1], coupling[1], chempot=cpt_b)

        gf = (gf_a, gf_b)

        return gf
Esempio n. 2
0
    def init_gf(self, frozen=False):
        ''' Builds the Hartree-Fock Green's function.

        Returns:
            :class:`GreensFunction`, :class:`SelfEnergy`
        '''

        energy = self.mo_energy
        coupling = np.eye(self.nmo)

        chempot = binsearch_chempot(np.diag(energy), self.nmo, self.nocc*2)[0]

        if frozen:
            mask = get_frozen_mask(self)
            energy = energy[mask]
            coupling = coupling[:,mask]

        gf = aux.GreensFunction(energy, coupling, chempot=chempot)

        return gf
Esempio n. 3
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
Esempio n. 4
0
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 = (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
    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))
    rdm1a_prev = 0
    rdm1b_prev = 0
    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