def f(mol): # Compute CCSD(T) energy mf = scf.RHF(mol).run() mycc = cc.CCSD(mf).run() et_correction = mycc.ccsd_t() e_tot = mycc.e_tot + et_correction # Compute CCSD(T) gradients eris = mycc.ao2mo() t1, t2 = mycc.t1, mycc.t2 conv, l1, l2 = ccsd_t_lambda.kernel(mycc, eris, t1, t2, verbose=mycc.verbose) g = ccsd_t_grad.kernel(mycc, t1, t2, l1, l2, eris=eris, verbose=mycc.verbose) print('CCSD(T) nuclear gradients:') print(g) return e_tot, g
def run_ccsd(hf_chkfile, chkfile): mol, mf = pyqmc.recover_pyscf(hf_chkfile) mycc = pyscf.cc.CCSD(mf).run(verbose=0) dm1 = mycc.make_rdm1() from pyscf.cc import ccsd_t_lambda_slow as ccsd_t_lambda from pyscf.cc import ccsd_t_rdm_slow as ccsd_t_rdm eris = mycc.ao2mo() conv, l1, l2 = ccsd_t_lambda.kernel(mycc, eris, mycc.t1, mycc.t2) dm1_t = ccsd_t_rdm.make_rdm1(mycc, mycc.t1, mycc.t2, l1, l2, eris=eris) pyscf.lib.chkfile.save(chkfile, 'ccsd', {'energy': mycc.e_tot, 'rdm': dm1}) pyscf.lib.chkfile.save(chkfile, 'ccsdt', { 'energy': mycc.ccsd_t(), 'rdm': dm1_t })
#mol.verbose = 5 #mol.output = 'out_h2o' mol.atom = [[8, (0., 0., 0.)], [1, (0., -.957, .587)], [1, (0.2, .757, .487)]] #mol.basis = 'ccpvdz' mol.basis = '631g' mol.build() mf = scf.RHF(mol) mf.conv_tol = 1e-1 mf.scf() mcc = ccsd.CCSD(mf) mcc.conv_tol = 1e-14 ecc, t1, t2 = mcc.kernel() eris = mcc.ao2mo() e3ref = ccsd_t.kernel(mcc, eris, t1, t2) l1, l2 = ccsd_t_lambda.kernel(mcc, eris, t1, t2)[1:] print(ecc, e3ref) eri_mo = ao2mo.kernel(mf._eri, mf.mo_coeff, compact=False) nmo = mf.mo_coeff.shape[1] eri_mo = eri_mo.reshape(nmo, nmo, nmo, nmo) dm1 = make_rdm1(mcc, t1, t2, l1, l2, eris=eris) dm2 = make_rdm2(mcc, t1, t2, l1, l2, eris=eris) print(lib.finger(dm1) - 1.289951975176953) print(lib.finger(dm2) - 6.6184784979411164) h1 = reduce(numpy.dot, (mf.mo_coeff.T, mf.get_hcore(), mf.mo_coeff)) e3 = (numpy.einsum('ij,ji->', h1, dm1) + numpy.einsum('ijkl,ijkl->', eri_mo, dm2) * .5 + mf.mol.energy_nuc()) print(e3ref, e3 - (mf.e_tot + ecc))
[1 , (0. , 0.757 ,-0.587)]], basis = '631g' ) mf = scf.RHF(mol) mf.conv_tol = 1e-14 ehf = mf.scf() mycc = ccsd.CCSD(mf) mycc.conv_tol = 1e-10 mycc.conv_tol_normt = 1e-10 ecc, t1, t2 = mycc.kernel() eris = mycc.ao2mo() e3ref = ccsd_t.kernel(mycc, eris, t1, t2) print ehf+ecc+e3ref eris = mycc.ao2mo(mf.mo_coeff) conv, l1, l2 = ccsd_t_lambda.kernel(mycc, eris, t1, t2) g1 = kernel(mycc, t1, t2, l1, l2, eris=eris, mf_grad=grad.RHF(mf)) print(g1 + grad.grad_nuc(mol)) #O 0.0000000000 0.0000000000 -0.0112045345 #H 0.0000000000 0.0234464201 0.0056022672 #H 0.0000000000 -0.0234464201 0.0056022672 mol = gto.M( verbose = 0, atom = ''' H -1.90779510 0.92319522 0.08700656 H -1.08388168 -1.61405643 -0.07315086 H 2.02822318 -0.61402169 0.09396693 H 0.96345360 1.30488291 -0.10782263 ''',
atom=[["O", (0., 0., 0.)], [1, (0., -0.757, -0.587)], [1, (0., 0.757, -0.587)]], basis='631g') mf = scf.RHF(mol) mf.conv_tol = 1e-14 ehf = mf.scf() mycc = ccsd.CCSD(mf) mycc.conv_tol = 1e-10 mycc.conv_tol_normt = 1e-10 ecc, t1, t2 = mycc.kernel() eris = mycc.ao2mo() e3ref = ccsd_t.kernel(mycc, eris, t1, t2) print ehf + ecc + e3ref eris = mycc.ao2mo(mf.mo_coeff) conv, l1, l2 = ccsd_t_lambda.kernel(mycc, eris, t1, t2) g1 = kernel(mycc, t1, t2, l1, l2, eris=eris, mf_grad=grad.RHF(mf)) print(g1 + grad.grad_nuc(mol)) #O 0.0000000000 0.0000000000 -0.0112045345 #H 0.0000000000 0.0234464201 0.0056022672 #H 0.0000000000 -0.0234464201 0.0056022672 mol = gto.M(verbose=0, atom=''' H -1.90779510 0.92319522 0.08700656 H -1.08388168 -1.61405643 -0.07315086 H 2.02822318 -0.61402169 0.09396693 H 0.96345360 1.30488291 -0.10782263 ''', unit='bohr', basis='631g')
def solve(mol, nel, cf_core, cf_gs, ImpOrbs, chempot=0., n_orth=0): # cf_core : core orbitals (in AO basis, assumed orthonormal) # cf_gs : guess orbitals (in AO basis) # ImpOrbs : cf_gs -> impurity orbitals transformation # n_orth : number of orthonormal orbitals in cf_gs [1..n_orth] mol_ = gto.Mole() mol_.build(verbose=0) mol_.nelectron = nel mol_.incore_anyway = True cfx = cf_gs Sf = mol.intor_symmetric('cint1e_ovlp_sph') Hc = mol.intor_symmetric('cint1e_kin_sph') \ + mol.intor_symmetric('cint1e_nuc_sph') occ = np.zeros((cfx.shape[1], )) occ[:nel / 2] = 2. # core contributions dm_core = np.dot(cf_core, cf_core.T) * 2 jk_core = scf.hf.get_veff(mol, dm_core) e_core = np.trace(np.dot(Hc, dm_core)) \ + 0.5*np.trace(np.dot(jk_core, dm_core)) # transform integrals Sp = np.dot(cfx.T, np.dot(Sf, cfx)) Hp = np.dot(cfx.T, np.dot(Hc, cfx)) jkp = np.dot(cfx.T, np.dot(jk_core, cfx)) intsp = ao2mo.outcore.full_iofree(mol, cfx) # orthogonalize cf [virtuals] cf = np.zeros((cfx.shape[1], ) * 2, ) if n_orth > 0: assert (n_orth <= cfx.shape[1]) assert (np.allclose(np.eye(n_orth), Sp[:n_orth, :n_orth])) else: n_orth = 0 cf[:n_orth, :n_orth] = np.eye(n_orth) if n_orth < cfx.shape[1]: val, vec = sla.eigh(-Sp[n_orth:, n_orth:]) idx = -val > 1.e-12 U = np.dot(vec[:,idx]*1./(np.sqrt(-val[idx])), \ vec[:,idx].T) cf[n_orth:, n_orth:] = U # define ImpOrbs projection Xp = np.dot(ImpOrbs, ImpOrbs.T) # Si = np.dot(ImpOrbs.T, np.dot(Sp, ImpOrbs)) # Mp = np.dot(ImpOrbs, np.dot(sla.inv(Si), ImpOrbs.T)) Np = np.dot(Sp, Xp) # print ( np.allclose(Np, np.dot(Np, np.dot(Mp, Np))) ) # HF calculation mol_.energy_nuc = lambda *args: mol.energy_nuc() + e_core mf = scf.RHF(mol_) #mf.verbose = 4 mf.mo_coeff = cf mf.mo_occ = occ mf.get_ovlp = lambda *args: Sp mf.get_hcore = lambda *args: Hp + jkp - 0.5 * chempot * (Np + Np.T) mf._eri = ao2mo.restore(8, intsp, cfx.shape[1]) nt = scf.newton(mf) #nt.verbose = 4 nt.max_cycle_inner = 1 nt.max_stepsize = 0.25 nt.ah_max_cycle = 32 nt.ah_start_tol = 1.0e-12 nt.ah_grad_trust_region = 1.0e8 nt.conv_tol_grad = 1.0e-6 nt.kernel() cf = nt.mo_coeff if not nt.converged: raise RuntimeError('hf failed to converge') mf.mo_coeff = nt.mo_coeff mf.mo_energy = nt.mo_energy mf.mo_occ = nt.mo_occ #CCSD(T) only implementation available is slow. from pyscf.cc import ccsd_t_slow as ccsd_t from pyscf.cc import ccsd_t_lambda_slow as ccsd_t_lambda from pyscf.cc import ccsd_t_rdm_slow as ccsd_t_rdm # CC solution ccsolver = cc.CCSD(mf) ccsolver.verbose = 5 ecc, t1, t2 = ccsolver.kernel() # CCSD(T) solution eris = ccsolver.ao2mo() e3ref = ccsd_t.kernel(ccsolver, eris, t1, t2) l1, l2 = ccsd_t_lambda.kernel(ccsolver, eris, t1, t2)[1:] print("CCSD(T) energy ", ecc + e3ref) rdm1 = ccsd_t_rdm.make_rdm1(ccsolver, t1, t2, l1, l2, eris=eris) rdm2 = ccsd_t_rdm.make_rdm2(ccsolver, t1, t2, l1, l2, eris=eris) # transform rdm's to original basis tei = ao2mo.restore(1, intsp, cfx.shape[1]) rdm1 = np.dot(cf, np.dot(rdm1, cf.T)) rdm2 = np.einsum('ai,ijkl->ajkl', cf, rdm2) rdm2 = np.einsum('bj,ajkl->abkl', cf, rdm2) rdm2 = np.einsum('ck,abkl->abcl', cf, rdm2) rdm2 = np.einsum('dl,abcl->abcd', cf, rdm2) ImpEnergy = +0.25 *np.einsum('ij,jk,ki->', 2*Hp+jkp, rdm1, Xp) \ +0.25 *np.einsum('ij,jk,ki->', 2*Hp+jkp, Xp, rdm1) \ +0.125*np.einsum('ijkl,ijkm,ml->', tei, rdm2, Xp) \ +0.125*np.einsum('ijkl,ijml,mk->', tei, rdm2, Xp) \ +0.125*np.einsum('ijkl,imkl,mj->', tei, rdm2, Xp) \ +0.125*np.einsum('ijkl,mjkl,mi->', tei, rdm2, Xp) Nel = np.trace(np.dot(np.dot(rdm1, Sp), Xp)) return Nel, ImpEnergy
# CCSD energy based on density matrices # h1 = numpy.einsum('pi,pq,qj->ij', mf.mo_coeff.conj(), mf.get_hcore(), mf.mo_coeff) nmo = mf.mo_coeff.shape[1] eri = ao2mo.kernel(mol, mf.mo_coeff, compact=False).reshape([nmo] * 4) E = numpy.einsum('pq,qp', h1, dm1) # Note dm2 is transposed to simplify its contraction to integrals E += numpy.einsum('pqrs,pqrs', eri, dm2) * .5 E += mol.energy_nuc() print('E(CCSD) = %s, reference %s' % (E, mycc.e_tot)) # When plotting CCSD density on grids, CCSD density matrices need to be # transformed to AO basis representation. dm1_ao = numpy.einsum('pi,ij,qj->pq', mf.mo_coeff, dm1, mf.mo_coeff.conj()) from pyscf.tools import cubegen cubegen.density(mol, 'rho_ccsd.cube', dm1_ao) ### # # Compute CCSD(T) density matrices with ccsd_t-slow implementation # (as of pyscf v1.7) # from pyscf.cc import ccsd_t_lambda_slow as ccsd_t_lambda from pyscf.cc import ccsd_t_rdm_slow as ccsd_t_rdm eris = mycc.ao2mo() conv, l1, l2 = ccsd_t_lambda.kernel(mycc, eris, mycc.t1, mycc.t2) dm1 = ccsd_t_rdm.make_rdm1(mycc, mycc.t1, mycc.t2, l1, l2, eris=eris) dm2 = ccsd_t_rdm.make_rdm2(mycc, mycc.t1, mycc.t2, l1, l2, eris=eris)
# # Author: Qiming Sun <*****@*****.**> # ''' CCSD and CCSD(T) lambda equation ''' import pyscf mol = pyscf.M(atom=''' O 0. 0. 0. H 0. -0.757 0.587 H 0. 0.757 0.587''', basis='cc-pvdz') mf = mol.RHF().run() cc = mf.CCSD().run() # # Solutions for CCSD Lambda equations are saved in cc.l1 and cc.l2 # cc.solve_lambda() print(cc.l1.shape) print(cc.l2.shape) ### # # Compute CCSD(T) lambda with ccsd_t-slow implementation # (as of pyscf v1.7) # from pyscf.cc import ccsd_t_lambda_slow as ccsd_t_lambda conv, l1, l2 = ccsd_t_lambda.kernel(cc, cc.ao2mo(), cc.t1, cc.t2, tol=1e-8)
[8 , (0. , 0. , 0.)], [1 , (0. , -.957 , .587)], [1 , (0.2, .757 , .487)]] #mol.basis = 'ccpvdz' mol.basis = '631g' mol.build() mf = scf.RHF(mol) mf.conv_tol = 1e-14 mf.scf() mcc = ccsd.CCSD(mf) mcc.conv_tol = 1e-14 ecc, t1, t2 = mcc.kernel() eris = mcc.ao2mo() e3ref = ccsd_t.kernel(mcc, eris, t1, t2) l1, l2 = ccsd_t_lambda.kernel(mcc, eris, t1, t2)[1:] print(ecc, e3ref) eri_mo = ao2mo.kernel(mf._eri, mf.mo_coeff, compact=False) nmo = mf.mo_coeff.shape[1] eri_mo = eri_mo.reshape(nmo,nmo,nmo,nmo) dm1 = make_rdm1(mcc, t1, t2, l1, l2, eris=eris) dm2 = make_rdm2(mcc, t1, t2, l1, l2, eris=eris) h1 = reduce(numpy.dot, (mf.mo_coeff.T, mf.get_hcore(), mf.mo_coeff)) e3 =(numpy.einsum('ij,ij->', h1, dm1) + numpy.einsum('ijkl,ijkl->', eri_mo, dm2)*.5 + mf.mol.energy_nuc()) #print e3ref, e3-(mf.e_tot+ecc) nocc, nvir = t1.shape eris_ovvv = _cp(eris.ovvv) eris_ovvv = _ccsd.unpack_tril(eris_ovvv.reshape(nocc*nvir,-1))