Sweep grating coupler periodΒΆ

Grating coupler period depends on the wavelength, waveguide thickness, etch depth and fiber incidence angle

Analytic calculation of the grating coupler period for various duty-cycles in SOI.

Seems to match well with the periods in Taillaert et al., *Grating Couplers for Coupling between Optical Fibers and Nanophotonic Waveguides*, IOP Science, 2006.

[1]:
import numpy as np
import matplotlib.pyplot as plt
import modes.design as de
import modes._mode_solver_full_vectorial as ms
import modes._structure as st
import modes._structure_base as stb
import opticalmaterialspy as mat

wls = [1.50, 1.55, 1.60]
x_step = 0.05
y_step = 0.05
etch_depth = 0.22
width = 10
sub_thickness = 0.5
sub_width = 14.
clad_thickness = [0.5]
film_thickness = 0.22
polarisation = 'TE'
dcs = np.linspace(20, 80, 61) / 100
incidence_angle_deg = 10

ed1 = etch_depth
ft1 = film_thickness
ed2 = ft1 - ed1
ft2 = ed2

periods = []
periods.append(dcs)

wavelength2period = {}

for wl in wls:
    ngc = []
    for thickness, film_thickness in [(ed1, ft1), (ed2, ft2)]:
        def wg(n_sub, n_wg, n_clad):
            return st.RidgeWaveguide(wavelength=wl, x_step=x_step, y_step=y_step, thickness=thickness, width=width,
                                     sub_thickness=sub_thickness, sub_width=sub_width, clad_thickness=clad_thickness,
                                     n_sub=n_sub, n_wg=n_wg, n_slab=None, angle=0, n_clad= n_clad, film_thickness=film_thickness)

        n_sub = mat.SiO2().n(wl)
        n_wg = mat.RefractiveIndexWeb('https://refractiveindex.info/?shelf=main&book=Si&page=Li-293K').n(wl)
        n_wg_xx = n_wg
        n_wg_yy = n_wg
        n_wg_zz = n_wg
        n_clad = [mat.SiO2().n(wl)]

        struct_xx = wg(n_sub, n_wg_xx, n_clad)
        struct_yy = wg(n_sub, n_wg_yy, n_clad)
        struct_zz = wg(n_sub, n_wg_zz, n_clad)

        struct_ani = stb.StructureAni(struct_xx, struct_yy, struct_zz)
        #struct_ani.write_to_file()

        solver = ms.ModeSolverFullyVectorial(4)
        solver.wg = struct_ani
        solver.solve()
        #solver.write_modes_to_file()

        if polarisation == 'TE':
            ngc.append(np.round(np.real(solver.n_effs_te), 4)[0])
        elif polarisation == 'TM':
            ngc.append(np.round(np.real(solver.n_effs_tm), 4)[0])

    #print(wl, dcs*ngc[0]+(1-dcs)*ngc[1])
    period = de.grating_coupler_period(wl, dcs*ngc[0]+(1-dcs)*ngc[1], n_clad[0], incidence_angle_deg=incidence_angle_deg, diffration_order=1)
    periods.append(period)
    wavelength2period[str(int(wl*1e3))] = period

filename = 'gc-sweep-%s-%inm-etch-%i-film.dat' % (polarisation, etch_depth*1000, film_thickness*1000)
np.savetxt(filename, np.array(periods).T, delimiter=',', header=','.join([str(val) for val in wls]))
#print(np.c_[periods])
[2]:
for w, p in wavelength2period.items():
    plt.plot(dcs, p, label=w)

plt.ylabel('period (um)')
plt.xlabel('duty cycle (%)')
plt.legend()
[2]:
<matplotlib.legend.Legend at 0x7fa0635c1850>
../_images/notebooks_31_sweep_grating_coupler_2_1.png
[ ]: