The one-particle density and the associated spin-orbital density matrix, , are related as follows
A nonzero contribution to the density requires the spin of both orbitals to be identical and the summation can therefore be separated by introducing the - and -spin densities and instead run over molecular orbitals
Natural orbitals is a single set of spatial orbitals in which the one-particle density is expanded
and the elements of the diagonal density matrix, , in this basis are referred to as occupation numbers.
Restricted orbitals¶
In restricted calculations, we have a common set of MOs for the - and -spin orbitals and can write
The density matrix is Hermitian and can be diagonalized by a unitary transformation. We get
In restricted closed (RHF) and open-shell Hartree–Fock (ROHF), the natural orbitals equal the HF orbitals and the occupation numbers equal to 0, 1, and 2 for unoccuppied, singly occupied, and doubly occupied MOs, respectively.
For the case of a multi-configurational wave function, we study the oxygen molecule as an example.
import multipsi as mtp
import numpy as np
import veloxchem as vlx
mol_str = """2
O -0.6 0.0 0.0
O 0.6 0.0 0.0
"""
molecule = vlx.Molecule.read_xyz_string(mol_str)
basis = vlx.MolecularBasis.read(molecule, "cc-pvdz", ostream=None)
molecule.set_multiplicity(3)
rohf_drv = vlx.ScfRestrictedOpenDriver()
rohf_drv.ostream.mute()
rohf_results = rohf_drv.compute(molecule, basis)print(f" RHF energy: {rohf_drv.get_scf_energy() : 14.8f}") RHF energy: -149.60946112
The MOs are occupied by nine - and seven -spin electrons.
rohf_drv.molecular_orbitals.print_orbitals(molecule, basis)
Spin Restricted Orbitals
------------------------
Molecular Orbital No. 3:
--------------------------
Occupation: 2.000 Energy: -1.66016 a.u.
( 1 O 2s : -0.34) ( 1 O 3s : -0.27) ( 1 O 1p+1: -0.16)
( 2 O 2s : -0.34) ( 2 O 3s : -0.27) ( 2 O 1p+1: 0.16)
Molecular Orbital No. 4:
--------------------------
Occupation: 2.000 Energy: -1.09511 a.u.
( 1 O 2s : -0.36) ( 1 O 3s : -0.45) ( 2 O 2s : 0.36)
( 2 O 3s : 0.45)
Molecular Orbital No. 5:
--------------------------
Occupation: 2.000 Energy: -0.73155 a.u.
( 1 O 3s : 0.27) ( 1 O 1p+1: -0.46) ( 1 O 2p+1: -0.24)
( 2 O 3s : 0.27) ( 2 O 1p+1: 0.46) ( 2 O 2p+1: 0.24)
Molecular Orbital No. 6:
--------------------------
Occupation: 2.000 Energy: -0.70486 a.u.
( 1 O 1p-1: 0.31) ( 1 O 1p0 : 0.32) ( 1 O 2p-1: 0.20)
( 1 O 2p0 : 0.20) ( 2 O 1p-1: 0.31) ( 2 O 1p0 : 0.32)
( 2 O 2p-1: 0.20) ( 2 O 2p0 : 0.20)
Molecular Orbital No. 7:
--------------------------
Occupation: 2.000 Energy: -0.70486 a.u.
( 1 O 1p-1: 0.32) ( 1 O 1p0 : -0.31) ( 1 O 2p-1: 0.20)
( 1 O 2p0 : -0.20) ( 2 O 1p-1: 0.32) ( 2 O 1p0 : -0.31)
( 2 O 2p-1: 0.20) ( 2 O 2p0 : -0.20)
Molecular Orbital No. 8:
--------------------------
Occupation: 1.000 Energy: -0.20397 a.u.
( 1 O 1p-1: 0.44) ( 1 O 1p0 : -0.31) ( 1 O 2p-1: 0.33)
( 1 O 2p0 : -0.23) ( 2 O 1p-1: -0.44) ( 2 O 1p0 : 0.31)
( 2 O 2p-1: -0.33) ( 2 O 2p0 : 0.23)
Molecular Orbital No. 9:
--------------------------
Occupation: 1.000 Energy: -0.20397 a.u.
( 1 O 1p-1: 0.31) ( 1 O 1p0 : 0.44) ( 1 O 2p-1: 0.23)
( 1 O 2p0 : 0.33) ( 2 O 1p-1: -0.31) ( 2 O 1p0 : -0.44)
( 2 O 2p-1: -0.23) ( 2 O 2p0 : -0.33)
Molecular Orbital No. 10:
--------------------------
Occupation: 0.000 Energy: 0.47356 a.u.
( 1 O 2s : 0.19) ( 1 O 3s : 1.28) ( 1 O 1p+1: 0.40)
( 1 O 2p+1: 1.23) ( 2 O 2s : -0.19) ( 2 O 3s : -1.28)
( 2 O 1p+1: 0.40) ( 2 O 2p+1: 1.23)
Molecular Orbital No. 11:
--------------------------
Occupation: 0.000 Energy: 1.08237 a.u.
( 1 O 3s : -0.99) ( 1 O 1p+1: 0.71) ( 1 O 2p+1: -1.33)
( 2 O 3s : 0.99) ( 2 O 1p+1: 0.71) ( 2 O 2p+1: -1.33)
Molecular Orbital No. 12:
--------------------------
Occupation: 0.000 Energy: 1.10988 a.u.
( 1 O 1p-1: -0.48) ( 1 O 1p0 : 0.48) ( 1 O 2p-1: 0.44)
( 1 O 2p0 : -0.44) ( 2 O 1p-1: -0.48) ( 2 O 1p0 : 0.48)
( 2 O 2p-1: 0.44) ( 2 O 2p0 : -0.44)
Molecular Orbital No. 13:
--------------------------
Occupation: 0.000 Energy: 1.10988 a.u.
( 1 O 1p-1: 0.48) ( 1 O 1p0 : 0.48) ( 1 O 2p-1: -0.44)
( 1 O 2p0 : -0.44) ( 2 O 1p-1: 0.48) ( 2 O 1p0 : 0.48)
( 2 O 2p-1: -0.44) ( 2 O 2p0 : -0.44)
Molecular Orbital No. 14:
--------------------------
Occupation: 0.000 Energy: 1.15024 a.u.
( 1 O 3s : 0.29) ( 1 O 1p+1: 0.59) ( 1 O 2p+1: -0.82)
( 2 O 3s : 0.29) ( 2 O 1p+1: -0.59) ( 2 O 2p+1: 0.82)
Main AO character of MOs
Active orbitals (8 electrons)
Inactive orbitals (8 electrons)
casscf_drv = mtp.McscfDriver()
orbital_space = mtp.OrbSpace(molecule, rohf_drv.mol_orbs)
orbital_space.cas(8, 6)
casscf_results = casscf_drv.compute(molecule, basis, orbital_space)print(f"CAS(8,6) energy: {casscf_results["energies"][0] : 12.8f}")CAS(8,6) energy: -149.70836718
The wave function is predominantly a sum of two determinants with -spin occupation of the and molecular orbitals, respectively.
casscf_results["ci_vectors"].print(0)Determinant coef. weight
222aa0 0.972 0.945
aa2220 -0.155 0.024
The occupation numbers are (i) equal to 2 for the four inactive orbitals, (ii) close to 2 for and , (iii) close to 1 for , and (iv) close to 0 for .
print(casscf_results["natural_occupations"][0])[1.96299851 1.96299851 1.96098176 1.03637599 1.03637599 0.04026925]
Unrestricted orbitals¶
In unrestricted calculations, we have separate sets of MOs for the - and -spin orbitals. However, one set can be expressed in terms of the other according to
where is the overlap between the two sets of orbitals that, in turn, can be expressed in terms of the overlap matrix in the AO basis
The one-particle density becomes
and the natural orbitals and occupation numbers are obtained from a diagonalization of this total density matrix.
Let us consider the unrestricted Hartree–Fock state of the oxygen molecule.
uhf_drv = vlx.ScfUnrestrictedDriver()
uhf_drv.ostream.mute()
uhf_results = uhf_drv.compute(molecule, basis)print(f"UDFT energy: {uhf_drv.get_scf_energy() : 14.8f}")UDFT energy: -149.62899231
norb = basis.get_dimensions_of_basis()
n_alpha_electrons = 9
n_beta_electrons = 7
S = uhf_results["S"]
C_alpha = uhf_results["C_alpha"]
C_beta = uhf_results["C_beta"]
D_alpha = np.zeros((norb, norb))
for i in range(n_alpha_electrons):
D_alpha[i, i] = 1
D_beta = np.zeros((norb, norb))
for i in range(n_beta_electrons):
D_beta[i, i] = 1S_ab = np.einsum("ap, bq, ab -> pq", C_alpha, C_beta, S)
D = D_alpha + np.einsum("pr, qs, rs -> pq", S_ab, S_ab, D_beta)
occ_numbers, U = np.linalg.eigh(D)print("Orbital Occ. number")
for orb, occ in enumerate(list(occ_numbers)[::-1]):
if occ > 1e-3:
print(f"{orb + 1 : >2} {occ : 12.3f}")Orbital Occ. number
1 2.000
2 2.000
3 2.000
4 1.999
5 1.997
6 1.994
7 1.994
8 1.000
9 1.000
10 0.006
11 0.006
12 0.003
We can also get the natural orbitals and occupation numbers from the natural_orbitals method in VeloxChem.
natural_orbs = uhf_drv.natural_orbitals(uhf_results)
natural_orbs.print_orbitals(molecule, basis)
Spin Restricted Orbitals
------------------------
Molecular Orbital No. 3:
--------------------------
Occupation: 4.000 Energy: -1.09255 a.u.
( 1 O 1p+1: -0.47) ( 1 O 2p+1: -0.22) ( 2 O 1p+1: 0.47)
( 2 O 2p+1: 0.22)
Molecular Orbital No. 4:
--------------------------
Occupation: 3.998 Energy: -1.34641 a.u.
( 1 O 2s : 0.33) ( 1 O 3s : 0.37) ( 1 O 1p+1: -0.16)
( 2 O 2s : 0.33) ( 2 O 3s : 0.37) ( 2 O 1p+1: 0.16)
Molecular Orbital No. 5:
--------------------------
Occupation: 3.994 Energy: -1.09919 a.u.
( 1 O 2s : 0.36) ( 1 O 3s : 0.45) ( 2 O 2s : -0.36)
( 2 O 3s : -0.45)
Molecular Orbital No. 6:
--------------------------
Occupation: 3.988 Energy: -0.70203 a.u.
( 1 O 1p0 : 0.44) ( 1 O 2p0 : 0.28) ( 2 O 1p0 : 0.44)
( 2 O 2p0 : 0.28)
Molecular Orbital No. 7:
--------------------------
Occupation: 3.988 Energy: -0.70203 a.u.
( 1 O 1p-1: 0.44) ( 1 O 2p-1: 0.28) ( 2 O 1p-1: 0.44)
( 2 O 2p-1: 0.28)
Molecular Orbital No. 8:
--------------------------
Occupation: 2.000 Energy: -0.20095 a.u.
( 1 O 1p-1: -0.53) ( 1 O 2p-1: -0.38) ( 2 O 1p-1: 0.53)
( 2 O 2p-1: 0.38)
Molecular Orbital No. 9:
--------------------------
Occupation: 2.000 Energy: -0.20095 a.u.
( 1 O 1p0 : -0.53) ( 1 O 2p0 : -0.38) ( 2 O 1p0 : 0.53)
( 2 O 2p0 : 0.38)
Molecular Orbital No. 10:
--------------------------
Occupation: 0.012 Energy: 1.21925 a.u.
( 1 O 1p-1: 0.57) ( 1 O 1p0 : -0.38) ( 1 O 2p-1: -0.49)
( 1 O 2p0 : 0.32) ( 2 O 1p-1: 0.57) ( 2 O 1p0 : -0.38)
( 2 O 2p-1: -0.49) ( 2 O 2p0 : 0.32)
Molecular Orbital No. 11:
--------------------------
Occupation: 0.012 Energy: 1.21925 a.u.
( 1 O 1p-1: 0.38) ( 1 O 1p0 : 0.57) ( 1 O 2p-1: -0.32)
( 1 O 2p0 : -0.49) ( 2 O 1p-1: 0.38) ( 2 O 1p0 : 0.57)
( 2 O 2p-1: -0.32) ( 2 O 2p0 : -0.49)
Molecular Orbital No. 12:
--------------------------
Occupation: 0.006 Energy: 0.65627 a.u.
( 1 O 2s : 0.41) ( 1 O 3s : 0.41) ( 1 O 1p+1: 0.32)
( 1 O 2p+1: 0.74) ( 1 O 1d+2: -0.20) ( 2 O 2s : -0.41)
( 2 O 3s : -0.41) ( 2 O 1p+1: 0.32) ( 2 O 2p+1: 0.74)
( 2 O 1d+2: 0.20)
Molecular Orbital No. 13:
--------------------------
Occupation: 0.002 Energy: 2.07548 a.u.
( 1 O 1s : 0.38) ( 1 O 2s : 0.94) ( 1 O 3s : -0.80)
( 1 O 2p+1: 0.18) ( 1 O 1d+2: -0.35) ( 1 O 1d0 : 0.20)
( 2 O 1s : 0.38) ( 2 O 2s : 0.94) ( 2 O 3s : -0.80)
( 2 O 2p+1: -0.18) ( 2 O 1d+2: -0.35) ( 2 O 1d0 : 0.20)
Molecular Orbital No. 14:
--------------------------
Occupation: 0.000 Energy: 1.39353 a.u.
( 1 O 1s : -0.23) ( 1 O 2s : -0.50) ( 1 O 3s : 0.17)
( 1 O 1p+1: -0.62) ( 1 O 2p+1: 0.83) ( 2 O 1s : -0.23)
( 2 O 2s : -0.50) ( 2 O 3s : 0.17) ( 2 O 1p+1: 0.62)
( 2 O 2p+1: -0.83)