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