def test_gen_uhf_response(self): numpy.random.seed(9) dm1 = numpy.random.random(dm_he.shape) dm1 = dm1 + dm1.transpose(0,2,1) mydf = df.FFTDF(cell_he) ni = dft.numint.NumInt() mf = dft.UKS(cell_he) mf.with_df = multigrid.MultiGridFFTDF(cell_he) mf.xc = 'lda,' ref = dft.numint.nr_uks_fxc(ni, cell_he, mydf.grids, mf.xc, dm_he, dm1) vj = mydf.get_jk(dm1, with_k=False)[0] ref += vj[0] + vj[1] v = multigrid._gen_uhf_response(mf, dm_he, with_j=True)(dm1) self.assertEqual(ref.dtype, v.dtype) self.assertEqual(ref.shape, v.shape) self.assertAlmostEqual(abs(v-ref).max(), 0, 9) mf.xc = 'b88,' ref = dft.numint.nr_uks_fxc(ni, cell_he, mydf.grids, mf.xc, dm_he, dm1) ref += vj[0] + vj[1] v = multigrid._gen_uhf_response(mf, dm_he, with_j=True)(dm1) self.assertEqual(ref.dtype, v.dtype) self.assertEqual(ref.shape, v.shape) self.assertAlmostEqual(abs(v-ref).max(), 0, 7)
def test_gen_uhf_response(self): numpy.random.seed(9) dm1 = numpy.random.random(dm_he.shape) dm1 = dm1 + dm1.transpose(0, 2, 1) mydf = df.FFTDF(cell_he) ni = dft.numint.NumInt() mf = dft.UKS(cell_he) mf.with_df = multigrid.MultiGridFFTDF(cell_he) mf.xc = 'lda,' ref = dft.numint.nr_uks_fxc(ni, cell_he, mydf.grids, mf.xc, dm_he, dm1) vj = mydf.get_jk(dm1, with_k=False)[0] ref += vj[0] + vj[1] v = multigrid._gen_uhf_response(mf, dm_he, with_j=True)(dm1) self.assertEqual(ref.dtype, v.dtype) self.assertEqual(ref.shape, v.shape) self.assertAlmostEqual(abs(v - ref).max(), 0, 9) mf.xc = 'b88,' ref = dft.numint.nr_uks_fxc(ni, cell_he, mydf.grids, mf.xc, dm_he, dm1) ref += vj[0] + vj[1] v = multigrid._gen_uhf_response(mf, dm_he, with_j=True)(dm1) self.assertEqual(ref.dtype, v.dtype) self.assertEqual(ref.shape, v.shape) self.assertAlmostEqual(abs(v - ref).max(), 0, 7)
def _gen_uhf_response(mf, mo_coeff=None, mo_occ=None, with_j=True, hermi=0, max_memory=None): if mo_coeff is None: mo_coeff = mf.mo_coeff if mo_occ is None: mo_occ = mf.mo_occ mol = mf.mol if _is_dft_object(mf): from pyscf.dft import rks ni = mf._numint ni.libxc.test_deriv_order(mf.xc, 2, raise_error=True) if getattr(mf, 'nlc', '') != '': logger.warn( mf, 'NLC functional found in DFT object. Its second ' 'deriviative is not available. Its contribution is ' 'not included in the response function.') omega, alpha, hyb = ni.rsh_and_hybrid_coeff(mf.xc, mol.spin) hybrid = abs(hyb) > 1e-10 # mf can be pbc.dft.UKS object with multigrid if (not hybrid and 'MultiGridFFTDF' == getattr( mf, 'with_df', None).__class__.__name__): from pyscf.pbc.dft import multigrid dm0 = mf.make_rdm1(mo_coeff, mo_occ) return multigrid._gen_uhf_response(mf, dm0, with_j, hermi) rho0, vxc, fxc = ni.cache_xc_kernel(mol, mf.grids, mf.xc, mo_coeff, mo_occ, 1) #dm0 =(numpy.dot(mo_coeff[0]*mo_occ[0], mo_coeff[0].T.conj()), # numpy.dot(mo_coeff[1]*mo_occ[1], mo_coeff[1].T.conj())) dm0 = None if max_memory is None: mem_now = lib.current_memory()[0] max_memory = max(2000, mf.max_memory * .8 - mem_now) def vind(dm1): if hermi == 2: v1 = numpy.zeros_like(dm1) else: v1 = ni.nr_uks_fxc(mol, mf.grids, mf.xc, dm0, dm1, 0, hermi, rho0, vxc, fxc, max_memory=max_memory) if not hybrid: if with_j: vj = mf.get_j(mol, dm1, hermi=hermi) v1 += vj[0] + vj[1] else: if with_j: vj, vk = mf.get_jk(mol, dm1, hermi=hermi) vk *= hyb if abs(omega) > 1e-10: # For range separated Coulomb vk += mf.get_k(mol, dm1, hermi, omega) * (alpha - hyb) v1 += vj[0] + vj[1] - vk else: vk = mf.get_k(mol, dm1, hermi=hermi) vk *= hyb if abs(omega) > 1e-10: # For range separated Coulomb vk += mf.get_k(mol, dm1, hermi, omega) * (alpha - hyb) v1 -= vk return v1 elif with_j: def vind(dm1): vj, vk = mf.get_jk(mol, dm1, hermi=hermi) v1 = vj[0] + vj[1] - vk return v1 else: def vind(dm1): return -mf.get_k(mol, dm1, hermi=hermi) return vind
def _gen_uhf_response(mf, mo_coeff=None, mo_occ=None, with_j=True, hermi=0, max_memory=None): from pyscf.pbc.dft import numint, multigrid assert (isinstance(mf, (kuhf.KUHF, krohf.KROHF))) if mo_coeff is None: mo_coeff = mf.mo_coeff if mo_occ is None: mo_occ = mf.mo_occ cell = mf.cell kpts = mf.kpts if getattr(mf, 'xc', None) and getattr(mf, '_numint', None): ni = mf._numint ni.libxc.test_deriv_order(mf.xc, 2, raise_error=True) omega, alpha, hyb = ni.rsh_and_hybrid_coeff(mf.xc, spin=cell.spin) hybrid = abs(hyb) > 1e-10 if abs(omega) > 1e-10: # For range separated Coulomb raise NotImplementedError if not hybrid and isinstance(mf.with_df, multigrid.MultiGridFFTDF): dm0 = mf.make_rdm1(mo_coeff, mo_occ) return multigrid._gen_uhf_response(mf, dm0, with_j, hermi) rho0, vxc, fxc = ni.cache_xc_kernel(cell, mf.grids, mf.xc, mo_coeff, mo_occ, 1, kpts) #dm0 =(numpy.dot(mo_coeff[0]*mo_occ[0], mo_coeff[0].conj().T), # numpy.dot(mo_coeff[1]*mo_occ[1], mo_coeff[1].conj().T)) dm0 = None if max_memory is None: mem_now = lib.current_memory()[0] max_memory = max(2000, mf.max_memory * .8 - mem_now) def vind(dm1): if hermi == 2: v1 = numpy.zeros_like(dm1) else: v1 = ni.nr_uks_fxc(cell, mf.grids, mf.xc, dm0, dm1, 0, hermi, rho0, vxc, fxc, kpts, max_memory=max_memory) if not hybrid: if with_j: vj = mf.get_j(cell, dm1, hermi=hermi, kpts=kpts) v1 += vj[0] + vj[1] else: if with_j: vj, vk = mf.get_jk(cell, dm1, hermi=hermi, kpts=kpts) v1 += vj[0] + vj[1] - vk * hyb else: v1 -= hyb * mf.get_k(cell, dm1, hermi=hermi, kpts=kpts) return v1 elif with_j: def vind(dm1): vj, vk = mf.get_jk(cell, dm1, hermi=hermi, kpts=kpts) v1 = vj[0] + vj[1] - vk return v1 else: def vind(dm1): return -mf.get_k(cell, dm1, hermi=hermi, kpts=kpts) return vind
def _gen_uhf_response(mf, mo_coeff=None, mo_occ=None, with_j=True, hermi=0, max_memory=None): if mo_coeff is None: mo_coeff = mf.mo_coeff if mo_occ is None: mo_occ = mf.mo_occ mol = mf.mol if getattr(mf, 'xc', None) and getattr(mf, '_numint', None): from pyscf.dft import rks ni = mf._numint ni.libxc.test_deriv_order(mf.xc, 2, raise_error=True) if getattr(mf, 'nlc', '') != '': logger.warn(mf, 'NLC functional found in DFT object. Its second ' 'deriviative is not available. Its contribution is ' 'not included in the response function.') omega, alpha, hyb = ni.rsh_and_hybrid_coeff(mf.xc, mol.spin) hybrid = abs(hyb) > 1e-10 # mf can be pbc.dft.UKS object with multigrid if (not hybrid and 'MultiGridFFTDF' == getattr(mf, 'with_df', None).__class__.__name__): from pyscf.pbc.dft import multigrid dm0 = mf.make_rdm1(mo_coeff, mo_occ) return multigrid._gen_uhf_response(mf, dm0, with_j, hermi) rho0, vxc, fxc = ni.cache_xc_kernel(mol, mf.grids, mf.xc, mo_coeff, mo_occ, 1) #dm0 =(numpy.dot(mo_coeff[0]*mo_occ[0], mo_coeff[0].T.conj()), # numpy.dot(mo_coeff[1]*mo_occ[1], mo_coeff[1].T.conj())) dm0 = None if max_memory is None: mem_now = lib.current_memory()[0] max_memory = max(2000, mf.max_memory*.8-mem_now) def vind(dm1): if hermi == 2: v1 = numpy.zeros_like(dm1) else: v1 = ni.nr_uks_fxc(mol, mf.grids, mf.xc, dm0, dm1, 0, hermi, rho0, vxc, fxc, max_memory=max_memory) if not hybrid: if with_j: vj = mf.get_j(mol, dm1, hermi=hermi) v1 += vj[0] + vj[1] else: if with_j: vj, vk = mf.get_jk(mol, dm1, hermi=hermi) vk *= hyb if abs(omega) > 1e-10: # For range separated Coulomb vk += rks._get_k_lr(mol, dm1, omega, hermi) * (alpha-hyb) v1 += vj[0] + vj[1] - vk else: vk = mf.get_k(mol, dm1, hermi=hermi) vk *= hyb if abs(omega) > 1e-10: # For range separated Coulomb vk += rks._get_k_lr(mol, dm1, omega, hermi) * (alpha-hyb) v1 -= vk return v1 elif with_j: def vind(dm1): vj, vk = mf.get_jk(mol, dm1, hermi=hermi) v1 = vj[0] + vj[1] - vk return v1 else: def vind(dm1): return -mf.get_k(mol, dm1, hermi=hermi) return vind