Molecular Hartree-Fock

Compute the restricted-Hartree-Fock energy of the water molecule in the 6-31G* basis.

from vibeqc import Atom, Molecule, BasisSet, run_rhf

# Water, experimental geometry in bohr.
mol = Molecule([
    Atom(8, [0.0,  0.0,  0.0]),
    Atom(1, [0.0,  1.43, -0.98]),
    Atom(1, [0.0, -1.43, -0.98]),
])
basis = BasisSet(mol, "6-31g*")
result = run_rhf(mol, basis)

print(f"E_RHF       = {result.energy:.10f}")
print(f"converged   = {result.converged}")
print(f"iterations  = {result.n_iter}")
print(f"MO energies = {result.mo_energies}")

Output:

E_RHF       = -76.0107424867
converged   = True
iterations  = 8
MO energies = [-20.55  -1.34  -0.71  -0.56  -0.50   0.21   0.31   ...]

What just happened

  1. Building the basis. BasisSet(mol, "6-31g*") looks up the 6-31G* contraction in libint’s built-in library, places its shells on each atomic centre, and records the resulting list of atomic orbitals.

  2. SCF with DIIS. The driver diagonalises H_core for an initial guess, builds the Fock matrix from the density, then iterates using Pulay’s DIIS extrapolation. Convergence tolerances default to conv_tol_energy = 1e-8 Ha and conv_tol_grad = 1e-6.

  3. Output. The RHFResult carries the total energy, converged MO coefficients, orbital energies, density matrix, and the full SCF trace for post-analysis.

Tuning convergence

Most of the time the defaults are fine. For tight benchmarks you may want:

from vibeqc import RHFOptions

opts = RHFOptions()
opts.conv_tol_energy = 1e-12
opts.conv_tol_grad = 1e-10
opts.use_diis = True
opts.initial_guess = vq.InitialGuess.SAD   # superposition of atomic densities

result = run_rhf(mol, basis, opts)

Computing gradients

For geometry optimisation or force evaluation, vibe-qc exposes analytic HF gradients:

from vibeqc import compute_gradient

grad = compute_gradient(mol, basis, result)   # (n_atoms, 3), Hartree / bohr

Gradients are analytic throughout; accuracy tracks the SCF convergence (better than 1e-8 Ha/bohr at default tolerances).

Next