def _init_primitives(self): N, R = self._meander_periods, self._turn_radius # meander_period = 2*meander_length + 2piR # self._length = coupling_length + (2piR/4 + offset_length + 2piR/4 + meander_length) # + N*meander_period + 2piR/2 + (meander_length/2 - R) + 2piR/4 + neck_length meander_length = (self._length - self._coupling_length \ - self._offset_length - 2*2*pi*R/4 \ -N*2*pi*R - 2*pi*R/2 + R - 2*pi*R/4 - self._neck_length)/(2*N+3/2) # print(meander_length) shape = "LRLRL" + N * "RLRL" + "RLRL" segment_lengths = [self._coupling_length + R, self._offset_length + 2*R]\ + [meander_length+R] + 2*N*[meander_length] \ + [meander_length/2, self._neck_length+R] turn_angles = [pi / 2, pi / 2] + N * [-pi, pi] + [-pi, pi / 2] # print(sum([abs(turn_angle) for turn_angle in turn_angles])/pi) # print(sum(segment_lengths) +\ # R*sum([abs(turn_angle) for turn_angle in turn_angles])-6*R) # print(self._length) # print(segment_lengths) self._line = CPW_RL_Path( DPoint(0, 0), shape, self._cpw_parameters, self._turn_radius, segment_lengths, turn_angles, DTrans(DPoint(-self._coupling_length + meander_length / 2, 0)), bridged=False) # print("Connections[0] 1:", self._line.connections[0]) # print("Primitive_start:", list(self._line.primitives.values())[0].connections[0]) self._line.make_trans(self._trans_in) self._line.make_trans(DTrans(self._origin)) # print("Primitive_start:", ) # print("Connections[0] 2:", self._line.connections[0]) self.start = list(self._line.primitives.values())[0].connections[0] self.end = list(self._line.primitives.values())[-1].connections[-1] self.alpha_start =\ list(self._line.primitives.values())[0].angle_connections[0] self.alpha_end =\ list(self._line.primitives.values())[-1].angle_connections[-1]
def init_half(self, origin, side=-1): # side = -1 is left, 1 is right up_st_gap = self.sq_area / (2 * self.sq_len) low_st_gap = up_st_gap + self.low_lead_w * 2.5 up_st_start_p = self.primitives["p_ext_up"].connections[1] low_st_start_p = self.primitives["p_ext_down"].connections[1] up_st_start = up_st_start_p + DVector(side * up_st_gap / 2, 0) up_st_stop = origin + DVector(side * up_st_gap / 2, self.bridge / 2) low_st_start = low_st_start_p + DVector(side * low_st_gap / 2, 0) low_st_stop = origin + DVector(side * (low_st_gap / 2 - self.b_ext), -self.bridge / 2) Z_low = CPWParameters(self.j_length, 0) Z_low2 = CPWParameters(self.low_lead_w, 0) len_ly = (low_st_stop - low_st_start).y - Z_low2.width / 2 len_lb = side * (low_st_start - low_st_stop).x - Z_low2.width / 2 suff = "_left" if side < 0 else "_right" self.primitives["upp_st" + suff] = Kolbaska(up_st_start, up_st_stop, self.j_width, self.j_width / 4) self.primitives["upp_st_thick" + suff] = Kolbaska( up_st_start, up_st_stop + DPoint(0, 400), self.low_lead_w, self.low_lead_w / 2) self.primitives["low_st" + suff] = CPW_RL_Path(low_st_start, 'LR', Z_low2, Z_low2.width/2,\ [len_ly],[side * pi/2],trans_in = DTrans.R90) self.primitives["low_st_jj" + suff] = CPW(Z_low.width, Z_low.gap, low_st_stop + DPoint(side * (self.b_ext - Z_low2.width/2),\ -self.j_length/2), low_st_stop + DPoint(0, -self.j_length/2))
def init_primitives(self): origin = DPoint(0, 0) total_neck_length = pi * self.R / 2 + self.neck if not self.no_neck else 0 meander_length = (self.len - self.cpl_L - 2 * (1 + self.N) * pi * self.R - 3 * self.R - total_neck_length - self.extra_neck_length) / (2 * self.N + 3 / 2) shape = "LRL" + self.N * "RLRL" + "RL" + ("RL" if not self.no_neck else "") segment_lengths = [ self.cpl_L, meander_length ] + 2 * self.N * [meander_length] + [ meander_length + 3 * self.R + self.extra_neck_length ] + ([self.neck] if not self.no_neck else []) turn_angles = [pi] + self.N * [-pi, pi] + [-pi] + ( [-pi / 2] if not self.no_neck else []) self.line = CPW_RL_Path(origin, shape, self.Z, self.R, segment_lengths, turn_angles) self.primitives['line'] = self.line if self.open_end == None: self.open_end = CPW( 0, self.Z.b / 2, self.line.end, self.line.end + (DPoint(0, -self.Z.b) if not self.no_neck else DPoint(-self.Z.b, 0))) self.primitives['open_end'] = self.open_end
def init_primitives(self): self.arc1 = CPW_arc(self.Z0, DPoint(0, 0), -self.r, pi / 2) self.primitives["arc1"] = self.arc1 p1 = self.arc1.end p2 = self.arc1.end + DPoint(0, -self.L0) self.cop_vertical = CPW(start=p1, end=p2, cpw_params=self.Z0) # open end tail face is separated from ground by `b = width + 2*gap` self.primitives["cop_vertical"] = self.cop_vertical # draw the open-circuited "tail" self.cpw_end_open_RLPath = CPW_RL_Path( self.cop_vertical.end, self.tail_shape, cpw_parameters=self.Z0, turn_radiuses=self.tail_turn_radiuses, segment_lengths=self.tail_segment_lengths, turn_angles=self.tail_turn_angles, trans_in=self.tail_trans_in ) self.primitives["cpw_end_open_RLPath"] = self.cpw_end_open_RLPath self.cpw_end_open_gap = CPW( 0, self.Z0.b / 2, self.cpw_end_open_RLPath.end, self.cpw_end_open_RLPath.end - DPoint(0, self.Z0.b) ) self.primitives["cpw_end_open_gap"] = self.cpw_end_open_gap # making coil name = "coil0" setattr(self, name, Coil_type_1(self.Z0, DPoint(0, 0), self.L_coupling, self.r, self.L1)) self.primitives[name] = getattr(self, name) # coils filling for i in range(self.N): name = "coil" + str(i + 1) setattr(self, name, Coil_type_1(self.Z0, DPoint(-self.L1 + self.L_coupling, -(i + 1) * (4 * self.r)), self.L1, self.r, self.L1)) self.primitives[name] = getattr(self, name) self.connections = [DPoint(0, 0), self.cpw_end_open_RLPath.end] self.angle_connections = [0, self.cpw_end_open_RLPath.alpha_end]
cell.clear() tmp_reg = Region() # faster to call `place` on single region # place chip metal layer chip_box = pya.Box(DPoint(0, 0), DPoint(CHIP.dx, CHIP.dy)) tmp_reg.insert(chip_box) contact_pads = CHIP.get_contact_pads() for contact_pad in contact_pads: contact_pad.place(tmp_reg) # place readout waveguide ro_line_turn_radius = 200e3 ro_line_dy = 600e3 cpwrl_ro = CPW_RL_Path( contact_pads[-1].end, shape="LRLRL", cpw_parameters=Z0, turn_radiuses=[ro_line_turn_radius]*2, segment_lengths=[ro_line_dy, CHIP.pcb_feedline_d, ro_line_dy], turn_angles=[pi/2, pi/2], trans_in=Trans.R270 ) cpwrl_ro.place(tmp_reg) params = zip(L1_list, L2_list, L_coupling_list, xmon_fork_penetrations) for res_idx, (L1, L2, L_coupling, xmon_fork_penetration) in enumerate(params): fork_y_span = xmon_fork_penetration + xmon_fork_gnd_gap worm_x = None # deduction for resonator placements # under condition that Xmon-Xmon distance equals # `xmon_x_distance` if res_idx == 0: worm_x = 1.2*CHIP.pcb_feedline_d else:
class CPWResonator(): _c = 299792458.0 def __init__(self, origin, cpw_parameters, turn_radius, frequency, ɛ, wavelength_fraction=1 / 4, coupling_length=200e3, offset_length=200e3, meander_periods=4, neck_length=100e3, end_primitive=None, trans_in=None): ''' A CPW resonator of wavelength fraction with automatic length calculation from given frequency. It's also possible to attach a primitive to the end of the resonator which should provide a get_phase_shift( ) method to calculate it's effective length as if it was just a straight CPW piece. Parameters: origin: DPoint The point where the resonator's couling tail ends and the meander starts cpw_parameters: CPWParameters CPW parameters for the resonator turn_radius: float Raduis of the resonator's meander turns frequency: float, GHz The frequency that the resonator will have ɛ: float Substrate relative permittivity wavelength_fraction: float The fraction of the wavelength the resonator's fundamental mode has at resonance. This parameter is not checked for consistensy with the resonator's boundaries coupling_length: float The length of the segment parallel to the feedline offset_length: float The distance away from the feedline before meandering meander_periods: int The number of periods in the meandering part neck_length: float The length of the straight part before the uncoupled end of the resonator end_primitive: ElementBase object Element that will be attached to the end of the resonator ''' self._origin = origin self._cpw_parameters = cpw_parameters self._turn_radius = turn_radius self._coupling_length = coupling_length self._offset_length = offset_length self._meander_periods = meander_periods self._neck_length = neck_length self._frequency = frequency self._wavelength_fraction = wavelength_fraction self._ɛ = ɛ self._end_primitive = end_primitive self._length = self._calculate_total_length() self._trans_in = trans_in self._init_primitives() def _init_primitives(self): N, R = self._meander_periods, self._turn_radius # meander_period = 2*meander_length + 2piR # self._length = coupling_length + (2piR/4 + offset_length + 2piR/4 + meander_length) # + N*meander_period + 2piR/2 + (meander_length/2 - R) + 2piR/4 + neck_length meander_length = (self._length - self._coupling_length \ - self._offset_length - 2*2*pi*R/4 \ -N*2*pi*R - 2*pi*R/2 + R - 2*pi*R/4 - self._neck_length)/(2*N+3/2) # print(meander_length) shape = "LRLRL" + N * "RLRL" + "RLRL" segment_lengths = [self._coupling_length + R, self._offset_length + 2*R]\ + [meander_length+R] + 2*N*[meander_length] \ + [meander_length/2, self._neck_length+R] turn_angles = [pi / 2, pi / 2] + N * [-pi, pi] + [-pi, pi / 2] # print(sum([abs(turn_angle) for turn_angle in turn_angles])/pi) # print(sum(segment_lengths) +\ # R*sum([abs(turn_angle) for turn_angle in turn_angles])-6*R) # print(self._length) # print(segment_lengths) self._line = CPW_RL_Path( DPoint(0, 0), shape, self._cpw_parameters, self._turn_radius, segment_lengths, turn_angles, DTrans(DPoint(-self._coupling_length + meander_length / 2, 0)), bridged=False) # print("Connections[0] 1:", self._line.connections[0]) # print("Primitive_start:", list(self._line.primitives.values())[0].connections[0]) self._line.make_trans(self._trans_in) self._line.make_trans(DTrans(self._origin)) # print("Primitive_start:", ) # print("Connections[0] 2:", self._line.connections[0]) self.start = list(self._line.primitives.values())[0].connections[0] self.end = list(self._line.primitives.values())[-1].connections[-1] self.alpha_start =\ list(self._line.primitives.values())[0].angle_connections[0] self.alpha_end =\ list(self._line.primitives.values())[-1].angle_connections[-1] # print(line.get_total_length()) # print(line._segment_lengths) def place(self, dest, layer=None, region_name="photo"): self._line.place(dest, region_name=region_name) def _calculate_total_length(self): length = self._c / self._frequency / ( sqrt(self._ɛ / 2 + 0.5)) / 1e9 * self._wavelength_fraction if self._end_primitive is not None: claw_phase_shift = self._claw.get_phase_shift(self._frequency) claw_effective_length = 1 / 180 * claw_phase_shift / self._frequency / 1e9 * self._c / 2 / sqrt( self._ɛ / 2 + 0.5) / 2 length -= claw_effective_length return length * 1e9 # in nm