luceda ipkiss教程 16:快速给线路添加光栅耦合器或者端面耦合器——IoFibcoupGeneric

最近发现ipkiss中有个非常有用功能IoFibcoupGeneric,用它可以快速地给线路添加光栅耦合器或者端面耦合器,效果如下:
在这里插入图片描述

代码如下:

from si_fab import all as pdk
from ipkiss3 import all as i3

class MZI(i3.Circuit):
    coupler = i3.ChildCellProperty(doc="The coupler used for the MZI")
    phase_shifter = i3.ChildCellProperty(doc="The class used for the phase shifter")
    x_separation = i3.PositiveNumberProperty(default=20, doc="The separation between the couplers and the heater")
    heater_length = i3.PositiveNumberProperty(default=30, doc="The length of the heater")

    def _default_coupler(self):
        return pdk.SiDirectionalCouplerSPower(name=self.name + "_coupler")

    def _default_phase_shifter(self):
        trace_template = pdk.SWG450()
        phase_shifter = pdk.HeatedWaveguide(name=self.name + "_phase_shifter", trace_template=trace_template, )
        phase_shifter.Layout(shape=[(0, 0), (self.heater_length, 0)])
        return phase_shifter

    def _default_insts(self):
        return {
            "coupler_in": self.coupler,
            "coupler_out": self.coupler,
            "phase_shifter": self.phase_shifter,
        }

    def _default_specs(self):
        return [
            i3.Place("coupler_in:in1", (0, 0)),
            i3.PlaceRelative(
                "phase_shifter:in",
                "coupler_in:out1",
                (self.x_separation, 0),
            ),
            i3.PlaceRelative(
                "coupler_out:in1",
                "phase_shifter:out",
                (self.x_separation, 0),
            ),
            i3.ConnectManhattan(
                "phase_shifter:in",
                "coupler_in:out1",
                min_straight=0,
            ),
            i3.ConnectManhattan(
                "phase_shifter:out",
                "coupler_out:in1",
                min_straight=0,
            ),
            i3.ConnectManhattan(
                "coupler_in:out2",
                "coupler_out:in2",
                min_straight=0,
            ),
        ]

    def _default_exposed_ports(self):
        return {
            "coupler_in:in1": "in1",
            "coupler_in:in2": "in2",
            "coupler_out:out1": "out1",
            "coupler_out:out2": "out2",
            "phase_shifter:elec1": "elec1",
            "phase_shifter:elec2": "elec2",
        }


class Five_MZI(i3.Circuit):
    mzi = i3.ChildCellProperty(doc="The coupler used for the MZI")
    x_separation = i3.PositiveNumberProperty(default=20, doc="The separation between the couplers and the heater")
    heater_length = i3.PositiveNumberProperty(default=30, doc="The length of the heater")
    x_st = i3.PositiveNumberProperty(default=400)
    y_st = i3.PositiveNumberProperty(default=100)
    bend_radius = i3.PositiveNumberProperty(default=50)

    def _default_mzi(self):
        return MZI(x_separation=self.x_separation, heater_length=self.heater_length)

    def _default_insts(self):
        return {
            "mzi1": self.mzi,
            "mzi2": self.mzi,
            "mzi3": self.mzi,
            "mzi4": self.mzi,
            "mzi5": self.mzi,
        }

    def _default_specs(self):
        return [
            i3.Place("mzi1:in1", (0, 0)),
            i3.PlaceRelative(
                "mzi2:in1",
                "mzi1:in1",
                (0, self.y_st),
            ),
            i3.PlaceRelative(
                "mzi3:in1",
                "mzi1:in1",
                (self.x_st, -self.y_st / 2),
            ),
            i3.PlaceRelative(
                "mzi4:in1",
                "mzi3:in1",
                (0, self.y_st),
            ),
            i3.PlaceRelative(
                "mzi5:in1",
                "mzi4:in1",
                (0, self.y_st),
            ),
            i3.ConnectBend(
                "mzi1:out1",
                "mzi3:in2",
                bend_radius=self.bend_radius
            ),
            i3.ConnectBend(
                "mzi1:out2",
                "mzi4:in1",
                bend_radius=self.bend_radius
            ),
            i3.ConnectBend(
                "mzi2:out1",
                "mzi4:in2",
                bend_radius=self.bend_radius
            ),
            i3.ConnectBend(
                "mzi2:out2",
                "mzi5:in1",
                bend_radius=self.bend_radius
            ),
        ]

    def _default_exposed_ports(self):
        return {
            "mzi1:in1": "in1",
            "mzi1:in2": "in2",
            "mzi2:in1": "in3",
            "mzi2:in2": "in4",

            "mzi3:out1": "out1",
            "mzi3:out2": "out2",
            "mzi4:out1": "out3",
            "mzi4:out2": "out4",
            "mzi5:out1": "out5",
            "mzi5:out2": "out6",
        }

if __name__ == '__main__':
    demo = Five_MZI(x_separation=20, heater_length=40)
    demo.Layout().visualize(annotate=False)

    from picazzo3.container.iofibcoup import IoFibcoup
    iofb = IoFibcoup(contents=demo)
    iofb_layout = iofb.Layout()
    iofb_layout.visualize(annotate=False)

发现只要

from picazzo3.container.iofibcoup import IoFibcoup
iofb = IoFibcoup(contents=demo)
iofb_layout = iofb.Layout()
iofb_layout.visualize(annotate=False)

这4行代码,就给线路中悬空的端口加上了光栅耦合器,并且能自动匹配光栅耦合器的数量。

如果要调整光栅耦合器的位置或者间距,可以这样,先看代码:

 from picazzo3.container.iofibcoup import IoFibcoupGeneric
    iofb = IoFibcoupGeneric(contents=demo)
    y_space_east = 127
    y0_east = -200
    y_space_west = 127
    y0_west = -100
    iofb_layout = iofb.Layout(
        south_west=(1000.0, 0.0),
        south_east=(2000.0, 0.0),
        east_fiber_coupler_transformations=[
            i3.HMirror() + i3.Translation((0.0, y0_east)),
            i3.HMirror() + i3.Translation((0.0, y0_east + y_space_east - 25)),
            i3.HMirror() + i3.Translation((0.0, y0_east + (y_space_east - 25) * 2)),
            i3.HMirror() + i3.Translation((0.0, y0_east + (y_space_east - 25) * 3)),
            i3.HMirror() + i3.Translation((0.0, y0_east + (y_space_east - 25) * 4)),
            i3.HMirror() + i3.Translation((0.0, y0_east + (y_space_east - 25) * 5)),
        ],
        west_fiber_coupler_transformations=[
            i3.Translation((0.0, y0_west)),
            i3.Translation((0.0, y0_west + y_space_west - 25)),
            i3.Translation((0.0, y0_west + (y_space_west - 25) * 2)),
            i3.Translation((0.0, y0_west + (y_space_west - 25) * 3)),
        ],
    )
    iofb_layout.visualize(annotate=False,legacy=True)

用上面替换原代码中的最后四行后,运行结果为:
在这里插入图片描述
通过:

y_space_east = 127
y0_east = -200
y_space_west = 127
y0_west = -100

可以调整东西边最底下光栅的y轴坐标,以及两边光栅的间距。
光栅x轴位置可以通过:

south_west=(1000.0, 0.0),
south_east=(2000.0, 0.0),

调整

那么怎么改变耦合器的类型呢,比如不是接光栅耦合器而是端面耦合器
代码如下:

from si_fab import all as pdk
from ipkiss3 import all as i3


class MZI(i3.Circuit):
    coupler = i3.ChildCellProperty(doc="The coupler used for the MZI")
    phase_shifter = i3.ChildCellProperty(doc="The class used for the phase shifter")
    x_separation = i3.PositiveNumberProperty(default=20, doc="The separation between the couplers and the heater")
    heater_length = i3.PositiveNumberProperty(default=30, doc="The length of the heater")

    def _default_coupler(self):
        return pdk.SiNDirectionalCouplerSPower(name=self.name + "_coupler")

    def _default_phase_shifter(self):
        trace_template = pdk.SiNWireWaveguideTemplate()
        phase_shifter = pdk.HeatedWaveguide(name=self.name + "_phase_shifter", trace_template=trace_template, )
        phase_shifter.Layout(shape=[(0, 0), (self.heater_length, 0)])
        return phase_shifter

    def _default_insts(self):
        return {
            "coupler_in": self.coupler,
            "coupler_out": self.coupler,
            "phase_shifter": self.phase_shifter,
        }

    def _default_specs(self):
        return [
            i3.Place("coupler_in:in1", (0, 0)),
            i3.PlaceRelative(
                "phase_shifter:in",
                "coupler_in:out1",
                (self.x_separation, 0),
            ),
            i3.PlaceRelative(
                "coupler_out:in1",
                "phase_shifter:out",
                (self.x_separation, 0),
            ),
            i3.ConnectManhattan(
                "phase_shifter:in",
                "coupler_in:out1",
                min_straight=0,
            ),
            i3.ConnectManhattan(
                "phase_shifter:out",
                "coupler_out:in1",
                min_straight=0,
            ),
            i3.ConnectManhattan(
                "coupler_in:out2",
                "coupler_out:in2",
                min_straight=0,
            ),
        ]

    def _default_exposed_ports(self):
        return {
            "coupler_in:in1": "in1",
            "coupler_in:in2": "in2",
            "coupler_out:out1": "out1",
            "coupler_out:out2": "out2",
            "phase_shifter:elec1": "elec1",
            "phase_shifter:elec2": "elec2",
        }


class Five_MZI(i3.Circuit):
    mzi = i3.ChildCellProperty(doc="The coupler used for the MZI")
    x_separation = i3.PositiveNumberProperty(default=20, doc="The separation between the couplers and the heater")
    heater_length = i3.PositiveNumberProperty(default=30, doc="The length of the heater")
    x_st = i3.PositiveNumberProperty(default=400)
    y_st = i3.PositiveNumberProperty(default=200)
    bend_radius = i3.PositiveNumberProperty(default=50)

    def _default_mzi(self):
        return MZI(x_separation=self.x_separation, heater_length=self.heater_length)

    def _default_insts(self):
        return {
            "mzi1": self.mzi,
            "mzi2": self.mzi,
            "mzi3": self.mzi,
            "mzi4": self.mzi,
            "mzi5": self.mzi,
        }
    def _default_specs(self):
        return [
            i3.Place("mzi1:in1", (0, 0)),
            i3.PlaceRelative(
                "mzi2:in1",
                "mzi1:in1",
                (0, self.y_st),
            ),
            i3.PlaceRelative(
                "mzi3:in1",
                "mzi1:in1",
                (self.x_st, -self.y_st / 2),
            ),
            i3.PlaceRelative(
                "mzi4:in1",
                "mzi3:in1",
                (0, self.y_st),
            ),
            i3.PlaceRelative(
                "mzi5:in1",
                "mzi4:in1",
                (0, self.y_st),
            ),
            i3.ConnectBend(
                "mzi1:out1",
                "mzi3:in2",
                bend_radius=self.bend_radius
            ),
            i3.ConnectBend(
                "mzi1:out2",
                "mzi4:in1",
                bend_radius=self.bend_radius
            ),
            i3.ConnectBend(
                "mzi2:out1",
                "mzi4:in2",
                bend_radius=self.bend_radius
            ),
            i3.ConnectBend(
                "mzi2:out2",
                "mzi5:in1",
                bend_radius=self.bend_radius
            ),
        ]
    def _default_exposed_ports(self):
        return {
            "mzi1:in1": "in1",
            "mzi1:in2": "in2",
            "mzi2:in1": "in3",
            "mzi2:in2": "in4",
            "mzi3:out1": "out1",
            "mzi3:out2": "out2",
            "mzi4:out1": "out3",
            "mzi4:out2": "out4",
            "mzi5:out1": "out5",
            "mzi5:out2": "out6",
        }
if __name__ == '__main__':
    demo = Five_MZI(x_separation=20, heater_length=40)
    from picazzo3.container.iofibcoup import IoFibcoupGeneric

    iofb = IoFibcoupGeneric(
        contents=demo,
        east_trace_templates=[pdk.SiNWireWaveguideTemplate()],  # trace template for East fanout
        west_trace_templates=[pdk.SiNWireWaveguideTemplate()],  # trace_template for West fanout
        east_connect_trace_templates=[pdk.SiNWireWaveguideTemplate()],  # trace template for wide connections
        west_connect_trace_templates=[pdk.SiNWireWaveguideTemplate()],  # trace template for wide connections
        east_fiber_couplers=[pdk.SiNInvertedTaper()],
        west_fiber_couplers=[pdk.SiNInvertedTaper()],
    )
    y_space_east = 127
    y0_east = -200
    y_space_west = 127
    y0_west = -100

    iofb_layout = iofb.Layout(
        south_west=(-100.0, 0.0),
        south_east=(1200.0, 0.0),
        east_fiber_coupler_transformations=[
            i3.HMirror() + i3.Translation((0.0, y0_east)),
            i3.HMirror() + i3.Translation((0.0, y0_east + y_space_east - 25)),
            i3.HMirror() + i3.Translation((0.0, y0_east + (y_space_east - 25) * 2)),
            i3.HMirror() + i3.Translation((0.0, y0_east + (y_space_east - 25) * 3)),
            i3.HMirror() + i3.Translation((0.0, y0_east + (y_space_east - 25) * 4)),
            i3.HMirror() + i3.Translation((0.0, y0_east + (y_space_east - 25) * 5)),
        ],
        west_fiber_coupler_transformations=[
            i3.Translation((0.0, y0_west)),
            i3.Translation((0.0, y0_west + y_space_west - 25)),
            i3.Translation((0.0, y0_west + (y_space_west - 25) * 2)),
            i3.Translation((0.0, y0_west + (y_space_west - 25) * 3)),
        ],
    )
    iofb_layout.visualize(annotate=False, legacy=True)

首先,将线路中的硅波导替换到了氮化硅波导,这只需要在MZI中替换dc以及trace_template

 def _default_coupler(self):
        return pdk.SiNDirectionalCouplerSPower(name=self.name + "_coupler")

    def _default_phase_shifter(self):
        trace_template = pdk.SiNWireWaveguideTemplate()
        phase_shifter = pdk.HeatedWaveguide(name=self.name + "_phase_shifter", trace_template=trace_template, )
        phase_shifter.Layout(shape=[(0, 0), (self.heater_length, 0)])
        return phase_shifter

最后只要设置一下的这些IoFibcoupGeneric属性:

iofb = IoFibcoupGeneric(
        contents=demo,
        east_trace_templates=[pdk.SiNWireWaveguideTemplate()],  # trace template for East fanout
        west_trace_templates=[pdk.SiNWireWaveguideTemplate()],  # trace_template for West fanout
        east_connect_trace_templates=[pdk.SiNWireWaveguideTemplate()],  # trace template for wide connections
        west_connect_trace_templates=[pdk.SiNWireWaveguideTemplate()],  # trace template for wide connections
        east_fiber_couplers=[pdk.SiNInvertedTaper()],
        west_fiber_couplers=[pdk.SiNInvertedTaper()],
    )

就可以自动连上端面耦合器:
在这里插入图片描述
耦合器的类型可以通过这两个参数调整:

east_fiber_couplers=[pdk.SiNInvertedTaper()],
west_fiber_couplers=[pdk.SiNInvertedTaper()],
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值