Source code for gdsfactory.components.dbr_tapered

from __future__ import annotations

import gdsfactory as gf
from gdsfactory import Component
from gdsfactory.snap import snap_to_grid2x
from gdsfactory.typings import CrossSectionSpec


def _generate_fins(
    c: Component,
    fin_size: tuple[float, float],
    taper_length: float,
    length: float,
    xs: CrossSectionSpec,
) -> Component:
    num_fins = xs.width // (2 * fin_size[1])
    x0, y0 = (
        0,
        -num_fins * (2 * fin_size[1]) / 2.0 + fin_size[1] / 2.0,
    )
    xend = 2 * taper_length + length

    for i in range(int(num_fins)):
        y = y0 + i * 2 * fin_size[1]
        rectangle_input = c << gf.components.rectangle(
            size=(fin_size[0], fin_size[1]),
            layer=xs.layer,
            centered=True,
            port_type=None,
            port_orientations=None,
        )
        rectangle_input.move(
            origin=(x0, y0),
            destination=(
                x0 + fin_size[0] / 2.0 - (2 * taper_length) / 2.0,
                y0 + y + fin_size[1] / 2.0,
            ),
        )
        c.absorb(rectangle_input)

        rectangle_output = c << rectangle_input.parent.copy()
        rectangle_output.move(
            origin=(x0, y0),
            destination=(
                xend - fin_size[0] / 2.0 - (2 * taper_length) / 2.0,
                y0 + y + fin_size[1] / 2.0,
            ),
        )
        c.absorb(rectangle_output)

    return c


[docs] @gf.cell def dbr_tapered( length: float = 10.0, period: float = 0.85, dc: float = 0.5, w1: float = 0.4, w2: float = 1.0, taper_length: float = 20.0, fins: bool = False, fin_size: tuple[float, float] = (0.2, 0.05), cross_section: CrossSectionSpec = "xs_sc", **kwargs, ) -> Component: """Distributed Bragg Reflector Cell class. Tapers the input straight to a periodic straight structure with varying width (1-D photonic crystal). Args: length: Length of the DBR region. period: Period of the repeated unit. dc: Duty cycle of the repeated unit (must be a float between 0 and 1.0). w1: thin section width. w1 = 0 corresponds to disconnected periodic blocks. w2: wide section width. taper_length: between the input/output straight and the DBR region. fins: If `True`, adds fins to the input/output straights. fin_size: Specifies the x- and y-size of the `fins`. Defaults to 200 nm x 50 nm cross_section: cross_section spec. Keyword Args: cross_section kwargs. .. code:: period <-----><--------> _________ _______| w1 w2 ... n times _______ |_________ """ c = gf.Component() xs = gf.get_cross_section(cross_section=cross_section, width=w2, **kwargs) xs1 = gf.get_cross_section(cross_section=cross_section, width=xs.width, **kwargs) xs2 = gf.get_cross_section(cross_section=cross_section, width=w1, **kwargs) input_taper = c << gf.components.taper( length=taper_length, width1=xs.width, width2=w1, cross_section=xs1 ) straight = c << gf.components.straight(length=length, cross_section=xs2) output_taper = c << gf.components.taper( length=taper_length, width1=w1, width2=xs.width, cross_section=xs1 ) input_taper.connect("o2", straight.ports["o1"]) output_taper.connect("o1", straight.ports["o2"]) num = (2 * taper_length + length) // period straight.move(straight.center, (0, 0)) input_taper.move(input_taper.center, (-length / 2 - taper_length / 2, 0)) output_taper.move(output_taper.center, (length / 2 + taper_length / 2, 0)) size = snap_to_grid2x((period * dc, w2)) teeth = gf.components.rectangle(size=size, layer=xs.layer) periodic_structures = c << gf.components.array(teeth, (period, 0), num) periodic_structures.move(periodic_structures.center, (0, 0)) if fins: _generate_fins(c, fin_size, taper_length, length, xs) c.absorb(input_taper) c.absorb(straight) c.absorb(output_taper) c.add_port("o1", port=input_taper.ports["o1"]) c.add_port("o2", port=output_taper.ports["o2"]) return c
if __name__ == "__main__": # c = dbr_tapered(length=10, period=0.85, dc=0.5, w2=1, w1=0.4, taper_length=20, fins=True) c = dbr_tapered(cross_section=gf.cross_section.rib) c.show(show_ports=True)