{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Bragg grating sections\n", "\n", "Bragg gratings are often used in waveguides, such as optical fibres, which can reflect light of certain frequencies while transmitting others. This is typically achieved by periodically changing the refractive index or dielectric constant in a section of the waveguide, and the reflective and transmitting frequency bands are controlled by appropriately designing the periodicity and material or geometry parameters of the grating.\n", "\n", "In this example, sections of two Bragg gratings will be simulated. The first one involves a waveguide with a perfectly-aligned corrugation on either side, which causes it to act as a reflector. The second one is similar, but with the corrugation on one side misaligned with the corrugation on the other side, so that the structure primarily transmits power.\n", "\n", "Reference: Xu Wang, Yun Wang, Jonas Flueckiger, Richard Bojko, Amy Liu, Adam Reid, James Pond, Nicolas A. F. Jaeger, and Lukas Chrostowski, \"Precise control of the coupling coefficient through destructive interference in silicon waveguide Bragg gratings,\" Opt. Lett. 39, 5519-5522 (2014)" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "execution": { "iopub.execute_input": "2023-02-03T04:19:53.377108Z", "iopub.status.busy": "2023-02-03T04:19:53.376822Z", "iopub.status.idle": "2023-02-03T04:19:54.314612Z", "shell.execute_reply": "2023-02-03T04:19:54.314202Z" }, "tags": [] }, "outputs": [ { "data": { "text/html": [ "
[22:19:54] WARNING This version of Tidy3D was pip installed from the 'tidy3d-beta' repository on __init__.py:103\n", " PyPI. Future releases will be uploaded to the 'tidy3d' repository. From now on, \n", " please use 'pip install tidy3d' instead. \n", "\n" ], "text/plain": [ "\u001b[2;36m[22:19:54]\u001b[0m\u001b[2;36m \u001b[0m\u001b[31mWARNING \u001b[0m This version of Tidy3D was pip installed from the \u001b[32m'tidy3d-beta'\u001b[0m repository on \u001b]8;id=957;file:///Users/twhughes/Documents/Flexcompute/tidy3d-docs/tidy3d/tidy3d/__init__.py\u001b\\\u001b[2m__init__.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=898659;file:///Users/twhughes/Documents/Flexcompute/tidy3d-docs/tidy3d/tidy3d/__init__.py#103\u001b\\\u001b[2m103\u001b[0m\u001b]8;;\u001b\\\n", "\u001b[2;36m \u001b[0m PyPI. Future releases will be uploaded to the \u001b[32m'tidy3d'\u001b[0m repository. From now on, \u001b[2m \u001b[0m\n", "\u001b[2;36m \u001b[0m please use \u001b[32m'pip install tidy3d'\u001b[0m instead. \u001b[2m \u001b[0m\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
INFO Using client version: 1.9.0rc1 __init__.py:121\n", "\n" ], "text/plain": [ "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m Using client version: \u001b[1;36m1.9\u001b[0m.0rc1 \u001b]8;id=613179;file:///Users/twhughes/Documents/Flexcompute/tidy3d-docs/tidy3d/tidy3d/__init__.py\u001b\\\u001b[2m__init__.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=24768;file:///Users/twhughes/Documents/Flexcompute/tidy3d-docs/tidy3d/tidy3d/__init__.py#121\u001b\\\u001b[2m121\u001b[0m\u001b]8;;\u001b\\\n" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# basic imports\n", "import numpy as np\n", "import matplotlib.pylab as plt\n", "\n", "# tidy3d imports\n", "import tidy3d as td\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Structure Setup\n", "\n", "First, the geometry of the structure is defined. Both waveguides are set up in the same simulation side-by-side." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "execution": { "iopub.execute_input": "2023-02-03T04:19:54.316948Z", "iopub.status.busy": "2023-02-03T04:19:54.316725Z", "iopub.status.idle": "2023-02-03T04:19:54.335904Z", "shell.execute_reply": "2023-02-03T04:19:54.335504Z" }, "tags": [] }, "outputs": [], "source": [ "# materials\n", "Air = td.Medium(permittivity=1.0)\n", "Si = td.Medium(permittivity=3.47**2)\n", "SiO2 = td.Medium(permittivity=1.44**2)\n", "# SiO2 = td.material_library['SiO2']['Horiba']\n", "\n", "# set basic geometric parameters\n", "wg_height = 0.22\n", "wg_feed_length = 0.75\n", "wg_feed_width = 0.5\n", "corrug_width = 0.05\n", "num_periods = 50\n", "period = 0.324\n", "\n", "shift = period / 2\n", "corrug_length = period / 2\n", "wg_length = num_periods * period\n", "wg_width = wg_feed_width - corrug_width\n", "\n", "wavelength0 = 1.532\n", "freq0 = td.C_0 / wavelength0\n", "fwidth = freq0 / 40.0\n", "run_time = 1250e-15\n", "wavelength_min = td.C_0 / (freq0 + fwidth)\n", "\n", "# place the two waveguides so that their centres are half a free-space wavelength apart\n", "wg1_y = wavelength0 / 2\n", "wg2_y = -wavelength0 / 2\n", "wg_separation = wavelength0 / 2\n", "\n", "# small buffer added to structures so they extend into the PML a bit\n", "pml_buffer = period\n", "\n", "# waveguide 1\n", "wg1_size = [wg_length + pml_buffer, wg_width, wg_height]\n", "wg1_center = [0, wg1_y, wg_height / 2]\n", "wg1_medium = Si\n", "\n", "# waveguide 2\n", "wg2_size = [wg_length + pml_buffer, wg_width, wg_height]\n", "wg2_center = [0, wg2_y, wg_height / 2]\n", "wg2_medium = Si\n", "\n", "# corrugation setup for waveguide 1\n", "cg1_size = [corrug_length, corrug_width, wg_height]\n", "cg1_center_plus = [\n", " -wg_length / 2 + corrug_length / 2,\n", " wg_width / 2 + corrug_width / 2 + wg1_y,\n", " wg_height / 2,\n", "]\n", "cg1_center_minus = [\n", " -wg_length / 2 + corrug_length / 2,\n", " -wg_width / 2 - corrug_width / 2 + wg1_y,\n", " wg_height / 2,\n", "]\n", "cg1_medium = Si\n", "\n", "# corrugation setup for waveguide 2\n", "cg2_size = [corrug_length, corrug_width, wg_height]\n", "cg2_center_plus = [\n", " -wg_length / 2 + corrug_length / 2,\n", " wg_width / 2 + corrug_width / 2 + wg2_y,\n", " wg_height / 2,\n", "]\n", "cg2_center_minus = [\n", " -wg_length / 2 + corrug_length / 2 + shift,\n", " -wg_width / 2 - corrug_width / 2 + wg2_y,\n", " wg_height / 2,\n", "]\n", "cg2_medium = Si\n", "\n", "# substrate\n", "sub_size = [td.inf, td.inf, 2]\n", "sub_center = [0, 0, -1.0]\n", "sub_medium = SiO2\n", "\n", "# create the substrate\n", "substrate = td.Structure(\n", " geometry=td.Box(center=sub_center, size=sub_size),\n", " medium=sub_medium,\n", " name=\"substrate\",\n", ")\n", "\n", "# create the first waveguide\n", "waveguide_1 = td.Structure(\n", " geometry=td.Box(center=wg1_center, size=wg1_size),\n", " medium=wg1_medium,\n", " name=\"waveguide_1\",\n", ")\n", "\n", "# create the second waveguide\n", "waveguide_2 = td.Structure(\n", " geometry=td.Box(center=wg2_center, size=wg2_size),\n", " medium=wg2_medium,\n", " name=\"waveguide_2\",\n", ")\n", "\n", "# create the corrugation for the first waveguide\n", "corrug1_plus = []\n", "corrug1_minus = []\n", "for i in range(num_periods):\n", " # corrugation on the +y side\n", " center = cg1_center_plus\n", " if i > 0:\n", " center[0] += period\n", " plus = td.Structure(\n", " geometry=td.Box(center=center, size=cg1_size),\n", " medium=cg1_medium,\n", " name=f\"corrug1_plus_{i}\",\n", " )\n", "\n", " # corrugation on the -y side\n", " center = cg1_center_minus\n", " if i > 0:\n", " center[0] += period\n", " minus = td.Structure(\n", " geometry=td.Box(center=center, size=cg1_size),\n", " medium=cg1_medium,\n", " name=f\"corrug1_minus_{i}\",\n", " )\n", "\n", " corrug1_plus.append(plus)\n", " corrug1_minus.append(minus)\n", "\n", "# create the corrugation for the second waveguide\n", "corrug2_plus = []\n", "corrug2_minus = []\n", "for i in range(num_periods):\n", " # corrugation on the +y side\n", " center = cg2_center_plus\n", " if i > 0:\n", " center[0] += period\n", " plus = td.Structure(\n", " geometry=td.Box(center=center, size=cg2_size),\n", " medium=cg2_medium,\n", " name=f\"corrug2_plus_{i}\",\n", " )\n", "\n", " # corrugation on the -y side\n", " center = cg2_center_minus\n", " if i > 0:\n", " center[0] += period\n", " minus = td.Structure(\n", " geometry=td.Box(center=center, size=cg2_size),\n", " medium=cg2_medium,\n", " name=f\"corrug2_minus_{i}\",\n", " )\n", "\n", " corrug2_plus.append(plus)\n", " corrug2_minus.append(minus)\n", "\n", "# full simulation domain\n", "sim_size = [\n", " wg_length + wavelength0 * 1.5,\n", " 2 * wavelength0 + wg_width + 2 * corrug_width,\n", " 3.7,\n", "]\n", "sim_center = [0, 0, 0.0]\n", "\n", "# boundary conditions - Bloch boundaries are used to emulate an infinitely long grating\n", "boundary_spec = td.BoundarySpec(\n", " # x=td.Boundary.bloch(bloch_vec=num_periods/2),\n", " x=td.Boundary.pml(),\n", " y=td.Boundary.pml(),\n", " z=td.Boundary.pml(),\n", ")\n", "\n", "# grid specification\n", "grid_spec = td.GridSpec.auto(min_steps_per_wvl=20)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Source Setup\n", "\n", "A mode source is defined for each waveguide." ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "execution": { "iopub.execute_input": "2023-02-03T04:19:54.338067Z", "iopub.status.busy": "2023-02-03T04:19:54.337906Z", "iopub.status.idle": "2023-02-03T04:19:54.341922Z", "shell.execute_reply": "2023-02-03T04:19:54.341557Z" }, "tags": [] }, "outputs": [], "source": [ "# mode source for waveguide 1\n", "source1_time = td.GaussianPulse(freq0=freq0, fwidth=fwidth, amplitude=1)\n", "mode_src1 = td.ModeSource(\n", " center=[-wg_length / 2 + period, wg1_y, wg_height / 2],\n", " size=[0, waveguide_1.geometry.size[1] * 2, waveguide_1.geometry.size[2] * 2],\n", " mode_index=0,\n", " direction=\"+\",\n", " source_time=source1_time,\n", " mode_spec=td.ModeSpec(),\n", ")\n", "\n", "# mode source for waveguide 2\n", "source2_time = td.GaussianPulse(freq0=freq0, fwidth=fwidth, amplitude=1)\n", "mode_src2 = td.ModeSource(\n", " center=[-wg_length / 2 + period, wg2_y, wg_height / 2],\n", " size=[0, waveguide_2.geometry.size[1] * 2, waveguide_2.geometry.size[2] * 2],\n", " mode_index=0,\n", " direction=\"+\",\n", " source_time=source2_time,\n", " mode_spec=td.ModeSpec(),\n", ")\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Monitor Setup\n", "\n", "To visualize the field distribution in the waveguides, a monitor is placed in the `xy` plane cutting through both waveguides. A pair of flux monitors is also placed on the far side the demonstrate the transmission and reflection characteristics." ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "execution": { "iopub.execute_input": "2023-02-03T04:19:54.343954Z", "iopub.status.busy": "2023-02-03T04:19:54.343818Z", "iopub.status.idle": "2023-02-03T04:19:54.348185Z", "shell.execute_reply": "2023-02-03T04:19:54.347820Z" } }, "outputs": [], "source": [ "# create monitors\n", "monitor_xy = td.FieldMonitor(\n", " center=[0, 0, wg_height / 2],\n", " size=[wg_length, 2 * wavelength0 + wg_width + 2 * corrug_width, 0],\n", " freqs=[freq0],\n", " name=\"fields_xy\",\n", ")\n", "\n", "freqs = np.linspace(freq0 - 2 * fwidth, freq0 + 2 * fwidth, 200)\n", "monitor_flux_aligned = td.FluxMonitor(\n", " center=[wg_length / 2 - period, wg1_y, wg_height / 2],\n", " size=[0, waveguide_1.geometry.size[1] * 2, waveguide_1.geometry.size[2] * 2],\n", " freqs=freqs,\n", " name=\"flux_aligned\",\n", ")\n", "\n", "monitor_flux_misaligned = td.FluxMonitor(\n", " center=[wg_length / 2 - period, wg2_y, wg_height / 2],\n", " size=[0, waveguide_2.geometry.size[1] * 2, waveguide_2.geometry.size[2] * 2],\n", " freqs=freqs,\n", " name=\"flux_misaligned\",\n", ")\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Create Simulation\n", "\n", "All the structures, sources, and monitors are consolidated, and the simulation is created and visualized." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "execution": { "iopub.execute_input": "2023-02-03T04:19:54.350150Z", "iopub.status.busy": "2023-02-03T04:19:54.349976Z", "iopub.status.idle": "2023-02-03T04:19:54.890700Z", "shell.execute_reply": "2023-02-03T04:19:54.890325Z" } }, "outputs": [ { "data": { "text/html": [ "
INFO Auto meshing using wavelength 1.5320 defined from sources. grid_spec.py:510\n", "\n" ], "text/plain": [ "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m Auto meshing using wavelength \u001b[1;36m1.5320\u001b[0m defined from sources. \u001b]8;id=743765;file:///Users/twhughes/Documents/Flexcompute/tidy3d-docs/tidy3d/tidy3d/components/grid/grid_spec.py\u001b\\\u001b[2mgrid_spec.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=73978;file:///Users/twhughes/Documents/Flexcompute/tidy3d-docs/tidy3d/tidy3d/components/grid/grid_spec.py#510\u001b\\\u001b[2m510\u001b[0m\u001b]8;;\u001b\\\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "