jaxdem.utils.random_sphere_configuration#

Generate random, energy-minimized sphere configurations in 2D or 3D.

Functions

minimize_sphere_configuration(...[, ...])

Minimize a user-supplied sphere configuration at a target packing fraction.

random_sphere_configuration(particle_radii, ...)

Generate one or more random sphere packings at a target packing fraction.

jaxdem.utils.random_sphere_configuration.random_sphere_configuration(particle_radii: Sequence[float] | Sequence[Sequence[float]], phi: float | Sequence[float], dim: int, seed: int | None = None, collider_type: str = 'naive', box_aspect: Sequence[float] | Sequence[Sequence[float]] | None = None, max_avg_pe: float | None = 1e-16, domain_type: str = 'periodic') tuple[Array, Array][source]#

Generate one or more random sphere packings at a target packing fraction.

The function builds systems of spherical particles, draws particle positions uniformly at random inside a rectangular box, and then minimizes the potential energy to get a mechanically stable configuration.

The function supports batching over multiple independent “systems”. It treats the leading axis as the system index and broadcasts any length-1 inputs to match the maximum number of systems inferred from the inputs.

Parameters:
  • particle_radii

    Particle radii for one system or multiple systems.

    • Single system: a 1D sequence of length N (radii for each particle).

    • Multiple systems: a 2D sequence with shape (S, N) (one radii list per system).

    The function converts this to a JAX array with shape (S, N).

  • phi

    Target packing fraction(s).

    • Scalar: a single float applied to all systems.

    • Per-system: a 1D sequence of length S.

    The function converts this to a JAX array with shape (S, 1) and then broadcasts/pads it to match the inferred number of systems.

  • dim – Spatial dimension (e.g. 2 or 3).

  • seed

    RNG seed used to initialize particle positions. If None, a random seed is drawn via NumPy.

    Note: the function uses a single JAX PRNGKey to generate the full position array of shape (S, N, dim).

  • collider_type – Collision detection backend. Must be one of "naive" or "celllist".

  • box_aspect

    Box aspect ratios for the periodic domain.

    • If None, defaults to jnp.ones(dim).

    • Otherwise must be a 1D sequence of length dim.

    The function broadcasts/pads this to shape (S, dim).

    (Even though the type annotation allows a sequence-of-sequences, the current implementation asserts len(box_aspect) == dim before broadcasting, so per-system (S, dim) input is not accepted here.)

  • max_avg_pe – Maximum potential energy per particle allowed in the configuration. The minimizer tries to adjust the sphere positions until it meets this value. Far above the jamming density, the minimizer will likely run for the maximum number of steps and may take unnecessarily long to terminate.

  • domain_type – Boundary condition for the analogue sphere system. Must be a registered Domain type (e.g. "periodic" or "reflect"). Default "periodic".

Returns:

  • pos – Particle positions after minimization.

    • If S > 1: shape (S, N, dim).

    • If S == 1: shape (N, dim) due to squeeze().

  • box_size – Periodic box size vectors.

    • If S > 1: shape (S, dim).

    • If S == 1: shape (dim,) due to squeeze().

Notes

  • Broadcasting rule: any input provided for a single system (leading dimension 1) is replicated to match the maximum S inferred from particle_radii, phi, and box_aspect.

  • The final squeeze() calls can also drop other singleton dimensions (e.g. if N == 1). If you need stable rank/shape, remove the squeezes.

jaxdem.utils.random_sphere_configuration.minimize_sphere_configuration(particle_radii: Sequence[float] | Sequence[Sequence[float]] | Array, pos: Sequence[Sequence[float]] | Sequence[Sequence[Sequence[float]]] | Array, phi: float | Sequence[float] | Array, dim: int, collider_type: str = 'naive', box_aspect: Sequence[float] | Sequence[Sequence[float]] | None = None, max_avg_pe: float | None = 1e-16, domain_type: str = 'periodic') tuple[Array, Array][source]#

Minimize a user-supplied sphere configuration at a target packing fraction.

The function builds a box whose volume is sum(particle_volume) / phi (with the requested aspect ratio), places the particles at pos in that box, and FIRE-minimizes the potential energy.

Parameters:
  • particle_radii

    Particle radii for one or multiple systems.

    • Single system: 1D sequence of length N.

    • Multiple systems: 2D sequence of shape (S, N).

  • pos – Particle centers in absolute coordinates (same frame as the final box anchored at the origin). Shape (N, dim) or (S, N, dim). A periodic domain wraps positions outside the computed box during minimization.

  • phi – Target packing fraction. Scalar or 1D sequence of length S.

  • dim – Spatial dimension (2 or 3).

  • collider_type – Collision-detection backend, "naive" or "celllist".

  • box_aspect – Aspect ratios of the periodic box. None defaults to jnp.ones(dim). Shape (dim,), broadcast to (S, dim).

  • max_avg_pe – Convergence tolerance used for both pe_tol and pe_diff_tol.

  • domain_type – Boundary condition for the analogue sphere system. Must be a registered Domain type (e.g. "periodic" or "reflect"). Default "periodic".

Returns:

  • pos – Minimized particle positions (shape (S, N, dim), squeezed if S == 1).

  • box_size – Periodic box size vector(s) (shape (S, dim), squeezed if S == 1).