Semiempirical Methods

vibe-qc ships a self-contained semiempirical platform covering four method families — DFTB, GFN-xTB, NDDO, and INDO — for molecules and periodic solids. The platform is vibe-qc’s own implementation, not a wrapper around external programs (External QC codes (ORCA / Psi4 / others)). The MACE machine-learning interatomic potential is documented separately because it is an external pre-trained model, not a semiempirical electronic-structure method (Machine-learning interatomic potentials (MACE)).

Warning

Production readiness varies by method. DFTB is intended for screening/preoptimization; GFN2-xTB is gated experimental; PM6, OM2 and OM3 are production for molecular work (PES shape pinned by regression, published-benchmark validation for OM2 — see the status table); OM1 is experimental until its analytic core-valence ECP lands; MSINDO is reference-parity validated for its current molecular scope. See the status table and the comparative production brief in Semiempirical and MACE method comparison.

Method families

Family

Methods

Best for

Cost

DFTB

DFTB0, SCC-DFTB, UDFTB0, USCC-DFTB

Screening, preoptimization

Fastest

GFN-xTB

GFN2-xTB

Organic / main-group

Fast

NDDO

PM6, OM1, OM2, OM3

Development benchmarking, pre-screening

Fast

INDO

MSINDO

Reference-parity molecular semiempirical runs inside the supported element/spin scope

Fast

Quick start

DFTB0 — non-self-consistent tight-binding

from vibeqc.semiempirical import DFTB0Model
from vibeqc import Molecule, Atom

mol = Molecule([
    Atom(8, [0.00, 0.00, 0.00]),
    Atom(1, [1.55, 0.90, 0.00]),
    Atom(1, [-1.55, 0.90, 0.00]),
])

model = DFTB0Model(mol)
print(f"Energy: {model.energy():.6f} Ha")
print(f"Gradient shape: {model.gradient().shape}")  # (3, 3)

SCC-DFTB — self-consistent charges

from vibeqc.semiempirical import SCCDFTBModel

model = SCCDFTBModel(mol, charge_mixing=0.2)
print(f"Energy: {model.energy():.6f} Ha")

GFN2-xTB — published parameters (experimental)

from vibeqc.semiempirical import GFN2Model
from vibeqc.semiempirical.methods.gfn2_params import load_gfn2_params

params = load_gfn2_params()  # auto-fetches 86-element Grimme parameter set
model = GFN2Model(mol, params=params, warn=False)  # warn=False silences experimental gate
print(f"Energy: {model.energy():.6f} Ha")

Warning

GFN2-xTB is gated experimental. The H0/overlap deep-state bug was fixed 2026-06-01, and molecular AES (dipole + quadrupole), the GAM3 third-order term, and post-SCF native D4-style dispersion are now implemented. The remaining production gates are self-consistent GFN2-D4, periodic AES image-cell multipole Ewald terms, SCC mixer tuning for difficult polar systems, and a full external-parity matrix against xtb. See Method status.

PM6 — NDDO with published parameters

from vibeqc.semiempirical import PM6Model

model = PM6Model(mol)
print(f"Energy: {model.energy():.6f} Ha")

OMx — orthogonalization-corrected NDDO

from vibeqc.semiempirical import OMxModel

model = OMxModel(mol, variant="om2")  # "om1", "om2", or "om3"
print(f"Energy: {model.energy():.6f} Ha")

Through run_job

All seven methods are available via vibeqc.runner.run_job():

from vibeqc import run_job

run_job(mol, method="dftb0", optimize=True, output="h2o_dftb0")
run_job(mol, method="pm6", output="h2o_pm6")
run_job(mol, method="gfn2_xtb", output="h2o_gfn2")   # emits experimental warning

Periodic systems

All families support Gamma-point periodic calculations with finite-difference gradients and stress.

DFTB periodic

from vibeqc._vibeqc_core import PeriodicSystem, Atom
from vibeqc._vibeqc_core import semiempirical as _se
import numpy as np

# 1D carbon chain
atoms = [Atom(6, [0.0, 0.0, 0.0])]
cell = np.diag([2.5, 30.0, 30.0])
system = PeriodicSystem(1, cell, atoms)

params = _se.SemiempiricalParameters.dftb0_default()
result = _se.run_dftb0_gamma(system, params)
print(f"Energy: {result.energy:.6f} Ha")

GFN2 periodic

from vibeqc._vibeqc_core.semiempirical import xtb as _xtb
from vibeqc.semiempirical.methods.gfn2_params import load_gfn2_params

params = load_gfn2_params()
result = _xtb.run_gfn2_xtb_gamma(system, params)

PM6 / OMx periodic

from vibeqc.semiempirical import PeriodicPM6Model, PeriodicOMxModel

pm6 = PeriodicPM6Model(system)
print(f"PM6: {pm6.energy():.6f} Ha")

omx = PeriodicOMxModel(system, variant="om2")
print(f"OM2: {omx.energy():.6f} Ha")

Preoptimization workflows

Use semiempirical methods for fast structure preoptimization before an expensive DFT calculation:

from vibeqc.semiempirical import preoptimize_periodic

# Preoptimize a periodic system with DFTB0, then run DFT
preoptimize_periodic(
    system,
    method="dftb0",
    fmax=0.01,
)

For molecular systems, use optimize=True with run_job:

from vibeqc import run_job

# Preoptimize with DFTB0, then refine with DFT
run_job(mol, method="dftb0", optimize=True)
run_job(mol, method="rks", functional="PBE", basis="def2-svp", optimize=True)

Method status

Method

Status

Energy accuracy

Gradient

Periodic

Open-shell

Elements

DFTB0 / UDFTB0

Screening/preopt

In-house parameters, not DFTB+ parity

Analytic

Gamma + k

yes

91 in-house

SCC-DFTB / USCC

Screening/preopt

In-house parameters, not DFTB+ parity

Approx

Gamma + k

yes

91 in-house

GFN2-xTB

Gated experimental

External xTB parity matrix still open

Approx

Gamma + k, experimental

yes

86 fetched (LGPL)

PM6 / UPM6

Production (molecular)

Physical PES pinned by regression; spherical Klopman–Ohno fallback where MOPAC diatomic data is absent (wells ~0.1–0.3 bohr long)

FD

Gamma, experimental

yes

82 bundled MOPAC

OM2 / OM3

Production (molecular)

Published OMx Hamiltonian (Dral 2016); relative energetics match published benchmarks (H3- bend 0.1 kcal/mol, ethane barrier ±0.6); bond minima ~0.1–0.2 Å long (documented integral stand-ins)

FD

Gamma, legacy-model parity only

yes (UHF)

5 published (H,C,N,O,F)

OM1

Experimental (warns)

Analytic core-valence ECP (Kolb-Thiel 1993) not implemented; X-H bonds ~0.3 A short, close contacts can collapse

FD

Gamma, legacy-model parity only

yes (UHF)

5 published (H,C,N,O,F)

MSINDO

Production within scope

Reference MSINDO parity ≤1 µHa (INDO + NDDO)

FD (analytic partially)

CCM 1-D/2-D/3-D + Ewald

UHF s/p + d-shell closed

H–Br (Z=1–35); NDDO H,Li–F,Na–Cl

See also

Semiempirical and MACE method comparison for production guidance and ../semiempirical_acceptance_matrix.py for the living validation-gate matrix.

Element coverage

DFTB — 91 elements (H–U except Po/Z=84), including 3d/4d/5d transition metals, lanthanides (La–Lu), and early actinides (Ac–U). All parameters are in-house estimates; DFT-fitted production repulsive potentials are deferred.

GFN2-xTB — 86 elements from the published Grimme-group parameter set. Parameters are fetched on demand at first use (LGPL-3.0 licensed, not bundled — see ADR-002).

PM6 — 82 elements from the bundled MOPAC PM6 parameter cache (Apache-2.0 provenance in the TOML header), with the Stewart 2007 H/C/N/O/F subset still available. The public wrapper auto-selects the MOPAC-derived cache for elements outside H/C/N/O/F.

OMx — 5 elements (H, C, N, O, F) from Dral 2016 Tables 1–3.

# Check element coverage
from vibeqc.semiempirical import SemiempiricalParameters

params = SemiempiricalParameters.dftb0_default()
elements = [Z for Z in range(1, 93) if params.has_element(Z)]
print(f"DFTB covers {len(elements)} elements")

Parameter customisation

DFTB custom parameters

from vibeqc.semiempirical import SemiempiricalParameters

custom = SemiempiricalParameters()
custom.add_element(
    Z=1, on_site=[-0.21], zeta=[1.24],
    hubbard_u=0.42, valence_electrons=1,
)
custom.add_element(
    Z=8, on_site=[-0.89, -0.33], zeta=[2.25, 2.25],
    hubbard_u=0.45, valence_electrons=6,
)
# Set repulsive pair (R⁻¹² form)
custom.set_repulsive_pair_analytic(1, 1, A=5.0)
custom.set_repulsive_pair_analytic(1, 8, A=15.0)
custom.set_repulsive_pair_analytic(8, 8, A=40.0)

model = DFTB0Model(mol, params=custom)

GFN2 parameters

GFN2-xTB parameters are fetched automatically from the Grimme group’s GitHub repository. To force a refresh:

from vibeqc.semiempirical.methods.gfn2_params import load_gfn2_params

params = load_gfn2_params(force_refetch=True)

PM6 parameters

from vibeqc.semiempirical.methods.pm6_params import load_pm6_params

params = load_pm6_params()
model = PM6Model(mol, params=params)

Comparing against external programs

Reference energies from external programs can be obtained via out-of-process subprocess runners (External QC codes (ORCA / Psi4 / others)):

from examples.regression.core.runner_xtb import energy as xtb_energy
from examples.regression.core.runner_mopac import energy as mopac_energy
from examples.regression.core.runner_dftbp import energy as dftbp_energy

print(f"xTB GFN2 H2O:  {xtb_energy('H2O'):.6f} Eh")
print(f"MOPAC PM6 H2O: {mopac_energy('H2O'):.6f} Ha")
print(f"DFTB+ H2O:     {dftbp_energy('H2O'):.6f} Ha")

These runners require the external program to be installed on $PATH (see each runner’s docstring for install instructions).

Performance tips

  • DFTB0 is 3–5× faster than SCC‑DFTB (no SCF loop). Use it for preoptimization where charge self-consistency is less important.

  • DFTB0 gradients are analytic and match finite differences tightly. SCC gradients use a fixed-charge approximation (~0.4 Ha/bohr FD gap).

  • Periodic systems support Gamma-point for all methods; DFTB also supports k-point meshes. Increase the lattice cutoff (cutoff_bohr) for tight cells.

  • Memory is negligible — the basis is minimal (one function per valence shell).

Known limitations

  • DFTB repulsive potentials are in-house R−12 estimates; DFT-fitted production repulsives are deferred.

  • GFN2-xTB still lacks self-consistent D4 and periodic AES image-cell multipole Ewald terms (Method status).

  • PM6 still has known Ha-scale gaps against MOPAC from unresolved core-core / gamma-function details; use MOPAC out-of-process for parity checks.

  • OMx validation against published references is thin; treat as implementation scaffolding with early working paths.

  • Periodic GFN2/NDDO gradients are finite-difference only; analytic periodic NDDO gradients are deferred.

  • MSINDO’s analytic gradients are partially implemented (integral derivatives done; full assembly pending); FD gradients are correct and production-ready. CCM is fully landed for 1-D/2-D/3-D. See MSINDO (semiempirical INDO).