"""vibe-qc — quantum chemistry code.
Milestone 1 scope: restricted Hartree-Fock total energy for a single
closed-shell molecule. The cyclic cluster model for periodic systems is
the longer-term target.
"""
from __future__ import annotations
import logging as _logging
import os as _os
from pathlib import Path as _Path
# Attach a NullHandler to the top-level logger so the library is silent
# unless the user explicitly configures logging. Standard practice.
_logging.getLogger(__name__).addHandler(_logging.NullHandler())
def _pin_blas_threads() -> None:
"""Default BLAS-internal threading to 1 to avoid nested
oversubscription with vibe-qc's OpenMP parallelism.
Why: the C++ core threads its inner loops with OpenMP (controlled
by ``OMP_NUM_THREADS``). If the linked BLAS (OpenBLAS-pthreads,
MKL, BLIS, Apple Accelerate) *also* threads internally, you get
N×K threads contending for cores — measurably worse than either
layer alone. Standard practice in mixed OpenMP+BLAS codes is to
keep BLAS single-threaded and let the outer parallelism drive
occupancy. These env vars are read at library-init time, so we
set them *before* anything imports the C extension.
User overrides are respected: ``os.environ.setdefault`` only fills
a key that isn't already set, so an explicit
``OPENBLAS_NUM_THREADS=4`` from the user's shell wins.
The set of probed vars covers the BLAS implementations we care
about: OpenBLAS, MKL, Apple Accelerate (vecLib), and BLIS.
"""
for _key in (
"OPENBLAS_NUM_THREADS", # OpenBLAS (Arch / Fedora / Debian / Homebrew)
"MKL_NUM_THREADS", # Intel MKL
"VECLIB_MAXIMUM_THREADS", # Apple Accelerate (vecLib)
"BLIS_NUM_THREADS", # BLIS
):
_os.environ.setdefault(_key, "1")
_pin_blas_threads()
def _install_basis_library() -> None:
"""Point libint at vibe-qc's bundled basis library.
libint looks at ``$LIBINT_DATA_PATH/basis/<name>.g94`` at BasisSet
construction time. The bundled basis library ships *inside* the
Python package (``python/vibeqc/basis_library/``) so a fresh
``pip install -e .`` from the vibe-qc checkout already has every
standard libint basis plus vibe-qc's custom additions (pob-tzvp,
pob-dzvp-rev2, pob-tzvp-rev2) immediately — no separate setup
step, no ``LIBINT_DATA_PATH`` fiddling.
Resolution order:
1. ``$LIBINT_DATA_PATH`` already set by user → respect it (user
override wins).
2. ``build/basis_library/basis/`` — populate output from
``scripts/setup_basis_library.sh`` (build-time overlay,
gitignored). Preferred over the committed copy when
present because it reflects the current libint install
+ custom/ state.
3. ``python/vibeqc/basis_library/basis/`` (bundled with the
wheel) → fallback.
4. ``<repo-root>/basis_library/basis/`` (legacy editable-install
layout, kept for backwards compatibility while users migrate).
"""
if "LIBINT_DATA_PATH" in _os.environ:
return
here = _Path(__file__).resolve().parent
# Build-output overlay: populate writes here; preferred when it exists.
build_dir = here.parent.parent / "build" / "basis_library"
if (build_dir / "basis").is_dir():
_os.environ["LIBINT_DATA_PATH"] = str(build_dir)
return
# Bundled with the wheel / package.
bundled = here / "basis_library"
if (bundled / "basis").is_dir():
_os.environ["LIBINT_DATA_PATH"] = str(bundled)
return
# Legacy editable-install layout (basis_library/ at the repo root).
legacy = here.parent.parent / "basis_library"
if (legacy / "basis").is_dir():
_os.environ["LIBINT_DATA_PATH"] = str(legacy)
_install_basis_library()
def _resolve_bundled_ecp_share_dir() -> str:
"""Locate the directory containing libecpint's XML basis library.
libecpint's :func:`ECPIntegrator::set_ecp_basis_from_library` takes
a ``share_dir`` argument and internally appends ``"/xml/" + name +
".xml"`` — so the path returned here is the parent of ``xml/``,
not ``xml/`` itself.
Resolution order:
1. ``$VIBEQC_ECP_SHARE_DIR`` if set (user override).
2. ``python/vibeqc/ecp_library/`` bundled with the wheel —
contains the libecpint 1.0.7 XML library
(ecp10mdf, ecp28mdf, ecp46mdf, ecp60mdf, ecp78mdf, lanl2dz).
3. ``<repo-root>/third_party/libecpint/install/share/libecpint``
(legacy editable-install path, kept while we migrate).
4. Empty string — caller must pass ``share_dir`` explicitly.
Returned in plain string form for direct hand-off to
:func:`compute_ecp_matrix`.
"""
if "VIBEQC_ECP_SHARE_DIR" in _os.environ:
return _os.environ["VIBEQC_ECP_SHARE_DIR"]
here = _Path(__file__).resolve().parent
bundled = here / "ecp_library"
if (bundled / "xml" / "ecp10mdf.xml").is_file():
return str(bundled)
legacy = (
here.parent.parent
/ "third_party"
/ "libecpint"
/ "install"
/ "share"
/ "libecpint"
)
if (legacy / "xml" / "ecp10mdf.xml").is_file():
return str(legacy)
return ""
_VIBEQC_ECP_SHARE_DIR = _resolve_bundled_ecp_share_dir()
# Tell the C++ side where to find the bundled XML library too —
# ``run_rhf`` / ``run_uhf`` / ``run_rks`` paths call
# ``compute_ecp_matrix`` internally with an empty ``share_dir`` and
# rely on the build-time ``VIBEQC_LIBECPINT_SHARE_DIR`` macro.
# That macro doesn't exist on a wheel install (the path was relative
# to the build host's third_party/libecpint/install/), so the C++
# side reads ``$VIBEQC_ECP_SHARE_DIR`` at runtime as the bundled
# fallback. Setting it from Python before any C++ ECP entry runs
# is the simplest cross-language plumbing.
if _VIBEQC_ECP_SHARE_DIR and "VIBEQC_ECP_SHARE_DIR" not in _os.environ:
_os.environ["VIBEQC_ECP_SHARE_DIR"] = _VIBEQC_ECP_SHARE_DIR
# Semiempirical module is imported lazily to avoid circular imports.
# Use ``from vibeqc import semiempirical`` or ``import vibeqc.semiempirical``.
# The module is attached below after all names are bound.
from ._vibeqc_core import (
ADIIS,
DIIS,
EDIIS,
Atom,
BandDiag,
BasisSet,
BlochKMesh,
CoulombMethod,
Crystal,
D3BJParams,
DipoleIntegrals,
DispersionResult,
ECPCenter,
EwaldOptions,
ExternalChargeGradient,
Functional,
GradientOptions,
Grid,
GridOptions,
InitialGuess,
IrreducibleKMesh,
JKBuilder,
JKMatrices,
LatticeCell,
LatticeMatrixSet,
LatticeSumOptions,
Molecule,
MP2Options,
MP2Result,
NewtonOptions,
PairJKContribution,
PeriodicKSOptions,
PeriodicKSResult,
PeriodicRHFOptions,
PeriodicRHFResult,
PeriodicSCFOptions,
PeriodicSystem,
PeriodicUKSXCContribution,
PeriodicXCContribution,
RHFOptions,
RHFResult,
RKSOptions,
RKSResult,
SCFAccelerator,
SCFIteration,
SCFMode,
ShellInfo,
SOSCFOptions,
SpaceGroup,
SymmetryOp,
TRAHOptions,
UHFOptions,
UHFResult,
UHFXCKernelBuilder,
UKSOptions,
UKSResult,
UMP2Options,
UMP2Result,
XCKernelBuilder,
XCKind,
analyze_symmetry,
attach_symmetry,
bloch_sum,
build_cosx_q,
build_cosx_schwarz,
build_fock_2e_real_space,
build_grid,
build_jk_2e_real_space,
build_jk_2e_real_space_explicit,
build_jk_gamma_molecular_limit,
build_jk_gamma_molecular_limit_explicit,
build_jk_pair_contributions,
build_xc_periodic,
build_xc_periodic_uks,
compute_2c_eri,
compute_2c_eri_gradient_contribution,
compute_2c_eri_gradient_weighted,
compute_2c_eri_lattice,
compute_2c_eri_lattice_blocks,
compute_2c_eri_lattice_sr,
compute_3c_eri,
compute_3c_eri_gradient_contribution,
compute_3c_eri_gradient_weighted,
compute_3c_eri_lattice,
compute_3c_eri_lattice_blocks,
compute_3c_eri_lattice_sr,
compute_cosx_k,
compute_cosx_k_gradient_contribution,
compute_df_j_gradient,
compute_df_jk_gradient,
compute_df_k_gradient,
compute_dipole,
compute_eri,
compute_external_charge_density_gradient,
compute_kinetic,
compute_kinetic_lattice,
compute_kinetic_lattice_explicit,
compute_nuclear,
compute_nuclear_erfc_lattice,
compute_nuclear_lattice,
compute_nuclear_lattice_ewald,
compute_nuclear_lattice_explicit,
compute_overlap,
compute_overlap_lattice,
compute_overlap_lattice_explicit,
compute_robust_cosx_k,
d3_coordination_numbers,
d3_r2r4,
d3_rcov,
diagonalize_bloch,
direct_lattice_cells,
evaluate_ao,
evaluate_ao_with_gradient,
evaluate_bloch_ao,
ewald_nuclear_potential,
ewald_nuclear_repulsion,
ewald_point_charge_energy,
ewald_point_charge_potential,
get_num_threads,
hartree_energy_on_grid,
hello,
irreducible_kpoints,
libecpint_version,
libint_version,
libxc_version,
make_cosx_jk_builder,
make_df_jk_builder,
make_direct_jk_builder,
make_four_index_jk_builder,
make_periodic_gamma_jk_builder,
make_polarised_gga_xc_kernel_builder,
make_polarised_lda_xc_kernel_builder,
make_polarised_xc_kernel_builder,
make_unpolarised_xc_kernel_builder,
nuclear_repulsion_per_cell,
real_space_density_from_kpoints,
rhf_result_from_rks,
run_mp2,
run_rhf,
run_rhf_periodic,
run_rhf_periodic_gamma,
run_rhf_scf_with_jk,
run_rks,
run_rks_periodic,
run_rks_scf_with_jk,
run_uhf,
run_uhf_scf_with_jk,
run_uks,
run_uks_scf_with_jk,
run_ump2,
sad_density,
set_num_threads,
solve_poisson_coulomb,
solve_poisson_erf_screened,
spglib_version,
to_primitive,
)
from ._vibeqc_core import (
compute_ecp_matrix as _compute_ecp_matrix_native,
)
from ._vibeqc_core import (
compute_gradient as _compute_gradient_core,
)
from ._vibeqc_core import (
compute_gradient_rks as _compute_gradient_rks_core,
)
from ._vibeqc_core import (
compute_gradient_uhf as _compute_gradient_uhf_core,
)
from ._vibeqc_core import (
compute_gradient_uks as _compute_gradient_uks_core,
)
from ._vibeqc_core import (
monkhorst_pack as _monkhorst_pack_native,
)
from .banner import VIBEQC_VERSION, banner, library_versions, print_banner
# ---------------------------------------------------------------------------
# SCFAccelerator string parsing — runner / config / user-input helper.
# ---------------------------------------------------------------------------
_SCF_ACCELERATOR_FROM_STRING = {
"diis": SCFAccelerator.DIIS,
"kdiis": SCFAccelerator.KDIIS,
"ediis": SCFAccelerator.EDIIS,
"ediis_diis": SCFAccelerator.EDIIS_DIIS,
"ediis+diis": SCFAccelerator.EDIIS_DIIS,
"adiis": SCFAccelerator.ADIIS,
}
def scf_accelerator_from_string(name: str) -> "SCFAccelerator":
"""Resolve a user-facing string to an SCFAccelerator enum value.
Accepts case-insensitive ``"diis"``, ``"kdiis"``, ``"ediis"``,
``"ediis_diis"`` and the ergonomic alias ``"ediis+diis"``.
Use this in input parsers / config-driven runners so users can
write ``scf.accelerator = "ediis_diis"`` in YAML and have it
resolve cleanly.
Raises ``ValueError`` on unrecognised input with the list of
accepted names.
"""
key = str(name).strip().lower()
try:
return _SCF_ACCELERATOR_FROM_STRING[key]
except KeyError:
raise ValueError(
f"Unknown SCFAccelerator name {name!r}; expected one of "
+ ", ".join(
sorted(set(v.name for v in _SCF_ACCELERATOR_FROM_STRING.values()))
)
)
# Attach as a class method on the enum for ergonomic call sites
# (``vibeqc.SCFAccelerator.from_string("kdiis")``).
SCFAccelerator.from_string = staticmethod(scf_accelerator_from_string)
[docs]
def monkhorst_pack(system, mesh, is_shift=None, use_symmetry=False, *, symmetry=None):
"""Build a legacy :class:`BlochKMesh` Monkhorst-Pack mesh.
This public compatibility wrapper keeps the historical
gamma-centred default of the C++ binding (``is_shift=(0, 0, 0)``)
while accepting the same low-dimensional active-axis shorthand as
:class:`KPoints`: ``[n]`` for 1D and ``[n1, n2]`` for 2D. Inactive
axes are pinned to Γ with mesh size 1 and shift 0.
Use :meth:`KPoints.monkhorst_pack` for the richer Python API with
classical Monkhorst-Pack auto-shifts.
"""
from .kpoints import _mesh_tuple_for_system, _shift_tuple_for_system
if symmetry is not None:
use_symmetry = bool(symmetry)
mesh_t = _mesh_tuple_for_system(system, mesh)
if is_shift is None:
shift_t = (0, 0, 0)
else:
shift_t = _shift_tuple_for_system(system, is_shift)
return _monkhorst_pack_native(
system,
list(mesh_t),
list(shift_t),
bool(use_symmetry),
)
[docs]
def compute_ecp_matrix(basis, ecp_centers, library_name="ecp10mdf", share_dir=""):
"""Compute the AO-basis ECP matrix V_ECP_{μν} = ⟨χ_μ|V_ECP|χ_ν⟩
via libecpint's built-in XML library (ecp10mdf, ecp28mdf,
ecp46mdf, ecp60mdf, ecp78mdf, lanl2dz). Output is in spherical
(real-solid-harmonic) basis.
``share_dir`` defaults to the XML library bundled inside the
vibe-qc Python package (``python/vibeqc/ecp_library/``) — no
setup, no LIBECPINT_SHARE_DIR fiddling, no Homebrew dependency.
Override by passing an explicit path, or by setting
``$VIBEQC_ECP_SHARE_DIR`` before ``import vibeqc``.
Note on the share-dir convention: libecpint's
:func:`ECPIntegrator::set_ecp_basis_from_library` internally
appends ``"/xml/" + name + ".xml"``, so ``share_dir`` is the
directory CONTAINING ``xml/`` (i.e. ``.../share/libecpint``),
not ``xml/`` itself. The libecpint header doc is misleading on
this; api.cpp:73 is the authority.
"""
if not share_dir:
share_dir = _VIBEQC_ECP_SHARE_DIR
return _compute_ecp_matrix_native(
basis,
ecp_centers,
library_name,
share_dir,
)
from ._vibeqc_core import (
EEQOptions,
EEQResult,
chg_max_supported_Z,
compute_chg_dispersion,
eeq_charges,
eeq_coordination_numbers,
)
from ._vibeqc_core import _HubbardSiteCxx as _HubbardSiteCxx # internal
from .composites import (
Availability as CompositeAvailability,
)
from .composites import (
CompositeRecipe,
CompositeUnavailable,
ShortRangeCorrection,
list_composites,
resolve_composite,
)
from .density_fitting import (
DensityFitting,
DensityFittingInfo,
default_aux_basis_for,
)
# Wrap the C++ SCF drivers to give users a clean ``dft_plus_u=`` kwarg
# surface. The C++ side carries two parallel arrays
# (``Options.dft_plus_u_sites`` + ``dft_plus_u_ao_groups``); the
# wrapper does the eV→Hartree conversion + ao_group_indices walk once
# at SCF setup so the SCF loop sees only the precomputed C++ structs.
# The actual translation helper lives in ``vibeqc.dft_plus_u`` so
# ``runner._run_single_point`` can reuse it without a circular import.
from .dft_plus_u import (
HubbardSite,
_apply_dft_plus_u_to_options,
ao_group_indices,
compute_dudarev_energy,
compute_occupation_matrices,
)
_run_rhf_cxx = run_rhf # capture the bare C++ binding before reassignment
_run_rks_cxx = run_rks # capture the bare C++ binding before reassignment
_run_uhf_cxx = run_uhf
_run_uks_cxx = run_uks
_run_rhf_periodic_gamma_cxx = run_rhf_periodic_gamma
_run_rks_periodic_cxx = run_rks_periodic
[docs]
def run_rhf(molecule, basis, options=None, *, dft_plus_u=None):
"""Restricted Hartree-Fock SCF on a closed-shell molecule.
Parameters
----------
molecule, basis
The Molecule and BasisSet (Python passes through to C++ unchanged).
options
Optional RHFOptions. A fresh one is constructed if not given.
dft_plus_u
Optional iterable of :class:`HubbardSite` objects (eV-input
user dataclass from :mod:`vibeqc.dft_plus_u`). When non-empty,
the SCF Fock builder adds the Dudarev rotationally-invariant
per-spin potential
``V_U^A = U_eff (½ δ − n^A_l)`` on each (atom, l) channel; the
Dudarev energy contribution ``E_U = 2 Σ_A (U_eff/2) (tr n −
tr n²)`` (closed-shell, summed over both spins) appears as
``result.e_dft_plus_u`` and is included in ``result.energy``.
Returns
-------
RHFResult
Same shape as the C++ binding, with the additional
``e_dft_plus_u`` field populated when +U was active.
"""
if options is None:
options = RHFOptions()
if dft_plus_u:
_apply_dft_plus_u_to_options(options, basis, dft_plus_u)
return _run_rhf_cxx(molecule, basis, options)
[docs]
def run_rks(molecule, basis, options=None, *, dft_plus_u=None):
"""Restricted Kohn-Sham SCF on a closed-shell molecule.
Same shape as :func:`run_rhf`; ``options`` is :class:`RKSOptions`
(carries the XC functional name) and the result type is
:class:`RKSResult` (carries the KS energy decomposition plus the
optional ``e_dft_plus_u`` field).
"""
if options is None:
options = RKSOptions()
if dft_plus_u:
_apply_dft_plus_u_to_options(options, basis, dft_plus_u)
return _run_rks_cxx(molecule, basis, options)
[docs]
def run_uhf(molecule, basis, options=None, *, dft_plus_u=None):
"""Unrestricted Hartree-Fock SCF on an open-shell molecule.
Open-shell counterpart of :func:`run_rhf`. The Dudarev +U formula
applies natively per-spin — the SCF Fock builder calls the kernel
once per spin with that spin's density matrix and adds the
per-spin V_U to the per-spin Fock; ``result.e_dft_plus_u`` is the
sum of the two per-spin contributions (no factor of 2 needed —
the per-spin formula already gives one term per spin).
"""
if options is None:
options = UHFOptions()
if dft_plus_u:
_apply_dft_plus_u_to_options(options, basis, dft_plus_u)
return _run_uhf_cxx(molecule, basis, options)
[docs]
def run_uks(molecule, basis, options=None, *, dft_plus_u=None):
"""Unrestricted Kohn-Sham SCF on an open-shell molecule.
Open-shell counterpart of :func:`run_rks`. Same per-spin
convention as :func:`run_uhf`; ``options`` is :class:`UKSOptions`
and the result is :class:`UKSResult`.
"""
if options is None:
options = UKSOptions()
if dft_plus_u:
_apply_dft_plus_u_to_options(options, basis, dft_plus_u)
return _run_uks_cxx(molecule, basis, options)
[docs]
def run_rhf_periodic_gamma(system, basis, options=None, *, dft_plus_u=None):
"""Γ-only closed-shell RHF for a periodic system (molecular-limit
regime).
The Γ-only periodic SCF carries a single real ``Eigen::MatrixXd``
density and AO overlap — same shape as the molecular case — so
the +U kernel is reused unchanged. ``options`` is a
:class:`PeriodicRHFOptions`; ``dft_plus_u`` is a list of
:class:`HubbardSite` objects (per-atom (atom_index, l, U_ev)
channels). Multi-k periodic +U is queued for Increment 4c.
"""
if options is None:
options = PeriodicRHFOptions()
if dft_plus_u:
_apply_dft_plus_u_to_options(options, basis, dft_plus_u)
return _run_rhf_periodic_gamma_cxx(system, basis, options)
[docs]
def run_rks_periodic(system, basis, kmesh, options=None, *, dft_plus_u=None):
"""Multi-k closed-shell periodic Kohn-Sham SCF (DIRECT_TRUNCATED).
Increment 4b adds an optional ``dft_plus_u=[HubbardSite(...)]``
kwarg. **The +U path is currently Γ-only**: passing a non-empty
``dft_plus_u`` together with a multi-k kmesh raises
``NotImplementedError`` pointing at Increment 4c. For Γ-only
(``kmesh = [1,1,1]``) the +U term is computed from the Γ-folded
AO occupation matrix ``(S_Γ P_Γ S_Γ)_{(A,l)}`` — equivalent to
the molecular convention when the unit cell is large enough that
only g=0 lattice translations contribute.
"""
# K7 boundary: KPoints → BlochKMesh, BlochKMesh passes through.
from .kpoints import as_bloch_kmesh
bm = as_bloch_kmesh(kmesh)
if options is None:
options = PeriodicKSOptions()
if dft_plus_u:
n_kpts = len(bm.kpoints)
if n_kpts > 1:
raise NotImplementedError(
f"DFT+U on the multi-k periodic RKS path (kmesh has "
f"{n_kpts} k-points) is not yet wired — Γ-only "
"(kmesh=[1,1,1]) is the only supported configuration "
"in Increment 4b. Multi-k +U (the correct k-averaged "
"Σ_k w_k (S(k) P(k) S(k))_{(A,l)} occupation matrix) "
"lands in Increment 4c — see "
"HANDOVER_DFT_PLUS_U.md § 3."
)
_apply_dft_plus_u_to_options(options, basis, dft_plus_u)
return _run_rks_periodic_cxx(system, basis, bm, options)
from .dispersion import (
compute_d3bj,
d3bj_params_for,
dftd3_available,
)
from .dispersion_d4 import (
D4Result,
compute_d4,
dftd4_available,
)
from .dispersion_d4_model import (
D4_WEIGHTING_FACTOR,
cn_gaussian_weights,
)
from .dispersion_d4_refdata import (
casimir_polder_c6,
coupled_polarizability_imag_freq,
imaginary_frequency_grid,
london_c6_single_pole,
molecular_c6,
uncoupled_polarizability_imag_freq,
)
from .dispersion_d4_reference_systems import (
ReferenceSystem,
all_reference_elements,
all_reference_systems,
reference_systems_for,
)
from .dispersion_d4_reference_systems import (
build_molecule as build_reference_molecule,
)
# v0.9.0 composite 3c methods + geometric counterpoise.
from .gcp import (
GCPDataMissing,
GCPParams,
GCPResult,
compute_gcp,
gcp_params_for,
)
from .gcp import (
available_basis_sets as available_gcp_basis_sets,
)
# ---------------------------------------------------------------------
# Gradient kernel — thin Python wrappers over the C++ bindings.
#
# History: v0.7.3 had a silent bug in the direct 4-index ERI gradient
# kernel on multi-heavy-atom systems with f-shells (def2-tzvp+). The
# v0.7.4 "Fix C" (canonical 1/8 shell loop + l-canonical reorder
# before libint) lives in ``cpp/src/gradient.cpp ::
# two_electron_gradient_contribution`` and resolves the bug to machine
# precision (H2CO/def2-tzvp Cs-zero ~1e-13, vs PySCF ~5e-11).
# Earlier branches shipped a "Fix D" auto-route through DF on f-shell
# bases — that workaround is removed here because the direct kernel is
# now correct. The ``_auto_df_for_fshell`` keyword survives as a no-op
# for one minor release for backwards compatibility; it will be
# removed in v0.8.0.
# ---------------------------------------------------------------------
[docs]
def compute_gradient(mol, basis, result, options=None, *, _auto_df_for_fshell=False):
"""RHF analytic nuclear gradient (Ha/bohr, per atom).
``_auto_df_for_fshell`` is accepted but ignored — kept for one
minor-version backwards compatibility after v0.7.3's f-shell
auto-route was retired.
"""
del _auto_df_for_fshell # no-op (v0.7.4); will be removed in v0.8.0.
if options is None:
options = GradientOptions()
return _compute_gradient_core(mol, basis, result, options)
[docs]
def compute_gradient_rks(
mol, basis, result, grid_options=None, options=None, *, _auto_df_for_fshell=False
):
"""RKS analytic nuclear gradient (Ha/bohr, per atom).
Note: the C++ signature is
``compute_gradient_rks(mol, basis, result, grid_options, options)``;
keep the positional order or pass by keyword.
"""
del _auto_df_for_fshell # no-op (v0.7.4); will be removed in v0.8.0.
if options is None:
options = GradientOptions()
if grid_options is None:
# Match the C++ default (vibeqc::GridOptions{}).
grid_options = GridOptions()
return _compute_gradient_rks_core(mol, basis, result, grid_options, options)
[docs]
def compute_gradient_uhf(
mol, basis, result, options=None, *, _auto_df_for_fshell=False
):
"""UHF analytic nuclear gradient (Ha/bohr, per atom)."""
del _auto_df_for_fshell # no-op (v0.7.4); will be removed in v0.8.0.
if options is None:
options = GradientOptions()
return _compute_gradient_uhf_core(mol, basis, result, options)
[docs]
def compute_gradient_uks(
mol, basis, result, grid_options=None, options=None, *, _auto_df_for_fshell=False
):
"""UKS analytic nuclear gradient (Ha/bohr, per atom).
Note: the C++ signature is
``compute_gradient_uks(mol, basis, result, grid_options, options)``;
keep the positional order or pass by keyword.
"""
del _auto_df_for_fshell # no-op (v0.7.4); will be removed in v0.8.0.
if options is None:
options = GradientOptions()
if grid_options is None:
grid_options = GridOptions()
return _compute_gradient_uks_core(mol, basis, result, grid_options, options)
# ---------------------------------------------------------------------
# Scaled-spin-component MP2 convenience wrappers.
#
# All of these default ``density_fit=True`` (RI-MP2) — for double-hybrid
# correlations the MP2 step is cost-dominant and canonical MP2 is
# untractable past def2-TZVP on a workstation. Pass ``density_fit=False``
# for an explicit canonical-MP2 parity run; ``aux_basis`` is then
# ignored. With the default RI path and ``aux_basis=""``, the per-zeta
# RIfit aux is auto-resolved from the orbital basis name via
# ``default_aux_basis_for(name, kind="ri")``.
#
# References:
# * SCS-MP2 — Grimme, J. Chem. Phys. 118, 9095 (2003).
# * SOS-MP2 — Jung, Lochan, Dutoi, Head-Gordon, J. Chem. Phys.
# 121, 9793 (2004).
# ---------------------------------------------------------------------
def _resolve_mp2_aux_basis(basis, density_fit, aux_basis):
if not density_fit:
return ""
if aux_basis:
return aux_basis
return default_aux_basis_for(basis.name, kind="ri")
def _emit_mp2_citations(output, basis, *, method_key):
"""Common citation-sibling emitter for the SCS / SOS MP2 wrappers."""
if output is None:
return
try:
from .output.citations import emit_citations
emit_citations(
output,
method=method_key,
basis=basis.name,
)
except Exception:
pass
def run_scs_mp2(
mol,
basis,
rhf_result,
*,
density_fit=True,
aux_basis="",
c_os=6.0 / 5.0,
c_ss=1.0 / 3.0,
report_ri_residual=False,
output=None,
):
"""SCS-MP2 (Grimme JCP 118, 9095 (2003)) on a closed-shell RHF
reference. Defaults to RI-MP2 with Grimme's c_os = 6/5 and
c_ss = 1/3.
``report_ri_residual=True`` (opt-in, default off) additionally
builds the canonical four-index (ia|jb) and reports the per-bucket
RI fit residual on ``MP2Result.{e_os_ri_residual,
e_ss_ri_residual}`` — doubles the cost, intended for verifying
aux-basis adequacy. No-op when ``density_fit=False``.
``output`` — when set, writes ``{output}.bibtex`` and
``{output}.references`` siblings carrying the SCS-MP2 citation
bundle (Møller-Plesset 1934 + Grimme 2003 + Feyereisen 1993 when
``density_fit=True``).
"""
opts = MP2Options()
opts.density_fit = density_fit
opts.aux_basis = _resolve_mp2_aux_basis(basis, density_fit, aux_basis)
opts.c_os = c_os
opts.c_ss = c_ss
opts.report_ri_residual = report_ri_residual
result = run_mp2(mol, basis, rhf_result, opts)
_emit_mp2_citations(
output, basis, method_key=("scs-ri-mp2" if density_fit else "scs-mp2")
)
return result
def run_sos_mp2(
mol,
basis,
rhf_result,
*,
density_fit=True,
aux_basis="",
c_os=1.3,
c_ss=0.0,
report_ri_residual=False,
output=None,
):
"""SOS-MP2 (Jung-Lochan-Dutoi-Head-Gordon, JCP 121, 9793 (2004))
on a closed-shell RHF reference. Defaults to RI-MP2 with the
original c_os = 1.3, c_ss = 0.
``report_ri_residual`` — see :func:`run_scs_mp2`.
``output`` — see :func:`run_scs_mp2`.
"""
opts = MP2Options()
opts.density_fit = density_fit
opts.aux_basis = _resolve_mp2_aux_basis(basis, density_fit, aux_basis)
opts.c_os = c_os
opts.c_ss = c_ss
opts.report_ri_residual = report_ri_residual
result = run_mp2(mol, basis, rhf_result, opts)
_emit_mp2_citations(
output, basis, method_key=("sos-ri-mp2" if density_fit else "sos-mp2")
)
return result
def run_scs_ump2(
mol,
basis,
uhf_result,
*,
density_fit=True,
aux_basis="",
c_os=6.0 / 5.0,
c_ss=1.0 / 3.0,
report_ri_residual=False,
output=None,
):
"""SCS-UMP2 on a UHF reference. Same scaling as ``run_scs_mp2`` but
applied per Grimme channel definition to the αβ (opposite-spin)
and αα+ββ (same-spin) UMP2 channels.
``report_ri_residual=True`` (opt-in, default off) additionally
reports the per-channel RI fit residual on
``UMP2Result.{e_aa_ri_residual, e_bb_ri_residual,
e_ab_ri_residual}`` — doubles the cost, for aux-basis
verification. No-op when ``density_fit=False``.
"""
opts = UMP2Options()
opts.density_fit = density_fit
opts.aux_basis = _resolve_mp2_aux_basis(basis, density_fit, aux_basis)
opts.c_os = c_os
opts.c_ss = c_ss
opts.report_ri_residual = report_ri_residual
result = run_ump2(mol, basis, uhf_result, opts)
_emit_mp2_citations(
output, basis, method_key=("scs-ri-mp2" if density_fit else "scs-mp2")
)
return result
def run_sos_ump2(
mol,
basis,
uhf_result,
*,
density_fit=True,
aux_basis="",
c_os=1.3,
c_ss=0.0,
report_ri_residual=False,
output=None,
):
"""SOS-UMP2 on a UHF reference. Same scaling as ``run_sos_mp2``.
``report_ri_residual`` — see :func:`run_scs_ump2`.
``output`` — see :func:`run_scs_mp2`.
"""
opts = UMP2Options()
opts.density_fit = density_fit
opts.aux_basis = _resolve_mp2_aux_basis(basis, density_fit, aux_basis)
opts.c_os = c_os
opts.c_ss = c_ss
opts.report_ri_residual = report_ri_residual
result = run_ump2(mol, basis, uhf_result, opts)
_emit_mp2_citations(
output, basis, method_key=("sos-ri-mp2" if density_fit else "sos-mp2")
)
return result
# ---------------------------------------------------------------------
# Double-hybrid DFT dispatcher (B2PLYP — first end-to-end double hybrid).
#
# Double hybrids partition the XC energy into an SCF-stage hybrid (HF +
# GGA exchange + GGA correlation) plus a post-SCF scaled-MP2 correction
# on the converged KS orbitals:
#
# E_DH = E_RKS[xc_scf_piece] + c_os · E_os^MP2 + c_ss · E_ss^MP2
#
# B2PLYP (Grimme 2006): xc_scf = 0.53·HF + 0.47·B88 + 0.73·LYP and
# c_os = c_ss = 0.27. ``Functional("b2plyp")`` resolves to the
# combined recipe — ``hf_exchange_fraction`` carries the 0.53,
# ``mp2_c_os`` / ``mp2_c_ss`` carry the 0.27. RI-MP2 is the default
# for the MP2 correction (the cost-dominant step at production
# basis sizes); pass ``density_fit_mp2=False`` for a canonical-MP2
# parity run.
# ---------------------------------------------------------------------
[docs]
class DoubleHybridResult:
"""Result of a double-hybrid run: the SCF (hybrid-DFT) result, the
post-SCF MP2 correction result, optionally a dispersion correction,
and the combined total energy.
Attributes
----------
rks : RKSResult
The converged hybrid-DFT SCF step.
mp2 : MP2Result
The post-SCF MP2 correction. ``mp2.e_correlation`` is already
scaled by the functional's ``mp2_c_os`` / ``mp2_c_ss``; the
unscaled per-component energies are in ``mp2.e_os`` / ``mp2.e_ss``.
dispersion : DispersionResult or D4Result or None
The dispersion correction. ``DispersionResult`` for D3(BJ),
:class:`D4Result` for D4, or ``None`` when the dispatcher was
called without a ``dispersion`` kwarg. Both result types
expose ``.energy`` (Hartree).
e_total : float
Published total energy in Hartree:
``rks.energy + mp2.e_correlation + (dispersion.energy if dispersion else 0)``.
With ``dispersion=None`` this is the un-dispersed XC + MP2
total; with ``dispersion="d3bj"`` / ``"d4"`` it is the
published ``X-D3BJ`` / ``X-D4`` total (e.g. B2PLYP-D3BJ,
B2PLYP-D4, DSD-PBEP86-D3BJ, DSD-PBEP86-D4).
functional : str
Name passed to the dispatcher (e.g. "b2plyp").
"""
__slots__ = ("rks", "mp2", "dispersion", "e_total", "functional")
[docs]
def __init__(self, rks, mp2, e_total, functional, dispersion=None):
self.rks = rks
self.mp2 = mp2
self.dispersion = dispersion
self.e_total = e_total
self.functional = functional
def __repr__(self):
disp_str = (
f", e_dispersion={self.dispersion.energy:.10f}"
if self.dispersion is not None
else ""
)
return (
f"DoubleHybridResult(functional={self.functional!r}, "
f"e_total={self.e_total:.10f}, "
f"e_rks={self.rks.energy:.10f}, "
f"e_mp2_corr={self.mp2.e_correlation:.10f}"
f"{disp_str})"
)
[docs]
def run_double_hybrid(
mol,
basis,
functional_name,
*,
density_fit=True,
aux_basis="",
density_fit_mp2=True,
aux_basis_mp2="",
dispersion=None,
rks_options=None,
output=None,
):
"""Generic double-hybrid dispatcher.
Resolves ``functional_name`` to a :class:`Functional`, runs a
hybrid-DFT SCF step with that functional's SCF piece, runs an MP2
correction on the converged KS orbitals with the functional's
``mp2_c_os`` / ``mp2_c_ss`` scaling, optionally adds a dispersion
correction, and returns a :class:`DoubleHybridResult` carrying all
pieces and the combined total energy.
``functional_name`` must resolve to an ``is_double_hybrid``
functional (currently ``"b2plyp"``, ``"dsd-pbep86"``, or
``"pwpb95"``); a ``ValueError`` is raised otherwise. The thin
wrappers :func:`run_b2plyp`, :func:`run_dsd_pbep86`, and
:func:`run_pwpb95` are the name-specific entry points most callers
will use. ``"pwpb95"`` resolves to a meta-GGA functional, so its
SCF step runs through the τ-dependent Kohn-Sham path; the
dispatcher handles that transparently.
Parameters
----------
mol, basis : Molecule, BasisSet
The molecular system. Must be closed-shell.
functional_name : str
Name of a double-hybrid functional registered in vibe-qc's
:class:`Functional` resolver.
density_fit : bool, default True
Density-fit the RKS hybrid SCF step (J via RI-J, K via RI-K
since double hybrids in this line all have α_HF > 0).
aux_basis : str, default ""
Aux basis for the SCF DF. Empty → auto-resolve a JKfit aux
from the orbital basis name.
density_fit_mp2 : bool, default True
Use RI-MP2 (recommended) for the post-SCF correction. False
falls back to canonical MP2 — only useful for parity
validation against canonical-MP2 reference codes.
aux_basis_mp2 : str, default ""
Aux basis for the MP2 DF. Empty → auto-resolve a per-zeta
RIfit aux from the orbital basis name. Ignored when
``density_fit_mp2=False``.
dispersion : str or None, default None
Optional dispersion correction folded into
:attr:`DoubleHybridResult.e_total`. Supported:
* ``None`` — un-dispersed XC + MP2 total (the published
"no-D" energy).
* ``"d3bj"`` — Grimme-Antony-Ehrlich-Krieg 2010 D3 with
Becke-Johnson damping, parameters for the functional read
from the existing :func:`vibeqc.compute_d3bj` framework
(prefers the optional ``dftd3`` backend when installed,
falls back to the vibe-qc native stub).
* ``"d4"`` — Caldeweyher-Bannwarth-Grimme 2019 D4 via the
optional ``dftd4`` package; see :func:`vibeqc.compute_d4`.
The dispersion energy is stored on
:attr:`DoubleHybridResult.dispersion` as either a
:class:`DispersionResult` (D3-BJ) or a :class:`D4Result` (D4);
both expose ``.energy`` so consumers can treat them
uniformly.
rks_options : RKSOptions, optional
Caller-provided options for the SCF step. The functional
field is overridden with ``functional_name`` regardless;
everything else is honoured. If ``None``, a default
:class:`RKSOptions` is used with ``density_fit`` /
``aux_basis`` applied per the keyword arguments above.
Returns
-------
DoubleHybridResult
"""
functional = Functional(functional_name)
if not functional.is_double_hybrid:
raise ValueError(
f"run_double_hybrid: {functional_name!r} resolves to a "
f"non-double-hybrid functional (mp2_c_os = "
f"{functional.mp2_c_os}, mp2_c_ss = {functional.mp2_c_ss}). "
"Use run_rks for plain hybrid / GGA / LDA functionals."
)
if rks_options is None:
rks_options = RKSOptions()
rks_options.functional = functional_name
rks_options.density_fit = density_fit
if density_fit:
rks_options.aux_basis = aux_basis or default_aux_basis_for(
basis.name, kind="jk"
)
elif aux_basis:
rks_options.aux_basis = aux_basis
rks_result = run_rks(mol, basis, rks_options)
if not rks_result.converged:
raise RuntimeError(
f"run_double_hybrid({functional_name!r}): hybrid SCF step "
f"did not converge (n_iter={rks_result.n_iter}, "
f"energy={rks_result.energy:.6f}). Tighten RKSOptions "
"(max_iter, accelerator) and retry."
)
mp2_opts = MP2Options()
mp2_opts.density_fit = density_fit_mp2
mp2_opts.aux_basis = _resolve_mp2_aux_basis(basis, density_fit_mp2, aux_basis_mp2)
mp2_opts.c_os = functional.mp2_c_os
mp2_opts.c_ss = functional.mp2_c_ss
rhf_ref = rhf_result_from_rks(rks_result)
mp2_result = run_mp2(mol, basis, rhf_ref, mp2_opts)
# Optional dispersion correction. Folded into e_total so the
# dispatcher returns the published "X-D3BJ" / "X-D4" total when
# dispersion is set.
disp_result = None
if dispersion is not None:
disp_name = dispersion.lower()
if disp_name == "d4":
disp_result = compute_d4(mol, functional_name, charge=float(mol.charge))
elif disp_name == "d3bj":
# Reuse the existing D3(BJ) framework. compute_d3bj's
# ``backend="auto"`` prefers Grimme's reference dftd3 when
# installed (fully populated parameter set, ~80
# functionals) and falls back to the vibe-qc native stub
# otherwise. Per-functional parameters for double hybrids
# (B2PLYP: s6 = 0.64, DSD-PBEP86: s6 = 0.48) are in the
# dftd3 parameters file and read automatically by
# d3bj_params_for(functional_name).
disp_result = compute_d3bj(mol, functional_name)
else:
raise ValueError(
f"run_double_hybrid: dispersion={dispersion!r} not "
"recognised. Supported: None (un-dispersed), "
"'d3bj', 'd4'."
)
e_total = rks_result.energy + mp2_result.e_correlation
if disp_result is not None:
e_total += disp_result.energy
# Optional citation siblings. The double-hybrid dispatcher cites
# the defining paper of the chosen functional (b2plyp / dsd-pbep86
# / pwpb95) plus the MP2 lineage (Møller-Plesset 1934 + Feyereisen
# 1993 for RI-MP2) and the dispersion paper when one is folded in.
if output is not None:
try:
from .output.citations import emit_citations
_disp_key = None
if disp_result is not None:
_disp_key = "d4" if dispersion.lower() == "d4" else "d3bj"
emit_citations(
output,
method=functional_name,
basis=basis.name,
functional=functional_name,
dispersion=_disp_key,
)
except Exception:
# Citation emission is best-effort; never let it tank a
# converged double-hybrid run. The user can still call
# emit_citations(...) manually if they want the siblings.
pass
return DoubleHybridResult(
rks_result,
mp2_result,
e_total,
functional_name,
dispersion=disp_result,
)
def run_b2plyp(mol, basis, **kwargs):
"""B2PLYP (Grimme, *J. Chem. Phys.* **124**, 034108 (2006)).
Thin wrapper around :func:`run_double_hybrid` with
``functional_name="b2plyp"``. Runs the hybrid SCF step
(0.53·HF + 0.47·B88 + 0.73·LYP) and the RI-MP2 correction
(c_os = c_ss = 0.27) on the converged KS orbitals. See
:func:`run_double_hybrid` for the keyword arguments and
:class:`DoubleHybridResult` for the return value.
"""
return run_double_hybrid(mol, basis, "b2plyp", **kwargs)
def run_dsd_pbep86(mol, basis, **kwargs):
"""DSD-PBEP86 (Kozuch & Martin, *Phys. Chem. Chem. Phys.* **13**,
20104 (2011)) — no D dispersion.
Thin wrapper around :func:`run_double_hybrid` with
``functional_name="dsd-pbep86"``. Runs the hybrid SCF step
(0.69·HF + 0.31·PBE + 0.44·P86) and the RI-MP2 correction with
asymmetric scaling (c_os = 0.55, c_ss = 0.09) on the converged
KS orbitals.
The published DSD-PBEP86 method usually pairs with the
Grimme-Antony-Ehrlich-Krieg D3(BJ) dispersion correction. This
dispatcher returns the un-dispersed XC + MP2 total — add the
dispersion correction via :func:`compute_d3bj` post-hoc when you
need the published "with-D" energy. A dedicated D4 parameter set
for DSD-PBEP86 is a separate upcoming item.
See :func:`run_double_hybrid` for keyword arguments and
:class:`DoubleHybridResult` for the return value.
"""
return run_double_hybrid(mol, basis, "dsd-pbep86", **kwargs)
def run_pwpb95(mol, basis, **kwargs):
"""PWPB95 (Goerigk & Grimme, *J. Chem. Theory Comput.* **7**, 291
(2011)) — spin-opposite-scaled double-hybrid meta-GGA.
Thin wrapper around :func:`run_double_hybrid` with
``functional_name="pwpb95"``. Runs the hybrid meta-GGA SCF step
(0.50·HF + 0.50·PW6-modified-mPW exchange + 0.731·B95 correlation)
and the post-SCF MP2 correction on the converged KS orbitals.
PWPB95 is the **SOS** member of the double-hybrid line: the
same-spin MP2 coefficient is zero, so the correction is
opposite-spin MP2 only (c_os = 0.269, c_ss = 0.0). It is also the
first meta-GGA double hybrid in vibe-qc — the SCF step runs through
the τ-dependent Kohn-Sham path because the B95 correlation
component is a meta-GGA. Unlike B2PLYP / DSD-PBEP86, PWPB95 mixes
*reparametrised* libxc components (the "PW6" mPW91 exchange and a
re-tuned B95 correlation); those parameters are baked into the
``Functional("pwpb95")`` resolver.
The published method is **PWPB95-D3(BJ)** — Goerigk-Grimme pair it
with Grimme's D3 Becke-Johnson dispersion. Pass ``dispersion="d3bj"``
(or ``"d4"`` for the D4 re-parameterisation) to fold the dispersion
correction into :attr:`DoubleHybridResult.e_total`; the default
(``dispersion=None``) returns the un-dispersed XC + MP2 total.
See :func:`run_double_hybrid` for keyword arguments and
:class:`DoubleHybridResult` for the return value.
"""
return run_double_hybrid(mol, basis, "pwpb95", **kwargs)
# ---------------------------------------------------------------------
# ωB97X-D — range-separated hybrid + Chai-Head-Gordon empirical
# dispersion. Like the double-hybrid dispatchers above, the complete
# ωB97X-D energy is "SCF + an additive correction": the libxc XC part
# (a range-separated hybrid GGA, id 471) plus the geometry-only "-D"
# dispersion term. ``functional="wb97x-d"`` through plain run_rks /
# run_uks gives the XC/SCF piece only; ``run_wb97x_d`` adds the
# dispersion for the published total — the same alias-vs-dispatcher
# split as ``b2plyp`` / ``run_b2plyp``.
# ---------------------------------------------------------------------
[docs]
class WB97XDResult:
"""Result of an ωB97X-D run: the range-separated-hybrid SCF result,
the Chai-Head-Gordon empirical dispersion correction, and the
combined total energy.
Attributes
----------
scf : RKSResult or UKSResult
The converged ωB97X-D range-separated-hybrid SCF step (the
libxc XC_HYB_GGA_XC_WB97X_D functional). ``RKSResult`` for a
closed-shell system, ``UKSResult`` for open-shell.
dispersion : DispersionResult
The Chai-Head-Gordon ("-D") dispersion correction. Exposes
``.energy`` (Hartree) and ``.gradient``.
e_total : float
Published ωB97X-D total energy (Hartree):
``scf.energy + dispersion.energy``.
functional : str
Always ``"wb97x-d"``.
"""
__slots__ = ("scf", "dispersion", "e_total", "functional")
[docs]
def __init__(self, scf, dispersion, e_total):
self.scf = scf
self.dispersion = dispersion
self.e_total = e_total
self.functional = "wb97x-d"
def __repr__(self):
return (
f"WB97XDResult(e_total={self.e_total:.10f}, "
f"e_scf={self.scf.energy:.10f}, "
f"e_dispersion={self.dispersion.energy:.10f})"
)
[docs]
def run_wb97x_d(mol, basis, options=None, *, output=None):
"""ωB97X-D (Chai & Head-Gordon, *Phys. Chem. Chem. Phys.* **10**,
6615 (2008)) — the full functional, XC + dispersion.
ωB97X-D is a range-separated hybrid GGA (libxc
``XC_HYB_GGA_XC_WB97X_D``) carrying an intrinsic empirical
dispersion correction of the older "DFT-D2" family. The two pieces
are independent — the dispersion is a geometry-only additive term
with no SCF coupling — so this dispatcher:
1. runs the range-separated-hybrid SCF (``run_rks`` for a
closed-shell system, ``run_uks`` for open-shell, picked from
``mol.multiplicity()``) with ``functional="wb97x-d"``;
2. computes the Chai-Head-Gordon dispersion
(:func:`vibeqc.compute_chg_dispersion`);
3. returns a :class:`WB97XDResult` with
``e_total = scf.energy + dispersion.energy``.
Range-separated hybrids run via direct SCF (the erf-attenuated
exchange is built on the fly); ``density_fit`` is not supported and
raises inside the SCF step.
Parameters
----------
mol, basis : Molecule, BasisSet
The molecular system. Closed- or open-shell.
options : RKSOptions or UKSOptions, optional
Options for the SCF step. The ``functional`` field is
overridden with ``"wb97x-d"``. If ``None``, a default is
created matching the system's shell type. For open-shell
ωB97X-D on orbital-near-degenerate radicals a level shift
(``options.level_shift ≈ 0.5``) may be needed — see the
ωB97X note in ``docs/user_guide/functionals.md``.
Returns
-------
WB97XDResult
"""
closed_shell = mol.multiplicity == 1
if options is None:
options = RKSOptions() if closed_shell else UKSOptions()
options.functional = "wb97x-d"
if closed_shell:
scf = run_rks(mol, basis, options)
else:
scf = run_uks(mol, basis, options)
if not scf.converged:
raise RuntimeError(
f"run_wb97x_d: ωB97X-D SCF did not converge "
f"(n_iter={scf.n_iter}, energy={scf.energy:.6f}). For "
"open-shell radicals try options.level_shift = 0.5."
)
disp = compute_chg_dispersion(mol)
if output is not None:
try:
from .output.citations import emit_citations
emit_citations(
output,
method="wb97x-d",
basis=basis.name,
functional="wb97x-d",
)
except Exception:
pass
return WB97XDResult(scf, disp, scf.energy + disp.energy)
# Implicit solvation (CPCM / COSMO) — v0.9.0 headline feature. Coupled
# self-consistently with the molecular SCF via macro-iteration over an
# apparent surface charge on a Lebedev-tessellated Bondi cavity. Wired
# through ``run_job(solvent=...)`` and the ASE calculator.
from . import solvation
# Non-mean-field solvers (v0.9.0)
from . import solvers as solvers # noqa: F401
from .bands import (
BandStructure,
DensityOfStates,
KPath,
ProjectedDensityOfStates,
ao_groups_per_atom,
ao_groups_per_atom_l,
band_structure,
band_structure_hcore,
density_of_states,
density_of_states_hcore,
density_of_states_projected,
density_of_states_projected_hcore,
kpath_from_segments,
)
from .basis_filter import (
BasisFilterReport,
DroppedPrimitive,
clear_filtered_basis_cache,
filter_basis_by_exponent,
format_basis_filter_report,
make_basis,
)
from .bipole_gradient import (
compute_bipole_gradient_fd,
compute_bipole_gradient_rhf,
compute_bipole_gradient_rks,
compute_bipole_gradient_uhf,
compute_bipole_gradient_uks,
compute_stress_tensor,
)
from .bipole_optimize import (
OptimizeResult,
relax_atoms,
relax_cell,
relax_cell_gradient,
relax_full,
)
from .build import (
BULK_LATTICE_CONSTANTS,
SlabInfo,
place_adsorbate,
slab,
)
from .build import (
molecule as build_molecule,
)
from .cphf import (
CPHFConvergenceError,
CPHFOptions,
cphf_solve_rhf,
dipole_polarizability_rhf,
)
from .crash_dump import (
active_crash_dump_stem,
classify_failure,
crash_dump_context,
dump_on_failure,
load_dump,
)
from .cube import (
CubeGrid,
make_uniform_grid,
write_cube_density,
write_cube_mo,
write_cube_mos,
)
from .dispersion_periodic import (
PeriodicDispersionResult,
compute_d3bj_periodic,
)
from .ecp_metadata import (
EcpHeader,
auto_ecp_centers,
library_for,
parse_sidecar_path,
sidecar_path_for,
)
from .eigs_preflight import (
DisambiguationReport,
EIGSReport,
TruncationOptimizationReport,
disambiguate_critical_overlap,
eigs_preflight,
format_disambiguation_report,
format_eigs_report,
format_truncation_optimization_report,
optimize_truncation,
)
from .ewald_composed import (
auto_ewald_alpha,
build_j_ewald_3d,
makov_payne_coefficient_cubic,
)
from .ewald_j import auto_grid, build_j_long_range
from .hessian import (
HessianFDOptions,
HessianResult,
compute_hessian_fd,
ir_intensities,
)
from .hessian_analytic import compute_hessian_rhf_analytic
from .hessian_analytic_rks import compute_hessian_rks_analytic
from .hessian_analytic_uhf import compute_hessian_uhf_analytic
from .hessian_analytic_uks import compute_hessian_uks_analytic
from .io import (
normal_mode_trajectory,
write_molden,
write_opt_trajectory,
write_orca_hess,
write_xyz_trajectory,
)
from .kpoints import KPoints, as_bloch_kmesh
from .lattice_screening import (
RcutStrategy,
estimate_rcut_pyscf,
estimate_rcut_pyscf_per_shell,
make_lattice_opts,
)
from .linear_dependence import (
DEFAULT_ERROR_THRESHOLD,
DEFAULT_NEGATIVE_THRESHOLD,
DEFAULT_WARN_THRESHOLD,
LinearDependenceError,
LinearDependenceOffender,
LinearDependenceReport,
check_linear_dependence,
check_overlap_matrix,
format_linear_dependence_report,
raise_if_severe,
scf_preflight_overlap_check,
)
from .madelung import (
apply_madelung_correction,
apply_madelung_correction_per_k,
cell_electron_charge,
cell_net_charge,
cell_nuclear_charge,
cubic_cell_edge,
madelung_alpha,
madelung_correction_scalar,
)
from .memory import (
InsufficientMemoryError,
MemoryEstimate,
available_memory_bytes,
check_memory,
estimate_memory,
format_memory_report,
)
from .molecular_optimize import (
MolecularOptimizeResult,
optimize_molecule,
)
from .molecule import from_xyz
from .neb import (
NEBImage,
NEBPath,
NEBResult,
interpolate_idpp,
interpolate_linear,
run_neb,
)
from .orthogonalisation import (
OrthogonalisationInfo,
canonical_orth,
orthogonalise_overlap,
pivoted_cholesky_orth,
symmetric_orth,
)
from .pbc_bipole import (
PBCBipoleEnergyComponents,
PBCBipoleRHFResult,
run_pbc_bipole_rhf,
)
from .pbc_bipole_rks import (
PBCBipoleRKSResult,
run_pbc_bipole_rks,
)
from .pbc_bipole_uhf import (
PBCBipoleUHFResult,
run_pbc_bipole_uhf,
)
from .pbc_bipole_uks import (
PBCBipoleUKSResult,
run_pbc_bipole_uks,
)
from .pbc_gdf import (
PBCExxDiv,
PBCGDFResult,
PBCMethod,
run_pbc_gdf_rhf,
)
from .perf import (
PerfScope,
PerfTracker,
active_tracker,
format_perf_report,
perf_log,
)
from .periodic_density import (
build_j_long_range_periodic,
evaluate_periodic_density_on_grid,
)
from .periodic_fock_multi_k import (
build_fock_2e_ewald3d_blocks,
build_periodic_fock_ewald3d_k,
)
# v0.10.x GAPW route — M1 + M2 infrastructure. Experimental;
# raises GAPWExperimentalWarning until the M3 full SCF wiring
# lands. See docs/design_periodic_gapw.md.
# v0.10.x GAPW route — M1 + M2 infrastructure. Experimental;
# raises GAPWExperimentalWarning until the M3 full SCF wiring
# lands. See docs/design_periodic_gapw.md.
from .periodic_gapw_grid import (
GAPWExperimentalWarning,
PlaneWaveGrid,
collocate_point_charges_on_grid,
make_grid,
nx_for_axis,
point_charge_self_energy,
recommend_cutoff_from_basis,
round_up_fft_friendly,
)
from .periodic_gapw_j import (
GpwEnergyBreakdown,
GpwJBuilder,
GpwScfResult,
collocate_density_on_grid,
compute_j_via_gpw,
evaluate_gpw_energy,
project_potential_to_ao,
run_periodic_rhf_gpw,
)
from .periodic_gapw_smearing import (
SmearedNuclearCharges,
alpha_to_sigma,
default_smearing_alpha_from_grid,
sigma_to_alpha,
smeared_nuclear_density_on_grid,
smeared_pairwise_overlap_energy,
smeared_self_energy,
smeared_v_ne_long_matrix,
)
from .periodic_gdf_blocks import (
bloch_sum_2c_eri_blocks,
bloch_sum_3c_eri_blocks,
gdf_block_phases,
)
from .periodic_gradient import compute_gradient_periodic_rhf_gamma
from .periodic_gradient_fd import compute_gradient_periodic_rhf_fd
from .periodic_gradient_multi_k import (
compute_gradient_periodic_rhf_multi_k,
compute_gradient_periodic_rks_multi_k,
)
from .periodic_gradient_open_shell import (
compute_gradient_periodic_uks_multi_k,
)
from .periodic_gradient_rks import compute_gradient_periodic_rks_gamma
from .periodic_grid import (
build_periodic_becke_grid,
extended_partition_atoms,
)
from .periodic_jk_direct import jk_via_direct
from .periodic_jk_method import (
PeriodicJKMethod,
describe_jk_method,
is_orthorhombic,
pick_jk_method,
validate_jk_method,
)
from .periodic_k_gdf import (
PeriodicKRHFGDFResult,
PeriodicKRKSGDFResult,
run_krhf_periodic_gdf,
run_krks_periodic_gdf,
)
from .periodic_ks_dispatch import (
run_rks_periodic_gamma_scf,
run_rks_periodic_scf,
)
from .periodic_orbitals import (
PrimitiveCellGrid,
evaluate_bloch_orbital,
make_primitive_cell_grid,
write_cube_mo_periodic,
write_xsf_density,
write_xsf_mo,
)
from .periodic_rhf_dispatch import (
run_rhf_periodic_gamma_scf,
run_rhf_periodic_scf,
)
from .periodic_rhf_ewald import (
PeriodicRHFEwaldResult,
run_rhf_periodic_gamma_ewald3d,
)
from .periodic_rhf_gdf import (
PeriodicRHFGDFResult,
run_rhf_periodic_gamma_gdf,
run_rks_periodic_gamma_gdf,
)
from .periodic_rhf_multi_k_ewald import (
PeriodicRHFMultiKEwaldResult,
run_rhf_periodic_multi_k_ewald3d,
)
from .periodic_rks_ewald import (
PeriodicRKSEwaldResult,
run_rks_periodic_gamma_ewald3d,
)
from .periodic_rks_multi_k_ewald import (
PeriodicRKSMultiKEwaldResult,
run_rks_periodic_multi_k_ewald3d,
)
from .periodic_runner import run_periodic_job
from .periodic_uhf_ewald import (
PeriodicUHFEwaldResult,
run_uhf_periodic_gamma_ewald3d,
)
from .periodic_uhf_multi_k_ewald import (
PeriodicUHFMultiKEwaldResult,
run_uhf_periodic_multi_k_ewald3d,
)
from .periodic_uks_ewald import (
PeriodicUKSEwaldResult,
run_uks_periodic_gamma_ewald3d,
)
from .periodic_uks_multi_k_ewald import (
PeriodicUKSMultiKEwaldResult,
run_uks_periodic_multi_k_ewald3d,
)
from .poscar import read_poscar, write_poscar
from .progress import ProgressLogger, resolve_progress
from .properties import (
DipoleMoment,
HirshfeldResult,
NaturalOrbitals,
center_of_mass,
dipole_moment,
hirshfeld_charges,
idempotency_deviation,
loewdin_charges,
mayer_bond_orders,
mulliken_charges,
natural_orbitals,
)
from .runner import run_job
from .scan import (
ScanResult,
relaxed_scan,
)
from .scf_log import format_basis_summary, format_scf_trace, log_scf_trace
from .settings_dump import format_settings, print_settings
from .smearing import (
EV_PER_HARTREE,
HARTREE_PER_RYDBERG,
KB_HARTREE_PER_K,
SMEARING_PRESETS,
SmearingOptions,
SmearingResolution,
SmearingResult,
apply_smearing,
aufbau_occupations_per_k,
closed_shell_periodic_occupations,
electronvolt_to_hartree_temperature,
fermi_dirac_occupations_per_k,
guess_smearing_temperature,
hartree_to_kelvin_temperature,
kelvin_to_hartree_temperature,
resolve_smearing_temperature,
rydberg_to_hartree_temperature,
temperature_in_hartree,
)
from .solvation import (
SOLVENT_PRESETS,
CavityTessellation,
CPCMResult,
SolventModel,
SolventResult,
build_cavity,
cpcm_gradient,
cpcm_gradient_fd,
resolve_solvent,
run_cpcm_scf,
)
from .solvers import (
DMRGOptions,
DMRGSolver,
Hamiltonian,
SelectedCIOptions,
SelectedCISolver,
SolverOptions,
SolverResult,
TranscorrelatedOptions,
V2RDMOptions,
V2RDMSolver,
build_hamiltonian_ao,
build_hamiltonian_mo,
build_transcorrelated_hamiltonian,
canonical_orthogonalize,
get_hf_orbital_provider,
solve_dmrg,
solve_selected_ci,
solve_v2rdm,
)
from .structured_log import (
StructuredLog,
active_structured_log,
run_fingerprint,
structured_log,
)
from .structured_log import (
emit as emit_structured,
)
from .symmetry_ao import (
AtomPermutation,
atom_permutation_under_op,
build_ao_permutation_matrix,
)
from .symmetry_core import (
euler_angles_from_rotation,
real_spherical_to_complex_unitary,
wigner_d_complex,
wigner_d_real,
wigner_small_d,
)
from .symmetry_fock_reduced import (
compute_jk_gamma_reduced,
)
from .symmetry_integrals import (
OrbitReducedLatticeMatrix,
compute_kinetic_lattice_with_orbits,
compute_nuclear_lattice_with_orbits,
compute_overlap_lattice_with_orbits,
symmorphic_operations,
verify_lattice_matrix_set_symmetry,
)
from .symmetry_integrals_reduced import (
compression_summary,
compute_kinetic_lattice_reduced,
compute_nuclear_lattice_reduced,
compute_overlap_lattice_reduced,
)
from .symmetry_lattice import (
LatticeOrbit,
LatticeOrbits,
compress_lattice_matrix_set,
identify_lattice_orbits,
lattice_to_cartesian_rotation,
reconstruct_lattice_matrix_set,
)
from .symmetry_lattice_c import (
AtomPairOrbit,
AtomPairOrbits,
compress_lattice_matrix_set_c,
identify_atom_pair_orbits,
reconstruct_lattice_matrix_set_c,
)
from .symmetry_salc import (
PointGroupCharacters,
character_table,
symmetry_project_matrix,
)
from .symmetry_scf import (
build_ao_permutation_cache,
symmetrize_density,
symmetrize_fock,
symmetrize_forces,
symmetrize_matrix,
)
from .system_info import system_info, write_system_manifest
from .thermo import (
ThermoOptions,
ThermoResult,
compute_thermochemistry,
)
from .xsf import write_bxsf, write_xsf_structure, write_xsf_volume
# Attach the XYZ parser as a Molecule classmethod so `Molecule.from_xyz(...)`
# works from Python. The native Molecule class was defined in C++ via pybind11
# and can be augmented at runtime.
Molecule.from_xyz = staticmethod(from_xyz) # type: ignore[attr-defined]
# ``__version__`` is sourced from the installed package metadata (see
# ``banner.VIBEQC_VERSION``). Hard-coding here would drift from
# pyproject.toml on release bumps.
__version__ = VIBEQC_VERSION
__all__ = [
"__version__",
"VIBEQC_VERSION",
"banner",
"library_versions",
"print_banner",
"InsufficientMemoryError",
"MemoryEstimate",
"available_memory_bytes",
"check_memory",
"estimate_memory",
"format_memory_report",
"Atom",
"BandDiag",
"BandStructure",
"CubeGrid",
"make_uniform_grid",
"write_cube_density",
"write_cube_mo",
"write_cube_mos",
"write_bxsf",
"write_xsf_structure",
"write_xsf_volume",
"DensityOfStates",
"KPath",
"ProjectedDensityOfStates",
"ao_groups_per_atom",
"ao_groups_per_atom_l",
"band_structure",
"band_structure_hcore",
"density_of_states",
"density_of_states_hcore",
"density_of_states_projected",
"density_of_states_projected_hcore",
"kpath_from_segments",
"BasisSet",
"BlochKMesh",
"CoulombMethod",
"Crystal",
"ADIIS",
"D3BJParams",
"DIIS",
"DipoleIntegrals",
"DipoleMoment",
"DispersionResult",
"EDIIS",
"EwaldOptions",
"InitialGuess",
"IrreducibleKMesh",
"JKBuilder",
"JKMatrices",
"LatticeCell",
"LatticeMatrixSet",
"LatticeSumOptions",
"MP2Options",
"Molecule",
"PairJKContribution",
"PeriodicKSOptions",
"PeriodicKSResult",
"PeriodicRHFOptions",
"PeriodicRHFResult",
"PeriodicSCFOptions",
"PeriodicSystem",
"BULK_LATTICE_CONSTANTS",
"SlabInfo",
"build_molecule",
"place_adsorbate",
"slab",
"PeriodicDispersionResult",
"compute_d3bj_periodic",
"PeriodicXCContribution",
"PeriodicUKSXCContribution",
"RHFOptions",
"RHFResult",
"MP2Result",
"RKSOptions",
"RKSResult",
"SCFAccelerator",
"SCFIteration",
"SCFMode",
"NewtonOptions",
"SOSCFOptions",
"TRAHOptions",
"ShellInfo",
"SpaceGroup",
"SymmetryOp",
"UHFOptions",
"UHFResult",
"UKSOptions",
"UKSResult",
"UMP2Options",
"UMP2Result",
"Functional",
"Grid",
"GridOptions",
"UHFXCKernelBuilder",
"XCKernelBuilder",
"CPHFConvergenceError",
"CPHFOptions",
"HessianFDOptions",
"HessianResult",
"ThermoOptions",
"ThermoResult",
"XCKind",
"analyze_symmetry",
"attach_symmetry",
"bloch_sum",
"build_grid",
"build_fock_2e_real_space",
"build_jk_2e_real_space",
"build_jk_2e_real_space_explicit",
"build_jk_gamma_molecular_limit",
"build_jk_gamma_molecular_limit_explicit",
"build_jk_pair_contributions",
"build_xc_periodic",
"build_xc_periodic_uks",
"center_of_mass",
"compute_d3bj",
"compute_2c_eri",
"compute_2c_eri_gradient_contribution",
"compute_2c_eri_gradient_weighted",
"compute_3c_eri",
"compute_3c_eri_gradient_contribution",
"compute_3c_eri_gradient_weighted",
"build_cosx_q",
"build_cosx_schwarz",
"compute_cosx_k",
"compute_cosx_k_gradient_contribution",
"compute_robust_cosx_k",
"make_cosx_jk_builder",
"make_df_jk_builder",
"make_direct_jk_builder",
"make_four_index_jk_builder",
"make_periodic_gamma_jk_builder",
"compute_df_j_gradient",
"compute_df_jk_gradient",
"compute_df_k_gradient",
"compute_dipole",
"auto_ecp_centers",
"compute_ecp_matrix",
"ECPCenter",
"EcpHeader",
"library_for",
"parse_sidecar_path",
"sidecar_path_for",
"compute_eri",
"compute_external_charge_density_gradient",
"ExternalChargeGradient",
"DensityFitting",
"DensityFittingInfo",
"default_aux_basis_for",
"d3_coordination_numbers",
"d3_r2r4",
"d3_rcov",
"d3bj_params_for",
"dftd3_available",
"HubbardSite",
"ao_group_indices",
"compute_occupation_matrices",
"compute_dudarev_energy",
"compute_2c_eri_lattice",
"compute_2c_eri_lattice_blocks",
"compute_2c_eri_lattice_sr",
"compute_3c_eri_lattice",
"compute_3c_eri_lattice_blocks",
"compute_3c_eri_lattice_sr",
"compute_kinetic_lattice",
"compute_kinetic_lattice_explicit",
"compute_nuclear_erfc_lattice",
"compute_nuclear_lattice",
"compute_nuclear_lattice_ewald",
"compute_nuclear_lattice_explicit",
"compute_overlap_lattice",
"compute_overlap_lattice_explicit",
"compute_gradient",
"compute_gradient_rks",
"compute_gradient_uhf",
"compute_gradient_uks",
"compute_hessian_fd",
"compute_hessian_rhf_analytic",
"compute_hessian_rks_analytic",
"KPoints",
"as_bloch_kmesh",
"compute_hessian_uhf_analytic",
"compute_hessian_uks_analytic",
"compute_gradient_periodic_rhf_fd",
"compute_gradient_periodic_rhf_gamma",
"compute_gradient_periodic_rhf_multi_k",
"compute_gradient_periodic_rks_gamma",
"compute_gradient_periodic_rks_multi_k",
"compute_gradient_periodic_uks_multi_k",
"compute_thermochemistry",
"cphf_solve_rhf",
"dipole_polarizability_rhf",
"ir_intensities",
"compute_kinetic",
"evaluate_ao",
"evaluate_ao_with_gradient",
"evaluate_bloch_ao",
"evaluate_bloch_orbital",
"make_polarised_gga_xc_kernel_builder",
"make_polarised_lda_xc_kernel_builder",
"make_polarised_xc_kernel_builder",
"make_unpolarised_xc_kernel_builder",
"get_num_threads",
"compute_nuclear",
"compute_overlap",
"sad_density",
"diagonalize_bloch",
"dipole_moment",
"hirshfeld_charges",
"HirshfeldResult",
"idempotency_deviation",
"loewdin_charges",
"mayer_bond_orders",
"mulliken_charges",
"natural_orbitals",
"NaturalOrbitals",
"direct_lattice_cells",
"ewald_nuclear_potential",
"ewald_nuclear_repulsion",
"ewald_point_charge_energy",
"ewald_point_charge_potential",
"auto_grid",
"auto_ewald_alpha",
"build_j_ewald_3d",
"build_j_long_range",
"makov_payne_coefficient_cubic",
"PeriodicRHFEwaldResult",
"run_rhf_periodic_gamma_ewald3d",
"PeriodicRHFGDFResult",
"run_rhf_periodic_gamma_gdf",
"run_rks_periodic_gamma_gdf",
"PBCExxDiv",
"PBCGDFResult",
"PBCMethod",
"run_pbc_gdf_rhf",
"PBCBipoleEnergyComponents",
"PBCBipoleRHFResult",
"run_pbc_bipole_rhf",
"PBCBipoleUHFResult",
"run_pbc_bipole_uhf",
"PBCBipoleRKSResult",
"run_pbc_bipole_rks",
"PBCBipoleUKSResult",
"run_pbc_bipole_uks",
"RcutStrategy",
"estimate_rcut_pyscf",
"estimate_rcut_pyscf_per_shell",
"make_lattice_opts",
"PeriodicKRHFGDFResult",
"PeriodicKRKSGDFResult",
"run_krhf_periodic_gdf",
"run_krks_periodic_gdf",
"bloch_sum_2c_eri_blocks",
"bloch_sum_3c_eri_blocks",
"gdf_block_phases",
"run_periodic_job",
"PeriodicJKMethod",
"pick_jk_method",
"validate_jk_method",
"describe_jk_method",
"is_orthorhombic",
"jk_via_direct",
"PeriodicUHFEwaldResult",
"run_uhf_periodic_gamma_ewald3d",
"PeriodicUHFMultiKEwaldResult",
"run_uhf_periodic_multi_k_ewald3d",
"PeriodicRKSEwaldResult",
"run_rks_periodic_gamma_ewald3d",
"PeriodicRKSMultiKEwaldResult",
"run_rks_periodic_multi_k_ewald3d",
"PeriodicUKSEwaldResult",
"run_uks_periodic_gamma_ewald3d",
"PeriodicUKSMultiKEwaldResult",
"run_uks_periodic_multi_k_ewald3d",
"build_j_long_range_periodic",
"evaluate_periodic_density_on_grid",
"PrimitiveCellGrid",
"make_primitive_cell_grid",
"write_cube_mo_periodic",
"write_xsf_density",
"write_xsf_mo",
"build_fock_2e_ewald3d_blocks",
"build_periodic_fock_ewald3d_k",
"PeriodicRHFMultiKEwaldResult",
"run_rhf_periodic_multi_k_ewald3d",
"run_rhf_periodic_gamma_scf",
"run_rhf_periodic_scf",
"run_rks_periodic_gamma_scf",
"run_rks_periodic_scf",
"build_periodic_becke_grid",
"extended_partition_atoms",
"OrbitReducedLatticeMatrix",
"compress_lattice_matrix_set_c",
"compression_summary",
"compute_kinetic_lattice_reduced",
"compute_kinetic_lattice_with_orbits",
"compute_jk_gamma_reduced",
"compute_nuclear_lattice_reduced",
"compute_nuclear_lattice_with_orbits",
"compute_overlap_lattice_reduced",
"compute_overlap_lattice_with_orbits",
"identify_atom_pair_orbits",
"reconstruct_lattice_matrix_set_c",
"symmorphic_operations",
"verify_lattice_matrix_set_symmetry",
"apply_madelung_correction",
"build_ao_permutation_cache",
"symmetrize_density",
"symmetrize_fock",
"symmetrize_forces",
"symmetrize_matrix",
"PointGroupCharacters",
"character_table",
"symmetry_project_matrix",
"apply_madelung_correction_per_k",
"cell_electron_charge",
"cell_net_charge",
"cell_nuclear_charge",
"cubic_cell_edge",
"madelung_alpha",
"madelung_correction_scalar",
"DEFAULT_ERROR_THRESHOLD",
"DEFAULT_NEGATIVE_THRESHOLD",
"DEFAULT_WARN_THRESHOLD",
"LinearDependenceError",
"LinearDependenceOffender",
"LinearDependenceReport",
"check_linear_dependence",
"check_overlap_matrix",
"format_linear_dependence_report",
"raise_if_severe",
"scf_preflight_overlap_check",
"BasisFilterReport",
"DroppedPrimitive",
"clear_filtered_basis_cache",
"filter_basis_by_exponent",
"format_basis_filter_report",
"make_basis",
"DisambiguationReport",
"EIGSReport",
"TruncationOptimizationReport",
"disambiguate_critical_overlap",
"eigs_preflight",
"format_disambiguation_report",
"format_eigs_report",
"format_truncation_optimization_report",
"optimize_truncation",
"OrthogonalisationInfo",
"canonical_orth",
"orthogonalise_overlap",
"pivoted_cholesky_orth",
"symmetric_orth",
"euler_angles_from_rotation",
"real_spherical_to_complex_unitary",
"wigner_d_complex",
"wigner_d_real",
"wigner_small_d",
"AtomPermutation",
"atom_permutation_under_op",
"build_ao_permutation_matrix",
"LatticeOrbit",
"LatticeOrbits",
"compress_lattice_matrix_set",
"identify_lattice_orbits",
"lattice_to_cartesian_rotation",
"reconstruct_lattice_matrix_set",
"AtomPairOrbit",
"AtomPairOrbits",
"compress_lattice_matrix_set_c",
"identify_atom_pair_orbits",
"reconstruct_lattice_matrix_set_c",
"KB_HARTREE_PER_K",
"EV_PER_HARTREE",
"HARTREE_PER_RYDBERG",
"SMEARING_PRESETS",
"SmearingOptions",
"SmearingResolution",
"SmearingResult",
"apply_smearing",
"aufbau_occupations_per_k",
"closed_shell_periodic_occupations",
"electronvolt_to_hartree_temperature",
"fermi_dirac_occupations_per_k",
"guess_smearing_temperature",
"hartree_to_kelvin_temperature",
"kelvin_to_hartree_temperature",
"resolve_smearing_temperature",
"rydberg_to_hartree_temperature",
"temperature_in_hartree",
"hartree_energy_on_grid",
"solve_poisson_coulomb",
"solve_poisson_erf_screened",
"format_basis_summary",
"format_scf_trace",
"format_settings",
"from_xyz",
"hello",
"irreducible_kpoints",
"libecpint_version",
"libint_version",
"libxc_version",
"log_scf_trace",
"monkhorst_pack",
"nuclear_repulsion_per_cell",
"PerfScope",
"PerfTracker",
"active_tracker",
"format_perf_report",
"perf_log",
"print_settings",
"ProgressLogger",
"StructuredLog",
"active_structured_log",
"active_crash_dump_stem",
"classify_failure",
"crash_dump_context",
"dump_on_failure",
"emit_structured",
"load_dump",
"run_fingerprint",
"structured_log",
"read_poscar",
"real_space_density_from_kpoints",
"resolve_progress",
"run_job",
"D4Result",
"DoubleHybridResult",
"D4_WEIGHTING_FACTOR",
"EEQOptions",
"EEQResult",
"ReferenceSystem",
"all_reference_elements",
"all_reference_systems",
"build_reference_molecule",
"casimir_polder_c6",
"cn_gaussian_weights",
"compute_d4",
"coupled_polarizability_imag_freq",
"dftd4_available",
"eeq_charges",
"eeq_coordination_numbers",
"imaginary_frequency_grid",
"london_c6_single_pole",
"molecular_c6",
"reference_systems_for",
"rhf_result_from_rks",
"uncoupled_polarizability_imag_freq",
"run_b2plyp",
"run_double_hybrid",
"run_dsd_pbep86",
"run_pwpb95",
"run_wb97x_d",
"WB97XDResult",
"compute_chg_dispersion",
"chg_max_supported_Z",
"run_mp2",
"run_rhf_scf_with_jk",
"run_rks_scf_with_jk",
"run_uhf_scf_with_jk",
"run_uks_scf_with_jk",
"run_rhf",
"run_rhf_periodic",
"run_rhf_periodic_gamma",
"run_rks",
# v0.9.0 — implicit solvation (CPCM/COSMO).
"solvation",
"SOLVENT_PRESETS",
"CavityTessellation",
"CPCMResult",
"SolventModel",
"SolventResult",
"build_cavity",
"cpcm_gradient",
"cpcm_gradient_fd",
"resolve_solvent",
"run_cpcm_scf",
"run_rks_periodic",
"run_scs_mp2",
"run_scs_ump2",
"run_sos_mp2",
"run_sos_ump2",
"run_uhf",
"run_uks",
"run_ump2",
"set_num_threads",
"spglib_version",
"system_info",
"to_primitive",
"write_molden",
"write_system_manifest",
"write_orca_hess",
"write_xyz_trajectory",
"write_opt_trajectory",
"normal_mode_trajectory",
"write_poscar",
# v0.9.0 — gCP (Kruse-Grimme 2012)
"GCPDataMissing",
"GCPParams",
"GCPResult",
"available_gcp_basis_sets",
"compute_gcp",
"gcp_params_for",
# v0.9.0 — composite 3c methods
"CompositeAvailability",
"CompositeRecipe",
"CompositeUnavailable",
"ShortRangeCorrection",
"list_composites",
"resolve_composite",
# v0.8.x — native molecular geometry optimization (no ASE required)
"MolecularOptimizeResult",
"optimize_molecule",
# v0.8.x — relaxed coordinate scans (molecular + periodic)
"ScanResult",
"relaxed_scan",
# v0.9.x — Nudged Elastic Band (NEB). Increment 1 ships path-
# construction primitives + dataclasses; Increment 2 adds the
# improved-tangent driver (run_neb / NEBResult).
"NEBImage",
"NEBPath",
"NEBResult",
"interpolate_idpp",
"interpolate_linear",
"run_neb",
]