Skip to content

Latest commit

 

History

History
179 lines (134 loc) · 6.97 KB

adc.rst

File metadata and controls

179 lines (134 loc) · 6.97 KB

Algebraic diagrammatic construction (ADC)

Modules: :py:mod:`pyscf.adc`

Introduction

The algebraic diagrammatic construction theory (ADC(n)) is a post-Hartree-Fock method used for computing correlated excited states of molecules. :cite:`Schirmer1983,Schirmer1998` The ADC methods involve a perturbative expansion of a propagator followed by truncation at a certain order n that defines the ADC(n) approximation. Depending upon the property being investigated, propagators can be of different types. Some common examples include the polarization propagator for neutral electronic excitations, the one-particle Green's function for charged excitations, and the two-electron propagator for Auger electron spectroscopy. The different propagators lead to different variants of the ADC method.

At present, the adc module in PySCF can be used to calculate the one-particle Green's function, that provides access to charged excitations, such as ionization potentials (IP-ADC) and electron affinities (EA-ADC) with different ADC(n) approximations (ADC(2), ADC(2)-X and ADC(3)). :cite:`Trofimov2005,Banerjee2019` The ADC(n) methods provide access to the excitation energies and their corresponding transition intensities via a 'one-shot' calculation.

A simple ADC(n) computation involves the calculation of the ground-state energy and wavefunction that correspond to those of the n-th order Møller--Plesset perturbation theory (MPn), followed by the evaluation of the ADC(n) excitation energies (e.g., IP or EA) and the corresponding transition probabilities.

An example of IP and EA computation using the default ADC method (ADC(2)) is shown below:

from pyscf import gto, scf, adc
mol = gto.M(atom='H 0 0 0; F 0 0 1', basis='ccpvdz')
mf = scf.RHF(mol).run()
myadc = adc.ADC(mf)
myadc.kernel_gs()
e_ip,v_ip,p_ip,x_ip,adc_es = myadc.ip_adc()
e_ea,v_ea,p_ea,x_ea,adc_ea = myadc.ea_adc()

In the example shown above, the ground state calculation is performed by running the function kernel_gs(), whereas the excited state calculations are carried out using the ip_adc() and ea_adc() functions.

Alternatively, both the ground and excited state calculations can be run together using the kernel() function:

from pyscf import gto, scf, adc
mol = gto.M(atom='H 0 0 0; F 0 0 1', basis='ccpvdz')
mf = scf.RHF(mol).run()
myadc = adc.ADC(mf)
myadc.kernel()

By default, the kernel() function performs a IP-ADC(2) calculation. One can specify the type of charged excitation and order of the desired ADC computation:

myadc.method = "adc(3)"
myadc.method_type = "ea"
myadc.kernel()

The ADC functions return the nroots lowest-energy eigenvalues. The default value of nroots is set to 1. More roots can be requested using:

myadc.kernel(nroots=3)

More examples can be found in :source:`examples/adc/01-closed_shell.py`, :source:`examples/adc/03-closed_shell_different_setup.py`.

Spin-restricted and spin-unrestricted calculations

The adc module can be used to perform calculations of IP's and EA's of closed- and open-shell molecules starting with the RHF and UHF reference wavefunctions, leading to the RADC(n) and UADC(n) methods, respectively. :cite:`Banerjee2021` See :ref:`user_scf` to learn more about the different reference wavefunctions.

Shown below is an example of the IP- and EA-UADC(2) calculations for the open-shell OH radical:

from pyscf import gto, scf, adc
mol = gto.M(atom='O 0 0 0; H 0 0 1', basis='aug-cc-pvdz')
mol.spin  = 1
mf = scf.UHF(mol).run()

myadc = adc.ADC(mf)  # This is a UADC calculation
myadc.kernel_gs()
eip,vip,pip,xip,ip_es = myadc.ip_adc()
eea,vea,pea,xea,ea_es = myadc.ea_adc()

More examples can be found in :source:`examples/adc/ 02-open_shell.py`, :source:`examples/adc/`04-open_shell_different_setup.py`.

Spectroscopic properties

The adc module supports calculation of the spectroscopic factors, which provide information about probabilities of transitions in the photoelectron spectra. :cite:`Banerjee2021` Computation of spectroscopic factors is performed by default and can be switched off by setting compute_properties = False

myadc.compute_properties = False
myadc.method = "adc(3)"
myadc.method_type = "ip"
myadc.kernel(nroots = 3)

After the ADC calculation is performed, the adc module can be used to compute the Dyson orbitals :cite:`Oana2007` corresponding to ionized and electron-attached states:

dyson_orb = myadc.compute_dyson_mo()

Analysis of spectroscopic properties

The adc module allows to perform the analysis of the ADC(n) eigenvectors, that can be useful for characterizing the nature of electronic transitions. When compute_properties is set to True, this analysis will also display the largest contributions to the spectroscopic factors. The analysis of the ADC(n) eigenvectors and spectroscopic factors can be invoked using the analyze() function:

myadc.kernel(nroots = 3)
myadc.analyze()

Algorithms and job control

The capabilities of the adc module at present are summarized in in the following table:

Method Reference Spin-adaptation Properties
ADC(2) RHF, UHF Yes IP, EA, spectroscopic factors, Dyson orb
ADC(2)-X RHF, UHF Yes IP, EA, spectroscopic factors, Dyson orb
ADC(3) RHF, UHF Yes IP, EA, spectroscopic factors, Dyson orb

The ADC(n) calculations can be performed using different algorithms, depending on the available memory controlled by the max_memory keyword:

  • In-core

    All tensors such as two-electron integrals and amplitudes are stored in memory. This is the default algorithm used when sufficient memory is available.

  • Out-of-core

    Use of disk to store the expensive tensors. This algorithm is invoked by setting max_memory to a small value. See :source:`examples/adc/05-outcore.py`

  • Density-fitted (DF) algorithm

The memory and disk usage can be greatly reduced by approximating the two-electron integrals with density-fitting. A simple example of a DF-ADC(2) calculation is:

from pyscf import gto, scf, adc, df
mol = gto.M(atom='H 0 0 0; F 0 0 1', basis='ccpvdz')

mf = scf.RHF(mol).density_fit('ccpvdz-jkfit').run()
myadc = adc.ADC(mf).density_fit('ccpvdz-ri')
eip,vip,pip,xip = myadc.kernel()

More examples can be found in: :source:`examples/adc/06-dfadc.py`.