MICCoM School 2022 Ex#1 : The vertical ionization potential of SiH4

We are going to compute the vertical ionization potential (VIP) of the silane molecule using two levels of theory, namely density functional theory (DFT) with the semilocal exchange-correlation functional PBE, and full-frequency G\(_0\)W\(_0\).

The VIP is the minimum amount of energy that is needed to remove an electron from a molecule. When the removal does not take into account ion relaxation processes (change of molecular geometry), the ionization is said to be vertical.

The experimental value for the VIP of silane is tabulated in the NIST chemistry webbook: http://webbook.nist.gov/chemistry/form-ser/.

VIP of silane = \(12.3\) eV (experimental value)

~ We would like to compute the VIP of silane from first principles using DFT and GW. ~

Let’s see which level of theory performs better.

1.1 : DFT calculation

We are going to numerically solve the Kohn-Sham equations for valence electrons only. Electronic wavefunctions and single-particle energies are obtained by solving the secular equation:

\begin{equation} H^{\text{KS}}[\rho] \, \psi_n = \varepsilon_n^{\text{KS}} \psi_n \end{equation}

The Kohn-Sham Hamiltonian of \(N\) interacting electrons includes the following terms:

\begin{equation} H^{\text{KS}}[\rho] = T + V_{\text{ion}} + V_{\text{Hartree}}[\rho] + V_{\text{xc}}[\rho] \end{equation}

where \(T\) is the kinetic energy, \(V_{\text{ion}}\) is the electron-ion potential, \(V_{\text{Hartree}}\) is the Hartree potential, and \(V_{\text{xc}}\) is the exchange-correlation potential.

Note that the secular equation needs to be solved self-consistenly since the operator that we are diagonalizing depends on the eigenvectors (\(\rho = \sum_n |\psi_n|^2\)).

We are going to use plane-waves as basis set, which means that an electronic wavefunction \(\psi_n\) is obtained by computing the coefficients \(C_n\) of the plane-waves expansion:

\begin{equation} \psi_n(\mathbf{r}) = \sum_{\mathbf{G}} C_n(\mathbf{G}) e^{i\mathbf{G}\cdot\mathbf{r}} \end{equation}

In this way the kinetic energy of a wavefunction is \(\sum_{\mathbf{G}} \left| C_n(\mathbf{G}) \right|^2 \mathbf{G}^2\). The total number of plane-waves is determined once we specify the size of the simulation box and the kinetic energy cutoff.

The electron-ion potetial \(V_{\text{ion}}\) is solved separately for each given atomic species. Pseudopotential files containing this information (previously computed) are typically loaded at the beginning of the calculation. Pseudopotentials can be downloaded from several websites, for instance:

In this tutorial we will be using only norm-conserving pseudopotentials, i.e., no ultrasoft or projector augmented wave (PAW).

The Hartree potential is determined self-consistely as \(V_{\text{Hartree}}(\mathbf{r}) = \int d\mathbf{r^\prime} \rho(\mathbf{r^\prime}) \frac{1}{|\mathbf{r}-\mathbf{r^\prime}|}\).

The exact form for the exchange and correlation potential is unknown. Many approximations are available. The user needs to make this decision. In this tutorial we will be using the PBE exchange-correlation functional, which belongs to the family of semilocal generalized gradient approximation (GGA).

If we interpret \(\varepsilon^{\text{KS}}_n\) as electronic excitation energies (which is physically incorrect but people still do this as an approximation), the VIP will simply be the energy of the highest occupied molecular orbital (HOMO) obtained in a DFT calculation.

\begin{equation} \text{VIP}^{\text{DFT}} = 0 - \varepsilon^{\text{KS}}_{\text{HOMO}} \end{equation}

Question: Where did the core electrons go?

Question: How many valence electrons do we have in SiH4?

Question: Plane-waves satisfy periodic boundary conditions, how can we simulate an isolated molecule?

The following files are needed in order to compute the electronic structure of SiH\(_4\) with DFT:

  • Si_ONCV_PBE-1.2.upf : pseudopotential file for Si

  • H_ONCV_PBE-1.2.upf : pseudopotential file for H

  • pw.in : input file for the DFT calculation (executable pw.x)

[1]:
# download the pseudopotential files
!wget -N -q http://www.quantum-simulation.org/potentials/sg15_oncv/upf/Si_ONCV_PBE-1.2.upf
!wget -N -q http://www.quantum-simulation.org/potentials/sg15_oncv/upf/H_ONCV_PBE-1.2.upf

# download the input file
!wget -N -q https://west-code.org/doc/training/silane/pw.in

Let’s give a quick look at the input for DFT (description of the input variables for pw.x can be found here: https://www.quantum-espresso.org/Doc/INPUT_PW.html).

[2]:
!cat pw.in
&control
calculation  = 'scf'
restart_mode = 'from_scratch'
pseudo_dir   = './'
outdir       = './'
prefix       = 'silane'
wf_collect   = .TRUE.
/
&system
ibrav           = 1
celldm(1)       = 20
nat             = 5
ntyp            = 2
ecutwfc         = 25.0
nbnd            = 10
assume_isolated ='mp'
/
&electrons
diago_full_acc = .TRUE.
/
ATOMIC_SPECIES
Si 28.0855  Si_ONCV_PBE-1.2.upf
H  1.00794   H_ONCV_PBE-1.2.upf
ATOMIC_POSITIONS bohr
Si      10.000000   10.000000  10.000000
H       11.614581   11.614581  11.614581
H        8.385418    8.385418  11.614581
H        8.385418   11.614581   8.385418
H       11.614581    8.385418   8.385418
K_POINTS {gamma}

We have placed the silane molecule in a cubic box (edge = 20 bohr), and specified a kinetic energy cutoff of 25 Ry.

We can run the DFT calculation invoking the executable pw.x on 4 cores. This calculation should finish in just a few seconds.

[3]:
!mpirun -n 4 pw.x -i pw.in > pw.out

Let’s extract the energy levels of the highest occupied molecular orbital (HOMO) and lowest unoccupied molecular orbital (LUMO) predicted by DFT.

[4]:
!grep 'highest occupied, lowest unoccupied level' pw.out
     highest occupied, lowest unoccupied level (ev):    -8.2251   -0.4647
  • HOMO : \(-8.2251\) eV

  • LUMO : \(-0.4647\) eV

Let’s plot this result.

[5]:
import matplotlib.pyplot as plt

# VIP
y = {}
y['exp'] = [12.3]     # experimental
y['dft'] = [8.2251]   # DFT

# colors of the plot
c = {}
c['exp'] = 'black'
c['dft'] = 'red'

# plot
x = list(range(1, len(y)+1))
labels = y.keys()

fig, ax = plt.subplots(1, 1)
for counter, label in enumerate(labels) :
    for a in y[label] :
        ax.hlines(a, x[counter]-0.25, x[counter]+0.25, color=c[label])

plt.xticks(x, labels)
plt.ylabel('Energy (eV)')
plt.title('VIP')

plt.show()
../../_images/tutorials_MICCoM_School_2022_miccom_001_12_0.png

Question: Is this level of agreement ok?

1.2 : Full-frequency G0W0 calculation

The GW method in the framework of many-body perturbation theory (MBPT) can improve the result of DFT by computing single-particle excitations as the eigenvalues of the quasiparticle (QP) Hamiltonian:

\begin{equation} H^{\text{QP}}[\rho] = T + V_{\text{ion}} + V_{\text{Hartree}}[\rho] + \Sigma \end{equation}

Note that \(H^{\text{QP}}\) can be obtained from \(H^{\text{KS}}\) by replacing the exchange and correlation potential with the self-energy \(\Sigma\). In the GW approximation the electron self-energy can be written as :

\begin{equation} \Sigma(\mathbf{r},\mathbf{r^\prime};E) = i \int \frac{d\omega}{2\pi} G(\mathbf{r},\mathbf{r^\prime};E-\omega) W(\mathbf{r},\mathbf{r^\prime};\omega) \end{equation}

\(G\) is the Green’s function and \(W=\epsilon^{-1}v\) is the screened Coulomb potential. Because both \(G\) and \(W\) depend self-consistently on the solution of the QP Hamiltonian, typically the eigenvalues of the operator of \(H^{\text{QP}}\) are obtained using the eigenvalues and eigenvectors of \(H^{\text{KS}}\) (computed previously in DFT) and using first order perturbation theory:

\begin{equation} E^{\text{QP}}_n = \varepsilon^{\text{KS}}_n + \left\langle \psi_n \right | \Sigma(E^{\text{QP}}_n) - V_{\text{xc}}\left| \psi_n \right\rangle \end{equation}

Following the workflow discussed in J. Chem. Theory Comput. 11, 2680 (2015), we use the DFT output to:

  • Compute the dielectric screening : executable wstat.x

  • Compute the quasiparticle energies : executable wfreq.x

90ef9e7d693341cb9759df761f5b4ecd

1.2.1 : Calculation of dielectric screening

The wstat executable will read the output of DFT and will compute the static dielectric screening adopting the projective dielectric eigendecomposition (PDEP) technique. An iterative diagonalization of the dielectric matrix is performed:

\begin{equation} \epsilon_{\mathbf{G},\mathbf{G^\prime}}(\omega=0) = \sum_{i=1}^{\texttt{n_pdep_eigen}} \, \phi_i(\mathbf{G}) \, \lambda_i \phi^\ast_i(\mathbf{G^\prime}) \end{equation}

where \(\phi_i\) and \(\lambda_i\) are the eigenvectors and eigenvalues of the dielectric matrix (extressed here in terms of plane-waves). The eigenvectors \(\phi_i\) are used as the basis set for the subsequent GW calculation.

The diagonalization is started with random potentials and then iterated using the Davidson algorithm:

6dd9b69cf8ae4b34ae5c2f8bd8e37044

Let’s download and give a quick look at the input for wstat.x (description of the input variables for wstat.x can be found here: https://west-code.org/doc/West/latest/manual.html#wstat-control).

[6]:
!wget -N -q https://west-code.org/doc/training/silane/wstat.in
!cat wstat.in
input_west:
    qe_prefix: silane
    west_prefix: silane
    outdir: ./

wstat_control:
    wstat_calculation: S
    n_pdep_eigen: 50

The variable silane instructs the code to find the output of DFT in the folder silane.save. We are computing 50 eigenpotentials \(\phi_i\), i.e., 50 eigenvectors of the static dielectric matrix. This step uses the occupied single-particle states and energies obtained in the DFT calculation. Unoccupied states are not needed.

We can run the PDEP calculation invoking the executable wstat.x on 16 cores. This calculation should finish in 1 minute.

[7]:
!mpirun -n 16 wstat.x -i wstat.in > wstat.out

We load the output (in JSON format) of the wstat.x calculation, which can be found in the silane.wstat.save folder.

[8]:
import json

# read data from JSON file
with open('silane.wstat.save/wstat.json', 'r') as file :
    data = json.load(file)

# print the data
print(json.dumps(data, indent=2))
{
  "runjob": {
    "startdate": "11Oct2022",
    "starttime": " 9:32:59",
    "completed": true,
    "endtime": " 9:33:15",
    "enddate": "11Oct2022"
  },
  "software": {
    "package": "WEST",
    "program": "WSTAT",
    "version": "5.2.0",
    "westgit": "v5.2.0-10-g918d532",
    "website": "https://west-code.org",
    "citation": "M. Govoni et al., J. Chem. Theory Comput. 11, 2680 (2015).",
    "qeversion": "7.1"
  },
  "config": {
    "io": {
      "islittleendian": true
    }
  },
  "parallel": {
    "nranks": 16,
    "nimage": 1,
    "npool": 1,
    "nbgrp": 1,
    "nrg": 16,
    "nproc": 16,
    "nthreads": 1
  },
  "input": {
    "input_west": {
      "qe_prefix": "silane",
      "west_prefix": "silane",
      "outdir": "./"
    },
    "wstat_control": {
      "wstat_calculation": "S",
      "n_pdep_eigen": 50,
      "n_pdep_times": 4,
      "n_pdep_maxiter": 100,
      "n_dfpt_maxiter": 250,
      "n_pdep_read_from_file": 0,
      "n_steps_write_restart": 1,
      "trev_pdep": 0.001,
      "trev_pdep_rel": 0.1,
      "tr2_dfpt": 1e-12,
      "l_kinetic_only": false,
      "l_minimize_exx_if_active": false,
      "l_use_ecutrho": false,
      "qlist": [
        1
      ]
    },
    "server_control": {
      "document": "{}"
    }
  },
  "system": {
    "basis": {
      "npw": {
        "proc": [
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0
        ],
        "min": 0,
        "max": 0,
        "sum": 0
      },
      "ngm": {
        "proc": [
          4220,
          4221,
          4219,
          4221,
          4221,
          4221,
          4220,
          4221,
          4221,
          4220,
          4219,
          4219,
          4219,
          4220,
          4220,
          4220
        ],
        "min": 4219,
        "max": 4221,
        "sum": 67522
      },
      "gamma_only": true,
      "ecutwfc:ry": 25.0,
      "ecutrho:ry": 100.0
    },
    "cell": {
      "units": "a.u.",
      "omega": 8000.0,
      "a1": [
        20.0,
        0.0,
        0.0
      ],
      "a2": [
        0.0,
        20.0,
        0.0
      ],
      "a3": [
        0.0,
        0.0,
        20.0
      ],
      "b1": [
        0.3141592653589793,
        0.0,
        0.0
      ],
      "b2": [
        0.0,
        0.3141592653589793,
        0.0
      ],
      "b3": [
        0.0,
        0.0,
        0.3141592653589793
      ],
      "alat": 20.0,
      "tpiba": 0.3141592653589793
    },
    "electron": {
      "nbnd": 10,
      "nkstot": 1,
      "nspin": 1,
      "nelec": 8.0,
      "npol": 1,
      "lsda": false,
      "noncolin": false,
      "lspinorb": false
    },
    "3dfft": {
      "s": [
        64,
        64,
        64
      ],
      "p": [
        64,
        64,
        64
      ]
    },
    "bzsamp": {
      "k": [
        {
          "id": 1,
          "crystcoord": [
            0.0,
            0.0,
            0.0
          ]
        }
      ]
    }
  },
  "memory": {
    "units": "Mb",
    "evc": 0.08026123046875,
    "nlpp": 0.12841796875,
    "rhor": 0.25,
    "rhog": 0.032196044921875,
    "gshells": 0.005401611328125,
    "dvg": 1.605224609375,
    "dng": 1.605224609375,
    "hr_distr": 0.30517578125,
    "vr_distr": 0.30517578125,
    "dvpsi": 0.0321044921875,
    "dpsi": 0.0321044921875
  },
  "exec": {
    "ndav": 4,
    "davitr": [
      {
        "dav_iter": -1,
        "ev": [
          -1.2605591279261816,
          -1.1812479933930013,
          -1.176354788237097,
          -1.1712738214218055,
          -0.8162645071961094,
          -0.8100056551237361,
          -0.8037713586928801,
          -0.6207256375128,
          -0.6139258457189167,
          -0.4504239969889595,
          -0.44258236373617965,
          -0.42285739065633154,
          -0.4161871352235839,
          -0.4086761256499228,
          -0.391144269933381,
          -0.35154650952224475,
          -0.22034435672551075,
          -0.21296061444937364,
          -0.2042616451193836,
          -0.1661200380207801,
          -0.15969273612456536,
          -0.1553415063345141,
          -0.15237493663785076,
          -0.14389848531187638,
          -0.1365968664788392,
          -0.12511600591857588,
          -0.11539384948929213,
          -0.10459429582946164,
          -0.10042992216715237,
          -0.09870244795049053,
          -0.0933238874905026,
          -0.09167788000062861,
          -0.08518312554603533,
          -0.07958471780926124,
          -0.0776708939312429,
          -0.07307036957745469,
          -0.06891873838631551,
          -0.060148023225904235,
          -0.05778630984761288,
          -0.05592401268009498,
          -0.05092294690647727,
          -0.04951946848860927,
          -0.0476517799892079,
          -0.04435874746873535,
          -0.04317218464886519,
          -0.040665473458473905,
          -0.03778191195635325,
          -0.03576602983411223,
          -0.033769213117953605,
          -0.015542819711099503
        ],
        "conv": [
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false
        ],
        "notcnv": 50,
        "time_elap:sec": 3.51153302192688,
        "time_elap:hum": "03.5s",
        "time_iter:sec": 3.5115301609039307,
        "time_iter:hum": "03.5s",
        "sternop_ncalls": 1011,
        "dfpt_tr2": 1e-06,
        "dfpt_dim": 50,
        "diago_dim": 50
      },
      {
        "dav_iter": 1,
        "ev": [
          -1.2754684424024114,
          -1.191995341184158,
          -1.19198786300694,
          -1.1918721110320232,
          -0.82442753885941,
          -0.8243639321874088,
          -0.8242997840716799,
          -0.6361356957558751,
          -0.6296568274548767,
          -0.6296413545568273,
          -0.5006636696332897,
          -0.5005795189579708,
          -0.500474475279866,
          -0.43005011856959735,
          -0.4300320948062763,
          -0.4299825294011507,
          -0.23235168084292807,
          -0.2322517154513132,
          -0.23209974647635992,
          -0.1829326559805843,
          -0.1827335781160475,
          -0.18229299877133223,
          -0.17784527910811446,
          -0.17672947835944156,
          -0.17667590632711627,
          -0.14560918460051153,
          -0.14528730945197754,
          -0.14486852686919827,
          -0.12075118485366688,
          -0.11910453951818724,
          -0.1187348760281049,
          -0.11809073390359559,
          -0.11578278244178404,
          -0.1151722894313686,
          -0.11430674937951284,
          -0.11350388815667996,
          -0.11006967778786642,
          -0.09208669672138343,
          -0.09144853305507969,
          -0.0897120173120519,
          -0.07827072092186087,
          -0.07558536284116134,
          -0.07372706056817617,
          -0.07142441109651232,
          -0.06943098454262646,
          -0.06809364629565738,
          -0.06268888490486112,
          -0.062021508729807016,
          -0.06072976596578535,
          -0.060135374072292344
        ],
        "conv": [
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false
        ],
        "notcnv": 50,
        "time_elap:sec": 7.870642900466919,
        "time_elap:hum": "07.8s",
        "time_iter:sec": 4.215182065963745,
        "time_iter:hum": "04.2s",
        "sternop_ncalls": 1724,
        "dfpt_tr2": 1e-12,
        "dfpt_dim": 50,
        "diago_dim": 100
      },
      {
        "dav_iter": 2,
        "ev": [
          -1.2754720666724284,
          -1.191998889630293,
          -1.1919914251534018,
          -1.1918750476969548,
          -0.8244331949249563,
          -0.824371989387179,
          -0.824307057750549,
          -0.6363480461593288,
          -0.629663885414068,
          -0.6296546797640005,
          -0.5007531759617246,
          -0.5007191828843528,
          -0.5006632705684765,
          -0.4301010435507772,
          -0.43008785306001956,
          -0.4300639248433781,
          -0.23245848670842764,
          -0.232454446880072,
          -0.23244933014889632,
          -0.18328587917955322,
          -0.1832547553729702,
          -0.18324633004836113,
          -0.17843114260158843,
          -0.17754830176814526,
          -0.17754103307355587,
          -0.14595932159715894,
          -0.145955923078163,
          -0.1459411471756543,
          -0.1226019592550607,
          -0.12013930359811296,
          -0.12013399805600997,
          -0.12012057383845803,
          -0.11636716556326777,
          -0.11636290017226038,
          -0.11529987441574399,
          -0.11529799856558509,
          -0.11525428280816115,
          -0.09406113606695948,
          -0.09404985091462528,
          -0.09401167062537157,
          -0.07992389685332407,
          -0.07987094865761875,
          -0.07975914970189521,
          -0.07468254818337605,
          -0.07301849155829937,
          -0.07296297688645226,
          -0.06562513611180669,
          -0.06555066994951836,
          -0.06528330422704633,
          -0.06306269344176937
        ],
        "conv": [
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          false,
          false,
          false,
          false,
          false,
          true,
          false,
          true,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false,
          false
        ],
        "notcnv": 21,
        "time_elap:sec": 12.536376953125,
        "time_elap:hum": "12.5s",
        "time_iter:sec": 4.1379029750823975,
        "time_iter:hum": "04.1s",
        "sternop_ncalls": 1692,
        "dfpt_tr2": 1e-12,
        "dfpt_dim": 50,
        "diago_dim": 150
      },
      {
        "dav_iter": 3,
        "ev": [
          -1.2754720668029091,
          -1.1919988897734295,
          -1.191991425327886,
          -1.1918750479082716,
          -0.8244331954209921,
          -0.8243719902168194,
          -0.8243070584764758,
          -0.6363480751501617,
          -0.6296638864684181,
          -0.62965468160695,
          -0.5007531991331637,
          -0.5007192212407726,
          -0.5006633284291045,
          -0.4301010610680996,
          -0.4300878999594423,
          -0.43006394104361023,
          -0.2324590857953143,
          -0.23245478344153164,
          -0.2324498222228378,
          -0.18328843644430254,
          -0.18325666138108107,
          -0.1832473382383492,
          -0.1784332377577128,
          -0.1775504004743457,
          -0.17754325566955023,
          -0.14596095608969584,
          -0.14595895912881743,
          -0.1459466107908167,
          -0.12261797473339454,
          -0.12014634880115369,
          -0.12014593756057011,
          -0.12014040871072855,
          -0.11637378892529171,
          -0.11636989698973867,
          -0.11531375801416825,
          -0.11530875850124506,
          -0.11530541512826781,
          -0.09409890231649157,
          -0.09409787245061647,
          -0.0940955088831779,
          -0.07996894456596207,
          -0.07996593163736887,
          -0.07996545801532576,
          -0.07480835355986729,
          -0.07311589574225359,
          -0.07311484170817655,
          -0.06579115177015801,
          -0.06578527255722108,
          -0.06578041128186739,
          -0.06314475074029666
        ],
        "conv": [
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true,
          true
        ],
        "notcnv": 0,
        "time_elap:sec": 14.89906096458435,
        "time_elap:hum": "14.8s",
        "time_iter:sec": 1.7204980850219727,
        "time_iter:hum": "01.7s",
        "sternop_ncalls": 708,
        "dfpt_tr2": 1e-12,
        "dfpt_dim": 21,
        "diago_dim": 171
      }
    ]
  },
  "timing": {
    "WSTAT": {
      "cpu:sec": 13.765601,
      "cpu:hum": "13.7s",
      "wall:sec": 16.18815803527832,
      "wall:hum": "16.1s",
      "nocalls": 2
    },
    "wstat_readin": {
      "cpu:sec": 0.4568550000000001,
      "cpu:hum": "00.4s",
      "wall:sec": 0.5870640277862549,
      "wall:hum": "00.5s",
      "nocalls": 1
    },
    "fetch_input": {
      "cpu:sec": 0.029162000000000132,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.0364842414855957,
      "wall:hum": "< 00.1s",
      "nocalls": 2
    },
    "fft": {
      "cpu:sec": 0.05137000000000036,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.09902167320251465,
      "wall:hum": "< 00.1s",
      "nocalls": 9
    },
    "fft_scatter": {
      "cpu:sec": 3.6312919999999504,
      "cpu:hum": "03.6s",
      "wall:sec": 3.8297791481018066,
      "wall:hum": "03.8s",
      "nocalls": 20889
    },
    "init_vloc": {
      "cpu:sec": 0.05437700000000012,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.05521893501281738,
      "wall:hum": "< 00.1s",
      "nocalls": 2
    },
    "init_us_1": {
      "cpu:sec": 0.009448999999999819,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.013067007064819336,
      "wall:hum": "< 00.1s",
      "nocalls": 2
    },
    "v_of_rho": {
      "cpu:sec": 0.020774999999999988,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.032330989837646484,
      "wall:hum": "< 00.1s",
      "nocalls": 1
    },
    "v_xc": {
      "cpu:sec": 0.018656999999999924,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.027471065521240234,
      "wall:hum": "< 00.1s",
      "nocalls": 1
    },
    "v_h": {
      "cpu:sec": 0.0016580000000001593,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.002373933792114258,
      "wall:hum": "< 00.1s",
      "nocalls": 1
    },
    "do_setup": {
      "cpu:sec": 0.05048600000000003,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.0683588981628418,
      "wall:hum": "< 00.1s",
      "nocalls": 1
    },
    "init_pw_ar": {
      "cpu:sec": 0.04259199999999996,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.05210399627685547,
      "wall:hum": "< 00.1s",
      "nocalls": 1
    },
    "hinit0": {
      "cpu:sec": 0.033872000000000124,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.034713029861450195,
      "wall:hum": "< 00.1s",
      "nocalls": 1
    },
    "chidiago": {
      "cpu:sec": 13.244492,
      "cpu:hum": "13.2s",
      "wall:sec": 15.499743938446045,
      "wall:hum": "15.4s",
      "nocalls": 1
    },
    "sqvc_init": {
      "cpu:sec": 0.016258000000000106,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.016334056854248047,
      "wall:hum": "< 00.1s",
      "nocalls": 1
    },
    "randomize": {
      "cpu:sec": 0.2202679999999999,
      "cpu:hum": "00.2s",
      "wall:sec": 0.22018694877624512,
      "wall:hum": "00.2s",
      "nocalls": 1
    },
    "paramgs": {
      "cpu:sec": 0.059492000000000544,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.06182503700256348,
      "wall:hum": "< 00.1s",
      "nocalls": 5
    },
    "dfpt": {
      "cpu:sec": 12.170046,
      "cpu:hum": "12.1s",
      "wall:sec": 12.78049111366272,
      "wall:hum": "12.7s",
      "nocalls": 5
    },
    "init_us_2": {
      "cpu:sec": 0.0030950000000018463,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.004007816314697266,
      "wall:hum": "< 00.1s",
      "nocalls": 5
    },
    "init_us_2:cp": {
      "cpu:sec": 0.003003000000001421,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.003938198089599609,
      "wall:hum": "< 00.1s",
      "nocalls": 5
    },
    "fftw": {
      "cpu:sec": 7.157574000000035,
      "cpu:hum": "07.1s",
      "wall:sec": 7.495359897613525,
      "wall:hum": "07.4s",
      "nocalls": 20880
    },
    "alphapc": {
      "cpu:sec": 0.04244199999999232,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.04595136642456055,
      "wall:hum": "< 00.1s",
      "nocalls": 221
    },
    "wstat_restar": {
      "cpu:sec": 0.5095869999999998,
      "cpu:hum": "00.5s",
      "wall:sec": 1.5846247673034668,
      "wall:hum": "01.5s",
      "nocalls": 4
    },
    "pdep_write": {
      "cpu:sec": 0.48690699999999687,
      "cpu:hum": "00.4s",
      "wall:sec": 1.6841545104980469,
      "wall:hum": "01.6s",
      "nocalls": 750
    },
    "linstern": {
      "cpu:sec": 11.062415000000001,
      "cpu:hum": "11.0s",
      "wall:sec": 11.60523533821106,
      "wall:hum": "11.6s",
      "nocalls": 171
    },
    "stern": {
      "cpu:sec": 9.671373999999979,
      "cpu:hum": "09.6s",
      "wall:sec": 10.131323099136353,
      "wall:hum": "10.1s",
      "nocalls": 5135
    },
    "h_psi": {
      "cpu:sec": 9.006320000000056,
      "cpu:hum": "09.0s",
      "wall:sec": 9.43653130531311,
      "wall:hum": "09.4s",
      "nocalls": 5135
    },
    "h_psi:pot": {
      "cpu:sec": 8.84657099999999,
      "cpu:hum": "08.8s",
      "wall:sec": 9.262455224990845,
      "wall:hum": "09.2s",
      "nocalls": 5135
    },
    "vloc_psi": {
      "cpu:sec": 7.466788999999979,
      "cpu:hum": "07.4s",
      "wall:sec": 7.8167266845703125,
      "wall:hum": "07.8s",
      "nocalls": 5135
    },
    "h_psi:calbec": {
      "cpu:sec": 0.8840789999999679,
      "cpu:hum": "00.8s",
      "wall:sec": 0.9279425144195557,
      "wall:hum": "00.9s",
      "nocalls": 5135
    },
    "calbec": {
      "cpu:sec": 0.8083199999999717,
      "cpu:hum": "00.8s",
      "wall:sec": 0.8619239330291748,
      "wall:hum": "00.8s",
      "nocalls": 5135
    },
    "add_vuspsi": {
      "cpu:sec": 0.36807999999999197,
      "cpu:hum": "00.3s",
      "wall:sec": 0.3934800624847412,
      "wall:hum": "00.3s",
      "nocalls": 5135
    },
    "alphapv": {
      "cpu:sec": 0.5223740000000312,
      "cpu:hum": "00.5s",
      "wall:sec": 0.5605552196502686,
      "wall:hum": "00.5s",
      "nocalls": 5135
    },
    "build_hr": {
      "cpu:sec": 0.015184000000001419,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.015445947647094727,
      "wall:hum": "< 00.1s",
      "nocalls": 4
    },
    "diagox": {
      "cpu:sec": 0.03941000000000017,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.05038881301879883,
      "wall:hum": "< 00.1s",
      "nocalls": 4
    },
    "redistr_vr": {
      "cpu:sec": 0.0027069999999991268,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.0043947696685791016,
      "wall:hum": "< 00.1s",
      "nocalls": 3
    },
    "update_vr": {
      "cpu:sec": 0.029883000000001658,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.032776832580566406,
      "wall:hum": "< 00.1s",
      "nocalls": 3
    },
    "chidiago:las": {
      "cpu:sec": 1.000000000139778e-05,
      "cpu:hum": "< 00.1s",
      "wall:sec": 7.152557373046875e-06,
      "wall:hum": "< 00.1s",
      "nocalls": 1
    },
    "refresh_vr": {
      "cpu:sec": 0.008898999999999546,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.00884103775024414,
      "wall:hum": "< 00.1s",
      "nocalls": 1
    },
    "pdep_db": {
      "cpu:sec": 0.033900999999998405,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.22748708724975586,
      "wall:hum": "00.2s",
      "nocalls": 1
    }
  }
}

Now we can plot the 50 eigenvalues \(\lambda_i\) of the dielectric matrix.

[9]:
import numpy as np
import matplotlib.pyplot as plt

# y : eigenvalues of the dielectic matrix
y = data['exec']['davitr'][-1]['ev']
# x : index of eigenvalue
x = np.arange(1, len(y)+1, 1)

print('y : ', y)
print('x : ', x)

# plot
fig, ax = plt.subplots(1, 1)
ax.plot(x, y, 'ro-')

plt.xlabel('i')
plt.ylabel('Eigenvalue')
plt.title('PDEP')

plt.show()
y :  [-1.2754720668029091, -1.1919988897734295, -1.191991425327886, -1.1918750479082716, -0.8244331954209921, -0.8243719902168194, -0.8243070584764758, -0.6363480751501617, -0.6296638864684181, -0.62965468160695, -0.5007531991331637, -0.5007192212407726, -0.5006633284291045, -0.4301010610680996, -0.4300878999594423, -0.43006394104361023, -0.2324590857953143, -0.23245478344153164, -0.2324498222228378, -0.18328843644430254, -0.18325666138108107, -0.1832473382383492, -0.1784332377577128, -0.1775504004743457, -0.17754325566955023, -0.14596095608969584, -0.14595895912881743, -0.1459466107908167, -0.12261797473339454, -0.12014634880115369, -0.12014593756057011, -0.12014040871072855, -0.11637378892529171, -0.11636989698973867, -0.11531375801416825, -0.11530875850124506, -0.11530541512826781, -0.09409890231649157, -0.09409787245061647, -0.0940955088831779, -0.07996894456596207, -0.07996593163736887, -0.07996545801532576, -0.07480835355986729, -0.07311589574225359, -0.07311484170817655, -0.06579115177015801, -0.06578527255722108, -0.06578041128186739, -0.06314475074029666]
x :  [ 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
 49 50]
../../_images/tutorials_MICCoM_School_2022_miccom_001_24_1.png

As we can see, the eigenvalues of the dielectric matrix decay to zero. The number of PDEPs, n_pdep_eigen, controls the size of the basis set used in the GW calculation. n_pdep_eigen is a parameter of the simulation that needs to be converged. Typically, n_pdep_eigen is set to multiple of the number of electrons in the system.

Question: How do we compute 70 eigenpotentials?

1.2.2 : Calculation of GW electronic structure

The GW electronic structure is computed by computing the dielectric screening at multipole frequencies with Lanczos iterations and by treating the frequency integration of the correlation part of the self energy with the contour deformation techinique.

Let’s download and give a quick look at the input for wfreq.x (description of the input variables for wfreq.x can be found here: https://west-code.org/doc/West/latest/manual.html#wfreq-control).

[10]:
!wget -N -q https://west-code.org/doc/training/silane/wfreq.in
!cat wfreq.in
input_west:
    qe_prefix: silane
    west_prefix: silane
    outdir: ./

wstat_control:
    wstat_calculation: S
    n_pdep_eigen: 50

wfreq_control:
    wfreq_calculation: XWGQ
    n_pdep_eigen_to_use: 50
    qp_bandrange: [1,5]
    n_refreq: 300
    ecut_refreq: 2.0

The keyword XWGQ instructs the code to compute the exact exchange operator (X), the screened Coulomb operator (W), the Green’s function (G), and the quasiparticle energies (Q).

In this case we are using the 50 eigenpotentials \(\phi_i\) obtained by wstat.x.

We are going to compute the quasiparticle energies of the states 1, 2, 3, 4 (HOMO), and 5 (LUMO). Remember that in this example (spin-unpolarized) each state can host two electrons.

The frequency parameters control the contour deformation integration. The frequency dependence of the dielectric screening is sampled in the energy window \([0,2]\) Ry using 300 points.

We can run the GW calculation invoking the executable wfreq.x on 16 cores. This calculation should finish in 1 minute.

[11]:
!mpirun -n 16 wfreq.x -i wfreq.in > wfreq.out

We load the output (in JSON format) of the wfreq.x calculation, which can be found in the silane.wfreq.save folder.

[12]:
import json

# read data from JSON file
with open('silane.wfreq.save/wfreq.json', 'r') as file :
    data = json.load(file)

# print the data
print(json.dumps(data, indent=2))
{
  "runjob": {
    "startdate": "11Oct2022",
    "starttime": " 9:33:34",
    "completed": true,
    "endtime": " 9:33:43",
    "enddate": "11Oct2022"
  },
  "software": {
    "package": "WEST",
    "program": "WFREQ",
    "version": "5.2.0",
    "westgit": "v5.2.0-10-g918d532",
    "website": "https://west-code.org",
    "citation": "M. Govoni et al., J. Chem. Theory Comput. 11, 2680 (2015).",
    "qeversion": "7.1"
  },
  "config": {
    "io": {
      "islittleendian": true
    }
  },
  "parallel": {
    "nranks": 16,
    "nimage": 1,
    "npool": 1,
    "nbgrp": 1,
    "nrg": 16,
    "nproc": 16,
    "nthreads": 1
  },
  "input": {
    "input_west": {
      "qe_prefix": "silane",
      "west_prefix": "silane",
      "outdir": "./"
    },
    "wstat_control": {
      "wstat_calculation": "S",
      "n_pdep_eigen": 50,
      "n_pdep_times": 4,
      "n_pdep_maxiter": 100,
      "n_dfpt_maxiter": 250,
      "n_pdep_read_from_file": 0,
      "n_steps_write_restart": 1,
      "trev_pdep": 0.001,
      "trev_pdep_rel": 0.1,
      "tr2_dfpt": 1e-12,
      "l_kinetic_only": false,
      "l_minimize_exx_if_active": false,
      "l_use_ecutrho": false,
      "qlist": [
        1
      ]
    },
    "wfreq_control": {
      "wfreq_calculation": "XWGQ",
      "n_pdep_eigen_to_use": 50,
      "qp_bandrange": [
        1,
        5
      ],
      "qp_bands": [
        0
      ],
      "macropol_calculation": "N",
      "n_lanczos": 30,
      "n_imfreq": 128,
      "n_refreq": 300,
      "ecut_imfreq": 100.0,
      "ecut_refreq": 2.0,
      "wfreq_eta": 0.0036749308824745378,
      "n_secant_maxiter": 21,
      "trev_secant": 0.0036749308824745378,
      "l_enable_lanczos": true,
      "l_enable_off_diagonal": false,
      "o_restart_time": 0.0,
      "ecut_spectralf": [
        -2.0,
        1.0
      ],
      "n_spectralf": 204
    }
  },
  "system": {
    "basis": {
      "npw": {
        "proc": [
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          0
        ],
        "min": 0,
        "max": 0,
        "sum": 0
      },
      "ngm": {
        "proc": [
          4220,
          4221,
          4219,
          4221,
          4221,
          4221,
          4220,
          4221,
          4221,
          4220,
          4219,
          4219,
          4219,
          4220,
          4220,
          4220
        ],
        "min": 4219,
        "max": 4221,
        "sum": 67522
      },
      "gamma_only": true,
      "ecutwfc:ry": 25.0,
      "ecutrho:ry": 100.0
    },
    "cell": {
      "units": "a.u.",
      "omega": 8000.0,
      "a1": [
        20.0,
        0.0,
        0.0
      ],
      "a2": [
        0.0,
        20.0,
        0.0
      ],
      "a3": [
        0.0,
        0.0,
        20.0
      ],
      "b1": [
        0.3141592653589793,
        0.0,
        0.0
      ],
      "b2": [
        0.0,
        0.3141592653589793,
        0.0
      ],
      "b3": [
        0.0,
        0.0,
        0.3141592653589793
      ],
      "alat": 20.0,
      "tpiba": 0.3141592653589793
    },
    "electron": {
      "nbnd": 10,
      "nkstot": 1,
      "nspin": 1,
      "nelec": 8.0,
      "npol": 1,
      "lsda": false,
      "noncolin": false,
      "lspinorb": false
    },
    "3dfft": {
      "s": [
        64,
        64,
        64
      ],
      "p": [
        64,
        64,
        64
      ]
    },
    "bzsamp": {
      "k": [
        {
          "id": 1,
          "crystcoord": [
            0.0,
            0.0,
            0.0
          ]
        }
      ]
    }
  },
  "exec": {
    "Q": {
      "secitr": 3,
      "en": [
        {
          "ksb": [
            1,
            1,
            1
          ],
          "ein": [
            -13.230981270352434,
            -16.26615213933269,
            -16.103461398940283
          ],
          "eout": [
            -16.26615213933269,
            -16.103461398940283,
            -16.126442757174104
          ],
          "sc_ein": [
            [
              1.7659827273250182,
              0.014583989091543714
            ],
            [
              3.581007935231201,
              0.07514251063272293
            ],
            [
              3.4409541840918707,
              0.11069082478558719
            ]
          ]
        },
        {
          "ksb": [
            1,
            1,
            2
          ],
          "ein": [
            -8.226552436785038,
            -12.145989533047741,
            -12.038568029539881
          ],
          "eout": [
            -12.145989533047741,
            -12.038568029539881,
            -12.041375786118818
          ],
          "sc_ein": [
            [
              0.010466906176382348,
              0.003272239246325086
            ],
            [
              0.7305227660066568,
              0.00892881625011567
            ],
            [
              0.7073751375953274,
              0.008794218426373911
            ]
          ]
        },
        {
          "ksb": [
            1,
            1,
            3
          ],
          "ein": [
            -8.22537802992713,
            -12.141823660074568,
            -12.034279625593381
          ],
          "eout": [
            -12.141823660074568,
            -12.034279625593381,
            -12.037079367870797
          ],
          "sc_ein": [
            [
              0.013781153568594457,
              0.003272405433181099
            ],
            [
              0.7333805411639928,
              0.008931013424447288
            ],
            [
              0.710217882884513,
              0.008796293848555962
            ]
          ]
        },
        {
          "ksb": [
            1,
            1,
            4
          ],
          "ein": [
            -8.225073262212328,
            -12.141850045890173,
            -12.034301905490201
          ],
          "eout": [
            -12.141850045890173,
            -12.034301905490201,
            -12.037101945463592
          ],
          "sc_ein": [
            [
              0.013237978473109088,
              0.0032729463236466855
            ],
            [
              0.7329844903483206,
              0.008932371065598663
            ],
            [
              0.7098182772432421,
              0.00879763962964248
            ]
          ]
        },
        {
          "ksb": [
            1,
            1,
            5
          ],
          "ein": [
            -0.4646702125746965,
            0.664173458065683,
            0.663067500001202
          ],
          "eout": [
            0.664173458065683,
            0.663067500001202,
            0.663067500001202
          ],
          "sc_ein": [
            [
              -0.3481319149046877,
              -1.058286063240667e-05
            ],
            [
              -0.3718350341861773,
              -0.00011661816924339793
            ],
            [
              -0.37181078103599796,
              -0.00011661816924339793
            ]
          ]
        }
      ]
    }
  },
  "output": {
    "Q": {
      "bandmap": [
        1,
        2,
        3,
        4,
        5
      ],
      "indexmap": [
        [
          1,
          1
        ],
        [
          2,
          2
        ],
        [
          3,
          3
        ],
        [
          4,
          4
        ],
        [
          5,
          5
        ]
      ],
      "K000001": {
        "eks": [
          -13.230981270352434,
          -8.226552436785038,
          -8.22537802992713,
          -8.225073262212328,
          -0.4646702125746965
        ],
        "z": [
          0.6612260601413072,
          0.868604768882124,
          0.8686339641874008,
          0.868616662913504,
          0.9803946557176213
        ],
        "eqpLin": [
          -16.26615213933269,
          -12.145989533047741,
          -12.141823660074568,
          -12.141850045890173,
          0.664173458065683
        ],
        "eqpSec": [
          -16.126442757174104,
          -12.041375786118818,
          -12.037079367870797,
          -12.037101945463592,
          0.663067500001202
        ],
        "sigma_diff": [
          -0.022981358233819825,
          -0.002807756578937437,
          -0.0027997422774165845,
          -0.0028000399733918565,
          0.0
        ],
        "occupation": [
          2.0,
          2.0,
          2.0,
          2.0,
          0.0
        ],
        "sigmax": [
          -17.605224493338945,
          -15.765070382904447,
          -15.764310528252162,
          -15.76413620844094,
          -0.5854584095249137
        ],
        "vxcl": [
          -11.249025118576247,
          -11.242266869012985,
          -11.241788303510699,
          -11.241686110388825,
          -2.0850079337127707
        ],
        "vxcnl": [
          0.0,
          0.0,
          0.0,
          0.0,
          0.0
        ],
        "hf": [
          -6.3561993747626975,
          -4.5228035138914615,
          -4.522522224741464,
          -4.522450098052116,
          1.4995495241878571
        ],
        "sigmac_eks": {
          "re": [
            1.7659827273250182,
            0.010466906176382348,
            0.013781153568594457,
            0.013237978473109088,
            -0.3481319149046877
          ],
          "im": [
            0.014583989091543714,
            0.003272239246325086,
            0.003272405433181099,
            0.0032729463236466855,
            -1.058286063240667e-05
          ]
        },
        "sigmac_eqpLin": {
          "re": [
            3.581007935231201,
            0.7305227660066568,
            0.7333805411639928,
            0.7329844903483206,
            -0.3718350341861773
          ],
          "im": [
            0.07514251063272293,
            0.00892881625011567,
            0.008931013424447288,
            0.008932371065598663,
            -0.00011661816924339793
          ]
        },
        "sigmac_eqpSec": {
          "re": [
            3.4409541840918707,
            0.7073751375953274,
            0.710217882884513,
            0.7098182772432421,
            -0.37181078103599796
          ],
          "im": [
            0.11069082478558719,
            0.008794218426373911,
            0.008796293848555962,
            0.00879763962964248,
            -0.00011661816924339793
          ]
        }
      }
    }
  },
  "timing": {
    "WFREQ": {
      "cpu:sec": 8.173569,
      "cpu:hum": "08.1s",
      "wall:sec": 8.818508863449097,
      "wall:hum": "08.8s",
      "nocalls": 2
    },
    "wfreq_readin": {
      "cpu:sec": 0.4345310000000001,
      "cpu:hum": "00.4s",
      "wall:sec": 0.5477490425109863,
      "wall:hum": "00.5s",
      "nocalls": 1
    },
    "fetch_input": {
      "cpu:sec": 0.0393199999999998,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.05291390419006348,
      "wall:hum": "< 00.1s",
      "nocalls": 2
    },
    "fft": {
      "cpu:sec": 0.036698999999999815,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.08657431602478027,
      "wall:hum": "< 00.1s",
      "nocalls": 14
    },
    "fft_scatter": {
      "cpu:sec": 2.313853999999959,
      "cpu:hum": "02.3s",
      "wall:sec": 2.429741621017456,
      "wall:hum": "02.4s",
      "nocalls": 14473
    },
    "init_vloc": {
      "cpu:sec": 0.054491999999999985,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.05463600158691406,
      "wall:hum": "< 00.1s",
      "nocalls": 2
    },
    "init_us_1": {
      "cpu:sec": 0.00997300000000001,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.011365890502929688,
      "wall:hum": "< 00.1s",
      "nocalls": 2
    },
    "v_of_rho": {
      "cpu:sec": 0.022467999999999932,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.02729201316833496,
      "wall:hum": "< 00.1s",
      "nocalls": 1
    },
    "v_xc": {
      "cpu:sec": 0.0381419999999999,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.04444599151611328,
      "wall:hum": "< 00.1s",
      "nocalls": 2
    },
    "v_h": {
      "cpu:sec": 0.0015659999999999563,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.0016570091247558594,
      "wall:hum": "< 00.1s",
      "nocalls": 1
    },
    "do_setup": {
      "cpu:sec": 0.048203999999999914,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.0633389949798584,
      "wall:hum": "< 00.1s",
      "nocalls": 1
    },
    "init_pw_ar": {
      "cpu:sec": 0.040395999999999876,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.0461888313293457,
      "wall:hum": "< 00.1s",
      "nocalls": 1
    },
    "hinit0": {
      "cpu:sec": 0.033833,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.03384113311767578,
      "wall:hum": "< 00.1s",
      "nocalls": 1
    },
    "solve_hf": {
      "cpu:sec": 0.06213999999999986,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.07319092750549316,
      "wall:hum": "< 00.1s",
      "nocalls": 1
    },
    "sigmavxc": {
      "cpu:sec": 0.0049640000000001905,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.006000041961669922,
      "wall:hum": "< 00.1s",
      "nocalls": 1
    },
    "init_us_2": {
      "cpu:sec": 0.0016629999999988598,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.0018558502197265625,
      "wall:hum": "< 00.1s",
      "nocalls": 3
    },
    "init_us_2:cp": {
      "cpu:sec": 0.001620000000000843,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.0018200874328613281,
      "wall:hum": "< 00.1s",
      "nocalls": 3
    },
    "fftw": {
      "cpu:sec": 4.50848900000002,
      "cpu:hum": "04.5s",
      "wall:sec": 4.702910661697388,
      "wall:hum": "04.7s",
      "nocalls": 14439
    },
    "sigmax": {
      "cpu:sec": 0.03873700000000002,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.041181087493896484,
      "wall:hum": "< 00.1s",
      "nocalls": 1
    },
    "sqvc_init": {
      "cpu:sec": 0.03898700000000055,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.039562225341796875,
      "wall:hum": "< 00.1s",
      "nocalls": 7
    },
    "ffts": {
      "cpu:sec": 0.014574000000000087,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.01490020751953125,
      "wall:hum": "< 00.1s",
      "nocalls": 20
    },
    "write_hf": {
      "cpu:sec": 0.0,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.0015702247619628906,
      "wall:hum": "< 00.1s",
      "nocalls": 1
    },
    "wlanczos": {
      "cpu:sec": 3.395701,
      "cpu:hum": "03.3s",
      "wall:sec": 3.589892864227295,
      "wall:hum": "03.5s",
      "nocalls": 1
    },
    "pdep_read": {
      "cpu:sec": 0.06580900000000334,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.08992171287536621,
      "wall:hum": "< 00.1s",
      "nocalls": 100
    },
    "alphapc": {
      "cpu:sec": 0.19857400000001313,
      "cpu:hum": "00.1s",
      "wall:sec": 0.20917320251464844,
      "wall:hum": "00.2s",
      "nocalls": 283
    },
    "lan_H": {
      "cpu:sec": 6.412891999999999,
      "cpu:hum": "06.4s",
      "wall:sec": 6.658470630645752,
      "wall:hum": "06.6s",
      "nocalls": 9
    },
    "h_psi": {
      "cpu:sec": 5.180463000000021,
      "cpu:hum": "05.1s",
      "wall:sec": 5.406877517700195,
      "wall:hum": "05.4s",
      "nocalls": 270
    },
    "h_psi:pot": {
      "cpu:sec": 5.140214000000003,
      "cpu:hum": "05.1s",
      "wall:sec": 5.367469787597656,
      "wall:hum": "05.3s",
      "nocalls": 270
    },
    "vloc_psi": {
      "cpu:sec": 4.892422000000003,
      "cpu:hum": "04.8s",
      "wall:sec": 5.10514497756958,
      "wall:hum": "05.1s",
      "nocalls": 270
    },
    "h_psi:calbec": {
      "cpu:sec": 0.1674900000000079,
      "cpu:hum": "00.1s",
      "wall:sec": 0.1779468059539795,
      "wall:hum": "00.1s",
      "nocalls": 270
    },
    "calbec": {
      "cpu:sec": 0.16089799999999777,
      "cpu:hum": "00.1s",
      "wall:sec": 0.17319059371948242,
      "wall:hum": "00.1s",
      "nocalls": 270
    },
    "add_vuspsi": {
      "cpu:sec": 0.0712160000000015,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.07684707641601562,
      "wall:hum": "< 00.1s",
      "nocalls": 270
    },
    "brak": {
      "cpu:sec": 0.09926699999999933,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.10172724723815918,
      "wall:hum": "00.1s",
      "nocalls": 9
    },
    "sw_restart": {
      "cpu:sec": 0.1092929999999992,
      "cpu:hum": "00.1s",
      "wall:sec": 0.17614316940307617,
      "wall:hum": "00.1s",
      "nocalls": 4
    },
    "chi_invert": {
      "cpu:sec": 0.01360599999999934,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.017594099044799805,
      "wall:hum": "< 00.1s",
      "nocalls": 1
    },
    "glanczos": {
      "cpu:sec": 4.018922,
      "cpu:hum": "04.0s",
      "wall:sec": 4.241312026977539,
      "wall:hum": "04.2s",
      "nocalls": 1
    },
    "write_over": {
      "cpu:sec": 0.001440000000000552,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.011359930038452148,
      "wall:hum": "< 00.1s",
      "nocalls": 5
    },
    "write_gfreq": {
      "cpu:sec": 0.003713999999998663,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.029255390167236328,
      "wall:hum": "< 00.1s",
      "nocalls": 5
    },
    "sg_restart": {
      "cpu:sec": 0.003068000000000737,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.01123499870300293,
      "wall:hum": "< 00.1s",
      "nocalls": 5
    },
    "solve_qp": {
      "cpu:sec": 0.16948000000000008,
      "cpu:hum": "00.1s",
      "wall:sec": 0.24360990524291992,
      "wall:hum": "00.2s",
      "nocalls": 1
    },
    "coll_gw": {
      "cpu:sec": 0.020823000000000036,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.03419899940490723,
      "wall:hum": "< 00.1s",
      "nocalls": 1
    },
    "read_over": {
      "cpu:sec": 0.0018779999999996022,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.0029571056365966797,
      "wall:hum": "< 00.1s",
      "nocalls": 5
    },
    "read_gfreq": {
      "cpu:sec": 0.003434999999999633,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.01312708854675293,
      "wall:hum": "< 00.1s",
      "nocalls": 5
    },
    "read_hf": {
      "cpu:sec": 0.00034199999999984243,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.00039505958557128906,
      "wall:hum": "< 00.1s",
      "nocalls": 1
    },
    "sigmac_i": {
      "cpu:sec": 0.020918999999997467,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.021049976348876953,
      "wall:hum": "< 00.1s",
      "nocalls": 4
    },
    "sigmac_r": {
      "cpu:sec": 0.0012529999999983943,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.0013022422790527344,
      "wall:hum": "< 00.1s",
      "nocalls": 4
    },
    "wfreq_db": {
      "cpu:sec": 0.0202650000000002,
      "cpu:hum": "< 00.1s",
      "wall:sec": 0.038127899169921875,
      "wall:hum": "< 00.1s",
      "nocalls": 1
    }
  }
}

We can print the quasiparticle energy levels using the WESTpy Python package, which offers useful pre- and post-processing tools for WEST calculations.

[13]:
from westpy import wfreq2df

df, data = wfreq2df('silane.wfreq.save/wfreq.json')
display(df)

 _    _ _____ _____ _____
| |  | |  ___/  ___|_   _|
| |  | | |__ \ `--.  | |_ __  _   _
| |/\| |  __| `--. \ | | '_ \| | | |
\  /\  / |___/\__/ / | | |_) | |_| |
 \/  \/\____/\____/  \_/ .__/ \__, |
                       | |     __/ |
                       |_|    |___/

WEST version     :  5.2.0
Today            :  2022-10-11 09:34:04.514495
k s n eks eqpLin eqpSec sigmax sigmac_eks sigmac_eqpLin sigmac_eqpSec vxcl vxcnl hf
0 1 1 1 -13.230981 -16.266152 -16.126443 -17.605224 1.765983 3.581008 3.440954 -11.249025 0.0 -6.356199
1 1 1 2 -8.226552 -12.145990 -12.041376 -15.765070 0.010467 0.730523 0.707375 -11.242267 0.0 -4.522804
2 1 1 3 -8.225378 -12.141824 -12.037079 -15.764311 0.013781 0.733381 0.710218 -11.241788 0.0 -4.522522
3 1 1 4 -8.225073 -12.141850 -12.037102 -15.764136 0.013238 0.732984 0.709818 -11.241686 0.0 -4.522450
4 1 1 5 -0.464670 0.664173 0.663068 -0.585458 -0.348132 -0.371835 -0.371811 -2.085008 0.0 1.499550

All energies in the table are given in eV. The full-frequency G\(_0\)W\(_0\) energies correspond to the eqpSec column.

Full explanation of the keys:

  • k : k-point index

  • s : spin index

  • n : state index

  • eks : Kohn-Sham energy \(\varepsilon^{\text{KS}}_n\), obtained in the DFT calculation

  • eqpLin : quasiparticle energy \(E^{\text{QP}}_n\), obtained by approximating the self-energy to first order in the frequency

  • eqpSec : quasiparticle energy \(E^{\text{QP}}_n\), obtained by using the secant method to solve the frequency-dependency in the quasiparticle equation

  • sigmax : exchange self-energy

  • sigmac_eks : correlation self-energy, evaluated at eks (re and im identify the real and imaginary parts respectively)

  • sigmac_eqpLin : correlation self-energy, evaluated at eqpLin

  • sigmac_eqpSec : correlation self-energy, evaluated at eqpSec

  • vxcl : contribution to the energy given by the semilocal exchange-correlation functional

  • vxcnl : contribution to the energy given by the excact exchange (when using hybrid functional)

  • hf : quasiparticle energy according to perturbative Hartree-Fock, i.e., no correlation self-energy

Let’s use WESTpy to plot the density of states (DOS), obtained as a sum of Gaussian functions

\begin{equation} \text{DOS}(E) = \sum_{i=1}^{N_{\text{states}}} \frac{1}{\sqrt{2\pi\sigma^2}} e^{-\frac{(E-E_i)^2}{2\sigma^2}} \end{equation}

We use \(\sigma\) = 0.2 eV.

[14]:
from westpy import ElectronicStructure

# extracting energy levels from the data
y = {}
y['dft'] = data['output']['Q']['K000001']['eks']
y['gw']  = data['output']['Q']['K000001']['eqpSec']

es = ElectronicStructure()

for key in ['dft','gw'] :
    es.addKey(key,key)
    for b, energy in enumerate(y[key]) :
        es.addDataPoint([1,1,b+1],key,y[key][b])

es.plotDOS(kk=[1],ss=[1],energyKeys=['dft','gw'],energyRange=[-18.,2.,0.01],fname='dos.png')
Requested (emin,emax) :  -18.0 2.0
Detected  (emin,emax) :  -16.126442757174104 0.663067500001202
output written in :  dos.png
waiting for user to close image preview...
../../_images/tutorials_MICCoM_School_2022_miccom_001_39_1.png

Now going back to the problem of computing the vertical ionization potential of SiH\(_4\), in the GW case we have:

\begin{equation} \text{VIP}^{\text{GW}} = 0 - E^{\text{QP}}_{\text{HOMO}} \end{equation}

The HOMO (n=4 in the table) predicted by GW is located at \(-12.037102\) eV. Let’s update the VIP plot to compare DFT and GW results.

[15]:
import matplotlib.pyplot as plt

# VIP
y = {}
y['exp'] = [12.3]      # experimental
y['dft'] = [8.2251]    # dft
y['gw']  = [12.037102] # gw

# colors
c = {}
c['exp'] = 'black'
c['dft'] = 'red'
c['gw']  = 'blue'

# plot
x = list(range(1, len(y)+1))
labels = y.keys()

fig, ax = plt.subplots(1, 1)
counter = 0
for counter, label in enumerate(labels) :
    for a in y[label] :
        ax.hlines(a, x[counter]-0.25, x[counter]+0.25, color=c[label])

plt.xticks(x, labels)
plt.ylabel('Energy (eV)')
plt.title('VIP')

plt.show()
../../_images/tutorials_MICCoM_School_2022_miccom_001_41_0.png

If we take into account finite size effects, we have:

\begin{equation} \text{VIP}^{\text{GW}} = E_{\text{vacuum}} - E^{\text{QP}}_{\text{HOMO}} \end{equation}

We extract the vacuum energy from the output of the DFT calculation.

[16]:
!grep 'Corrected vacuum level' pw.out
     Corrected vacuum level    =       0.24581357 eV

The vacuum energy is \(0.24581357\) eV. Let’s update the VIP plot again.

[17]:
import matplotlib.pyplot as plt

# vacumm
vacuum = 0.24581357

# VIP
y = {}
y['exp']     = [12.3]             # experimental
y['dft']     = [8.2251]           # dft
y['dft_vac'] = [8.2251+vacuum]    # dft
y['gw']      = [12.037102]        # gw
y['gw_vac']  = [12.037102+vacuum] # gw

# colors
c = {}
c['exp']     = 'black'
c['dft']     = 'red'
c['dft_vac'] = 'red'
c['gw']      = 'blue'
c['gw_vac']  = 'blue'

# plot
x = list(range(1, len(y)+1))
labels = y.keys()

fig, ax = plt.subplots(1, 1)
for counter, label in enumerate(labels) :
    for a in y[label] :
        ax.hlines(a, x[counter]-0.25, x[counter]+0.25, color=c[label])

plt.xticks(x, labels)
plt.ylabel('Energy (eV)')
plt.title('VIP')

plt.show()
../../_images/tutorials_MICCoM_School_2022_miccom_001_45_0.png

Question: Which level of theory better describes electronic excitations, DFT or GW?

Finally, we inspect the convergence of GW with respect to the size of the basis set used to represent the dielectric matrices. We have computed 50 eigenpotentials using wstat.x. We can now use fewer eigenpotentials in wfreq.x and test the convergece.

Let’s prepare the input for 5 calculations done with 10, 20, 30, 40, 50 eigenpotentials. This is achieved by setting the n_pdep_eigen_to_use keyword in the input file.

[18]:
import yaml

# create 5 files, each with a different value of the variable n_pdep_eigen_to_use
for npdep in [10, 20, 30, 40, 50] :

    # read data wfreq.in
    with open('wfreq.in', 'r') as file :
        input_data = yaml.load(file, Loader=yaml.FullLoader)

    # modify the input_data
    input_data['wfreq_control']['n_pdep_eigen_to_use'] = npdep

    # write data to YAML file
    with open(f'wfreq_{npdep}.in', 'w') as file :
        yaml.dump(input_data, file, sort_keys=False)
[19]:
# give a quick look
!cat wfreq_10.in
!cat wfreq_20.in
!cat wfreq_30.in
!cat wfreq_40.in
!cat wfreq_50.in
input_west:
  qe_prefix: silane
  west_prefix: silane
  outdir: ./
wstat_control:
  wstat_calculation: S
  n_pdep_eigen: 50
wfreq_control:
  wfreq_calculation: XWGQ
  n_pdep_eigen_to_use: 10
  qp_bandrange:
  - 1
  - 5
  n_refreq: 300
  ecut_refreq: 2.0
input_west:
  qe_prefix: silane
  west_prefix: silane
  outdir: ./
wstat_control:
  wstat_calculation: S
  n_pdep_eigen: 50
wfreq_control:
  wfreq_calculation: XWGQ
  n_pdep_eigen_to_use: 20
  qp_bandrange:
  - 1
  - 5
  n_refreq: 300
  ecut_refreq: 2.0
input_west:
  qe_prefix: silane
  west_prefix: silane
  outdir: ./
wstat_control:
  wstat_calculation: S
  n_pdep_eigen: 50
wfreq_control:
  wfreq_calculation: XWGQ
  n_pdep_eigen_to_use: 30
  qp_bandrange:
  - 1
  - 5
  n_refreq: 300
  ecut_refreq: 2.0
input_west:
  qe_prefix: silane
  west_prefix: silane
  outdir: ./
wstat_control:
  wstat_calculation: S
  n_pdep_eigen: 50
wfreq_control:
  wfreq_calculation: XWGQ
  n_pdep_eigen_to_use: 40
  qp_bandrange:
  - 1
  - 5
  n_refreq: 300
  ecut_refreq: 2.0
input_west:
  qe_prefix: silane
  west_prefix: silane
  outdir: ./
wstat_control:
  wstat_calculation: S
  n_pdep_eigen: 50
wfreq_control:
  wfreq_calculation: XWGQ
  n_pdep_eigen_to_use: 50
  qp_bandrange:
  - 1
  - 5
  n_refreq: 300
  ecut_refreq: 2.0

We run them all and stash the output files. These calculations should finish in 3 minutes.

[20]:
!rm -f silane.wfreq.save/*.json

!mpirun -n 16 wfreq.x -i wfreq_10.in > wfreq_10.out
!mv silane.wfreq.save/wfreq.json wfreq_10.json

!mpirun -n 16 wfreq.x -i wfreq_20.in > wfreq_20.out
!mv silane.wfreq.save/wfreq.json wfreq_20.json

!mpirun -n 16 wfreq.x -i wfreq_30.in > wfreq_30.out
!mv silane.wfreq.save/wfreq.json wfreq_30.json

!mpirun -n 16 wfreq.x -i wfreq_40.in > wfreq_40.out
!mv silane.wfreq.save/wfreq.json wfreq_40.json

!mpirun -n 16 wfreq.x -i wfreq_50.in > wfreq_50.out
!mv silane.wfreq.save/wfreq.json wfreq_50.json

We plot the quasiparticle energy levels as a function of n_pdep_eigen_to_use.

[21]:
import json
import matplotlib.pyplot as plt

# load data from wfreq_XX.json
data = {}
for npdep in [10, 20, 30, 40, 50] :
    with open(f'wfreq_{npdep}.json') as file :
        data[npdep] = json.load(file)

# energy levels
y = {}
for npdep in [10, 20, 30, 40, 50] :
    y[npdep] = data[npdep]['output']['Q']['K000001']['eqpSec']

# colors
c = {}
c[10] = 'red'
c[20] = 'blue'
c[30] = 'green'
c[40] = 'purple'
c[50] = 'black'

# plot
x = list(range(1, len(y)+1))
labels = y.keys()

fig, ax = plt.subplots(1, 1)
for counter, label in enumerate(labels) :
    for a in y[label] :
        ax.hlines(a, x[counter]-0.25, x[counter]+0.25, color=c[label])

plt.xticks(x, labels)
plt.ylabel('Energy (eV)')
plt.title('Energy structure')

plt.show()
../../_images/tutorials_MICCoM_School_2022_miccom_001_53_0.png

Question: How many PDEPs are needed to converge the quasiparticle energies?