jaxdem.forces.cundall_strack#
Cundall-Strack linear spring-dashpot contact force model.
Functions
|
Mix sliding-friction coefficients with their arithmetic mean. |
|
Mix sliding-friction coefficients with their geometric mean. |
|
Collect resolved Cundall-Strack forces for all active directed contacts. |
|
Mix sliding-friction coefficients with their maximum. |
|
Mix sliding-friction coefficients with their minimum. |
Classes
|
Directed active contacts resolved into Cundall-Strack components. |
|
History-dependent linear spring/dashpot friction with rolling resistance. |
- class jaxdem.forces.cundall_strack.CundallStrackContactData(pair_ids: jax.Array, normal_forces: jax.Array, tangential_forces: jax.Array, torques: jax.Array, friction_coefficients: jax.Array, mobilized: jax.Array)[source]#
Bases:
NamedTupleDirected active contacts resolved into Cundall-Strack components.
- Variables:
pair_ids (jax.Array) – Sphere indices
(i, j), shape(M, 2). Each row describes the contact force and torque onifromj. Reciprocal contacts are represented by separate rows.tangential_forces (normal_forces,) – Normal and Coulomb-limited tangential force vectors, shape
(M, dim).torques (jax.Array) – Force-law torques about the center of sphere
i, shape(M, 1 | 3). These include tangential contact torque and rolling resistance, but not a clump-member offset moment.friction_coefficients (jax.Array) – Effective sliding-friction coefficient
mu_ijselected by the configured mixing rule, shape(M,).mobilized (jax.Array) – Whether the tangential trial force is on or beyond the Coulomb surface, shape
(M,).
- pair_ids: Array#
Alias for field number 0
- normal_forces: Array#
Alias for field number 1
- tangential_forces: Array#
Alias for field number 2
- torques: Array#
Alias for field number 3
- friction_coefficients: Array#
Alias for field number 4
- mobilized: Array#
Alias for field number 5
- as_contact_data(state: State, system: System) ContactData[source]#
Return the matching generic contact snapshot without reevaluation.
The resolved normal and tangential components are combined into total pair forces. Torques are shifted from each source sphere’s center to its clump center of mass, matching
ContactData. Pair displacements use the configured domain’s image convention.stateandsystemmust describe the unchanged configuration from which this snapshot was collected. Contact history is not read or advanced.
- jaxdem.forces.cundall_strack.minimum_friction(mu_i: Array, mu_j: Array) Array[source]#
Mix sliding-friction coefficients with their minimum.
- jaxdem.forces.cundall_strack.maximum_friction(mu_i: Array, mu_j: Array) Array[source]#
Mix sliding-friction coefficients with their maximum.
- jaxdem.forces.cundall_strack.arithmetic_mean_friction(mu_i: Array, mu_j: Array) Array[source]#
Mix sliding-friction coefficients with their arithmetic mean.
- jaxdem.forces.cundall_strack.geometric_mean_friction(mu_i: Array, mu_j: Array) Array[source]#
Mix sliding-friction coefficients with their geometric mean.
- class jaxdem.forces.cundall_strack.CundallStrackForce(laws: tuple[~jaxdem.forces.ForceModel, ...] = (), parameterization: ~typing.Literal['elastic', 'coefficients'] = 'elastic', friction_mixing: ~typing.Callable[[~jax.Array, ~jax.Array], ~jax.Array] = <function minimum_friction>, rolling_friction_mixing: ~typing.Callable[[~jax.Array, ~jax.Array], ~jax.Array] = <function minimum_friction>)#
Bases:
ForceModelHistory-dependent linear spring/dashpot friction with rolling resistance.
The tangential spring displacement is accumulated per contact, transported with the changing contact frame, and return-mapped at the Coulomb limit.
parameterization="elastic"derives contact coefficients fromyoung,poisson, ande.parameterization="coefficients"readsk_n,k_t,b_n, andb_tdirectly from the material table and combines particle values with a zero-safe harmonic mean.friction_mixingandrolling_friction_mixingselect the pair sliding- and rolling-friction coefficients.Computes the interaction between two spheres with a linear elastic assumption, viscous damping, and Coulomb friction.
Elastic Parameterization The elastic parameterization computes the effective mass \(m_{eff}\) and restitution coefficient \(e_{eff}\) as:
\[m_{eff} = \left( \frac{1}{m_i} + \frac{1}{m_j} \right)^{-1}, \quad e_{eff} = \min(e_i, e_j)\]The model computes the shear modulus \(G\) per particle from Young’s modulus \(E\) and Poisson’s ratio \(\nu\):
\[G = \frac{E}{2(1 + \nu)}\]The model treats the effective stiffnesses for the normal (\(k_n\)) and tangential (\(k_t\)) directions as springs in series:
\[k_n = \frac{2 E_i R_i E_j R_j}{E_i R_i + E_j R_j}, \quad k_t = \frac{2 G_i R_i G_j R_j}{G_i R_i + G_j R_j}\]The viscous damping coefficient \(\beta\) and the directional damping coefficients are:
\[\beta = \frac{-\ln(e_{eff})}{\sqrt{\pi^2 + \ln^2(e_{eff})}}\]\[\gamma_n = 2 \beta \sqrt{k_n m_{eff}}, \quad \gamma_t = 2 \beta \sqrt{k_t m_{eff}}\]Forces The normal force \(F_n\) includes spring repulsion and viscous damping, limited to repulsive values:
\[F_n = \max(0, k_n \delta_n - \gamma_n v_n)\]The tangential force combines the history spring and viscous dashpot and is capped by the Coulomb sliding friction limit:
\[\mathbf{F}_{t, trial} = -k_t\boldsymbol{\xi}_t-\gamma_t \mathbf{v}_t\]\[\mathbf{F}_t = \min\!\left(1,\frac{\mu F_n}{\|\mathbf{F}_{t,trial}\|}\right) \mathbf{F}_{t,trial}\]Rolling Friction The rolling friction torque resists the relative angular velocity at the contact:
\[\boldsymbol{\tau}_{\text{roll}} = -\mu_r \, R_{\text{eff}} \, F_n \, \hat{\omega}_{\text{rel}}\]The configured
rolling_friction_mixingcallable determines \(\mu_r\); its default is \(\min(\mu_{r,i}, \mu_{r,j})\). The effective radius is \(R_{\text{eff}} = R_i R_j / (R_i + R_j)\), and \(\hat{\omega}_{\text{rel}}\) is the unit relative angular velocity.References
- parameterization: Literal['elastic', 'coefficients']#
- friction_mixing: Callable[[Array, Array], Array]#
- rolling_friction_mixing: Callable[[Array, Array], Array]#
- property supports_analytical_energy_gradient: bool[source]#
Whether force is the negative analytical gradient of
energy.Translational components use body-center positions and rotational components use world angular increments. Force laws are assumed to satisfy this contract by default. Laws that do not must override this property with
False; value-based minimizers then differentiateenergydirectly, with stored pair history held fixed.
- history_shape(dim: int) tuple[int, ...][source]#
Store tangential displacement and the previous contact normal.
- search_radii(state: State, system: System) jax.Array[source]#
Conservative search extent for this law’s finite interaction range.
- static force(i: int, j: int, pos: jax.Array, state: State, system: System, history: jax.Array, *, advance_history: bool = True, quasistatic: bool = False) tuple[jax.Array, jax.Array, jax.Array][source]#
Compute Cundall-Strack normal and tangential forces and torque.
- Parameters:
i (int) – Particle indices.
j (int) – Particle indices.
pos (jax.Array) – Particle positions.
state (State) – Current simulation state.
system (System) – System configuration.
history (jax.Array) – Stored tangential spring and previous contact normal.
advance_history (bool, optional) – Advance the stored spring with this step’s relative motion.
quasistatic (bool, optional) – Evaluate with no time passing: the normal and tangential dashpots and rolling friction are switched off and the Coulomb cap uses the elastic normal force only.
- Returns:
(force, torque, history)with dimension-agnostic shapes. Whenadvance_historyis false the returned history is exactly the input, while force uses its contact-frame-transported spring.- Return type:
tuple[jax.Array, jax.Array, jax.Array]
- static energy(i: int, j: int, pos: jax.Array, state: State, system: System, history: jax.Array) jax.Array[source]#
Return normal plus stored tangential spring energy.
The stored spring is transported to the current contact normal but not advanced or return-mapped. Dissipated work is not part of the energy.
- property required_material_properties: tuple[str, ...][source]#
Names of the material properties this force model needs.
Each name (for example ‘young_eff’ or ‘restitution’) must be present in
System.mat_table. Used for validation.
- jaxdem.forces.cundall_strack.get_cundall_strack_contacts(state: State, system: System) tuple[State, System, CundallStrackContactData][source]#
Collect resolved Cundall-Strack forces for all active directed contacts.
The configured collider supplies pair candidates and stored tangential history. Neighbor-list caches are rebuilt when necessary, but contact history is never advanced. The returned
systemretains any refreshed cache. Results are sorted by source and destination sphere index.This is a host-side operation because it returns variable-length arrays.
- Raises:
TypeError – The system does not use
CundallStrackForcedirectly.ValueError – Pair search results are incomplete or a reported value is nonfinite.