Orbital and density visualisation¶
Converged molecular orbitals and electron densities become useful when you can see them. vibe-qc writes two interchange formats that every molecular-viewer understands:
Molden (
.molden) — one file carrying geometry + basis + every MO. Jmol, Avogadro, IQmol, MolView all open it.Gaussian cube (
.cube) — volumetric data on a 3D grid, suitable for isosurface rendering in VMD, PyMOL, ChimeraX, VESTA, ParaView, Blender.
Molden is the fast path — no grid choice, smallest file, every modern viewer supports it. Cube is the publication-quality path — explicit sampling of ρ(r) or a single MO on a grid you control, rendered as smooth isosurfaces by a dedicated volume-rendering tool.
The one-liner: .molden via run_job¶
Every run_job call already writes a Molden file by default:
from vibeqc import Atom, Molecule, run_job
mol = Molecule([
Atom(8, [ 0.0, 0.00, 0.00]),
Atom(1, [ 0.0, 1.43, -0.98]),
Atom(1, [ 0.0, -1.43, -0.98]),
])
run_job(mol, basis="6-31g*", method="rhf", output="water")
# -> water.molden
Open it:
open -a Avogadro2 water.molden # macOS
# or
jmol water.molden # cross-platform
Select an MO from the energy list, render as an isosurface. For a publication-style plot you’ll usually want the cube route.
Cube files for single orbitals¶
import vibeqc as vq
mol = vq.Molecule([
vq.Atom(8, [ 0.0, 0.00, 0.00]),
vq.Atom(1, [ 0.0, 1.43, -0.98]),
vq.Atom(1, [ 0.0, -1.43, -0.98]),
])
basis = vq.BasisSet(mol, "6-31g*")
result = vq.run_rhf(mol, basis)
# HOMO is the highest doubly-occupied orbital (0-based index)
homo = mol.n_electrons() // 2 - 1
vq.write_cube_mo("water_homo.cube", result.mo_coeffs, homo, basis, mol)
vq.write_cube_mo("water_lumo.cube", result.mo_coeffs, homo + 1, basis, mol)
# Or write the full density
vq.write_cube_density("water_rho.cube", result.density, basis, mol)
The cube writer auto-picks a cubic bounding box and grid spacing appropriate for the molecule. For custom control see the volumetric data user guide.
Multiple MOs in one file¶
Some viewers (VMD, Avogadro) support multi-volume cube files — one file, several MOs, toggle between them in the UI.
homo = mol.n_electrons() // 2 - 1
vq.write_cube_mos(
"water_frontier.cube",
result.mo_coeffs,
orbital_indices=[homo - 1, homo, homo + 1, homo + 2],
basis=basis,
molecule=mol,
)
Viewer recipes¶
Given water_homo.cube on disk:
VMD (publication-quality rendering with Tachyon/POV-Ray):
vmd water_homo.cube
# In the TkCon:
mol rename top water
mol addrep top
mol modstyle 1 top Isosurface 0.05 0 0 0 1 1
Avogadro 2 — open the cube, View → Add View → Orbitals, pick the isovalue (0.03–0.05 is a good starting point for MOs).
PyMOL:
load water_homo.cube
isomesh homo_pos, water_homo, 0.05
isomesh homo_neg, water_homo, -0.05
color cyan, homo_pos
color orange, homo_neg
Blender (with Molecular Nodes): directly imports cube as a volumetric object, isosurface is a geometry-nodes tree away.
Grid settings¶
The default grid (0.2 bohr spacing, 3 bohr padding around atoms) is fine for visualisation. For tighter or sparser meshes:
vq.write_cube_mo(
"water_homo_fine.cube",
result.mo_coeffs, homo, basis, mol,
spacing=0.1, # bohr
padding=5.0, # bohr around the bounding box of atoms
)
A finer grid gives cleaner isosurface curvature at the cost of file
size; 0.1 bohr is typical for papers, 0.2 bohr is plenty for quick
looks. The file size scales as 1 / spacing³.
Caveats¶
HF orbitals aren’t “truth”. Molecular orbitals are a representation-dependent quantity — Kohn-Sham orbitals from the same basis set often look visibly different. When comparing to the literature, note the method that generated them.
Phase arbitrariness. The overall sign of an MO is arbitrary — two SCF runs can land on C_i → +C_i or −C_i. The density is the physical quantity; the colour of HOMO lobes can flip between runs.
Tighter basis → more structure. Minimal-basis HOMOs look bland; by TZVP you start seeing polarisation lobes that are genuinely chemically informative.
Next¶
For periodic systems, XSF files play the role cube files do for
molecules — see the volumetric-data user guide
for the periodic equivalents (write_xsf_volume, write_bxsf for
Fermi surfaces).