You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Adjoint sensitivity silently omits a parameter that enters through a Dirichlet datum #762
solver.sensitivity(mu, m) (and so solver.gradient(...)) integrates mu . dR/dm over the volume and adds the facet part for a parameter in a natural condition. A parameter that appears only in an essential datum, u|Γ = g(m), contributes nothing, and nothing says so: the gradient comes back zero for a lid velocity or a wall value used as a control.
The missing term is the reaction one. With our convention Kᵀμ = -∂J/∂u,
dJ/dm |_BC = μ_Iᵀ K_IΓ ∂g/∂m = (Kᵀμ)_Γ · ∂g/∂m
since μ_Γ = 0. K_IΓ is not available: PETSc's global vector holds only the unconstrained dofs, and its local residual assembly skips the constrained rows too (ADD_VALUES drops them), so neither the assembled matrix nor a residual evaluation carries them.
Design: assemble Kᵀμ on every node, constrained ones included, as the FEM load ∫ φ f0_adj(μ) + ∇φ · f1_adj(μ) of the adjoint templates on an unconstrained copy of the unknown's space (the load assembler uw.adjoint.dual_on already does this for misfit duals), then dot the constrained rows with ∂g/∂m evaluated at the boundary nodes, honouring the order in which PETSc inserts boundary values where boundaries meet. For Stokes the pressure adjoint enters through the transposed divergence block. Until that lands, a parameter found in an essential datum should be refused loudly rather than dropped.
Found while validating the adjoint against a run with a prescribed wall velocity as the control (branch feature/discrete-adjoint, PR #744).
Landed in 6fb6055 on feature/discrete-adjoint. The sensitivity now carries [(Kᵀμ)_Γ + (∂J/∂u)_Γ] · ∂g/∂m: Kᵀμ is assembled on every node as the load of the adjoint templates on an unconstrained copy of the unknown's space, the constrained rows are dotted with the datum's derivative at the boundary nodes, and the misfit's own dual supplies the rows the adjoint solve leaves out. Where boundaries meet, the last one registered owns the corner, as PETSc inserts it. Poisson wall value and Stokes lid velocity against central differences to 1e-4 (test_0026). A solver with a boundary tangent the reaction cannot see refuses.
Activity
adjoint: a parameter in a Dirichlet datum gets its reaction term
lmoresi commentedon Sep 20, 2026
Landed in 6fb6055 on
feature/discrete-adjoint. The sensitivity now carries[(Kᵀμ)_Γ + (∂J/∂u)_Γ] · ∂g/∂m:Kᵀμis assembled on every node as the load of the adjoint templates on an unconstrained copy of the unknown's space, the constrained rows are dotted with the datum's derivative at the boundary nodes, and the misfit's own dual supplies the rows the adjoint solve leaves out. Where boundaries meet, the last one registered owns the corner, as PETSc inserts it. Poisson wall value and Stokes lid velocity against central differences to 1e-4 (test_0026). A solver with a boundary tangent the reaction cannot see refuses.adjoint: the datum term through the transcript driver, and a refusal …