Ejemplo n.º 1
0
def coupler90(
    bend_radius=10.0,
    width=0.5,
    gap=0.2,
    waveguide_factory=waveguide,
    bend90_factory=bend_circular,
):
    """ Waveguide coupled to a bend with gap

    Args:
        bend_radius: um
        width: waveguide width (um)
        gap: um

    .. plot::
      :include-source:

      import pp
      c = pp.c.coupler90()
      pp.plotgds(c)

    """
    # pp.drc.assert_on_1nm_grid((width + gap) / 2)
    y = pp.drc.snap_to_1nm_grid((width + gap) / 2)

    c = Component()

    wg = c << waveguide_factory(length=bend_radius, width=width)
    bend = c << bend90_factory(radius=bend_radius, width=width)

    pbw = bend.ports["W0"]
    bend.movey(pbw.midpoint[1] + gap + width)

    # This component is a leaf cell => using absorb
    c.absorb(wg)
    c.absorb(bend)

    port_width = 2 * width + gap

    c.add_port(port=wg.ports["E0"], name="E0")
    c.add_port(port=bend.ports["N0"], name="N0")
    c.add_port(name="W0", midpoint=[0, y], width=port_width, orientation=180)
    return c
Ejemplo n.º 2
0
def wg_heater_connected(
    waveguide_heater=waveguide_heater,
    wg_heater_connector=wg_heater_connector,
    tlm_layers=[
        LAYER.VIA1, LAYER.M1, LAYER.VIA2, LAYER.M2, LAYER.VIA3, LAYER.M3
    ],
    **kwargs,
):
    """
    .. plot::
      :include-source:

      import pp

      c = pp.c.wg_heater_connected()
      pp.plotgds(c)

    """
    wg_heater = waveguide_heater(**kwargs)
    conn1 = wg_heater_connector(
        heater_ports=[wg_heater.ports["E0"], wg_heater.ports["E2"]],
        tlm_layers=tlm_layers,
    )

    conn2 = wg_heater_connector(
        heater_ports=[wg_heater.ports["W0"], wg_heater.ports["W2"]],
        tlm_layers=tlm_layers,
    )

    cmp = Component()
    for c in [wg_heater, conn1, conn2]:
        _c = cmp.add_ref(c)
        cmp.absorb(_c)

    for i, p in enumerate(wg_heater.get_optical_ports()):
        cmp.add_port(name=i, port=p)

    i += 1
    cmp.add_port(name=i, port=conn1.ports["0"])
    i += 1
    cmp.add_port(name=i, port=conn2.ports["0"])

    return cmp
Ejemplo n.º 3
0
def coupler90(
    bend_radius=10.0,
    width=0.5,
    gap=0.2,
    waveguide_factory=waveguide,
    bend90_factory=bend_circular,
):
    """ Waveguide coupled to a bend with gap

    Args:
        bend_radius: um
        width: waveguide width (um)
        gap: um

    .. plot::
      :include-source:

      import pp
      c = pp.c.coupler90()
      pp.plotgds(c)

    """
    y = width + gap
    _bend = bend90_factory(radius=bend_radius, width=width).ref((0, y))
    c = Component()

    _wg = c.add_ref(waveguide_factory(length=bend_radius, width=width))
    c.add(_bend)

    # This component is a leaf cell => using absorb
    c.absorb(_wg)
    c.absorb(_bend)

    port_width = 2 * width + gap

    c.add_port(port=_wg.ports["E0"], name="E0")
    c.add_port(port=_bend.ports["N0"], name="N0")
    c.add_port(name="W0", midpoint=[0, y / 2], width=port_width, orientation=180)
    c.y = y
    return c
Ejemplo n.º 4
0
def waveguide_heater(
    length=10.0,
    width=0.5,
    heater_width=0.5,
    heater_spacing=1.2,
    metal_connection=True,
    sstw=2.0,
    trench_width=0.5,
    trench_keep_out=2.0,
    trenches=[
        {
            "nb_segments": 2,
            "lane": 1,
            "x_start_offset": 0
        },
        {
            "nb_segments": 2,
            "lane": -1,
            "x_start_offset": 0
        },
    ],
    layers_heater=[LAYER.HEATER],
    waveguide_factory=waveguide,
    layer_trench=LAYER.DEEPTRENCH,
):
    """ waveguide with heater

    .. code::
    
        TTTTTTTTTTTTT    TTTTTTTTTTTTT <-- trench
        
        HHHHHHHHHHHHHHHHHHHHHHHHHHHHHH <-- heater
        
        ------------------------------ <-- waveguide

        HHHHHHHHHHHHHHHHHHHHHHHHHHHHHH <-- heater
        
        TTTTTTTTTTTTT    TTTTTTTTTTTTT <-- trench

    .. plot::
      :include-source:

      import pp

      c = pp.c.waveguide_heater()
      pp.plotgds(c)
    
    """
    c = Component()

    _heater = heater(length=length,
                     width=heater_width,
                     layers_heater=layers_heater)

    y_heater = heater_spacing + (width + heater_width) / 2
    heater_top = c << _heater
    heater_bot = c << _heater

    heater_top.movey(+y_heater)
    heater_bot.movey(-y_heater)

    wg = c << waveguide_factory(length=length, width=width)

    for i in [heater_top, heater_bot, wg]:
        c.absorb(i)

    # Add wg ports
    for p in wg.ports.values():
        c.add_port(name=p.name, port=p)

    # Add heater ports
    for p in heater_top.ports.values():
        c.add_port(name="HT" + p.name, port=p)

    for p in heater_bot.ports.values():
        c.add_port(name="HB" + p.name, port=p)

    c.settings["width"] = width
    c.settings["heater_width"] = heater_width
    c.settings["heater_spacing"] = heater_spacing
    c.settings["length"] = length
    add_trenches(c,
                 sstw,
                 trench_width,
                 trench_keep_out,
                 trenches,
                 layer_trench=layer_trench)

    return c
Ejemplo n.º 5
0
def _bend_circular_heater(
    radius=10,
    wg_width=0.5,
    theta=-90,
    start_angle=0,
    angle_resolution=2.5,
    heater_to_wg_distance=1.2,
    heater_width=0.5,
):
    """ Creates an arc of arclength ``theta`` starting at angle ``start_angle``

    Args:
        radius
        width: of the waveguide
        theta: arc length
        start_angle:
        angle_resolution
    """
    component = Component()

    wg_bend = bend_circular(
        radius=radius,
        width=wg_width,
        theta=theta,
        start_angle=start_angle,
        angle_resolution=angle_resolution,
        layer=LAYER.WG,
    ).ref((0, 0))

    a = heater_to_wg_distance + wg_width / 2 + heater_width / 2

    heater_outer = bend_circular(
        radius=radius + a,
        width=heater_width,
        theta=theta,
        start_angle=start_angle,
        angle_resolution=angle_resolution,
        layer=LAYER.HEATER,
    ).ref((0, -a))

    heater_inner = bend_circular(
        radius=radius - a,
        width=heater_width,
        theta=theta,
        start_angle=start_angle,
        angle_resolution=angle_resolution,
        layer=LAYER.HEATER,
    ).ref((0, a))

    component.add(wg_bend)
    component.add(heater_outer)
    component.add(heater_inner)

    component.absorb(wg_bend)
    component.absorb(heater_outer)
    component.absorb(heater_inner)

    i = 0

    for device in [wg_bend, heater_outer, heater_inner]:
        for port in device.ports.values():
            component.ports["{}".format(i)] = port
            i += 1

    component.info["length"] = wg_bend.info["length"]
    component.radius = radius
    component.width = wg_width
    return component