Source code for gdsfactory.components.grating_coupler_dual_pol

from __future__ import annotations

from functools import partial

import numpy as np

import gdsfactory as gf
from gdsfactory.component import Component
from gdsfactory.components.rectangle import rectangle
from gdsfactory.components.taper import taper as taper_function
from gdsfactory.typings import (
    ComponentSpec,
    CrossSectionSpec,
    LayerSpec,
)

rectangle_unit_cell = partial(
    rectangle, size=(0.3, 0.3), layer="SLAB150", centered=True, port_type=None
)


[docs] @gf.cell def grating_coupler_dual_pol( unit_cell: ComponentSpec = rectangle_unit_cell, period_x: float = 0.58, period_y: float = 0.58, x_span: float = 11, y_span: float = 11, length_taper: float = 150.0, width_taper: float = 10.0, polarization: str = "dual", wavelength: float = 1.55, taper: ComponentSpec = taper_function, base_layer: LayerSpec | None = "WG", cross_section: CrossSectionSpec = "xs_sc", **kwargs, ) -> Component: r"""2 dimensional, dual polarization grating coupler. Based on a photonic crystal with a unit cell that is usually an ellipse, a rectangle or a circle. The default values are loosely based on Taillaert et al, "A Compact Two-Dimensional Grating Coupler Used as a Polarization Splitter", IEEE Phot. Techn. Lett. 15(9), 2003 Args: unit_cell: component describing the unit cell of the photonic crystal. period_x: spacing between unit cells in the x direction [um]. period_y: spacing between unit cells in the y direction [um]. x_span: full x span of the photonic crystal. y_span: full y span of the photonic crystal. length_taper: taper length [um]. width_taper: width of the taper at the grating coupler side [um]. polarization: polarization of the grating coupler. wavelength: operation wavelength [um] taper: function to generate the tapers. base_layer: layer to draw over the whole photonic crystal \ (necessary if the unit cells are etched into a base layer). cross_section: for the routing waveguides. kwargs: cross_section settings. .. code:: side view fiber / / / / / / / / _|-|_|-|_|-|___ --> unit_cells base_layer | o1 ______________| top view ------------- // | o o o | o1 __ // | o o o | \\ | o o o | \\ | o o o | ------------- \\ // \\ // | o2 """ xs = gf.get_cross_section(cross_section, **kwargs) wg_width = xs.width layer = xs.layer c = Component() _ = c << rectangle( size=(x_span, y_span), layer=base_layer, centered=True, port_type=None ) # Photonic crystal num_x = int(np.floor(x_span / period_x)) num_y = int(np.floor(y_span / period_y)) x_start = -(num_x * period_x) / 2 y_start = -(num_y * period_y) / 2 x_end = -x_start y_end = -y_start x = np.linspace(x_start, x_end, num_x) y = np.linspace(y_start, y_end, num_y) xpos, ypos = np.meshgrid(x, y) for x, y in zip(xpos.flatten(), ypos.flatten()): un_cell = c << unit_cell() un_cell.x = gf.snap.snap_to_grid(x) un_cell.y = gf.snap.snap_to_grid(y) port_type = f"vertical_{polarization.lower()}" c.add_port( name=port_type, port_type=port_type, center=(0, 0), orientation=0, width=x_span, layer=layer, ) c.info["polarization"] = polarization c.info["wavelength"] = wavelength # First taper taper1 = c << gf.get_component( taper, length=length_taper, width2=width_taper, width1=wg_width, cross_section=xs, ) taper1.xmax = -x_span / 2 taper1.y = 0 c.add_port(port=taper1.ports["o1"], name="o1") # Second taper taper2 = c << gf.get_component( taper, length=length_taper, width2=width_taper, width1=wg_width, cross_section=xs, ) taper2.rotate(90) taper2.x = 0 taper2.ymax = -y_span / 2 c.add_port(port=taper2.ports["o1"], name="o2") return c
if __name__ == "__main__": c = grating_coupler_dual_pol() c.show(show_ports=True)