Repository navigation
[7/13][Adjoint Module] Launch a mode through a stratified stack into the simulation (and backprop) - #3284
Open
smartalecH wants to merge 4 commits into
Open
[7/13][Adjoint Module] Launch a mode through a stratified stack into the simulation (and backprop)#3284smartalecH wants to merge 4 commits into
smartalecH wants to merge 4 commits into
Conversation
smartalecH
force-pushed
the
feat/adjoint-asm-source
branch
from
September 2, 2026 22:16
4ab1a53 to
b885b28
Compare
This was referenced Sep 2, 2026
Closed
Open
Open
Open
smartalecH
force-pushed
the
feat/adjoint-asm-source
branch
from
October 7, 2026 23:24
b885b28 to
717e81b
Compare
smartalecH
force-pushed
the
feat/adjoint-asm-source
branch
2 times, most recently
from
October 9, 2026 20:55
8076dfb to
96a9ba9
Compare
smartalecH
force-pushed
the
feat/adjoint-asm-source
branch
from
October 12, 2026 18:52
96a9ba9 to
82c1044
Compare
smartalecH
marked this pull request as ready for review
October 12, 2026 21:58
incident_fields is the time reverse of spectrum: a Mode is specified where it is physically meaningful -- at the fiber facet, on the far side of the stack -- and carried back down to the monitor plane, where Meep can inject it. The scalar transfer function of a stratified medium is the same in both directions, so the same product of transmission and propagation phases applies. The result is purely in-going by construction, since it inverts decompose for a spectrum with no outgoing part. equivalent_sources then hands those fields to mp.get_equiv_sources, which already applies the equivalence principle and emits sources carrying amp_data. Because amp_data is differentiable, a beam injected this way backpropagates to its own waist, tilt and offset. from_volume builds a propagator without a monitor, which the injection path needs: a DFT monitor requires the field components to be allocated, and that does not happen until sources are added -- which is what is being built. Verified end to end: the injected field is 99.997% in-going, the radiated beam leaks 4e-3 in amplitude the wrong way (1.6e-5 in power), and the beam measured downstream is still 99.99% travelling the direction it was sent.
incident_fields assumed the 2D s axis is the first tangential one, which only holds for y-normal lines, and equivalent_sources laid the (u, v) arrays out as amp_data's (x, y, z) without reordering them or putting the singleton along the normal, which only holds for 2D y-normal lines and 3D z-normal planes. Add tests for an x-normal line and for the 3D layout. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- incident_fields reused the monitor-to-far transmission, but the stack is crossed from the far side; by reciprocity that is t * Y_far / Y_monitor. Across an interface the injected power was wrong (2.1x for glass/air). - incident_fields used the mode's spectrum unchanged, which launches a tilted mode at the mirrored angle; inject its time reverse, conj(a(-kt)), so the same Mode describes the same fiber in both directions. - from_volume read the grid from an uninitialized simulation, which crashed; initialize it to read the grid and reset it afterwards. - The example rebuilt the equivalent currents with a component swap that picked the wrong (zero) components, so its optimization launched nothing and never stopped. Add equivalent_currents, the JAX version of what equivalent_sources places, and use it in both. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A small 2D grating coupler driven by a fiber mode carried through a superstrate stack outside the cell. It checks the launched field against the propagator with no fitted scale, transmit-vs-receive reciprocity across fiber tilts (with its convergence in resolution), and the gradient with respect to the fiber's waist, tilt and offset against finite differences of the full simulation, and draws a figure of all three. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
smartalecH
force-pushed
the
feat/adjoint-asm-source
branch
from
October 14, 2026 01:16
c8b30fc to
5e04191
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Launches a mode into a simulation through a stratified stack, completing the angular-spectrum work in #3281 (which carries fields out through a stack). The typical use is a fiber far above a chip: the mode is specified where it physically lives, at the fiber facet outside the FDTD cell, carried analytically through the superstrate, and injected just above the device. The whole path is differentiable, so the fiber's waist, tilt and offset can be optimized together with the device.
API.
incident_fields(mode, distance)gives the tangential fields at the injection plane for a mode arriving from the far side of the stack.Modedescribes the same fiber in both directions: whatoverlapcollects withgaussian_mode(tilt=θ)is whatincident_fieldslaunches with it. Its spectrum isconj(a(-kt)).t · Y_far / Y_monitor.equivalent_sources(fields, ...)turns those fields into an electric sheetK = n̂×Hand a magnetic sheetN = −n̂×E, which radiate one way, as ordinaryamp_datasources.equivalent_currents(fields)returns the same arrays in JAX. A loss can feed them toMeepJaxWrapperand differentiate end to end with respect to the mode's parameters; Meep returns the cotangent with respect toamp_datathrough [6/13][Adjoint Module] Adjoint gradients with respect to sources #3283's source adjoint.from_volumebuilds a propagator for a plane that has no monitor yet, since the sources are exactly what it is building.End-to-end check (
examples/adjoint_optimization/grating_coupler_asm_end_to_end.py): a small 2D grating coupler with the fiber 10 µm up in air, above 2 µm of silica, all outside the cell.The example runs in about 20 minutes on one core, or about 2 minutes with
--quick.Tests.
equivalent_currentsequals the placedamp_dataand is differentiable with respect to the mode.amp_datalayout for every normal in 3D.Also includes the example
grating_coupler_asm_source.py, which drives the coupler from the fiber and co-optimizes the grating and the fiber alignment.