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
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
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
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
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