案例分享:画多端口螺旋线
注:spiral的长度不是真实长度,具体可以参考教程28
代码如下:
from si_fab import all as pdk
import ipkiss3.all as i3
import numpy as np
from scipy.constants import piclass SpiralCircular(i3.PCell):core_width = i3.PositiveNumberProperty(doc="Core width of the bend waveguide", default=0.4)radius = i3.PositiveNumberProperty(doc="Radius of the central bends", default=5.0)spacing = i3.PositiveNumberProperty(doc="Separation between adjacent waveguides", default=2)spiral_length = i3.PositiveNumberProperty(doc="Length of the total spiral waveguide", default=1000.0)layout_properties = i3.NumpyArrayProperty(doc="Calculated layout properties of the spiral.", locked=True)def _default_layout_properties(self):r = self.radiustot_sep = self.spacing + self.core_widthn_o_loops_act = -(2.0 * r / tot_sep) + np.sqrt((2.0 * r / tot_sep) ** 2.0 - ((2.0 * r - self.spiral_length / pi) / tot_sep))n_o_loops = np.floor(n_o_loops_act)theta_nom = self.spiral_length - 2.0 * r * pi * (2.0 * n_o_loops + 1.0) - (n_o_loops ** 2.0) * tot_sep * pitheta_denom = 4.0 * r + (2.0 * n_o_loops + 1.0) * tot_septheta_m = theta_nom / theta_denomr_out = 2.0 * r + (n_o_loops + 0.5) * tot_sepdx0 = tot_sep * 0.5 * np.sin(theta_m)dy0 = r_out * (1.0 - np.cos(theta_m)) + (r_out - 0.5 * tot_sep) * np.cos(theta_m)return np.array([r, tot_sep, n_o_loops, theta_m, r_out, dx0, dy0])class Layout(i3.LayoutView):def _generate_elements(self, elems):for p in self.ports:elems += i3.Label(text=p.name,layer=i3.TECH.PPLAYER.DOC,coordinate=p.position,height=5.0,)return elemsdef _generate_instances(self, insts):r = self.layout_properties[0]tot_sep = self.layout_properties[1]n_o_loops = self.layout_properties[2]theta_m = self.layout_properties[3]r_out = self.layout_properties[4]dx0 = self.layout_properties[5]dy0 = self.layout_properties[6]# spiral waveguidefor index in range(int(n_o_loops + 1)):sign = 1.0 if index % 2 == 0 else -1.0if index == 0:radius1 = rdy1 = 0.0radius2 = rdy2 = 0.0radius3 = r - 0.8dy3 = 0.0 - 0.8radius4 = r + 0.8dy4 = 0.0 + 0.8else:radius1 = 2.0 * r + (2.0 * index - 1.0) * tot_sep * 0.5dy1 = 2.0 * r + (index - 1.0) * tot_sepradius2 = 2.0 * r + (2.0 * index - 1.0) * tot_sep * 0.5dy2 = 2.0 * r + (index - 1.0) * tot_sepradius3 = 2.0 * r + (2.0 * index - 1.0) * tot_sep * 0.5-0.8dy3 = 2.0 * r + (index - 1.0) * tot_sep-0.8radius4 = 2.0 * r + (2.0 * index - 1.0) * tot_sep * 0.5+0.8dy4 = 2.0 * r + (index - 1.0) * tot_sep+0.8shape_wg1 = [(0.0, -sign * dy1),(sign * radius1, -sign * dy1),(sign * radius1, -sign * (dy1 - radius1)),(sign * radius1, -sign * (dy1 - 2.0 * radius1)),(0.0, -sign * (dy1 - 2.0 * radius1)),]shape_wg2 = [(0.0, sign * dy2),(-sign * radius2, sign * dy2),(-sign * radius2, sign * (dy2 - radius2)),(-sign * radius2, sign * (dy2 - 2.0 * radius2)),(0.0, sign * (dy2 - 2.0 * radius2)),]shape_wg3 = [(0.0, -sign * dy3),(sign * radius3, -sign * dy3),(sign * radius3, -sign * (dy3 - radius3)),(sign * radius3, -sign * (dy3 - 2.0 * radius3)),(0.0, -sign * (dy3 - 2.0 * radius3)),]shape_wg4 = [(0.0, sign * dy4),(-sign * radius4, sign * dy4),(-sign * radius4, sign * (dy4 - radius4)),(-sign * radius4, sign * (dy4 - 2.0 * radius4)),(0.0, sign * (dy4 - 2.0 * radius4)),]wg1 = i3.RoundedWaveguide(trace_template=pdk.SWG450())wg2 = i3.RoundedWaveguide(trace_template=pdk.SWG450())wg3 = i3.RoundedWaveguide(trace_template=pdk.SWG450())wg4 = i3.RoundedWaveguide(trace_template=pdk.SWG450())wg1.Layout(bend_radius=radius1, shape=shape_wg1)wg2.Layout(bend_radius=radius2, shape=shape_wg2)wg3.Layout(bend_radius=radius3, shape=shape_wg3)wg4.Layout(bend_radius=radius4, shape=shape_wg4)insts += i3.SRef(wg1, flatten=True)insts += i3.SRef(wg2, flatten=True)insts += i3.SRef(wg3, flatten=True)insts += i3.SRef(wg4, flatten=True)return instsif __name__ == '__main__':SpiralCircular().Layout().visualize(legacy=True)