Add the geometric term to the flex stretch stiffness
K_stretch was the Gauss-Newton Hessian of the stretch force, not its Jacobian. With elongation e_a = L_a^2 - L0_a^2 and force f = -sum_ab M_ab e_a grad(e_b)/2, K = 2 sum_ab M_ab (s_a d_a)(s_b d_b)^T + sum_a Me_a (Laplacian_a (x) I3) and only the first term was there. The second is proportional to the edge tension Me_a = sum_b M_ab e_b, so it vanishes at rest and grows with strain: the operator was first-order correct and no more. Finite-differencing it against -d(qfrc_passive)/dq on a mesh dilated by 5% gives 7.8% of the force scale; with the term it is exact to roundoff. Add only the tensile part. The geometric block is Me_a*[[I,-I],[-I,I]] over the edge's two vertices, which is positive semi-definite exactly when Me_a >= 0; a compressed edge would make K indefinite, and both consumers -- the CG constraint solver and the PCG in mjd_effSolve -- require SPD. The clamp is structural, so no eigendecomposition is needed, and it is confined to the operator: mj_flexPassiveStretch keeps the full Me_a, so no force changes. Both the matrix-free operator and the CSR assembly the effective metric builds from are updated, since they must agree. This changes how flexes with elastic2d="stretch" integrate under the implicit integrators and the effective metric -- bag.xml moves, poncho.xml is bit-identical because bending energy is quadratic and has no geometric term. The interpolated-flex path still uses its Gauss-Newton approximation, which FlexInterpDerivativesDeformed asserts.
This commit is contained in:
@@ -63,6 +63,11 @@ Bug fixes
|
||||
large penetration depth between nearly touching thin boxes with positive margin, causing resting stacks to explode.
|
||||
- Fixed a bug in the box-box collider where penetrations deeper than a box's smallest half-size could produce no
|
||||
contacts, letting boxes tunnel through thin boxes. Fixes :issue:`1800`.
|
||||
- Fixed the flex stretch stiffness operator, which was the Gauss-Newton Hessian of the stretch force rather than its
|
||||
Jacobian: the geometric (stress-proportional) term was missing. Only the tensile part of that term is added, since
|
||||
it is positive semi-definite exactly when the edge is in tension, and its consumers require an SPD operator; the
|
||||
stretch force itself is unchanged. This affects the implicit integrators and the implicit effective metric, so
|
||||
flexes using ``elastic2d="stretch"`` integrate slightly differently. Bending-only flexes are unaffected.
|
||||
|
||||
Version 3.11.0 (July 27, 2026)
|
||||
------------------------------
|
||||
|
||||
Reference in New Issue
Block a user