feat: pbc.lo - native Maximally Localized Wannier Functions#190
Conversation
Native PySCF/NumPy/SciPy implementation of MLWFs (Marzari-Vanderbilt 1997) with SMV disentanglement (Souza-Marzari-Vanderbilt 2001). Entry point is pyscf.pbc.lo.kernel(kmf, proj_guess, ...) returning plain-tuple (U, centers, spreads, omega_i, omega_d, omega_od, converged). See pyscf-forge PR for full description, module layout, and cross-validation against wannier90.x v4.0.0 (agreement to 6-7 decimals on H2 isolated and entangled cases).
|
Thanks for this PR! Native MLWFs in PySCF will be great to have. A few quick questions, though I admit I haven't read the code super closely.
|
|
Thanks for the review! FFTDF vs GDF. Works the same with both, the pipeline never touches lo.boys. Boys minimizes ⟨r²⟩ − |⟨r⟩|² with real position-operator integrals; in PBC the position operator isn't well-defined, so MV replaces it with the finite-difference expression in M_mn(k, b) that couples k-points. Boys' CIAH-driven |
feat:
pbc.lo— native Maximally Localized Wannier FunctionsAdds a pure-Python MLWF implementation (NumPy/SciPy) as
pyscf.pbc.lo.kernel(kmf, proj_guess, ...). Takes a converged k-pointmean-field object and returns the Wannier gauge, centers, spreads, and
the Ω_I + Ω_OD + Ω_D decomposition. Algorithm is MV 1997 (PRB 56,
12847) plus SMV 2001 (PRB 65, 035109) for entangled bands. No
libwannier90 / Fortran dependency — everything flows from
kmf.mo_coeff,no file I/O at runtime.
Usage
Projection dicts use standard
(l, m)(no Wannier90m_r/ axisconventions to juggle). Supports s/p/d and arbitrary hybrids. Centers
Bohr, spreads Bohr², energy windows Hartree. Collinear only — call
twice with
spin=0/spin=1for UHF.Layout
Validation
42 unit tests covering each stage of the pipeline, plus 2 optional
end-to-end tests that drive a compiled
wannier90.xon inputs emittedfrom our side (
.mmn/.amn/.eig/.win) and compare finalcenters/spreads. Enable with
W90_EXE=/path/to/wannier90.x; skippedotherwise.
2×2×2 H₂ crystal (8 Bohr cubic, STO-3G):
Agreement to 6–7 decimals on both paths.
Running tests
Not included / known limits
dis_froz(frozen inner window) — raisesNotImplementedError.dis_winassumes a uniform band-index set across k (fine for gappedwindows; partial metals would need ragged arrays).
Test plan
pip install -e .from repo rootpython -m pytest pyscf/pbc/lo -q→ 42 passed, 2 skippedfrom pyscf.pbc.lo import kernelimportsW90_EXE→ 44 passed