Skip to content

fix(solvers): correct reverse rules of the projected damage solve - #14

Merged
allamaprabhuani merged 3 commits into
mainfrom
fix/damage-adjoint-reverse-rules
Oct 12, 2026
Merged

allamaprabhuani merged 3 commits into
mainfrom
fix/damage-adjoint-reverse-rules

Conversation

@allamaprabhuani

@allamaprabhuani allamaprabhuani commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

Summary

The damage update solves A(H) d_unc = b(H) and enforces the bounds d_prev <= d <= 1. Three defects affected reverse-mode gradients through this step:

  1. History pullback. On solve-then-clamp routes (bounds_method='post_clamp' or 'direct'), dA/dH was evaluated at the projected damage instead of the unconstrained solution d_unc (_AdjointDamageSolve, _AdjointDamageSolveScalar, _AdjointDamageSolveField).
  2. Missing d_prev gradient. The history-only route returned None for d_prev, so nodes held at their previous damage (irreversibility branch) did not pass gradients to earlier steps.
  3. Detached solve. With fixed material values (Gc/l0 passed without requires_grad), the solve was dispatched to the forward-only path even when H or d_prev required gradients.

Forward solutions are unchanged. The direct Gc/l0 pullback term was already evaluated at d_unc and is unchanged, but total multi-step gradients with respect to Gc, l0 or other parameters change wherever the history or d_prev paths contribute.

Projected CG (bounds_method='projected_cg'). This route solves a bound-constrained problem whose exact sensitivity needs a reduced active-set system, which is not implemented. On an AT1 projected-CG case the unconstrained pullback moved the gradient further from central differences (relative error 0.66 against 0.56), so this route keeps the projected damage in the history pullback; corrections 2 and 3 apply to all routes. Gradients through projected-CG solves remain approximate.

Tests

New tests/test_damage_adjoint_regressions.py:

  • history gradient against a dense solve-and-project reference (autograd) and central differences, with the projection active;
  • d_prev gradient on the irreversibility branch;
  • history gradient with fixed material values on a small mesh, against central differences.

All five test cases fail on the current main and pass with this change. Full suite locally: 472 passed.

The damage update solves A(H) d_unc = b(H) and projects the result,
d = clamp(max(d_unc, d_prev), 0, 1). Three defects affected gradients
through this step:

- the history pullback evaluated dA/dH at the projected damage instead
  of the unconstrained solution d_unc;
- the history-only route returned no gradient for d_prev, so nodes held
  at their previous damage did not propagate gradients to earlier steps;
- with fixed material values the solve was dispatched to the
  forward-only path, detaching the damage from H and d_prev.

The forward solution is unchanged. Gradients with respect to Gc and l0
were already evaluated at d_unc and are unaffected.

Adds three regression tests: the history gradient against a dense
solve-and-project reference and central differences with the projection
active, the d_prev gradient on the irreversibility branch, and the
history gradient with fixed material values on a small mesh. All three
fail on the previous implementation.
… damage

The unconstrained-damage history pullback is derived for solve-then-clamp
routes ('post_clamp', 'direct'). The projected-CG route solves a
bound-constrained problem whose exact sensitivity needs a reduced
active-set system, which is not implemented. On an AT1 projected-CG test
case the unconstrained pullback moved the gradient further from central
differences (relative error 0.66 against 0.56 with the projected damage),
so that route keeps the projected damage. The d_prev gradient and the
dispatch correction apply to all routes.
The fixed-material dispatch test meshed a SENT plate with gmsh, which
fails to load on the Ubuntu CI runners (missing libGLU). It now uses a
structured unit-square T3 mesh from FEMMesh.from_tensors; the test still
fails on the previous code at the intended assertion.
@allamaprabhuani
allamaprabhuani merged commit 3a7320f into main Oct 12, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant