{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Sweep grating coupler period\n", "\n", "Grating coupler period depends on the wavelength, waveguide thickness, etch depth and fiber incidence angle \n", "\n", "Analytic calculation of the grating coupler period for various duty-cycles in SOI.\n", "\n", "Seems to match well with the periods in [Taillaert et al., _Grating Couplers for\n", "Coupling between Optical Fibers and Nanophotonic Waveguides_, IOP Science, 2006](http://iopscience.iop.org/article/10.1143/JJAP.45.6071/meta).\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import matplotlib.pyplot as plt\n", "import modes.design as de\n", "import modes._mode_solver_full_vectorial as ms\n", "import modes._structure as st\n", "import modes._structure_base as stb\n", "import opticalmaterialspy as mat\n", "\n", "wls = [1.50, 1.55, 1.60]\n", "x_step = 0.05\n", "y_step = 0.05\n", "etch_depth = 0.22\n", "width = 10\n", "sub_thickness = 0.5\n", "sub_width = 14.\n", "clad_thickness = [0.5]\n", "film_thickness = 0.22\n", "polarisation = 'TE'\n", "dcs = np.linspace(20, 80, 61) / 100\n", "incidence_angle_deg = 10\n", "\n", "ed1 = etch_depth\n", "ft1 = film_thickness\n", "ed2 = ft1 - ed1\n", "ft2 = ed2\n", "\n", "periods = []\n", "periods.append(dcs)\n", "\n", "wavelength2period = {}\n", "\n", "for wl in wls:\n", " ngc = []\n", " for thickness, film_thickness in [(ed1, ft1), (ed2, ft2)]:\n", " def wg(n_sub, n_wg, n_clad):\n", " return st.RidgeWaveguide(wavelength=wl, x_step=x_step, y_step=y_step, thickness=thickness, width=width,\n", " sub_thickness=sub_thickness, sub_width=sub_width, clad_thickness=clad_thickness,\n", " n_sub=n_sub, n_wg=n_wg, n_slab=None, angle=0, n_clad= n_clad, film_thickness=film_thickness)\n", "\n", " n_sub = mat.SiO2().n(wl)\n", " n_wg = mat.RefractiveIndexWeb('https://refractiveindex.info/?shelf=main&book=Si&page=Li-293K').n(wl)\n", " n_wg_xx = n_wg\n", " n_wg_yy = n_wg\n", " n_wg_zz = n_wg\n", " n_clad = [mat.SiO2().n(wl)]\n", " \n", " struct_xx = wg(n_sub, n_wg_xx, n_clad)\n", " struct_yy = wg(n_sub, n_wg_yy, n_clad)\n", " struct_zz = wg(n_sub, n_wg_zz, n_clad)\n", "\n", " struct_ani = stb.StructureAni(struct_xx, struct_yy, struct_zz)\n", " #struct_ani.write_to_file()\n", "\n", " solver = ms.ModeSolverFullyVectorial(4)\n", " solver.wg = struct_ani\n", " solver.solve()\n", " #solver.write_modes_to_file()\n", "\n", " if polarisation == 'TE':\n", " ngc.append(np.round(np.real(solver.n_effs_te), 4)[0])\n", " elif polarisation == 'TM':\n", " ngc.append(np.round(np.real(solver.n_effs_tm), 4)[0])\n", " \n", " #print(wl, dcs*ngc[0]+(1-dcs)*ngc[1])\n", " 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)\n", " periods.append(period)\n", " wavelength2period[str(int(wl*1e3))] = period\n", "\n", "filename = 'gc-sweep-%s-%inm-etch-%i-film.dat' % (polarisation, etch_depth*1000, film_thickness*1000)\n", "np.savetxt(filename, np.array(periods).T, delimiter=',', header=','.join([str(val) for val in wls]))\n", "#print(np.c_[periods])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "for w, p in wavelength2period.items():\n", " plt.plot(dcs, p, label=w)\n", "\n", "plt.ylabel('period (um)')\n", "plt.xlabel('duty cycle (%)')\n", "plt.legend()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.7" } }, "nbformat": 4, "nbformat_minor": 4 }