pm7-rs
pm7-rs is a Rust implementation of the PM7 semiempirical NDDO method and its PM7-TS,
PM7-minus, PM7-HH, and Sparkle/PM7 methods, for molecules and for periodic systems in one, two
and three dimensions. It provides RHF/UHF energies, heats of formation, Mulliken charges,
analytic gradients, analytic stress, Hessians, phonons, geometry optimization, harmonic
frequencies, a linear-scaling divide-and-conquer SCF, a CLI, and Python/ASE interfaces.
The parameter tables are generated from a pinned MOPAC v23.2.5 source tree. The implementation
uses faer for dense eigensolvers and rayon for deterministic pair- and coordinate-level
parallelism. The project is GPL-3.0-or-later.
Status and physical scope
- Full minimal-valence s/p/d MNDO/d kernel for supported PM7 elements.
- PM7 dispersion, EH+ hydrogen-bond correction, and PM7-HH H-H correction — all periodic.
- RHF and UHF with explicit
ScfReference::{Auto, Restricted, Unrestricted}control. - Forward-mode AD gradients and AD/CPHF Hessians for RHF and UHF.
- SCF stability analysis (Seeger–Pople), on the same orbital Hessian the CPHF already applies:
is the converged solution a minimum, or only a stationary point? Singlet and triplet channels,
and — opt-in — an escape along the unstable direction that keeps whichever solution is lower.
It removes the classic RHF dissociation failure: stretched H₂ goes from 121.6 kcal/mol above
two hydrogen atoms to within 0.02 of them.
⟨S²⟩is reported for every unrestricted solution. Off by default. - Sparkle/PM7 lanthanide sites and PM7-family parameter selection.
- Periodic boundary conditions in 1-D, 2-D and 3-D: Gamma point and Monkhorst-Pack k meshes,
neutral and charged cells, energy, analytic gradient, analytic stress, analytic zone-centre
force constants. See
docs/pbc.md. - Phonons and perturbation theory at arbitrary wavevector (an NDDO density-functional
perturbation theory coupling
kwithk + q), for restricted, unrestricted and smeared metallic cells, plus band structures along a k path. - Molecular properties: a uniform external electric field with an exact analytic gradient and
Hessian, a corrected dipole with its terms reported separately, orbital energies and
coefficients, IR spectra, and Molden output. See
docs/properties.md. - Born effective charges, the polarizability, both dielectric tensors and LO–TO splitting, from
the same perturbation solver with a homogeneous field taken through the commutator
[H, r]. The electroniceps^infin 3-D and, with an assigned extent, for a chain or a slab; the staticeps^0with the ionic term added. - Berry-phase polarization and a finite field along a lattice vector (the Nunes-Gonze electric enthalpy), which exist as independent checks on the perturbative field response: the finite-field polarizability agrees with the CPHF one to a ratio of 1.0063 on two formalisms sharing only the SCF.
- Divide and conquer: a linear-scaling SCF with gradient and stress, measured log-log slope
0.99 above 200 atoms. See
docs/divide_and_conquer.md.
Two limits worth knowing before you start: sampling a small cell at the Gamma point alone gets
the exchange quantitatively wrong, not merely coarse (29 eV/atom for a two-atom diamond
cell), so use a k mesh; and the EH+ hydrogen-bond gradient diverges when the acceptor's dihedral
axis goes collinear, which is a defect in PM7's published functional form rather than in this
implementation. Both are measured in docs/scope.md and
docs/singularities.md.
PM7 is an empirical semiempirical model; agreement with a MOPAC implementation does not imply ab-initio accuracy outside the model's parameterization domain. Hydrogen-bond topology is perceived from geometry and its derivatives are evaluated at fixed topology, so a topology change is a piecewise-smooth boundary. At the singular orientation of a two-center local frame, the value remains analytic and a localized symmetric finite-difference fallback supplies that pair's derivative. A residual of up to about 0.36 kcal/mol is still known for some four-coordinate, highly d-populated transition-metal compounds such as TiF4.
Build and test
Rust 1.82 or newer is required.
$env:CARGO_BUILD_JOBS = '1'
cargo test --all-targets --all-features
cargo clippy --all-targets --all-features -- -D warnings
cargo build --release
Release builds use Fat LTO and one codegen unit as a project policy, prioritizing calculation throughput:
cargo build --release
Rust API
use pm7_rs::{run_pm7, Molecule, Pm7Options, Pm7Parameters, Pm7Method};
let molecule = Molecule::from_xyz_file("examples/water.xyz", 0.0)?;
let method = Pm7Method::Pm7;
let parameters = Pm7Parameters::method(method)?;
let options = Pm7Options {
method,
charge: 0.0,
multiplicity: 1,
..Pm7Options::default()
};
let result = run_pm7(&molecule, ¶meters, &options)?;
println!("Delta Hf = {:.6} kcal/mol", result.heat_of_formation_kcal);
# Ok::<(), pm7_rs::Pm7Error>(())
Pm7Parameters and Pm7Options must select the same method. Coordinates stored in Molecule
are Bohr; XYZ input is read as Angstrom. Energies are eV and gradients are eV/Bohr unless a
field documents another unit.
CLI
cargo run --release --bin pm7_rs_cli -- energy examples/water.xyz --json
cargo run --release --bin pm7_rs_cli -- gradient examples/methane.xyz
cargo run --release --bin pm7_rs_cli -- energy examples/methyl.xyz --multiplicity 2
cargo run --release --bin pm7_rs_cli -- frequencies examples/water.xyz --ir
cargo run --release --bin pm7_rs_cli -- forces examples/methane.xyz
cargo run --release --bin pm7_rs_cli -- hessian examples/water.xyz
cargo run --release --bin pm7_rs_cli -- molden examples/water.xyz -o water.molden
cargo run --release --bin pm7_rs_cli -- energy examples/water.xyz --field 0.5,0,0
Periodic modes take the cell from an extended-XYZ Lattice="..." key — which is what
atoms.write() produces in ASE — or from --cell:
cargo run --release --bin pm7_rs_cli -- energy diamond.xyz --kpoints 4 4 4
cargo run --release --bin pm7_rs_cli -- stress diamond.xyz --kpoints 4 4 4
cargo run --release --bin pm7_rs_cli -- phonons diamond.xyz --supercell 2 2 2 --qpoints 0,0,0 0.5,0,0
cargo run --release --bin pm7_rs_cli -- dfpt diamond.xyz --kpoints 4 4 4 --qpoints 0.3,-0.15,0.42
cargo run --release --bin pm7_rs_cli -- born diamond.xyz --kpoints 4 4 4 --lo-to 1,0,0
cargo run --release --bin pm7_rs_cli -- bands diamond.xyz --kpoints 4 4 4 --qpoints 0,0,0 0.5,0,0
cargo run --release --bin pm7_rs_cli -- dielectric bn_sheet.xyz --slab-thickness 3.33 --kpoints 4 4 1
cargo run --release --bin pm7_rs_cli -- energy chain.xyz --cell 3.2,0,0
cargo run --release --bin pm7_rs_cli -- energy slab.xyz --cell 3.2,0,0,0,0,12,0,3.2,0 --pbc TFT
cargo run --release --bin pm7_rs_cli -- optimize diamond.xyz --kpoints 2 2 2 --opt-cell
cargo run --release --bin pm7_rs_cli -- energy big.xyz --dandc 15.0
--opt-cell relaxes the lattice as well as the atoms, driven by the analytic stress. Without it a
periodic optimize reports success with whatever stress the fixed cell implies — diamond at
a = 3.75 Å comes back converged after one iteration with −29.6 GPa standing.
--pbc takes any per-axis pattern; the lattice vectors are reordered so the periodic ones lead,
and --kpoints, --supercell and fractional --qpoints move with them.
--stability check|follow asks whether the converged SCF is a minimum rather than merely a
stationary point, and — with follow — escapes it. Off by default:
cargo run --release --bin pm7_rs_cli -- energy h2_stretched.xyz # 225.79 kcal/mol
cargo run --release --bin pm7_rs_cli -- energy h2_stretched.xyz --stability follow # 104.19, two H atoms
pm7_rs_cli with no arguments prints every mode and flag. Both command lines offer the same fifteen
modes — energy, charges, gradient, forces, stress, optimize, frequencies, hessian,
phonons, dfpt, born, bands, orbitals, molden, dielectric — and the same flags, both
enumerated by tests to keep it that way.
Python and ASE
Build the extension with maturin:
python -m pip install maturin
maturin develop --release --features python
Installing from PyPI also puts a pm7-rs command on your path, covering every mode the Rust
binary does (the Rust binary is not shipped inside the wheel):
pip install pm7-rs-python
pm7-rs energy water.xyz --json
pm7-rs phonons diamond.xyz --supercell 2 2 2 --qpoints 0,0,0 0.5,0,0
python -m pm7_rs is the same entry point, and works even when the scripts directory is not on
PATH.
The native Python API accepts Angstrom coordinates and exposes both atomic-unit and eV/Angstrom
results:
from pm7_rs import native
numbers = [8, 1, 1]
positions = [[0.0, 0.0, 0.0], [0.9584, 0.0, 0.0], [-0.24, 0.9278, 0.0]]
point = native.single_point(numbers, positions, method="pm7")
force = native.forces(numbers, positions, method="pm7")
print(point["heat_of_formation_kcal"])
print(force["forces_ev_per_angstrom"])
The ASE calculator follows ASE's eV/Angstrom conventions. Force evaluations reuse the energy from the gradient calculation and therefore require one SCF, rather than a separate energy SCF followed by a gradient SCF.
from ase.build import molecule
from pm7_rs.ase import PM7
atoms = molecule("H2O")
atoms.calc = PM7(charge=0, multiplicity=1, reference="auto", method="pm7")
energy_ev = atoms.get_potential_energy()
forces_ev_per_angstrom = atoms.get_forces()
Calculation-time memory and performance controls
Before dense SCF or CPHF allocations, the library estimates calculation-time peak memory. The budget is resolved in this order:
Pm7Options::max_memory_mb- the
PM7_MEM_BUDGET_MBenvironment variable - 80% of currently available physical RAM on Windows/Linux
If the estimate exceeds the budget, the calculation returns Pm7Error::InsufficientMemory
instead of relying on the operating system's OOM handling. The Fock builder processes at most
2048 atom-pair contribution blocks at a time, and the large-stack EH+ Hessian pool is capped at
four workers. Finite-difference Hessian validation also derives its concurrent SCF-column count
from the same memory budget instead of launching one full SCF per Rayon worker. Set
RAYON_NUM_THREADS to control the upper bound on global parallelism.
For very large Hessians, Pm7Options::exchange_cutoff = Some((inner, outer)) enables a smooth
long-range exchange approximation in the CPHF response build. Distances are Bohr, Coulomb terms
are never cut, and None is the exact default.
MOPAC validation
Fixed-geometry results compared with the official MOPAC v23.2.5 executable. The oracle scripts in
tools/oracle/ regenerate these against a real MOPAC install and currently report a difference of
0.0000 kcal/mol on every molecule they cover:
| System | pm7-rs (kcal/mol) | MOPAC (kcal/mol) |
|---|---|---|
| H2O | -57.78933784 | -57.78934 |
| CH4 | -14.39979910 | -14.39980 |
| H2S | -3.05174959 | -3.05175 |
| CH3 doublet | 28.46324808 | 28.46325 |
The regression suite also covers PM7 methods, d-shell species, Sparkle/PM7 fluorides, hydrogen-bond corrections, SCF-basin selection, all supported element pairs, and gradient/Hessian finite-difference checks.
tools/oracle/baseline.py carries 176 cases covering all 73 elements PM7 is parameterized
for — a contract enforced by reading src/data/pm7_elements.csv, not a comment — across five
multiplicities, charges −2 to +2 and sixteen organometallics. It compares the heat of formation,
every Mulliken charge, both frontier channels, the dipole and ⟨S²⟩, at MOPAC's printed precision:
1057 of 1086 comparisons pass, and docs/fidelity.md accounts for each of the
29 that do not, case by case.
References
- J. J. P. Stewart, “Optimization of parameters for semiempirical methods VI: more modifications to the NDDO approximations and re-optimization of parameters,” J. Mol. Model. 19, 1-32 (2013). doi:10.1007/s00894-012-1667-x
- J. E. Moussa and J. J. P. Stewart, “MOPAC: An open-source semiempirical molecular orbital program,” J. Open Source Softw. 11, 8025 (2026). doi:10.21105/joss.08025
- M. Korth, “Third-Generation Hydrogen-Bonding Corrections for Semiempirical QM Methods and Force Fields,” J. Chem. Theory Comput. 6, 3808-3816 (2010). doi:10.1021/ct100408b
- A. H. Larsen et al., “The atomic simulation environment-a Python library for working with atoms,” J. Phys.: Condens. Matter 29, 273002 (2017). doi:10.1088/1361-648X/aa680e
- G. Zhou et al., “Graphics Processing Unit-Accelerated Semiempirical Born Oppenheimer Molecular Dynamics Using PyTorch,” J. Chem. Theory Comput. 16, 4951-4962 (2020). doi:10.1021/acs.jctc.0c00243
Software sources: MOPAC v23.2.5,
ASE, faer, and
Rayon. Parameter and code provenance details are recorded in
THIRD_PARTY_NOTICES.md.
Metadata
Release files for pm7-rs-python 0.2.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| pm7_rs_python-0.2.4.tar.gz | 1.0 MB | Without provenance | Details for pm7_rs_python-0.2.4.tar.gz |
Release files / pm7_rs_python-0.2.4.tar.gz
| Download URL | pm7_rs_python-0.2.4.tar.gz |
|---|---|
| Size | 1.0 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
afe4dd65ec9f70116519a5f94b13723167fcf69e82d7cf4dd620cf5487b5be9f
|
|
BLAKE2b-256 checksum How to use checksums |
42f6b9ae6836229938b031f1c15f697cb1dcbe72b71bef981067c003b45d0890
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.9
|
Security for pm7-rs-python 0.2.4
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.