def get_jk(self, u): mo_coeff = numpy.dot(self.mo_coeff, u) nmo = mo_coeff.shape[1] dms = [numpy.einsum('i,j->ij', mo_coeff[:,i], mo_coeff[:,i]) for i in range(nmo)] vj, vk = hf.get_jk(self.mol, dms, hermi=1) vj = numpy.asarray([reduce(numpy.dot, (mo_coeff.T, v, mo_coeff)) for v in vj]) vk = numpy.asarray([reduce(numpy.dot, (mo_coeff.T, v, mo_coeff)) for v in vk]) return vj, vk
def get_jk(self, mol=None, dm=None, hermi=1): if mol is None: mol = self.mol if dm is None: dm = self.make_rdm1() cpu0 = (time.clock(), time.time()) if self._eri is not None or self._is_mem_enough(): if self._eri is None: self._eri = _vhf.int2e_sph(mol._atm, mol._bas, mol._env) vj, vk = hf.dot_eri_dm(self._eri, dm, hermi) else: vj, vk = hf.get_jk(mol, dm, hermi, self.opt) logger.timer(self, 'vj and vk', *cpu0) return vj, vk
def get_jk_(self, mol=None, dm=None, hermi=1): if mol is None: mol = self.mol if dm is None: dm = self.make_rdm1() dm = numpy.asarray(dm) nao = dm.shape[-1] cpu0 = (time.clock(), time.time()) if self._eri is not None or mol.incore_anyway or self._is_mem_enough(): if self._eri is None: self._eri = _vhf.int2e_sph(mol._atm, mol._bas, mol._env) vj, vk = hf.dot_eri_dm(self._eri, dm.reshape(-1,nao,nao), hermi) else: if self.direct_scf: self.opt = self.init_direct_scf(mol) vj, vk = hf.get_jk(mol, dm.reshape(-1,nao,nao), hermi, self.opt) logger.timer(self, 'vj and vk', *cpu0) return vj.reshape(dm.shape), vk.reshape(dm.shape)
def get_jk(self, mol=None, dm=None, hermi=1): if mol is None: mol = self.mol if dm is None: dm = self.make_rdm1() dm = numpy.asarray(dm) nao = dm.shape[-1] cpu0 = (time.clock(), time.time()) if self._eri is not None or mol.incore_anyway or self._is_mem_enough(): if self._eri is None: self._eri = _vhf.int2e_sph(mol._atm, mol._bas, mol._env) vj, vk = hf.dot_eri_dm(self._eri, dm.reshape(-1, nao, nao), hermi) else: if self.direct_scf: self.opt = self.init_direct_scf(mol) vj, vk = hf.get_jk(mol, dm.reshape(-1, nao, nao), hermi, self.opt) logger.timer(self, 'vj and vk', *cpu0) return vj.reshape(dm.shape), vk.reshape(dm.shape)
def get_veff(mol, dm, dm_last=0, vhf_last=0, hermi=1, vhfopt=None): r'''Unrestricted Hartree-Fock potential matrix of alpha and beta spins, for the given density matrix .. math:: V_{ij}^\alpha &= \sum_{kl} (ij|kl)(\gamma_{lk}^\alpha+\gamma_{lk}^\beta) - \sum_{kl} (il|kj)\gamma_{lk}^\alpha \\ V_{ij}^\beta &= \sum_{kl} (ij|kl)(\gamma_{lk}^\alpha+\gamma_{lk}^\beta) - \sum_{kl} (il|kj)\gamma_{lk}^\beta Args: mol : an instance of :class:`Mole` dm : a list of ndarrays A list of density matrices, stored as (alpha,alpha,...,beta,beta,...) Kwargs: dm_last : ndarray or a list of ndarrays or 0 The density matrix baseline. When it is not 0, this function computes the increment of HF potential w.r.t. the reference HF potential matrix. vhf_last : ndarray or a list of ndarrays or 0 The reference HF potential matrix. hermi : int Whether J, K matrix is hermitian | 0 : no hermitian or symmetric | 1 : hermitian | 2 : anti-hermitian vhfopt : A class which holds precomputed quantities to optimize the computation of J, K matrices Returns: :math:`V_{hf} = (V^\alpha, V^\beta)`. :math:`V^\alpha` (and :math:`V^\beta`) can be a list matrices, corresponding to the input density matrices. Examples: >>> import numpy >>> from pyscf import gto, scf >>> from pyscf.scf import _vhf >>> mol = gto.M(atom='H 0 0 0; H 0 0 1.1') >>> dmsa = numpy.random.random((3,mol.nao_nr(),mol.nao_nr())) >>> dmsb = numpy.random.random((3,mol.nao_nr(),mol.nao_nr())) >>> dms = numpy.vstack((dmsa,dmsb)) >>> dms.shape (6, 2, 2) >>> vhfa, vhfb = scf.uhf.get_veff(mol, dms, hermi=0) >>> vhfa.shape (3, 2, 2) >>> vhfb.shape (3, 2, 2) ''' if ((isinstance(dm, numpy.ndarray) and dm.ndim == 4) or (isinstance(dm[0], numpy.ndarray) and dm[0].ndim == 3) or (isinstance(dm[0][0], numpy.ndarray) and dm[0][0].ndim == 2)): # remove first dim, compress (dma,dmb) dm = numpy.vstack(dm) ddm = numpy.array(dm, copy=False) - numpy.array(dm_last, copy=False) vj, vk = hf.get_jk(mol, ddm, hermi=hermi, vhfopt=vhfopt) nset = len(dm) // 2 vhf = _makevhf(vj, vk, nset) + numpy.array(vhf_last, copy=False) return vhf
def get_veff(mol, dm, dm_last=0, vhf_last=0, hermi=1, vhfopt=None): r'''Unrestricted Hartree-Fock potential matrix of alpha and beta spins, for the given density matrix .. math:: V_{ij}^\alpha &= \sum_{kl} (ij|kl)(\gamma_{lk}^\alpha+\gamma_{lk}^\beta) - \sum_{kl} (il|kj)\gamma_{lk}^\alpha \\ V_{ij}^\beta &= \sum_{kl} (ij|kl)(\gamma_{lk}^\alpha+\gamma_{lk}^\beta) - \sum_{kl} (il|kj)\gamma_{lk}^\beta Args: mol : an instance of :class:`Mole` dm : a list of ndarrays A list of density matrices, stored as (alpha,alpha,...,beta,beta,...) Kwargs: dm_last : ndarray or a list of ndarrays or 0 The density matrix baseline. When it is not 0, this function computes the increment of HF potential w.r.t. the reference HF potential matrix. vhf_last : ndarray or a list of ndarrays or 0 The reference HF potential matrix. hermi : int Whether J, K matrix is hermitian | 0 : no hermitian or symmetric | 1 : hermitian | 2 : anti-hermitian vhfopt : A class which holds precomputed quantities to optimize the computation of J, K matrices Returns: :math:`V_{hf} = (V^\alpha, V^\beta)`. :math:`V^\alpha` (and :math:`V^\beta`) can be a list matrices, corresponding to the input density matrices. Examples: >>> import numpy >>> from pyscf import gto, scf >>> from pyscf.scf import _vhf >>> mol = gto.M(atom='H 0 0 0; H 0 0 1.1') >>> dmsa = numpy.random.random((3,mol.nao_nr(),mol.nao_nr())) >>> dmsb = numpy.random.random((3,mol.nao_nr(),mol.nao_nr())) >>> dms = numpy.vstack((dmsa,dmsb)) >>> dms.shape (6, 2, 2) >>> vhfa, vhfb = scf.uhf.get_veff(mol, dms, hermi=0) >>> vhfa.shape (3, 2, 2) >>> vhfb.shape (3, 2, 2) ''' dm = numpy.asarray(dm) nao = dm.shape[-1] ddm = dm - numpy.asarray(dm_last) # dm.reshape(-1,nao,nao) to remove first dim, compress (dma,dmb) vj, vk = hf.get_jk(mol, ddm.reshape(-1, nao, nao), hermi=hermi, vhfopt=vhfopt) vhf = _makevhf(vj.reshape(dm.shape), vk.reshape(dm.shape)) vhf += numpy.asarray(vhf_last) return vhf
def dump(self, fname='mole.h5'): # Effective nbas = self.nbas - self.nfrozen sbas = nbas * 2 print('\n[iface.dump] (self.nbas,nbas)=', (self.nbas, nbas)) # Basic information f = h5py.File(fname, "w") cal = f.create_dataset("cal", (1, ), dtype='i') enuc = self.mol.energy_nuc() nelecA = self.nelec - self.nfrozen * 2 cal.attrs["nelec"] = nelecA cal.attrs["sbas"] = sbas cal.attrs["enuc"] = enuc cal.attrs["escf"] = 0. # Not useful at all # Intergrals flter = 'lzf' mcoeffC = self.mo_coeff[:, :self.nfrozen].copy() mcoeffA = self.mo_coeff[:, self.nfrozen:].copy() # Core part pCore = 2.0 * mcoeffC.dot(mcoeffC.T) vj, vk = hf.get_jk(self.mol, pCore) h = self.mf.get_hcore() fock = h + vj - 0.5 * vk fmo = reduce(numpy.dot, (mcoeffA.T, fock, mcoeffA)) ecore = 0.5 * numpy.trace(pCore.dot(h + fock)) # Active part nact = mcoeffA.shape[1] eri = ao2mo.general(self.mol, (mcoeffA, mcoeffA, mcoeffA, mcoeffA), compact=0) eri = eri.reshape(nact, nact, nact, nact) # Reorder if self.ifreorder: order = fielder.orbitalOrdering(eri, 'kij') else: order = list(range(mcoeffA.shape[1])) # Sort mcoeffA = mcoeffA[:, numpy.array(order)].copy() fmo = fmo[numpy.ix_(order, order)].copy() eri = eri[numpy.ix_(order, order, order, order)].copy() #======================== # Spin orbital integrals #======================== gmo_coeff = numpy.hstack((mcoeffC, mcoeffA)) print('gmo_coeff.shape=', gmo_coeff.shape) f.create_dataset("mo_coeff_spatialAll", data=gmo_coeff) # INT1e: h1e = numpy.zeros((sbas, sbas)) h1e[0::2, 0::2] = fmo # AA h1e[1::2, 1::2] = fmo # BB # INT2e: h2e = numpy.zeros((sbas, sbas, sbas, sbas)) h2e[0::2, 0::2, 0::2, 0::2] = eri # AAAA h2e[1::2, 1::2, 1::2, 1::2] = eri # BBBB h2e[0::2, 0::2, 1::2, 1::2] = eri # AABB h2e[1::2, 1::2, 0::2, 0::2] = eri # BBAA # <ij|kl> = [ik|jl] h2e = h2e.transpose(0, 2, 1, 3) # Antisymmetrize V[pqrs]=-1/2*<pq||rs> - In MPO construnction, only r<s part is used. h2e = -0.5 * (h2e - h2e.transpose(0, 1, 3, 2)) print('E[core]=', ecore) cal.attrs["ecor"] = ecore int1e = f.create_dataset("int1e", data=h1e, compression=flter) int2e = f.create_dataset("int2e", data=h2e, compression=flter) # Occupation occun = numpy.zeros(sbas) for i in range(self.nalpha - self.nfrozen): occun[2 * i] = 1.0 for i in range(self.nbeta - self.nfrozen): occun[2 * i + 1] = 1.0 print() print('initial occun for', len(occun), ' spin orbitals:\n', occun) sorder = numpy.array([[2 * i, 2 * i + 1] for i in order]).flatten() occun = occun[sorder].copy() assert abs(numpy.sum(occun) - nelecA) < 1.e-10 print("sorder:", sorder) print("occun :", occun) orbsym = numpy.array([0] * sbas) spinsym = numpy.array([[0, 1] for i in range(nbas)]).flatten() print("orbsym :", orbsym) print("spinsym:", spinsym) f.create_dataset("occun", data=occun) f.create_dataset("orbsym", data=orbsym) f.create_dataset("spinsym", data=spinsym) f.close() print('Successfully dump information for HS-DMRG calculations! fname=', fname) self.check(fname) return 0