# \[pre-ANN\] Differentiable FDTD for inverse design in photonics, acoustics and RF

**URL:** <https://discourse.julialang.org/t/pre-ann-differentiable-fdtd-for-inverse-design-in-photonics-acoustics-and-rf/105405>\
**Category:** Package Announcements\
**Tags:** package, announcement, diffeq, flux, machine-learning\
**Created:** [October 26, 2023, 12:22am UTC](https://discourse.julialang.org/t/pre-ann-differentiable-fdtd-for-inverse-design-in-photonics-acoustics-and-rf/105405 "2023-10-26T00:22:55Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![pxshen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pxshen/32/38776_2.png) [@pxshen](https://discourse.julialang.org/u/pxshen)\
**Post date:** [October 26, 2023, 12:22am UTC](https://discourse.julialang.org/t/pre-ann-differentiable-fdtd-for-inverse-design-in-photonics-acoustics-and-rf/105405/1 "2023-10-26T00:22:55Z")

</div>

Planning to release a differentiable FDTD package for inverse design in photonics, acoustics and RF. I’ll include examples on designing stacks, gratings and couplers as well as meta-materials and meta-surfaces. The electromagnetic FDTD update is simple, drawing on earlier patterns in FDTD.jl and uFDTD.jl based on Schneider’s uFDTD book. Autodiff uses DiffEqFlux.jl neural ODEs and fits within the SciML ecosystem. We have fully featured boundary conditions and support dispersive lossy materials (had to pull some hacks to appease Zygote.jl here). Meant as a differentiable, inverse design focused version of a commercial solver like Ansys Lumerical.

Feature requests welcome 🙂 Academic collaborators, grant cooperation and corporate sponsorship welcome.

---

<div class="post-metadata">

**Author:** ![garrek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/garrek/32/27937_2.png) [@garrek](https://discourse.julialang.org/u/garrek)\
**Post date:** [October 26, 2023, 2:24am UTC](https://discourse.julialang.org/t/pre-ann-differentiable-fdtd-for-inverse-design-in-photonics-acoustics-and-rf/105405/2 "2023-10-26T02:24:01Z")

</div>

I would be interested in testing something like this. I’ve been meaning to set up a simulation of a pulsed laser in a cavity (possibly with an absorptive material). If this package could do different electromagnetic sources (like a Gaussian pulse) that would be very interesting.

---

<div class="post-metadata">

**Author:** ![pxshen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pxshen/32/38776_2.png) [@pxshen](https://discourse.julialang.org/u/pxshen)\
**Post date:** [October 26, 2023, 2:59am UTC](https://discourse.julialang.org/t/pre-ann-differentiable-fdtd-for-inverse-design-in-photonics-acoustics-and-rf/105405/3 "2023-10-26T02:59:24Z")

</div>

Yeah side injection of Gaussian pulse will be a standard source in our code. The update loop is fully exposed so you can also inject whatever additive source you want.

---

<div class="post-metadata">

**Author:** ![garrek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/garrek/32/27937_2.png) [@garrek](https://discourse.julialang.org/u/garrek)\
**Post date:** [October 26, 2023, 3:00am UTC](https://discourse.julialang.org/t/pre-ann-differentiable-fdtd-for-inverse-design-in-photonics-acoustics-and-rf/105405/4 "2023-10-26T03:00:57Z")

</div>

Awesome. I’m excited to try it when you release!

---

<div class="post-metadata">

**Author:** ![mike.ingold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mike.ingold/32/203749_2.png) [@mike.ingold](https://discourse.julialang.org/u/mike.ingold)\
**Post date:** [November 13, 2023, 4:45pm UTC](https://discourse.julialang.org/t/pre-ann-differentiable-fdtd-for-inverse-design-in-photonics-acoustics-and-rf/105405/5 "2023-11-13T16:45:21Z")

</div>

This is something I would be very interested in. I’ve written some toy FDTD codes in Julia and have considered putting in the work to make a good implementation for the General registry, but haven’t had the time lately to work more on it. Making it AD-compatible is something I’d considered but wasn’t even sure would be possible (or at least practical), so hats off for making that work.

Do you have a repo for it on GitHub? I’d love to check it out and see if there’s anything I could contribute.

---

<div class="post-metadata">

**Author:** ![pxshen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pxshen/32/38776_2.png) [@pxshen](https://discourse.julialang.org/u/pxshen)\
**Post date:** [November 14, 2023, 7:21pm UTC](https://discourse.julialang.org/t/pre-ann-differentiable-fdtd-for-inverse-design-in-photonics-acoustics-and-rf/105405/6 "2023-11-14T19:21:22Z")

</div>

Thanks I’ll release it around end of this month. The AD piggy backs off DiffEqFlux.jl which uses constant memory wrt timesteps. I’m still testing on toy inverse design problems in [Google’s Ceviche challenges in invrs.io](https://github.com/invrs-io/gym) ported to Julia.

> **[GitHub - invrs-io/gym: A collection of inverse design challenges](https://github.com/invrs-io/gym)**
>
> A collection of inverse design challenges. Contribute to invrs-io/gym development by creating an account on GitHub.

> **[GitHub - google/ceviche-challenges: A suite of photonic inverse design...](https://github.com/google/ceviche-challenges)**
>
> A suite of photonic inverse design challenge problems for topology optimization benchmarking - GitHub - google/ceviche-challenges: A suite of photonic inverse design challenge problems for topology...

---

<div class="post-metadata">

**Author:** ![smartalecH](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/smartalech/32/32379_2.png) [@smartalecH](https://discourse.julialang.org/u/smartalecH)\
**Post date:** [November 15, 2023, 2:33am UTC](https://discourse.julialang.org/t/pre-ann-differentiable-fdtd-for-inverse-design-in-photonics-acoustics-and-rf/105405/7 "2023-11-15T02:33:12Z")

</div>

What kind of adjoint did you implement? Is it strictly time domain? Or do you have a hybrid time-/frequency-domain implementation too?

Is it purely CPU-based?

---

<div class="post-metadata">

**Author:** ![pxshen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pxshen/32/38776_2.png) [@pxshen](https://discourse.julialang.org/u/pxshen)\
**Post date:** [November 15, 2023, 3:40pm UTC](https://discourse.julialang.org/t/pre-ann-differentiable-fdtd-for-inverse-design-in-photonics-acoustics-and-rf/105405/8 "2023-11-15T15:40:10Z")

</div>

Hi Alec adjoints are done in time domain. Problem is treated as a neural ODE. DiffEqFlux.jl integrates it backwards to recover intermediates for reverse mode AD.

Everything can be on the GPU but I haven’t tested it there. Takes only couple lines of code to move to/from GPU on Flux.jl / Cuda.jl. Probably have to tweak some code but nothing major.

---

<div class="post-metadata">

**Author:** ![brianguenter](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brianguenter/32/29519_2.png) [@brianguenter](https://discourse.julialang.org/u/brianguenter)\
**Post date:** [November 15, 2023, 6:40pm UTC](https://discourse.julialang.org/t/pre-ann-differentiable-fdtd-for-inverse-design-in-photonics-acoustics-and-rf/105405/9 "2023-11-15T18:40:03Z")

</div>

Would you be interested in trying my AD package [FastDifferentiation.jl](https://github.com/brianguenter/FastDifferentiation.jl)? I’m always looking for new applications.

Not sure if it will work in your case but for problems in its domain it can be substantially faster than other AD packages. I’ll help you work through any problems you encounter.

---

<div class="post-metadata">

**Author:** ![pxshen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pxshen/32/38776_2.png) [@pxshen](https://discourse.julialang.org/u/pxshen)\
**Post date:** [November 17, 2023, 12:46am UTC](https://discourse.julialang.org/t/pre-ann-differentiable-fdtd-for-inverse-design-in-photonics-acoustics-and-rf/105405/10 "2023-11-17T00:46:32Z")

</div>

Thanks - interesting work! I’ll read up on your approach. It seems a major advantage is a more natural way of handling higher order and mixed derivatives, which would benefit the PINN folks or loss functions involving derivatives? .

---

<div class="post-metadata">

**Author:** ![brianguenter](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brianguenter/32/29519_2.png) [@brianguenter](https://discourse.julialang.org/u/brianguenter)\
**Post date:** [November 17, 2023, 9:15am UTC](https://discourse.julialang.org/t/pre-ann-differentiable-fdtd-for-inverse-design-in-photonics-acoustics-and-rf/105405/11 "2023-11-17T09:15:01Z")

</div>

Yes, I find it much simpler to specify derivatives this way. If you need a Jacobian rather than just a gradient FastDifferentiation can also be much faster, hundreds of times faster in some cases.

---

<div class="post-metadata">

**Author:** ![pxshen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pxshen/32/38776_2.png) [@pxshen](https://discourse.julialang.org/u/pxshen)\
**Post date:** [December 7, 2023, 3:22pm UTC](https://discourse.julialang.org/t/pre-ann-differentiable-fdtd-for-inverse-design-in-photonics-acoustics-and-rf/105405/12 "2023-12-07T15:22:33Z")

</div>

Adjoint works now. Successfully solves the first couple Ceviche challenges. Sorry for the delay - will publish repo in a week.

---

<div class="post-metadata">

**Author:** ![pxshen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pxshen/32/38776_2.png) [@pxshen](https://discourse.julialang.org/u/pxshen)\
**Post date:** [December 15, 2023, 5:46pm UTC](https://discourse.julialang.org/t/pre-ann-differentiable-fdtd-for-inverse-design-in-photonics-acoustics-and-rf/105405/13 "2023-12-15T17:46:20Z")

</div>

I’m sharing a working draft at [GitHub - paulxshen/differentiable-fdtd-beta-prerelease](https://github.com/paulxshen/differentiable-fdtd-beta-prerelease/)  
Still messy and undocumented. If you’re curious you can peak at the examples to get a sense of the API. Goal is inverse design so you have full access to the physics and update looop. I ended up just AD the bare loop (accumulator) because I had stability issues playing around the adjoint ODE sensealg in SciMLSensitivity/DiffEqFlux which trades compute for less memory. So I’m happy I’ve derisked my hypothesis - what’s left is optimization & documentation to make the repo usable for other folks in the coming month.  
 ![bend-pre](https://global.discourse-cdn.com/julialang/original/3X/c/8/c820b9f469341685e2dd52edda532904c45d9804.gif)  
 ![bend-post](https://global.discourse-cdn.com/julialang/original/3X/2/2/226a5925a592575973e47ed20470b0fab1f6b682.gif)

---

<div class="post-metadata">

**Author:** ![mike.ingold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mike.ingold/32/203749_2.png) [@mike.ingold](https://discourse.julialang.org/u/mike.ingold)\
**Post date:** [December 15, 2023, 7:31pm UTC](https://discourse.julialang.org/t/pre-ann-differentiable-fdtd-for-inverse-design-in-photonics-acoustics-and-rf/105405/14 "2023-12-15T19:31:25Z")

</div>

Have you looked at putting all the code into a common module so that it can be imported into Julia as a package, i.e. `Pkg.add("https://github.com/paulxshen/differentiable-fdtd-beta-prerelease")`? I don’t see a `Project.toml` or a main module file under `/src`, and from the [runtest.jl](https://github.com/paulxshen/differentiable-fdtd-beta-prerelease/blob/master/src/runtests.jl) example it looks like each source file is being `include`d directly.

The provided example is pretty cool. I’m looking forward to trying it out this weekend. If you’re willing to entertain PR’s maybe I could help chip away at some documentation and such.

---

<div class="post-metadata">

**Author:** ![pxshen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pxshen/32/38776_2.png) [@pxshen](https://discourse.julialang.org/u/pxshen)\
**Post date:** [December 15, 2023, 9:33pm UTC](https://discourse.julialang.org/t/pre-ann-differentiable-fdtd-for-inverse-design-in-photonics-acoustics-and-rf/105405/15 "2023-12-15T21:33:59Z")

</div>

Yes, definitely, just haven’t gotten there yet 😃 But I can pack it together so you can run it during prerelease. Also, I meant the examples folder file [https://github.com/paulxshen/differentiable-fdtd-beta-prerelease/blob/master/examples/waveguide\_bend.jl](https://github.com/paulxshen/differentiable-fdtd-beta-prerelease/blob/master/examples/waveguide_bend.jl)

Yeah thanks for your help. I’ll push out basic docs so folks can add to it.

---

<div class="post-metadata">

**Author:** ![pxshen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pxshen/32/38776_2.png) [@pxshen](https://discourse.julialang.org/u/pxshen)\
**Post date:** [December 28, 2023, 9:45pm UTC](https://discourse.julialang.org/t/pre-ann-differentiable-fdtd-for-inverse-design-in-photonics-acoustics-and-rf/105405/16 "2023-12-28T21:45:47Z")

</div>

I packed everything into a module and uploaded the inverse design example to Google Colab [Google Colab](https://colab.research.google.com/drive/1-g6ShK54MbSsAAeE2c5cj5g7OY7CXfpy?usp=sharing) . The settings are on a coarse resolution and lax tolerance to save time but gives you a sense of the workflow. Code is probably still too messy to run yourself but you can peak around. I’ll upload some forward simulation examples too (much easier/shorter than inverse design).

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [December 29, 2023, 2:37am UTC](https://discourse.julialang.org/t/pre-ann-differentiable-fdtd-for-inverse-design-in-photonics-acoustics-and-rf/105405/17 "2023-12-29T02:37:59Z")

</div>

> [@pxshen](#):
>
> I ended up just AD the bare loop (accumulator) because I had stability issues playing around the adjoint ODE sensealg in SciMLSensitivity/DiffEqFlux which trades compute for less memory.

Can you describe that more? Most of the algorithms don’t trade memory for compute. The BacksolveAdjoint will generally be unstable on any PDE you’d use FDTD for (I describe this in my talks [https://youtu.be/OyFP565kDUI?si=UsHRRs2B5p5anPrn&t=3738](https://youtu.be/OyFP565kDUI?si=UsHRRs2B5p5anPrn&t=3738)) and so you’d want to not use BacksolveAdjoint but InterpolatingAdjoint or GaussAdjoint.

---

<div class="post-metadata">

**Author:** ![pxshen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pxshen/32/38776_2.png) [@pxshen](https://discourse.julialang.org/u/pxshen)\
**Post date:** [December 29, 2023, 4:48am UTC](https://discourse.julialang.org/t/pre-ann-differentiable-fdtd-for-inverse-design-in-photonics-acoustics-and-rf/105405/18 "2023-12-29T04:48:10Z")

</div>

Thanks Chris I tried InterpolatingAdjoint & QuadratureAdjoint but might’ve been my problem using it. AD the bare loop was the first thing that worked so I’m just using that for prototyping. Also it compiled much faster than ODE adjoints, which I’ll probably come back to once I transition from experimentation to optimization. Will get back to you.

---

<div class="post-metadata">

**Author:** ![pxshen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pxshen/32/38776_2.png) [@pxshen](https://discourse.julialang.org/u/pxshen)\
**Post date:** [December 30, 2023, 9:21pm UTC](https://discourse.julialang.org/t/pre-ann-differentiable-fdtd-for-inverse-design-in-photonics-acoustics-and-rf/105405/19 "2023-12-30T21:21:20Z")

</div>

Happy holidays folks!

Documentation now live at [fdtd\_prerelease.jl · fdtd\_prerelease](https://paulxshen.github.io/differentiable-fdtd-beta-prerelease/)  
I also uploaded a quick 2d simulation tutorial at [Google Colab](https://colab.research.google.com/drive/1SiP7MvSE4P05uNgostV9WWx3pFQtFYDW?usp=sharing), [movie](https://paulxshen.github.io/differentiable-fdtd-beta-prerelease/assets/periodic_array_nres_32.mp4)

I’m still testing 3d but 2d is mostly ready for public testing  
LMK of issues and bugs

---

<div class="post-metadata">

**Author:** ![pxshen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pxshen/32/38776_2.png) [@pxshen](https://discourse.julialang.org/u/pxshen)\
**Post date:** [January 9, 2024, 3:20am UTC](https://discourse.julialang.org/t/pre-ann-differentiable-fdtd-for-inverse-design-in-photonics-acoustics-and-rf/105405/20 "2024-01-09T03:20:47Z")

</div>

We’re also looking for a package name - suggestions welcome 🙂

[Next page](https://discourse.julialang.org/t/pre-ann-differentiable-fdtd-for-inverse-design-in-photonics-acoustics-and-rf/105405.md?page=2)
