I am working on a high school graduation paper on Hartree Fock and have gotten pretty far already. With help from this community, I managed to generate all the necessary integrals and implement the algorithm in python. I am currently checking whether the algorithm is actually doing what it's supposed to do. I compare my values with the ones provided by pyscf. See this example.
For noble gases I get correct values. If I try my implementation for molecules however I get too high values. I've tried $\ce{H2}$, $\ce{F2}$, $\ce{O2}$, and $\ce{HF}$. My algorithm works totally fine for atoms so I feel like there can't be something wrong with the implementation itself. I've also tried generating completely random initial guesses. I get the exact same results as well. I therefore feel like the algorithm is stopping on a local minimum or saddle point. Does anybody have an idea how to fix it or whether HF just returns such bad results?
This is my code if someone wants to check it out and give feedback. It only runs on MacOS and Linux distributions since pyscf can't run on Windows. Help is greatly appreciated since the due date for the paper is getting closer and closer ;)
TLDR: Restricted Hartree Fock SCF Algorithm returns too high orbital energies for molecules, but not for Atoms. How can I fix that?
Update: Here is a list of what I've tried:
- I first checked my code by using a zero matrix as the initial guess. This I compared to the PySCF HF kernels result. The energies are too high.
- I then checked whether the algorithm is doing anything anyway. I therefore used a completely random initial guess with values ranging between -100 and 100. The algorithm returned the same energies as with the zero matrix as the initial guess.
- I then checked whether all the matrices are correct. I used PySCF
get_hcore(), get_ovlp(), get_veff(), get_fock()
for a given density matrix. All my matrices are the same as the ones generated by PySCF.
Here a quick explanation of my implementation of the algorithm:
- Initial guess density Matrix $P$ is a zero matrix
- Generate transformation matrix $X$ as $S^{-1/2}$.
- Generate Fock matrix with given $P$.
- Transform Fock matrix as $F^{'} = X^{\dagger}FX$
- Diagonalize $F^{'}$
- Transform coefficients $C^{'}$ back as $C = X C^{'}$
- Use $C$ to generate new $P$ and repeat till energies meet convergence criteria. I assume that if the sum of orbital energies minus the sum of the last orbital energies is an absolute value of less than 0.0001 it converges.
There is no implementation of DIIS, level shifting or damping. I hope this makes it clearer.
if 0 <= energy_diff <= 10e-14
: Normally folks check if the absolute-value of the deviation is beneath a threshold. That particular check would seem to reject near-perfect convergence if it happened to be negative. $\endgroup$