Ejemplo n.º 1
0
def ring_single_dut(component=taper2,
                    wg_width=0.5,
                    gap=0.2,
                    length_x=4,
                    radius=5,
                    length_y=0,
                    coupler=coupler_ring,
                    straight=straight_function,
                    bend=bend_euler,
                    with_component=True,
                    **kwargs):
    """Single bus ring made of two couplers (ct: top, cb: bottom)
    connected with two vertical straights (wyl: left, wyr: right)
    (Device Under Test) in the middle to extract loss from quality factor


    Args:
        with_component: if False changes component for just a straight

    .. code::

          bl-wt-br
          |      | length_y
          wl     component
          |      |
         --==cb==-- gap

          length_x
    """
    component = call_if_func(component)
    assert_on_2nm_grid(gap)

    coupler = call_if_func(coupler,
                           gap=gap,
                           radius=radius,
                           length_x=length_x,
                           **kwargs)
    straight_side = call_if_func(straight,
                                 width=wg_width,
                                 length=length_y + component.xsize,
                                 **kwargs)
    straight_top = call_if_func(straight,
                                width=wg_width,
                                length=length_x,
                                **kwargs)
    bend = call_if_func(bend, width=wg_width, radius=radius, **kwargs)

    c = Component()
    c.component = component
    cb = c << coupler
    wl = c << straight_side
    if with_component:
        d = c << component
    else:
        d = c << straight_side
    bl = c << bend
    br = c << bend
    wt = c << straight_top

    wl.connect(port="o2", destination=cb.ports["o2"])
    bl.connect(port="o2", destination=wl.ports["o1"])

    wt.connect(port="o1", destination=bl.ports["o1"])
    br.connect(port="o2", destination=wt.ports["o2"])
    d.connect(port="o1", destination=br.ports["o1"])

    c.add_port("o2", port=cb.ports["o4"])
    c.add_port("o1", port=cb.ports["o1"])
    c.copy_child_info(component)
    return c
def ring_single_sample(gap: float = 0.2,
                       radius: float = 10.0,
                       length_x: float = 4.0,
                       length_y: float = 0.010,
                       coupler_ring: ComponentFactory = coupler_ring_function,
                       straight: ComponentFactory = straight_function,
                       bend: Optional[ComponentFactory] = None,
                       cross_section: CrossSectionFactory = strip,
                       **kwargs) -> Component:
    """Single bus ring made of a ring coupler (cb: bottom)
    connected with two vertical straights (wl: left, wr: right)
    two bends (bl, br) and horizontal straight (wg: top)

    Args:
        gap: gap between for coupler
        radius: for the bend and coupler
        length_x: ring coupler length
        length_y: vertical straight length
        coupler_ring: ring coupler function
        straight: straight function
        bend: 90 degrees bend function
        cross_section:
        kwargs: cross_section settings


    .. code::

          bl-wt-br
          |      |
          wl     wr length_y
          |      |
         --==cb==-- gap

          length_x

    """
    assert_on_2nm_grid(gap)

    coupler_ring_component = (coupler_ring(bend=bend,
                                           gap=gap,
                                           radius=radius,
                                           length_x=length_x,
                                           cross_section=cross_section,
                                           **kwargs)
                              if callable(coupler_ring) else coupler_ring)
    straight_side = call_if_func(straight,
                                 length=length_y,
                                 cross_section=cross_section,
                                 **kwargs)
    straight_top = call_if_func(straight,
                                length=length_x,
                                cross_section=cross_section,
                                **kwargs)

    bend = bend or bend_euler
    bend_ref = (bend(radius=radius, cross_section=cross_section, **kwargs)
                if callable(bend) else bend)

    c = Component()
    cb = c << coupler_ring_component
    wl = c << straight_side
    wr = c << straight_side
    bl = c << bend_ref
    br = c << bend_ref
    wt = c << straight_top
    # wt.mirror(p1=(0, 0), p2=(1, 0))

    wl.connect(port="o2", destination=cb.ports["o2"])
    bl.connect(port="o2", destination=wl.ports["o1"])

    wt.connect(port="o2", destination=bl.ports["o1"])
    br.connect(port="o2", destination=wt.ports["o1"])
    wr.connect(port="o1", destination=br.ports["o1"])

    c.add_port("o2", port=cb.ports["o2"])
    c.add_port("o1", port=cb.ports["o1"])
    return c
Ejemplo n.º 3
0
def ring_double_heater(
        gap: float = 0.2,
        radius: float = 10.0,
        length_x: float = 0.01,
        length_y: float = 0.01,
        coupler_ring: ComponentFactory = coupler_ring_function,
        straight: ComponentFactory = straight_function,
        bend: Optional[ComponentFactory] = None,
        cross_section_heater: gf.types.CrossSectionFactory = gf.cross_section.
    strip_heater_metal,
        cross_section: CrossSectionFactory = strip,
        contact: gf.types.ComponentFactory = contact_heater_m3_mini,
        port_orientation: int = 90,
        contact_offset: Float2 = (0, 0),
        **kwargs) -> Component:
    """Double bus ring made of two couplers (ct: top, cb: bottom)
    connected with two vertical straights (sl: left, sr: right)
    includes heater on top

    Args:
        gap: gap between for coupler
        radius: for the bend and coupler
        length_x: ring coupler length
        length_y: vertical straight length
        coupler_ring: ring coupler function
        straight: straight function
        bend: bend function
        cross_section_heater:
        cross_section:
        contact:
        port_orientation: for electrical ports to promote from contact
        contact_offset: for each contact
        kwargs: cross_section settings

    .. code::

         --==ct==--
          |      |
          sl     sr length_y
          |      |
         --==cb==-- gap

          length_x

    """
    assert_on_2nm_grid(gap)

    coupler_component = (coupler_ring(gap=gap,
                                      radius=radius,
                                      length_x=length_x,
                                      bend=bend,
                                      cross_section=cross_section,
                                      bend_cross_section=cross_section_heater,
                                      **kwargs)
                         if callable(coupler_ring) else coupler_ring)
    straight_component = call_if_func(straight,
                                      length=length_y,
                                      cross_section=cross_section_heater,
                                      **kwargs)

    c = Component()
    cb = c.add_ref(coupler_component)
    ct = c.add_ref(coupler_component)
    sl = c.add_ref(straight_component)
    sr = c.add_ref(straight_component)

    sl.connect(port="o1", destination=cb.ports["o2"])
    ct.connect(port="o3", destination=sl.ports["o2"])
    sr.connect(port="o2", destination=ct.ports["o2"])
    c.add_port("o1", port=cb.ports["o1"])
    c.add_port("o2", port=cb.ports["o4"])
    c.add_port("o3", port=ct.ports["o4"])
    c.add_port("o4", port=ct.ports["o1"])

    c1 = c << contact()
    c2 = c << contact()
    c1.xmax = -length_x / 2 + cb.x - contact_offset[0]
    c2.xmin = +length_x / 2 + cb.x + contact_offset[0]
    c1.movey(contact_offset[1])
    c2.movey(contact_offset[1])
    c.add_ports(c1.get_ports_list(orientation=port_orientation), prefix="e1")
    c.add_ports(c2.get_ports_list(orientation=port_orientation), prefix="e2")
    c.auto_rename_ports()
    return c
Ejemplo n.º 4
0
def coupler_ring(
        gap: float = 0.2,
        radius: float = 5.0,
        length_x: float = 4.0,
        coupler90: ComponentFactory = coupler90function,
        bend: Optional[ComponentFactory] = None,
        coupler_straight: ComponentFactory = coupler_straight_function,
        cross_section: CrossSectionFactory = strip,
        **kwargs) -> Component:
    r"""Coupler for ring.

    Args:
        gap: spacing between parallel coupled straight waveguides.
        radius: of the bends.
        length_x: length of the parallel coupled straight waveguides.
        coupler90: straight coupled to a 90deg bend.
        straight: library for straight waveguides.
        bend: library for bend
        coupler_straight: two parallel coupled straight waveguides.
        cross_section:
        **kwargs: cross_section settings

    .. code::

           2             3
           |             |
            \           /
             \         /
           ---=========---
         1    length_x    4


    """
    bend = bend or bend_euler

    c = Component()
    assert_on_2nm_grid(gap)

    # define subcells
    coupler90_component = (coupler90(gap=gap,
                                     radius=radius,
                                     bend=bend,
                                     cross_section=cross_section,
                                     **kwargs)
                           if callable(coupler90) else coupler90)
    coupler_straight_component = (coupler_straight(
        gap=gap, length=length_x, cross_section=cross_section, **
        kwargs) if callable(coupler_straight) else coupler_straight)

    # add references to subcells
    cbl = c << coupler90_component
    cbr = c << coupler90_component
    cs = c << coupler_straight_component

    # connect references
    y = coupler90_component.y
    cs.connect(port="o4", destination=cbr.ports["o1"])
    cbl.reflect(p1=(0, y), p2=(1, y))
    cbl.connect(port="o2", destination=cs.ports["o2"])

    c.absorb(cbl)
    c.absorb(cbr)
    c.absorb(cs)

    c.add_port("o1", port=cbl.ports["o3"])
    c.add_port("o2", port=cbl.ports["o4"])
    c.add_port("o3", port=cbr.ports["o3"])
    c.add_port("o4", port=cbr.ports["o4"])
    c.auto_rename_ports()
    return c
Ejemplo n.º 5
0
def ring_double(gap: float = 0.2,
                radius: float = 10.0,
                length_x: float = 0.01,
                length_y: float = 0.01,
                coupler_ring: ComponentFactory = coupler_ring_function,
                straight: ComponentFactory = straight_function,
                bend: Optional[ComponentFactory] = None,
                cross_section: CrossSectionFactory = strip,
                **kwargs) -> Component:
    """Double bus ring made of two couplers (ct: top, cb: bottom)
    connected with two vertical straights (sl: left, sr: right)

    Args:
        gap: gap between for coupler
        radius: for the bend and coupler
        length_x: ring coupler length
        length_y: vertical straight length
        coupler: ring coupler function
        straight: straight function
        bend: bend function
        **kwargs: cross_section settings

    .. code::

         --==ct==--
          |      |
          sl     sr length_y
          |      |
         --==cb==-- gap

          length_x

    """
    assert_on_2nm_grid(gap)

    coupler_component = (coupler_ring(gap=gap,
                                      radius=radius,
                                      length_x=length_x,
                                      bend=bend,
                                      cross_section=cross_section,
                                      **kwargs)
                         if callable(coupler_ring) else coupler_ring)
    straight_component = call_if_func(straight,
                                      length=length_y,
                                      cross_section=cross_section,
                                      **kwargs)

    c = Component()
    cb = c.add_ref(coupler_component)
    ct = c.add_ref(coupler_component)
    sl = c.add_ref(straight_component)
    sr = c.add_ref(straight_component)

    sl.connect(port="o1", destination=cb.ports["o2"])
    ct.connect(port="o3", destination=sl.ports["o2"])
    sr.connect(port="o2", destination=ct.ports["o2"])
    c.add_port("o1", port=cb.ports["o1"])
    c.add_port("o2", port=cb.ports["o4"])
    c.add_port("o3", port=ct.ports["o4"])
    c.add_port("o4", port=ct.ports["o1"])
    return c
Ejemplo n.º 6
0
def coupler(gap: float = 0.236,
            length: float = 20.0,
            coupler_symmetric: ComponentFactory = coupler_symmetric_function,
            coupler_straight: ComponentFactory = coupler_straight_function,
            dy: float = 5.0,
            dx: float = 10.0,
            cross_section: CrossSectionFactory = strip,
            **kwargs) -> Component:
    r"""Symmetric coupler.

    Args:
        gap: between straights
        length: of coupling region
        coupler_symmetric
        coupler_straight
        dy: port to port vertical spacing
        dx: length of bend in x direction
        cross_section: factory
        kwargs: cross_section settings

    .. code::

               dx                                 dx
            |------|                           |------|
         o2 ________                           ______o3
                    \                         /           |
                     \        length         /            |
                      ======================= gap         | dy
                     /                       \            |
            ________/                         \_______    |
         o1                                          o4

                        coupler_straight  coupler_symmetric


    """
    length = snap_to_grid(length)
    assert_on_2nm_grid(gap)
    c = Component()

    sbend = coupler_symmetric(gap=gap,
                              dy=dy,
                              dx=dx,
                              cross_section=cross_section,
                              **kwargs)

    sr = c << sbend
    sl = c << sbend
    cs = c << coupler_straight(
        length=length, gap=gap, cross_section=cross_section, **kwargs)
    sl.connect("o2", destination=cs.ports["o1"])
    sr.connect("o1", destination=cs.ports["o4"])

    c.add_port("o1", port=sl.ports["o3"])
    c.add_port("o2", port=sl.ports["o4"])
    c.add_port("o3", port=sr.ports["o3"])
    c.add_port("o4", port=sr.ports["o4"])

    c.absorb(sl)
    c.absorb(sr)
    c.absorb(cs)
    c.info.length = sbend.info.length
    c.info.min_bend_radius = sbend.info.min_bend_radius
    c.auto_rename_ports()
    return c