Skip to content

[6/n][Adjoint Module] Register a material grid's susceptibilities with the structure - #3286

Draft
smartalecH wants to merge 1 commit into
masterfrom
fix/material-grid-susceptibilities
Draft

[6/n][Adjoint Module] Register a material grid's susceptibilities with the structure#3286
smartalecH wants to merge 1 commit into
masterfrom
fix/material-grid-susceptibilities

Conversation

@smartalecH

Copy link
Copy Markdown
Collaborator

No description provided.

`add_susceptibilities` collects poles only from materials that satisfy
`is_medium`, which is true only for `which_subclass == MEDIUM`.  A
`MaterialGrid` is `MATERIAL_GRID`, so its constituents' poles were never
registered: nothing called `sigma_row` for them and the amplitudes that
`epsilon_material_grid` interpolates went nowhere.  A dispersive material
grid was silently non-dispersive in the forward simulation.

The adjoint side reads `medium.E_susceptibilities` directly through
`get_material_pt`, so `get_chi1_tensor_disp` did see the poles.  The result
was a confident gradient for a structure that was never simulated -- a
finite difference of the objective with respect to a design variable came
back exactly zero while the adjoint reported a large value.

Three changes:

* Collect poles from `medium_1` and `medium_2` for a material grid, via a
  small `add_material_pols` helper used at all three enumeration sites.
  Electric only, since the grid does not interpolate a magnetic response.

* Accumulate in `sigma_row` instead of stopping at the first match.  The
  grid's list is the concatenation of its constituents' poles, so when both
  media carry the same pole -- same frequency and damping, different
  strength -- two entries match the one registered susceptibility and the
  mixture's amplitude is their sum.  Taking the first match dropped
  `medium2`'s contribution.  Identical poles superpose, so this is also the
  right answer for a plain medium that lists a pole twice.

* Refuse constituent properties a material grid cannot interpolate.  It
  mixes epsilon, the electric susceptibilities and the diagonal
  `D_conductivity`; `mu`, `H_susceptibilities`, the nonlinearities and
  `B_conductivity` are never written to the mixed medium and were accepted
  and then ignored, which is the same failure mode.

Also check the invariant `epsilon_material_grid` relies on -- that the mixed
medium's pole list is the concatenation of the two constituents', assembled
in `python/typemap_utils.cpp` -- rather than indexing past the end of a list
built through some other path.

The new tests are endpoint and superposition identities that hold exactly,
so each compares against a value known independently of the grid machinery:
a grid at u=1 is indistinguishable from a block of its second constituent,
at u=0 from its first, and a pole shared by both constituents has the summed
amplitude.
@smartalecH smartalecH changed the title Register a material grid's susceptibilities with the structure [6/n] Register a material grid's susceptibilities with the structure Aug 31, 2026
@smartalecH smartalecH changed the title [6/n] Register a material grid's susceptibilities with the structure [6/n][Adjoint Module] Register a material grid's susceptibilities with the structure Aug 31, 2026
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