2.6. Defining an Active Space Hamiltonian

PyBEST also supports the feature of generating an active space Hamiltonian, that is, an electronic Hamiltonian defined for a specific subsets of molecular orbitals. The split_core_active() function performs several operations:

  1. Transform AO integrals into the MO basis (if required)

  2. Calculcate active space Hamiltonian

When calculating an active-space Hamitlonian, the core energy as well as the one-electron integrals need to be updated, while the two-electron integrals are simply ‘sliced’. Specifically, the one-electron integrals for the active space \(\tilde{h}_{pq}\) are calculated from

\[\tilde{h}_{pq} = h_{pq} + \sum_{i \in \textrm{ncore}} ( 2 \langle pi \vert qi \rangle - \langle pi \vert iq \rangle),\]

where \(h_{pq}\) is an element of the original one-electron integrals and \(\langle pi \vert qi \rangle\) are the original two-electron integral in physicist’s notation. The core energy of the active space is determined from

\[E_\text{core} = E_\text{nn} + 2\sum_{i \in \textrm{ncore}} t_{ii} + \sum_{i, j \in \textrm{ncore}} (2 \langle ij \vert ij \rangle - \langle ij \vert ji \rangle)\]

where \(E_\text{nn}\) is the original core energy (for instance the nuclear-nuclear repulsion term). The sums over the one- and two-electron integrals run over the frozen core orbitals only. The updated two-electron integrals \(\langle pq \vert rs \rangle\) contain only the elements corresponding to the active orbital indices \(p,q,r,s\).

2.6.1. Defining the molecular Hamiltonian for an active orbital space

An active space can be defined as follows, where the integrals are transformed into the molecular orbital basis,

# Define an active space with ncore=10 frozen core orbitals and nactive=24
# active orbitals
cas = split_core_active(kin, ne, er, orb, e_core=external, ncore=10, nactive=24)

# all one-electron integrals
one = cas.one
# all two-electron integrals
two = cas.two
# the core energy
e_core = cas.e_core

where kin, ne, and er are the original one- and two-electron integrals, respectively (see also The AO/MO Transformation of the Hamiltonian), external is the original core energy (see also Computing the matrix representation of the Hamiltonian), orb are the molecular orbitals that transform the AO integrals into the MO basis, and ncore (nactive) is the number of frozen core (active) orbitals. The active space Hamiltonian is stored/returned as an instance of IOData.

Note

The core energy e_core as well as number of core and active orbitals has to be passed as a keyword argument using e_core, ncore, or nactive, respectively.

If you want to calculate the active space Hamiltonian for a specific method (that is, for a specific set of orbitals and method specific core energy), you have to pass the corresponding method output (an instance of the IOData class) to the split_core_active() function (in addition to the Hamiltonian). PyBEST will assign all quantities automatically,

# Define an active space with ncore=10 frozen core orbitals and nactive=24
# active orbitals from a pCCD wave function stored in pccd_out
cas = split_core_active(kin, ne, er, pccd_out, ncore=10, nactive=24)

# all one-electron integrals
one = cas.one
# all two-electron integrals
two = cas.two
# the core energy
e_core = cas.e_core

Thus, only all one- and two-electron integrals as well as the return value of the desired QC method are required. Note that the IOData container has to contain an e_core attribute. By default, all QC methods implemented in PyBEST return their corresponding core energy. The IOData container can be overwritten using arguments or keyword arguments. However, we recommend this option for experienced users only.

Note

The order of the arguments does not matter. PyBEST will automatically recognize all Hamiltonian terms, orbitals, and external energy contributions.

If the AO/MO transformation of the one- and two-electron integrals should be skipped, do no pass the orbitals as argument,

# Define an active space with 10 frozen core orbitals and 24 active orbitals
# Skip the AO/MO transformation step
cas = split_core_active(kin, ne, er, e_core=external, ncore=10, nactive=24)

Note

The split_core_active() function supports only restricted orbitals.

2.6.2. Dumping the active space Hamiltonian to disk

Once the active space Hamiltonian has been defined, it can be dump to disk (see Dumping/Loading a Hamiltonian to/from a file for more information). In PyBEST, the active space integrals can be either stored using the internal file format (binary)

# Dump active space integrals stored in "cas" to disk using .h5 format
cas.to_file('cas_hamiltonian.h5')

or the FCIDUMP format (ASCII)

# Dump active space integrals stored in "cas" to disk using the FCIDUMP format
cas.to_file('cas_hamiltonian.FCIDUMP')