Пример #1
0
    def test_rsh_df4c_get_jk(self):
        nao = mol.nao_nr() * 4
        numpy.random.seed(1)
        dm = numpy.random.random((2,nao,nao)) + 0j
        dfobj = df.DF4C(mol)
        vj, vk = dfobj.get_jk(dm, hermi=0, omega=1.1)
        self.assertAlmostEqual(lib.finger(vj), 4.4552047176479235+50.015369284963256j, 4)
        self.assertAlmostEqual(lib.finger(vk), 27.562574245800487+11.439296646723120j, 4)

        vj1, vk1 = scf.dhf.get_jk(mol, dm, hermi=0, omega=1.1)
        self.assertAlmostEqual(abs(vj-vj1).max(), 0, 2)
        self.assertAlmostEqual(abs(vk-vk1).max(), 0, 2)
Пример #2
0
    def test_rsh_df4c_get_jk(self):
        with lib.temporary_env(lib.param, LIGHT_SPEED=1):
            nao = mol.nao_nr() * 4
            numpy.random.seed(1)
            dm = numpy.random.random((2,nao,nao)) + numpy.random.random((2,nao,nao))*1j
            dm[0] += scf.dhf.time_reversal_matrix(mol, dm[0])
            dm[1] += scf.dhf.time_reversal_matrix(mol, dm[1])
            dfobj = df.DF4C(mol)
            vj, vk = dfobj.get_jk(dm, hermi=0, omega=0.9)
            self.assertAlmostEqual(lib.finger(vj), 1364.9807926997748+215.73363929678885j, 4)
            self.assertAlmostEqual(lib.finger(vk), 159.03611112342566+687.9032914356833j , 4)

            vj1, vk1 = scf.dhf.get_jk(mol, dm, hermi=0, omega=0.9)
            self.assertAlmostEqual(abs(vj-vj1).max(), 0, 2)
            self.assertAlmostEqual(abs(vk-vk1).max(), 0, 2)
Пример #3
0
def density_fit(mf, auxbasis=None, with_df=None, only_dfj=False):
    '''For the given SCF object, update the J, K matrix constructor with
    corresponding density fitting integrals.

    Args:
        mf : an SCF object

    Kwargs:
        auxbasis : str or basis dict
            Same format to the input attribute mol.basis.  If auxbasis is
            None, optimal auxiliary basis based on AO basis (if possible) or
            even-tempered Gaussian basis will be used.

        only_dfj : str
            Compute Coulomb integrals only and no approximation for HF
            exchange. Same to RIJONX in ORCA

    Returns:
        An SCF object with a modified J, K matrix constructor which uses density
        fitting integrals to compute J and K

    Examples:

    >>> mol = gto.M(atom='H 0 0 0; F 0 0 1', basis='ccpvdz', verbose=0)
    >>> mf = scf.density_fit(scf.RHF(mol))
    >>> mf.scf()
    -100.005306000435510

    >>> mol.symmetry = 1
    >>> mol.build(0, 0)
    >>> mf = scf.density_fit(scf.UHF(mol))
    >>> mf.scf()
    -100.005306000435510
    '''
    from pyscf import df
    from pyscf.scf import dhf
    from pyscf.soscf import newton_ah
    assert (isinstance(mf, scf.hf.SCF))

    if with_df is None:
        if isinstance(mf, dhf.UHF):
            with_df = df.DF4C(mf.mol)
        else:
            with_df = df.DF(mf.mol)
        with_df.max_memory = mf.max_memory
        with_df.stdout = mf.stdout
        with_df.verbose = mf.verbose
        with_df.auxbasis = auxbasis

    mf_class = mf.__class__

    if isinstance(mf, _DFHF):
        if getattr(mf.with_df, 'auxbasis', None) != auxbasis:
            #logger.warn(mf, 'DF might have been initialized twice.')
            mf = copy.copy(mf)
            mf.with_df = with_df
            mf.only_dfj = only_dfj
        return mf

    class DFHF(_DFHF, mf_class):
        __doc__ = '''
        Density fitting SCF class

        Attributes for density-fitting SCF:
            auxbasis : str or basis dict
                Same format to the input attribute mol.basis.
                The default basis 'weigend+etb' means weigend-coulomb-fit basis
                for light elements and even-tempered basis for heavy elements.
            with_df : DF object
                Set mf.with_df = None to switch off density fitting mode.

        See also the documents of class %s for other SCF attributes.
        ''' % mf_class

        def __init__(self, mf, df, only_dfj):
            self.__dict__.update(mf.__dict__)
            self._eri = None
            self.with_df = df
            self.only_dfj = only_dfj
            self._keys = self._keys.union(['with_df', 'only_dfj'])

        def get_jk(self,
                   mol=None,
                   dm=None,
                   hermi=1,
                   with_j=True,
                   with_k=True,
                   omega=None):
            if dm is None: dm = self.make_rdm1()
            if self.with_df and self.only_dfj:
                vj = vk = None
                if with_j:
                    vj, vk = self.with_df.get_jk(dm, hermi, True, False,
                                                 self.direct_scf_tol, omega)
                if with_k:
                    vk = mf_class.get_jk(self, mol, dm, hermi, False, True,
                                         omega)[1]
            elif self.with_df:
                vj, vk = self.with_df.get_jk(dm, hermi, with_j, with_k,
                                             self.direct_scf_tol, omega)
            else:
                vj, vk = mf_class.get_jk(self, mol, dm, hermi, with_j, with_k,
                                         omega)
            return vj, vk

        # for pyscf 1.0, 1.1 compatibility
        @property
        def _cderi(self):
            naux = self.with_df.get_naoaux()
            return next(self.with_df.loop(blksize=naux))

        @_cderi.setter
        def _cderi(self, x):
            self.with_df._cderi = x

        @property
        def auxbasis(self):
            return getattr(self.with_df, 'auxbasis', None)

    return DFHF(mf, with_df, only_dfj)
Пример #4
0
def density_fit(mf, auxbasis=None, with_df=None):
    '''For the given SCF object, update the J, K matrix constructor with
    corresponding density fitting integrals.

    Args:
        mf : an SCF object

    Kwargs:
        auxbasis : str or basis dict
            Same format to the input attribute mol.basis.  If auxbasis is
            None, optimal auxiliary basis based on AO basis (if possible) or
            even-tempered Gaussian basis will be used.

    Returns:
        An SCF object with a modified J, K matrix constructor which uses density
        fitting integrals to compute J and K

    Examples:

    >>> mol = gto.M(atom='H 0 0 0; F 0 0 1', basis='ccpvdz', verbose=0)
    >>> mf = scf.density_fit(scf.RHF(mol))
    >>> mf.scf()
    -100.005306000435510

    >>> mol.symmetry = 1
    >>> mol.build(0, 0)
    >>> mf = scf.density_fit(scf.UHF(mol))
    >>> mf.scf()
    -100.005306000435510
    '''
    from pyscf import df
    from pyscf.scf import dhf
    from pyscf.soscf import newton_ah
    assert (isinstance(mf, scf.hf.SCF))

    if isinstance(mf, _DFHF):
        if mf.with_df is None:
            mf = mf.__class__(mf)
        elif mf.with_df.auxbasis != auxbasis:
            if (isinstance(mf, newton_ah._CIAH_SOSCF)
                    and isinstance(mf._scf, _DFHF)):
                mf.with_df = copy.copy(mf.with_df)
                mf.with_df.auxbasis = auxbasis
            else:
                raise RuntimeError('DFHF has been initialized. '
                                   'It cannot be initialized twice.')
        return mf

    if with_df is None:
        if isinstance(mf, dhf.UHF):
            with_df = df.DF4C(mf.mol)
        else:
            with_df = df.DF(mf.mol)
        with_df.max_memory = mf.max_memory
        with_df.stdout = mf.stdout
        with_df.verbose = mf.verbose
        with_df.auxbasis = auxbasis

    mf_class = mf.__class__

    class DFHF(mf_class, _DFHF):
        __doc__ = '''
        Density fitting SCF class

        Attributes for density-fitting SCF:
            auxbasis : str or basis dict
                Same format to the input attribute mol.basis.
                The default basis 'weigend+etb' means weigend-coulomb-fit basis
                for light elements and even-tempered basis for heavy elements.
            with_df : DF object
                Set mf.with_df = None to switch off density fitting mode.

        See also the documents of class %s for other SCF attributes.
        ''' % mf_class

        def __init__(self, mf):
            self.__dict__.update(mf.__dict__)
            self._eri = None
            self.auxbasis = auxbasis
            self.direct_scf = False
            self.with_df = with_df
            self._keys = self._keys.union(['auxbasis', 'with_df'])

        def get_jk(self, mol=None, dm=None, hermi=1):
            if self.with_df:
                if mol is None: mol = self.mol
                if dm is None: dm = self.make_rdm1()
                vj, vk = self.with_df.get_jk(dm, hermi)
                return vj, vk
            else:
                return mf_class.get_jk(self, mol, dm, hermi)

        def get_j(self, mol=None, dm=None, hermi=1):
            if self.with_df:
                if mol is None: mol = self.mol
                if dm is None: dm = self.make_rdm1()
                vj = self.with_df.get_jk(dm, hermi, with_k=False)[0]
                return vj
            else:
                return mf_class.get_j(self, mol, dm, hermi)

        def get_k(self, mol=None, dm=None, hermi=1):
            if self.with_df:
                if mol is None: mol = self.mol
                if dm is None: dm = self.make_rdm1()
                vk = self.with_df.get_jk(dm, hermi, with_j=False)[1]
                return vk
            else:
                return mf_class.get_k(self, mol, dm, hermi)

# _cderi accesser for pyscf 1.0, 1.1 compatibility

        @property
        def _cderi(self):
            return self.with_df._cderi

        @_cderi.setter
        def _cderi(self, x):
            self.with_df._cderi = x

    return DFHF(mf)
Пример #5
0
def density_fit(mf, auxbasis=None, with_df=None):
    '''For the given SCF object, update the J, K matrix constructor with
    corresponding density fitting integrals.

    Args:
        mf : an SCF object

    Kwargs:
        auxbasis : str or basis dict
            Same format to the input attribute mol.basis.  If auxbasis is
            None, optimal auxiliary basis based on AO basis (if possible) or
            even-tempered Gaussian basis will be used.

    Returns:
        An SCF object with a modified J, K matrix constructor which uses density
        fitting integrals to compute J and K

    Examples:

    >>> mol = gto.M(atom='H 0 0 0; F 0 0 1', basis='ccpvdz', verbose=0)
    >>> mf = scf.density_fit(scf.RHF(mol))
    >>> mf.scf()
    -100.005306000435510

    >>> mol.symmetry = 1
    >>> mol.build(0, 0)
    >>> mf = scf.density_fit(scf.UHF(mol))
    >>> mf.scf()
    -100.005306000435510
    '''
    from pyscf import df
    from pyscf.scf import dhf
    mf_class = mf.__class__
    if mf_class.__doc__ is None:
        doc = ''
    else:
        doc = mf_class.__doc__

    if with_df is None:
        if isinstance(mf, dhf.UHF):
            with_df = df.DF4C(mf.mol)
        else:
            with_df = df.DF(mf.mol)
        with_df.max_memory = mf.max_memory
        with_df.stdout = mf.stdout
        with_df.verbose = mf.verbose
        with_df.auxbasis = auxbasis

    class DFHF(mf_class, _DFHF):
        __doc__ = doc + \
        '''
        Attributes for density-fitting SCF:
            auxbasis : str or basis dict
                Same format to the input attribute mol.basis.
                The default basis 'weigend+etb' means weigend-coulomb-fit basis
                for light elements and even-tempered basis for heavy elements.
        '''

        def __init__(self):
            self.__dict__.update(mf.__dict__)
            self.auxbasis = auxbasis
            self.direct_scf = False
            self.with_df = with_df
            self._keys = self._keys.union(['auxbasis', 'with_df'])

        def get_jk(self, mol=None, dm=None, hermi=1):
            if self.with_df:
                if mol is None: mol = self.mol
                if dm is None: dm = self.make_rdm1()
                vj, vk = self.with_df.get_jk(dm, hermi)
                return vj, vk
            else:
                return mf_class.get_jk(self, mol, dm, hermi)

        def get_j(self, mol=None, dm=None, hermi=1):
            if self.with_df:
                if mol is None: mol = self.mol
                if dm is None: dm = self.make_rdm1()
                vj = self.with_df.get_jk(dm, hermi, with_k=False)[0]
                return vj
            else:
                return mf_class.get_j(self, mol, dm, hermi)

        def get_k(self, mol=None, dm=None, hermi=1):
            if self.with_df:
                if mol is None: mol = self.mol
                if dm is None: dm = self.make_rdm1()
                vk = self.with_df.get_jk(dm, hermi, with_j=False)[1]
                return vk
            else:
                return mf_class.get_k(self, mol, dm, hermi)

# _cderi accesser for pyscf 1.0, 1.1 compatibility

        @property
        def _cderi(self):
            return self.with_df._cderi

        @_cderi.setter
        def _cderi(self, x):
            self.with_df._cderi = x

        @property
        def _tag_df(self):
            sys.stderr.write(
                'WARN: Deprecated attribute ._tag_df will be removed in future release. '
                'It is replaced by attribute .with_df\n')
            if self.with_df:
                return True
            else:
                return False

    return DFHF()