def coupler_netlist( wg_width=0.5, gap=0.236, length=20.007, coupler_symmetric_factory=coupler_symmetric, coupler_straight=coupler_straight, ): """ SBEND_L-CS-SBEND_R """ assert_on_1nm_grid(length) assert_on_2nm_grid(gap) _sbend = coupler_symmetric_factory(gap=gap, wg_width=wg_width) _cpl_straight = coupler_straight(length=length, gap=gap, width=wg_width) components = { "SBEND_L": (_sbend, "mirror_y"), "SBEND_R": (_sbend, "None"), "CS": (_cpl_straight, "None"), } connections = [("SBEND_L", "W0", "CS", "W0"), ("CS", "E0", "SBEND_R", "W0")] ports_map = { "W0": ("SBEND_L", "E0"), "W1": ("SBEND_L", "E1"), "E0": ("SBEND_R", "E0"), "E1": ("SBEND_R", "E1"), } return components, connections, ports_map
def ring_double_bus_netlist( bend_radius=5, length_x=1, length_y=1, gap=0.2, coupler90_factory=coupler90, straight_factory=waveguide, cpl_straight_factory=coupler_straight, wg_width=0.5, ): """ .. code:: -CTL==CTS==CTR- | | VL VR | | -CBL==CBS==CBR- """ assert_on_2nm_grid(gap) _cpl_bend = coupler90_factory(bend_radius=bend_radius, width=wg_width, gap=gap) _cpl_straight = cpl_straight_factory(length=length_x, gap=gap, width=wg_width) _v = straight_factory(length=length_y) components = { "CBL": (_cpl_bend, "mirror_y"), "CBR": (_cpl_bend, "None"), "CTR": (_cpl_bend, "mirror_x"), "CTL": (_cpl_bend, "R180"), "CTS": (_cpl_straight, "None"), "CBS": (_cpl_straight, "None"), "VL": (_v, "R90"), "VR": (_v, "R90"), } connections = [ ("CBL", "W0", "CBS", "W0"), ("CBS", "E0", "CBR", "W0"), ("CBL", "N0", "VL", "W0"), ("VL", "E0", "CTL", "N0"), ("CTL", "W0", "CTS", "W0"), ("CTS", "E0", "CTR", "W0"), ("CBR", "N0", "VR", "W0"), ("VR", "E0", "CTR", "N0"), ] ports_map = { "W0": ("CBL", "E0"), "E0": ("CBR", "E0"), "W1": ("CTL", "E0"), "E1": ("CTR", "E0"), } return components, connections, ports_map
def ring_single_bus_netlist( bend_radius=5, length_x=1, length_y=1, gap=0.2, bend90_factory=bend_circular, coupler90_factory=coupler90, straight_factory=waveguide, cpl_straight_factory=coupler_straight, wg_width=0.5, ): """ .. code:: BL--H1--BR | | VL VR | | -CL==CS==CR- """ assert_on_2nm_grid(gap) bend = bend90_factory(width=wg_width, radius=bend_radius) cpl_bend = coupler90_factory(bend_radius=bend_radius, width=wg_width, gap=gap) cpl_straight = cpl_straight_factory(length=length_x, gap=gap, width=wg_width) h1 = straight_factory(length=length_x, width=wg_width) v = straight_factory(length=length_y, width=wg_width) components = { "CL": (cpl_bend, "mirror_y"), "CR": (cpl_bend, "None"), "BR": (bend, "mirror_x"), "BL": (bend, "R180"), "CS": (cpl_straight, "None"), "H1": (h1, "None"), "VL": (v, "R90"), "VR": (v, "R90"), } connections = [ ("CL", "W0", "CS", "W0"), ("CS", "E0", "CR", "W0"), ("CR", "N0", "VR", "W0"), ("VR", "E0", "BR", "N0"), ("BR", "W0", "H1", "E0"), ("H1", "W0", "BL", "W0"), ("BL", "N0", "VL", "E0"), ("VL", "W0", "CL", "N0"), ] ports_map = {"W0": ("CL", "E0"), "E0": ("CR", "E0")} return components, connections, ports_map
def ring_double( wg_width: float = 0.5, gap: float = 0.2, length_x: float = 3.0, bend_radius: float = 5.0, length_y: float = 2.0, coupler: Callable = coupler_ring, waveguide: Callable = waveguide_function, pins: bool = False, ) -> Component: """ double bus ring made of two couplers (ct: top, cb: bottom) connected with two vertical waveguides (wyl: left, wyr: right) .. code:: --==ct==-- | | wl wr length_y | | --==cb==-- gap length_x .. plot:: :include-source: import pp c = pp.c.ring_double(wg_width=0.5, gap=0.2, length_x=4, length_y=0.1, bend_radius=5) pp.plotgds(c) """ assert_on_2nm_grid(gap) coupler = call_if_func(coupler, gap=gap, wg_width=wg_width, bend_radius=bend_radius, length_x=length_x) waveguide = call_if_func(waveguide, width=wg_width, length=length_y) c = Component() cb = c << coupler ct = c << coupler wl = c << waveguide wr = c << waveguide wl.connect(port="E0", destination=cb.ports["N0"]) ct.connect(port="N1", destination=wl.ports["W0"]) wr.connect(port="W0", destination=ct.ports["N0"]) cb.connect(port="N1", destination=wr.ports["E0"]) c.add_port("E0", port=cb.ports["E0"]) c.add_port("W0", port=cb.ports["W0"]) c.add_port("E1", port=ct.ports["W0"]) c.add_port("W1", port=ct.ports["E0"]) if pins: pp.add_pins_to_references(c) return c
def coupler_ring( coupler90: Callable = coupler90, coupler: Callable = coupler_straight, length_x: float = 4.0, gap: float = 0.2, wg_width: float = 0.5, bend_radius: float = 5.0, ) -> Component: """ coupler for half a ring .. code:: N0 N1 | | \ / \ / ---=========--- W0 length_x E0 .. plot:: :include-source: import pp c = pp.c.coupler_ring(length_x=20, bend_radius=5.0, gap=0.3, wg_width=0.45) pp.plotgds(c) """ c = pp.Component() assert_on_2nm_grid(gap) # define subcells coupler90 = pp.call_if_func(coupler90, gap=gap, width=wg_width, bend_radius=bend_radius) coupler_straight = pp.call_if_func(coupler, gap=gap, length=length_x, width=wg_width) # add references to subcells cbl = c << coupler90 cbr = c << coupler90 cs = c << coupler_straight # connect references cs.connect(port="E0", destination=cbr.ports["W0"]) cbl.reflect(p1=(0, coupler90.y), p2=(1, coupler90.y)) cbl.connect(port="W0", destination=cs.ports["W0"]) c.add_port("W0", port=cbl.ports["E0"]) c.add_port("N0", port=cbl.ports["N0"]) c.add_port("E0", port=cbr.ports["E0"]) c.add_port("N1", port=cbr.ports["N0"]) return c
def coupler_netlist( wg_width: float = 0.5, gap: float = 0.236, length: float = 20.007, coupler_symmetric_factory: Callable = coupler_symmetric, coupler_straight: Callable = coupler_straight, layer: Tuple[int, int] = LAYER.WG, layers_cladding: List[Tuple[int, int]] = [LAYER.WGCLAD], cladding_offset: int = 3, ) -> Tuple[Dict[str, Tuple[Component, str]], List[Tuple[str, str, str, str]], Dict[str, Tuple[str, str]], ]: """ SBEND_L-CS-SBEND_R """ assert_on_1nm_grid(length) assert_on_2nm_grid(gap) _sbend = coupler_symmetric_factory( gap=gap, wg_width=wg_width, layer=layer, layers_cladding=layers_cladding, cladding_offset=cladding_offset, ) _cpl_straight = coupler_straight( length=length, gap=gap, width=wg_width, layer=layer, layers_cladding=layers_cladding, cladding_offset=cladding_offset, ) components = { "SBEND_L": (_sbend, "mirror_y"), "SBEND_R": (_sbend, "None"), "CS": (_cpl_straight, "None"), } connections = [("SBEND_L", "W0", "CS", "W0"), ("CS", "E0", "SBEND_R", "W0")] ports_map = { "W0": ("SBEND_L", "E0"), "W1": ("SBEND_L", "E1"), "E0": ("SBEND_R", "E0"), "E1": ("SBEND_R", "E1"), } return components, connections, ports_map
def ring_single( wg_width: float = 0.5, gap: float = 0.2, length_x: float = 4.0, bend_radius: float = 5.0, length_y: float = 2.0, coupler: Callable = coupler_ring, waveguide: Callable = waveguide, bend: Callable = bend_circular, ) -> Component: """ single bus ring made of two couplers (ct: top, cb: bottom) connected with two vertical waveguides (wyl: left, wyr: right) .. code:: bl-wt-br | | wl wr length_y | | --==cb==-- gap length_x .. plot:: :include-source: import pp c = pp.c.ring_single(wg_width=0.5, gap=0.2, length_x=4, length_y=0.1, bend_radius=5) pp.plotgds(c) """ bend_radius = float(bend_radius) assert_on_2nm_grid(gap) coupler = call_if_func(coupler, gap=gap, wg_width=wg_width, bend_radius=bend_radius, length_x=length_x) waveguide_side = call_if_func(waveguide, width=wg_width, length=length_y) waveguide_top = call_if_func(waveguide, width=wg_width, length=length_x) bend = call_if_func(bend, width=wg_width, radius=bend_radius) c = Component() cb = c << coupler wl = c << waveguide_side wr = c << waveguide_side bl = c << bend br = c << bend wt = c << waveguide_top wl.connect(port="E0", destination=cb.ports["N0"]) bl.connect(port="N0", destination=wl.ports["W0"]) wt.connect(port="W0", destination=bl.ports["W0"]) br.connect(port="N0", destination=wt.ports["E0"]) wr.connect(port="W0", destination=br.ports["W0"]) wr.connect(port="E0", destination=cb.ports["N1"]) # just for netlist c.add_port("E0", port=cb.ports["E0"]) c.add_port("W0", port=cb.ports["W0"]) return c
def ring_single_bus( coupler90_factory: Callable = coupler90, cpl_straight_factory: Callable = coupler_straight, straight_factory: Callable = waveguide, bend90_factory: Callable = bend_circular, length_y: float = 2.0, length_x: float = 4.0, gap: float = 0.2, wg_width: float = 0.5, bend_radius: int = 5, ) -> Component: """ single bus ring .. code:: ctl--wx--ctr | | wyl wgr | | -cbl==CS==cbr- """ c = pp.Component() assert_on_2nm_grid(gap) # define subcells coupler90 = pp.call_if_func(coupler90_factory, gap=gap, width=wg_width, bend_radius=bend_radius) waveguide_x = pp.call_if_func(straight_factory, length=length_x, width=wg_width, pins=False) waveguide_y = pp.call_if_func(straight_factory, length=length_y, width=wg_width, pins=False) bend = pp.call_if_func(bend90_factory, width=wg_width, radius=bend_radius, pins=False) coupler_straight = pp.call_if_func(cpl_straight_factory, gap=gap, length=length_x, width=wg_width) # add references to subcells cbl = c << coupler90 cbr = c << coupler90 cs = c << coupler_straight wyl = c << waveguide_y wyr = c << waveguide_y wx = c << waveguide_x btl = c << bend btr = c << bend # connect references wyr.connect(port="E0", destination=cbr.ports["N0"]) cs.connect(port="E0", destination=cbr.ports["W0"]) cbl.reflect(p1=(0, coupler90.y), p2=(1, coupler90.y)) cbl.connect(port="W0", destination=cs.ports["W0"]) wyl.connect(port="E0", destination=cbl.ports["N0"]) btl.connect(port="N0", destination=wyl.ports["W0"]) btr.connect(port="W0", destination=wyr.ports["W0"]) wx.connect(port="W0", destination=btl.ports["W0"]) c.add_port("W0", port=cbl.ports["E0"]) c.add_port("E0", port=cbr.ports["E0"]) return c
def ring_with_taper_netlist( bend_radius=5, length_x=1, length_y=0, gap=0.2, taper_width=1.0, taper_length=10, taper_factory=taper, bend90_factory=bend_circular, coupler90_factory=coupler90, straight_factory=waveguide, cpl_straight_factory=coupler_straight, wg_width=0.5, ): """ .. code:: BL--H1--BR | | | T2 | VR length_y VL T1 | | -CL==CS==CR- """ assert_on_2nm_grid(gap) taper = taper_factory(length=taper_length, width1=wg_width, width2=taper_width) bend = bend90_factory(radius=bend_radius, width=wg_width) cpl_bend = coupler90_factory(bend_radius=bend_radius, width=wg_width, gap=gap) cpl_straight = cpl_straight_factory(length=length_x, gap=gap, width=wg_width) h1 = straight_factory(length=length_x, width=wg_width) vl = straight_factory(length=length_y + 2 * taper_length, width=wg_width) vr = straight_factory(length=length_y, width=taper_width) components = { "CL": (cpl_bend, "mirror_y"), "CR": (cpl_bend, "None"), "BR": (bend, "mirror_x"), "BL": (bend, "R180"), "CS": (cpl_straight, "None"), "H1": (h1, "None"), "T1": (taper, "R90"), "T2": (taper, "R270"), "VL": (vl, "R90"), "VR": (vr, "R90"), } connections = [ ("CL", "W0", "CS", "W0"), ("CS", "E0", "CR", "W0"), ("CR", "N0", "T1", "1"), ("T1", "2", "VR", "W0"), ("VR", "E0", "T2", "2"), ("T2", "1", "BR", "N0"), ("BR", "W0", "H1", "E0"), ("H1", "W0", "BL", "W0"), ("BL", "N0", "VL", "E0"), ("VL", "W0", "CL", "N0"), ] ports_map = {"W0": ("CL", "E0"), "E0": ("CR", "E0")} return components, connections, ports_map
def ring_single_dut( component, wg_width=0.5, gap=0.2, length_x=4, bend_radius=5, length_y=0, coupler=coupler_ring, waveguide=waveguide, bend=bend_circular, with_dut=True, ): """ single bus ring made of two couplers (ct: top, cb: bottom) connected with two vertical waveguides (wyl: left, wyr: right) DUT (Device Under Test) in the middle to extract loss from quality factor Args: with_dut: if False changes dut for just a waveguide .. code:: bl-wt-br | | length_y wl dut | | --==cb==-- gap length_x """ dut = pp.call_if_func(component) dut = rename_ports_by_orientation(dut) assert_on_2nm_grid(gap) coupler = call_if_func(coupler, gap=gap, wg_width=wg_width, bend_radius=bend_radius, length_x=length_x) waveguide_side = call_if_func(waveguide, width=wg_width, length=length_y + dut.xsize) waveguide_top = call_if_func(waveguide, width=wg_width, length=length_x) bend = call_if_func(bend, width=wg_width, radius=bend_radius) c = Component() cb = c << coupler wl = c << waveguide_side if with_dut: d = c << dut else: d = c << waveguide_side bl = c << bend br = c << bend wt = c << waveguide_top wl.connect(port="E0", destination=cb.ports["N0"]) bl.connect(port="N0", destination=wl.ports["W0"]) wt.connect(port="W0", destination=bl.ports["W0"]) br.connect(port="N0", destination=wt.ports["E0"]) d.connect(port="W0", destination=br.ports["W0"]) c.add_port("E0", port=cb.ports["E0"]) c.add_port("W0", port=cb.ports["W0"]) return c
def ring_single( wg_width: float = 0.5, gap: float = 0.2, bend_radius: float = 10.0, length_x: float = 4.0, length_y: float = 0.001, coupler: Callable = coupler_ring, waveguide: Callable = waveguide_function, bend: Callable = bend_circular, pins: bool = False, ) -> Component: """Single bus ring made of a ring coupler (cb: bottom) connected with two vertical waveguides (wl: left, wr: right) two bends (bl, br) and horizontal waveguide (wg: top) Args: wg_width: waveguide width gap: gap between for coupler bend_radius: for the bend and coupler length_x: ring coupler length length_y: vertical waveguide length coupler: ring coupler function waveguide: waveguide function bend: bend function pins: add pins .. code:: bl-wt-br | | wl wr length_y | | --==cb==-- gap length_x .. plot:: :include-source: import pp c = pp.c.ring_single(wg_width=0.5, gap=0.2, length_x=4, length_y=0.1, bend_radius=5) pp.plotgds(c) """ bend_radius = float(bend_radius) assert_on_2nm_grid(gap) coupler = call_if_func(coupler, gap=gap, wg_width=wg_width, bend_radius=bend_radius, length_x=length_x) waveguide_side = call_if_func(waveguide, width=wg_width, length=length_y) waveguide_top = call_if_func(waveguide, width=wg_width, length=length_x) bend_ref = bend(width=wg_width, radius=bend_radius) if callable(bend) else bend c = Component() cb = c << coupler wl = c << waveguide_side wr = c << waveguide_side bl = c << bend_ref br = c << bend_ref wt = c << waveguide_top wl.connect(port="E0", destination=cb.ports["N0"]) bl.connect(port="N0", destination=wl.ports["W0"]) wt.connect(port="W0", destination=bl.ports["W0"]) br.connect(port="N0", destination=wt.ports["E0"]) wr.connect(port="W0", destination=br.ports["W0"]) wr.connect(port="E0", destination=cb.ports["N1"]) # just for netlist c.add_port("E0", port=cb.ports["E0"]) c.add_port("W0", port=cb.ports["W0"]) if pins: pp.add_pins_to_references(c) return c
def ring_double_bus_netlist( bend_radius: float = 5.0, length_x: float = 1.0, length_y: float = 1.0, gap: float = 0.2, coupler90_factory: Callable = coupler90, straight_factory: Callable = waveguide, cpl_straight_factory: Callable = coupler_straight, wg_width: float = 0.5, ) -> Tuple[Dict[str, Tuple[Component, str]], List[Tuple[str, str, str, str]], Dict[str, Tuple[str, str]], ]: """ .. code:: -CTL==CTS==CTR- | | VL VR | | -CBL==CBS==CBR- """ assert_on_2nm_grid(gap) _cpl_bend = coupler90_factory(bend_radius=bend_radius, width=wg_width, gap=gap) _cpl_straight = cpl_straight_factory(length=length_x, gap=gap, width=wg_width) _v = straight_factory(length=length_y) components = { "CBL": (_cpl_bend, "mirror_y"), "CBR": (_cpl_bend, "None"), "CTR": (_cpl_bend, "mirror_x"), "CTL": (_cpl_bend, "R180"), "CTS": (_cpl_straight, "None"), "CBS": (_cpl_straight, "None"), "VL": (_v, "R90"), "VR": (_v, "R90"), } connections = [ ("CBL", "W0", "CBS", "W0"), ("CBS", "E0", "CBR", "W0"), ("CBL", "N0", "VL", "W0"), ("VL", "E0", "CTL", "N0"), ("CTL", "W0", "CTS", "W0"), ("CTS", "E0", "CTR", "W0"), ("CBR", "N0", "VR", "W0"), ("VR", "E0", "CTR", "N0"), ] ports_map = { "W0": ("CBL", "E0"), "E0": ("CBR", "E0"), "W1": ("CTL", "E0"), "E1": ("CTR", "E0"), } return components, connections, ports_map