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)
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)
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)
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)
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()