pub struct Friction {
pub normal_dof: usize,
pub shear_dof: usize,
pub mu: f64,
pub k0: f64,
pub b: f64,
/* private fields */
}Expand description
Couples one “shear” DOF to a different DOF’s own material — the
normal direction’s current force — via a bilinear-kinematic-hardening
Coulomb return map: sticks (stiffness k0) until |V| reaches
mu * yield-eligible normal force, then slides with post-slip tangent
b*k0 (see the b field doc comment for why b is required, not
optional).
This is deliberately not a Material variant: Material::evaluate is
a pure function of one scalar strain (every call site — Truss,
ZeroLength, Fiber, the Parallel/Series/MinMax composites —
depends on that signature), and friction’s yield force needs a second
DOF’s current force, which a single Material has no way to see. So the
coupling lives here, in the element, not the material catalog.
Sign convention: this codebase is compression-negative (see
Material::Ent/Gap — strain <= 0.0 is the compression/engaged
branch). Friction is mobilized only when the normal direction is in
compression: yield force is mu * (-normal_force).max(0.0).
The return map: trial = k0*(shear_relative - slip) is the elastic
predictor (same shape as ElasticPP’s trial_stress = e*(strain - ep),
elastic_like.rs). Inside the yield surface, force = trial. Past it,
this is standard 1D linear-kinematic-hardening plasticity with
(fixed, for one call) yield force yield_force and hardening modulus
chosen so the post-yield tangent is exactly b*k0:
force = b*trial + (1-b)*yield_force*sign(trial), which by construction
satisfies k0*(shear_relative - next_slip) == force — so, exactly like
ElasticPP’s next_ep = strain - stress/e, next_slip = shear_relative - force/k0.
Fields§
§normal_dof: usize§shear_dof: usize§mu: f64§k0: f64§b: f64Post-slip hardening ratio (fraction of k0) — required at
construction, not defaulted, so callers make an active choice. A
small nonzero value (recommended starting range 1e-3-1e-4) keeps
the post-slip tangent away from exactly zero: while sliding, this
DOF is commonly the only stiffness path on its shear direction, so
an exactly-zero tangent risks a structurally singular row/column in
the global system (AnalysisError::SingularSystem) — the same
reasoning behind Material::MinMax’s nonzero failed-state tangent
floor, except here b is part of the actual force law (rounding the
stick/slip corner, reducing Newton bouncing at the transition), not
a tangent-only fudge. Set to 0.0 for an exact textbook Coulomb
comparison and accept the singularity risk that comes back with it.
Implementations§
Trait Implementations§
Auto Trait Implementations§
impl Freeze for Friction
impl RefUnwindSafe for Friction
impl Send for Friction
impl Sync for Friction
impl Unpin for Friction
impl UnsafeUnpin for Friction
impl UnwindSafe for Friction
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T, U> Imply<T> for U
§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read more§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.