def _generate_instances(self, insts): # First create shapes # Break the channel that contain two obstacles into three segments # Obstacles need to intersect these three segments # Obs 1. Segment 1:2, Obs 2 Segment 2:3 #define points will be helpful to make schematic p1 = (self.cInp.x + 0.0, self.cInp.y + 0.0) p2 = ((self.gap_btw_barriers * 0.5 + self.obstacle_trap_radius), 0.0) p3 = ((self.gap_btw_barriers * 0.5 + self.obstacle_trap_radius), self.gap_btw_barriers + self.obstacle_trap_radius * 2) p4 = (0.0, self.gap_btw_barriers + self.obstacle_trap_radius * 2) sr1 = i3.Shape(points=[p1, p2, p3, p4], closed=True) #Internal holes as Circles #to do: define position of SC2 as a function of perpendicular GAP sc1 = i3.ShapeCircle(center=(self.cInp.x + 0.0, self.gap_btw_barriers * 0.5 + self.obstacle_trap_radius), radius=(self.obstacle_trap_radius)) #Define the boundaries for shapes br1 = i3.Boundary(layer=self.layer, shape=sr1) bc1 = i3.Boundary(layer=self.layer, shape=sc1) #Substruct boundaries and add to the element list b_sub = br1 - bc1 s = i3.Structure(elements=b_sub) insts += i3.SRef(s) return insts
def _generate_elements(self, elems): shape_rect = i3.ShapeRectangle(box_size=(self.length, self.width)) elems += i3.Boundary(layer=i3.TECH.PPLAYER.WG.CORE, shape=shape_rect) return elems
def _generate_elements(self, elems): # Center of the structure (x0, y0) = self.position elems += i3.Rectangle(layer=self.layer, center=(x0 + 7500, y0 + 4500), box_size=(15000, 1000)) # elems += i3.Rectangle(layer=i3.TECH.PPLAYER.NONE.DOC, center=(x0 + 7500, y0 + 4500), # box_size=(15000, 1000)) elems += i3.Rectangle(layer=self.layer, center=(x0 + 7500, y0 + 500), box_size=(15000, 1000)) elems += i3.Rectangle(layer=self.layer, center=(x0 + 12500+1000, y0 + 2500), #change box_size=(self.length, self.width)) if self.pocket: PO = i3.Rectangle(layer=self.layer_bool, center=(10001+2000, 2500), box_size=(2, 160)) #change elems += PO generated1 = self.layer - self.layer_bool mapping = {generated1: self.layer} elems = i3.get_elements_for_generated_layers(elems, mapping) if self.tilt: # TI = i3.Rectangle(layer=self.layer_bool, center=(10001, 2500), box_size=(2, 160)) # elems += TI TI_shape = i3.Shape(points=[(10000.0+2000, 2470.0), (10010.58+2000, 2530.0), (10000.0+2000, 2530.0)], closed=True) #change TI = i3.Boundary(layer=self.layer_bool, shape=TI_shape) elems += TI generated1 = self.layer - self.layer_bool mapping = {generated1: self.layer} elems = i3.get_elements_for_generated_layers(elems, mapping) return elems
def _generate_elements(self, elems): from ..metal.contact import CONTACT_STD elems += i3.Line(layer=i3.TECH.PPLAYER.GE, begin_coord=(0.0, 0.0), end_coord=(self.length, 0.0), line_width=self.width) elems += i3.Line(layer=i3.TECH.PPLAYER.N, begin_coord=(0.0, self.contact_offset), end_coord=(self.length, self.contact_offset), line_width=1.0) elems += i3.Line(layer=i3.TECH.PPLAYER.P, begin_coord=(0.0, -self.contact_offset), end_coord=(self.length, -self.contact_offset), line_width=1.0) elems += i3.Wedge(layer=i3.TECH.PPLAYER.SI, begin_coord=(-5.0, 0.0), end_coord=(0.0, 0.0), begin_width=0.45, end_width=self.taper_width) elems += i3.ARef( reference=CONTACT_STD(), origin=(0.5 * self.contact_pitch, self.contact_offset), period=(self.contact_pitch, 0.0), n_o_periods=(int(np.floor(self.length / self.contact_pitch)), 1)) elems += i3.ARef( reference=CONTACT_STD(), origin=(0.5 * self.contact_pitch, -self.contact_offset), period=(self.contact_pitch, 0.0), n_o_periods=(int(np.floor(self.length / self.contact_pitch)), 1)) elems += i3.Boundary(layer=i3.TECH.PPLAYER.M1, shape=[ (0.0, self.contact_offset - 0.5), (self.length, self.contact_offset - 0.5), (self.length, self.contact_offset + 2.0), (0.0, self.contact_offset + 2.0) ]) elems += i3.Boundary(layer=i3.TECH.PPLAYER.M1, shape=[ (0.0, -self.contact_offset + 0.5), (self.length, -self.contact_offset + 0.5), (self.length, -self.contact_offset - 2.0), (0.0, -self.contact_offset - 2.0) ]) return elems
def _generate_instances(self, insts): sr1 = i3.ShapeCircle(center=(0.0, 0.0), radius=self.radius) #, line_width = 200) sr2 = i3.ShapeCircle( center=(0.0, 0.0), radius=self.radius - self.vacuum_channel_circular) #, line_width = 200) #Rectangles sc1 = i3.ShapeRectangle( center=(self.cInp.x - self.radius, -self.radius), box_size=(self.radius * 2, self.radius * 2 + 100)) #100 has to be linked to channel input width)) #Define the boundaries for shapes br1 = i3.Boundary(layer=self.layer, shape=sr1) br2 = i3.Boundary(layer=self.layer, shape=sr2) bc1 = i3.Boundary(layer=self.layer, shape=sc1) #Substruct boundaries and add to the element list b_sub = br1 - br2 s = i3.Structure(elements=b_sub) b_sub = b_sub[0] - bc1 s = i3.Structure(elements=b_sub) insts += i3.SRef(s) #Input channel - segment channel1 = microfluidics.Channel( trace_template=self.cell.channel_template) channel1_lo = channel1.Layout( shape=[(0, 0), (0, self.inlet_channel_length + self.vacuum_channel_circular * 0.5)]) insts += i3.SRef(channel1_lo, position=(0, self.radius - self.vacuum_channel_circular * 0.5), transformation=i3.Rotation((0.0, 0.0), 0.0)) return insts
def _get_splitting_elem(self): pos_in = self.instances["in"].ports["out"].position pos_out_1 = self.instances["out1"].ports["in"].position pos_out_2 = self.instances["out2"].ports["in"].position wg_width = self.wg_template.core_width waypoint_shape_top = i3.Shape(points=[ pos_in + i3.Coord2(0, wg_width / 2), pos_in + i3.Coord2(self.small_straights, wg_width / 2), self.waypoint, pos_out_2 + i3.Coord2(-self.small_straights, +wg_width / 2), pos_out_2 + i3.Coord2(0, +wg_width / 2) ]) shape_top = SplinedShape(waypoint_shape=waypoint_shape_top, resolution=0.05) shape_top_m = shape_top.v_mirror_copy() start_parabole = i3.Coord2(self.split_base_pos, self.split_base_width / 2) end_parabole = pos_out_2 - i3.Coord2(self.small_straights, wg_width / 2) x_parabole = np.linspace(start_parabole[0], end_parabole[0], 50) y_parabole = (end_parabole[1] - start_parabole[1]) * 1 / ( end_parabole[0] - x_parabole[0])**0.5 * ( x_parabole - x_parabole[0])**0.5 + start_parabole[1] points_parabole = [ i3.Coord2(x, y) for x, y in zip(x_parabole, y_parabole) ] points_parabole = [ i3.Coord2(start_parabole[0], 0) ] + points_parabole + [pos_out_2 - i3.Coord2(0, wg_width / 2)] shape_parabole = i3.Shape(points=points_parabole) shape_parabole_m = shape_parabole.v_mirror_copy() shape_parabole_final = shape_parabole.reversed() + shape_parabole_m shape_parabole_final.remove_identicals() shape_bot = SplinedShape( waypoint_shape=i3.Shape(points=shape_parabole_final), resolution=0.05) shape_elem = shape_top + shape_bot + shape_top_m.reversed() shape_elem.remove_identicals() elem = i3.Boundary(layer=self.wg_template.core_layer, shape=shape_elem) return elem
def _generate_elements(self, elems): # Waveguide path wg_path = [(0.0, 0.0), (self.length, 0.0)] taper_boundary = [(0.0, self.wg_width_in/2),(self.length, self.wg_width_out/2), (self.length, -self.wg_width_out/2),(0.0, -self.wg_width_in/2)] taper_shape = i3.Boundary(shape=taper_boundary,layer=i3.TECH.PPLAYER.WG.COR) # Add taper shape to core layer elems += taper_shape # Add block layers import block_layers as bl block_layers = bl.layers block_widths = bl.widths for ii in range(len(block_layers)): fill_boundary = [(0.0, self.wg_width_in / 2+block_widths[ii]), (self.length, self.wg_width_out / 2+block_widths[ii]), (self.length, -self.wg_width_out / 2-block_widths[ii]), (0.0, -self.wg_width_in / 2-block_widths[ii])] fill_shape = i3.Boundary(shape=fill_boundary,layer=block_layers[ii]) elems += fill_shape return elems
def _generate_elements(self, insts): block_width = self.channel_template.channel_width point_list = [] point_list.append((-self.block_length * 0.5, -block_width * 0.5)) point_list.insert(0, (-self.block_length * 0.5, block_width * 0.5)) point_list.append((self.block_length * 0.5, -block_width * 0.5)) point_list.insert(0, (self.block_length * 0.5, block_width * 0.5)) t = i3.Shape(point_list, closed=True) bo = i3.Boundary(i3.TECH.PPLAYER.CH2.TRENCH, t) insts += bo #comm/uncomm for debugging round stl return insts
def _get_cladding_elem(self): shape_cladding = i3.Shape( points=[(self.length_straights, self.wg_template.width / 2), (self.length_straights + self.length_splitting_shape, self.spacing / 2 + self.wg_template.width / 2)]) shape_cladding_m = i3.Shape( points=[(self.length_straights, -self.wg_template.width / 2), (self.length_straights + self.length_splitting_shape, -self.spacing / 2 - self.wg_template.width / 2)]) shape_elem = shape_cladding + shape_cladding_m.reversed() elem = i3.Boundary(layer=self.wg_template.windows[1].layer, shape=shape_elem) return elem
def _generate_elements(self, elems): elems += i3.CirclePath(layer=i3.TECH.PPLAYER.CH2.TRENCH, center=(0.0, 0.0), radius=self.diameter * 0.5, line_width=50) point_list = [] point_list.append((0, -self.diameter * 0.5)) point_list.insert(0, (0, self.diameter * 0.5)) point_list.append( (self.diameter * self.cell.reduction_ratio, -self.diameter * 0.5 * self.cell.reduction_ratio)) point_list.insert( 0, (self.diameter * self.cell.reduction_ratio, self.diameter * 0.5 * self.cell.reduction_ratio)) funnel = i3.Shape(point_list, closed=True) bo = i3.Boundary(i3.TECH.PPLAYER.CH2.TRENCH, funnel) elems += bo return elems
def _generate_elements(self, elems): # Append start and end angles size = self.wg_width.shape length = size[0] allangles = np.zeros([length], np.float_) allangles[0] = self.start_angle * np.pi / 180.0 allangles[1:(length - 1)] = self.wg_angles allangles[length - 1] = self.end_angle * np.pi / 180.0 # Check block fill layer widths import block_layers as bl block_layers = bl.layers block_widths = bl.widths max_width = 0.0 for ii in range(len(block_widths)): if block_widths[ii] > max_width: max_width = block_widths[ii] # Create coord list for boundaries topcoords = np.zeros([length, 2], np.float_) botcoords = np.zeros([length, 2], np.float_) topbfillcoords = np.zeros([length, 2], np.float_) botbfillcoords = np.zeros([length, 2], np.float_) for ii in range(length): norm = np.array( [-np.sin(allangles[ii]), np.cos([allangles[ii]])], np.float_) topcoords[ ii, :] = self.wg_path[ii, :] + self.wg_width[ii] / 2 * norm botcoords[ ii, :] = self.wg_path[ii, :] - self.wg_width[ii] / 2 * norm topbfillcoords[ii, :] = self.wg_path[ ii, :] + (self.wg_width[ii] / 2 + max_width) * norm botbfillcoords[ii, :] = self.wg_path[ ii, :] - (self.wg_width[ii] / 2 + max_width) * norm allcoords = np.zeros([2 * length, 2], np.float_) allbfillcoords = np.zeros([2 * length, 2], np.float_) allcoords[0:length, :] = topcoords allbfillcoords[:length, :] = topbfillcoords for ii in range(length): allcoords[(length + ii), :] = botcoords[length - (ii + 1), :] allbfillcoords[(length + ii), :] = botbfillcoords[length - (ii + 1), :] wg_coords = [] fill_coords = [] for ii in range(2 * length): wg_coords.append((allcoords[ii, 0], allcoords[ii, 1])) fill_coords.append((allbfillcoords[ii, 0], allbfillcoords[ii, 1])) wg_shape = i3.Boundary(shape=wg_coords, layer=i3.TECH.PPLAYER.WG.COR) # Add wg shape to core layer elems += wg_shape # Add block layers for ii in range(len(block_layers)): fill_shape = i3.Boundary(shape=fill_coords, layer=block_layers[ii]) elems += fill_shape return elems
def _generate_instances(self, insts): # First create shapes # Break the block containig the feature into two segments # Block need to intersect these two segments # Feature 1. Segment 1:2 #define points will be helpful to make schematic p1 = ((self.feature_width + self.gap_horiz + self.vacuum_width) * (-0.5), 0.0) p2 = (self.cInp.x + 0.0, self.cInp.y + 0.0) p3 = (self.cInp.x, self.feature_height * 0.5 + self.vacuum_width) p4 = ((self.feature_width + self.gap_horiz + self.vacuum_width) * (-0.5), self.feature_height * 0.5 + self.vacuum_width) p5 = ((self.feature_width + self.gap_horiz + self.vacuum_width) * (0.5), 0.0) p6 = ((self.feature_width + self.gap_horiz + self.vacuum_width) * (0.5), self.feature_height * 0.5 + self.vacuum_width) p7 = ((self.feature_width + self.gap_horiz + self.vacuum_width) * (-0.5), -(self.feature_height * 0.5 + self.vacuum_width)) p8 = (self.cInp.x, -(self.feature_height * 0.5 + self.vacuum_width)) p9 = ((self.feature_width + self.gap_horiz + self.vacuum_width) * (0.5), -(self.feature_height * 0.5 + self.vacuum_width)) sr1 = i3.Shape(points=[p1, p2, p3, p4], closed=True) sr2 = i3.Shape(points=[p2, p5, p6, p3], closed=True) sr3 = i3.Shape(points=[p7, p8, p2, p1], closed=True) sr4 = i3.Shape(points=[p8, p9, p5, p2], closed=True) #Internal holes as Circles #It is needed to define position of SC2 as a function of perpendicular GAP #sc1 = i3.ShapeCircle(center = (self.cInp.x+(self.gap_btw_barriers+self.obstacle_trap_length)*0.65, 0.0), radius = (self.obstacle_trap_width)) #sc2 = i3.ShapeCircle(center = (self.cInp.x+(self.gap_btw_barriers+self.obstacle_trap_length)*1.35,self.cInp.y+self.channel_trap_width), radius = (self.obstacle_trap_width)) #Internal holes as Rectangles sc1 = i3.ShapeRectangle( center=(self.cInp.x, self.cInp.y), box_size=(self.feature_width + self.gap_horiz, self.feature_height + self.gap_vertical)) #Define the boundaries for shapes br1 = i3.Boundary(layer=self.layer, shape=sr1) br2 = i3.Boundary(layer=self.layer, shape=sr2) br3 = i3.Boundary(layer=self.layer, shape=sr3) br4 = i3.Boundary(layer=self.layer, shape=sr4) bc1 = i3.Boundary(layer=self.layer, shape=sc1) #Substruct boundaries and add to the element list b_sub = br1 - bc1 s = i3.Structure(elements=b_sub) insts += i3.SRef(s) b_sub = br2 - bc1 b_sub = b_sub[0] - bc1 s = i3.Structure(elements=b_sub) insts += i3.SRef(s) b_sub = br3 - bc1 s = i3.Structure(elements=b_sub) insts += i3.SRef(s) b_sub = br4 - bc1 s = i3.Structure(elements=b_sub) insts += i3.SRef(s) return insts
def _generate_elements(self, elems): cell_trap_width = self.channel_template.channel_width alpha = math.radians(self.in_angle) beta = math.radians(self.out_angle) point_list = [] point_list.append( (-self.cell_trap_length * 0.25, -cell_trap_width * 0.5)) point_list.insert( 0, (-self.cell_trap_length * 0.25, cell_trap_width * 0.5)) point_list.append( (-(cell_trap_width - self.cell_trap_gap) / math.tan(alpha) - self.cell_trap_gap_length * 0.5, -(cell_trap_width * 0.5))) point_list.insert( 0, (-(cell_trap_width - self.cell_trap_gap) / math.tan(alpha) - self.cell_trap_gap_length * 0.5, (cell_trap_width * 0.5))) point_list.append((-self.cell_trap_gap_length * 0.25, -self.cell_trap_gap * 0.5)) # end of array point_list.insert( 0, (-self.cell_trap_gap_length * 0.25, self.cell_trap_gap * 0.5)) # begging of array, position 0 point_list.append( (self.cell_trap_gap_length * 0.25, -self.cell_trap_gap * 0.5)) point_list.insert( 0, (self.cell_trap_gap_length * 0.25, self.cell_trap_gap * 0.5)) point_list.append( ((cell_trap_width - self.cell_trap_gap) / math.tan(beta) + self.cell_trap_gap_length * 0.25, -(cell_trap_width * 0.5))) point_list.insert( 0, ((cell_trap_width - self.cell_trap_gap) / math.tan(beta) + self.cell_trap_gap_length * 0.25, (cell_trap_width * 0.5))) point_list.append( (-self.cell_trap_length * 0.25 + self.cell_trap_length * 0.5, -cell_trap_width * 0.5)) point_list.insert( 0, (-self.cell_trap_length * 0.25 + self.cell_trap_length * 0.5, cell_trap_width * 0.5)) t = i3.Shape(point_list, closed=True) rectang = i3.ShapeRound(original_shape=t, start_face_angle=0, end_face_angle=0, radius=self.radius_fillet) bo = i3.Boundary(self.channel_template.layer, rectang) #insts += bo #comm/uncomm for debugging round stl #creating an inlet rectangle boundary to avoid round corners point_list = [] #w = 3 point_list.append( (-self.cell_trap_length * 0.5, -cell_trap_width * 0.5)) point_list.insert( 0, (-self.cell_trap_length * 0.5, cell_trap_width * 0.5)) point_list.append( (-self.cell_trap_length * 0.25 + self.radius_fillet, -cell_trap_width * 0.5)) point_list.insert(0, (-self.cell_trap_length * 0.25 + self.radius_fillet, cell_trap_width * 0.5)) t = i3.Shape(point_list, closed=True) bo1 = i3.Boundary(self.channel_template.layer, t) #creating an outlet rectangle boundary to avoid round corners point_list = [] point_list.append( (self.cell_trap_length * 0.25 - self.radius_fillet, -cell_trap_width * 0.5)) point_list.insert(0, (self.cell_trap_length * 0.25 - self.radius_fillet, cell_trap_width * 0.5)) point_list.append( (self.cell_trap_length * 0.5, -cell_trap_width * 0.5)) point_list.insert(0, (-self.cell_trap_length * 0.5 + self.cell_trap_length, cell_trap_width * 0.5)) t = i3.Shape(point_list, closed=True) bo2 = i3.Boundary(self.channel_template.layer, t) #boolean operation adding main geometry and inlet rectangle b_add = bo1 | bo #boolean operation adding main geometry and outlet rectangle b_add2 = bo2 | b_add[0] elems += b_add2 return elems
def _generate_instances(self, insts): width = 200.0 p1 = (-self.radius, -self.radius) #near cylinders p2 = (-self.radius, -2 * self.radius) #bottom p3 = (2 * self.radius, -2 * self.radius) #right p4 = (2 * self.radius, 0) #top p5 = (2 * self.radius + 500, 0) #out pax = (-width * 0.5 * math.cos(45), width * 0.5 * math.sin(45)) #generate a circle sr1 = i3.ShapeCircle(center=(0.0, 0.0), radius=self.radius) #, line_width = 200) br1 = i3.Boundary(layer=self.layer, shape=sr1) #s= i3.Structure(elements = br1) #rectangle sc1 = i3.ShapeRectangle(center=p1, box_size=(self.radius * 4, self.radius * 0.25)) bc1 = i3.Boundary(layer=self.layer, shape=sc1, transformation=i3.Rotation((0, 0), -45.0)) # was -35 #Substruct boundaries and add to the element list b_sub = br1 - bc1 s = i3.Structure(elements=b_sub) insts += i3.SRef(s) #Input channel - segment channel1 = microfluidics.Channel( trace_template=self.cell.channel_template) #channel_template = microfluidics.ShortChannelTemplate().Layout(width=200.0) channel1_lo = channel1.Layout(shape=[(self.inlet_channel_length + self.offset_matching * 0.5, 0), (0, 0)]) insts += i3.SRef( channel1_lo, position=(-(self.inlet_channel_length + self.radius), 0), transformation=i3.Rotation((0.0, 0.0), 0.0)) #############################routing from ipkiss.plugins.photonics.routing.manhattan import RouteManhattan channel_4 = microfluidics.RoundedChannel( trace_template=self.cell.channel_template) # used for routing channel_4_layout = channel_4.Layout() import operator p1Array = tuple(map(operator.add, p1, pax)) print 'p1: ', p1 print 'pax: ', pax print 'p1Array: ', p1Array #obstacles insts += i3.SRef(reference=self.obstacles, position=p1Array, transformation=i3.Rotation((0, 0), -45.0)) in_port_1 = microfluidics.FluidicPort( position=p1, trace_template=self.cell.channel_template) out_port_1 = microfluidics.FluidicPort( trace_template=self.cell.channel_template) in_port_1.angle_deg = 225 out_port_1.angle_deg = 45 in_port_2 = microfluidics.FluidicPort( position=p2, trace_template=self.cell.channel_template) in_port_2.angle_deg = 225 channel_4_layout.set(bend_radius=150.0, shape=RouteManhattan(input_port=in_port_2, points=[p2, p3, p4, p5], output_port=out_port_1, bend_radius=300.0)) insts += i3.SRef(name="Route_1", reference=channel_4) ##############################routing from ipkiss3.pcell.routing import RouteToAngle # create the route object channel_1 = microfluidics.RoundedChannel( trace_template=self.cell.channel_template) # used for routing channel_1_layout = channel_1.Layout() channel_1_layout.set(bend_radius=50.0, shape=RouteToAngle(input_port=in_port_1, start_straight=300, end_straight=300, angle_out=45)) #insts += i3.SRef(name = "Route_2", reference = channel_1) from ipkiss3.pcell.routing import RouteToEastAtMaxY, RouteToEastAtMinY, RouteToEastAtY # create the route object input_portx = i3.OpticalPort(name="in", position=(-self.radius, -self.radius), angle_deg=225.0) channel_x = microfluidics.RoundedChannel( trace_template=self.cell.channel_template) # used for routing channel_x_layout = channel_x.Layout() channel_x_layout.set(bend_radius=150.0, shape=RouteToEastAtY(input_port=input_portx, start_straight=200, end_straight=200, y_position=-2 * self.radius)) insts += i3.SRef(name="Route_x", reference=channel_x) return insts
def _generate_elements(self, elems): super(PlaceAndAutoRoute.Layout, self)._generate_elements(elems) total_length = self.modulator_length + self.additional_length delta = self.delta delay = self.delay signal_width = self.signal_width metal_spacing = self.metal_spacing ground_width = self.ground_width period_pad = self.period_pad taper_length = self.taper_length pad_length = self.pad_length pad_width = self.pad_width pad_size = (pad_length, pad_width) y_ground = -delta + min( delay / 2., 0.) - signal_width - 1.5 * metal_spacing - ground_width / 2. y_arm1_n = -delta + min( delay / 2., 0.) - signal_width / 2. - metal_spacing / 2. y_arm1_p = delay / 4. - signal_width / 2. - metal_spacing / 2. y_arm2_n = delta + max(delay / 2., 0.) - signal_width / 2. - metal_spacing / 2. y_arm2_p = delta + max(delay / 2., 0.) + ground_width / 2. + metal_spacing / 2. arm2_n_width = 2 * delta + abs( delay / 2.) - signal_width - 2 * metal_spacing # Metal lines lines = [] ground = i3.Rectangle(layer=i3.TECH.PPLAYER.M1, center=(0., y_ground), box_size=(total_length, ground_width)) arm1_n = i3.Rectangle(layer=i3.TECH.PPLAYER.M1, center=(0., y_arm1_n), box_size=(total_length, signal_width)) arm1_p = i3.Rectangle(layer=i3.TECH.PPLAYER.M1, center=(0., y_arm1_p), box_size=(total_length, arm2_n_width)) arm2_n = i3.Rectangle(layer=i3.TECH.PPLAYER.M1, center=(0., y_arm2_n), box_size=(total_length, signal_width)) arm2_p = i3.Rectangle(layer=i3.TECH.PPLAYER.M1, center=(0., y_arm2_p), box_size=(total_length, ground_width)) lines += [ground, arm1_n, arm1_p, arm2_n, arm2_p] # Metal left pads left_pads = [] taper_ground = i3.Boundary( layer=i3.TECH.PPLAYER.M1, shape=[ (-(total_length / 2. + taper_length), y_arm1_p - 2 * period_pad + pad_width / 2.), (-(total_length / 2. + taper_length), y_arm1_p - 2 * period_pad - pad_width / 2.), (-total_length / 2., y_ground - ground_width / 2.), (-total_length / 2., y_ground + ground_width / 2.), ]) taper_arm1_n = i3.Boundary( layer=i3.TECH.PPLAYER.M1, shape=[ (-(total_length / 2. + taper_length), y_arm1_p - period_pad + pad_width / 2.), (-(total_length / 2. + taper_length), y_arm1_p - period_pad - pad_width / 2.), (-total_length / 2., y_arm1_n - signal_width / 2.), (-total_length / 2., y_arm1_n + signal_width / 2.), ]) taper_arm1_p = i3.Wedge( layer=i3.TECH.PPLAYER.M1, begin_coord=(-(total_length / 2. + taper_length), y_arm1_p), end_coord=(-total_length / 2., y_arm1_p), begin_width=pad_width, end_width=arm2_n_width, ) taper_arm2_n = i3.Boundary( layer=i3.TECH.PPLAYER.M1, shape=[ (-(total_length / 2. + taper_length), y_arm1_p + period_pad + pad_width / 2.), (-(total_length / 2. + taper_length), y_arm1_p + period_pad - pad_width / 2.), (-total_length / 2., y_arm2_n - signal_width / 2.), (-total_length / 2., y_arm2_n + signal_width / 2.), ]) taper_arm2_p = i3.Boundary( layer=i3.TECH.PPLAYER.M1, shape=[ (-(total_length / 2. + taper_length), y_arm1_p + 2 * period_pad + pad_width / 2.), (-(total_length / 2. + taper_length), y_arm1_p + 2 * period_pad - pad_width / 2.), (-total_length / 2., y_arm2_p - ground_width / 2.), (-total_length / 2., y_arm2_p + ground_width / 2.), ]) for i in range(-2, 3): left_pads += i3.Rectangle( layer=i3.TECH.PPLAYER.M1, center=( -(total_length / 2. + taper_length + pad_length / 2.), y_arm1_p + i * period_pad), box_size=pad_size) left_pads += [ taper_ground, taper_arm1_n, taper_arm1_p, taper_arm2_n, taper_arm2_p ] # Metal right pads right_pads = [ elt.transform_copy(i3.HMirror(0.)) for elt in left_pads ] elems += lines elems += left_pads elems += right_pads return elems
# specify generated layers and the layer to use in the output generated1 = (layer1 ^ layer2) & layer1 generated2 = ~layer3 mapping = {generated1: i3.Layer(10), generated2: i3.Layer(20)} # generated layout output_elems = i3.get_elements_for_generated_layers(layout.layout, mapping) final_layout = i3.LayoutCell(name="generated").Layout(elements=output_elems) final_layout.visualize() # create and visualize a hierarchical layout simple_layout = i3.LayoutCell(name="circle_and_path").Layout( elements=[circle, circle_path]) top_layout = i3.LayoutCell(name="top_original").Layout(elements=[ i3.SRef(simple_layout, (0.0, 0.0)), i3.SRef(simple_layout, (0.0, 15.0)), # cover the full layout with layer3 i3.Boundary(layer=layer3, shape=[(-10.0, -10.0), (-10.0, 35.0), (20.0, 35.0), (20.0, -10.0)]) ]) top_layout.visualize() # and create and visualize the generated result top_output_elems = i3.get_elements_for_generated_layers( top_layout.layout, mapping) final_top_layout = i3.LayoutCell(name="top_generated").Layout( elements=top_output_elems) final_top_layout.visualize()
def _generate_instances(self, insts): # First create shapes # Break the channel that contain two obstacles into three segments # Obstacles need to intersect these three segments # Obs 1. Segment 1:2, Obs 2 Segment 2:3 #define points will be helpful to make schematic p1 = (self.cInp.x+0.0,self.cInp.y+0.0) p2 = ((self.gap_btw_barriers+self.obstacle_trap_length)*0.5,0.0) p3 = ((self.gap_btw_barriers+self.obstacle_trap_length)*0.5,self.channel_trap_width) p4 = (0.0,self.channel_trap_width) p5 = ((self.gap_btw_barriers+self.obstacle_trap_length)*1.5, 0.0) p6 = ((self.gap_btw_barriers+self.obstacle_trap_length)*2, 0.0) p7 = ((self.gap_btw_barriers+self.obstacle_trap_length)*2, self.channel_trap_width) p8 = ((self.gap_btw_barriers+self.obstacle_trap_length)*1.5,self.channel_trap_width) sr1 = i3.Shape(points = [p1,p2,p3,p4], closed =True) sr2 = i3.Shape(points = [p2,p5,p8,p3], closed =True) sr3 = i3.Shape(points = [p5,p6,p7,p8], closed =True) #Internal holes as Circles #to do: define position of SC2 as a function of perpendicular GAP sc1 = i3.ShapeCircle(center = (self.cInp.x+(self.gap_btw_barriers+self.obstacle_trap_length)*0.65, 0.0), radius = (self.obstacle_trap_width)) sc2 = i3.ShapeCircle(center = (self.cInp.x+(self.gap_btw_barriers+self.obstacle_trap_length)*1.35,self.cInp.y+self.channel_trap_width), radius = (self.obstacle_trap_width)) #Internal holes as Rectangles ''' sc1 = i3.ShapeRectangle(center = (self.cInp.x+(self.gap_btw_barriers +self.obstacle_trap_length)*0.5, self.cInp.y+self.obstacle_trap_width*0.5), box_size = (self.obstacle_trap_length, self.obstacle_trap_width)) sc2 = i3.ShapeRectangle(center = (self.cInp.x+(self.gap_btw_barriers +self.obstacle_trap_length)*1.5, self.cInp.y+self.channel_trap_width-self.obstacle_trap_width*0.5), box_size = (self.obstacle_trap_length, self.obstacle_trap_width)) ''' #Define the boundaries for shapes br1 = i3.Boundary(layer = self.layer, shape = sr1) br2 = i3.Boundary(layer = self.layer, shape = sr2) br3 = i3.Boundary(layer = self.layer, shape = sr3) bc1 = i3.Boundary(layer = self.layer, shape = sc1) bc2 = i3.Boundary(layer = self.layer, shape = sc2) #Substruct boundaries and add to the element list b_sub = br1-bc1 s= i3.Structure(elements = b_sub) insts += i3.SRef(s) b_sub = br2-bc1 b_sub = b_sub[0] - bc2 s= i3.Structure(elements = b_sub) insts += i3.SRef(s) b_sub = br3-bc2 s= i3.Structure(elements = b_sub) insts += i3.SRef(s) return insts
def _generate_elements(self, elems): cell_trap_width = self.channel_template.channel_width entry_Lfd = self.cell_trap_length * 0.5 # 1000.0 exit_Lfd = self.cell_trap_length * 0.5 # 500.0 beta = math.radians(self.out_angle) lf = self.funnel_length wi = cell_trap_width wf = self.cell_trap_gap #lfd = 0 taper_samples = 200 a = lf / (wi / wf - 1.0) dx = lf / taper_samples x = 0.0 xl = [] wl = [] point_list = [] x_offset = self.funnel_length + self.cell_trap_gap_length # all expansion will be at 0.0x a = 0.5 b = .35 point_list.append( self.cInp + (-(self.cell_trap_length * b), wi * 0.5)) # end of array point_list.insert(0, self.cInp + (-(self.cell_trap_length * b), -wi * 0.5)) # begging of array, position 0 for i in reversed(range(1, taper_samples + 1)): #xa = lf * math.exp(10.0 * (i / taper_samples - 1.0)) #discretization radius = 0.5 * wi ### this needs to be improved xa = (radius) * math.cos(0.5 * math.pi * i / taper_samples) #w = wi / (1.0 + xa / a) #function value w = (radius) * math.sin(0.5 * math.pi * i / taper_samples) p = (xa - radius - self.cell_trap_gap_length * 0.5, 0.5 * (w + 0.5 * wi)) point_list.append(self.cInp + p) p = (xa - radius - self.cell_trap_gap_length * 0.5, -0.5 * (w + 0.5 * wi)) point_list.insert(0, self.cInp + p) # GAP LENGTH p = ( point_list[-1][0], wf * 0.5 ) #wGet last point, coordX use it for next point with wf as coordY point_list.append(self.cInp + p) # Insert it at the bottom of point_list p = point_list[-1] + (0.0, (-wf)) # Get last point, add -wf point_list.insert(0, self.cInp + p) # Insert it at the bottom of point_list p = point_list[-1] + (self.cell_trap_gap_length, 0.0 ) # Get last point and add length point_list.append(self.cInp + p) # Insert it at [0] in the point_list p = point_list[-1] + (0.0, -wf) # Get last point and add length point_list.insert(0, self.cInp + p) # Insert it at [0] in the point_list # EXIT ANGLE p = point_list[-1] + ( 0.5 * (cell_trap_width - self.cell_trap_gap) / math.tan(beta), -cell_trap_width * 0.5 - wf * .50 ) # Get last point and add length of angle point_list.insert(0, self.cInp + p) # Insert it at [0] in the point_list p = point_list[0] + (0, wi) point_list.append(self.cInp + p) # Insert it at the bottom of point_list # EXIT LENGTH p = (self.cell_trap_length * b, point_list[-1][1] ) # get first point (last point added) and add length point_list.append(self.cInp + p) p = point_list[-1] + (0, -wi) ##get last point and add length point_list.insert(0, self.cInp + p) t = i3.Shape(point_list, closed=True) rectang = i3.ShapeRound(original_shape=t, start_face_angle=0, end_face_angle=0, radius=self.radius_fillet) bo = i3.Boundary(self.channel_template.layer, rectang) #creating an inlet rectangle boundary to avoid round corners point_list = [] point_list.append( (-self.cell_trap_length * a, -cell_trap_width * 0.5)) point_list.insert( 0, (-self.cell_trap_length * a, cell_trap_width * 0.5)) point_list.append((-self.cell_trap_length * b + self.radius_fillet, -cell_trap_width * 0.5)) point_list.insert(0, (-self.cell_trap_length * b + self.radius_fillet, cell_trap_width * 0.5)) t = i3.Shape(point_list, closed=True) bo1 = i3.Boundary(self.channel_template.layer, t) #creating an outlet rectangle boundary to avoid round corners point_list = [] point_list.append((self.cell_trap_length * b - self.radius_fillet, -cell_trap_width * 0.5)) point_list.insert(0, (self.cell_trap_length * b - self.radius_fillet, cell_trap_width * 0.5)) point_list.append( (self.cell_trap_length * a, -cell_trap_width * 0.5)) point_list.insert( 0, (self.cell_trap_length * a, cell_trap_width * 0.5)) t = i3.Shape(point_list, closed=True) bo2 = i3.Boundary(self.channel_template.layer, t) #boolean operation adding main geometry and inlet rectangle b_add = bo | bo1 #boolean operation adding main geometry and outlet rectangle b_add2 = b_add[0] | bo2 #s2 = i3.Structure(elements=b_add2) elems += b_add2 #insts += bo return elems