def run_diis(self, se, diis=None): ''' Runs the direct inversion of the iterative subspace for the self-energy. Args: se : SelfEnergy Auxiliaries of the self-energy diis : lib.diis.DIIS DIIS object Returns: :class:`SelfEnergy` ''' if diis is None: return se se_occ = se.get_occupied() se_vir = se.get_virtual() vv_occ = np.dot(se_occ.coupling, se_occ.coupling.T) vv_vir = np.dot(se_vir.coupling, se_vir.coupling.T) vev_occ = np.dot(se_occ.coupling * se_occ.energy[None], se_occ.coupling.T) vev_vir = np.dot(se_vir.coupling * se_vir.energy[None], se_vir.coupling.T) dat = np.array([vv_occ, vv_vir, vev_occ, vev_vir]) dat = diis.update(dat) vv_occ, vv_vir, vev_occ, vev_vir = dat se_occ = aux.SelfEnergy(*_agf2.cholesky_build(vv_occ, vev_occ), chempot=se.chempot) se_vir = aux.SelfEnergy(*_agf2.cholesky_build(vv_vir, vev_vir), chempot=se.chempot) se = aux.combine(se_occ, se_vir) return se
def run_diis(self, se, diis=None): ''' Runs the direct inversion of the iterative subspace for the self-energy. Args: se : SelfEnergy Auxiliaries of the self-energy diis : lib.diis.DIIS DIIS object Returns: tuple of :class:`SelfEnergy` ''' if diis is None: return se se_occ_a, se_occ_b = (se[0].get_occupied(), se[1].get_occupied()) se_vir_a, se_vir_b = (se[0].get_virtual(), se[1].get_virtual()) vv_occ_a = np.dot(se_occ_a.coupling, se_occ_a.coupling.T) vv_occ_b = np.dot(se_occ_b.coupling, se_occ_b.coupling.T) vv_vir_a = np.dot(se_vir_a.coupling, se_vir_a.coupling.T) vv_vir_b = np.dot(se_vir_b.coupling, se_vir_b.coupling.T) vev_occ_a = np.dot(se_occ_a.coupling * se_occ_a.energy[None], se_occ_a.coupling.T) vev_occ_b = np.dot(se_occ_b.coupling * se_occ_b.energy[None], se_occ_b.coupling.T) vev_vir_a = np.dot(se_vir_a.coupling * se_vir_a.energy[None], se_vir_a.coupling.T) vev_vir_b = np.dot(se_vir_b.coupling * se_vir_b.energy[None], se_vir_b.coupling.T) dat = np.array([ vv_occ_a, vv_vir_a, vev_occ_a, vev_vir_a, vv_occ_b, vv_vir_b, vev_occ_b, vev_vir_b ]) dat = diis.update(dat) vv_occ_a, vv_vir_a, vev_occ_a, vev_vir_a, \ vv_occ_b, vv_vir_b, vev_occ_b, vev_vir_b = dat se_occ_a = aux.SelfEnergy(*_agf2.cholesky_build(vv_occ_a, vev_occ_a), chempot=se[0].chempot) se_vir_a = aux.SelfEnergy(*_agf2.cholesky_build(vv_vir_a, vev_vir_a), chempot=se[0].chempot) se_occ_b = aux.SelfEnergy(*_agf2.cholesky_build(vv_occ_b, vev_occ_b), chempot=se[1].chempot) se_vir_b = aux.SelfEnergy(*_agf2.cholesky_build(vv_vir_b, vev_vir_b), chempot=se[1].chempot) se = (aux.combine(se_occ_a, se_vir_a), aux.combine(se_occ_b, se_vir_b)) return se
def build_se(self, eri=None, gf=None, os_factor=None, ss_factor=None, se_prev=None): ''' Builds the auxiliaries of the self-energy. Args: eri : _ChemistsERIs Electronic repulsion integrals gf : GreensFunction Auxiliaries of the Green's function Kwargs: os_factor : float Opposite-spin factor for spin-component-scaled (SCS) calculations. Default 1.0 ss_factor : float Same-spin factor for spin-component-scaled (SCS) calculations. Default 1.0 se_prev : SelfEnergy Previous self-energy for damping. Default value is None Returns: :class:`SelfEnergy` ''' if eri is None: eri = self.ao2mo() if gf is None: gf = self.gf if gf is None: gf = self.init_gf() if os_factor is None: os_factor = self.os_factor if ss_factor is None: ss_factor = self.ss_factor facs = dict(os_factor=os_factor, ss_factor=ss_factor) gf_occ = gf.get_occupied() gf_vir = gf.get_virtual() if gf_occ.naux == 0 or gf_vir.naux == 0: logger.warn( self, 'Attempting to build a self-energy with ' 'no (i,j,a) or (a,b,i) configurations.') se = aux.SelfEnergy([], [ [], ] * self.nmo, chempot=gf.chempot) else: se_occ = self.build_se_part(eri, gf_occ, gf_vir, **facs) se_vir = self.build_se_part(eri, gf_vir, gf_occ, **facs) se = aux.combine(se_occ, se_vir) if se_prev is not None and self.damping != 0.0: se.coupling *= np.sqrt(1.0 - self.damping) se_prev.coupling *= np.sqrt(self.damping) se = aux.combine(se, se_prev) se = se.compress(n=(None, 0)) return se
def build_se_part(agf2, eri, gf_occ, gf_vir, os_factor=1.0, ss_factor=1.0): ''' Builds either the auxiliaries of the occupied self-energy, or virtual if :attr:`gf_occ` and :attr:`gf_vir` are swapped. Args: eri : _ChemistsERIs Electronic repulsion integrals gf_occ : GreensFunction Occupied Green's function gf_vir : GreensFunction Virtual Green's function Kwargs: os_factor : float Opposite-spin factor for spin-component-scaled (SCS) calculations. Default 1.0 ss_factor : float Same-spin factor for spin-component-scaled (SCS) calculations. Default 1.0 Returns: :class:`SelfEnergy` ''' cput0 = (time.clock(), time.time()) log = logger.Logger(agf2.stdout, agf2.verbose) assert type(gf_occ) is aux.GreensFunction assert type(gf_vir) is aux.GreensFunction nmo = agf2.nmo nocc = gf_occ.naux nvir = gf_vir.naux naux = nocc * nocc * nvir tol = agf2.weight_tol if not (agf2.frozen is None or agf2.frozen == 0): mask = ragf2.get_frozen_mask(agf2) nmo -= np.sum(~mask) e = np.zeros((naux)) v = np.zeros((nmo, naux)) fpos = np.sqrt(0.5 * os_factor) fneg = np.sqrt(0.5 * os_factor + ss_factor) fdia = np.sqrt(os_factor) eja = lib.direct_sum('j,a->ja', gf_occ.energy, -gf_vir.energy) coeffs = (gf_occ.coupling, gf_occ.coupling, gf_vir.coupling) qeri = _make_qmo_eris_incore(agf2, eri, coeffs) p1 = 0 for i in range(nocc): xija = qeri[:,i,:i].reshape(nmo, -1) xjia = qeri[:,:i,i].reshape(nmo, -1) xiia = qeri[:,i,i].reshape(nmo, -1) eija = gf_occ.energy[i] + eja[:i+1] p0, p1 = p1, p1 + i*nvir e[p0:p1] = eija[:i].ravel() v[:,p0:p1] = fneg * (xija - xjia) p0, p1 = p1, p1 + i*nvir e[p0:p1] = eija[:i].ravel() v[:,p0:p1] = fpos * (xija + xjia) p0, p1 = p1, p1 + nvir e[p0:p1] = eija[i].ravel() v[:,p0:p1] = fdia * xiia se = aux.SelfEnergy(e, v, chempot=gf_occ.chempot) se.remove_uncoupled(tol=tol) if not (agf2.frozen is None or agf2.frozen == 0): coupling = np.zeros((agf2.nmo, se.naux)) coupling[mask] = se.coupling se = aux.SelfEnergy(se.energy, coupling, chempot=se.chempot) log.timer('se part', *cput0) return se
def build_se_part(agf2, eri, gf_occ, gf_vir, os_factor=1.0, ss_factor=1.0): ''' Builds either the auxiliaries of the occupied self-energy, or virtual if :attr:`gf_occ` and :attr:`gf_vir` are swapped, for a single spin. Args: eri : _ChemistsERIs Electronic repulsion integrals gf_occ : tuple of GreensFunction Occupied Green's function for each spin gf_vir : tuple of GreensFunction Virtual Green's function for each spin Kwargs: os_factor : float Opposite-spin factor for spin-component-scaled (SCS) calculations. Default 1.0 ss_factor : float Same-spin factor for spin-component-scaled (SCS) calculations. Default 1.0 Returns: :class:`SelfEnergy` ''' cput0 = (time.clock(), time.time()) log = logger.Logger(agf2.stdout, agf2.verbose) assert type(gf_occ[0]) is aux.GreensFunction assert type(gf_occ[1]) is aux.GreensFunction assert type(gf_vir[0]) is aux.GreensFunction assert type(gf_vir[1]) is aux.GreensFunction nmo = eri.nmo noa, nob = gf_occ[0].naux, gf_occ[1].naux nva, nvb = gf_vir[0].naux, gf_vir[1].naux tol = agf2.weight_tol facs = dict(os_factor=os_factor, ss_factor=ss_factor) ci_a, ei_a = gf_occ[0].coupling, gf_occ[0].energy ci_b, ei_b = gf_occ[1].coupling, gf_occ[1].energy ca_a, ea_a = gf_vir[0].coupling, gf_vir[0].energy ca_b, ea_b = gf_vir[1].coupling, gf_vir[1].energy mem_incore = (nmo[0]*noa*(noa*nva+nob*nvb)) * 8/1e6 mem_now = lib.current_memory()[0] if (mem_incore+mem_now < agf2.max_memory) or agf2.incore_complete: qeri = _make_qmo_eris_incore(agf2, eri, (ci_a, ci_a, ca_a), (ci_b, ci_b, ca_b), spin=0) else: qeri = _make_qmo_eris_outcore(agf2, eri, (ci_a, ci_a, ca_a), (ci_b, ci_b, ca_b), spin=0) if isinstance(qeri[0], np.ndarray): vv, vev = _agf2.build_mats_uagf2_incore(qeri, (ei_a, ei_b), (ea_a, ea_b), **facs) else: vv, vev = _agf2.build_mats_uagf2_outcore(qeri, (ei_a, ei_b), (ea_a, ea_b), **facs) e, c = _agf2.cholesky_build(vv, vev) se_a = aux.SelfEnergy(e, c, chempot=gf_occ[0].chempot) se_a.remove_uncoupled(tol=tol) if not (agf2.frozen is None or agf2.frozen == 0): mask = get_frozen_mask(agf2) coupling = np.zeros((nmo[0], se_a.naux)) coupling[mask[0]] = se_a.coupling se_a = aux.SelfEnergy(se_a.energy, coupling, chempot=se_a.chempot) cput0 = log.timer('se part (alpha)', *cput0) mem_incore = (nmo[1]*nob*(nob*nvb+noa*nva)) * 8/1e6 mem_now = lib.current_memory()[0] if (mem_incore+mem_now < agf2.max_memory) or agf2.incore_complete: qeri = _make_qmo_eris_incore(agf2, eri, (ci_a, ci_a, ca_a), (ci_b, ci_b, ca_b), spin=1) else: qeri = _make_qmo_eris_outcore(agf2, eri, (ci_a, ci_a, ca_a), (ci_b, ci_b, ca_b), spin=1) rv = np.s_[::-1] if isinstance(qeri[0], np.ndarray): vv, vev = _agf2.build_mats_uagf2_incore(qeri, (ei_b, ei_a), (ea_b, ea_a), **facs) else: vv, vev = _agf2.build_mats_uagf2_outcore(qeri, (ei_b, ei_a), (ea_b, ea_a), **facs) e, c = _agf2.cholesky_build(vv, vev) se_b = aux.SelfEnergy(e, c, chempot=gf_occ[1].chempot) se_b.remove_uncoupled(tol=tol) if not (agf2.frozen is None or agf2.frozen == 0): mask = get_frozen_mask(agf2) coupling = np.zeros((nmo[1], se_b.naux)) coupling[mask[1]] = se_b.coupling se_b = aux.SelfEnergy(se_b.energy, coupling, chempot=se_b.chempot) cput0 = log.timer('se part (beta)', *cput0) return (se_a, se_b)
def build_se_part(agf2, eri, gf_occ, gf_vir, os_factor=1.0, ss_factor=1.0): ''' Builds either the auxiliaries of the occupied self-energy, or virtual if :attr:`gf_occ` and :attr:`gf_vir` are swapped. Args: eri : _ChemistsERIs Electronic repulsion integrals gf_occ : GreensFunction Occupied Green's function gf_vir : GreensFunction Virtual Green's function Kwargs: os_factor : float Opposite-spin factor for spin-component-scaled (SCS) calculations. Default 1.0 ss_factor : float Same-spin factor for spin-component-scaled (SCS) calculations. Default 1.0 Returns: :class:`SelfEnergy` ''' cput0 = (logger.process_clock(), logger.perf_counter()) log = logger.Logger(agf2.stdout, agf2.verbose) assert type(gf_occ) is aux.GreensFunction assert type(gf_vir) is aux.GreensFunction nmo = eri.nmo nocc, nvir = gf_occ.naux, gf_vir.naux naux = agf2.with_df.get_naoaux() tol = agf2.weight_tol facs = dict(os_factor=os_factor, ss_factor=ss_factor) ei, ci = gf_occ.energy, gf_occ.coupling ea, ca = gf_vir.energy, gf_vir.coupling qxi, qja = _make_qmo_eris_incore(agf2, eri, (ci, ci, ca)) himem_required = naux * (nvir + nmo) + (nocc * nvir) * (2 * nmo + 1) + ( 2 * nmo**2) himem_required *= 8e-6 himem_required *= lib.num_threads() if ((himem_required * 1.05 + lib.current_memory()[0]) > agf2.max_memory and agf2.allow_lowmem_build) or agf2.allow_lowmem_build == 'force': log.debug( 'Thread-private memory overhead %.3f exceeds max_memory, using ' 'low-memory version.', himem_required) vv, vev = _agf2.build_mats_dfragf2_lowmem(qxi, qja, ei, ea, **facs) else: vv, vev = _agf2.build_mats_dfragf2_incore(qxi, qja, ei, ea, **facs) e, c = _agf2.cholesky_build(vv, vev) se = aux.SelfEnergy(e, c, chempot=gf_occ.chempot) se.remove_uncoupled(tol=tol) if not (agf2.frozen is None or agf2.frozen == 0): mask = ragf2.get_frozen_mask(agf2) coupling = np.zeros((nmo, se.naux)) coupling[mask] = se.coupling se = aux.SelfEnergy(se.energy, coupling, chempot=se.chempot) log.timer('se part', *cput0) return se
def build_se_part(agf2, eri, gf_occ, gf_vir, os_factor=1.0, ss_factor=1.0): ''' Builds either the auxiliaries of the occupied self-energy, or virtual if :attr:`gf_occ` and :attr:`gf_vir` are swapped. Args: eri : _ChemistsERIs Electronic repulsion integrals gf_occ : GreensFunction Occupied Green's function gf_vir : GreensFunction Virtual Green's function Kwargs: os_factor : float Opposite-spin factor for spin-component-scaled (SCS) calculations. Default 1.0 ss_factor : float Same-spin factor for spin-component-scaled (SCS) calculations. Default 1.0 Returns: :class:`SelfEnergy` ''' cput0 = (logger.process_clock(), logger.perf_counter()) log = logger.Logger(agf2.stdout, agf2.verbose) assert type(gf_occ[0]) is aux.GreensFunction assert type(gf_occ[1]) is aux.GreensFunction assert type(gf_vir[0]) is aux.GreensFunction assert type(gf_vir[1]) is aux.GreensFunction nmoa, nmob = eri.nmo nocca, nvira = gf_occ[0].naux, gf_vir[0].naux noccb, nvirb = gf_occ[1].naux, gf_vir[1].naux naux = agf2.with_df.get_naoaux() tol = agf2.weight_tol facs = dict(os_factor=os_factor, ss_factor=ss_factor) ci_a, ei_a = gf_occ[0].coupling, gf_occ[0].energy ci_b, ei_b = gf_occ[1].coupling, gf_occ[1].energy ca_a, ea_a = gf_vir[0].coupling, gf_vir[0].energy ca_b, ea_b = gf_vir[1].coupling, gf_vir[1].energy qeri = _make_qmo_eris_incore(agf2, eri, (ci_a, ci_a, ca_a), (ci_b, ci_b, ca_b)) (qxi_a, qja_a), (qxi_b, qja_b) = qeri qxi = (qxi_a, qxi_b) qja = (qja_a, qja_b) himem_required = naux * (nvira + nmoa) + ( nocca * nvira + noccb * nvirb) * (1 + 2 * nmoa) + (2 * nmoa**2) himem_required *= 8e-6 himem_required *= lib.num_threads() if ((himem_required * 1.05 + lib.current_memory()[0]) > agf2.max_memory and agf2.allow_lowmem_build) or agf2.allow_lowmem_build == 'force': log.debug( 'Thread-private memory overhead %.3f exceeds max_memory, using ' 'low-memory version.', himem_required) build_mats_dfuagf2 = _agf2.build_mats_dfuagf2_lowmem else: build_mats_dfuagf2 = _agf2.build_mats_dfuagf2_incore vv, vev = build_mats_dfuagf2(qxi, qja, (ei_a, ei_b), (ea_a, ea_b), **facs) e, c = _agf2.cholesky_build(vv, vev) se_a = aux.SelfEnergy(e, c, chempot=gf_occ[0].chempot) se_a.remove_uncoupled(tol=tol) if not (agf2.frozen is None or agf2.frozen == 0): mask = uagf2.get_frozen_mask(agf2) coupling = np.zeros((nmoa, se_a.naux)) coupling[mask[0]] = se_a.coupling se_a = aux.SelfEnergy(se_a.energy, coupling, chempot=se_a.chempot) cput0 = log.timer('se part (alpha)', *cput0) himem_required = naux * (nvirb + nmob) + ( noccb * nvirb + nocca * nvira) * (1 + 2 * nmob) + (2 * nmob**2) himem_required *= 8e-6 himem_required *= lib.num_threads() if ((himem_required * 1.05 + lib.current_memory()[0]) > agf2.max_memory and agf2.allow_lowmem_build) or agf2.allow_lowmem_build == 'force': log.debug( 'Thread-private memory overhead %.3f exceeds max_memory, using ' 'low-memory version.', himem_required) build_mats_dfuagf2 = _agf2.build_mats_dfuagf2_lowmem else: build_mats_dfuagf2 = _agf2.build_mats_dfuagf2_incore rv = np.s_[::-1] vv, vev = build_mats_dfuagf2(qxi[rv], qja[rv], (ei_b, ei_a), (ea_b, ea_a), **facs) e, c = _agf2.cholesky_build(vv, vev) se_b = aux.SelfEnergy(e, c, chempot=gf_occ[1].chempot) se_b.remove_uncoupled(tol=tol) if not (agf2.frozen is None or agf2.frozen == 0): mask = uagf2.get_frozen_mask(agf2) coupling = np.zeros((nmoa, se_b.naux)) coupling[mask[1]] = se_b.coupling se_b = aux.SelfEnergy(se_b.energy, coupling, chempot=se_b.chempot) cput0 = log.timer('se part (beta)', *cput0) return (se_a, se_b)
def build_se_part(agf2, eri, gf_occ, gf_vir, os_factor=1.0, ss_factor=1.0): ''' Builds either the auxiliaries of the occupied self-energy, or virtual if :attr:`gf_occ` and :attr:`gf_vir` are swapped. Args: eri : _ChemistsERIs Electronic repulsion integrals gf_occ : GreensFunction Occupied Green's function gf_vir : GreensFunction Virtual Green's function Kwargs: os_factor : float Opposite-spin factor for spin-component-scaled (SCS) calculations. Default 1.0 ss_factor : float Same-spin factor for spin-component-scaled (SCS) calculations. Default 1.0 Returns: :class:`SelfEnergy` ''' cput0 = (time.clock(), time.time()) log = logger.Logger(agf2.stdout, agf2.verbose) assert type(gf_occ) is aux.GreensFunction assert type(gf_vir) is aux.GreensFunction nmo = eri.nmo tol = agf2.weight_tol facs = dict(os_factor=os_factor, ss_factor=ss_factor) ci, ei = gf_occ.coupling, gf_occ.energy ca, ea = gf_vir.coupling, gf_vir.energy mem_incore = (gf_occ.nphys * gf_occ.naux**2 * gf_vir.naux) * 8 / 1e6 mem_now = lib.current_memory()[0] if (mem_incore + mem_now < agf2.max_memory) or agf2.incore_complete: qeri = _make_qmo_eris_incore(agf2, eri, (ci, ci, ca)) else: qeri = _make_qmo_eris_outcore(agf2, eri, (ci, ci, ca)) if isinstance(qeri, np.ndarray): vv, vev = _agf2.build_mats_ragf2_incore(qeri, ei, ea, **facs) else: vv, vev = _agf2.build_mats_ragf2_outcore(qeri, ei, ea, **facs) e, c = _agf2.cholesky_build(vv, vev) se = aux.SelfEnergy(e, c, chempot=gf_occ.chempot) se.remove_uncoupled(tol=tol) if not (agf2.frozen is None or agf2.frozen == 0): mask = get_frozen_mask(agf2) coupling = np.zeros((nmo, se.naux)) coupling[mask] = se.coupling se = aux.SelfEnergy(se.energy, coupling, chempot=se.chempot) log.timer('se part', *cput0) return se
def _build_se_part_spin(spin=0): ''' Perform the build for a single spin spin = 0: alpha spin = 1: beta ''' if spin == 0: ab = slice(None) else: ab = slice(None, None, -1) nmoa, nmob = agf2.nmo[ab] gfo_a, gfo_b = gf_occ[ab] gfv_a, gfv_b = gf_vir[ab] noa, nob = gfo_a.naux, gfo_b.naux nva, nvb = gfv_a.naux, gfv_b.naux naux = nva * noa * (noa - 1) // 2 + nvb * noa * nob if not (agf2.frozen is None or agf2.frozen == 0): mask = uagf2.get_frozen_mask(agf2) nmoa -= np.sum(~mask[ab][0]) nmob -= np.sum(~mask[ab][1]) e = np.zeros((naux)) v = np.zeros((nmoa, naux)) falph = np.sqrt(ss_factor) fbeta = np.sqrt(os_factor) eja_a = lib.direct_sum('j,a->ja', gfo_a.energy, -gfv_a.energy) eja_b = lib.direct_sum('j,a->ja', gfo_b.energy, -gfv_b.energy) ca = (gf_occ[0].coupling, gf_occ[0].coupling, gf_vir[0].coupling) cb = (gf_occ[1].coupling, gf_occ[1].coupling, gf_vir[1].coupling) qeri = _make_qmo_eris_incore(agf2, eri, ca, cb, spin=spin) qeri_aa, qeri_ab = qeri p1 = 0 for i in range(noa): xija_aa = qeri_aa[:, i, :i].reshape(nmoa, -1) xjia_aa = qeri_aa[:, :i, i].reshape(nmoa, -1) xija_ab = qeri_ab[:, i].reshape(nmoa, -1) eija_aa = gfo_a.energy[i] + eja_a[:i] eija_ab = gfo_a.energy[i] + eja_b p0, p1 = p1, p1 + i * nva e[p0:p1] = eija_aa.ravel() v[:, p0:p1] = falph * (xija_aa - xjia_aa) p0, p1 = p1, p1 + nob * nvb e[p0:p1] = eija_ab.ravel() v[:, p0:p1] = fbeta * xija_ab se = aux.SelfEnergy(e, v, chempot=gfo_a.chempot) se.remove_uncoupled(tol=tol) if not (agf2.frozen is None or agf2.frozen == 0): coupling = np.zeros((agf2.nmo[ab][0], se.naux)) coupling[mask[ab][0]] = se.coupling se = aux.SelfEnergy(se.energy, coupling, chempot=gfo_a.chempot) return se