A pure-Rust library of exchange–correlation (XC) functionals for density-functional theory (DFT) — a libxc-compatible reimplementation with no C dependency, no build-time toolchain requirements, and trivial cross-compilation.
Given a density (and, depending on the functional, its gradient and/or kinetic
energy density), xcx returns the XC energy per particle, its first and
second derivatives (vxc and fxc), plus rich metadata (family, input
requirements, exact-exchange fraction, range-separation and VV10 parameters).
Each functional is written once as a single scalar energy expression;
derivatives are obtained by forward-mode automatic differentiation
(num-dual), so they are correct by
construction. Functional IDs and names match libxc for drop-in interoperability.
xcx maps `(rho, sigma, tau[, lapl]) → energy density + derivatives + metadata
- linear mixing
and nothing else. It deliberately contains **no** integration grids, atomic-orbital evaluation, SCF driver, or dispersion correction. For hybrids and VV10 it **exposes the parameters** (EXX fraction, CAM ω/α/β, VV10 b/C) so the host electronic-structure code can build those terms;xcx` never computes the exact-exchange or nonlocal-correlation integrals.
See docs/api-convention.md for the full,
semver-stable data/ABI contract.
[dependencies]
xcx = "0.2"MSRV: Rust 1.87.
use xcx::{Functional, FunctionalId, Spin, XcInput};
fn main() -> Result<(), xcx::XcError> {
// Spin-unpolarized LDA exchange over three grid points.
let f = Functional::new(FunctionalId::LdaX, Spin::Unpolarized)?;
let rho = [0.1_f64, 0.2, 0.3];
let out = f.eval(rho.len(), &XcInput::lda(&rho))?;
// out.exc[i] = XC energy per particle ε_xc at point i
// out.vrho[i] = ∂(n·ε_xc)/∂n at point i
println!("{:?}", out.exc);
Ok(())
}All with energy, all first derivatives, and second derivatives (fxc), in
both spin-polarized and unpolarized modes. The parenthesised number is the
libxc functional id.
| Family | Functional | libxc id | Notes |
|---|---|---|---|
| LDA | lda_x |
1 | Slater exchange |
| LDA | lda_c_pw |
12 | PW92 correlation |
| LDA | lda_c_vwn |
7 | VWN5 |
| LDA | lda_c_vwn_3 |
30 | VWN3 |
| LDA | lda_c_vwn_rpa |
8 | VWN5 (RPA) |
| GGA | gga_x_pbe |
101 | PBE exchange |
| GGA | gga_x_pbe_r |
102 | revPBE exchange |
| GGA | gga_x_pbe_sol |
116 | PBEsol exchange |
| GGA | gga_x_rpbe |
117 | RPBE exchange (exponential enhancement) |
| GGA | gga_c_pbe |
130 | PBE correlation |
| GGA | gga_c_pbe_sol |
133 | PBEsol correlation |
| GGA | gga_x_b88 |
106 | Becke 88 exchange |
| GGA | gga_c_lyp |
131 | Lee–Yang–Parr correlation |
| meta-GGA | mgga_x_tpss |
202 | TPSS exchange |
| meta-GGA | mgga_c_tpss |
231 | TPSS correlation |
| meta-GGA | mgga_x_r2scan |
497 | r²SCAN exchange |
| meta-GGA | mgga_c_r2scan |
498 | r²SCAN correlation |
| meta-GGA | mgga_x_m06_l |
203 | M06-L exchange |
| meta-GGA | mgga_c_m06_l |
233 | M06-L correlation |
| Hybrid | hyb_gga_xc_b3lyp |
402 | B3LYP — uses VWN_RPA (matching libxc 402) |
| Hybrid | hyb_gga_xc_b3lyp5 |
475 | B3LYP/VWN5 |
| Hybrid | hyb_gga_xc_pbeh |
406 | PBE0 |
Range-separated (CAM) hybrids and the meta-GGA Laplacian (lapl) path are
planned via the same AD framework.
Correctness is checked two ways:
- Public, dependency-free tests (run in CI, no libxc needed): finite-difference self-consistency of derivatives, polarized/unpolarized consistency, analytic spot-checks, and a fuzz gate asserting finite energy and every derivative component (no NaN/Inf/panic) across the physical input range for all functionals, both spins.
- Golden cross-check vs. libxc (
crates/xcx-validation, never published): values are compared against snapshots generated from a pinned conda-forge libxc (6.1.0) to ≤ 1e-10 relative, plus an end-to-end SCF cross-check on real integration grids. The snapshots are committed, so CI runs deterministically without libxc present.
This is a Cargo workspace with two crates:
crates/xcx— the published library. Its only dependencies arenum-dualandnalgebra; it carries no C/FFI surface of any kind.crates/xcx-validation— an unpublished (publish = false) crate that cross-checksxcxagainst the reference C libxc. The libxc FFI (libloading, behind thelibxc-ffifeature), the committed reference snapshots, and the snapshot-regeneration tools all live here on purpose, so the publishedxcxcrate stays dependency-light and its packaged artifact can never include test data. Seecrates/xcx-validation/README.md.
The everyday xcx tests (unit, finite-difference, and the fuzz gate) live in
crates/xcx itself and run in CI without libxc.
xcx aims to reproduce pinned libxc to ≤ 1e-10, even where libxc is the less
accurate of the two — faithfulness beats "being right" so results are
interchangeable. The handful of intentional, documented numerical divergences
(all outside the physically-relevant domain or below the golden tolerance) are
described in docs/api-convention.md.
Licensed under the Mozilla Public License 2.0 (LICENSE),
matching upstream libxc. MPL-2.0 is file-level copyleft: you may depend on
xcx from MIT/Apache/proprietary projects freely; only modifications to xcx's
own source files must remain under the MPL. Portions are derived from libxc; see
NOTICE for attribution and per-file provenance.
See CONTRIBUTING.md. All contributions are made under the MPL-2.0;
new functionals must be golden-verified against libxc.