1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
import matplotlib.pyplot as plt
import meep as mp
resolution = 25 # pixels/μm
w1 = 1.0 # width of waveguide 1
w2 = 2.0 # width of waveguide 2
Lw = 10.0 # length of waveguides 1 and 2
# lengths of waveguide taper
Lts = [2**m for m in range(4)]
dair = 3.0 # length of air region
dpml_x = 6.0 # length of PML in x direction
dpml_y = 2.0 # length of PML in y direction
sy = dpml_y + dair + w2 + dair + dpml_y
Si = mp.Medium(epsilon=12.0)
boundary_layers = [mp.PML(dpml_x, direction=mp.X), mp.PML(dpml_y, direction=mp.Y)]
lcen = 6.67 # mode wavelength
fcen = 1 / lcen # mode frequency
symmetries = [mp.Mirror(mp.Y)]
R_coeffs = []
R_flux = []
for Lt in Lts:
sx = dpml_x + Lw + Lt + Lw + dpml_x
cell_size = mp.Vector3(sx, sy, 0)
src_pt = mp.Vector3(-0.5 * sx + dpml_x + 0.2 * Lw)
sources = [
mp.EigenModeSource(
src=mp.GaussianSource(fcen, fwidth=0.2 * fcen),
center=src_pt,
size=mp.Vector3(y=sy - 2 * dpml_y),
eig_match_freq=True,
eig_parity=mp.ODD_Z + mp.EVEN_Y,
)
]
# straight waveguide
vertices = [
mp.Vector3(-0.5 * sx - 1, 0.5 * w1),
mp.Vector3(0.5 * sx + 1, 0.5 * w1),
mp.Vector3(0.5 * sx + 1, -0.5 * w1),
mp.Vector3(-0.5 * sx - 1, -0.5 * w1),
]
sim = mp.Simulation(
resolution=resolution,
cell_size=cell_size,
boundary_layers=boundary_layers,
geometry=[mp.Prism(vertices, height=mp.inf, material=Si)],
sources=sources,
symmetries=symmetries,
)
mon_pt = mp.Vector3(-0.5 * sx + dpml_x + 0.7 * Lw)
flux = sim.add_flux(
fcen, 0, 1, mp.FluxRegion(center=mon_pt, size=mp.Vector3(y=sy - 2 * dpml_y))
)
sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Ez, mon_pt, 1e-9))
res = sim.get_eigenmode_coefficients(flux, [1], eig_parity=mp.ODD_Z + mp.EVEN_Y)
incident_coeffs = res.alpha
incident_flux = mp.get_fluxes(flux)
incident_flux_data = sim.get_flux_data(flux)
sim.reset_meep()
# linear taper
vertices = [
mp.Vector3(-0.5 * sx - 1, 0.5 * w1),
mp.Vector3(-0.5 * Lt, 0.5 * w1),
mp.Vector3(0.5 * Lt, 0.5 * w2),
mp.Vector3(0.5 * sx + 1, 0.5 * w2),
mp.Vector3(0.5 * sx + 1, -0.5 * w2),
mp.Vector3(0.5 * Lt, -0.5 * w2),
mp.Vector3(-0.5 * Lt, -0.5 * w1),
mp.Vector3(-0.5 * sx - 1, -0.5 * w1),
]
sim = mp.Simulation(
resolution=resolution,
cell_size=cell_size,
boundary_layers=boundary_layers,
geometry=[mp.Prism(vertices, height=mp.inf, material=Si)],
sources=sources,
symmetries=symmetries,
)
flux = sim.add_flux(
fcen, 0, 1, mp.FluxRegion(center=mon_pt, size=mp.Vector3(y=sy - 2 * dpml_y))
)
sim.load_minus_flux_data(flux, incident_flux_data)
sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Ez, mon_pt, 1e-9))
res2 = sim.get_eigenmode_coefficients(flux, [1], eig_parity=mp.ODD_Z + mp.EVEN_Y)
taper_coeffs = res2.alpha
taper_flux = mp.get_fluxes(flux)
R_coeffs.append(
abs(taper_coeffs[0, 0, 1]) ** 2 / abs(incident_coeffs[0, 0, 0]) ** 2
)
R_flux.append(-taper_flux[0] / incident_flux[0])
print(f"refl:, {Lt}, {R_coeffs[-1]:.8f}, {R_flux[-1]:.8f}")
if mp.am_master():
plt.figure()
plt.loglog(Lts, R_coeffs, "bo-", label="mode decomposition")
plt.loglog(Lts, R_flux, "ro-", label="Poynting flux")
plt.loglog(
Lts,
[0.005 / Lt**2 for Lt in Lts],
"k-",
label=r"quadratic reference (1/Lt$^2$)",
)
plt.legend(loc="upper right")
plt.xlabel("taper length Lt (μm)")
plt.ylabel("reflectance")
plt.show()
|