Source code for gdsfactory.components.mode_converter
from __future__ import annotations
from functools import partial
import gdsfactory as gf
from gdsfactory.component import Component
from gdsfactory.components.bend_euler import bend_euler_s
from gdsfactory.components.coupler_straight_asymmetric import (
coupler_straight_asymmetric as coupler_straight_asymmetric_function,
)
from gdsfactory.components.taper import taper as taper_function
from gdsfactory.typings import ComponentSpec, CrossSectionSpec
[docs]
@gf.cell
def mode_converter(
gap: float = 0.3,
length: float = 10,
coupler_straight_asymmetric: ComponentSpec = coupler_straight_asymmetric_function,
bend: ComponentSpec = partial(bend_euler_s, angle=45),
taper: ComponentSpec = taper_function,
mm_width: float = 1.2,
mc_mm_width: float = 1,
sm_width: float = 0.5,
taper_length: float = 25,
cross_section: CrossSectionSpec = "xs_sc",
**kwargs,
) -> Component:
r"""Returns Mode converter from TE0 to TE1.
By matching the effective indices of two waveguides with different widths,
light can couple from different transverse modes e.g. TE0 <-> TE1.
https://doi.org/10.1109/JPHOT.2019.2941742
Args:
gap: directional coupler gap.
length: coupler length interaction.
coupler_straight_asymmetric: spec.
mm_width: input/output multimode waveguide width.
mc_mm_width: mode converter multimode waveguide width
sm_width: single mode waveguide width.
cross_section: cross_section spec.
kwargs: cross_section settings.
.. code::
o2 --- --- o4
\ /
\ /
-------
o1 -----=======----- o3
|-----|
length
= : multimode width
- : singlemode width
"""
c = Component()
coupler = gf.get_component(
coupler_straight_asymmetric,
length=length,
gap=gap,
width_bot=mc_mm_width,
width_top=sm_width,
**kwargs,
)
bend = gf.get_component(bend, **kwargs)
bot_taper = gf.get_component(
taper,
width1=mc_mm_width,
width2=mm_width,
length=taper_length,
**kwargs,
)
# directional coupler
dc = c << coupler
c.absorb(dc)
# straight waveguides at the bottom
l_bot_straight = c << bot_taper
r_bot_straight = c << bot_taper
l_bot_straight.connect("o1", dc.ports["o1"])
r_bot_straight.connect("o1", dc.ports["o4"])
c.absorb(l_bot_straight)
c.absorb(r_bot_straight)
# top right bend with termination
r_bend = c << bend
l_bend = c << bend
l_bend.mirror()
l_bend.connect("o1", dc.ports["o2"])
r_bend.connect("o1", dc.ports["o3"])
# define ports of mode converter
c.add_port("o1", port=l_bot_straight.ports["o2"])
c.add_port("o3", port=r_bot_straight.ports["o2"])
c.add_port("o2", port=l_bend.ports["o2"])
c.add_port("o4", port=r_bend.ports["o2"])
return c
if __name__ == "__main__":
c = mode_converter()
c.pprint_ports()
c.show(show_ports=True)