Skip to content

[LinearSolver.Direct] BTDLinearSolver::partial_solve: fix members initialization/bad values - #6227

Open
fredroy wants to merge 2 commits into
sofa-framework:masterfrom
fredroy:fix_unbuilt_gcsolver_mult_constraints
Open

[LinearSolver.Direct] BTDLinearSolver::partial_solve: fix members initialization/bad values#6227
fredroy wants to merge 2 commits into
sofa-framework:masterfrom
fredroy:fix_unbuilt_gcsolver_mult_constraints

Conversation

@fredroy

@fredroy fredroy commented Aug 13, 2026

Copy link
Copy Markdown
Contributor
  1. 2 private members were unitialized and potentially read (UB)
  2. those two variables could have a starting value initialized from a previous step so could be bad in certain case.

I got some unexplained crash with scenes with unbuilt CS + lagrangian contact + some misc lagrangian constraints.

I fixed these by myself, but I never really knew the reason on why the crashes were only with my scenes 🥴 so I ask Claude to explain

Explanation by Claude

Why your constraints hit it and the stock scenes mostly don't
The reads are only reachable if the first partial_solve() of the simulation takes neither step 2 nor step 3, because those two are what set both members to a sane value (bwdAccumulateLHGlobal() sets both to 0 at inl:517-520, fwdAccumulateRHGlobal() sets _indMaxFwdLHComputed = current_bloc).

In the unbuilt GS loop (UnbuiltGaussSeidelConstraintSolver.cpp:141-207), the first thing a correction sees is addConstraintDisplacement → partial_solve(Vec_I_list_dof[last_disp], …, NewIn=false). current_bloc is nb-1 at that point, so step 2 fires as long as MinIdBloc_OUT < nb-1 — i.e. as long as the first-processed constraint touches something other than the last node. Everything is initialized before it's read, and you never notice the bug.

You skip both steps when the first constraint block processed has Vec_I_list_dof[j].front() == nb-1, i.e. it acts only on the last block/node of the BTD system. That depends entirely on:

which DOFs your custom constraint writes into the Jacobian (LinearSolverConstraintCorrection.inl:745-768 builds Vec_I_list_dof from the Jacobian columns),
the order of constraints_sequence, and the wire_optimization renumbering at inl:504-532,
how many constraints there are and which corrections appear in cclist_elems[j].

[with-all-tests]


By submitting this pull request, I acknowledge that
I have read, understand, and agree SOFA Developer Certificate of Origin (DCO).


Reviewers will merge this pull-request only if

  • it builds with SUCCESS for all platforms on the CI.
  • it does not generate new warnings.
  • it does not generate new unit test failures.
  • it does not generate new scene test failures.
  • it does not break API compatibility.
  • it is more than 1 week old (or has fast-merge label).

@fredroy fredroy added pr: fix Fix a bug pr: status to review To notify reviewers to review this pull-request labels Aug 13, 2026
@fredroy

fredroy commented Aug 13, 2026

Copy link
Copy Markdown
Contributor Author

[ci-build][with-all-tests]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr: fix Fix a bug pr: status to review To notify reviewers to review this pull-request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant