nvalchemiops.interactions.dispersion: Dispersion Corrections#

Core warp-based dispersion correction implementations.

This module provides framework-agnostic warp launchers for dispersion corrections. For PyTorch bindings, use nvalchemiops.torch.interactions.dispersion instead.

Warp-Level Interface#

DFT-D3(BJ) Dispersion Corrections#

Tip

This is the low-level Warp interface that operates on warp.array objects. For PyTorch tensor support, see nvalchemiops.torch.interactions.dispersion: Dispersion Corrections.

The DFT-D3 implementation supports two neighbor representation formats:

  • Neighbor matrix (dense): [num_atoms, max_neighbors] with padding

  • Neighbor list (sparse CSR): Compressed sparse row format with idx_j and neighbor_ptr

Both formats produce identical results and support all features including periodic boundary conditions, batching, and smooth cutoff functions.

Non-Periodic Systems#

nvalchemiops.interactions.dispersion._dftd3.dftd3_matrix(positions, numbers, neighbor_matrix, covalent_radii, r4r2, c6_reference, coord_num_ref, a1, a2, s8, coord_num, forces, energy, virial, batch_idx, cartesian_shifts, dE_dCN, wp_dtype, device, k1=16.0, k3=-4.0, s6=1.0, s5_smoothing_on=0.0, s5_smoothing_off=0.0, fill_value=None)[source]#

Launch DFT-D3(BJ) dispersion calculation using neighbor matrix format (non-periodic).

This is a framework-agnostic warp launcher for non-periodic (non-PBC) systems that accepts warp arrays directly and orchestrates the multi-pass kernel execution for DFT-D3(BJ) dispersion energy, forces, and coordination number calculations. Framework-specific wrappers (PyTorch, JAX) handle tensor-to-warp conversion and call this function.

For periodic systems, use dftd3_matrix_pbc() instead.

Multi-Pass Algorithm#
  1. Pass 1: Compute coordination numbers using geometric counting function

  2. Pass 2: Compute direct forces, energy, and accumulate \(\partial E/\partial \text{CN}\)

  3. Pass 3: Add CN-dependent force contribution using chain rule

param positions:

Atomic coordinates in consistent distance units (typically Bohr). Supports both float32 (vec3f) and float64 (vec3d) precision.

type positions:

wp.array(dtype=vec3f or vec3d), shape [num_atoms]

param numbers:

Atomic numbers

type numbers:

wp.array(dtype=int32), shape [num_atoms]

param neighbor_matrix:

Neighbor indices. Padding entries have values >= fill_value.

type neighbor_matrix:

wp.array2d(dtype=int32), shape [num_atoms, max_neighbors]

param covalent_radii:

Covalent radii indexed by atomic number, in same units as positions

type covalent_radii:

wp.array(dtype=float32), shape [max_Z+1]

param r4r2:

\(\langle r^4 \rangle / \langle r^2 \rangle\) expectation values for \(C_8\) computation (dimensionless)

type r4r2:

wp.array(dtype=float32), shape [max_Z+1]

param c6_reference:

\(C_6\) reference values in energy \(\times\) distance\(^6\) units

type c6_reference:

wp.array4d(dtype=float32), shape [max_Z+1, max_Z+1, 5, 5]

param coord_num_ref:

CN reference grid (dimensionless)

type coord_num_ref:

wp.array4d(dtype=float32), shape [max_Z+1, max_Z+1, 5, 5]

param a1:

Becke-Johnson damping parameter 1 (functional-dependent, dimensionless)

type a1:

float

param a2:

Becke-Johnson damping parameter 2 (functional-dependent), in same units as positions

type a2:

float

param s8:

\(C_8\) term scaling factor (functional-dependent, dimensionless)

type s8:

float

param coord_num:

OUTPUT: Coordination numbers (dimensionless). Must be pre-allocated and zeroed.

type coord_num:

wp.array(dtype=float32), shape [num_atoms]

param forces:

OUTPUT: Atomic forces in energy/distance units. Must be pre-allocated and zeroed.

type forces:

wp.array(dtype=vec3f), shape [num_atoms]

param energy:

OUTPUT: Dispersion energy in energy units. Must be pre-allocated and zeroed.

type energy:

wp.array(dtype=float32), shape [num_systems]

param virial:

OUTPUT: Virial tensor (not computed for non-periodic systems). Must be pre-allocated but will not be modified.

type virial:

wp.array(dtype=mat33f), shape [num_systems]

param batch_idx:

Batch indices mapping each atom to its system index.

type batch_idx:

wp.array(dtype=int32), shape [num_atoms]

param cartesian_shifts:

SCRATCH: Pre-allocated buffer for Cartesian shift vectors. Values are not used for non-periodic systems, but the array must still be provided with shape matching neighbor_matrix. Must be pre-allocated by caller.

type cartesian_shifts:

wp.array(dtype=vec3f or vec3d), shape [num_atoms, max_neighbors]

param dE_dCN:

SCRATCH: Pre-allocated buffer for chain rule \(\partial E/\partial \text{CN}\) intermediate. Must be pre-allocated and zeroed by caller.

type dE_dCN:

wp.array(dtype=float32), shape [num_atoms]

param wp_dtype:

Warp scalar dtype (wp.float32 or wp.float64) matching positions dtype.

type wp_dtype:

type

param device:

Warp device string (e.g., ‘cuda:0’, ‘cpu’).

type device:

str

param k1:

CN counting function steepness parameter, in inverse distance units (typically 16.0 1/Bohr). Default: 16.0

type k1:

float, optional

param k3:

CN interpolation Gaussian width parameter (typically -4.0, dimensionless). Default: -4.0

type k3:

float, optional

param s6:

\(C_6\) term scaling factor (typically 1.0, dimensionless). Default: 1.0

type s6:

float, optional

param s5_smoothing_on:

Distance where S5 switching begins, in same units as positions. Default: 0.0

type s5_smoothing_on:

float, optional

param s5_smoothing_off:

Distance where S5 switching completes, in same units as positions. Default: 0.0

type s5_smoothing_off:

float, optional

param fill_value:

Value indicating padding in neighbor_matrix. If None, inferred from num_atoms.

type fill_value:

int or None, optional

returns:

All outputs are written to pre-allocated arrays (coord_num, forces, energy).

rtype:

None

Notes

  • All output arrays must be pre-allocated and zeroed by the caller

  • Supports float32 and float64 positions; outputs always float32

  • Padding atoms indicated by numbers[i] == 0 are skipped

  • Two-body only: Three-body Axilrod-Teller-Muto (\(C_9\)) terms not included

  • Unit consistency required: standard D3 parameters use atomic units (Bohr for distances, Hartree for energy)

  • Virial is NOT computed for non-periodic systems (use dftd3_matrix_pbc for PBC)

See also

dftd3_matrix_pbc

Neighbor matrix format with PBC support

dftd3

Neighbor list (CSR) format, non-periodic

dftd3_pbc

Neighbor list (CSR) format with PBC support

Parameters:
Return type:

None

nvalchemiops.interactions.dispersion._dftd3.dftd3(positions, numbers, idx_j, neighbor_ptr, covalent_radii, r4r2, c6_reference, coord_num_ref, a1, a2, s8, coord_num, forces, energy, virial, batch_idx, cartesian_shifts, dE_dCN, wp_dtype, device, k1=16.0, k3=-4.0, s6=1.0, s5_smoothing_on=0.0, s5_smoothing_off=0.0)[source]#

Launch DFT-D3(BJ) dispersion calculation using neighbor list (CSR) format (non-periodic).

This is a framework-agnostic warp launcher for non-periodic (non-PBC) systems that accepts warp arrays directly and orchestrates the multi-pass kernel execution for DFT-D3(BJ) dispersion energy, forces, and coordination number calculations using CSR (Compressed Sparse Row) neighbor list format. Framework-specific wrappers (PyTorch, JAX) handle tensor-to-warp conversion and call this function.

For periodic systems, use dftd3_pbc() instead.

Multi-Pass Algorithm#
  1. Pass 1: Compute coordination numbers using geometric counting function

  2. Pass 2: Compute direct forces, energy, and accumulate \(\partial E/\partial \text{CN}\)

  3. Pass 3: Add CN-dependent force contribution using chain rule

param positions:

Atomic coordinates in consistent distance units (typically Bohr). Supports both float32 (vec3f) and float64 (vec3d) precision.

type positions:

wp.array(dtype=vec3f or vec3d), shape [num_atoms]

param numbers:

Atomic numbers

type numbers:

wp.array(dtype=int32), shape [num_atoms]

param idx_j:

Destination atom indices in CSR format

type idx_j:

wp.array(dtype=int32), shape [num_edges]

param neighbor_ptr:

CSR row pointers where neighbor_ptr[i]:neighbor_ptr[i+1] gives the range of neighbors for atom i

type neighbor_ptr:

wp.array(dtype=int32), shape [num_atoms+1]

param covalent_radii:

Covalent radii indexed by atomic number, in same units as positions

type covalent_radii:

wp.array(dtype=float32), shape [max_Z+1]

param r4r2:

\(\langle r^4 \rangle / \langle r^2 \rangle\) expectation values for \(C_8\) computation (dimensionless)

type r4r2:

wp.array(dtype=float32), shape [max_Z+1]

param c6_reference:

\(C_6\) reference values in energy \(\times\) distance\(^6\) units

type c6_reference:

wp.array4d(dtype=float32), shape [max_Z+1, max_Z+1, 5, 5]

param coord_num_ref:

CN reference grid (dimensionless)

type coord_num_ref:

wp.array4d(dtype=float32), shape [max_Z+1, max_Z+1, 5, 5]

param a1:

Becke-Johnson damping parameter 1 (functional-dependent, dimensionless)

type a1:

float

param a2:

Becke-Johnson damping parameter 2 (functional-dependent), in same units as positions

type a2:

float

param s8:

\(C_8\) term scaling factor (functional-dependent, dimensionless)

type s8:

float

param coord_num:

OUTPUT: Coordination numbers (dimensionless). Must be pre-allocated and zeroed.

type coord_num:

wp.array(dtype=float32), shape [num_atoms]

param forces:

OUTPUT: Atomic forces in energy/distance units. Must be pre-allocated and zeroed.

type forces:

wp.array(dtype=vec3f), shape [num_atoms]

param energy:

OUTPUT: Dispersion energy in energy units. Must be pre-allocated and zeroed.

type energy:

wp.array(dtype=float32), shape [num_systems]

param virial:

OUTPUT: Virial tensor (not computed for non-periodic systems). Must be pre-allocated but will not be modified.

type virial:

wp.array(dtype=mat33f), shape [num_systems]

param batch_idx:

Batch indices mapping each atom to its system index.

type batch_idx:

wp.array(dtype=int32), shape [num_atoms]

param cartesian_shifts:

SCRATCH: Pre-allocated buffer for Cartesian shift vectors. Values are not used for non-periodic systems, but the array must still be provided with length matching idx_j. Must be pre-allocated by caller.

type cartesian_shifts:

wp.array(dtype=vec3f or vec3d), shape [num_edges]

param dE_dCN:

SCRATCH: Pre-allocated buffer for chain rule \(\partial E/\partial \text{CN}\) intermediate. Must be pre-allocated and zeroed by caller.

type dE_dCN:

wp.array(dtype=float32), shape [num_atoms]

param wp_dtype:

Warp scalar dtype (wp.float32 or wp.float64) matching positions dtype.

type wp_dtype:

type

param device:

Warp device string (e.g., ‘cuda:0’, ‘cpu’).

type device:

str

param k1:

CN counting function steepness parameter, in inverse distance units (typically 16.0 1/Bohr). Default: 16.0

type k1:

float, optional

param k3:

CN interpolation Gaussian width parameter (typically -4.0, dimensionless). Default: -4.0

type k3:

float, optional

param s6:

\(C_6\) term scaling factor (typically 1.0, dimensionless). Default: 1.0

type s6:

float, optional

param s5_smoothing_on:

Distance where S5 switching begins, in same units as positions. Default: 0.0

type s5_smoothing_on:

float, optional

param s5_smoothing_off:

Distance where S5 switching completes, in same units as positions. Default: 0.0

type s5_smoothing_off:

float, optional

returns:

All outputs are written to pre-allocated arrays (coord_num, forces, energy). Virial is not computed for non-periodic systems.

rtype:

None

Notes

  • All output arrays must be pre-allocated and zeroed by the caller

  • Supports float32 and float64 positions; outputs always float32

  • Padding atoms indicated by numbers[i] == 0 are skipped

  • Two-body only: Three-body Axilrod-Teller-Muto (\(C_9\)) terms not included

  • Unit consistency required: standard D3 parameters use atomic units (Bohr for distances, Hartree for energy)

  • CSR format is more memory-efficient for sparse neighbor lists

  • Virial is NOT computed for non-periodic systems (use dftd3_pbc for PBC)

See also

dftd3_pbc

Neighbor list (CSR) format with PBC support

dftd3_matrix

Neighbor matrix format, non-periodic

dftd3_matrix_pbc

Neighbor matrix format with PBC support

Parameters:
Return type:

None

Periodic Boundary Conditions (PBC)#

nvalchemiops.interactions.dispersion._dftd3.dftd3_matrix_pbc(positions, numbers, neighbor_matrix, cell, neighbor_matrix_shifts, covalent_radii, r4r2, c6_reference, coord_num_ref, a1, a2, s8, coord_num, forces, energy, virial, batch_idx, cartesian_shifts, dE_dCN, wp_dtype, device, k1=16.0, k3=-4.0, s6=1.0, s5_smoothing_on=0.0, s5_smoothing_off=0.0, fill_value=None, compute_virial=False)[source]#

Launch DFT-D3(BJ) dispersion calculation using neighbor matrix format with PBC.

This is a framework-agnostic warp launcher for periodic boundary condition (PBC) systems that accepts warp arrays directly and orchestrates the multi-pass kernel execution for DFT-D3(BJ) dispersion energy, forces, virial, and coordination number calculations. Framework-specific wrappers (PyTorch, JAX) handle tensor-to-warp conversion and call this function.

For non-periodic systems, use dftd3_matrix() instead.

Multi-Pass Algorithm#
  1. Pass 0: Convert unit cell shifts to Cartesian coordinates

  2. Pass 1: Compute coordination numbers using geometric counting function

  3. Pass 2: Compute direct forces, energy, and accumulate \(\partial E/\partial \text{CN}\)

  4. Pass 3: Add CN-dependent force contribution using chain rule

param positions:

Atomic coordinates in consistent distance units (typically Bohr). Supports both float32 (vec3f) and float64 (vec3d) precision.

type positions:

wp.array(dtype=vec3f or vec3d), shape [num_atoms]

param numbers:

Atomic numbers

type numbers:

wp.array(dtype=int32), shape [num_atoms]

param neighbor_matrix:

Neighbor indices. Padding entries have values >= fill_value.

type neighbor_matrix:

wp.array2d(dtype=int32), shape [num_atoms, max_neighbors]

param cell:

Unit cell lattice vectors for PBC, in same dtype/units as positions. Convention: cell[s, i, :] is the i-th lattice vector for system s (row vectors).

type cell:

wp.array(dtype=mat33f or mat33d), shape [num_systems]

param neighbor_matrix_shifts:

Integer unit cell shifts for PBC. shift[i, k] is the shift for the k-th neighbor of atom i.

type neighbor_matrix_shifts:

wp.array2d(dtype=vec3i), shape [num_atoms, max_neighbors]

param covalent_radii:

Covalent radii indexed by atomic number, in same units as positions

type covalent_radii:

wp.array(dtype=float32), shape [max_Z+1]

param r4r2:

\(\langle r^4 \rangle / \langle r^2 \rangle\) expectation values for \(C_8\) computation (dimensionless)

type r4r2:

wp.array(dtype=float32), shape [max_Z+1]

param c6_reference:

\(C_6\) reference values in energy \(\times\) distance\(^6\) units

type c6_reference:

wp.array4d(dtype=float32), shape [max_Z+1, max_Z+1, 5, 5]

param coord_num_ref:

CN reference grid (dimensionless)

type coord_num_ref:

wp.array4d(dtype=float32), shape [max_Z+1, max_Z+1, 5, 5]

param a1:

Becke-Johnson damping parameter 1 (functional-dependent, dimensionless)

type a1:

float

param a2:

Becke-Johnson damping parameter 2 (functional-dependent), in same units as positions

type a2:

float

param s8:

\(C_8\) term scaling factor (functional-dependent, dimensionless)

type s8:

float

param coord_num:

OUTPUT: Coordination numbers (dimensionless). Must be pre-allocated and zeroed.

type coord_num:

wp.array(dtype=float32), shape [num_atoms]

param forces:

OUTPUT: Atomic forces in energy/distance units. Must be pre-allocated and zeroed.

type forces:

wp.array(dtype=vec3f), shape [num_atoms]

param energy:

OUTPUT: Dispersion energy in energy units. Must be pre-allocated and zeroed.

type energy:

wp.array(dtype=float32), shape [num_systems]

param virial:

OUTPUT: Virial tensor in energy units. Must be pre-allocated and zeroed. Only computed if compute_virial=True.

type virial:

wp.array(dtype=mat33f), shape [num_systems]

param batch_idx:

Batch indices mapping each atom to its system index.

type batch_idx:

wp.array(dtype=int32), shape [num_atoms]

param cartesian_shifts:

SCRATCH: Pre-allocated buffer for Cartesian shift vectors. Populated by Pass 0 from unit cell shifts. Must be pre-allocated with shape matching neighbor_matrix.

type cartesian_shifts:

wp.array(dtype=vec3f or vec3d), shape [num_atoms, max_neighbors]

param dE_dCN:

SCRATCH: Pre-allocated buffer for chain rule \(\partial E/\partial \text{CN}\) intermediate. Must be pre-allocated and zeroed by caller.

type dE_dCN:

wp.array(dtype=float32), shape [num_atoms]

param wp_dtype:

Warp scalar dtype (wp.float32 or wp.float64) matching positions dtype.

type wp_dtype:

type

param device:

Warp device string (e.g., ‘cuda:0’, ‘cpu’).

type device:

str

param k1:

CN counting function steepness parameter, in inverse distance units (typically 16.0 1/Bohr). Default: 16.0

type k1:

float, optional

param k3:

CN interpolation Gaussian width parameter (typically -4.0, dimensionless). Default: -4.0

type k3:

float, optional

param s6:

\(C_6\) term scaling factor (typically 1.0, dimensionless). Default: 1.0

type s6:

float, optional

param s5_smoothing_on:

Distance where S5 switching begins, in same units as positions. Default: 0.0

type s5_smoothing_on:

float, optional

param s5_smoothing_off:

Distance where S5 switching completes, in same units as positions. Default: 0.0

type s5_smoothing_off:

float, optional

param fill_value:

Value indicating padding in neighbor_matrix. If None, inferred from num_atoms.

type fill_value:

int or None, optional

param compute_virial:

If True, compute virial tensor. Default: False

type compute_virial:

bool, optional

returns:

All outputs are written to pre-allocated arrays (coord_num, forces, energy, virial).

rtype:

None

Notes

  • All output arrays must be pre-allocated and zeroed by the caller

  • Supports float32 and float64 positions/cell; outputs always float32

  • Padding atoms indicated by numbers[i] == 0 are skipped

  • Two-body only: Three-body Axilrod-Teller-Muto (\(C_9\)) terms not included

  • Unit consistency required: standard D3 parameters use atomic units (Bohr for distances, Hartree for energy)

  • Virial tensor is computed when compute_virial=True

See also

dftd3_matrix

Neighbor matrix format, non-periodic

dftd3

Neighbor list (CSR) format, non-periodic

dftd3_pbc

Neighbor list (CSR) format with PBC support

Parameters:
Return type:

None

nvalchemiops.interactions.dispersion._dftd3.dftd3_pbc(positions, numbers, idx_j, neighbor_ptr, cell, unit_shifts, covalent_radii, r4r2, c6_reference, coord_num_ref, a1, a2, s8, coord_num, forces, energy, virial, batch_idx, cartesian_shifts, dE_dCN, wp_dtype, device, k1=16.0, k3=-4.0, s6=1.0, s5_smoothing_on=0.0, s5_smoothing_off=0.0, compute_virial=False)[source]#

Launch DFT-D3(BJ) dispersion calculation using neighbor list (CSR) format with PBC.

This is a framework-agnostic warp launcher for periodic boundary condition (PBC) systems that accepts warp arrays directly and orchestrates the multi-pass kernel execution for DFT-D3(BJ) dispersion energy, forces, virial, and coordination number calculations using CSR (Compressed Sparse Row) neighbor list format. Framework-specific wrappers (PyTorch, JAX) handle tensor-to-warp conversion and call this function.

For non-periodic systems, use dftd3() instead.

Multi-Pass Algorithm#
  1. Pass 0: Convert unit cell shifts to Cartesian coordinates

  2. Pass 1: Compute coordination numbers using geometric counting function

  3. Pass 2: Compute direct forces, energy, and accumulate \(\partial E/\partial \text{CN}\)

  4. Pass 3: Add CN-dependent force contribution using chain rule

param positions:

Atomic coordinates in consistent distance units (typically Bohr). Supports both float32 (vec3f) and float64 (vec3d) precision.

type positions:

wp.array(dtype=vec3f or vec3d), shape [num_atoms]

param numbers:

Atomic numbers

type numbers:

wp.array(dtype=int32), shape [num_atoms]

param idx_j:

Destination atom indices in CSR format

type idx_j:

wp.array(dtype=int32), shape [num_edges]

param neighbor_ptr:

CSR row pointers where neighbor_ptr[i]:neighbor_ptr[i+1] gives the range of neighbors for atom i

type neighbor_ptr:

wp.array(dtype=int32), shape [num_atoms+1]

param cell:

Unit cell lattice vectors for PBC, in same dtype/units as positions. Convention: cell[s, i, :] is the i-th lattice vector for system s (row vectors).

type cell:

wp.array(dtype=mat33f or mat33d), shape [num_systems]

param unit_shifts:

Integer unit cell shifts for PBC. shift[e] is the shift for edge e.

type unit_shifts:

wp.array(dtype=vec3i), shape [num_edges]

param covalent_radii:

Covalent radii indexed by atomic number, in same units as positions

type covalent_radii:

wp.array(dtype=float32), shape [max_Z+1]

param r4r2:

\(\langle r^4 \rangle / \langle r^2 \rangle\) expectation values for \(C_8\) computation (dimensionless)

type r4r2:

wp.array(dtype=float32), shape [max_Z+1]

param c6_reference:

\(C_6\) reference values in energy \(\times\) distance\(^6\) units

type c6_reference:

wp.array4d(dtype=float32), shape [max_Z+1, max_Z+1, 5, 5]

param coord_num_ref:

CN reference grid (dimensionless)

type coord_num_ref:

wp.array4d(dtype=float32), shape [max_Z+1, max_Z+1, 5, 5]

param a1:

Becke-Johnson damping parameter 1 (functional-dependent, dimensionless)

type a1:

float

param a2:

Becke-Johnson damping parameter 2 (functional-dependent), in same units as positions

type a2:

float

param s8:

\(C_8\) term scaling factor (functional-dependent, dimensionless)

type s8:

float

param coord_num:

OUTPUT: Coordination numbers (dimensionless). Must be pre-allocated and zeroed.

type coord_num:

wp.array(dtype=float32), shape [num_atoms]

param forces:

OUTPUT: Atomic forces in energy/distance units. Must be pre-allocated and zeroed.

type forces:

wp.array(dtype=vec3f), shape [num_atoms]

param energy:

OUTPUT: Dispersion energy in energy units. Must be pre-allocated and zeroed.

type energy:

wp.array(dtype=float32), shape [num_systems]

param virial:

OUTPUT: Virial tensor in energy units. Must be pre-allocated and zeroed. Only computed if compute_virial=True.

type virial:

wp.array(dtype=mat33f), shape [num_systems]

param batch_idx:

Batch indices mapping each atom to its system index.

type batch_idx:

wp.array(dtype=int32), shape [num_atoms]

param cartesian_shifts:

SCRATCH: Pre-allocated buffer for Cartesian shift vectors. Populated by Pass 0 from unit cell shifts. Must be pre-allocated with length matching idx_j.

type cartesian_shifts:

wp.array(dtype=vec3f or vec3d), shape [num_edges]

param dE_dCN:

SCRATCH: Pre-allocated buffer for chain rule \(\partial E/\partial \text{CN}\) intermediate. Must be pre-allocated and zeroed by caller.

type dE_dCN:

wp.array(dtype=float32), shape [num_atoms]

param wp_dtype:

Warp scalar dtype (wp.float32 or wp.float64) matching positions dtype.

type wp_dtype:

type

param device:

Warp device string (e.g., ‘cuda:0’, ‘cpu’).

type device:

str

param k1:

CN counting function steepness parameter, in inverse distance units (typically 16.0 1/Bohr). Default: 16.0

type k1:

float, optional

param k3:

CN interpolation Gaussian width parameter (typically -4.0, dimensionless). Default: -4.0

type k3:

float, optional

param s6:

\(C_6\) term scaling factor (typically 1.0, dimensionless). Default: 1.0

type s6:

float, optional

param s5_smoothing_on:

Distance where S5 switching begins, in same units as positions. Default: 0.0

type s5_smoothing_on:

float, optional

param s5_smoothing_off:

Distance where S5 switching completes, in same units as positions. Default: 0.0

type s5_smoothing_off:

float, optional

param compute_virial:

If True, compute virial tensor. Default: False

type compute_virial:

bool, optional

returns:

All outputs are written to pre-allocated arrays (coord_num, forces, energy, virial).

rtype:

None

Notes

  • All output arrays must be pre-allocated and zeroed by the caller

  • Supports float32 and float64 positions/cell; outputs always float32

  • Padding atoms indicated by numbers[i] == 0 are skipped

  • Two-body only: Three-body Axilrod-Teller-Muto (\(C_9\)) terms not included

  • Unit consistency required: standard D3 parameters use atomic units (Bohr for distances, Hartree for energy)

  • Virial tensor is computed when compute_virial=True

See also

dftd3

Neighbor list (CSR) format, non-periodic

dftd3_matrix

Neighbor matrix format, non-periodic

dftd3_matrix_pbc

Neighbor matrix format with PBC support

Parameters:
Return type:

None

FourierD3: Particle-Mesh DFT-D3#

FourierD3 evaluates a periodic particle-mesh variant of DFT-D3(BJ) in \(O(N \log N)\), using the same damped dispersion lattice sum with a modified coordination-number model, and with no pair cutoff on the dispersion sum. The one real-space cutoff that remains is the short coordination-number list.

Unlike the launchers above, these are component launchers rather than one end-to-end call. Warp has no full-mesh FFT, so the two transforms belong to the calling framework and the launchers are driven around them, in the pass order given below.

FourierD3: Particle-Mesh Evaluation of the DFT-D3 Dispersion Correction#

Periodic DFT-D3(BJ) dispersion in \(O(N \log N)\) with no pair cutoff on the dispersion sum; only the short coordination-number list remains.

Mesh summation needs a separable pair coefficient, and D3’s \(C_6\) couples both atoms’ coordination numbers. A host-side low-rank decomposition (nvalchemiops.interactions.dispersion._c6_decomposition) restores separability, \(C_6^{ij} = \sum_\ell \lambda_\ell c_6[i, \ell] c_6[j, \ell]\), so each slot spreads onto its own mesh channel. Becke-Johnson damping makes the potential absolutely integrable, so its transform is closed-form: no Ewald splitting parameter and no real-space dispersion sum, with the mesh Nyquist frequency the only truncation.

Warp has no full-mesh FFT, so the two transforms belong to the calling framework and this module supplies the surrounding launchers. Spread and gather live in nvalchemiops.math.spline.

Self-energy must precede the chain rule: it is quadratic in the coefficients, which depend on coordination number, so applying it afterwards as a scalar would drop its force and virial contribution.

Units#

Unit-agnostic, but positions, cell, covalent_radii, cutoff and the mesh spacing must share one system (D3 parameters are conventionally atomic units). cutoff must equal the neighbour-list cutoff, because the counting function reaches zero exactly there.

References

Valeeva et al., A fast summation method for the DFT-D3 dispersion correction, arXiv:2607.15103.

Real-Space Passes#

nvalchemiops.interactions.dispersion._fourier_dftd3.fd3_coordination_numbers(positions, numbers, idx_j, neighbor_ptr, cartesian_shifts, covalent_radii, cutoff, coord_num, wp_dtype, device=None)[source]#

Compute coordination numbers with the FourierD3 counting function.

Parameters:
  • positions (wp.array, shape (N,), dtype=wp.vec3f or wp.vec3d) – Atomic positions.

  • numbers (wp.array, shape (N,), dtype=wp.int32) – Atomic numbers. Zero marks a padding atom, which is skipped.

  • idx_j (wp.array, shape (E,), dtype=wp.int32) – Neighbour index for each directed edge.

  • neighbor_ptr (wp.array, shape (N + 1,), dtype=wp.int32) – Start of each atom’s edge slice.

  • cartesian_shifts (wp.array, shape (E,), dtype=wp.vec3f or wp.vec3d) – Periodic image offset for each edge, already in Cartesian units.

  • covalent_radii (wp.array, shape (max_z + 1,)) – Covalent radii indexed by atomic number, in the same length unit as positions.

  • cutoff (float) – Neighbour-list cutoff. Must equal the radius the list was built with: the counting function is constructed to reach zero exactly here, and a mismatch reintroduces the truncation discontinuity the modified form exists to remove.

  • coord_num (wp.array, shape (N,)) – OUTPUT: coordination number per atom.

  • wp_dtype (type) – Warp scalar dtype (wp.float32 or wp.float64).

  • device (str | None) – Warp device string. If None, inferred from arrays.

Return type:

None

nvalchemiops.interactions.dispersion._fourier_dftd3.fd3_coordination_numbers_matrix(positions, numbers, neighbor_matrix, cartesian_shifts, covalent_radii, cutoff, coord_num, wp_dtype, device=None, fill_value=None)[source]#

Coordination numbers from a dense neighbour matrix.

The dense counterpart of fd3_coordination_numbers(); see that function for the shared parameters and for the requirement that cutoff match the radius the neighbour list was built with.

Parameters:
  • neighbor_matrix (wp.array2d, shape (N, max_neighbors), dtype=wp.int32) – Neighbour indices, padded with values at or above fill_value.

  • cartesian_shifts (wp.array2d, shape (N, max_neighbors)) – Periodic image offset for each slot, in Cartesian units.

  • fill_value (int, optional) – Padding sentinel. Defaults to the atom count, matching the neighbour-list builders.

  • positions (array)

  • numbers (array)

  • covalent_radii (array)

  • cutoff (float)

  • coord_num (array)

  • wp_dtype (type)

  • device (str | None)

Return type:

None

nvalchemiops.interactions.dispersion._fourier_dftd3.fd3_coefficients(coord_num, species_index, cnref, v_q, c6, dc6_dcn, wp_dtype, device=None)[source]#

Evaluate the separable per-atom coefficients and their coordination derivative.

Parameters:
  • coord_num (wp.array, shape (N,)) – Coordination number per atom.

  • species_index (wp.array, shape (N,), dtype=wp.int32) – Channel index per atom, from C6Decomposition.species_map. Negative marks an atom whose species is not covered; its coefficients are set to zero.

  • cnref (wp.array2d, shape (n_species, n_ref)) – Reference coordination numbers. Negative entries mark unused reference slots.

  • v_q (wp.array3d, shape (n_species, n_ref, rank)) – Eigenvectors of the decomposed reference tensor.

  • c6 (wp.array2d, shape (N, rank)) – OUTPUT: separable coefficients.

  • dc6_dcn (wp.array2d, shape (N, rank)) – OUTPUT: their derivative with respect to the coordination number.

  • wp_dtype (type) – Warp scalar dtype (wp.float32 or wp.float64).

  • device (str | None) – Warp device string. If None, inferred from arrays.

Return type:

None

Mesh Spread#

Pass 3, between the real-space passes and the forward transform. Unlike the general channel spread in nvalchemiops.math.spline, this one applies no stencil-weight threshold, so the interpolation is the exact B-spline that fd3_gather_and_force() differentiates.

nvalchemiops.interactions.dispersion._fourier_dftd3.fd3_spread(positions, c6, group_idx, cell_inv_t, spline_order, rank, mesh, wp_dtype, device=None)[source]#

Spread the separable coefficients onto the mesh.

Parameters:
  • positions (wp.array, shape (N,), dtype=wp.vec3f or wp.vec3d) – Atomic positions.

  • c6 (wp.array2d, shape (N, rank)) – Separable per-atom coefficients.

  • group_idx (wp.array, shape (N,), dtype=wp.int32) – system * n_species + species per atom. Negative marks an atom to skip.

  • cell_inv_t (wp.array, shape (B * n_species,), dtype=wp.mat33f or wp.mat33d) – Transpose of the inverse cell per group, repeat-interleaved across species.

  • spline_order (int) – B-spline order.

  • rank (int) – Channels per group.

  • mesh (wp.array4d, shape (B * n_species * rank, nx, ny, nz)) – OUTPUT: accumulated into, so it must be zero-initialised.

  • wp_dtype (type) – Warp scalar dtype (wp.float32 or wp.float64).

  • device (str | None) – Warp device string. If None, inferred from arrays.

Return type:

None

See also

fd3_gather_and_force

The adjoint, which applies the same interpolation.

Reciprocal-Space Pass#

nvalchemiops.interactions.dispersion._fourier_dftd3.fd3_kspace(mesh_fft, k_matrix, moduli_x, moduli_y, moduli_z, volumes, sqrt_q, eigs, s6, s8, a1, a2, mesh_dimensions, n_species, rank, energy, cotangent, virial, wp_dtype, device=None, compute_virial=False)[source]#

Contract the transformed mesh against the dispersion kernel.

Consumes the forward real-to-complex transform of the spread mesh and produces the reciprocal-space energy together with the cotangent field.

Parameters:
  • mesh_fft (wp.array4d, shape (B * n_species * rank, nx, ny, nz // 2 + 1), dtype=wp.vec2f) – or wp.vec2d Transformed mesh, real and imaginary parts adjacent. Channel (b * n_species + species) * rank + slot.

  • k_matrix (wp.array, shape (B,), dtype=wp.mat33f or wp.mat33d) – 2 * pi * inverse(cell) per system, so that k_matrix @ miller is the Cartesian wave vector.

  • moduli_x (wp.array) – B-spline attenuation per axis, lengths nx, ny and nz // 2 + 1.

  • moduli_y (wp.array) – B-spline attenuation per axis, lengths nx, ny and nz // 2 + 1.

  • moduli_z (wp.array) – B-spline attenuation per axis, lengths nx, ny and nz // 2 + 1.

  • volumes (wp.array, shape (B,)) – Cell volume per system.

  • sqrt_q (wp.array, shape (n_species,)) – Square root of the quadrupole-to-dipole ratio per species channel.

  • eigs (wp.array, shape (rank,)) – Eigenvalues of the decomposed reference tensor. May be negative.

  • s6 (float) – Becke-Johnson damping parameters. These are the only source of the damping used anywhere in the evaluation.

  • s8 (float) – Becke-Johnson damping parameters. These are the only source of the damping used anywhere in the evaluation.

  • a1 (float) – Becke-Johnson damping parameters. These are the only source of the damping used anywhere in the evaluation.

  • a2 (float) – Becke-Johnson damping parameters. These are the only source of the damping used anywhere in the evaluation.

  • mesh_dimensions (tuple[int, int, int]) – Full mesh size, before the real-to-complex transform halves the last axis.

  • n_species (int) – Channel layout of mesh_fft.

  • rank (int) – Channel layout of mesh_fft.

  • energy (wp.array, shape (B,)) – OUTPUT: accumulated reciprocal-space energy. Must be zero-initialised.

  • cotangent (wp.array4d) – OUTPUT: field whose inverse transform, taken with an unnormalised convention, is dE/d(mesh). Same shape and dtype as mesh_fft; fully overwritten.

  • virial (wp.array, shape (B,), dtype=wp.mat33f or wp.mat33d) – IN-OUT: the reciprocal-space strain derivative is accumulated when compute_virial is set. Must be zero-initialised.

  • wp_dtype (type) – Warp scalar dtype (wp.float32 or wp.float64).

  • device (str | None) – Warp device string. If None, inferred from arrays.

  • compute_virial (bool, default=False) – Whether to accumulate the reciprocal-space virial. This is the only pass that can produce it.

Return type:

None

Notes

The energy sum carries the real-to-complex multiplicity weight, because it reduces over a half spectrum. The cotangent does not: the inverse transform reconstructs the unstored half itself, so weighting it as well would double-count every interior bin.

Gradient Passes#

nvalchemiops.interactions.dispersion._fourier_dftd3.fd3_gather_and_force(potential, positions, c6, group_idx, cell_inv_t, spline_order, rank, d_energy_d_c6, forces, wp_dtype, device=None)[source]#

Gather the coefficient derivative and the direct mesh force in one pass.

Parameters:
  • potential (wp.array4d, shape (B * n_species * rank, nx, ny, nz)) – Inverse transform of the cotangent field from fd3_kspace(), taken with an unnormalised convention so that it is the derivative of the energy with respect to the mesh.

  • positions (wp.array, shape (N,), dtype=wp.vec3f or wp.vec3d) – Atomic positions.

  • c6 (wp.array2d, shape (N, rank)) – Separable per-atom coefficients.

  • group_idx (wp.array, shape (N,), dtype=wp.int32) – system * n_species + species per atom, the same index used when spreading. Negative marks an atom to skip.

  • cell_inv_t (wp.array, shape (B * n_species,), dtype=wp.mat33f or wp.mat33d) – Transpose of the inverse cell per group, repeat-interleaved across species.

  • spline_order (int) – B-spline order used for the spread.

  • rank (int) – Channels per group.

  • d_energy_d_c6 (wp.array2d, shape (N, rank)) – OUTPUT: derivative with respect to the coefficients. Must be zero-initialised.

  • forces (wp.array, shape (N,), dtype=wp.vec3f or wp.vec3d) – IN-OUT: the direct mesh force is added to the existing contents.

  • wp_dtype (type) – Warp scalar dtype (wp.float32 or wp.float64).

  • device (str | None) – Warp device string. If None, inferred from arrays.

Return type:

None

nvalchemiops.interactions.dispersion._fourier_dftd3.fd3_self_energy(c6, species_index, batch_idx, sqrt_q, eigs, s6, s8, a1, a2, energy, d_energy_d_c6, wp_dtype, device=None)[source]#

Cancel the self pair and record its coefficient derivative.

Must run before fd3_cn_chain(), because the term it adds depends on the coefficients and therefore reaches the forces through the coordination-number chain rule.

Parameters:
  • c6 (wp.array2d, shape (N, rank)) – Separable per-atom coefficients.

  • species_index (wp.array, shape (N,), dtype=wp.int32) – Channel index per atom; negative marks an uncovered species, which is skipped.

  • batch_idx (wp.array, shape (N,), dtype=wp.int32) – System index per atom.

  • sqrt_q (wp.array, shape (n_species,)) – Square root of the quadrupole-to-dipole ratio per species channel.

  • eigs (wp.array, shape (rank,)) – Eigenvalues of the decomposed reference tensor.

  • s6 (float) – Becke-Johnson damping parameters, the same values passed to fd3_kspace().

  • s8 (float) – Becke-Johnson damping parameters, the same values passed to fd3_kspace().

  • a1 (float) – Becke-Johnson damping parameters, the same values passed to fd3_kspace().

  • a2 (float) – Becke-Johnson damping parameters, the same values passed to fd3_kspace().

  • energy (wp.array, shape (B,)) – IN-OUT: the self-energy is added to the existing contents.

  • d_energy_d_c6 (wp.array2d, shape (N, rank)) – IN-OUT: the coefficient derivative is added to the existing contents.

  • wp_dtype (type) – Warp scalar dtype (wp.float32 or wp.float64).

  • device (str | None) – Warp device string. If None, inferred from arrays.

Return type:

None

nvalchemiops.interactions.dispersion._fourier_dftd3.fd3_cn_chain(d_energy_d_c6, dc6_dcn, positions, numbers, idx_j, neighbor_ptr, cartesian_shifts, covalent_radii, cutoff, batch_idx, d_energy_d_cn, forces, virial, wp_dtype, device=None, compute_virial=False)[source]#

Carry the coefficient derivative back to positions through the coordination numbers.

Parameters:
  • d_energy_d_c6 (wp.array2d, shape (N, rank)) – Derivative of the energy with respect to the separable coefficients. Every contribution must already be folded in, the self-energy included.

  • dc6_dcn (wp.array2d, shape (N, rank)) – Derivative of the coefficients with respect to coordination number, from fd3_coefficients().

  • positions (array) – The same neighbour-list description passed to fd3_coordination_numbers().

  • numbers (array) – The same neighbour-list description passed to fd3_coordination_numbers().

  • idx_j (array) – The same neighbour-list description passed to fd3_coordination_numbers().

  • neighbor_ptr (array) – The same neighbour-list description passed to fd3_coordination_numbers().

  • cartesian_shifts (array) – The same neighbour-list description passed to fd3_coordination_numbers().

  • covalent_radii (array) – The same neighbour-list description passed to fd3_coordination_numbers().

  • cutoff (float) – The same neighbour-list description passed to fd3_coordination_numbers().

  • batch_idx (wp.array, shape (N,), dtype=wp.int32) – System index per atom.

  • d_energy_d_cn (wp.array, shape (N,)) – OUTPUT: per-atom coordination sensitivity. Overwritten.

  • forces (wp.array, shape (N,), dtype=wp.vec3f or wp.vec3d) – IN-OUT: the chain-rule contribution is accumulated into the existing contents.

  • virial (wp.array, shape (B,), dtype=wp.mat33f or wp.mat33d) – IN-OUT: accumulated when compute_virial is set.

  • wp_dtype (type) – Warp scalar dtype (wp.float32 or wp.float64).

  • device (str | None) – Warp device string. If None, inferred from arrays.

  • compute_virial (bool, default=False) – Whether to accumulate the virial.

Return type:

None

nvalchemiops.interactions.dispersion._fourier_dftd3.fd3_cn_chain_matrix(d_energy_d_c6, dc6_dcn, positions, numbers, neighbor_matrix, cartesian_shifts, covalent_radii, cutoff, batch_idx, d_energy_d_cn, forces, virial, wp_dtype, device=None, compute_virial=False, fill_value=None)[source]#

Coordination chain rule over a dense neighbour matrix.

The dense counterpart of fd3_cn_chain(); see that function for the shared parameters.

Parameters:
  • neighbor_matrix (wp.array2d, shape (N, max_neighbors), dtype=wp.int32) – Neighbour indices, padded with values at or above fill_value.

  • cartesian_shifts (wp.array2d, shape (N, max_neighbors)) – Periodic image offset for each slot, in Cartesian units.

  • fill_value (int, optional) – Padding sentinel. Defaults to the atom count.

  • d_energy_d_c6 (array)

  • dc6_dcn (array)

  • positions (array)

  • numbers (array)

  • covalent_radii (array)

  • cutoff (float)

  • batch_idx (array)

  • d_energy_d_cn (array)

  • forces (array)

  • virial (array)

  • wp_dtype (type)

  • device (str | None)

  • compute_virial (bool)

Return type:

None

Reference Tensor Decomposition#

Computed once on the host, not on the GPU. The rank it selects sets the number of mesh channels and so the cost of every evaluation that follows.

Low-Rank Decomposition of the DFT-D3 Reference Tensor#

FourierD3 evaluates the D3 dispersion sum on a particle mesh. Mesh methods require the pairwise coefficient to separate into atom-centred factors, which D3’s environment-dependent \(C_6\) coefficients do not do: they couple the coordination numbers of both atoms.

This module restores separability by decomposing Grimme’s \(C_6^{\text{ref}}\) tensor once, on the host, into

\[C_6^{\text{ref}}(Z_i, \theta^p; Z_j, \theta^q) \approx \sum_{\ell} \lambda_{\ell}\, v_{\ell, Z_i}(\theta^p)\, v_{\ell, Z_j}(\theta^q)\]

so that the per-atom coefficients

\[c_6[i, \ell] = \frac{\sum_p v_{\ell, Z_i}(\theta^p) L_i^p}{\sum_p L_i^p}, \qquad L_i^p = \exp\!\big(-4 (\theta_i - \theta_{Z_i}^p)^2\big)\]

reproduce the pair coefficient as \(C_6^{ij} = \sum_{\ell} \lambda_{\ell}\, c_6[i,\ell]\, c_6[j,\ell]\). Each rank slot then spreads onto its own mesh channel and is summed independently.

Rank is the accuracy/cost knob: it sets the number of mesh channels, and therefore both the FFT cost and the mesh memory. The reference tensor is strongly linearly dependent, so the rank needed for a given tolerance grows sublinearly with the number of species.

The decomposition depends only on the reference tables, the species present, and the tolerance. It is independent of the damping parameters, so one result is valid for every functional parametrisation.

Units#

This module is unit-agnostic. eigs and v_q carry whatever units c6ab uses, and the returned cn_ref whatever units the input cn_ref table uses (coordination numbers are dimensionless). The two differ in layout, not in meaning: the input is pair-indexed (max_z + 1, max_z + 1, n_ref, n_ref), the output per-species (n_species, n_ref).

References

Valeeva et al., A fast summation method for the DFT-D3 dispersion correction, arXiv:2607.15103, Section II B and Eq. (20)-(22).

nvalchemiops.interactions.dispersion._c6_decomposition.decompose_c6_reference(c6ab, cn_ref, species, tol=1e-4, max_rank=None)[source]#

Decompose the DFT-D3 reference tensor into separable low-rank factors.

Builds the symmetric block matrix over (species, reference-slot) pairs, eigendecomposes it, and truncates at the smallest rank meeting tol.

Parameters:
  • c6ab (np.ndarray, shape (max_z + 1, max_z + 1, n_ref, n_ref)) – Reference \(C_6\) coefficients from the DFT-D3 parametrisation. Zero entries mark unused reference slots.

  • cn_ref (np.ndarray, shape (max_z + 1, max_z + 1, n_ref, n_ref)) – Reference coordination numbers, pair-indexed.

  • species (Sequence[int]) – Atomic numbers present in the system. Duplicates and ordering are ignored: the result is canonicalised to sorted unique values, so the channel layout is deterministic.

  • tol (float, default=1e-4) – Target maximum relative error of the reconstructed tensor. The default follows the FourierD3 paper, which reports it as a good balance for systems with fewer than ten elements.

  • max_rank (int, optional) – Hard ceiling on the retained rank. When the ceiling prevents tol from being met, the decomposition is returned anyway and C6Decomposition.max_relative_error reports what was achieved.

Returns:

Factors, reference coordination numbers, channel map, and achieved error.

Return type:

C6Decomposition

Raises:

ValueError – If species is empty, tol is not positive, max_rank is not positive, the tables have inconsistent shapes, or a species carries no reference data.

Notes

Results are cached on the content of the tables together with every option that can change the factors, so switching parameter sets or ceilings cannot return stale factors. The cache holds at most 32 entries.

The decomposition does not depend on the damping parameters, so a single result may be reused across functional parametrisations.

Examples

>>> decomposition = decompose_c6_reference(c6ab, cn_ref, species=[1, 8])
>>> decomposition.rank, decomposition.num_channels
(4, 8)
nvalchemiops.interactions.dispersion._c6_decomposition.extract_species_reference_cn(c6ab, cn_ref, species)[source]#

Collapse the pair-indexed reference tables to per-species arrays.

Grimme’s tables store reference coordination numbers per element pair, as cn_ref[Zi, Zj, p, q], because they are consumed by a pairwise interpolation. The value depends only on Zi and p; the trailing indices repeat it. FourierD3 needs the per-species form, since each atom is weighted independently before it reaches the mesh.

Parameters:
  • c6ab (np.ndarray, shape (max_z + 1, max_z + 1, n_ref, n_ref)) – Reference \(C_6\) coefficients. Entries equal to zero mark unused reference slots.

  • cn_ref (np.ndarray, shape (max_z + 1, max_z + 1, n_ref, n_ref)) – Reference coordination numbers, pair-indexed.

  • species (Sequence[int]) – Atomic numbers to extract, in the caller’s order.

Returns:

  • cnref (np.ndarray, shape (n_species, n_ref), dtype=float64) – Reference coordination numbers, padded with CNREF_INVALID.

  • valid (np.ndarray, shape (n_species, n_ref), dtype=bool) – True where a species uses a reference slot.

Raises:

ValueError – If a species has no valid reference data, or if the tables disagree about a species’ reference coordination numbers across partner elements.

Return type:

tuple[ndarray, ndarray]

Notes

The consistency check is not defensive padding: it is the assumption that makes the per-species form well defined. If a future parameter set breaks it, silently taking the first partner’s values would produce wrong coefficients with no other symptom.

nvalchemiops.interactions.dispersion._c6_decomposition.clear_decomposition_cache()[source]#

Drop all cached decompositions.

Useful in tests and in long-running processes that have finished with one chemistry.

Return type:

None

class nvalchemiops.interactions.dispersion._c6_decomposition.C6Decomposition(species, eigs, v_q, cn_ref, valid, species_map, max_relative_error)[source]#

Separable low-rank factors of the DFT-D3 reference tensor.

Parameters:
species#

Atomic numbers covered, ascending. Position in this array is the channel index.

Type:

np.ndarray, shape (n_species,), dtype=int32

eigs#

Eigenvalues \(\lambda_{\ell}\), ordered by descending magnitude. May be negative; the energy expression is a signed sum, not a norm.

Type:

np.ndarray, shape (rank,), dtype=float64

v_q#

Eigenvectors \(v_{\ell, Z}(\theta^p)\). Rows for invalid reference slots are zero.

Type:

np.ndarray, shape (n_species, n_ref, rank), dtype=float64

cn_ref#

Reference coordination numbers per species, padded with CNREF_INVALID.

Type:

np.ndarray, shape (n_species, n_ref), dtype=float64

valid#

True where a reference slot carries data.

Type:

np.ndarray, shape (n_species, n_ref), dtype=bool

species_map#

Atomic number to channel index; -1 for elements not covered.

Type:

np.ndarray, shape (max_z + 1,), dtype=int32

max_relative_error#

Largest relative error of the reconstructed tensor over all valid entries.

Type:

float

property n_ref: int#

Reference-coordination-number slots per species, including padding.

property n_species: int#

Number of species covered.

property num_channels: int#

Mesh channels required, n_species * rank.

property rank: int#

Number of retained rank slots.