Source code for vibeqc

"""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", ]