jaxdem.utils.post_processing#

Packing summaries, contact networks, and energy spectra.

Functions

analyze_packing(state, system, *[, ...])

Analyze a sphere or rigid-clump packing before and after rattler removal.

Classes

ClumpContactNetwork(pair_ids, row_offsets, ...)

Packed directed clump contacts with aligned geometry and pair statistics.

PackingAnalysis(full, non_rattlers, ...)

Full and non-rattler packing data from the same input configuration.

PackingData(state, system, sphere_contacts, ...)

Analysis of one configuration, with all indices relative to its state.

SphereContactNetwork(pair_ids, row_offsets, ...)

Packed directed sphere contacts, sorted by source then destination ID.

class jaxdem.utils.post_processing.SphereContactNetwork(pair_ids: Array, row_offsets: Array, forces: Array, torques: Array, displacements: Array, overlap: Array, mu: Array, pair_species: Array | None)#

Bases: object

Packed directed sphere contacts, sorted by source then destination ID.

pair_ids has shape (M, 2). For sphere i, slice every pair array with row_offsets[i]:row_offsets[i + 1]. Offsets have length state.N + 1; isolated spheres have empty rows. There is no padding.

forces and displacements have shape (M, dim). Displacement points from destination to source using the domain’s image rule. torques has shape (M, angular_dim) and measures each contact’s moment about the source clump COM, including the member lever arm.

overlap is the signed radius sum minus sphere separation, shape (M,). Attractive contacts can have negative overlap. mu is |F_t| / |F_n| along the sphere separation: zero for zero force, infinity for purely tangential force, and NaN for nonzero force at zero separation. pair_species is None or an integer array (M, 2) inherited from the clump labels supplied to analyze_packing.

Entries exist when force or torque is nonzero. Reciprocal contacts have both directions; pair_ids[:, 0] < pair_ids[:, 1] selects one edge for drawing or counting each physical contact once.

pair_ids: Array#
row_offsets: Array#
forces: Array#
torques: Array#
displacements: Array#
overlap: Array#
mu: Array#
pair_species: Array | None#
class jaxdem.utils.post_processing.ClumpContactNetwork(pair_ids: Array, row_offsets: Array, forces: Array, torques: Array, displacements: Array, mu: Array, sphere_counts: Array, contact_counts: Array, pair_species: Array | None)#

Bases: object

Packed directed clump contacts with aligned geometry and pair statistics.

pair_ids contains clump IDs from the accompanying state, shape (K, 2). row_offsets has length max(clump_id) + 2 (one for an empty state). Unoccupied IDs and isolated clumps have empty rows.

forces is the net force on the source clump; torques is its total moment about the source COM. displacements points from destination COM to source COM using the domain’s image rule. Their shapes are (K, dim), (K, angular_dim), and (K, dim).

mu has shape (K,) and uses the COM axis with the same zero, infinity, and NaN conventions as SphereContactNetwork. sphere_counts has shape (K, 2) and counts distinct participating spheres on each side. contact_counts has shape (K,) and counts constituent directed contacts, including torque-only contacts. Net-force cancellation does not erase an interaction.

pair_species is None or the supplied source/destination species labels, shape (K, 2). All pair arrays share the same row ordering. Reciprocal interactions have both directions.

pair_ids: Array#
row_offsets: Array#
forces: Array#
torques: Array#
displacements: Array#
mu: Array#
sphere_counts: Array#
contact_counts: Array#
pair_species: Array | None#
class jaxdem.utils.post_processing.PackingData(state: State, system: System, sphere_contacts: SphereContactNetwork, clump_contacts: ClumpContactNetwork, original_sphere_ids: jax.Array, original_clump_ids: jax.Array, clump_ids: jax.Array, clump_positions: jax.Array, potential_energy: jax.Array, pressure: jax.Array, packing_fraction: jax.Array, effective_packing_fraction: jax.Array, sphere_contact_counts: jax.Array, vertex_contact_counts: jax.Array, clump_contact_counts: jax.Array, mean_vertex_contacts: float, mean_clump_contacts: float, coordinates: str, dof_per_clump: int, global_modes: int, isostatic_coordination: float, satisfies_isostatic_count: bool, hessian: jax.Array, eigenvalues: jax.Array, eigenvectors: jax.Array, zero_mode_count: int, negative_mode_count: int)#

Bases: object

Analysis of one configuration, with all indices relative to its state.

Variables:
  • system (state,) – Configuration with refreshed forces and collider caches. Positions, velocities, time, queued loads, and contact history are not advanced.

  • clump_contacts (sphere_contacts,) – Packed contact networks. Pair indices address this object’s state.

  • original_clump_ids (original_sphere_ids,) – Maps from current indices to the input state’s indices. Unoccupied clump ID slots contain -1. clump_ids lists the occupied slots.

  • clump_positions (jax.Array) – COM positions indexed by clump ID, shape (max(clump_id) + 1, dim). Unoccupied slots contain NaN. Network edges can be drawn from these positions and the domain-aware pair displacements.

  • pressure (potential_energy,) – Non-bonded pair potential energy and contact virial pressure. Managed external energies, kinetic stress, and boundary reactions are excluded.

  • effective_packing_fraction (packing_fraction,) – Physical particle volume divided by box volume, and a contact-distance estimate. The latter assigns each clump a disk/sphere whose diameter is its mean contacting-clump COM distance. Zero mean distance uses the clump’s stored physical volume. It is not a union-volume measurement.

  • clump_contact_counts (sphere_contact_counts, vertex_contact_counts,) – Force-bearing coordination per sphere, constituent contacts per clump, and distinct contacting clumps per clump. Clump arrays are indexed by clump ID; means include only occupied clumps, including isolated ones.

  • mean_clump_contacts (mean_vertex_contacts,) – Mean per-clump coordination. NaN for an empty state.

  • global_modes (coordinates, dof_per_clump,) – Hessian coordinate convention and degrees used in the count criterion. Sphere coordinates are translational; clump coordinates include rotation.

  • satisfies_isostatic_count (isostatic_coordination,) – 2 * (G * dof_per_clump - global_modes) / G and its comparison with mean vertex coordination. This is a count criterion, not a mechanical stability test. Empty states have NaN coordination and a False result.

  • eigenvectors (hessian, eigenvalues,) – Dense non-bonded energy Hessian, ascending eigenvalues, and eigenvectors stored as columns. Sphere coordinates follow sphere-array order; clump coordinate blocks follow clump_ids. Arrays for an empty state have shapes (0, 0), (0,), and (0, 0).

  • negative_mode_count (zero_mode_count,) – Counts from the spectrum. Negative modes exclude eigenvalues classified as numerical zero. These describe the potential energy, not the full response of a dissipative or history-dependent force law.

state: State#
system: System#
sphere_contacts: SphereContactNetwork#
clump_contacts: ClumpContactNetwork#
original_sphere_ids: jax.Array#
original_clump_ids: jax.Array#
clump_ids: jax.Array#
clump_positions: jax.Array#
potential_energy: jax.Array#
pressure: jax.Array#
packing_fraction: jax.Array#
effective_packing_fraction: jax.Array#
sphere_contact_counts: jax.Array#
vertex_contact_counts: jax.Array#
clump_contact_counts: jax.Array#
mean_vertex_contacts: float#
mean_clump_contacts: float#
coordinates: str#
dof_per_clump: int#
global_modes: int#
isostatic_coordination: float#
satisfies_isostatic_count: bool#
hessian: jax.Array#
eigenvalues: jax.Array#
eigenvectors: jax.Array#
zero_mode_count: int#
negative_mode_count: int#
class jaxdem.utils.post_processing.PackingAnalysis(full: PackingData, non_rattlers: PackingData, rattler_ids: Array, non_rattler_ids: Array, rattler_proportion: float)#

Bases: object

Full and non-rattler packing data from the same input configuration.

full and non_rattlers are PackingData objects with the same fields. When nothing is removed, both refer to the same object. rattler_ids and non_rattler_ids contain original input clump IDs. rattler_proportion is the fraction of input clumps removed, or zero for an empty input. No files are written by the analysis.

jaxdem.utils.h5.save() and jaxdem.utils.h5.load() preserve the nested data objects, contact networks, and their states and systems.

full: PackingData#
non_rattlers: PackingData#
rattler_ids: Array#
non_rattler_ids: Array#
rattler_proportion: float#
jaxdem.utils.post_processing.analyze_packing(state: State, system: System, *, clump_species_ids: jax.typing.ArrayLike | None = None, coordinates: Literal['auto', 'sphere', 'clump'] = 'auto', rotation_scale: jax.typing.ArrayLike | None = None, zc: int | None = None, check_contact_rank: bool = False, contact_rank_tol: float | None = None, global_modes: int | None = None, zero_mode_rel_gap: float = 10000.0, zero_mode_atol: float = 0.0) → PackingAnalysis[source]#

Analyze a sphere or rigid-clump packing before and after rattler removal.

Both results include contact networks, packing statistics, the dense energy Hessian, its eigenvalues and eigenvectors, and zero/negative mode counts.

Parameters:
  • state – One 2D or 3D configuration with its configured collider. Contact snapshots are reused for network geometry, coordination, pressure, effective packing fraction, and rattler detection. History is never advanced. Bonded models are unsupported because removal would require remapping their topology.

  • system – One 2D or 3D configuration with its configured collider. Contact snapshots are reused for network geometry, coordination, pressure, effective packing fraction, and rattler detection. History is never advanced. Bonded models are unsupported because removal would require remapping their topology.

  • clump_species_ids – Optional integer labels, one per occupied clump in ascending clump-ID order. They label both networks’ pairs without changing force routing. No species masks are stored. Omit to return None for pair species.

  • coordinates – auto uses sphere coordinates when each clump is a single sphere at its COM; otherwise it uses clump translations and rotations. This selects both the rattler criterion and Hessian coordinates. The same convention is used for both returned configurations.

  • rotation_scale – Optional positive finite length per occupied clump in ascending ID order, for clump coordinates (delta r_c, R*omega). It is mapped to surviving clumps after removal. Requires clump coordinates.

  • zc – Passed to the matching sphere or clump rattler helper. The default contact threshold is dof_per_clump + 1.

  • check_contact_rank – Passed to the matching sphere or clump rattler helper. The default contact threshold is dof_per_clump + 1.

  • contact_rank_tol – Passed to the matching sphere or clump rattler helper. The default contact threshold is dof_per_clump + 1.

  • global_modes – Modes subtracted in the coordination count, default dim for global translations of a periodic packing. Set explicitly for a different constraint convention. Fixed bodies are included in coordination and Hessian coordinates; this function does not impose their constraints.

  • zero_mode_rel_gap – Relative gap for zero_mode_mask and an additional absolute zero threshold. All-zero spectra are counted entirely as zero modes.

  • zero_mode_atol – Relative gap for zero_mode_mask and an additional absolute zero threshold. All-zero spectra are counted entirely as zero modes.

Returns:

Matching full and non_rattlers data, plus original rattler and non-rattler clump IDs and the removed fraction. Empty results use the same types. No simulation steps, minimization, or file writes occur.

Return type:

PackingAnalysis

Notes

This is a host operation. Contact storage scales with active pairs; dense Hessian and eigenvector storage grows quadratically with coordinate count. The two results share one PackingData object when no clumps are removed.