Skip to content

add tutorial about source normalization #301

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

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from

Conversation

FilipeFcp
Copy link
Contributor

Hi all,
This is the example of source normalization related to issue #900.
Let me know if you think we should add, remove, or modify anything.

It was run using version 2.9-rc.1, with the fixes to the diffraction monitor included.

Copy link
Contributor

github-actions bot commented Jun 6, 2025

Spell check passed successfully for 1 notebook(s).
Generated by GitHub Action run: https://github.com/flexcompute/tidy3d-notebooks/actions/runs/15645147129

Copy link
Contributor

@alec-flexcompute alec-flexcompute left a comment

Choose a reason for hiding this comment

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

Excellent work @Filipe, this will be a super useful resource - this answers a number of my questions as well!

A couple comments:

  1. Above cell 5, it might help to plot a couple of these simulations, so the user can quickly visualize what you're measuring

  2. For the plot in cell 21, maybe connect the data points with a line to better illustrate the behavior

  3. Above cell 22, a bit more explanation of what the simulation will do will be helpful

Other than that, I think this is great - super clear, illustrative, and useful!

Copy link
Contributor

@tomflexcompute tomflexcompute left a comment

Choose a reason for hiding this comment

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

Thanks @FilipeFcp . Very helpful content, especially the error on the monitor position, which I didn't realize before.

  1. Consider adding doc string to the get_sim function since it's relatively long with many arguments.

  2. For plane wave, "|E_0| is proportional to the source plane area" is incorrect right? |E_0| should be proportional to the area**(-1/2) as the figure below shows?

  3. Since we are on this topic, shall we spend some time on custom field source and current source normalization just to make the tutorial complete?

@momchil-flex
Copy link
Collaborator

Thanks @FilipeFcp, great stuff! A few comments from my side too:

  • I am a bit surprised by the diffraction monitor result at 20 degrees. It seems to have jumped quite a lot compared to the trend from the previous degrees. Since you're focusing on that data point exactly, I want to be sure that it's actually correct (I mean, it seems that the error goes down with resolution, but still it looks a bit fishy if there's a sudden jump). Maybe, at least for internal consideration, could you run this with more angles and we can see if there's some discontinuity we need to look at? If there's a discontinuity, I wonder if it may be related to a second diffraction order appearing in the simulation? In which case it would be affected by the simulation domain size.

  • For the point dipole, instead of saying for a classical radiating dipole, let's either explicitly say classical radiating current dipole (as opposed to electric dipole, which will be normalized differently), or infinitesimal antenna with a fixed current density as in our FAQ. Also, mention that the formula you give is specific to an electric current dipole in 3D (and maybe link to our FAQ again).

  • Just wondering why you use nu for the frequency instead of f as in the rest of our documentation (I believe?), or even just omega directly.

@FilipeFcp
Copy link
Contributor Author

Hi all.
Thanks for the comments. I've fixed the issue and am now adding the current and custom source components.

@momchil-flex, I did some tests with more angles, and it seems odd. Using 2.9rc, for a plane size of 1 µm:

image

Changing the plane size to 1.5 µm:
image

That doesn't happen in 2.8.3:
image

Is it some issue with the monitor, or should I adapt something in the simulation?

The $\nu$ name was just old habits. I will change to omega to be more consistent with our documentation.

@FilipeFcp
Copy link
Contributor Author

It gets much better with increased resolution. The previous results used 10 steps per wavelength.

Using 20:

image
image

Using 30:
image

image

@momchil-flex
Copy link
Collaborator

Ok, yeah, this is pretty interesting. In some sense it is showing exactly what I wanted to show: that in some cases, especially when the DiffractionMonitor has to differentiate between roughly equal powers going in both directions, the accuracy can get degraded. Notice that the problems are happening exactly beyond TIR when reflection hits 1, meaning that there's exactly equal powers going in each direction, and the flux at that location is 0.

The problem is that numerically the flux is rather numerical noise on the scale of 1e-6. In the new handling in 2.9.0rc1, I've added some flux normalization similar to what we already do for ModeMonitor-s, which ensures that, in the typical "correct" setups (like in the "back" monitors in this setup), the power recorded by a DiffractionMonitor matches very closely the flux of a FluxMonitor. However, this flux normalization is indeed introducing more noise in the case of flux ~ 0. Increasing the resolution decreases the "noisiness" of the flux around 0, and thus decreases the numerical normalization error.

Understanding now how everything fits together, my suggestion is to preserve the current behavior. I think the increased accuracy in the "correct" setup is worth the potential decrease in the specific case of a DiffractionMonitor placed in a region with (almost) 0 flux.

@momchil-flex
Copy link
Collaborator

Note that my original comment on the issue was exactly that I would expect DiffractionMonitor to have a large error when there is full reflection, there I was suggesting PEC, but here it is the same once TIR is hit. So yeah while not ideal that this gets exacerbated by the "fixes", I think it's a good opportunity to discuss this point exactly!

@FilipeFcp
Copy link
Contributor Author

@momchil-flex. Seems good. I will wrap up this discussion in the notebook. Also, I think it could be good to add a few comments regarding this in the DiffractionMonitor docs. I work on it today

@FilipeFcp
Copy link
Contributor Author

Hi all,
I believe I’ve addressed all the comments.
I added a section about the custom source, which seems fine.

I’m less confident about the section on the current source. I found an analytical expression in the Balanis book:

image

It seems to work well for small-area sources, which fits the approximation.

However, I’m not sure about the normalization for a 1D source. Sorry, @momchil-flex, I recall we had a brief discussion about this on Slack earlier this year, but I couldn’t locate it. We do apply some normalization when the source 1D right?

@momchil-flex
Copy link
Collaborator

Thanks @FilipeFcp!

In this figure, maybe still keep the diffraction monitor result in the right panel? It's zoomed in but for small angles maybe it will show good agreement?

image

Regarding source normalization of the uniform current source, it's nice to see that the result approximately matches the analytical result you've found! I am not really sure about it honestly, for this type of source (as well as CustomCurrent and CustomField) my thinking has generally been that some normalization run is needed as it's hard to nail down an exact result a priori.

Regarding normalization when the source is smaller than 3D, basically for every dimension that is 0-size, we divide by the cell size at the pixel at which the source is injected, so we get a result that is independent of the exact discretization. If we weren't doing this, the source would have an effective size that is given by the pixel size. This also means that the amplitude units of what the user is defining change from A / um**2 to A / um to A to A * um going from 3D to 2D to 1D to 0D. In other words, when e.g. defining a point dipole of a given amplitude, the user is defining the electric current moment I * d where I is the total current and d is the dipole size. When defining the amplitude for a 1D source, it is in units of A and the injected current is something like e.g. amp * delta(z-z0) when the source is centered at z0 and 0-dim along z.

Note that your last plots seem to be messed up in their axis labels. In both of them it says "theta [degrees]" but you're plotting source size in the next-to-last, and resolution in the last one.

@FilipeFcp
Copy link
Contributor Author

Thanks @momchil-flex! I corrected the plots and labels and added a small discussion in the current source section.

@tomflexcompute tomflexcompute self-requested a review June 14, 2025 16:57
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.

4 participants