Default AGF2 corresponds to the AGF2(1,0) method outlined in the papers: - O. J. Backhouse, M. Nusspickel and G. H. Booth, J. Chem. Theory Comput., 16, 1090 (2020). - O. J. Backhouse and G. H. Booth, J. Chem. Theory Comput., 16, 6294 (2020). ''' from pyscf import gto, scf, agf2, mp mol = gto.M(atom='O 0 0 0; H 0 0 1; H 0 1 0', basis='cc-pvdz') mf = scf.RHF(mol) mf.conv_tol = 1e-12 mf.run() # Run an AGF2 calculation gf2 = agf2.AGF2(mf) gf2.conv_tol = 1e-7 # Freeze two orbitals (four electrons) gf2.frozen = 2 gf2.run() # Print the first 3 ionization potentials gf2.ipagf2(nroots=3) # Print the first 3 electron affinities gf2.eaagf2(nroots=3) # Check that a high-moment calculation is equal to MP2 in the first iteration for frozen core example mol = gto.M(atom='H 0 0 0; Li 0 0 1', basis='cc-pvdz') mf = scf.RHF(mol)
# ''' A simple example of restricted AGF2. AGF2 will compute correlation energies, one-particle properties and charged excitations / energy levels via an iterated, renormalized perturbation theory. Default AGF2 corresponds to the AGF2(1,0) method outlined in the papers: - O. J. Backhouse, M. Nusspickel and G. H. Booth, J. Chem. Theory Comput., 16, 1090 (2020). - O. J. Backhouse and G. H. Booth, J. Chem. Theory Comput., 16, 6294 (2020). ''' from pyscf import gto, scf, agf2 mol = gto.M(atom='O 0 0 0; H 0 0 1; H 0 1 0', basis='cc-pvdz') mf = scf.RHF(mol) mf.conv_tol = 1e-12 mf.run() # Run an AGF2 calculation gf2 = agf2.AGF2(mf) gf2.conv_tol = 1e-7 gf2.run(verbose=4) # Print the first 3 ionization potentials # Note that there is no additional cost to write out larger numbers of excitations. gf2.ipagf2(nroots=3) # Print the first 3 electron affinities gf2.eaagf2(nroots=3)
- O. J. Backhouse, M. Nusspickel and G. H. Booth, J. Chem. Theory Comput., 16, 1090 (2020). - O. J. Backhouse and G. H. Booth, J. Chem. Theory Comput., 16, 6294 (2020). ''' import numpy from pyscf import gto, scf, agf2, adc mol = gto.M(atom='O 0 0 0; H 0 0 1; H 0 1 0', basis='cc-pvdz', verbose=0) mf = scf.RHF(mol) mf.conv_tol = 1e-12 mf.run() # We can build the compressed ADC(2) self-energy as the zeroth iteration # of AGF2, taking only the space corresponding to 1p coupling to 2p1h gf2 = agf2.AGF2(mf) se = gf2.build_se() se = se.get_occupied() # 2p1h/1p2h -> 2p1h se.coupling = se.coupling[:gf2.nocc] # 1p/1h -> 1p # Use the adc module to get the 1p space from ADC(2). In AGF2, this is the # bare Fock matrix, and is relaxed through the self-consistency. We can use # the ADC 1p space instead. adc2 = adc.radc.RADCIP(adc.ADC(mf).run()) h_1p = adc2.get_imds() # Find the eigenvalues of the self-energy in the 'extended Fock matrix' # format, which are the ionization potentials: e_ip = se.eig(h_1p)[0] print('IP-ADC(2) using the AGF2 solver (with renormalization):') print(-e_ip[-1])
else: nmom_o = nmom_v = self.nmom[1] se_occ = self.build_se_part(eri, gf_occ, gf_vir, nmom_o, **facs) se_vir = self.build_se_part(eri, gf_vir, gf_occ, nmom_v, **facs) se = agf2.aux.combine(se_occ, se_vir) se = se.compress(phys=fock, n=(self.nmom[0], None)) if se_prev is not None and self.damping != 0.0: se.coupling *= np.sqrt(1.0-self.damping) se_prev.coupling *= np.sqrt(self.damping) se = aux.combine(se, se_prev) se = se.compress(n=self.nmom) return se if __name__ == '__main__': from pyscf import gto, scf, agf2 mol = gto.M(atom='O 0 0 0; O 0 0 1', basis='6-31g', verbose=4) rhf = scf.RHF(mol).run() gf2_a = agf2.AGF2(rhf, nmom=(2,3)).run() gf2_b = RAGF2(rhf, nmom=(2,3)).run()
for i in range(1, nblock + 1): m[i] = c[i, 1, i] return m, b if __name__ == '__main__': from pyscf import gto, scf, mp, agf2 nmom = 5 mol = gto.M(atom='O 0 0 0; O 0 0 1', basis='cc-pvdz', verbose=False) rhf = scf.RHF(mol).run() mp2 = mp.MP2(rhf).run() gf2 = agf2.AGF2(rhf, nmom=(None, None)) se = gf2.build_se() t_occ = se.get_occupied().moment(range(2 * nmom + 2)) t_vir = se.get_virtual().moment(range(2 * nmom + 2)) se_occ = agf2.SelfEnergy( *build_from_tridiag(*block_lanczos(t_occ, nmom + 1)), chempot=se.chempot) se_vir = agf2.SelfEnergy( *build_from_tridiag(*block_lanczos(t_vir, nmom + 1)), chempot=se.chempot) se = agf2.aux.combine(se_occ, se_vir) e_mp2 = agf2.ragf2.energy_mp2(gf2, rhf.mo_energy, se)
from pyscf import gto, scf, agf2, mp mol = gto.M(atom='O 0 0 0; H 0 0 1; H 0 1 0', basis='6-31g') mf = scf.RHF(mol) mf.conv_tol = 1e-12 mf.run() # Get the canonical MP2 mp2 = mp.MP2(mf) mp2.run() # We can use very high moment calculations to converge to traditional GF2 limit. # We can also use the zeroth iteration to quantify the AGF2 error by comparison # to the MP2 energy. gf2_56 = agf2.AGF2(mf, nmom=(5,6)) gf2_56.build_se() e_mp2 = gf2_56.energy_mp2() print('Canonical MP2 Ecorr: ', mp2.e_corr) print('AGF2(%s,%s) MP2 Ecorr: '%gf2_56.nmom, e_mp2) print('Error: ', abs(mp2.e_corr - e_mp2)) # Run a high moment AGF2(5,6) calculation and compare to AGF2 (AGF2 as # default in pyscf is technically AGF2(None,0)). See # second reference for more details. gf2_56.run() gf2 = agf2.AGF2(mf) gf2.run()