(gp, gh, gdc, theta)
| 12 | |
| 13 | |
| 14 | def binary_grating_diffraction(gp, gh, gdc, theta): |
| 15 | |
| 16 | resolution = 50 # pixels/μm |
| 17 | |
| 18 | dpml = 1.0 # PML thickness |
| 19 | dsub = 3.0 # substrate thickness |
| 20 | dpad = 3.0 # length of padding between grating and PML |
| 21 | |
| 22 | sx = dpml + dsub + gh + dpad + dpml |
| 23 | sy = gp |
| 24 | |
| 25 | cell_size = mp.Vector3(sx, sy, 0) |
| 26 | pml_layers = [mp.PML(thickness=dpml, direction=mp.X)] |
| 27 | |
| 28 | wvl = 0.5 # center wavelength |
| 29 | fcen = 1 / wvl # center frequency |
| 30 | df = 0.05 * fcen # frequency width |
| 31 | |
| 32 | ng = 1.5 |
| 33 | glass = mp.Medium(index=ng) |
| 34 | |
| 35 | # rotation angle of incident planewave; counter clockwise (CCW) about Z axis, 0 degrees along +X axis |
| 36 | theta_in = math.radians(theta) |
| 37 | |
| 38 | eig_parity = mp.EVEN_Z |
| 39 | |
| 40 | # k (in source medium) with correct length (plane of incidence: XY) |
| 41 | k = mp.Vector3(fcen * ng).rotate(mp.Vector3(z=1), theta_in) |
| 42 | |
| 43 | symmetries = [] |
| 44 | if theta_in == 0: |
| 45 | k = mp.Vector3() |
| 46 | eig_parity += mp.ODD_Y |
| 47 | symmetries = [mp.Mirror(direction=mp.Y, phase=-1)] |
| 48 | |
| 49 | def pw_amp(k, x0): |
| 50 | def _pw_amp(x): |
| 51 | return cmath.exp(1j * 2 * math.pi * k.dot(x + x0)) |
| 52 | |
| 53 | return _pw_amp |
| 54 | |
| 55 | src_pt = mp.Vector3(-0.5 * sx + dpml, 0, 0) |
| 56 | sources = [ |
| 57 | mp.Source( |
| 58 | mp.GaussianSource(fcen, fwidth=df), |
| 59 | component=mp.Hz, |
| 60 | center=src_pt, |
| 61 | size=mp.Vector3(0, sy, 0), |
| 62 | amp_func=pw_amp(k, src_pt), |
| 63 | ) |
| 64 | ] |
| 65 | |
| 66 | sim = mp.Simulation( |
| 67 | resolution=resolution, |
| 68 | cell_size=cell_size, |
| 69 | boundary_layers=pml_layers, |
| 70 | k_point=k, |
| 71 | default_material=glass, |
no test coverage detected