# GW approximation¶

*Modules*: `pyscf.gw`

, `pyscf.pbc.gw`

## Introduction¶

The GW approximation is a Green’s function-based method that calculates charged
excitation energies, i.e. ionizations potentials (IPs) and electron affinities
(EAs). PySCF implements the G_{0}W_{0} approximation, in which the
self-energy is built with mean-field orbitals and orbital energies. Therefore,
the results depend on the mean-field starting point, which can be Hartree-Fock
or density functional theory. As described below, PySCF has three
implementations of the GW approximation, all of which are “full-frequency”.

An example GW calculation is shown below:

```
#!/usr/bin/env python
'''
A simple example to run a GW calculation
'''
from pyscf import gto, dft, gw
mol = gto.M(
atom = 'H 0 0 0; F 0 0 1.1',
basis = 'ccpvdz')
mf = dft.RKS(mol)
mf.xc = 'pbe'
mf.kernel()
nocc = mol.nelectron//2
# By default, GW is done with analytic continuation
gw = gw.GW(mf)
# same as gw = gw.GW(mf, freq_int='ac')
gw.kernel(orbs=range(nocc-3,nocc+3))
print(gw.mo_energy)
```

In this example, the `orbs`

keyword argument is
provided to select which GW orbital energies are requested. By default,
all orbital energies (occupied and unoccupied) will be calculated, which
will increase the cost and may have errors, depending on the method
of frequency integration.

## Frequency integration¶

The frequency integration needed for the GW approximation can be done in three
ways, controlled by the `freq_int`

keyword argument: by analytic continuation
(AC, `freq_int='ac'`

), contour deformation (CD, `freq_int='cd'`

), or
exactly (Exact, `freq_int='exact'`

). The first two are much more affordable
and typically provide sufficient accuracy. GW-AC supports spin-restricted and
spin-unrestricted calculations; GW-CD and GW-Exact only support spin-restricted
calculations. Details of the GW-AC and GW-CD implementations in PySCF can be
found in Ref. [30].

### Analytic continuation¶

Integration via analytic continuation is implemented in the `GWAC`

module
that is accessed with `freq_int='ac'`

, which is also
the default `GW`

module. GW-AC has \(N^4\) scaling and is recommended for
valence states only.
The analytic continuation can be done using a Pade
approximation (default, more reliable) or a two-pole model, controlled by the `ac`

attribute.
GW-AC supports frozen core orbitals for reducing computational cost,
controlled by the `frozen`

attribute (number of frozen core MOs neglected in GW-AC
calculation). Frozen core orbitals are not supported by other GW methods currently.
There are two ways to compute GW orbital energies, controlled by the `linearized`

attribute:
`linearized=False`

(default) solves the quasiparticle equation through a Newton solver
self-consistently, while `linearized=True`

employs a linearization approximation:

```
mygw = gw.GW(mf) # same as freq_int='ac' or GWAC module
# mygw.ac = 'pade' # default
mygw.ac = 'twopole'
mygw.frozen = 1 # default is None
mygw.linearized = False # default
mygw.kernel(orbs=range(nocc-3,nocc+3))
```

### Contour deformation¶

Integration via contour deformation is implemented in the `GWCD`

module
that is accessed with `freq_int='cd'`

.
GW-CD has \(N^4\) scaling and is slower, but more robust, than GW-AC.
GW-CD is particularly recommended for accurate core and high-energy states:

```
mygw = gw.GW(mf, freq_int='cd').run(orbs=[0,1])
```

### Exact¶

Exact frequency integration can be carried out analytically and is implemented
in the `GWExact`

module that is accessed with `freq_int='exact'`

. Exact integration
requires complete diagonalization of the RPA matrix, which has \(N^6\)
scaling. However, all orbital energies can be readily obtained without error:

```
mygw = gw.GW(mf, freq_int='exact').run()
```

By default, GW-Exact, like the other GW implementations, use the direct random-phase
approximation (dRPA) to screen the Coulomb interaction.
Within GW-Exact, any alternative time-dependent mean-field theory (TDHF, TDDFT, etc.) can
be also used. The instance of an executed `tdscf`

method can be provided as a
keyword argument:

```
#!/usr/bin/env python
'''
GW calculation with exact frequency integration
and TDDFT screening instead of dRPA
'''
from pyscf import gto, dft, gw
mol = gto.M(
atom = 'H 0 0 0; F 0 0 1.1',
basis = 'ccpvdz')
mf = dft.RKS(mol)
mf.xc = 'pbe'
mf.kernel()
from pyscf import tdscf
nocc = mol.nelectron//2
nmo = mf.mo_energy.size
nvir = nmo-nocc
td = tdscf.TDDFT(mf)
td.nstates = nocc*nvir
td.verbose = 0
td.kernel()
gw = gw.GW(mf, freq_int='exact', tdmf=td)
gw.kernel()
print(gw.mo_energy)
```