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
| import numpy as np import matplotlib as mpl mpl.rcParams['figure.dpi']=100 import matplotlib.pylab as plt import ceviche from skimage.draw import disk from ceviche.modes import insert_mode from ceviche import fdfd_ez, jacobian import autograd.numpy as npa import collections Slice = collections.namedtuple('Slice', 'x y')
def viz_sim(epsr, source1, source2, slices=[]): simulation1 = fdfd_ez(omega1, dl, epsr, [Npml, Npml]) _, _, Ez1 = simulation1.solve(source1) simulation2 = fdfd_ez(omega2, dl, epsr, [Npml, Npml]) _, _, Ez2 = simulation2.solve(source2)
fig, ax = plt.subplots(1, 3, constrained_layout=True, figsize=(9,3)) ceviche.viz.abs(Ez1, outline=epsr, ax=ax[0], cbar=False) ceviche.viz.abs(Ez2, outline=epsr, ax=ax[1], cbar=False) ceviche.viz.abs(epsr, ax=ax[2], cmap='Greys') for sl in slices: ax[0].plot(sl.x*np.ones(len(sl.y)), sl.y, 'w-', alpha=0.5) ax[1].plot(sl.x*np.ones(len(sl.y)), sl.y, 'w-', alpha=0.5) ax[0].set_title(r'$\lambda_1$ = %.2f $\mu$m' % (299792458/(omega1/2/np.pi)/1e-6)) ax[1].set_title(r'$\lambda_2$ = %.2f $\mu$m' % (299792458/(omega2/2/np.pi)/1e-6))
return (simulation1, simulation2, ax, fig)
def init_structure(Nx, Ny, Nwg, Nwd, Nox, Noy, Npml, edge_N, index_font, index_background): epsr = np.ones((Nx, Ny)) * (index_font ** 2) epsr[0:Nwg, (Ny-Nwd)//2:(Ny+Nwd)//2] = index_background ** 2 epsr[Nwg:Nwg+Nox, (edge_N) * Npml:(edge_N) * Npml+Noy] = index_background ** 2 epsr[Nwg+Nox:2*Nwg+Nox,(edge_N) * Npml: (edge_N) * Npml+Nwd] = index_background ** 2 epsr[Nwg+Nox:2*Nwg+Nox,(edge_N) * Npml+Noy-Nwd:(edge_N) * Npml+Noy] = index_background ** 2 input_slice = Slice(x=np.array(Npml+Nwg//2), y=np.arange((Ny-Nwd)//2- Nwd, (Ny+Nwd)//2+Nwd)) output_slice1 = Slice(x=np.array(Nwg+Nox+Nwg//2), y=np.arange(edge_N*Npml+Noy-2*Nwd, edge_N*Npml+Noy+Nwd)) output_slice2 = Slice(x=np.array(Nwg+Nox+Nwg//2), y=np.arange( edge_N*Npml-Nwd, edge_N*Npml+2*Nwd)) return epsr, input_slice, output_slice1, output_slice2
def init_opt_structure(Nwg, circule_outer_radius, Npml, circule_inter_radius, epsr, index_font, index_background): m = Nox // (circule_outer_radius * 2) n = Noy // (circule_outer_radius * 2) poles = [] for i in range(m): for j in range(n): rr, cc = disk((Nwg+2*circule_outer_radius*(j+0.5), (edge_N)*Npml+2*circule_outer_radius*(i+0.5)), circule_inter_radius) poles.append([rr,cc]) epsr[rr,cc] = (index_font ** 2) return epsr, poles
def set_opt_structure(poles, pole_index, epsr, index): epsr[poles[pole_index][0],poles[pole_index][1]] = index ** 2 return epsr
if __name__ == "__main__": omega1=2*np.pi*200e12 omega2=2*np.pi*230e12 dl = 20e-9 opt_size_x = 2400e-9 opt_size_y = 2400e-9 wg_len = 2000e-9 wg_width = 500e-9 Npml = 20 edge_N = 4 index_background = 3.47 index_font = 1.22 circule_outer_radius = 6 circule_inter_radius = 5
Nx = int((opt_size_x + 2 * wg_len)*10e9 / (dl*10e9)) Ny = int((opt_size_y)*10e9 / (dl*10e9) + 2 * edge_N * Npml) Nox = int((opt_size_x*10e9) / (dl*10e9)) Noy = int((opt_size_y*10e9) / (dl*10e9)) Nwg = int(wg_len*10e9 / (dl*10e9)) Nwd = int(wg_width*10e9 / (dl*10e9))
epsr, input_slice, output_slice1, output_slice2 = init_structure(Nx, Ny, Nwg, Nwd, Nox, Noy, Npml, edge_N, index_font, index_background) epsr, poles = init_opt_structure(Nwg, circule_outer_radius, Npml, circule_inter_radius, epsr, index_font, index_background)
source1 = insert_mode(omega1, dl, input_slice.x, input_slice.y, epsr, m=1) source2 = insert_mode(omega2, dl, input_slice.x, input_slice.y, epsr, m=1)
probe1 = insert_mode(omega1, dl, output_slice1.x, output_slice1.y, epsr, m=1) probe2 = insert_mode(omega2, dl, output_slice2.x, output_slice2.y, epsr, m=1) epsr = set_opt_structure(poles, 0, epsr, index_background) simulation1, simulation2, ax, fig = viz_sim(epsr, source1, source2, slices = [input_slice, output_slice1, output_slice2])
_, _, Ez1 = simulation1.solve(source1) _, _, Ez2 = simulation2.solve(source2)
E01 = mode_overlap(Ez1, probe1) E02 = mode_overlap(Ez2, probe2)
print(E01,E02)
plt.show()
|