Access molecular integrals via MintsHelper?

Is there any method to access MO integrals using the MintsHelper, something along the lines of mints.mo_kinetic() or such?

I know I can get these integrals: Printing of molecular orbitals

I was wondering if I can directly access them and modify and work with them. For reference, I’m trying to get the AO basis canonically orthogonalized and was wondering if a MO->AO route was feasible. If not, what would be some other options?

Thanks so much!!

2 Likes

Unfortunately the MintsHelper does not contain orbital information so this is not possible. Probably the easiest way to obtain canonically orthonormalized orbitals and overlap matrices is to run a SCF computation and take the orbitals and S matrix from this result.

scf_wfn, scf_e = psi4.energy("SCF", return_wfn=True)
S = scf_wfn.S()

It might be worth checking out Psi4Numpy: https://github.com/psi4/psi4numpy

I thought that the default is symmetric orthogonalization as long as the smallest eigenvalue is not too small. At least that’s what is printed in the psi4 output file for most calculations I have run so far.

Additionally, the overlap matrix that the scf calculation returns is not an orthonormalized basis (it is not identity), so I figured ao_kinetic/potential are in some non-orthonormalized atomic basis. Is that not true?

Thanks again for your help!

The ao_ signifies that you are in the atomic orbital basis (not orthonormalized). In general the orthogonalization is built into the orbitals themselves so we rarely look at the symmetrize version of the AO’s. AFAIK canonical orthogonalization is identical to symmetric orthogonalization unless there are eigenvalues smaller that the cutoff.

You can obtain symmetric orthogonalized integrals like so:

import psi4
import numpy as np
np.set_printoptions(precision=1.e-4, suppress=True)

water = psi4.geometry("""
O
H 1 1.1
H 1 1.1 2 104
""")


scf_e, scf_wfn = psi4.energy("SCF/sto-3g", return_wfn=True)

mints = psi4.core.MintsHelper(scf_wfn.basisset())
ao_potential = mints.ao_potential()
ao_kinetic = mints.ao_kinetic()
ao_overlap = mints.ao_overlap()

# Build orthogonalizer
X = ao_overlap.clone()
X.power(-0.5, 1.e-14)

print("\nOverlap matrix")
print(np.dot(X, ao_overlap).dot(X))

print("\nPotential matrix")
print(np.dot(X, ao_potential).dot(X))

print("\nKinetic matrix")
print(np.dot(X, ao_kinetic).dot(X))

This will return:

Overlap matrix
[[ 1. -0. -0. -0.  0. -0. -0.]
 [-0.  1.  0.  0. -0. -0. -0.]
 [-0.  0.  1. -0.  0. -0. -0.]
 [-0.  0. -0.  1.  0.  0. -0.]
 [ 0. -0.  0.  0.  1. -0.  0.]
 [-0. -0.  0.  0. -0.  1. -0.]
 [-0.  0. -0. -0.  0. -0.  1.]]

Potential matrix
[[-63.   2.   0.   0.  -0.  -1.  -1.]
 [  2. -10.  -0.  -0.   0.  -0.  -0.]
 [  0.  -0. -10.   0.  -0.   0.   0.]
 [  0.  -0.   0. -10.  -0.  -0.   0.]
 [ -0.   0.  -0.  -0. -10.  -0.   0.]
 [ -1.  -0.   0.  -0.  -0.  -5.   0.]
 [ -1.  -0.   0.   0.   0.   0.  -5.]]

1 Like