From ef96b413e73891b6f1c0f959cbcb3845db1a2c2e Mon Sep 17 00:00:00 2001 From: remibessard Date: Mon, 8 Sep 2025 08:20:14 +0200 Subject: [PATCH 1/4] UPDATE SpringForceField so that it handles configuration singularity in simulation by adding regularisation term (so that matrix can be inverted) --- .../component/solidmechanics/spring/SpringForceField.inl | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/SpringForceField.inl b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/SpringForceField.inl index 6c926549d4e..bd8f85938be 100644 --- a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/SpringForceField.inl +++ b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/SpringForceField.inl @@ -542,11 +542,18 @@ auto SpringForceField::computeSpringForce( // dF = k_s.U.U^T.dX + f/l.(I-U.U^T).dX = ((k_s-f/l).U.U^T + f/l.I).dX auto& m = springForce->dForce_dX; Real tgt = forceIntensity * inverseLength; + Real tol = 1e-8; + Real regParam = 1e-4; + bool isSingular = std::abs(elongation) < tol && std::abs(elongationVelocity) < tol; + if (isSingular) + msg_warning(this) << "!!! We detected a degenerated Spring configuration, we've to add a " + "regularization term to make the matrix invertible !!!"; for(sofa::Index j=0; j Date: Fri, 23 Jan 2026 09:25:42 +0100 Subject: [PATCH 2/4] simplify ternary and use (,) --- .../component/solidmechanics/spring/SpringForceField.inl | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/SpringForceField.inl b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/SpringForceField.inl index bd8f85938be..dadd52d661a 100644 --- a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/SpringForceField.inl +++ b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/SpringForceField.inl @@ -552,8 +552,13 @@ auto SpringForceField::computeSpringForce( { for(sofa::Index k=0; k Date: Fri, 23 Jan 2026 11:09:00 +0100 Subject: [PATCH 3/4] Apply suggestions from code review --- .../sofa/component/solidmechanics/spring/SpringForceField.inl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/SpringForceField.inl b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/SpringForceField.inl index dadd52d661a..415062d9721 100644 --- a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/SpringForceField.inl +++ b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/SpringForceField.inl @@ -546,8 +546,7 @@ auto SpringForceField::computeSpringForce( Real regParam = 1e-4; bool isSingular = std::abs(elongation) < tol && std::abs(elongationVelocity) < tol; if (isSingular) - msg_warning(this) << "!!! We detected a degenerated Spring configuration, we've to add a " - "regularization term to make the matrix invertible !!!"; + msg_warning(this) << "Degenerated spring configuration detected: a regularization term added making the matrix invertible"; for(sofa::Index j=0; j Date: Tue, 27 Jan 2026 15:40:50 +0100 Subject: [PATCH 4/4] Apply suggestions from code review Co-authored-by: Alex Bilger --- .../sofa/component/solidmechanics/spring/SpringForceField.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/SpringForceField.inl b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/SpringForceField.inl index 415062d9721..f2d9619bd04 100644 --- a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/SpringForceField.inl +++ b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/SpringForceField.inl @@ -554,7 +554,7 @@ auto SpringForceField::computeSpringForce( m(j,k) = ((Real)spring.ks-tgt) * u[j] * u[k]; if(isSingular) { - const double diagonalTerm = (j == k) ? 1.0 : 0.0; + const Real diagonalTerm = (j == k) ? 1.0 : 0.0; m(j,k) += regParam * spring.ks * (diagonalTerm - u[j] * u[k]); }