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

Waveguide crossing inverse design example #2800

Merged
merged 13 commits into from
Apr 11, 2024
Merged

Waveguide crossing inverse design example #2800

merged 13 commits into from
Apr 11, 2024

Conversation

smartalecH
Copy link
Collaborator

@smartalecH smartalecH commented Mar 7, 2024

Here we add a python inverse-design example that maximizes the transmission of a waveguide crossing. In particular, it's meant to showcase the new (first-order accurate) smoothed projection functionality. Using this example, you can:

Perform shape optimization:

image

Perform topology optimization:

image

Analyze the norm of the gradient as $\beta \to \infty$ for both the smoothed case and non-smoothed case:

image

Analyze the convergence properties of a shape optimization problem at a finite beta ($\beta=64$ here) for both the smoothed case and non-smoothed case:

image

@codecov-commenter
Copy link

codecov-commenter commented Mar 7, 2024

Codecov Report

Attention: Patch coverage is 14.28571% with 24 lines in your changes are missing coverage. Please review.

Project coverage is 73.75%. Comparing base (295fa63) to head (68e7ae1).
Report is 26 commits behind head on master.

❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2800      +/-   ##
==========================================
- Coverage   74.06%   73.75%   -0.32%     
==========================================
  Files          18       18              
  Lines        5395     5422      +27     
==========================================
+ Hits         3996     3999       +3     
- Misses       1399     1423      +24     
Files Coverage Δ
python/adjoint/filters.py 69.09% <14.28%> (-8.12%) ⬇️

@smartalecH smartalecH marked this pull request as ready for review March 7, 2024 19:03
@smartalecH smartalecH assigned oskooi and unassigned oskooi Mar 7, 2024
Copy link
Collaborator

@oskooi oskooi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it really necessary to have the two functions run_shape_optimization and run_topology_optimization be separate? They share a lot of code and can probably be combined into a single function.

python/examples/waveguide_crossing.py Show resolved Hide resolved
x
+ npa.rot90(x)
+ npa.rot90(npa.rot90(x))
+ npa.rot90(npa.rot90(npa.rot90(x)))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be cleaner to replace npa.rot90(npa.rot90(x)) with npa.rot90(x, 2), and similar.

else:
x = mpa.tanh_projection(x, beta=beta, eta=eta)

x = npa.clip(x, 0, 1)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really necessary or just meant to ensure the weights are bounded. Since the return values of smoothed_projection and tanh_projection should already have this property it might be better to place this statement inside those functions rather than make it a requirement for the user to include in their functions.

#
# Importantly, this particular example highlights some of the ways one can use
# the novel smoothed projection function to perform both shape and topology
# optimization.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can we use the docstring style for modules which uses triple quotes """ and starts with a one-line summary?

python/examples/waveguide_crossing.py Show resolved Hide resolved
python/examples/waveguide_crossing.py Show resolved Hide resolved
python/adjoint/filters.py Show resolved Hide resolved


if __name__ == "__main__":
run_shape_optimization(resolution=25.0, beta=np.inf, maxeval=30)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How are the return values handled?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not used here so NA

@smartalecH
Copy link
Collaborator Author

Here is an example that runs for 1000 iterations. Interesting how the non-smoothing case eventually breaks through the floor and keeps descending.

image

@mochen4
Copy link
Collaborator

mochen4 commented Mar 21, 2024

As discussed, if it is a greyscale issue, you can try using the damping term in the MaterialGrid, and it really helps with binarization. From my experience, typically damping=0.05ω is sufficient.

@smartalecH
Copy link
Collaborator Author

smartalecH commented Mar 28, 2024

If we look at the final designs for both cases, we see that the optimizer is not simply relying on making the non-smoothed case less binary. Rather, it continues to perturb the geometry.

image image

@stevengj
Copy link
Collaborator

stevengj commented Mar 28, 2024

I wonder if it's getting stuck from the subpixel-smoothed structure being only piecewise differentiable?

In principle, we could fix that by convolving with something like a Gaussian rather than a sphere.

@smartalecH
Copy link
Collaborator Author

smartalecH commented Mar 28, 2024

So here is a plot of the gradients during the "flat region" of the smoothing optimization:

image

What's interesting, is that the gradients for the smoothed case are antisymmetric across x and y... this is problematic though because our mapping function forces a symmetry across x and y... so the optimizer can't actually achieve the change it wants to make (i.e. there may be a bug somewhere breaking down the gradient accuracy?)

Edit: Actually the mapping function is forcing a C4 symmetry only, so this is consistent... but the optimizer isn't wanting to deviate from mirror symmetries?

@stevengj
Copy link
Collaborator

The alternating signs of the gradient would cause the changes to cancel out to first order, so if that's due to a sign error it would be a problem.

@smartalecH
Copy link
Collaborator Author

@stevengj if I monitor the output of CCSA during the optimization, rho indeed blows up.

During the stalled region, it's not necessarily stuck in the same outer iteration. But rho keeps climbing (eg 1e15) and it does take more inner iterations to converge than the rest of the optimization.

@stevengj
Copy link
Collaborator

stevengj commented Apr 3, 2024

Some things to try:

  1. Check smoothness numerically. Define ρ to be e.g. a Gaussian centered at (x,0), which projects to a cylinder, and plot the smoothed/projected ρ̂ at some pixel as a function of x — it should go smoothly (or at least with a continuous 1st derivative) from 0 to 1 as the cylinder passes through the pixel location.

  2. If that looks fine, in principle you could do the same experiment with the Meep solution, e.g. plot DFT electric field at some point as a function of the Gaussian center x and see if it is changing smoothly.

  3. Replace the smoothing function

image with some function of our choosing, e.g. a Gaussian or a twice-differentiable "bump" function with compact support (on a sphere). Implicitly, this defines a smoothing kernel that you could reverse-engineer if you wanted (since the smoothing kernel integrated over the spherical cap gives F_c, you should be able to take some derivatives of the latter to get the former)

python/adjoint/filters.py Outdated Show resolved Hide resolved
Alec Hammond added 2 commits April 11, 2024 09:46
@smartalecH smartalecH requested a review from oskooi April 11, 2024 18:06
@stevengj stevengj merged commit 3c58a5b into master Apr 11, 2024
10 checks passed
@stevengj stevengj deleted the crossing_example branch April 11, 2024 19:53
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.

5 participants