Source code for gdsfactory.components.grating_coupler_rectangular_arbitrary_slab

from __future__ import annotations

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_strip_to_slab150
from gdsfactory.typings import (
    ComponentSpec,
    CrossSectionSpec,
    Floats,
    LayerSpec,
)

_gaps = (0.2,) * 10
_widths = (0.5,) * 10


[docs] @gf.cell def grating_coupler_rectangular_arbitrary_slab( gaps: Floats = _gaps, widths: Floats = _widths, width_grating: float = 11.0, length_taper: float = 150.0, polarization: str = "te", wavelength: float = 1.55, taper: ComponentSpec = taper_strip_to_slab150, layer_slab: LayerSpec | None = "SLAB150", layer_grating: LayerSpec | None = None, slab_offset: float = 2.0, fiber_angle: float = 15, cross_section: CrossSectionSpec = "xs_sc", **kwargs, ) -> Component: r"""Grating coupler uniform (grating with rectangular shape not elliptical). Therefore it needs a longer taper. Grating teeth are straight instead of elliptical. Args: gaps: list of gaps. widths: list of widths. width_grating: um. length_taper: um. polarization: 'te' or 'tm'. wavelength: in um. taper: function. layer_slab: for pedestal. layer_grating: optional layer for the grating. Defaults to the cross_section main layer. slab_offset: from edge. fiber_angle: in degrees. cross_section: for input waveguide port. kwargs: cross_section settings. .. code:: side view fiber / / / / / / / / _|-|_|-|_|-|___ layer layer_slab | o1 ______________| top view _________ /| | | | | / | | | | | /taper_angle /_ _| | | | | wg_width | | | | | | \ | | | | | \ | | | | | \ | | | | | \|_|_|_|_| <--> taper_length """ xs = gf.get_cross_section(cross_section, **kwargs) wg_width = xs.width layer = layer_grating or xs.layer c = Component() taper = gf.get_component( taper, length=length_taper, width2=width_grating, width1=wg_width, w_slab2=width_grating + 2 * slab_offset, ) taper_ref = c << taper c.add_port(port=taper_ref.ports["o1"], name="o1") x0 = xi = taper_ref.xmax widths = gf.snap.snap_to_grid(widths) gaps = gf.snap.snap_to_grid(gaps) for width, gap in zip(widths, gaps): xi += gap + width / 2 cgrating = c.add_ref( rectangle( size=[width, width_grating], layer=layer, port_type=None, centered=True, ) ) cgrating.x = gf.snap.snap_to_grid(xi) cgrating.y = 0 xi += width / 2 if layer_slab: slab = c << rectangle( size=( gf.snap.snap_to_grid(xi - x0) + slab_offset, width_grating + 2 * slab_offset, ), layer=layer_slab, port_type=None, centered=True, ) slab.xmin = x0 xport = np.round((xi + length_taper) / 2, 3) c.add_port( name="o2", port_type=f"vertical_{polarization}", center=(xport, 0), orientation=0, width=width_grating, layer=layer, ) c.info["polarization"] = polarization c.info["wavelength"] = wavelength if fiber_angle is not None: c.info["fiber_angle"] = fiber_angle return c
if __name__ == "__main__": c = grating_coupler_rectangular_arbitrary_slab(slab_offset=2.0) print(c.ports) c.show(show_ports=True)