Exemple #1
0
def spiral_external_io(N: int = 6,
                       x_inner_length_cutback: float = 300.0,
                       x_inner_offset: float = 0.0,
                       y_straight_inner_top: float = 0.0,
                       dx: float = 3.0,
                       dy: float = 3.0,
                       bend90_function: Callable = bend_circular,
                       bend180_function: Callable = bend_circular180,
                       bend_radius: float = 50.0,
                       wg_width: float = 0.5,
                       straight_factory: Callable = waveguide,
                       straight_factory_fall_back_no_taper: None = None,
                       taper: Optional[Callable] = None,
                       cutback_length: Optional[float] = None,
                       **kwargs_round_corner) -> Component:
    """

    Args:
        cutback_length: length in um, it is the approximates total length
        N: number of loops
        x_straight_inner_right:
        x_straight_inner_left:
        y_straight_inner_top:
        dx: center to center x-spacing
        dy: center to center y-spacing
        grating_coupler
        bend90_function
        bend180_function
        bend_radius
        wg_width
        straight_factory
        taper

    .. plot::
      :include-source:

      import pp

      c = pp.c.spiral_external_io()
      pp.plotgds(c)
    """
    if straight_factory_fall_back_no_taper is None:
        straight_factory_fall_back_no_taper = straight_factory

    if cutback_length:
        x_inner_length_cutback = cutback_length / (4 * (N - 1))

    y_straight_inner_top += 5

    x_inner_length_cutback += x_inner_offset
    _bend180 = pp.call_if_func(bend180_function,
                               radius=bend_radius,
                               width=wg_width)
    _bend90 = pp.call_if_func(bend90_function,
                              radius=bend_radius,
                              width=wg_width)

    rx, ry = get_bend_port_distances(_bend90)
    _, rx180 = get_bend_port_distances(
        _bend180)  # rx180, second arg since we rotate

    component = pp.Component()

    inner_loop_spacing = 2 * bend_radius + 5.0

    # Create manhattan path going from west grating to westest port of bend 180

    x_inner_length = x_inner_length_cutback + 5.0 + dx

    y_inner_bend = y_straight_inner_top - bend_radius - 5.0
    x_inner_loop = x_inner_length - 5.0
    p1 = (x_inner_loop, y_inner_bend)
    p2 = (x_inner_loop + inner_loop_spacing, y_inner_bend)

    _pt = np.array(p1)
    pts_w = [_pt]

    for i in range(N):
        y1 = y_straight_inner_top + ry + (2 * i + 1) * dy
        x2 = inner_loop_spacing + 2 * rx + x_inner_length + (2 * i + 1) * dx
        y3 = -ry - (2 * i + 2) * dy
        x4 = -(2 * i + 1) * dx
        if i == N - 1:
            x4 = x4 - rx180 + dx

        _pt1 = np.array([_pt[0], y1])
        _pt2 = np.array([x2, _pt1[1]])
        _pt3 = np.array([_pt2[0], y3])
        _pt4 = np.array([x4, _pt3[1]])
        _pt5 = np.array([_pt4[0], 0])
        _pt = _pt5

        pts_w += [_pt1, _pt2, _pt3, _pt4, _pt5]

    pts_w = pts_w[:-2]

    # Create manhattan path going from east grating to eastest port of bend 180
    _pt = np.array(p2)
    pts_e = [_pt]

    for i in range(N):
        y1 = y_straight_inner_top + ry + (2 * i) * dy
        x2 = inner_loop_spacing + 2 * rx + x_inner_length + 2 * i * dx
        y3 = -ry - (2 * i + 1) * dy
        x4 = -2 * i * dx

        _pt1 = np.array([_pt[0], y1])
        _pt2 = np.array([x2, _pt1[1]])
        _pt3 = np.array([_pt2[0], y3])
        _pt4 = np.array([x4, _pt3[1]])
        _pt5 = np.array([_pt4[0], 0])
        _pt = _pt5

        pts_e += [_pt1, _pt2, _pt3, _pt4, _pt5]

    pts_e = pts_e[:-2]

    # Join the two bits of paths and extrude the spiral geometry
    route = round_corners(
        pts_w[::-1] + pts_e,
        bend90=_bend90,
        straight_factory=straight_factory,
        straight_factory_fall_back_no_taper=straight_factory_fall_back_no_taper,
        taper=taper,
        **kwargs_round_corner,
    )

    component.add(route["references"])
    component.ports = route["ports"]

    length = route["settings"]["length"]
    component.length = length
    return component
Exemple #2
0
def spiral_inner_io(
    N: int = 6,
    x_straight_inner_right: float = 150.0,
    x_straight_inner_left: float = 150.0,
    y_straight_inner_top: float = 50.0,
    y_straight_inner_bottom: float = 10.0,
    grating_spacing: float = 127.0,
    dx: float = 3.0,
    dy: float = 3.0,
    bend90_function: Callable = bend_circular,
    bend180_function: Callable = bend_circular180,
    bend_radius: float = 50.0,
    wg_width: float = 0.5,
    wg_width_grating_coupler: float = 0.5,
    straight_factory: Callable = waveguide,
    taper: Optional[Callable] = None,
    length: Optional[float] = None,
) -> Component:
    """Spiral with ports inside the spiral circle.

    Args:
        N: number of loops
        x_straight_inner_right:
        x_straight_inner_left:
        y_straight_inner_top:
        y_straight_inner_bottom:
        grating_spacing:
        dx: center to center x-spacing
        dy: center to center y-spacing
        bend90_function
        bend180_function
        bend_radius
        wg_width
        straight_factory
        taper:
        length: cm

    .. plot::
      :include-source:

      import pp
      from pp.components.spiral_inner_io import spiral_inner_io

      c = spiral_inner_io()
      pp.plotgds(c)
    """
    if length:
        if bend180_function == bend_circular180:
            y_straight_inner_top = get_straight_length(
                length_cm=length,
                spiral_function=spiral_inner_io,
                N=N,
                x_straight_inner_right=x_straight_inner_right,
                x_straight_inner_left=x_straight_inner_left,
                y_straight_inner_top=y_straight_inner_top,
                y_straight_inner_bottom=y_straight_inner_bottom,
                grating_spacing=grating_spacing,
                dx=dx,
                dy=dy,
                straight_factory=waveguide,
                bend90_function=bend_euler90,
                bend180_function=bend_euler180,
                wg_width=wg_width,
            )
        else:
            y_straight_inner_top = get_straight_length(
                length_cm=length,
                spiral_function=spiral_inner_io_euler,
                N=N,
                x_straight_inner_right=x_straight_inner_right,
                x_straight_inner_left=x_straight_inner_left,
                y_straight_inner_top=y_straight_inner_top,
                y_straight_inner_bottom=y_straight_inner_bottom,
                grating_spacing=grating_spacing,
                dx=dx,
                dy=dy,
                wg_width=wg_width,
            )

    _bend180 = pp.call_if_func(bend180_function, radius=bend_radius, width=wg_width)
    _bend90 = pp.call_if_func(bend90_function, radius=bend_radius, width=wg_width)

    rx, ry = get_bend_port_distances(_bend90)
    _, rx180 = get_bend_port_distances(_bend180)  # rx180, second arg since we rotate

    component = pp.Component()
    # gc_port_lbl = "W0"
    # gc1 = _gc.ref(port_id=gc_port_lbl, position=(0, 0), rotation=-90)
    # gc2 = _gc.ref(port_id=gc_port_lbl, position=(grating_spacing, 0), rotation=-90)
    # component.add([gc1, gc2])

    p1 = pp.Port(
        name="S0",
        midpoint=(0, y_straight_inner_top),
        orientation=270,
        width=wg_width,
        layer=pp.LAYER.WG,
    )
    p2 = pp.Port(
        name="S1",
        midpoint=(grating_spacing, y_straight_inner_top),
        orientation=270,
        width=wg_width,
        layer=pp.LAYER.WG,
    )
    taper = pp.c.taper(
        width1=wg_width_grating_coupler,
        width2=_bend180.ports["W0"].width,
        length=TAPER_LENGTH + y_straight_inner_top - 15 - 35,
    )
    taper_ref1 = component.add_ref(taper)
    taper_ref1.connect("2", p1)

    taper_ref2 = component.add_ref(taper)
    taper_ref2.connect("2", p2)

    component.absorb(taper_ref1)
    component.absorb(taper_ref2)

    component.add_port(name="S0", port=taper_ref1.ports["1"])
    component.add_port(name="S1", port=taper_ref2.ports["1"])

    # Create manhattan path going from west grating to westest port of bend 180
    _pt = np.array(p1.position)
    pts_w = [_pt]

    for i in range(N):
        y1 = y_straight_inner_top + ry + (2 * i + 1) * dy
        x2 = grating_spacing + 2 * rx + x_straight_inner_right + (2 * i + 1) * dx
        y3 = -y_straight_inner_bottom - ry - (2 * i + 3) * dy
        x4 = -x_straight_inner_left - (2 * i + 1) * dx
        if i == N - 1:
            x4 = x4 - rx180 + dx

        _pt1 = np.array([_pt[0], y1])
        _pt2 = np.array([x2, _pt1[1]])
        _pt3 = np.array([_pt2[0], y3])
        _pt4 = np.array([x4, _pt3[1]])
        _pt5 = np.array([_pt4[0], 0])
        _pt = _pt5

        pts_w += [_pt1, _pt2, _pt3, _pt4, _pt5]

    route_west = round_corners(
        pts_w, bend90=_bend90, straight_factory=straight_factory, taper=taper
    )
    component.add(route_west["references"])

    # Add loop back
    bend180_ref = _bend180.ref(
        port_id="W1", position=route_west["ports"]["output"], rotation=90
    )
    component.add(bend180_ref)
    component.absorb(bend180_ref)

    # Create manhattan path going from east grating to eastest port of bend 180
    _pt = np.array(p2.position)
    pts_e = [_pt]

    for i in range(N):
        y1 = y_straight_inner_top + ry + (2 * i) * dy
        x2 = grating_spacing + 2 * rx + x_straight_inner_right + 2 * i * dx
        y3 = -y_straight_inner_bottom - ry - (2 * i + 2) * dy
        x4 = -x_straight_inner_left - (2 * i) * dx

        _pt1 = np.array([_pt[0], y1])
        _pt2 = np.array([x2, _pt1[1]])
        _pt3 = np.array([_pt2[0], y3])
        _pt4 = np.array([x4, _pt3[1]])
        _pt5 = np.array([_pt4[0], 0])
        _pt = _pt5

        pts_e += [_pt1, _pt2, _pt3, _pt4, _pt5]

    route_east = round_corners(
        pts_e, bend90=_bend90, straight_factory=straight_factory, taper=taper
    )
    component.add(route_east["references"])

    length = (
        route_east["settings"]["length"]
        + route_west["settings"]["length"]
        + bend180_ref.info["length"]
    )
    component.length = pp.drc.snap_to_1nm_grid(length + 2 * y_straight_inner_top)
    return component