Skip to content

sensitivity() returns 0.0 for a parameter carried by an essential BC — indistinguishable from 'no influence' #766

Description

@lmoresi

What

adjoint_integrand differentiates F0 and F1: the volume residual. A parameter
that reaches the solution through a Dirichlet value has no term there, so the integral is
identically zero and sensitivity() returned 0.0.

That is the single worst wrong answer this API can give, because 0.0 reads as "this
parameter does not influence the solution"
— and that is precisely the conclusion these
numbers get used to draw. On the notch, the convergence velocity V drives the entire
problem through the side-wall Dirichlet condition and reported a sensitivity of exactly
zero.

Louis, 2026-09-20: "I agree that the bc terms should be differentiable."

Why the volume integral cannot see it

A Dirichlet value u|_G = g(m) contributes a reaction term -mu_I^T K_IG dg/dm, and
K_IG is the block eliminated before the adjoint sees the matrix — the global vector holds
only unconstrained dofs. Supporting it needs that block kept, or the boundary term
assembled as its own form.

Interim fix (in hand)

Raise NotImplementedError naming the parameter and the mechanism, rather than return a
number. The guard fires whenever the parameter touches an essential BC, not only when
the volume part happens to be zero: a parameter appearing in both the residual and a
Dirichlet value returns its volume part alone, which is incomplete and harder to notice
than a bare zero because it looks like a plausible number.

A natural condition is different and is supported — a prescribed traction or flux has a
facet part (d bd_F0/dm) . mu on that boundary, which sensitivity now assembles.

Still open

The design question: keep K_IG, or assemble the boundary term as its own form. Until one
of those lands, essential-BC parameters are simply not differentiable and the raise is the
honest report.

Activity

  1. lmoresi commented on Oct 7, 2026

    @lmoresi
    MemberAuthor

    Not reproducible on development (7c9cbbfd) — the adjoint API is not there:

    uw.adjoint present:        False
    Stokes adjoint API:        []
    files with 'adjoint' in the path: 0
    

    Only scattered references remain (one line in petsc_generic_snes_solvers.pyx, five in mcp/__init__.py, eight in transcript_query.py), not the implementation. So this defect lives in unmerged work — feature/discrete-adjoint (#744, currently conflicting and red), feature/adjoint-rotated-bc (#751, based on #744), or scratch/adjoint-merge.

    That is why it has sat untouched: there is nothing on the main line to fix. It is not fixed-in-PR — the opposite. It has to be fixed on the branch before that branch lands, or it lands with the defect.

    Checked in the untouched-issue triage. Blocked behind #744, which needs its conflicts resolved and a CI re-run (its red check is test_1063_constrained_traction, whose timeout #814 addressed when it merged on 2026-10-06).

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions