Source code for gdsfactory.components.ring_single_bend_coupler

from __future__ import annotations

import gdsfactory as gf
from gdsfactory.component import Component
from gdsfactory.components.bend_circular import bend_circular
from gdsfactory.components.bend_euler import bend_euler
from gdsfactory.components.straight import straight
from gdsfactory.typings import ComponentSpec, CrossSectionSpec


[docs] @gf.cell def coupler_bend( radius: float = 10.0, coupler_gap: float = 0.2, coupling_angle_coverage: float = 120.0, cross_section: CrossSectionSpec = "xs_sc", cross_section_inner: CrossSectionSpec = "xs_sc", cross_section_outer: CrossSectionSpec = "xs_sc", bend: ComponentSpec = bend_circular, ) -> Component: r"""Compact curved coupler with bezier escape. TODO: fix for euler bends. Args: radius: um. gap: um. angle_inner: of the inner bend, from beginning to end. Depending on the bend chosen, gap may not be preserved. angle_outer: of the outer bend, from beginning to end. Depending on the bend chosen, gap may not be preserved. bend: for bend. cross_section: cross_section. cross_section_inner: spec inner bend. cross_section_outer: spec outer bend. .. code:: r 4 | | | / ___3 | / / 2____/ / 1_____/ """ c = Component() xi = gf.get_cross_section(cross_section_inner) xo = gf.get_cross_section(cross_section_outer) angle_inner = 90 angle_outer = coupling_angle_coverage / 2 gap = coupler_gap width = xo.width / 2 + xi.width / 2 spacing = gap + width bend90_inner_right = gf.get_component( bend, radius=radius, cross_section=cross_section_inner, angle=angle_inner ) bend_outer_right = gf.get_component( bend, radius=radius + spacing, cross_section=cross_section_outer, angle=angle_outer, ) bend_inner_ref = c << bend90_inner_right bend_outer_ref = c << bend_outer_right output = gf.get_component( bend_euler, angle=angle_outer, cross_section=cross_section ).mirror() output_ref = c << output output_ref.connect("o1", bend_outer_ref.ports["o2"]) pbw = bend_inner_ref.ports["o1"] bend_inner_ref.movey(pbw.center[1] + spacing) c.absorb(bend_outer_ref) c.absorb(bend_inner_ref) c.absorb(output_ref) c.add_port("o1", port=bend_outer_ref.ports["o1"]) c.add_port("o2", port=bend_inner_ref.ports["o1"]) c.add_port("o3", port=output_ref.ports["o2"]) c.add_port("o4", port=bend_inner_ref.ports["o2"]) return c
@gf.cell def coupler_ring_bend( radius: float = 10.0, coupler_gap: float = 0.2, coupling_angle_coverage: float = 90.0, length_x: float = 0.0, cross_section: CrossSectionSpec = "xs_sc", cross_section_inner: CrossSectionSpec = "xs_sc", cross_section_outer: CrossSectionSpec = "xs_sc", bend: ComponentSpec = bend_circular, ) -> Component: r"""Two back-to-back coupler_bend. Args: radius: um. gap: um. angle_inner: of the inner bend, from beginning to end. Depending on the bend chosen, gap may not be preserved. angle_outer: of the outer bend, from beginning to end. Depending on the bend chosen, gap may not be preserved. bend: for bend. length_x: horizontal straight length. cross_section: cross_section. cross_section_inner: spec inner bend. cross_section_outer: spec outer bend. kwargs: """ c = Component() cp = coupler_bend( radius=radius, coupler_gap=coupler_gap, coupling_angle_coverage=coupling_angle_coverage, cross_section=cross_section, cross_section_inner=cross_section_inner, cross_section_outer=cross_section_outer, bend=bend, ) sin = gf.get_component(straight, length=length_x, cross_section=cross_section_inner) sout = gf.get_component( straight, length=length_x, cross_section=cross_section_outer ) coupler_right = c << cp coupler_left = c << cp.mirror() straight_inner = c << sin straight_inner.movex(-length_x / 2) straight_outer = c << sout straight_outer.movex(-length_x / 2) coupler_left.connect("o1", straight_outer.ports["o1"]) straight_inner.connect("o1", coupler_left.ports["o2"]) coupler_right.connect("o2", straight_inner.ports["o2"]) straight_outer.connect("o2", coupler_right.ports["o1"]) c.absorb(coupler_right) c.absorb(coupler_left) c.absorb(straight_inner) c.absorb(straight_outer) c.add_port("o1", port=coupler_left.ports["o3"]) c.add_port("o2", port=coupler_left.ports["o4"]) c.add_port("o4", port=coupler_right.ports["o3"]) c.add_port("o3", port=coupler_right.ports["o4"]) return c
[docs] @gf.cell def ring_single_bend_coupler( radius: float = 5.0, gap: float = 0.2, coupling_angle_coverage: float = 180.0, bend: ComponentSpec = bend_circular, length_x: float = 0.6, length_y: float = 0.6, cross_section: CrossSectionSpec = "xs_sc", cross_section_inner: CrossSectionSpec = "xs_sc", cross_section_outer: CrossSectionSpec = "xs_sc", **kwargs, ) -> Component: r"""Returns ring with curved coupler. TODO: enable euler bends. Args: radius: um. gap: um. angle_inner: of the inner bend, from beginning to end. Depending on the bend chosen, gap may not be preserved. angle_outer: of the outer bend, from beginning to end. Depending on the bend chosen, gap may not be preserved. bend: for bend. length_x: horizontal straight length. length_y: vertical straight length. cross_section: cross_section. cross_section_inner: spec inner bend. cross_section_outer: spec outer bend. kwargs: cross_section settings. """ c = Component() cb = c << coupler_ring_bend( radius=radius, coupler_gap=gap, coupling_angle_coverage=coupling_angle_coverage, length_x=length_x, cross_section=cross_section, cross_section_inner=cross_section_inner, cross_section_outer=cross_section_outer, bend=bend, ) cross_section = cross_section_inner sx = gf.get_component( straight, length=length_x, cross_section=cross_section, **kwargs ) sy = gf.get_component( straight, length=length_y, cross_section=cross_section, **kwargs ) b = gf.get_component(bend, cross_section=cross_section, radius=radius, **kwargs) sl = c << sy sr = c << sy bl = c << b br = c << b st = c << sx sl.connect(port="o1", destination=cb.ports["o2"]) bl.connect(port="o2", destination=sl.ports["o2"]) st.connect(port="o2", destination=bl.ports["o1"]) br.connect(port="o2", destination=st.ports["o1"]) sr.connect(port="o1", destination=br.ports["o1"]) sr.connect(port="o2", destination=cb.ports["o3"]) c.add_port("o2", port=cb.ports["o4"]) c.add_port("o1", port=cb.ports["o1"]) return c
if __name__ == "__main__": # c = coupler_bend(radius=5) # c = coupler_ring_bend() c = ring_single_bend_coupler( cross_section_inner="xs_rc", cross_section_outer="xs_rc", cross_section="xs_rc" ) c.assert_ports_on_grid() c.show(show_ports=True)