Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Poynting flux Adjoint #2191

Draft
wants to merge 10 commits into
base: master
Choose a base branch
from
Draft

Conversation

Alex-Kaylor
Copy link
Contributor

@Alex-Kaylor Alex-Kaylor commented Aug 9, 2022

Closes #1307, #1299, #1398

Initial Implementation of Poynting Flux Adjoint. Uses add_DFT_fields objects. Forward run is accurate. Throws an error in step_db.cpp on adjoint run: "Assertion 'changed_materials' failed." Using this pull request to help debug code changes.

…unction.

The Poynting Flux adjoint still fails when given field components of zero.
The test file test_poynting_flux.py does the same simulation for adjoint and
non-adjoint calls now. I'll need to add it into the actual test cases next,
however.
…or in step_db.cpp - Assertion 'changed_materials' failed. Creating a pull request will let me difftool code changes to debug the problem.
… Off by a factor of ten in initial tests, debugging today.
…ine sources (one for each tangential H or E component) to a series of point sources to accomodate end-to-end interpolation - we needed middle to middle. Unfortunately, this did not seem to improve the error appreciably.
@codecov-commenter
Copy link

codecov-commenter commented Aug 16, 2022

Codecov Report

Merging #2191 (1ac0ae1) into master (2aa9164) will decrease coverage by 2.03%.
The diff coverage is 19.44%.

@@            Coverage Diff             @@
##           master    #2191      +/-   ##
==========================================
- Coverage   73.09%   71.05%   -2.04%     
==========================================
  Files          17       17              
  Lines        4906     4975      +69     
==========================================
- Hits         3586     3535      -51     
- Misses       1320     1440     +120     
Impacted Files Coverage Δ
python/adjoint/objective.py 50.92% <15.94%> (-42.08%) ⬇️
python/adjoint/optimization_problem.py 54.40% <100.00%> (-2.44%) ⬇️
python/adjoint/connectivity.py 8.64% <0.00%> (-1.84%) ⬇️
python/adjoint/filter_source.py 87.17% <0.00%> (-1.29%) ⬇️
python/visualization.py 41.49% <0.00%> (-1.16%) ⬇️
python/adjoint/filters.py 60.14% <0.00%> (-0.73%) ⬇️
python/simulation.py 76.84% <0.00%> (-0.02%) ⬇️
python/adjoint/wrapper.py 98.46% <0.00%> (ø)
... and 1 more

@stevengj
Copy link
Collaborator

Ideally this would be done in C++ directly from the dft_flux object — the problem with forming the Poynting flux from DFT fields in Python is that it requires all the DFT fields to be loaded into a single process, which may be prohibitive for computing the flux through large areas.

In particular, it should be very similar to dft_fields::fourier_sourcedata (

meep/src/dft.cpp

Line 1462 in ea43f83

std::vector<struct sourcedata> dft_fields::fourier_sourcedata(const volume &where, component c,
), except that the amplitude dJ comes not from the user but rather from the Fourier field you are multiplying with (e.g. the Ex adjoint source's "dJ` comes from Hy etcetera).

Note that the dft_flux object already has lists of field pairs that are multiplied together (

F[i] += real(curE->dft[k * Nfreq + i] * conj(curH->dft[k * Nfreq + i]));
), so for each pair you will add two adjoint sources.

… dJ. Works well in 2D, fails in 3D. Multiple frequencies untested.
…ro (due to symmetry, etc.). Tested with eigenmode and point sources radiating toward line monitors.

3D returns the wrong gradient entirely - I should be able to fix it since it should just be the format of the input.
There are a couple cases in 2D simulations where the gradient is somewhat wrong.
@Alex-Kaylor
Copy link
Contributor Author

Works ok in 2D (see below), fails in 3D (still sticking with a purely Python implementation using FourierFields). I can resolve 3D on my own - I expect the derivative's format isn't what FourierFields expects when we place the adjoint source.

The accuracy doesn't improve monotonically in 2D. The gradient's inaccurate in a few cases. Note sure why, I'll explore it some more once it works in 3D. The same resolutions cause similar errors with different sources.

Plots from 2D:

Eigenmode source resolution is 10

point_source_res_is_10

Eigenmode source resolution is 22

point_source_res_is_22

Eigenmode source resolution is 26
point_source_res_is_26

Eigenmode source resolution is 30

point_source_res_is_30

Eigenmode source resolution is 42

point_source_res_is_42

point source resolution is 22
point_source_res_is_22

point source resolution is 26
point_source_res_is_26

…'s place_adjoint_source function. This works in 2D, but it returns 9 separate sources in 3D. The extra sources are handled and collated correctly now.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Adjoint optimization through Poynting Flux
4 participants