Skip to main content

PM6 semiempirical method (pm6-rs) with a Python-native API and an ASE calculator, including PM6-D3/D3H4/D3H4X corrections

Project description

pm6-rs

Rust-native implementation of the PM6 semiempirical NDDO method (J. J. P. Stewart, J. Mol. Model. 13, 1173 (2007)). Non-periodic heats of formation, fully analytic nuclear gradients and Hessians, L-BFGS geometry optimization, P-RFO transition-state search, and the PM6-D3 / PM6-D3H4 / PM6-D3H4X post-SCF corrections, with Rust, Python-native and ASE APIs.

  • Author: ss0832
  • License: GPL-3.0-or-later
  • Pure Rust linear algebra (faer + rayon); no LAPACK/BLAS.

Scope and validation status

Validated against the MOPAC v23.2.5 oracle (openmopac/mopac, Apache-2.0); parameters are extracted from the same release.

Capability Status
SCF energy (RHF + UHF), heats of formation ✅ frozen molecular set; s/p ≤1e-6, hypervalent/TM ≤1e-4 kcal/mol vs MOPAC; see limitations below
d-orbital two-center integrals (S, P, Cl, transition metals, …) ✅ e.g. TiCl₄ ≤2e-5, HCl ≤1e-8 kcal/mol
Analytic gradient (dual-number, Hellmann–Feynman) ✅ s/p and d, matches MOPAC & FD
Analytic Hessian + frequencies ✅ closed-shell s/p/d CPHF; open-shell d uses FD-of-analytic-gradient
L-BFGS geometry optimization ✅ all elements, matches MOPAC minima
Mulliken charges, dipole ✅ (≤1e-5 e / ≤1e-4 D)
Lanthanide sparkles (Ce…Yb) ⚠️ functional (0-orbital cores, oracle-derived ΔH_f); energy ~10 kcal/mol from MOPAC
D3 dispersion (PM6-D3) ⚠️ implemented, ~0.25 kcal/mol vs MOPAC
H4 / X corrections (PM6-D3H4 / -D3H4X) ⚠️ implemented per source; full PM6-D3H4 parity pending
Python native + ASE APIs (energy/grad/forces/Hessian/opt/freq)
PBC ⛔ out of scope (PM6 is molecular)

✅ = validated to the stated tolerance; ⚠️ = implemented and functional, not yet bit-exact. See docs/scope.md and THIRD_PARTY_NOTICES.md.

Units

Internal computation uses eV and Bohr with MOPAC's 2018-CODATA model constants (src/constants.rs). At the boundaries:

  • Rust and Python-native APIs return atomic units (Hartree, Bohr), plus convenience eV fields and ΔH_f in kcal/mol.
  • The ASE calculator uses eV / Å (PM6 is natively eV, so no round-trip).

Build

cargo build --release        # library + pm6_rs_cli
cargo test                   # unit + MOPAC-oracle regression tests

CLI

pm6_rs_cli energy      water.xyz
pm6_rs_cli gradient    water.xyz
pm6_rs_cli optimize    water.xyz            # writes water.pm6opt.xyz
pm6_rs_cli frequencies water.pm6opt.xyz
pm6_rs_cli charges     water.xyz --charge 0 --multiplicity 1
pm6_rs_cli energy      dimer.xyz --method PM6-D3H4X   # PM6 | PM6-D3 | PM6-D3H4 | PM6-D3H4X

Rust API

use pm6_rs::{Molecule, Pm6Parameters, Pm6Options, run_pm6};

let mol = Molecule::from_xyz_file("water.xyz", 0.0)?;
let params = Pm6Parameters::standard()?;
let r = run_pm6(&mol, &params, &Pm6Options::default())?;
println!("ΔHf = {} kcal/mol", r.heat_of_formation_kcal);

Python

pip install maturin
maturin develop --release --features python   # or: pip install pm6-rs-python
import pm6_rs
import numpy as np

numbers = [8, 1, 1]
positions = np.array([[0.0, 0.0, 0.0], [0.9584, 0.0, 0.0], [-0.24, 0.9278, 0.0]])

# charge, multiplicity and reference ("auto"/"rhf"/"uhf") are per-call arguments.
out = pm6_rs.single_point(numbers, positions, charge=0.0, multiplicity=1, reference="auto")
print(out["heat_of_formation_kcal"], out["charges"])

g = pm6_rs.gradient(numbers, positions)          # dE/dR (Hartree/Bohr and eV/Å)
f = pm6_rs.forces(numbers, positions)            # −dE/dR
h = pm6_rs.hessian(numbers, positions)           # Hartree/Bohr², 3N×3N
w = pm6_rs.frequencies(numbers, positions)       # cm⁻¹ (evaluate at a minimum)

ASE

from ase.build import molecule
from pm6_rs.ase import PM6

atoms = molecule("H2O")
atoms.calc = PM6(charge=0, multiplicity=1, reference="auto")
print(atoms.get_potential_energy())   # eV
print(atoms.get_forces())             # eV/Å
print(atoms.calc.get_gradient())      # eV/Å  (= −forces)
print(atoms.calc.get_hessian())       # eV/Ų, 3N×3N

References

  • J. J. P. Stewart, J. Mol. Model. 13, 1173 (2007) — PM6.
  • W. Thiel, A. A. Voityuk, J. Phys. Chem. 100, 616 (1996) — MNDO-d.
  • S. Grimme et al., J. Chem. Phys. 132, 154104 (2010) — D3.
  • J. Řezáč, P. Hobza, J. Chem. Theory Comput. 8, 141 (2012) — H4.
  • J. J. P. Moussa, J. J. P. Stewart, J. Open Source Softw. 11(119), 8025 (2026) — MOPAC.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pm6_rs_python-0.1.2.tar.gz (515.0 kB view details)

Uploaded Source

File details

Details for the file pm6_rs_python-0.1.2.tar.gz.

File metadata

  • Download URL: pm6_rs_python-0.1.2.tar.gz
  • Upload date:
  • Size: 515.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.9

File hashes

Hashes for pm6_rs_python-0.1.2.tar.gz
Algorithm Hash digest
SHA256 c7267d4fb5ae84543f657a12a20a1105e87e7ba9ab36c7aabac0d395f60ee1e8
MD5 eee66aa25ef0343ef2e52f9ad1853f6b
BLAKE2b-256 85ba2a79eab643da6494baadead40db4f19e150cb0e36aaf58ebdb14d7f32be7

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page