Integrals
ElemCo.Integrals — Module
Electron-repulsion (and other) integrals
Exported functions
ElemCo.Integrals.n_ao4cartshell — Method
n_ao4cartshell(id::Integer, info::ILibcint)Return the number of AOs for a given cartesian shell id.
ElemCo.Integrals.n_ao4sphshell — Method
n_ao4sphshell(id::Integer, info::ILibcint)Return the number of AOs for a given spherical shell id.
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.
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.
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.
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).
ElemCo.Integrals.eri_2e4idx — Method
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.
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.
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.
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!.
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.
ElemCo.Integrals.ket_shell_blocks — Method
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.
ElemCo.Integrals.schwarz_bounds — Method
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.
Two-index integrals
ElemCo.Integrals.dipole — Method
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.
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.
ElemCo.Integrals.eri_2e2idx — Method
eri_2e2idx(basis::BasisSet)Compute the two-electron 2-index electron-repulsion integral matrix.
ElemCo.Integrals.kinetic! — Method
kinetic!(out, basis::BasisSet)Compute the kinetic integral matrix. The result is stored in out.
ElemCo.Integrals.kinetic — Method
kinetic(basis::BasisSet)Compute the kinetic integral matrix.
ElemCo.Integrals.nuclear! — Method
nuclear!(out, basis::BasisSet)Compute the nuclear integral matrix. The result is stored in out.
ElemCo.Integrals.nuclear — Method
nuclear(basis::BasisSet)Compute the nuclear integral matrix.
ElemCo.Integrals.overlap! — Method
overlap!(out, basis::BasisSet)Compute the overlap integral matrix. The result is stored in out.
ElemCo.Integrals.overlap — Method
overlap(basis::BasisSet)Compute the overlap integral matrix.
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).
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.
ElemCo.Integrals.eri_2e3idx — Method
eri_2e3idx(ao_basis::BasisSet, fit_basis::BasisSet)Compute the two-electron three-index electron-repulsion integral.
Calculation in batches
ElemCo.Integrals.BasisBatch — Type
BasisBatchA 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.
ElemCo.Integrals.BasisBatcher — Type
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.
ElemCo.Integrals.BasisBatcher — Type
BasisBatcherA 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)
endElemCo.Integrals.buffer_size_3idx — Method
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).
ElemCo.Integrals.buffer_size_4idx — Method
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).
ElemCo.Integrals.max_batch_length — Method
max_batch_length(bb::BasisBatcher)Return the maximum batch length.
Internal functions
Base.range — Method
range(bb::BasisBatch)Return the range of basis functions in the batch.
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.
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.
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.
ElemCo.Integrals.eri_2e2idx_cart — Method
eri_2e2idx_cart(ash1::AngularShell, ash2::AngularShell, basis::BasisSet)Compute the two-electron 2-index electron-repulsion integral between two angular shells.
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.
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.
ElemCo.Integrals.eri_2e2idx_sph — Method
eri_2e2idx_sph(ash1::AngularShell, ash2::AngularShell, basis::BasisSet)Compute the two-electron 2-index electron-repulsion integral between two angular shells.
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.
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.
ElemCo.Integrals.eri_2e3idx_cart — Method
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.
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.
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.
ElemCo.Integrals.eri_2e3idx_sph — Method
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.
ElemCo.Integrals.eri_2e4idx_callback — Method
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.
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.
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.
ElemCo.Integrals.kinetic_cart — Method
kinetic_cart(ash1::AngularShell, ash2::AngularShell, basis::BasisSet)Compute the kinetic integral between two angular shells.
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.
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.
ElemCo.Integrals.kinetic_sph — Method
kinetic_sph(ash1::AngularShell, ash2::AngularShell, basis::BasisSet)Compute the kinetic integral between two angular shells.
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.
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.
ElemCo.Integrals.nuclear_cart — Method
nuclear_cart(ash1::AngularShell, ash2::AngularShell, basis::BasisSet)Compute the nuclear integral between two angular shells.
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.
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.
ElemCo.Integrals.nuclear_sph — Method
nuclear_sph(ash1::AngularShell, ash2::AngularShell, basis::BasisSet)Compute the nuclear integral between two angular shells.
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.
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.
ElemCo.Integrals.overlap_cart — Method
overlap_cart(ash1::AngularShell, ash2::AngularShell, basis::BasisSet)Compute the overlap integral between two angular shells.
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.
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.
ElemCo.Integrals.overlap_sph — Method
overlap_sph(ash1::AngularShell, ash2::AngularShell, basis::BasisSet)Compute the overlap integral between two angular shells.
Integral libraries
ElemCo.Libcint — Module
LibcintMinimal wrap around the integral library libcint. This module exposes libcint functions to the Julia interface.
(adapted from GaussianBasis.jl)
ElemCo.Libcint.CIntOpt — Type
CIntOptA 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.
ElemCo.Libcint.cint2e_cart_optimizer — Method
cint2e_cart_optimizer(lib::ILibcint) -> CIntOptAllocate the libcint optimizer for cint2e_cart on this basis.
ElemCo.Libcint.cint2e_sph_optimizer — Method
cint2e_sph_optimizer(lib::ILibcint) -> CIntOptAllocate the libcint optimizer for cint2e_sph on this basis.
ElemCo.Libcint.free_optimizer! — Method
free_optimizer!(opt::CIntOpt)Free the libcint optimizer (idempotent; also attached as a finalizer).