MLResearchAtOSRAM / tmm_fast

tmm_fast is a lightweight package to speed up optical planar multilayer thin-film device computation. Developed by Alexander Luce (@Nerrror) in cooperation with Heribert Wankerl (@HarryTheBird).
MIT License
53 stars 22 forks source link

Error when dealing with absorbing material #11

Closed matthew991033 closed 1 year ago

matthew991033 commented 1 year ago

When the substrate is an absorbing material, the calculation is correct. However, when it is placed at upper layer of the photonic structure with thickness large enough, for instance a structure like W(e. g. 1000 nm)/SiO2/W(substrate), the upper layer of W (Although this structure is meaningless) would lead to 'nan' in calculated reflectance.

drcosquared commented 1 year ago

I believe I am also encountering this issue. I'm simulating reflection spectra of epitaxial layers, using Drude-Lorentz theory to model the refractive indices of the substrate and layer. The substrate is 500 micron thick and the epilayer is 14 microns. The structure is bounded by air in the simulation. Using the original tmm package by Byrnes yields the expected result (see attached figure). However, in tmm_fast, the reflectance is calculated as nan as R approaches one. See other attached figure.

Original Byrnes tmm package: Byrnes tmm R

tmm_fast: fast_tmm R

drcosquared commented 1 year ago

I believe I know what the issue is. In the original tmm package, the coh_tmm function contains a check for very opaque layers, making them ever so slightly transparent to avoid nan situations:

# For a very opaque layer, reset delta to avoid divide-by-0 and similar
# errors. The criterion imag(delta) > 35 corresponds to single-pass
# transmission < 1e-30 --- small enough that the exact value doesn't
# matter.
for i in range(1, num_layers-1):
    if delta[i].imag > 35:
        delta[i] = delta[i].real + 35j
        if 'opacity_warning' not in globals():
            global opacity_warning
            opacity_warning = True
            print("Warning: Layers that are almost perfectly opaque "
                  "are modified to be slightly transmissive, "
                  "allowing 1 photon in 10^30 to pass through. It's "
                  "for numerical stability. This warning will not "
                  "be shown again.")

The tmm_fast method seems to have removed this check, not sure what the reason is. I may try to reimplement this check, but I'm not very familiar with pytorch.

Nerrror commented 1 year ago

Hey, thanks for bringing this to my attention. I reimplemented the opacity check but I'm not confident that this solves the issue here since It doesn't make sense that a thicker layer leads to the opacity problem, it would only make a difference if you give a very large k value to the solver. I could imagine though that when an absorbing layer becomes too large, the values in the transport matrix become too small which leads to nans when you're calculating the system matrix M. I corrected that, too. Can you confirm whether the update solved the issue?

@drcosquared would you mind sharing the thicknesses and refractive indices somehow if the update didn't resolve the problem?

drcosquared commented 1 year ago

Thanks for looking into this! Unfortunately, there still seems to be a bug somewhere. I re-ran my code with your changes and there is still something weird happening in the highly absorbing band of the spectrum. The plot is below. tmm_newversion

I'm attaching a csv file with the refractive indices of the layers. The first row of the CSV file is the wavenumber. It's two layers bounded by air. The first layer is the substrate with a thickness of 500 microns and the second layer is 14.5 microns. refractive indices.csv

Nerrror commented 1 year ago

I think I found the problem now. It was a combination of the opacity check and not enough floating point precision, I missunderstood what the opacity check was actually doing. Now, both programms give the same result again: image

@drcosquared Btw, I think you reversed the stacking order in your last graph, right?

drcosquared commented 1 year ago

@Nerrror thanks so much for your help! I've also confirmed that tmm_fast matches the original tmm package for my system.

I believe you're correct, I may have gotten the layers reversed in my last graph.