NanoComp / meep

free finite-difference time-domain (FDTD) software for electromagnetic simulations
GNU General Public License v2.0
1.16k stars 596 forks source link

Add unit test for broadband sources at fixed angle in a periodic cell (BFAST) #2722

Closed oskooi closed 7 months ago

oskooi commented 7 months ago

Adds a unit test for broadband sources at fixed angle in a cell with periodic boundaries (BFAST). This is to be merged after #2609. The test is an extension of python/tests/test_refl_angular.py and involves verifying that the reflectance from an interface of two lossless, frequency-independent dielectrics (index of 1.4 and 3.5) given a broadband input planewave at normal and oblique (20.6°) incidence with P polarization matches the Fresnel equations. There are two separate runs: without and with the BFAST feature.

There is a large and unexpected discrepancy in the BFAST results and the Fresnel equations for the case of oblique incidence. See the output in 2b below. This required increasing the error threshold by nearly two orders of magnitude compared to the without BFAST case in order for this test to pass:

        if need_bfast:
            tol = 0.1
    else:
            tol = 0.005 if mp.is_single_precision() else 0.004

This discrepancy did not diminish by reducing the Courant parameter. In fact, the choice of the Courant parameter had practically no impact on the results. As such, it would be good to investigate whether it is actually necessary to reduce the Courant as the oblique input angle increases. The results for normal incidence are fine.

The results in 2b require more investigation. There could a bug in (1) the way I am using this feature in the test (which is based on its use in the function planar_reflectance in the colab in #2609) or (2) the implementation in #2609.

1. Without BFAST

a) incident angle = 0°

refl:, wavelength (μm), incident angle (°), reflectance (Meep), reflectance (analytic), error
refl:, 0.80, 0.00, 0.183460, 0.183673, 0.0012
refl:, 0.73, 0.00, 0.183485, 0.183673, 0.0010
refl:, 0.67, 0.00, 0.183423, 0.183673, 0.0014
refl:, 0.62, 0.00, 0.183380, 0.183673, 0.0016
refl:, 0.57, 0.00, 0.183333, 0.183673, 0.0019
refl:, 0.53, 0.00, 0.183282, 0.183673, 0.0021
refl:, 0.50, 0.00, 0.183229, 0.183673, 0.0024
refl:, 0.47, 0.00, 0.183171, 0.183673, 0.0027
refl:, 0.44, 0.00, 0.183108, 0.183673, 0.0031
refl:, 0.42, 0.00, 0.183038, 0.183673, 0.0035
refl:, 0.40, 0.00, 0.183007, 0.183673, 0.0036

b) incident angle = 20.6°

refl:, wavelength (μm), incident angle (°), reflectance (Meep), reflectance (analytic), error
refl:, 0.80, 20.60, 0.164221, 0.164359, 0.0008
refl:, 0.73, 18.65, 0.167659, 0.167881, 0.0013
refl:, 0.67, 17.05, 0.170263, 0.170509, 0.0014
refl:, 0.62, 15.70, 0.172239, 0.172526, 0.0017
refl:, 0.57, 14.56, 0.173772, 0.174109, 0.0019
refl:, 0.53, 13.57, 0.174989, 0.175374, 0.0022
refl:, 0.50, 12.70, 0.175962, 0.176403, 0.0025
refl:, 0.47, 11.94, 0.176753, 0.177250, 0.0028
refl:, 0.44, 11.27, 0.177404, 0.177957, 0.0031
refl:, 0.42, 10.67, 0.177927, 0.178552, 0.0035
refl:, 0.40, 10.13, 0.178432, 0.179059, 0.0035

2. With BFAST a) incident angle = 0°

refl:, wavelength (μm), incident angle (°), reflectance (Meep), reflectance (analytic), error
refl:, 0.80, 0.00, 0.183520, 0.183673, 0.0008
refl:, 0.73, 0.00, 0.183458, 0.183673, 0.0012
refl:, 0.67, 0.00, 0.183425, 0.183673, 0.0014
refl:, 0.62, 0.00, 0.183379, 0.183673, 0.0016
refl:, 0.57, 0.00, 0.183333, 0.183673, 0.0019
refl:, 0.53, 0.00, 0.183283, 0.183673, 0.0021
refl:, 0.50, 0.00, 0.183229, 0.183673, 0.0024
refl:, 0.47, 0.00, 0.183171, 0.183673, 0.0027
refl:, 0.44, 0.00, 0.183111, 0.183673, 0.0031
refl:, 0.42, 0.00, 0.183044, 0.183673, 0.0034
refl:, 0.40, 0.00, 0.182991, 0.183673, 0.0037

b) incident angle = 20.6°

refl:, wavelength (μm), incident angle (°), reflectance (Meep), reflectance (analytic), error
refl:, 0.80, 20.60, 0.173850, 0.164359, 0.0577
refl:, 0.73, 20.60, 0.173927, 0.164359, 0.0582
refl:, 0.67, 20.60, 0.173857, 0.164359, 0.0578
refl:, 0.62, 20.60, 0.173820, 0.164359, 0.0576
refl:, 0.57, 20.60, 0.173773, 0.164359, 0.0573
refl:, 0.53, 20.60, 0.173723, 0.164359, 0.0570
refl:, 0.50, 20.60, 0.173671, 0.164359, 0.0567
refl:, 0.47, 20.60, 0.173613, 0.164359, 0.0563
refl:, 0.44, 20.60, 0.173553, 0.164359, 0.0559
refl:, 0.42, 20.60, 0.173499, 0.164359, 0.0556
refl:, 0.40, 20.60, 0.173350, 0.164359, 0.0547

cc @Dan2357

oskooi commented 7 months ago

It turns out there was a bug in my unit test: I had neglected to include the index of the source medium when specifying bfast_k_bar. The fix required changing:

bfast_k_bar = (np.sin(theta_rad), 0, 0)

to

bfast_k_bar = (self.n1 * np.sin(theta_rad), 0, 0)

It was also necessary to reduce the Courant parameter otherwise the fields were blowing up.

With these changes, the reflectance values match those from the Fresnel equations. The relative difference also decreases with increasing resolution, as expected.