jaxdem.forces.spring#

Linear spring force model.

Classes

FacetFacetSpringForce([laws])

Linear spring contact between facets.

SphereFacetSpringForce([laws])

Linear spring contact between spheres and facets.

SpringForce([laws])

A ForceModel implementation for a linear spring-like interaction between particles.

class jaxdem.forces.spring.SpringForce(laws: tuple[ForceModel, ...] = ())#

Bases: ForceModel

A ForceModel implementation for a linear spring-like interaction between particles.

Notes

  • The ‘effective Young’s modulus’ (\(k_{eff,\; ij}\)) is retrieved from the jaxdem.System.mat_table based on the material IDs of the interacting particles.

  • The force is zero if \(i == j\).

  • Distances and normals are computed with the zero-safe double-where helpers in jaxdem.utils.linalg, so the force and its gradients remain finite when particles are perfectly co-located.

The penetration \(\delta\) (overlap) between two particles \(i\) and \(j\) is:

\[\delta = \max\left(0, (R_i + R_j) - r\right)\]

where \(R_i\) and \(R_j\) are the radii of particles \(i\) and \(j\) respectively, and \(r = ||r_{ij}||\) is the distance between their centers.

The force \(F_{ij}\) acting on particle \(i\) due to particle \(j\) is:

\[F_{ij} = k_{eff,\; ij}\, \delta\, \hat{n}_{ij}\]

where \(\hat{n}_{ij} = \vec{r}_{ij} / r\) is the unit vector from particle \(j\) to particle \(i\).

The potential energy \(E_{ij}\) of the interaction is:

\[E_{ij} = \frac{1}{2} k_{eff,\; ij} \delta^2\]

where \(k_{eff,\; ij}\) is the effective Young’s modulus for the particle pair.

static force(i: int, j: int, pos: jax.Array, state: State, system: System) tuple[jax.Array, jax.Array][source]#

Compute linear spring-like interaction force acting on particle \(i\) due to particle \(j\).

Returns zero when \(i = j\).

Parameters:
  • i (int) – Index of the first particle.

  • j (int) – Index of the second particle.

  • state (State) – Current state of the simulation.

  • system (System) – Simulation system configuration.

Returns:

(force, torque) with shapes (dim,) and (ang_dim,). The torque is always zero for this model.

Return type:

tuple[jax.Array, jax.Array]

static energy(i: int, j: int, pos: jax.Array, state: State, system: System) jax.Array[source]#

Compute linear spring-like interaction potential energy between particle \(i\) and particle \(j\).

Returns zero when \(i = j\).

Parameters:
  • i (int) – Index of the first particle.

  • j (int) – Index of the second particle.

  • state (State) – Current state of the simulation.

  • system (System) – Simulation system configuration.

Returns:

Scalar JAX array representing the potential energy of the interaction between particles \(i\) and \(j\).

Return type:

jax.Array

property required_material_properties: tuple[str, ...][source]#

A static tuple of strings specifying the material properties required by this force model.

These properties (e.g., ‘young_eff’, ‘restitution’, …) must be present in the System.mat_table for the model to function correctly. This is used for validation.

class jaxdem.forces.spring.SphereFacetSpringForce(laws: tuple[ForceModel, ...] = ())#

Bases: ForceModel

Linear spring contact between spheres and facets.

Warning

Facet contacts are detected through the facet’s vertex spheres (in particular the facet’s primary vertex). The collider’s neighbor cutoff must therefore be at least the facet circumradius (the largest vertex-to-contact-point distance) plus the contact thickness (state.rad). If the primary vertex lies outside the cutoff while the contact point is in range, the contact is silently missed or applied asymmetrically. Cell-list based colliders must be configured with cutoff >= max facet circumradius + thickness.

The contact thickness is taken from the facet vertices’ state.rad (set via State.add_facet(thickness=...)); the force model itself has no thickness parameter.

static force(i: int, j: int, pos: jax.Array, state: State, system: System) tuple[jax.Array, jax.Array][source]#
static energy(i: int, j: int, pos: jax.Array, state: State, system: System) jax.Array[source]#
class jaxdem.forces.spring.FacetFacetSpringForce(laws: tuple[ForceModel, ...] = ())#

Bases: ForceModel

Linear spring contact between facets.

Warning

Facet contacts are detected through the facets’ vertex spheres (in particular each facet’s primary vertex). The collider’s neighbor cutoff must therefore be at least the facet circumradius (the largest vertex-to-contact-point distance) plus the contact thickness (state.rad). If a primary vertex lies outside the cutoff while the contact point is in range, the contact is silently missed or applied asymmetrically. Cell-list based colliders must be configured with cutoff >= max facet circumradius + thickness.

The contact thickness is taken from the facet vertices’ state.rad (set via State.add_facet(thickness=...)); the force model itself has no thickness parameter.

static force(i: int, j: int, pos: jax.Array, state: State, system: System) tuple[jax.Array, jax.Array][source]#
static energy(i: int, j: int, pos: jax.Array, state: State, system: System) jax.Array[source]#