Skip to content

[14/14][Adjoint Module] 3D grating coupler example: fiber, grating and mirror co-optimization - #3295

Draft
smartalecH wants to merge 5 commits into
test/adjoint-mode-monitor-symmetryfrom
example/grating-coupler-3d
Draft

[14/14][Adjoint Module] 3D grating coupler example: fiber, grating and mirror co-optimization#3295
smartalecH wants to merge 5 commits into
test/adjoint-mode-monitor-symmetryfrom
example/grating-coupler-3d

Conversation

@smartalecH

@smartalecH smartalecH commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Top of the stack, and the thing the rest of it was built for.

A fiber mode at 1550 nm passing through an ARC and cladding onto a single-etch silicon grating, with an aluminum reflector underneath whose position is optimised alongside the beam angle and location. Topology optimization runs the usual epoch schedule -- two to three epochs at low beta with no constraints, then beta = infinity with the ANT foundry length scales enforced via SSP's smoothed projection and length constraints. The objective is on a log scale, which amplifies the gradient early while coupling is still poor (more notes on this found in our paper).

Each run writes its own directory: the normalized design, the gradient with a color bar, a running objective plot, and a cross section showing where the metal sits annotated with the current coupling efficiency.

While working on this large-scale example, we encountered various bugs and feature gaps. Those are all implemented as part of the stack.

@smartalecH smartalecH changed the title [10/n][Adjoint Module] 3D grating coupler example: fiber, grating and mirror [13/13][Adjoint Module] 3D grating coupler example: fiber, grating and mirror Sep 2, 2026
@smartalecH
smartalecH force-pushed the example/grating-coupler-3d branch from 3010b2e to fbe9308 Compare September 4, 2026 04:42
@smartalecH smartalecH changed the title [13/13][Adjoint Module] 3D grating coupler example: fiber, grating and mirror [14/14][Adjoint Module] 3D grating coupler example: fiber, grating and mirror Sep 4, 2026
@smartalecH
smartalecH changed the base branch from feat/adjoint-pade-dft to test/adjoint-mode-monitor-symmetry September 4, 2026 04:43
@smartalecH
smartalecH force-pushed the example/grating-coupler-3d branch from fbe9308 to 7ff2b8d Compare September 4, 2026 17:32
Clamping an infinite-extent geometry monitor to the cell, and refusing
MaterialGrid constituent properties the grid cannot interpolate rather than
silently dropping them.
A fibre mode at 1550 nm through an ARC and cladding onto a single-etch silicon
grating, with an aluminium reflector underneath whose position is optimised
alongside the beam angle and location.  Topology optimisation runs the usual
epoch schedule -- low beta unconstrained, then beta = infinity with the ANT
foundry length scales enforced -- and the objective is on a log scale, which
amplifies the gradient early when coupling is still poor.

Each run writes its own directory: normalised design, gradient with a colour
bar, a running objective plot, and a cross section showing where the metal sits
with the current coupling efficiency.
Four defects, all in the example, found by finite-differencing the objective
against the adjoint gradient.

Mirror eigenvalue.  A mirror in y maps y -> -y and flips the sign of
y-components, so a mode whose Ey is even in y has eigenvalue -1.  The guided
mode here is quasi-TE with Ey even, and the symmetry was declared with +1, which
projects onto the orthogonal sector and symmetry-forbids the mode the objective
measures.  Measured at resolution 8 on an identical structure, +1 gave a mode
coefficient 1.51x the unsymmetrised answer and a design gradient 16.8x too large
against a converged finite difference; -1 reproduces it to 5e-6 and the gradient
is right to 1.3%.

That inflated gradient is what broke the optimization rather than merely
skewing it.  MMA sizes its first step from the gradient, so a 17x overestimate
put every density onto a bound immediately, SSP's projection derivative vanished
once the filtered field saturated, and the design never moved again -- every run
so far was optimizing three scalars and a frozen grating.

Metal through the PML.  The reflector was built with size.y = inf, so a Drude
metal ran through the y PML.  PML is unstable against negative permittivity, and
a long cavity ring-down ended in NaN tens of thousands of steps in.  It now
stops MARGIN clear of the boundary in y as it already did in x.

Objective and gradient disagreed.  nlopt was handed the linear efficiency as the
value while the gradient was of log|a|^2.  It does not change MMA's step, which
depends on the gradient and its asymptotes rather than the value, but the two
should describe the same function.

Density band.  Even with a correct gradient MMA saturates the densities on its
first step, so the box is clipped to a band around the design each stage starts
from, widening as the stage index grows.
Banding keeps the densities off their bounds, which is what the projection
derivative needs, but it also stalls the three scalars: measured at resolution
8, 2.7e-4 against 5.1e-3 for the plain box over the same budget.  Both the
re-centred and the fixed-band variants behaved the same way.  Left in behind a
flag because the saturation it addresses is real.
nlopt hands the callback a numpy view of its own parameter buffer, which it
reuses and frees between callbacks.  `unpack` sliced that view and `History.add`
stored it with `np.asarray`, which returns the same object for an ndarray
rather than copying, so every recorded row was a dangling view into memory
nlopt had since reused.

Two consequences.  The rows stopped describing the iterations they were
labelled with -- which is why the saved designs looked frozen and identical
across iterations even while the run was making progress -- and `save()`
eventually memcpy'd from freed memory.  That surfaced as a SIGSEGV inside
numpy's array assignment, five to nine iterations after the damage, killing
a run that had already spent two hours.

Copy at the boundary: two megabytes against a four hundred second solve.
@smartalecH
smartalecH force-pushed the example/grating-coupler-3d branch from 7ff2b8d to 1ce6986 Compare September 4, 2026 17:42
@smartalecH smartalecH changed the title [14/14][Adjoint Module] 3D grating coupler example: fiber, grating and mirror [14/14][Adjoint Module] 3D grating coupler example: fiber, grating and mirror co-optimization Sep 4, 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