pub struct Basis { /* private fields */ }Expand description
An ordered collection of shells defining the atomic-orbital basis.
Implementations§
Source§impl Basis
impl Basis
Sourcepub fn eri_2c(&self) -> Vec<f64>
pub fn eri_2c(&self) -> Vec<f64>
2-center Coulomb metric (P|Q) = ∫∫ φ_P(1) r₁₂⁻¹ φ_Q(2) d1 d2 over
self as the auxiliary basis.
Row-major [naux, naux] with naux = self.nao(), kind-aware (spherical
shells contribute their 2l+1 components). The matrix is exactly
symmetric: each canonical shell pair is evaluated once and mirrored,
so (P|Q) and (Q|P) are the same f64.
Sourcepub fn eri_2c_with(&self, engine: Engine) -> Vec<f64>
pub fn eri_2c_with(&self, engine: Engine) -> Vec<f64>
Like Basis::eri_2c but forces a specific Engine (or
Engine::Auto). Both engines produce the same metric to tolerance.
Sourcepub fn eri_2c_kernel(&self, k: EriKernel) -> Vec<f64>
pub fn eri_2c_kernel(&self, k: EriKernel) -> Vec<f64>
2-center metric over the chosen EriKernel — layout identical to
Basis::eri_2c (row-major [naux, naux], exactly symmetric).
EriKernel::Coulomb routes to Basis::eri_2c itself (bit-identical
output); EriKernel::Erf evaluates (P| erf(ω·r₁₂)/r₁₂ |Q) via the
same zero-exponent unit-s dummy construction, on the Rys engine (see
Basis::eri_kernel).
§Panics
Panics if k is Erf { omega } with ω ≤ 0, NaN, or infinite.
Sourcepub fn eri_3c_block(
&self,
aux: &Basis,
ish: usize,
jsh: usize,
psh: usize,
) -> Vec<f64>
pub fn eri_3c_block( &self, aux: &Basis, ish: usize, jsh: usize, psh: usize, ) -> Vec<f64>
One 3-center Coulomb shell block (ij|P): shells ish, jsh over self
(the main basis), shell psh over aux (the auxiliary basis).
Row-major [n_i, n_j, n_p] with P fastest-varying (so a
per-shell-pair GEMM against the metric is contiguous), kind-aware like
Basis::eri_block: n_x is the shell’s n_func (n_cart for
Cartesian, 2l+1 for spherical) in the usual component order.
Sourcepub fn eri_3c_block_with(
&self,
engine: Engine,
aux: &Basis,
ish: usize,
jsh: usize,
psh: usize,
) -> Vec<f64>
pub fn eri_3c_block_with( &self, engine: Engine, aux: &Basis, ish: usize, jsh: usize, psh: usize, ) -> Vec<f64>
Like Basis::eri_3c_block but forces a specific Engine (or
Engine::Auto). Both engines produce the same block to tolerance.
Sourcepub fn eri_3c_block_kernel(
&self,
aux: &Basis,
ish: usize,
jsh: usize,
psh: usize,
k: EriKernel,
) -> Vec<f64>
pub fn eri_3c_block_kernel( &self, aux: &Basis, ish: usize, jsh: usize, psh: usize, k: EriKernel, ) -> Vec<f64>
One 3-center shell block over the chosen EriKernel — layout identical
to Basis::eri_3c_block (row-major [n_i, n_j, n_p], P fastest).
EriKernel::Coulomb routes to Basis::eri_3c_block itself
(bit-identical output); EriKernel::Erf evaluates
(ij| erf(ω·r₁₂)/r₁₂ |P) via the same zero-exponent unit-s dummy
construction, on the Rys engine (see Basis::eri_kernel). The Coulomb
Schwarz factors (Basis::schwarz_bounds / Basis::schwarz_aux_bounds)
remain valid upper bounds for the attenuated blocks (erf(ωr)/r ≤ 1/r).
§Panics
Panics if k is Erf { omega } with ω ≤ 0, NaN, or infinite.
Sourcepub fn schwarz_aux_bounds(&self) -> Vec<f64>
pub fn schwarz_aux_bounds(&self) -> Vec<f64>
Auxiliary-side Schwarz factors over self as the aux basis, one per
shell: QP[p] = sqrt(max_{μ∈p} (μ|μ)) with (μ|μ) the diagonal of the
2-center block (p|p).
Together with the main-basis Basis::schwarz_bounds this bounds every
3-center integral: |(μν|P)| ≤ Q[i,j] · QP[p] for μν in shell pair
(i, j) and P in aux shell p (Cauchy–Schwarz in the Coulomb inner
product). Kind-aware, like the 4-center bounds.
Sourcepub fn schwarz_aux_bounds_with(&self, engine: Engine) -> Vec<f64>
pub fn schwarz_aux_bounds_with(&self, engine: Engine) -> Vec<f64>
Like Basis::schwarz_aux_bounds but with a forced Engine. The
bound is engine-independent to tolerance.
Sourcepub fn eri_3c_builder<'a>(&'a self, aux: &'a Basis) -> Eri3cBuilder<'a>
pub fn eri_3c_builder<'a>(&'a self, aux: &'a Basis) -> Eri3cBuilder<'a>
Create a parallel-ready Eri3cBuilder filling (ij|P) with ij over
self (the main basis) and P over aux, with the default
Engine::Auto dispatch. Equivalent to Eri3cBuilder::new.
Source§impl Basis
impl Basis
Sourcepub fn ecp(&self, ecps: &[Ecp]) -> Vec<f64>
pub fn ecp(&self, ecps: &[Ecp]) -> Vec<f64>
ECP matrix ⟨μ| Σ_A U_A |ν⟩, nao × nao row-major (same layout, AO
ordering, and normalization as Basis::overlap). Contributions from
all listed ECPs are summed; an empty list (or ECPs with empty / all-zero
expansions) yields an exactly-zero matrix. The matrix is exactly
symmetric by construction (the upper triangle is the transpose of the
computed lower triangle).
See the module docs for the evaluation method, accuracy, and screening.
§Panics
Panics if an Ecp::atom index is out of range of Basis::atoms.
Sourcepub fn ecp_grad_contract(
&self,
ecps: &[Ecp],
gamma: &[f64],
) -> Result<Vec<[f64; 3]>, IntegralError>
pub fn ecp_grad_contract( &self, ecps: &[Ecp], gamma: &[f64], ) -> Result<Vec<[f64; 3]>, IntegralError>
Contracted ECP nuclear gradient: per-atom dE/dR_a for
E = Σ_{μν} γ_{μν} ⟨μ| Σ_A U_A |ν⟩, never materializing the per-atom
derivative matrices.
Mirrors Basis::eri_grad_contract: the result is the raw
derivative dE/dR_a (not the force −dE/dR_a), one [x, y, z]
triple per atom in Basis::atoms order, atomic units (hartree/bohr).
gamma is the row-major nao × nao density (same layout as
Basis::ecp); a non-symmetric gamma is handled exactly — only its
symmetric part contributes, as in the energy expression.
§Method
The bra/ket Gaussian centers are differentiated with the standard shift
relation ∂/∂A_i χ_a = 2α·χ_{a+1_i} − a_i·χ_{a−1_i}, evaluated through
the same analytic-angular × radial-quadrature machinery as
Basis::ecp (the raised/lowered blocks reuse the value path with
per-primitive weights 2α·w / w). The ECP-center contribution is
obtained from translational invariance per shell-pair × ECP
triplet: ∂/∂C = −(∂/∂A + ∂/∂B) — exact for these integrals, and it
makes Σ_a dE/dR_a = 0 hold to round-off by construction (each
contribution is added to a shell’s atom and subtracted from the ECP’s
atom). Degenerate geometries (shells on the ECP center) need no special
casing — the radial/angular path is NaN-free there.
§Screening
A shell pair is skipped only when its symmetrized density block
γ + γᵀ is exactly zero; within a pair the value path’s conservative
e^{−120} peak-bound primitive screen applies (see the
module docs).
§Errors
IntegralError::AngularMomentumTooHighForGradient if any shell has
l > MAX_ECP_GRAD_L, or IntegralError::GammaLengthMismatch if
gamma.len() != nao².
§Panics
Panics if an Ecp::atom index is out of range of Basis::atoms
(as Basis::ecp), or if an ECP has more than 5 projector channels
(l > 4 projectors are outside the validated gradient range).
Source§impl Basis
impl Basis
Sourcepub fn eri_builder(&self) -> EriBuilder<'_>
pub fn eri_builder(&self) -> EriBuilder<'_>
Create a parallel-ready EriBuilder for this basis (default
Engine::Auto dispatch). Equivalent to EriBuilder::new.
Source§impl Basis
impl Basis
Sourcepub fn overlap_grad(&self) -> Result<Gradient1e, IntegralError>
pub fn overlap_grad(&self) -> Result<Gradient1e, IntegralError>
Per-atom gradient of the overlap matrix, ∂S/∂R_c.
§Errors
IntegralError::AngularMomentumTooHighForGradient if any shell has
l > MAX_GRAD_L.
Sourcepub fn kinetic_grad(&self) -> Result<Gradient1e, IntegralError>
pub fn kinetic_grad(&self) -> Result<Gradient1e, IntegralError>
Sourcepub fn nuclear_grad(
&self,
charges: &[(Vec3, f64)],
) -> Result<Gradient1e, IntegralError>
pub fn nuclear_grad( &self, charges: &[(Vec3, f64)], ) -> Result<Gradient1e, IntegralError>
Per-atom gradient of the nuclear-attraction matrix, ∂V/∂R_c, for the
point charges charges = [(center, Z)].
Includes both the basis-function derivatives and the operator
(Hellmann–Feynman) term: the 1/|r−C| operator depends on the charge
position C, so moving the atom carrying charge C contributes
∂_C ⟨a|V_C|b⟩. By the exact single-charge translational identity
∂_C = −(∂_A + ∂_B), this term is assembled from the same basis-center
derivatives, placed on the charge’s atom.
§Errors
IntegralError::AngularMomentumTooHighForGradient as above, or
IntegralError::ChargeNotOnAtom if a charge center is not a basis atom.
Sourcepub fn eri_grad(&self) -> Result<GradientEri, IntegralError>
pub fn eri_grad(&self) -> Result<GradientEri, IntegralError>
Per-atom gradient of the electron-repulsion tensor, ∂(ij|kl)/∂R_c.
Uses the dispatch policy (Engine::Auto); see Basis::eri_grad_with
to force an engine.
§Errors
IntegralError::AngularMomentumTooHighForGradient if any shell has
l > MAX_GRAD_L.
Sourcepub fn eri_grad_with(
&self,
engine: Engine,
) -> Result<GradientEri, IntegralError>
pub fn eri_grad_with( &self, engine: Engine, ) -> Result<GradientEri, IntegralError>
Like Basis::eri_grad but forces a specific Engine. Both engines
produce the same gradient to tolerance; forcing exists so tests exercise
each derivative path on the same quartets.
§Errors
As Basis::eri_grad.
Sourcepub fn eri_grad_contract(
&self,
gamma: &[f64],
) -> Result<Vec<[f64; 3]>, IntegralError>
pub fn eri_grad_contract( &self, gamma: &[f64], ) -> Result<Vec<[f64; 3]>, IntegralError>
Contraction of the ERI geometric derivative with a two-particle density
gamma, never materializing the nao⁴ derivative tensor:
F_c = Σ_{μνλσ} Γ_{μνλσ} · ∂(μν|λσ)/∂R_c (one [x, y, z] per atom)gamma uses the same row-major nao⁴ layout (and hence the same 8-fold
symmetry convention) as Basis::eri. The result equals contracting
gamma against each GradientEri::block of Basis::eri_grad, but
peak memory is one shell-quartet block instead of natom·3·nao⁴. Atom
order is Basis::atoms.
Uses the dispatch policy (Engine::Auto); see
Basis::eri_grad_contract_with to force an engine.
§Errors
IntegralError::AngularMomentumTooHighForGradient if any shell has
l > MAX_GRAD_L, or IntegralError::GammaLengthMismatch if
gamma.len() != nao⁴.
Sourcepub fn eri_grad_contract_with(
&self,
engine: Engine,
gamma: &[f64],
) -> Result<Vec<[f64; 3]>, IntegralError>
pub fn eri_grad_contract_with( &self, engine: Engine, gamma: &[f64], ) -> Result<Vec<[f64; 3]>, IntegralError>
Like Basis::eri_grad_contract but forces a specific Engine.
Both engines produce the same contraction to tolerance.
§Errors
Sourcepub fn eri_grad_contract_kernel(
&self,
gamma: &[f64],
k: EriKernel,
) -> Result<Vec<[f64; 3]>, IntegralError>
pub fn eri_grad_contract_kernel( &self, gamma: &[f64], k: EriKernel, ) -> Result<Vec<[f64; 3]>, IntegralError>
Like Basis::eri_grad_contract but over the chosen EriKernel —
the density-contracted geometric ERI derivative of the long-range
(range-separated) operator, for forces of RSH SCF energies.
EriKernel::Coulombroutes toBasis::eri_grad_contractitself: the output is bit-identical.EriKernel::Erf{ omega }evaluates the derivative oferf(ω·r₁₂)/r₁₂integrals on the Rys engine. The attenuation enters only through the 0th-order kernel (F_m → F_m^ω, realized as the root/weight transformx → s·x(sT),w → √s·w(sT)withs = ω²/(ρ+ω²)); the Gaussian center-derivative relation∂/∂A χ = 2α·χ_{l+1} − l·χ_{l−1}acts on the basis functions, not the two-electron operator, so the transform commutes with the gradient structure and the Coulomb recurrences are reused unchanged (Gill & Adamson, Chem. Phys. Lett. 261, 105 (1996); Ahlrichs, Phys. Chem. Chem. Phys. 8, 3072 (2006)).
Same units, layout (Vec<[f64; 3]> in Basis::atoms order), gamma
convention, and l ≤ MAX_GRAD_L limit as Basis::eri_grad_contract.
§Errors
§Panics
Panics if k is Erf { omega } with ω ≤ 0, NaN, or infinite.
Sourcepub fn eri_3c_grad_contract(
&self,
aux: &Basis,
gamma: &[f64],
) -> Result<Vec<[f64; 3]>, IntegralError>
pub fn eri_3c_grad_contract( &self, aux: &Basis, gamma: &[f64], ) -> Result<Vec<[f64; 3]>, IntegralError>
Density-contracted geometric gradient of the 3-center density-fitting
Coulomb integrals (μν|P):
F_c = Σ_{μν,P} Γ_{μν,P} · ∂(μν|P)/∂R_c (one [x, y, z] per atom)μν run over self (the orbital basis) and P over aux; gamma is
row-major [μ, ν, P] with P fastest — the same layout as the dense
Eri3cBuilder::build tensor, length nao²·naux. No symmetry of
gamma is assumed (the full μν sweep is contracted; a μν-symmetric
gamma simply works).
Atom convention: aux must sit on exactly the atoms of self
(Basis::atoms lists bitwise equal, including order — the practical
RI case where the fitting basis shares the orbital basis’s centers).
The result has one [x, y, z] per shared atom, in Basis::atoms
order, and sums to zero over atoms (translational invariance).
The derivative is taken via the same zero-exponent unit-s dummy
construction as Basis::eri_3c_block; only the three real centers
(μ, ν, P) are differentiated — the dummy is the constant function
1, which does not move with any atom, so its center derivative is
exactly zero by construction (it is never evaluated). Uses the
Engine::Auto dispatch policy.
§Errors
IntegralError::AngularMomentumTooHighForGradientif any shell ofselforauxhasl > MAX_GRAD_L.IntegralError::ChargeNotOnAtomifaux.atoms() != self.atoms()(reused as the atom-mismatch error — the enum is exhaustive, so no new variant is added;centeris the first non-shared / out-of-order atom).IntegralError::GammaLengthMismatchifgamma.len() != nao²·naux.
Sourcepub fn eri_2c_grad_contract(
&self,
gamma: &[f64],
) -> Result<Vec<[f64; 3]>, IntegralError>
pub fn eri_2c_grad_contract( &self, gamma: &[f64], ) -> Result<Vec<[f64; 3]>, IntegralError>
Density-contracted geometric gradient of the 2-center density-fitting
Coulomb metric (P|Q) over self as the auxiliary basis:
F_c = Σ_{PQ} γ_{PQ} · ∂(P|Q)/∂R_c (one [x, y, z] per atom)gamma is row-major [naux, naux] (naux = Basis::nao), the same
layout as Basis::eri_2c. The contraction is the full double sum
Σ_{PQ} γ_{PQ} ∂(P|Q) with no implicit symmetrization — an
asymmetric gamma is contracted as given ((P|Q) = (Q|P), so a caller
holding only a triangle should symmetrize first).
Both centers P and Q are differentiated with the same
center-derivative recurrences as Basis::eri_grad_contract; the two
zero-exponent unit-s dummies are constant functions with exactly zero
derivative and are never differentiated. Result is per atom in
Basis::atoms order and sums to zero over atoms. Uses the
Engine::Auto dispatch policy.
§Errors
IntegralError::AngularMomentumTooHighForGradient if any shell has
l > MAX_GRAD_L, or IntegralError::GammaLengthMismatch if
gamma.len() != naux².
Source§impl Basis
impl Basis
Sourcepub fn grid_coulomb(&self, points: &[[f64; 3]]) -> Vec<f64>
pub fn grid_coulomb(&self, points: &[[f64; 3]]) -> Vec<f64>
Per-grid-point Coulomb matrices A^g_{μν} = ⟨μ| 1/|r−r_g| |ν⟩, one
dense nao × nao matrix per point.
Output layout: row-major [g][μ][ν] — the point index g is slowest,
so &out[g·nao²..(g+1)·nao²] is the g-th matrix (nao =
Basis::nao; spherical shells contribute their 2l+1 components).
§Sign convention
A^g is the positive kernel ⟨μ| 1/|r−r_g| |ν⟩ — the bare Coulomb
potential of a unit positive charge, with no −Z attraction sign.
Basis::nuclear includes that sign, so per point
A^g == −nuclear(&[(r_g, 1.0)]), element for element.
Each A^g is symmetric (Hermitian, real basis): off-diagonal shell
blocks are mirrored from one evaluation (exactly equal across the
diagonal); diagonal shell blocks carry the usual round-off-level
kernel asymmetry, exactly as in Basis::nuclear.
Sourcepub fn grid_coulomb_into(&self, points: &[[f64; 3]], out: &mut [f64])
pub fn grid_coulomb_into(&self, points: &[[f64; 3]], out: &mut [f64])
Basis::grid_coulomb into a caller-provided buffer — the parallel
seam: a driver splits its grid into point sub-ranges and calls this
concurrently on disjoint (points, out) chunks (the method takes
&self; the builder is Send + Sync). Every element of out is
assigned, so the buffer need not be zeroed.
Layout and sign convention as Basis::grid_coulomb; the two are
identical (this is the implementation).
§Panics
If out.len() != points.len() · nao².
Sourcepub fn grid_coulomb_kernel(&self, points: &[[f64; 3]], k: EriKernel) -> Vec<f64>
pub fn grid_coulomb_kernel(&self, points: &[[f64; 3]], k: EriKernel) -> Vec<f64>
Like Basis::grid_coulomb but over the chosen EriKernel — the
range-separated COSX ingredient.
EriKernel::Coulombroutes to theBasis::grid_coulombcode path itself: the output is bit-identical.EriKernel::Erf{ omega }evaluates the long-range matricesA^g_{μν} = ⟨μ| erf(ω·|r−r_g|)/|r−r_g| |ν⟩(same positive-kernel convention — equivalently, the plain-Coulomb matrices of a normalized Gaussian charge of exponentω²atr_g, since the potential of that charge is exactlyerf(ωr)/r).
Layout ([g][μ][ν] row-major), symmetry, and the supported angular
momenta (every l ≤ crate::engine::os::MAX_L, like
Basis::nuclear) are identical to Basis::grid_coulomb.
§Panics
Panics if k is Erf { omega } with ω ≤ 0, NaN, or infinite.
Sourcepub fn grid_coulomb_kernel_into(
&self,
points: &[[f64; 3]],
k: EriKernel,
out: &mut [f64],
)
pub fn grid_coulomb_kernel_into( &self, points: &[[f64; 3]], k: EriKernel, out: &mut [f64], )
Basis::grid_coulomb_kernel into a caller-provided buffer — the same
parallel-partition contract as Basis::grid_coulomb_into (every
element of out is assigned; disjoint point sub-ranges may be filled
concurrently). EriKernel::Coulomb is bit-identical to
Basis::grid_coulomb_into.
§Panics
If out.len() != points.len() · nao², or if k is Erf { omega }
with ω ≤ 0, NaN, or infinite.
Source§impl Basis
impl Basis
Sourcepub fn nuclear(&self, charges: &[([f64; 3], f64)]) -> Vec<f64>
pub fn nuclear(&self, charges: &[([f64; 3], f64)]) -> Vec<f64>
Nuclear-attraction matrix V_{μν} = Σ_C ⟨μ| −Z_C/|r−C| |ν⟩ for the given
point charges charges = [(center, Z)].
Sourcepub fn pvp(&self) -> Vec<f64>
pub fn pvp(&self) -> Vec<f64>
Spin-free scalar-relativistic integral W_{μν} = Σ_k ⟨∂_k μ| V |∂_k ν⟩ with
V = Σ_A −Z_A/|r−R_A| over this basis’s atoms (same charges/sign convention
as Basis::nuclear). nao×nao row-major, same layout/order/normalization
as Basis::overlap/Basis::nuclear.
A Basis carries shell centers but no nuclear charges, so the atom list
is Basis::atoms (distinct shell centers, first-appearance order) with
unit charge Z_A = 1 on every atom. For physical nuclear charges use
Basis::pvp_charges, of which this is exactly
pvp_charges(&[(atom, 1.0), …]).
W is the spin-free part of the p·Vp operator (p = −i∇) the
one-electron X2C transformation needs; it is symmetric and is built
symmetric (W = Wᵀ bitwise; see Basis::pvp_charges).
§Panics
If any shell has l > MAX_L − 1 (= 5): the gradient raises the shell to
l + 1, which must stay within the engines’ validated MAX_L.
Sourcepub fn pvp_charges(&self, charges: &[([f64; 3], f64)]) -> Vec<f64>
pub fn pvp_charges(&self, charges: &[([f64; 3], f64)]) -> Vec<f64>
Spin-free pVp matrix W_{μν} = Σ_{k∈{x,y,z}} ⟨∂_k μ| V |∂_k ν⟩ for the
given point charges charges = [(center, Z)] — the same charge list,
units, and −Z/|r−C| sign convention as Basis::nuclear.
Each ⟨∂_k μ|V|∂_k ν⟩ is assembled at the primitive level from up to four
ordinary nuclear-attraction integrals with the bra/ket angular momenta
shifted by ±1 (∂_k g = 2α·g_{l+1_k} − l_k·g_{l−1_k}; see
crate::engine::os::pvp_nuclear_into). The matrix is symmetric by
construction and is built bitwise symmetric: only canonical shell pairs
are evaluated, the diagonal shell block is symmetrized, and the lower
triangle is mirrored.
§Panics
If any shell has l > MAX_L − 1 (= 5), since the derivative raises the
shell to l + 1 (so AO angular momenta through g (l = 4) — and h —
are fully supported).
Sourcepub fn dipole(&self, o: [f64; 3]) -> [Vec<f64>; 3]
pub fn dipole(&self, o: [f64; 3]) -> [Vec<f64>; 3]
Cartesian dipole matrices [D_x, D_y, D_z], D_k = ⟨μ| (r−O)_k |ν⟩,
about the origin o.
Sourcepub fn eri_block(&self, i: usize, j: usize, k: usize, l: usize) -> Vec<f64>
pub fn eri_block(&self, i: usize, j: usize, k: usize, l: usize) -> Vec<f64>
Contracted Cartesian ERI block for the four shells (i, j, k, l) in
chemists’ notation (ij|kl) = ∫∫ φ_i(1)φ_j(1) r₁₂⁻¹ φ_k(2)φ_l(2) d1 d2.
The returned block is row-major over the four Cartesian component
indices (a, b, c, d) of shells (i, j, k, l):
block[((a · n_j + b) · n_k + c) · n_l + d]with n_x = self.shells()[x].n_func() (n_cart for a Cartesian shell,
2l+1 for a spherical one) and the Cartesian component order of
crate::math::am (or the crate::math::solid_harmonics::m_order spherical
order for spherical shells) — the
fastest-varying index is d, slowest is a. The block length is
n_i · n_j · n_k · n_l.
Sourcepub fn eri_block_with(
&self,
engine: Engine,
i: usize,
j: usize,
k: usize,
l: usize,
) -> Vec<f64>
pub fn eri_block_with( &self, engine: Engine, i: usize, j: usize, k: usize, l: usize, ) -> Vec<f64>
Like Basis::eri_block but forces a specific Engine (or Engine::Auto
for the dispatch policy). Both engines produce the same block to tolerance;
forcing exists so tests/CI exercise each path on the same quartets.
Sourcepub fn eri(&self) -> Vec<f64>
pub fn eri(&self) -> Vec<f64>
Dense electron-repulsion tensor (ij|kl) over the whole basis, in
chemists’ notation. Shells declared crate::ShellKind::Spherical
contribute their 2l+1 spherical components; Cartesian shells their
n_cart.
Shape [nao, nao, nao, nao] flattened row-major:
eri[((i · nao + j) · nao + k) · nao + l] = (ij|kl)where nao = self.nao() and i, j, k, l are global AO indices (shell
blocks placed at the offsets from offsets()). The tensor obeys the
8-fold permutational symmetry (ij|kl) = (ji|kl) = (ij|lk) = (kl|ij) = ….
The build exploits that symmetry: only the canonical shell quartets
(i ≥ j, k ≥ l, pair index ij ≥ kl) are evaluated, and each computed
block is scattered to every distinct permutation-equivalent position. Slots
related by a shell-level permutation are therefore bitwise-equal copies of
one evaluation; within a block whose bra (or ket) shells coincide, the usual
round-off-level (~1e-16 relative) asymmetry of one kernel evaluation
remains, exactly as for an unsymmetrized build.
Sourcepub fn eri_with(&self, engine: Engine) -> Vec<f64>
pub fn eri_with(&self, engine: Engine) -> Vec<f64>
Like Basis::eri but forces a specific Engine (or Engine::Auto).
Both engines produce the same tensor to tolerance.
Sourcepub fn eri_kernel(&self, k: EriKernel) -> Vec<f64>
pub fn eri_kernel(&self, k: EriKernel) -> Vec<f64>
Dense two-electron tensor over the chosen EriKernel — layout, ordering,
normalization, and units identical to Basis::eri.
EriKernel::Coulombroutes toBasis::eriitself: the output is bit-identical (the same code path).EriKernel::Erf{ omega }evaluates the long-range operatorerf(ω·r₁₂)/r₁₂. The attenuation is implemented in the Rys engine only (the quadrature transform is a few lines there, whereas the OS/HGP recurrences would need their own attenuated path), so the engine dispatch is bypassed and every quartet runs through Rys over the same canonical-quartet (8-fold) loop. The CoulombBasis::schwarz_boundsremain valid upper bounds for screening attenuated integrals at the call site (erf(ωr)/r ≤ 1/r).
§Panics
Panics if k is Erf { omega } with ω ≤ 0, NaN, or infinite.
Sourcepub fn schwarz_bounds(&self) -> Vec<f64>
pub fn schwarz_bounds(&self) -> Vec<f64>
Cauchy–Schwarz shell-pair bound matrix Q (Häser–Ahlrichs 1989), row-major
n_shells × n_shells:
Q[i, j] = sqrt( max_{μ∈i, ν∈j} (μν|μν) ).Each diagonal self-repulsion (μν|μν) ≥ 0 is read from the (ij|ij) shell
block, so Q bounds every ERI by |(μν|λσ)| ≤ Q[i,j]·Q[k,l] for μν in
shell pair (i,j) and λσ in (k,l). Kind-aware: spherical shells use
their 2l+1 components, so Q bounds the spherical integrals directly.
Sourcepub fn schwarz_bounds_with(&self, engine: Engine) -> Vec<f64>
pub fn schwarz_bounds_with(&self, engine: Engine) -> Vec<f64>
Like Basis::schwarz_bounds but with a forced Engine (the diagonal
blocks are evaluated with it). The bound is engine-independent to tolerance.
Sourcepub fn eri_screened(&self, tau: f64) -> (Vec<f64>, ScreeningStats)
pub fn eri_screened(&self, tau: f64) -> (Vec<f64>, ScreeningStats)
Schwarz-screened dense ERI tensor: identical to Basis::eri except a
shell quartet (ij|kl) is skipped (left zero) when its Cauchy–Schwarz
bound Q[i,j]·Q[k,l] < τ (tau). Because every element of a skipped block
satisfies |(μν|λσ)| ≤ Q[i,j]·Q[k,l] < τ, screening introduces no error
above τ. Returns the tensor and ScreeningStats.
tau is the documented screening threshold; smaller τ retains more
quartets (more accurate, slower). A typical production value is 1e-10–
1e-12.
Sourcepub fn eri_screened_with(
&self,
engine: Engine,
tau: f64,
) -> (Vec<f64>, ScreeningStats)
pub fn eri_screened_with( &self, engine: Engine, tau: f64, ) -> (Vec<f64>, ScreeningStats)
Like Basis::eri_screened but with a forced Engine.
Source§impl Basis
impl Basis
Sourcepub fn int1e(&self, op: &Operator) -> Result<OperatorMatrix, IntegralError>
pub fn int1e(&self, op: &Operator) -> Result<OperatorMatrix, IntegralError>
Evaluate a one-electron Operator over the basis, returning its complex
matrix as real + imaginary parts (OperatorMatrix).
The operator is decomposed into base overlap integrals
(crate::engine::operator); spherical shells are transformed to their
2l+1 components (the transform is applied to each part). This is the
generic operator-DSL path; the bespoke Basis::overlap /
Basis::kinetic / Basis::dipole builders remain the fast paths.
§Errors
IntegralError::OperatorMomentumTooHigh if any shell has
l + op.degree() > MAX_L (the DSL raises the ket to l + degree).
Source§impl Basis
impl Basis
Sourcepub fn new(shells: Vec<Shell>) -> Self
pub fn new(shells: Vec<Shell>) -> Self
Create a basis from a list of shells. AO ordering follows shell order.
Sourcepub fn nao_cart(&self) -> usize
pub fn nao_cart(&self) -> usize
Total number of Cartesian atomic orbitals (counting every shell as
Cartesian, regardless of ShellKind).
Sourcepub fn nao(&self) -> usize
pub fn nao(&self) -> usize
Total number of output atomic orbitals: the sum of each shell’s
Shell::n_func (n_cart for Cartesian shells, 2l+1 for spherical).
This is the dimension of the matrices/tensors the builders return.
Sourcepub fn atoms(&self) -> Vec<[f64; 3]>
pub fn atoms(&self) -> Vec<[f64; 3]>
Distinct shell centers (“atoms”), in order of first appearance.
Two shells belong to the same atom iff their centers are bitwise equal
([f64; 3] equality). This is the natural grouping when shells on one
nucleus share the same center value, and it defines the per-atom ordering
of the geometric-derivative (gradient) builders.