xnn.common.models.dispersion.three_body_energy_chunked#
- xnn.common.models.dispersion.three_body_energy_chunked(z, edge_index, edge_vec, r, r0_table, s9, alp3, cutoff, width, n_atoms, c6_mat=None, alpha_a=None, alpha_b=None, chunk=None, r0_atom=None, a1=None, a2=None, c6_edge=None, edge_shift=None, once=True, analytic=True, triplet_cache=None)[source]#
three_body_energy()with memory bounded by one block (eager only).The edges are sorted by center once, the centers are cut into blocks holding about
chunktriplets each (read off the cumulative pair counts;Nonesizes the block from the free device memory, between 2^20 and 2^24, since every block pays a fixed set-up in both passes), and every block – triplet enumeration included – runs as arecompute()block, so the retained state is the neighbor list and the per-atom sums at every derivative order (force training included); the block is recomputed in the backward passes. PairC6values come from a dense matrixc6_mat(N, N)or, without one, from the polarizability factorsalpha_a,alpha_b(N, K)assum_k alpha_a[i, k] alpha_b[j, k](D4: the Casimir-Polder weights folded intoalpha_a), which removes the(N, N)table altogether. Faster still,c6_edge(E,)gives the pair C6 per directed edge (computed once, differentiable in whatever it depends on) together with the edges’ integer cell shiftsedge_shift(E, 3): the two sides through the center are then scalar gathers and the third side is found by a binary search over packed pair keys, which removes the(T, 23)gathers and, above all, their contended index-accumulate backward (energy + forces 53 -> 15 ns per triplet on an A100). The pair critical radii come from the element tabler0_tableor, for BJ radiia1 sqrt(3 Q_A Q_B) + a2, from the per-atom factorsr0_atom = 3^(1/4) sqrt(Q)with the scalarsa1, a2(cheap gradients when those are trainable). Withonce(default) each triangle of distinct atoms is evaluated from its smallest-index corner only. Withanalytic(default) and the per-edge C6 / per-atom radius inputs, the block’s first derivative is evaluated in closed form (_triplet_block_grad()) in one pass instead of re-running the block under autograd. On that pathtriplet_cachekeeps each block’s triples from the forward to the backward pass (_TripletCache; GB,Nonefor a quarter of the free device memory, 0 to disable), so they are enumerated once per step. Results equal the scripted loop to rounding.- Parameters:
z (Tensor)
edge_index (Tensor)
edge_vec (Tensor)
r (Tensor)
r0_table (Tensor | None)
s9 (Tensor)
alp3 (float)
cutoff (float)
width (float)
n_atoms (int)
c6_mat (Tensor | None)
alpha_a (Tensor | None)
alpha_b (Tensor | None)
chunk (int | None)
r0_atom (Tensor | None)
a1 (Tensor | None)
a2 (Tensor | None)
c6_edge (Tensor | None)
edge_shift (Tensor | None)
once (bool)
analytic (bool)
triplet_cache (float | None)
- Return type: