Integrals

Exported functions

ElemCo.Integrals.calc_2e4idx_tri!Method
calc_2e4idx_tri!(int2, callback::Function, ao_basis::BasisSet; target_length=100)

Assemble the AO two-electron integrals directly into the physicist-triangular layout used by an AO FDump, i.e.

  int2[p, q, tri(r,s)] = ⟨pq|rs⟩ = (pr|qs) = G[p,r,q,s]   (for r ≤ s),

with tri(r,s) = uppertriangular_index(r,s) and int2 of shape (nao, nao, nao*(nao+1)÷2). The full dense nao⁴ chemists' tensor is never materialized.

The ket index s (physicist ket-2 = chemists' 4th index σ) is batched with a single-basis BasisBatcher: each batch is a contiguous run of s-shells, hence owns a contiguous block of tri(r,s) columns of int2 — written in I/O-friendly order and race-free (disjoint columns per batch). Within a batch the triangular symmetry is applied at the shell-pair level (r-shell ≤ s-shell); the bra indices (p,q) are full. The per-batch core eri_2e4idx_tri_batch! can likewise be used integral-direct (e.g. an AO Fock build) without an int2.

source
ElemCo.Integrals.calc_2e4idx_tri_blockwise!Method
calc_2e4idx_tri_blockwise!(consume!::Function, ao_basis::BasisSet, groups)

Generate the physicist-triangular AO integrals block by block: for each group of s-batches (from ket_shell_blocks) the contiguous ket-column slab slab[p, q, tri(r,s) − col_offset] = ⟨pq|rs⟩ is assembled in a reusable RAM buffer — batches within a block run in parallel over disjoint columns, exactly like calc_2e4idx_tri! — and handed to consume!(J, slab). The full triangular array is never stored; e.g. the ± supermatrix store is folded directly from the slabs.

With rowcut=true only the bra pairs the ± store keeps for block J are generated: slab entries with max(p,q) < s_lo(J) (packed row below the block's first ket-pair index, i.e. the store's conj-Hermitian mirror) are stale garbage the consumer must not read — exactly the rows a ± fold discards. The floor is the GROUP's s_lo, shared by all its batches (each batch owns distinct columns but must produce all kept rows of the block). Default false keeps the full-slab contract.

source
ElemCo.Integrals.eri_2e4idx!Method
eri_2e4idx!(out, ao_basis::BasisSet)

Compute the full two-electron four-index electron-repulsion integral tensor (chemists' notation) into out (nao × nao × nao × nao). Dispatches on the basis.

source
ElemCo.Integrals.eri_2e4idx!Method
eri_2e4idx!(out, i::Int, j::Int, k::Int, l::Int, basis::BasisSet)

Compute the two-electron four-index electron-repulsion integral block $(ij|kl)$ (chemists' notation) for the shells i,j,k,l. The result is stored in out. Dispatches on the basis (spherical/cartesian).

source
ElemCo.Integrals.eri_2e4idxMethod
eri_2e4idx(ao_basis::BasisSet)

Compute the full two-electron four-index electron-repulsion integral tensor $(\mu\nu|\rho\sigma)$ in chemists' notation, i.e. out[μ,ν,ρ,σ] = (μν|ρσ).

The result is a dense nao × nao × nao × nao array. This is the non-density-fitted (exact) AO integral tensor. For storage in an FDump it has to be brought into physicists' notation (<pq|rs> = (pr|qs)); see the AO-dump assembler.

source
ElemCo.Integrals.eri_2e4idx_cart!Method
eri_2e4idx_cart!(out, i::Int, j::Int, k::Int, l::Int, basis::BasisSet)

Compute the two-electron four-index electron-repulsion integral block $(ij|kl)$ (chemists' notation) for the cartesian shells i,j,k,l. The result is stored in out.

source
ElemCo.Integrals.eri_2e4idx_sph!Method
eri_2e4idx_sph!(out, i::Int, j::Int, k::Int, l::Int, basis::BasisSet)

Compute the two-electron four-index electron-repulsion integral block $(ij|kl)$ (chemists' notation) for the spherical shells i,j,k,l. The result is stored in out.

source
ElemCo.Integrals.eri_2e4idx_tri!Method
eri_2e4idx_tri!(int2, ao_basis::BasisSet; target_length=100)

Assemble the AO two-electron integrals directly in the physicist-triangular layout of an AO FDump, dispatching on the basis (spherical/cartesian). See calc_2e4idx_tri!.

source
ElemCo.Integrals.eri_2e4idx_tri_batch!Method
eri_2e4idx_tri_batch!(out, buffer, callback::Function, batch::BasisBatch)

Fill one s-batch of the physicist-triangular AO integrals into the slab out,

  out[p, q, tri(r,s) - col_offset] = ⟨pq|rs⟩ = (pr|qs)   (for r ≤ s),

where batch (from a single-basis BasisBatcher) supplies the s-shells and col_offset = tri(1, s_lo) - 1 aligns the contiguous column block to out's third dimension. The triangular symmetry is applied at the shell-pair level (r-shell ≤ s-shell, with the diagonal shell handled at the AO level); the bra shells (p,q) are full. buffer is a Cdouble (threads) buffer of size buffer_size_4idx. Passing schwarz_bounds as qsh with thr > 0 skips shell quartets whose Cauchy–Schwarz bound Q[P,R]·Q[Q,S] falls below thr; out is then zeroed first, since screened quartets are never written. This is the reusable core — pass an int2 view to fill a memory-mapped dump, or a scratch slab to consume the block integral-direct.

rowfloor (an AO index, default 1 = off) is the Hermiticity row cut for a consumer that keeps only the bra pairs with packed row tri(p,q) ≥ tri(1, rowfloor) — equivalently max(p,q) ≥ rowfloor — and reconstructs the rest as the conj-Hermitian mirror (the ± supermatrix store). Bra shell pairs with BOTH shells entirely below rowfloor produce only discarded rows and are skipped; the predicate is symmetric in P↔Q, so both ordered quartets of every kept unordered pair are still computed (a ± fold needs out[p,q,·] and out[q,p,·]). With rowfloor > 1, out entries with max(p,q) < rowfloor are never written (stale garbage) and must not be read by the consumer.

source
ElemCo.Integrals.ket_shell_blocksMethod
ket_shell_blocks(ao_basis::BasisSet; maxcols, target_length=100) -> Vector{Vector{BasisBatch}}

Group the ket-2 (s) batches of a single-basis BasisBatcher into consecutive blocks of at most maxcols triangular tri(r,s) columns (each block keeps ≥ 1 batch, so a single oversized batch stands alone). Each block owns a contiguous, shell-aligned run of ket columns — a valid σ-blocking for the ± supermatrix store.

source
ElemCo.Integrals.schwarz_boundsMethod
schwarz_bounds(ao_basis::BasisSet, callback::Function) -> Matrix{Float64}

Cauchy–Schwarz shell-pair bounds Q[P,R] = sqrt(max_{p∈P,r∈R} |(pr|pr)|) for prescreening the four-index integrals: the chemists' quartet obeys |(pr|qs)| ≤ Q[P,R]·Q[Q,S], so a quartet whose product falls below the threshold can be skipped without computing it.

Costs nshell²/2 diagonal quartets against the nshell⁴ of the full generation, i.e. nothing.

source

Two-index integrals

ElemCo.Integrals.dipoleMethod
dipole(basis::BasisSet)

Compute the AO dipole integral matrices $\langle \mu | r_\alpha | \nu \rangle$ for $\alpha = x, y, z$.

Returns a tuple (Dx, Dy, Dz) of nao × nao matrices.

source
ElemCo.Integrals.eri_2e2idx!Method
eri_2e2idx!(out, basis::BasisSet)

Compute the two-electron 2-index electron-repulsion integral matrix. The result is stored in out.

source

Three-index integrals

ElemCo.Integrals.eri_2e3idx!Method
eri_2e3idx!(out, buffer, batch::BasisBatch)

Compute the two-electron three-index electron-repulsion integral in batch mode (see BasisBatcher). The result is stored in out. buffer is a preallocated buffer [MAlloc]Buffer{Cdouble} of size buffer_size_3idx(batch.bb).

source
ElemCo.Integrals.eri_2e3idx!Method
eri_2e3idx!(out, ao_basis::BasisSet, fit_basis::BasisSet)

Compute the two-electron three-index electron-repulsion integral. The result is stored in out.

source

Calculation in batches

ElemCo.Integrals.BasisBatchType
BasisBatch

A structure to represent a batch of basis functions. The structure is used to loop over basis functions in a batched manner. The structure is used in conjunction with BasisBatcher.

source
ElemCo.Integrals.BasisBatcherType
BasisBatcher(basis::BasisSet, target_length::Int=100)

Single-basis batcher: iterate the shells of basis (the batched dimension) in target-length batches, without combining two basis sets. Used e.g. to batch the ket-2 (s) index of the four-index AO integrals ⟨pq|rs⟩, where all four indices live in the same AO basis. n4sh(batch, 1)/bas_offset(batch, 1) then refer to that single basis.

source
ElemCo.Integrals.BasisBatcherType
BasisBatcher

A structure to loop of basis functions in a batched manner. This is useful for computing integrals in batches. The structure is initialized with two basis sets and provides a method to loop over all basis functions of the second basis in a batched manner:

function BasisBatcher(basis1::BasisSet, basis2::BasisSet, target_length::Int=100)

The batch length is determined by the target_length parameter. The actual batch length depends on the number of basis functions in the shells of the second basis set and can be smaller or larger than the target_length. One can use the max_batch_length function to determine the maximum batch length.

Example

bbatches = BasisBatcher(basis1, basis2)
for batch in bbatches
  range = range(batch) # range of basis functions in the batch
  eri_2e3idx!(@view(pqP[:,:,range]), batch)
end
source
ElemCo.Integrals.buffer_size_3idxMethod
buffer_size_3idx(bb::BasisBatcher)

Return the buffer size needed in the 3-index integral calculation.

The buffer has to be of type [MAlloc]Buffer{Cdouble}(lenbuf) or [MAlloc]ThreadsBuffer{Cdouble}(lenbuf).

source
ElemCo.Integrals.buffer_size_4idxMethod
buffer_size_4idx(bb::BasisBatcher)

Return the per-thread buffer size needed for a four-index AO shell quartet (P R | Q S) in the single-basis batcher (largest nP·nR·nQ·nS).

source

Internal functions

Base.rangeMethod
range(bb::BasisBatch)

Return the range of basis functions in the batch.

source
ElemCo.Integrals.calc_2e4idx!Method
calc_2e4idx!(out, callback::Function, ao_basis::BasisSet)

Assemble the full four-index AO integral tensor out[μ,ν,ρ,σ] = (μν|ρσ) (chemists' notation) by looping over shell quartets and calling callback (one of eri_2e4idx_sph!/eri_2e4idx_cart!).

Permutational symmetry is exploited at the shell-pair level ((μν|··) = (νμ|··) and (··|ρσ) = (··|σρ), i.e. 4-fold reduction). The bra↔ket pair symmetry (μν|ρσ) = (ρσ|μν) is not exploited so that the parallel loop stays race-free: each task owns a distinct ket shell-pair {K,L} (keyed by L = max(K,L)), hence different tasks write disjoint (ρ,σ) blocks.

source
ElemCo.Integrals.eri_2e2idx_cart!Method
eri_2e2idx!(out, ash1::AngularShell, ash2::AngularShell, basis::BasisSet)

Compute the two-electron 2-index electron-repulsion integral between two angular shells. The result is stored in out.

source
ElemCo.Integrals.eri_2e2idx_cart!Method
eri_2e2idx_cart!(out, i::Int, j::Int, basis::BasisSet)

Compute the two-electron 2-index electron-repulsion integral between two angular shells. The result is stored in out.

source
ElemCo.Integrals.eri_2e2idx_cartMethod
eri_2e2idx_cart(ash1::AngularShell, ash2::AngularShell, basis::BasisSet)

Compute the two-electron 2-index electron-repulsion integral between two angular shells.

source
ElemCo.Integrals.eri_2e2idx_sph!Method
eri_2e2idx!(out, ash1::AngularShell, ash2::AngularShell, basis::BasisSet)

Compute the two-electron 2-index electron-repulsion integral between two angular shells. The result is stored in out.

source
ElemCo.Integrals.eri_2e2idx_sph!Method
eri_2e2idx_sph!(out, i::Int, j::Int, basis::BasisSet)

Compute the two-electron 2-index electron-repulsion integral between two angular shells. The result is stored in out.

source
ElemCo.Integrals.eri_2e2idx_sphMethod
eri_2e2idx_sph(ash1::AngularShell, ash2::AngularShell, basis::BasisSet)

Compute the two-electron 2-index electron-repulsion integral between two angular shells.

source
ElemCo.Integrals.eri_2e3idx_cart!Method
eri_2e3idx!(out, ash1ao::AngularShell, ash2ao::AngularShell, ashfit::AngularShell, basis::BasisSet)

Compute the two-electron three-index electron-repulsion integral $v_{a_1}^{a_2 P}$ for given angular shells. basis has to contain ao and fit bases. The result is stored in out.

source
ElemCo.Integrals.eri_2e3idx_cart!Method
eri_2e3idx_cart!(out, i::Int, j::Int, P::Int, basis::BasisSet)

Compute the two-electron three-index electron-repulsion integral $v_i^{j P}$ for given angular shells. basis has to contain ao and fit bases. The result is stored in out.

source
ElemCo.Integrals.eri_2e3idx_cartMethod
eri_2e3idx_cart(ash1ao::AngularShell, ash2ao::AngularShell, ashfit::AngularShell, basis::BasisSet)

Compute the two-electron three-index electron-repulsion integral $v_{a_1}^{a_2 P}$ for given angular shells. basis has to contain ao and fit bases.

source
ElemCo.Integrals.eri_2e3idx_sph!Method
eri_2e3idx!(out, ash1ao::AngularShell, ash2ao::AngularShell, ashfit::AngularShell, basis::BasisSet)

Compute the two-electron three-index electron-repulsion integral $v_{a_1}^{a_2 P}$ for given angular shells. basis has to contain ao and fit bases. The result is stored in out.

source
ElemCo.Integrals.eri_2e3idx_sph!Method
eri_2e3idx_sph!(out, i::Int, j::Int, P::Int, basis::BasisSet)

Compute the two-electron three-index electron-repulsion integral $v_i^{j P}$ for given angular shells. basis has to contain ao and fit bases. The result is stored in out.

source
ElemCo.Integrals.eri_2e3idx_sphMethod
eri_2e3idx_sph(ash1ao::AngularShell, ash2ao::AngularShell, ashfit::AngularShell, basis::BasisSet)

Compute the two-electron three-index electron-repulsion integral $v_{a_1}^{a_2 P}$ for given angular shells. basis has to contain ao and fit bases.

source
ElemCo.Integrals.eri_2e4idx_callbackMethod
eri_2e4idx_callback(ao_basis::BasisSet) -> (callback, opt)

The per-quartet ERI callback for a generation sweep, running through libcint's optimizer fast path: allocates the CIntOpt for this basis (spherical/cartesian resolved here) and returns a closure with the plain callback(out, i, j, k, l, basis) signature every driver and schwarz_bounds expects, plus the optimizer handle. The caller frees the handle with free_optimizer!(opt) after the sweep (a finalizer backs it up); the handle is read-only during evaluation, so all threads of the sweep share it.

source
ElemCo.Integrals.kinetic_cart!Method
kinetic!(out, ash1::AngularShell, ash2::AngularShell, basis::BasisSet)

Compute the kinetic integral between two angular shells. The result is stored in out.

source
ElemCo.Integrals.kinetic_cart!Method
kinetic_cart!(out, i::Int, j::Int, basis::BasisSet)

Compute the kinetic integral between two angular shells. The result is stored in out.

source
ElemCo.Integrals.kinetic_sph!Method
kinetic!(out, ash1::AngularShell, ash2::AngularShell, basis::BasisSet)

Compute the kinetic integral between two angular shells. The result is stored in out.

source
ElemCo.Integrals.kinetic_sph!Method
kinetic_sph!(out, i::Int, j::Int, basis::BasisSet)

Compute the kinetic integral between two angular shells. The result is stored in out.

source
ElemCo.Integrals.nuclear_cart!Method
nuclear!(out, ash1::AngularShell, ash2::AngularShell, basis::BasisSet)

Compute the nuclear integral between two angular shells. The result is stored in out.

source
ElemCo.Integrals.nuclear_cart!Method
nuclear_cart!(out, i::Int, j::Int, basis::BasisSet)

Compute the nuclear integral between two angular shells. The result is stored in out.

source
ElemCo.Integrals.nuclear_sph!Method
nuclear!(out, ash1::AngularShell, ash2::AngularShell, basis::BasisSet)

Compute the nuclear integral between two angular shells. The result is stored in out.

source
ElemCo.Integrals.nuclear_sph!Method
nuclear_sph!(out, i::Int, j::Int, basis::BasisSet)

Compute the nuclear integral between two angular shells. The result is stored in out.

source
ElemCo.Integrals.overlap_cart!Method
overlap!(out, ash1::AngularShell, ash2::AngularShell, basis::BasisSet)

Compute the overlap integral between two angular shells. The result is stored in out.

source
ElemCo.Integrals.overlap_cart!Method
overlap_cart!(out, i::Int, j::Int, basis::BasisSet)

Compute the overlap integral between two angular shells. The result is stored in out.

source
ElemCo.Integrals.overlap_sph!Method
overlap!(out, ash1::AngularShell, ash2::AngularShell, basis::BasisSet)

Compute the overlap integral between two angular shells. The result is stored in out.

source
ElemCo.Integrals.overlap_sph!Method
overlap_sph!(out, i::Int, j::Int, basis::BasisSet)

Compute the overlap integral between two angular shells. The result is stored in out.

source

Integral libraries

ElemCo.LibcintModule
Libcint

Minimal wrap around the integral library libcint. This module exposes libcint functions to the Julia interface.

(adapted from GaussianBasis.jl)

source
ElemCo.Libcint.CIntOptType
CIntOpt

A libcint CINTOpt optimizer handle: per-(integral type, basis) precomputed shell-pair data that libcint's kernels use to skip work — its intended fast path (without it every quartet call passes a NULL optimizer and recomputes the pair data). Create with the *_optimizer constructors (e.g. cint2e_sph_optimizer), pass to the optimizer-taking integral methods, and free with free_optimizer! (a finalizer is attached as a leak backstop, but generation sweeps free deterministically). The handle is READ-ONLY during integral evaluation, so one optimizer can be shared by all threads of a sweep.

source