Notebooks · lib/hf/jk
Coulomb and exchange matrices from packed integrals, three ways
The two-electron part of the Fock matrix is built from two contractions of
the electron repulsion integrals (ij|kl) (chemist's notation) with a
density D:
J_ij = sum_kl (ij|kl) D_kl Coulomb: the field of the whole density
K_ik = sum_jl (ij|kl) D_jl exchange: the same integrals, indices crossed
A closed shell uses F = H + J - K/2 with the total density; UHF uses
F_s = H + J(Da) + J(Db) - K(D_s) for each spin.
The integrals are stored once per 8-fold symmetry class (lib/hf/eri_store),
so for n = 19 there are 18,145 values instead of 130,321. The members:
jk_packed(member 0, production): one pass over the packed vector. Each stored value stands for up to 8 index orders; it is scaled by 1/2 for each coincidence (i = j,k = l,ij = kl), which leaves exactly one unit of weight per distinct order, and then added in all 8 orders. That touches each stored value once and needs no branch per order.jk_pairs: the integrals as annpair x npairmatrix.Jis a matrix-vector product over pairs;Kreads the matrix through a table of pair indices, one term per(i, j, k, l).jk_dense: unpack to the full[n, n, n, n]tensor and apply the definitions above literally. It costsn^4memory and time and exists to be obviously right.
Member signature, frozen:
(X1, X2, X3, D, opts) -> [2 ndens, n, n], where X1 is the packed vector
for these in-core members (X2, X3 and opts are not read), D is
[ndens, n, n] and the result holds J(D_0), K(D_0), J(D_1), K(D_1). A
direct member, which computes integrals on the fly, would take the atoms,
shells and prims packs in X1..X3 instead; that is why the signature has
three slots.
None of the members assumes D is symmetric.
jk_of(Gp, D, opts) runs the member opts[OPT_JK] names: these three, or
the direct member int_jk_direct (lib/hf/jk_direct), which reads a basis
blob in Gp instead of packed integrals. It calls each by name, the
production member jk_packed when the option is left at its default, so the
SCF reaches J and K without a registry. jk_methods() lists the three
in-core members for the tests and sweeps that run them side by side;
int_jk_methods() (lib/hf/integrals) adds the direct one.
Used with import hf.jk.
Look inside this program
- Atlas
The program’s map: every function and which calls which.
There’s no recorded run of this program yet.
Shift+Enter in a cell runs it and moves to the next. Running a cell runs every cell above it too, as one program.