Functionals¶
XC functionals are resolved through libxc
at runtime. Any functional name libxc accepts works: short names
("LDA", "PBE", "B3LYP", "PBE0"), libxc XC_… identifiers,
weighted-sum custom strings ("0.2*HF + 0.8*GGA_X_PW91, GGA_C_PW91"
for PW1PW), and vibe-qc’s own aliases.
⚠️ B3LYP behaviour change at v0.8.0¶
The b3lyp keyword now resolves to libxc id 475 (VWN5 — the
ORCA / ADF convention) rather than id 402 (VWN-RPA, a.k.a.
VWN3 — the libxc default and Gaussian convention).
“B3LYP” is a fixed hybrid recipe; codes differ only in which
Vosko-Wilk-Nusair parametrisation fills the LSDA-correlation
slot. vibe-qc follows the ORCA convention: bare b3lyp is
the VWN5 variant. It’s a noticeable shift for users comparing
pre- vs post-v0.8.0 numbers:
Effect: B3LYP energies move by ~10–15 mHa per heavy atom.
On 10-atom organics, the silent disagreement vs ORCA’s bare
B3LYPwas ~150 mHa pre-fix; post-fix it matches to <1 mHa.
For the Gaussian-compatible VWN3 variant (e.g. for parity
with Gaussian or PySCF’s default b3lyp), pass
functional="b3lyp/g" — vibe-qc’s alias for the VWN3 variant,
mirroring ORCA’s B3LYP / B3LYP/G keyword pair.
(functional="402" or functional="XC_HYB_GGA_XC_B3LYP"
resolve to the same functional.)
To use the default post-v0.8.0 B3LYP explicitly, either
functional="b3lyp" (the default) or
functional="XC_HYB_GGA_XC_B3LYP5" is fine.
Recipe table¶
vibe-qc resolves these short names in xc.cpp::resolve_alias()
(plus everything libxc accepts directly):
Name |
Type |
HF-exchange |
libxc id |
Notes |
|---|---|---|---|---|
|
LDA |
0 % |
1 + 7 |
Slater exchange + VWN5 correlation. Fast sanity check. |
|
GGA |
0 % |
101 + 130 |
Workhorse for solid state. |
|
GGA |
0 % |
106 + 131 |
Classic molecular GGA. |
|
hybrid |
20 % |
475 (was 402) |
de-facto for organics; VWN5 / ORCA convention; see warning above. |
|
hybrid |
20 % |
402 |
Gaussian-compatible B3LYP (VWN3); mirrors ORCA’s |
|
hybrid |
25 % |
406 |
PBE + 25% Fock exchange. |
|
hybrid |
20 % |
weighted-sum |
Bredow’s 1-parameter periodic hybrid; cite Bredow & Gerson PRB 61, 5194 (2000). |
|
meta-GGA |
0 % |
202 + 231 |
Non-empirical τ-dependent MGGA; Tao-Perdew-Staroverov-Scuseria PRL 91, 146401 (2003). |
|
hybrid meta-GGA |
10 % |
457 |
10 % global hybrid of TPSS; Staroverov-Scuseria-Tao-Perdew JCP 119, 12129 (2003). |
|
meta-GGA |
0 % |
203 + 233 |
Pure Minnesota meta-GGA; Zhao-Truhlar JCP 125, 194101 (2006). |
|
hybrid meta-GGA |
54 % |
450 + 236 |
54 % global hybrid for thermochemistry + non-covalent interactions; Zhao-Truhlar TCA 120, 215 (2008). |
|
meta-GGA |
0 % |
263 + 267 |
Strongly-constrained meta-GGA; Sun-Ruzsinszky-Perdew PRL 115, 036402 (2015). Grid-sensitive — use a fine grid (prefer |
|
meta-GGA |
0 % |
497 + 498 |
Re-regularized SCAN — smooth, grid-friendly; Furness et al JPCL 11, 8208 (2020). Recommended default of the family. |
|
hybrid meta-GGA |
25 % |
660 |
25 % global hybrid of r²SCAN (PBE0-like). |
|
hybrid meta-GGA |
10 % |
659 |
10 % global hybrid of r²SCAN (TPSSh-like). |
|
range-sep hybrid |
15.77 %→100 % |
464 |
Long-range-corrected hybrid GGA; Chai-Head-Gordon 2008. ω = 0.3. Direct SCF only (see § Range-separated hybrids). |
|
range-sep hybrid + D |
22.2 %→100 % |
471 |
ωB97X-D — Chai-Head-Gordon 2008. ω = 0.2 + intrinsic CHG dispersion. Use |
|
screened RSH |
25 %→0 % |
428 |
Heyd-Scuseria-Ernzerhof screened hybrid; 25 % HF short-range, 0 % long-range, ω = 0.11. The solid-state band-gap workhorse. |
The full libxc functional set is also reachable directly. Use
the libxc identifier if your shorthand isn’t in the table:
functional="XC_HYB_GGA_XC_M06_2X", functional="XC_GGA_X_RPBE,XC_GGA_C_PBE",
etc.
PW1PW: Bredow’s periodic hybrid¶
pw1pw is the first non-libxc-built-in custom hybrid in
vibe-qc. The functional is:
PW1PW = 0.20 × HF exchange + 0.80 × GGA_X_PW91 exchange + GGA_C_PW91 correlation
Implemented via libxc’s custom-string path:
vibeqc.vibeqc_xc_to_pyscf translates "pw1pw" to
".2*HF + .8*GGA_X_PW91, GGA_C_PW91" for the PySCF-grid V_xc
evaluation in periodic UKS / RKS dispatch.
import vibeqc as vq
result = vq.run_periodic_job(
mgo,
basis="pob-tzvp",
method="RKS",
functional="pw1pw",
kmesh=(4, 4, 4),
output="mgo-pw1pw-444",
)
Cite: Bredow, T.; Gerson, A. R. Phys. Rev. B 61, 5194 (2000). PW1PW is the strict-comparison reference for the Peintinger 2013 SI basis- set paper’s HF + PW1PW totals on ~60 compounds.
Choosing a functional (decision tree)¶
Periodic ionic insulator (oxides, halides, sulphides):
pw1pworb3lyporpbe0for hybrids;pbefor pure GGA. Cite the published reference for the system class.Periodic semiconductor / metal:
pbe(most common). Hybrids hit the dense-Lpq RAM ceiling fast — seemulti_k_scf.md§ Open issues.Molecular organic geometry optimisation:
r²SCAN-3c— the turnkey “Swiss army knife” composite (seecomposites.md) — orb3lypwith D3(BJ) (seemolecules.md) /pbe0for more reactive systems.Molecular thermochemistry: the
r²SCAN-3c/ωB97X-3c/HSE-3ccomposite methods are runnable today (composites.md);pbe0+ def2-TZVP + D3(BJ) is the conventional mid-tier workhorse.Open-shell radicals: prefer
uksdriver overrks. Same functional table works.
⚠️ Plain B3LYP for noncovalent interactions¶
Plain B3LYP (no dispersion correction) systematically under-binds noncovalent interactions by 20–50% on the S22 set. Always pair B3LYP with a dispersion correction when noncovalent interactions matter:
result = vq.run_rks(
mol,
basis="def2-tzvp",
functional="b3lyp",
options=vq.RHFOptions(dispersion="d3bj"), # or "d4"
)
D3(BJ) is the standard. D4 (Caldeweyher-Bannwarth-Grimme, 2019)
ships alongside D3(BJ): use dispersion="d4" to opt in. There
are two D4 backends, the optional dftd4 package (production
default) and an in-tree native MPL-2.0 implementation (opt-in
via compute_d4(mol, func, backend="native") while the
reference dataset is being upgraded). Both are documented in
molecules.md § Dispersion.
Meta-GGA functionals (TPSS / TPSSh, M06-L / M06-2X, SCAN / r²SCAN)¶
vibe-qc evaluates the kinetic-energy density τ(r) = ½ Σ_i |∇ψ_i(r)|² on the DFT grid (using the AO gradients that already power the GGA path), so the τ-dependent meta-GGA family is now available in molecular RKS + UKS:
opts = vq.RKSOptions()
opts.functional = "r2scan" # or tpss / tpssh / m06-l / m06-2x /
# scan / r2scan0 / r2scanh
result = vq.run_rks(mol, basis, opts)
SCAN vs r²SCAN. SCAN (scan) satisfies all 17 exact
constraints a semilocal functional can, but its sharp enhancement
factor is notoriously grid-sensitive — on vibe-qc’s default medium
grid the H₂O/def2-SVP energy sits ~1 mHa off the fine-grid limit.
For SCAN, set a fine grid (opts.grid.n_radial = 120,
opts.grid.lebedev_order = 41 or finer). r²SCAN (r2scan) is
the re-regularized SCAN — same constraint satisfaction, a smooth
enhancement factor, grid-stable to ~µHa on the default grid. It is
the recommended default of the family; r2scan0 (25 % HF) and
r2scanh (10 % HF) are its global hybrids.
Coverage:
Molecular RKS / UKS — closed-shell + open-shell SCF live; parity to PySCF.dft within grid-quadrature noise (~µHa on def2-SVP / medium grid for closed-shell H₂O; ~10–50 µHa on STO-3G /
grids.level=5for O₂ triplet UKS).Periodic SCF — not yet.
cpp/src/periodic_xc.cppwill reject meta-GGA functionals at theFunctional::eval_*call with a clear error pointing here. Periodic τ-grid + V_τ is a follow-up workstream.Analytic gradients — available for molecular RKS + UKS (
vibeqc.compute_gradient_rks/compute_gradient_uks). The XC Pulay force includes the τ term; finite-difference validated to ~3e-9 (TPSS/TPSSh) / ~1e-7 (M06-2X) on H₂/STO-3G. Geometry optimisation with meta-GGAs works end-to-end.Analytic Hessian / CPKS — not yet. The meta-GGA second-derivative kernel (
eval_unpolarised_fxc) raises on MGGA; finite-difference Hessians work as a workaround.Laplacian-dependent meta-GGAs (TB09, …) — not supported. vibe-qc populates τ but not ∇²ρ on the grid; libxc functionals with
XC_FLAGS_NEEDS_LAPLACIANare refused atFunctionalconstruction with a clear error.
Range-separated hybrids (ωB97X, ωB97X-D)¶
A range-separated (CAM) hybrid makes the exact-exchange admixture position-dependent:
EXX(r₁₂) = cam_alpha + cam_beta · erf(ω · r₁₂)
so the exchange operator is
cam_alpha·(1/r₁₂) + cam_beta·(erf(ω·r₁₂)/r₁₂). vibe-qc reads the
(ω, α, β) triple from libxc at construction —
Functional("wb97x").is_range_separated / rsh_omega / cam_alpha / cam_beta — and the SCF driver builds the second, erf-attenuated
exchange matrix K_erf(ω) alongside the ordinary K.
wb97x (Chai-Head-Gordon 2008) is the first range-separated hybrid
in vibe-qc: a long-range-corrected functional — 15.77 % HF at short
range ramping to 100 % HF at long range, ω = 0.3 bohr⁻¹.
opts = vq.RKSOptions()
opts.functional = "wb97x"
result = vq.run_rks(mol, basis, opts)
ωB97X-D — range-separated hybrid + dispersion¶
wb97x-d (Chai-Head-Gordon 2008) is the dispersion-corrected
re-parameterisation of ωB97X (ω = 0.2 bohr⁻¹, 22.2 % HF short-range →
100 % long-range). It has two pieces: the range-separated-hybrid
XC functional (libxc XC_HYB_GGA_XC_WB97X_D), and an intrinsic
empirical “-D” dispersion correction of the older “DFT-D2” family.
The dispersion is geometry-only — no SCF coupling — so the complete
ωB97X-D energy is E_SCF + E_disp. Use the dispatcher
:func:vibeqc.run_wb97x_d for the full total:
result = vq.run_wb97x_d(mol, basis) # closed- or open-shell
print(result.e_total) # E_SCF + E_dispersion
print(result.scf.energy, result.dispersion.energy)
The CHG dispersion is
E_disp = −Σ_{A<B} C6_AB/R^6 · 1/(1 + 6·(R/R0_AB)^-12) with the
Grimme-2006 D2 atomic C6 / vdW-radius tables (H–Xe); a heavier
element raises a clear error. vibeqc.compute_chg_dispersion(mol)
exposes the standalone term. The bare functional="wb97x-d" alias
through run_rks / run_uks gives the XC/SCF part only (the
range-separated hybrid) — the same alias-vs-dispatcher split as
b2plyp / run_b2plyp; use run_wb97x_d for the published total.
Coverage and caveats:
Molecular RKS / UKS energies — live; parity to PySCF.dft at grid-quadrature precision (~µHa, def2-SVP).
Direct SCF only — the erf-attenuated K is built by the direct-SCF Fock kernel.
density_fit=truewith a range-separated functional is rejected with a clear error (the RI path has no erf-attenuated 3-centre integrals yet). The molecular drivers select the direct builder automatically for RSH functionals, so no user action is needed — just leavedensity_fitat its default.Hard open-shell radicals — ωB97X’s 100 % long-range HF makes open-shell SCF stiffer. O₂, CH₃, and atomic radicals converge with the defaults; an orbital-near-degenerate case such as the OH ²Π radical can plateau near the gradient tolerance with plain DIIS — set
opts.level_shift = 0.5to converge it cleanly (standard QC practice for stiff open-shell SCF).Newton / TRAH second-order acceleration is disabled for RSH functionals (their orbital-Hessian exchange response is not yet range-separation aware); DIIS + SOSCF + the quadratic fallback carry convergence.
Analytic gradients for RSH functionals are not yet available (finite-difference works). ωB97X-V and periodic RSH are queued — see below.
HSE06 — screened range-separated hybrid¶
hse06 (Heyd, Scuseria, Ernzerhof; the Krukau-Vydrov-Izmaylov-
Scuseria 2006 re-parameterisation, libxc XC_HYB_GGA_XC_HSE06) is a
screened RSH: 25 % HF at short range tapering to 0 % at long
range — the opposite ramp direction to ωB97X. In vibe-qc’s erf-form
CAM representation this is cam_alpha = +0.25, cam_beta = −0.25
(EXX(r→0) = 0.25, EXX(r→∞) = 0), so it runs through the same
erf-attenuated-K machinery as ωB97X — just with a negative long-range
coefficient. No separate erfc kernel is needed.
opts = vq.RKSOptions()
opts.functional = "hse06"
result = vq.run_rks(mol, basis, opts)
HSE06 is primarily a solid-state band-gap functional; molecular HSE06 is available here, periodic HSE06 follows once periodic RSH lands.
Queued (not yet shipped)¶
These functional families are designed but not in the v0.8.0
cut. Track at
docs/roadmap.md § XC functional library
expansion:
Range-separated hybrids — molecular
wb97x,wb97x-d(viavibeqc.run_wb97x_d) andhse06ship now (see § Range-separated hybrids above). Still queued: ωB97X-V / ωB97M-V (need the VV10 non-local correlation), RSH analytic gradients, RSH + density fitting, and periodic RSH.r²SCAN family — molecular
scan/r2scan/r2scan0/r2scanhship now (see § Meta-GGA functionals above). Still queued: periodic SCAN / r²SCAN (needs periodic meta-GGA support incpp/src/periodic_xc.cpp).Composite “3c” methods — r²SCAN-3c, ωB97X-3c, and HSE-3c are runnable today (turnkey: functional + matching basis + gCP + D4 in one call); B3LYP-3c / B97-3c / PBEh-3c are
PENDING_GCP_DATA(the framework is wired, the per-basis gCP tables are pending). Seecomposites.mdfor the recipe table, status flags, and worked examples.Double hybrids — B2PLYP (Grimme 2006), DSD-PBEP86 (Kozuch-Martin 2011), and PWPB95 (Goerigk-Grimme 2011) ship now via
vibeqc.run_b2plyp/vibeqc.run_dsd_pbep86/vibeqc.run_pwpb95, withvibeqc.run_double_hybrid(name, …)as the generic dispatcher. PWPB95 is vibe-qc’s first meta-GGA double hybrid and its first spin-opposite-scaled one (the same-spin MP2 coefficient is zero). The SCS-MP2 / SOS-MP2 machinery the double-hybrid line rides is also live; see the MP2 and double hybrids page. ωB97M(2) (range-separated meta-GGA double hybrid) remains blocked: it builds on ωB97M-V, which needs the VV10 non-local correlation functional vibe-qc does not yet implement (see the range-separated-hybrids bullet above — the same VV10 gap blocks ωB97X-V / ωB97M-V). D4 dispersion ships via the optionaldftd4package — passdispersion="d4"torun_b2plyp/run_dsd_pbep86/run_pwpb95for the publishedX-D4total, or callvibeqc.compute_d4directly for arbitrary functionals. D3(BJ) is also wired through the molecular runner via the existingvibeqc.compute_d3bjmachinery.
Programmatic access¶
from vibeqc import Functional
fn = Functional("PBE0")
print(fn.hf_exchange_fraction()) # 0.25
print(fn.kind()) # XCKind.GGA (well, GGA-hybrid)
# Custom libxc composition strings (comma-separated; X then C):
fn = Functional("XC_LDA_X,XC_LDA_C_VWN") # explicit Slater + VWN
fn = Functional("XC_GGA_X_PBE,XC_GGA_C_PBE") # PBE from separate parts
# Weighted-sum custom strings (PW1PW pattern):
fn = Functional("0.2*HF + 0.8*GGA_X_PW91, GGA_C_PW91")
The Functional ctor docstring lists every known short alias
the resolver accepts.
Citations¶
Every run_job call writes a {stem}.bibtex and
{stem}.references sibling alongside {stem}.out, pre-assembled
with all the per-functional papers your job needs to cite. The list
below is the human-readable equivalent of what the runtime emits;
look at the auto-generated files first.
B3LYP: Becke, J. Chem. Phys. 98, 5648 (1993); Lee, Yang, Parr, Phys. Rev. B 37, 785 (1988); Stephens, Devlin, Chabalowski, Frisch, J. Phys. Chem. 98, 11623 (1994); Vosko, Wilk, Nusair, Can. J. Phys. 58, 1200 (1980) (the VWN5 correlation now used post-v0.8.0).
PBE: Perdew, Burke, Ernzerhof, Phys. Rev. Lett. 77, 3865 (1996).
PBE0: PBE 1996 above plus Adamo, Barone, J. Chem. Phys. 110, 6158 (1999).
PW91 / PW1PW: Perdew, Chevary, Vosko, Jackson, Pederson, Singh, Fiolhais, Phys. Rev. B 46, 6671 (1992); Bredow, Gerson, Phys. Rev. B 61, 5194 (2000) for the PW1PW hybrid mixing.
B2PLYP (and other double hybrids): Grimme, J. Chem. Phys. 124, 034108 (2006), plus the B3LYP components above.
TPSS / TPSSh: Tao, Perdew, Staroverov, Scuseria, Phys. Rev. Lett. 91, 146401 (2003); Staroverov, Scuseria, Tao, Perdew, J. Chem. Phys. 119, 12129 (2003) for the 10 % global-hybrid (TPSSh) variant.
M06-L / M06-2X: Zhao, Truhlar, J. Chem. Phys. 125, 194101 (2006) (M06-L, pure meta-GGA); Zhao, Truhlar, Theor. Chem. Acc. 120, 215 (2008) (Minnesota M06 family, including the 54 %-hybrid M06-2X).
SCAN: Sun, Ruzsinszky, Perdew, Phys. Rev. Lett. 115, 036402 (2015).
ωB97X: Chai, Head-Gordon, J. Chem. Phys. 128, 084106 (2008).
ωB97X-D (and its CHG / DFT-D2-type dispersion): Chai, Head-Gordon, Phys. Chem. Chem. Phys. 10, 6615 (2008); the D2 atomic C6 / vdW-radius set is Grimme, J. Comput. Chem. 27, 1787 (2006).
HSE06: Heyd, Scuseria, Ernzerhof, J. Chem. Phys. 118, 8207 (2003); erratum ibid. 124, 219906 (2006); Krukau, Vydrov, Izmaylov, Scuseria, J. Chem. Phys. 125, 224106 (2006) (the “06” re-parameterisation).
r²SCAN (and
r2scan0/r2scanh): Furness, Kaplan, Ning, Perdew, Sun, J. Phys. Chem. Lett. 11, 8208 (2020); erratum ibid. 11, 9248 (2020).D3(BJ) / D4 dispersion: Grimme, Antony, Ehrlich, Krieg, J. Chem. Phys. 132, 154104 (2010); Grimme, Ehrlich, Goerigk, J. Comput. Chem. 32, 1456 (2011) (BJ damping extension); Caldeweyher, Bannwarth, Grimme, J. Chem. Phys. 150, 154122 (2019).
libxc itself: Lehtola, Steigemann, Oliveira, Marques, SoftwareX 7, 1 (2018).
Pre-v0.8.x workflows hand-curated this list from
docs/citing.md. The runtime database now does it
for you — see the
citations user guide for the full schema, the
auto-citations tutorial for the
end-to-end manuscript workflow, and
AGENTS.md § “Citation database ownership”
for the rule on keeping the database in sync when adding a new
functional.
See also¶
density_fitting.md— JKBuilderRIJCOSX (the right Fock build for big-system hybrid DFT).
multi_k_scf.md— KRHF / KRKS multi-k periodic SCF. PW1PW + B3LYP + PBE0 work at multi-k via the KRKS driver.molecules.md— molecular SCF + dispersion + analytic gradients.scf_convergence.md— DIIS / EDIIS hybrid + level-shift / quadratic-fallback for stiff functionals.