Open rafael-fuente opened 1 year ago
Ya adjoint gradients with periodic boundaries are a bit hairy because it's hard for the fields to converge. I know you already ran it for a really long time, but here are a few suggestions.
Try swapping your PML out for absorbers. Maybe make them a bit larger (do some convergence checks) and remove the maximum_runtime limit. The fields should decay away reasonably well with the absorbers (no need to "force" the simulation to terminate).
Try playing with the finite difference step size. Make sure you have enough samples, etc.
Typically, we opt for a directional derivative, rather than several different samples to compare to your gradient (I know our example notebook does the linear regression thing but it's more for show...). All of the adjoint tests do this, so you can look at those for an example.
Maybe try in 2D first. Make sure you get decent agreement there. Then project out into that third dimension. When ready.
Also, you can try a single frequency. That may make things easier for now (or at least identify a bug).
@mochen4 any other suggestions?
We tried some optimization in 3D with a similar setup (periodic boundary condition and mpa.FourierFields of mp.Ex), and had decent results, so I believe the adjoint gradients should be correct. As far I can recall, we also explicitly checked the gradients in 3D. So there shouldn't be any issue.
Regarding the parameters in your test script, I would use a larger resolution (30), smaller finite difference size (~1e-7), and longer maximum_run_time (500 or 1000). You can also try absorber or 2D or directional derivative as Alec suggested, but personally I think it should still work without those changes.
Another thing I would try is a different objective function that involves only Ex or Hy fields, maybe even only at one single point. As I said, there really shouldn't be any issue.
@mochen4 @smartalecH I extensively studied this problem by running it on a computer cluster. I've used resolutions as large as 100, runtimes of 1500, PMLs and spacing size = 2.0, and adjoint gradients are still inconsistent with finite-difference gradients. (and also, compared with frequency domain solvers with direct differentiability modeling the same setup)
When trying to do an optimization, optimization algorithms usually get stuck in many steps; no matter how small, the step doesn't lower the loss value.
However, I tried the same setup in 2D, and optimization works fine, and gradients are consistent even for a resolution of 20, so the problem comes exclusively from 3D.
@mochen4 What was the 3D setup you said you got the gradients working?
and gradients are consistent even for a resolution of 20
The gradients shouldn't really be sensitive to resolution anymore. We implemented the adjoint for the actual discrete operator awhile back.
Sorry it's giving you so much trouble. Try some of the other suggestions we gave (eg absorber instead of PML, smaller FD step sizes) and let us know how it goes.
@mochen4 What was the 3D setup you said you got the gradients working?
Try an objective function of npa.abs(Ex[0, a, b])**2, where a, b are the indices of some specific point in the monitor region (e.g. a=2, b=1).
You can also shrink the size of simulation in each direction to lower the time cost.
I'm testing a simple 3D optimization setup, shown in the image below, consisting of a source plane, a design layer, and a monitor plane whose objective function is simply the flux of one polarization. The setup is periodic in the X and Y axes, and the Z axis contains two PMLs placed at the top and bottom boundaries.
Meep version I'm using is 1.27.0 (parallel), but I get similar results with older versions.
For simplicity, I set up the design region resolution exactly equal to the FDTD resolution, which I randomly initialize and then apply a Gaussian filter to smooth it. However, I'm unable to get consistent finite-difference and adjoint gradients no matter what is the simulation resolution or the run time.
I attached the code used below:
Running this script yields gradients like the following plot:
Raising the resolution to 40, and changing the value of the gaussian filter to apply to the initial design from 1.0 to 2.0, still produces inconsistent gradients: