Пример #1
0
    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()

        fock = None
        if self.nmom[0] is not None:
            fock = self.get_fock(eri=eri, gf=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()

        se_occ = self.build_se_part(eri, gf_occ, gf_vir, **facs)
        se_occ = se_occ.compress(n=(None, self.nmom[1]))

        se_vir = self.build_se_part(eri, gf_vir, gf_occ, **facs)
        se_vir = se_vir.compress(n=(None, self.nmom[1]))

        se = aux.combine(se_vir, se_occ)
        se = se.compress(phys=fock, n=(self.nmom[0], None))

        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=self.nmom)

        return se
Пример #2
0
    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
Пример #3
0
    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 : tuple of 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
            tuple of :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[0].get_occupied(), gf[1].get_occupied())
        gf_vir = (gf[0].get_virtual(), gf[1].get_virtual())

        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_a = aux.combine(se_occ[0], se_vir[0])
        se_b = aux.combine(se_occ[1], se_vir[1])

        if se_prev is not None and self.damping != 0.0:
            se_a_prev, se_b_prev = se_prev
            se_a.coupling *= np.sqrt(1.0 - self.damping)
            se_b.coupling *= np.sqrt(1.0 - self.damping)
            se_a_prev.coupling *= np.sqrt(self.damping)
            se_b_prev.coupling *= np.sqrt(self.damping)
            se_a = aux.combine(se_a, se_a_prev)
            se_b = aux.combine(se_b, se_b_prev)
            se_a = se_a.compress(n=(None, 0))
            se_b = se_b.compress(n=(None, 0))

        return (se_a, se_b)
Пример #4
0
    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
Пример #5
0
    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