Changelog¶
All notable changes are collected here. Format loosely follows
Keep a Changelog. Until vibe-qc
cuts its first tagged release, every change lands on the main branch
and is rolled up into the [Unreleased] block below.
[Unreleased]¶
Added¶
Phases 18 + 19 — atomic charges, bond orders, dipole moment. Every
run_job.outfile now appends a properties block with Mulliken and Löwdin atomic charges, Mayer bond orders (filtered to pairs withB_AB ≥ 0.10for compactness), and the molecular dipole moment in both atomic units (e·bohr) and Debye, with the centre of mass as the default origin. Public Python API: :func:vibeqc.mulliken_charges, :func:vibeqc.loewdin_charges, :func:vibeqc.mayer_bond_orders, :func:vibeqc.dipole_moment(returning :class:vibeqc.DipoleMoment), :func:vibeqc.center_of_mass, and the lower-level :func:vibeqc.compute_dipole/ :class:vibeqc.DipoleIntegrals.format_scf_tracegrowsbasis=andinclude_properties=keywords. Verified against PySCF: Mulliken charges and dipole-moment components on H₂O / 6-31G* agree to better than 1e-6. 17 new tests; full suite 381 passing.Phase P1.1 — gradient parallelism + thread-count control + timing reports. All five shell-quartet loops in
cpp/src/gradient.cpp(overlap, kinetic, nuclear, two-electron RHF, two-electron UHF) now run under OpenMP via the thread-local-gradient-with-post-reduce pattern — closing the remaining P1 gap so analytic gradients scale on multi-core hardware. New public API: :func:vibeqc.get_num_threads, :func:vibeqc.set_num_threads(withn <= 0meaning “restore default” — eitherOMP_NUM_THREADSor the hardware core count).run_jobgrows anum_threads=keyword; every.outfile records the actual thread count used plus a wall-clock timing block summarising SCF total, per-iteration average, geometry-optimisation time (if any), and job total. 7 new tests cover the thread API and timing.Phase 12e-c-2 — erfc-screened ERIs for the short-range Ewald J/K.
build_jk_gamma_molecular_limitandbuild_fock_2e_real_spacegrow an optionalomegaparameter (default0.0). When positive, the builders swap libint’sOperator::coulombforOperator::erfc_coulombwith screening parameterω, producing the short-range piece of the Ewald split for 3D bulk. Matching long-range piece (reciprocal-space Hartree, FFTW-accelerated) lands in 12e-c-3. 10 new tests cover the ω → 0 / ω → ∞ limits, monotone decrease in ω, and the J(0) = J_short(ω) + J_long(ω) decomposition consistency.Phase 12e-c-1 — Gaussian-charge Ewald for V(g) via grid integration. First sub-phase of the full 3D Ewald stack. New public API: :func:
vibeqc.ewald_point_charge_potential(Ewald-summed Coulomb potential of a periodic lattice of point charges, with optional short/long-range decomposition), :func:vibeqc.ewald_nuclear_potential(convenience wrapper for electronic attraction), and :func:vibeqc.compute_nuclear_lattice_ewald(fullV_μν(g)via analytical erfc short-range (libint’s erfc_nuclear, Phase 12e-b) plus numerical grid integration of the smooth erf long-range part). α-invariant to ~1e-4 Ha across the working range of α. Not yet dispatched bycompute_nuclear_lattice; callers that want the Ewald V must invoke it directly. FullEWALD_3Ddispatch with the ERI Coulomb (J-term) Ewald, Saunders–Dovesi multipolar splitting, and FFTW3 acceleration follow in 12e-c-2 and 12e-c-3.Phase P2 — memory estimator + pre-flight abort. Every compute-heavy driver now surfaces an upper-bound peak-memory estimate before the SCF starts, printed to the run log as
vibeqc estimates this calculation will require ~12.4 GB of memory: ERI tensor 11.6 GB ... Available on this machine: 119.8 GB. Proceeding.
When the estimate exceeds available RAM,
run_jobaborts with :class:vibeqc.InsufficientMemoryError; users can setmemory_override=Trueon therun_jobcall to proceed anyway (the block then showsProceeding (override)). New public API: :class:vibeqc.MemoryEstimate, :class:vibeqc.InsufficientMemoryError, :func:vibeqc.estimate_memory, :func:vibeqc.check_memory, :func:vibeqc.available_memory_bytes, :func:vibeqc.format_memory_report. Estimators cover RHF / UHF / RKS / UKS / MP2 / UMP2; theavailable_memory_bytesprobe tries psutil first (optional dep), then falls back to/proc/meminfo(Linux) andos.sysconf(macOS). 22 new tests.Phase P1 — OpenMP shared-memory parallelism. Single-node multithreading lands on every compute-heavy kernel: molecular 1e and 2e integrals (
compute_overlap,compute_kinetic,compute_nuclear,compute_eri), the molecular Fock builder (build_fock_g,build_coulomb,build_exchange), periodic one-electron lattice sums (compute_overlap_lattice,compute_kinetic_lattice,compute_nuclear_lattice,compute_nuclear_erfc_lattice), the Γ-only and multi-k periodic Fock builds (build_jk_gamma_molecular_limit,build_fock_2e_real_space), the Ewald real-space and reciprocal-space loops, and AO evaluation on DFT grids (evaluate_ao,evaluate_ao_with_gradient,evaluate_ao_with_hessian). Thread-safe via a one-engine-per-thread pool incpp/include/vibeqc/thread_pool.hpp. Controlled byOMP_NUM_THREADS; no API change, all 320 regression tests pass unchanged. Benchmark harness inscripts/bench.pyreports scaling across a sweep of thread counts. Analytic gradients and the SAD initial guess remain single-threaded for now — a follow-on P1.1 pass.Phase 12e-a — classical Ewald for point-charge Madelung energies. New public API:
vibeqc.EwaldOptions,vibeqc.ewald_point_charge_energy,vibeqc.ewald_nuclear_repulsion.CoulombMethod.EWALD_3Ddispatchesnuclear_repulsion_per_cellthrough the Ewald engine. Validated against literature Madelung constants for NaCl (1e-8), CsCl (1e-6), ZnS (1e-4), and simple-cubic jellium (1e-6); α-invariance holds to 1e-9 across α ∈ {0.2, 0.3, 0.5, 1.0}. Seedocs/user_guide/ewald.md.Phase 12e-b — erfc-screened nuclear-attraction lattice sum as an Ewald building block. New public API:
vibeqc.compute_nuclear_erfc_lattice(basis, system, omega, options). Wraps libint’sOperator::erfc_nuclear; exponentially convergent real-space sum for any ω > 0. Used by Phase 12e-c to assemble the fullEWALD_3Ddispatch ofcompute_nuclear_lattice.Documentation — new
docs/user_guide/ewald.mdwith math, references, and usage examples; API index updated with the new symbols and the Version & banner section added; roadmap and feature matrix reflect 12e-a/b shipped and the 12e-c / 12f / v0.3.0+ work ahead.
Limitations¶
EWALD_3Don the SCF-facing nuclear-attractionV(g)and the ERI Coulomb termJis not yet wired. Bulk 3D HF / DFT results remain cutoff-dependent until Phase 12e-c lands the reciprocal-space pieces and the Saunders–Dovesi multipolar splitting.
[0.1.0] — 2026-04-18¶
First tagged release. All subsequent releases will follow semantic
versioning (pre-1.0: any minor bump may break API; 0.2.0, 0.3.0,
… mark milestone achievements).
Added¶
Runtime banner printed at the top of SCF-trace output — shows vibe-qc version, MPL 2.0 attribution, and linked library versions (libint, libxc, spglib). Exposed as
vibeqc.banner(),vibeqc.print_banner(),vibeqc.library_versions().Documentation site (Sphinx + Furo + MyST) with installation guide, tutorial, feature matrix, roadmap, and autogenerated API reference.
MPL 2.0 license at the repository root.
CRYSTAL-format basis-set parser and NWChem/.g94 emitter (
python/vibeqc/basis_crystal.py) for per-element CRYSTAL basis files.Bredow-group pob- basis sets* fetched into
basis_library/custom/: pob-TZVP (H–Br), pob-TZVP-rev2 (H–Br), pob-DZVP-rev2 (subset).Phase 12d — multi-k periodic Kohn-Sham DFT (
run_rks_periodic), LDA and pure GGA. Validated against molecular RKS in the molecular limit across dim ∈ {1, 2, 3} × {LDA, PBE, BLYP}.Phase 12c — multi-k periodic RHF (
run_rhf_periodic) with real-space density matrix and the general three-lattice-index direct-SCF Fock build.Phase 12b — Γ-only periodic RHF (
run_rhf_periodic_gamma) in the molecular-limit regime.Phase 12a — periodic one-electron infrastructure:
PeriodicSystem, lattice-summed S/T/V integrals, Bloch sums, Monkhorst-Pack k-mesh, IBZ reduction via spglib.spglib integration (
vibeqc.Crystal,analyze_symmetry,to_primitive) + minimal VASP 5 POSCAR I/O.UMP2 — open-shell MP2 on a UHF reference, three spin channels.
RMP2 — closed-shell MP2 on an RHF reference.
Known limitations (being addressed)¶
3D bulk Coulomb lattice sum is currently direct-truncated (conditional convergence). Proper Ewald splitting lands in Phase 12e.
Periodic DFT uses the molecular Becke weight partition; image-atom Voronoi cells may intrude on the reference unit cell for tight crystals. Proper periodic Becke partition lands in Phase 12f.
ECP basis sets (pob-* for Rb–I, Cs–Po, La–Lu) parse but cannot be used: applying them needs libecpint integration.
Hybrid periodic DFT implemented in the code path (via
exchange_scale) but not yet validated end-to-end.Periodic UKS not yet available.