AO to MO transformation

Modules: ao2mo

Overview

The ao2mo module exposes important functionality for transforming 2-electron integrals, i.e. the 4-index transformation from atomic orbitals (AOs) to molecular orbitals (MOs). The most important functions are kernel(), load, restore(). The function kernel() takes in a Mole object or the AO integrals stored in a numpy.ndarray and a set of MO coefficients. If erifile is specified, the integrals will be stored in a HDF5 file with the given name, otherwise the integrals are returned as a numpy array.

from pyscf import gto, scf, ao2mo
import tempfile
mol = gto.Mole()
mol.build(
    atom = 'H 0 0 0; F 0 0 1.1',  # in Angstrom
    basis = 'ccpvdz',
    symmetry = True,
)

mf = scf.RHF(mol)
mf.kernel()

orb = mf.mo_coeff
# get the two-electron integrals as a numpy array
eri = ao2mo.kernel(mol, orb)

ftmp = tempfile.NamedTemporaryFile()
# saves the two-electron integrals in the file ftmp.name
ao2mo.kernel(mol, orb, ftmp.name)

The kernel() function can also be invoked as the ao2mo() method of the Mole object

mol.ao2mo(orb)

The class load allows users to load two-electron integrals from a hdf5 file.

ftmp = tempfile.NamedTmpFile()
ao2mo.kernel(mol, orb, ftmp)
with ao2mo.load(ftmp) as eri:
    print(eri.shape)

The function restore() restores a set of integrals to the desired permutation symmetry.

import numpy
with ao2mo.load(ftmp) as eri:
    eri1 = ao2mo.restore(1, numpy.asarray(eri), orb.shape[1])
    eri4 = ao2mo.restore('4', numpy.asarray(eri), orb.shape[1)
    eri8 = ao2mo.restore('s8', numpy.asarray(eri), orb.shape[1])
    print(eri1.shape)
    print(eri4.shape)
    print(eri8.shape)

The kernel function

kernel(eri_or_mol, mo_coeffs, erifile=None, dataname='eri_mo', intor='int2e', *args, **kwargs)
Parameters:
  • eri_or_mol – This is either a four-dimensional array that stores the AO integrals explicitly or a Mole object. If it is an array, everything will be kept in memory, and an incore algorithm will be used. If it is a Mole object, AO integrals will be computed on the fly, and the outcore algorithm will be used.

  • mo_coeffs – This can be either a single set of MO coefficients in a numpy array, or a list of four sets of MO coefficients. Each of the four sets of MO coefficients correspond to an index in (ij|kl). If only one is provided, the four indices will correspond to the same MO coefficients.

  • erifile (str or h5py.Group object or h5py.File object) – This is the name of the HDF5 file to store the integrals in. If the eri_or_mol argument is a numpy array, kernel() will call the incore algorithm to perform the transformation, and this argument will not be used. If specified, the integrals will be stored in the HDF5 file or the related group. If not specified, PySCF will use an anonymous temp file and return a numpy.ndarray in the end.

  • dataname (str) – dataname labels the integrals stored in the erifile. The integrals can be reused by assigning different datanames. If the erifile already contains the given dataname, the old integrals will be overwritten.

  • intor (str) – the name of the integral you want to evaluate. More details can be found in gto.

  • comp (int) – the component of the integral to be evaluated. It is closely related to intor, more details can also be found in gto.

  • aosym (int or str) – It specifies to what level will the ao2mo() utilize symmetry in ao integrals. Supported symmetry labels are the same as those in restore(). For more details see Transform integrals between symmetries section below. Default aosym is ‘s4’.

  • compact (bool) – When this is True, the returned MO integrals have (up to 4-fold) permutation symmetry. When this is False, the function will abandon any permutation symmetry, and return the “plain” MO integrals without any permutation symmetry.

Load the integrals

Since integrals are stored in a HDF5 file when the outcore algorithm is used, Pyscf provides the load to help users access the integrals stored in the HDF5 file. It takes a flexible ranges of objects including a str which is the name of the HDF5 file, a h5py.File object, a h5py.Group object and a numpy array. The dataname can also be taken as a second argument. In this way, it helps users access integrals stored in memory and in a file on the same footing. The load class should only be used within a with statement.

eri = ao2mo.kernel(mol, orb)
print(type(eri))
with ao2mo.load(erifile) as eri:
    print(eri.shape)

ao2mo.kernel(mol, orb, erifile = 'hf.h5', dataname = 'test')
# load 2e integrals by filename and dataname
with ao2mo.load('hf.h5', 'test') as eri:
    print(eri.shape)

import numpy
erirand = numpy.random.random((5,5,5,5))
# load 2e integrals from numpy array
with ao2mo.load(erirand) as eri:
    print(eri.shape)

Transform integrals between symmetries

The function restore() can transform 2e integrals or any 4-index quantity (e.g. 2rdm) between different permutation symmetries. It takes a symmetry label, a numpy.ndarray as the 4-index quantity and the dimension norb of this quantity (the four indices must have the same dimension). The symmetry label specifies the output symmetry the user desires, while the symmetry of the input array is determined by its shape. The relation between different symmetries and shape is described below.

“Plain” MO integrals or ‘s1’ symmetry have a shape of (norb, norb, norb, norb). If a pair of indices have permutation symmetry, then only the triangular index is used and the shape is (npair, npair) with npair = norb*(norb+1)/2. Thus integrals with ‘s2ij’ and ‘s2kl’ symmetries have a shape of (npair, norb, norb) or (norb, norb, npair) respectively. If the integrals have ‘s4’ symmetry, then there is permutation symmetry between both ij indices and kl indices and the shape will be (npair, npair). If the integrals have ‘s8’ symmetry, then permutation symmetry also exists between the ij pair and kl pair. This will yield a one-dimensional array with length npair*(npair+1)/2. restore() determines the symmetry of the input array based on the above rules, and the shape of the output is also determined in this way. If the input does not correspond to any of the above shapes, PySCF will throw an error.

Listed are the symmetry labels that can be used, whichcan be either be a str or int.

‘s8’, ‘8’, 8

8-fold symmetry

‘s4, ‘4’, 4

4-fold symmetry

‘s2kl’, ‘2kl’

2-fold symmetry between ij indices.

‘s2ij’, ‘2ij’

2-fold symmetry between kl indices.

‘s1’, ‘1’, 1

1-fold symmetry or no symmetry.

Note

The examples in this document can be found as a single python script in examples/ao2mo/02-ao2mo_doc.py, more examples can also be found at examples/ao2mo/02-ao2mo_doc.py directory.