def draw_arc(self): self.Z0 = CPWParameters(200e3, 100e3) cpw_start = (self.chip_box.p1 + self.chip_box.p2)/2 self.arc = CPWArc( z0=self.Z0, start=cpw_start, R=1.2e6, delta_alpha=5/4*np.pi, trans_in=DTrans.R0 ) self.arc.place(self.region_ph)
def init_half(self, origin, side=-1): # side = -1 is left, 1 is right pars = self.params j_width = pars.j_width_1 if side < 0 else pars.j_width_2 j_length = pars.j_length if side < 0 else pars.j_length_2 suff = "_left" if side < 0 else "_right" up_st_gap = pars.sq_area / (2 * pars.sq_len) # exact correction in first row # additional extension to isolate jj's from intermediate bottom polygons # without correction horizontal faces of jj's will be adjacent # to thick intemediate polygons low_st_gap = up_st_gap + ((pars.j_length + pars.j_length_2) / 2 + pars.intermediate_width) + \ 2 * pars.intermediate_width ### upper and lower vertical intermediate and jj leads ### ## top leads ## upper_leads_extension = j_width / 4 # upper intemediate lead up_st_start = self.primitives["p_ext_up"].connections[1] + \ DVector(side * up_st_gap / 2, 0) up_st_stop = origin + \ DVector(side * up_st_gap / 2, pars.bridge / 2 + upper_leads_extension) # top jj lead self.primitives["upp_st" + suff] = Kolbaska(up_st_start, up_st_stop, j_width, upper_leads_extension) # top intermediate lead upper_thin_part_len = 4 * pars.bridge + pars.intermediate_width / 2 self.primitives["upp_st_thick" + suff] = Kolbaska( up_st_start, up_st_stop + DPoint(0, upper_thin_part_len), pars.intermediate_width, pars.intermediate_width / 2) ## bottom leads ## low_st_start = self.primitives["p_ext_down"].connections[1] + \ DVector(side * low_st_gap / 2, 0) low_st_stop = origin + \ DVector(side * (low_st_gap / 2 + 2 * pars.intermediate_width), -pars.bridge / 2 - pars.intermediate_width / 2) len_ly = (low_st_stop - low_st_start).y # bottom intermediate lead self.primitives["low_st" + suff] = CPW_RL_Path( low_st_start, 'LR', CPWParameters(pars.intermediate_width, 0), pars.intermediate_width / 2, [len_ly], [side * pi / 2], trans_in=DTrans.R90) # bottom jj lead (horizontal) low_st_end = self.primitives["low_st" + suff].connections[1] low_st_jj_start = low_st_end + DPoint( 0, -j_length / 2 + pars.intermediate_width / 2) low_st_jj_stop = low_st_jj_start + DPoint(-side * pars.b_ext, 0) self.primitives["low_st_jj" + suff] = Kolbaska(low_st_jj_start, low_st_jj_stop, j_length, j_length / 2)
def init_primitives(self): origin = DPoint(0, 0) # square box that clears out the area of the mark self.primitives["empty_box"] = Rectangle(DPoint(-self.leaf_outer, -self.leaf_outer), 2 * self.leaf_outer, 2 * self.leaf_outer, inverse=True) self.primitives["cross"] = Cross(DPoint(-self.cross_out_a / 2, -self.cross_out_a / 2), self.cross_in_a, self.cross_out_a) Z = CPWParameters(self.leaf_outer - self.leaf_inner, 0) for i in range(self.leafs_N): start_angle = i * (self.leaf_angle + self.empty_leaf_angle) - self.leaf_angle / 2 trans = DCplxTrans(1, start_angle + 90, False, 0, -self.avg_r) self.primitives["leaf_" + str(i)] = CPW_arc(Z, origin, self.avg_r, self.leaf_angle * pi / 180, trans_in=trans) Z_empty = CPWParameters(0, self.empty_rings_width / 2) for i in range(1, self.empty_rings_N + 1): r = self.leaf_inner + (self.leaf_outer - self.leaf_inner) / (self.empty_rings_N + 1) * i self.primitives["empty_ring_" + str(i)] = CPW_arc(Z_empty, DVector(0, -r), r, 2 * pi)
def __init__(self, origin, pcb_cpw_params=CPWParameters(width=200e3, gap=120e3), chip_cpw_params=CPWParameters(width=24.1e3, gap=12.95e3), pad_length=300e3, back_metal_width=0, back_metal_gap=None, transition_len=150e3, trans_in=None): self.pcb_cpw_params: CPWParameters = pcb_cpw_params self.chip_cpw_params: CPWParameters = chip_cpw_params self.pad_length = pad_length self.back_metal_length = back_metal_width if back_metal_gap is not None: self.back_metal_gap = back_metal_gap else: self.back_metal_gap = self.pcb_cpw_params.gap self.transition_length = transition_len super().__init__(origin, trans_in) self.start = self.connections[0] self.end = self.connections[1]
def draw_inductor_for_fl_line(design, fl_line_idx): cpwrl_fl = self.cpw_fl_lines[fl_line_idx] cpwrl_fl_inductor_start = cpwrl_fl.end + \ DVector(0, -design.current_line_width / 2) cpwrl_fl_inductor = CPW( cpw_params=CPWParameters(width=design.current_line_width, gap=0), start=cpwrl_fl_inductor_start, end=cpwrl_fl_inductor_start + DVector(2 * abs(design.flux_lines_x_shifts[fl_line_idx]), 0)) cpwrl_fl_inductor.place(design.region_ph) cpwrl_fl_inductor_empty_box = Rectangle( origin=cpwrl_fl.end + DVector(0, -design.current_line_width - 2 * design.z_md_fl.gap), width=cpwrl_fl_inductor.dr.abs(), height=2 * design.z_md_fl.gap, inverse=True) cpwrl_fl_inductor_empty_box.place(design.region_ph)
def __init__(self, origin, w_JJ, h_JJ, asymmetry, JJ_site_span, frame_cpw_params=CPWParameters(200e3, 8e3), frame_length=200e3, trans_in=None, use_cell=False): self._frame_cpw_params = frame_cpw_params self._frame_length = frame_length self._h_JJ, self._w_JJ = h_JJ, w_JJ self._asymmetry = asymmetry self._JJ_site_span = JJ_site_span self._use_cell = use_cell self._origin = origin super().__init__(origin, trans_in) self.start = self.connections[0] self.end = self.connections[1]
def draw_microwave_drvie_lines(self): self.cont_lines_y_ref = self.xmons[0].cpw_bempt.end.y - 200e3 tmp_reg = self.region_ph # place caplanar line 1md _p1 = self.contact_pads[0].end _p2 = _p1 + DPoint(1e6, 0) _p3 = self.xmons[0].cpw_l.end + DVector(-1e6, 0) _p4 = self.xmons[0].cpw_l.end + DVector(-66.2e3, 0) _p5 = _p4 + DVector(11.2e3, 0) self.cpwrl_md1 = DPathCPW( points=[_p1, _p2, _p3, _p4, _p5], cpw_parameters=[self.z_md_fl] * 5 + [CPWParameters(width=0, gap=self.z_md_fl.b / 2)], turn_radiuses=self.ctr_lines_turn_radius) self.cpwrl_md1.place(tmp_reg) self.cpw_md_lines.append(self.cpwrl_md1) # place caplanar line 2md _p1 = self.contact_pads[3].end _p2 = _p1 + DPoint(0, 500e3) _p3 = DPoint(self.xmons[1].cpw_b.end.x + self.md234_cross_bottom_dx, self.cont_lines_y_ref) _p4 = DPoint(_p3.x, self.xmons[1].cpw_b.end.y - self.md234_cross_bottom_dy) _p5 = _p4 + DPoint(0, 10e3) self.cpwrl_md2 = DPathCPW( points=[_p1, _p2, _p3, _p4, _p5], cpw_parameters=[self.z_md_fl] * 5 + [CPWParameters(width=0, gap=self.z_md_fl.b / 2)], turn_radiuses=self.ctr_lines_turn_radius) self.cpwrl_md2.place(tmp_reg) self.cpw_md_lines.append(self.cpwrl_md2) # place caplanar line 3md _p1 = self.contact_pads[5].end _p2 = _p1 + DPoint(0, 500e3) _p3 = _p2 + DPoint(-2e6, 2e6) _p5 = DPoint(self.xmons[2].cpw_b.end.x + self.md234_cross_bottom_dx, self.cont_lines_y_ref) _p4 = DPoint(_p5.x, _p5.y - 1e6) _p6 = DPoint(_p5.x, self.xmons[2].cpw_b.end.y - self.md234_cross_bottom_dy) _p7 = _p6 + DPoint(0, 10e3) self.cpwrl_md3 = DPathCPW( points=[_p1, _p2, _p3, _p4, _p5, _p6, _p7], cpw_parameters=[self.z_md_fl] * 8 + [CPWParameters(width=0, gap=self.z_md_fl.b / 2)], turn_radiuses=self.ctr_lines_turn_radius) self.cpwrl_md3.place(tmp_reg) self.cpw_md_lines.append(self.cpwrl_md3) # place caplanar line 4md _p1 = self.contact_pads[7].end _p2 = _p1 + DPoint(-3e6, 0) _p3 = DPoint(self.xmons[3].cpw_b.end.x + self.md234_cross_bottom_dx, self.cont_lines_y_ref) _p4 = DPoint(_p3.x, self.xmons[3].cpw_b.end.y - self.md234_cross_bottom_dy) _p5 = _p4 + DPoint(0, 10e3) self.cpwrl_md4 = DPathCPW( points=[_p1, _p2, _p3, _p4, _p5], cpw_parameters=[self.z_md_fl] * 5 + [CPWParameters(width=0, gap=self.z_md_fl.b / 2)], turn_radiuses=self.ctr_lines_turn_radius) self.cpwrl_md4.place(tmp_reg) self.cpw_md_lines.append(self.cpwrl_md4) # place caplanar line 5md _p1 = self.contact_pads[9].end _p2 = _p1 + DPoint(0, -0.5e6) _p3 = _p2 + DPoint(1e6, -1e6) _p4 = self.xmons[4].cpw_r.end + DVector(1e6, 0) _p5 = self.xmons[4].cpw_r.end + DVector(66.2e3, 0) _p6 = _p5 + DVector(11.2e3, 0) self.cpwrl_md5 = DPathCPW( points=[_p1, _p2, _p3, _p4, _p5, _p6], cpw_parameters=[self.z_md_fl] * 8 + [CPWParameters(width=0, gap=self.z_md_fl.b / 2)], turn_radiuses=self.ctr_lines_turn_radius, ) self.cpwrl_md5.place(tmp_reg) self.cpw_md_lines.append(self.cpwrl_md5)
def __init__(self, cell_name): super().__init__(cell_name) info_el2 = pya.LayerInfo(3, 0) # for DC contact deposition self.region_el2 = Region() self.layer_el2 = self.layout.layer(info_el2) info_bridges1 = pya.LayerInfo(4, 0) # bridge photo layer 1 self.region_bridges1 = Region() self.layer_bridges1 = self.layout.layer(info_bridges1) info_bridges2 = pya.LayerInfo(5, 0) # bridge photo layer 2 self.region_bridges2 = Region() self.layer_bridges2 = self.layout.layer(info_bridges2) # layer with polygons that will protect structures located # on the `self.region_el` - e-beam litography layer info_el_protection = pya.LayerInfo(6, 0) self.region_el_protection = Region() self.layer_el_protection = self.layout.layer(info_el_protection) # has to call it once more to add new layers self.lv.add_missing_layers() ### ADDITIONAL VARIABLES SECTION START ### # chip rectangle and contact pads self.chip = CHIP_10x10_12pads self.chip_box: pya.DBox = self.chip.box # Z = 50.09 E_eff = 6.235 (E = 11.45) self.z_md_fl: CPWParameters = CPWParameters(11e3, 5.7e3) self.ro_Z: CPWParameters = self.chip.chip_Z self.contact_pads: list[ContactPad] = self.chip.get_contact_pads( [self.z_md_fl] * 10 + [self.ro_Z] * 2) # readout line parameters self.ro_line_turn_radius: float = 200e3 self.ro_line_dy: float = 1600e3 self.cpwrl_ro_line: CPWRLPath = None self.Z0: CPWParameters = CHIP_10x10_12pads.chip_Z # resonators objects list self.resonators: List[EMResonatorTL3QbitWormRLTailXmonFork] = [] # distance between nearest resonators central conductors centers # constant step between resonators origin points along x-axis. self.resonators_dx: float = 900e3 # resonator parameters self.L_coupling_list: list[float] = [ 1e3 * x for x in [310, 320, 320, 310, 300] ] # corresponding to resonanse freq is linspaced in interval [6,9) GHz self.L0 = 1150e3 self.L1_list = [ 1e3 * x for x in [50.7218, 96.3339, 138.001, 142.77, 84.9156] ] self.r = 60e3 self.N_coils = [3] * len(self.L1_list) self.L2_list = [self.r] * len(self.L1_list) self.L3_list = [0e3] * len(self.L1_list) # to be constructed self.L4_list = [self.r] * len(self.L1_list) self.width_res = 20e3 self.gap_res = 10e3 self.Z_res = CPWParameters(self.width_res, self.gap_res) self.to_line_list = [56e3] * len(self.L1_list) self.fork_metal_width = 10e3 self.fork_gnd_gap = 15e3 self.xmon_fork_gnd_gap = 14e3 # resonator-fork parameters # for coarse C_qr evaluation self.fork_y_spans = [ x * 1e3 for x in [8.73781, 78.3046, 26.2982, 84.8277, 35.3751] ] # xmon parameters self.xmon_x_distance: float = 545e3 # from simulation of g_12 # for fine C_qr evaluation self.xmon_dys_Cg_coupling = [14e3] * 5 self.xmons: list[XmonCross] = [] self.cross_len_x = 180e3 self.cross_width_x = 60e3 self.cross_gnd_gap_x = 20e3 self.cross_len_y = 155e3 self.cross_width_y = 60e3 self.cross_gnd_gap_y = 20e3 # fork at the end of resonator parameters self.fork_x_span = self.cross_width_y + 2 * (self.xmon_fork_gnd_gap + self.fork_metal_width) # squids self.squids: List[AsymSquidDCFlux] = [] self.test_squids: List[AsymSquidDCFlux] = [] # el-dc concacts attributes # required extension of el_dc contacts into the el polygon self.dc_cont_el_ext = 0.0e3 # 1.8e3 # required extension into the photo polygon self.dc_cont_ph_ext = 1.4e3 # minimum distance from el_dc contact polygon perimeter points to # dc + el polygons perimeter. (el-dc contact polygon lies within # el + dc polygons) self.dc_cont_clearance = 1e3 # [nm] = [m*1e-9] # el-photo layer cut box width self.dc_cont_cut_width = \ SQUID_PARAMETERS.flux_line_contact_width - 2e3 # cut box clearance from initial el ^ ph regions self.dc_cont_cut_clearance = 1e3 self.el_dc_contacts: List[List[ElementBase, ...]] = [] # microwave and flux drive lines parameters self.ctr_lines_turn_radius = 100e3 self.cont_lines_y_ref: float = None # nm self.md234_cross_bottom_dy = 55e3 self.md234_cross_bottom_dx = 60e3 self.cpwrl_md1: DPathCPW = None self.cpwrl_fl1: DPathCPW = None self.cpwrl_md2: DPathCPW = None self.cpwrl_fl2: DPathCPW = None self.cpwrl_md3: DPathCPW = None self.cpwrl_fl3: DPathCPW = None self.cpwrl_md4: DPathCPW = None self.cpwrl_fl4: DPathCPW = None self.cpwrl_md5: DPathCPW = None self.cpwrl_fl5: DPathCPW = None self.cpw_fl_lines: List[DPathCPW] = [] self.cpw_md_lines: List[DPathCPW] = [] # marks self.marks: List[MarkBolgar] = []
def init_ph_el_conn_pads(self, leg_side=0): ''' draw top contact pad ''' origin = DPoint(0, 0) pars = self.params top_pad_center = origin + DVector(0, pars.pads_distance / 2) self.pad_top = Circle(top_pad_center, pars.pad_r, n_pts=pars.n, offset_angle=np.pi / 2) self.primitives["pad_top"] = self.pad_top self.top_ph_el_conn_pad = DPathCL( pts=[top_pad_center, origin + DPoint(0, pars.sq_dy / 2)], width=pars.contact_pad_width) self.primitives["top_ph_el_conn_pad"] = self.top_ph_el_conn_pad ''' draw bottom DC flux line ''' if leg_side == 1 or leg_side == 0: # print(self.bot_inter_lead_dx) self.bot_dc_flux_line_right = CPWRLPath( origin=origin + DPoint( pars.flux_line_dx / 2, -(pars.sq_dy / 4 + pars.flux_line_dy) - pars.flux_line_outer_width / 2), shape="LRL", cpw_parameters=[ CPWParameters(width=pars.flux_line_contact_width, gap=0), CPWParameters(smoothing=True), CPWParameters(width=pars.flux_line_outer_width, gap=0) ], turn_radiuses=max(pars.flux_line_outer_width, pars.flux_line_contact_width), segment_lengths=[ pars.flux_line_dy + pars.flux_line_outer_width, pars.flux_line_dx / 2 - self.bot_inter_lead_dx ], turn_angles=[np.pi / 2], trans_in=Trans.R90) self.primitives["bot_dc_flux_line_right"] = \ self.bot_dc_flux_line_right if leg_side == 0 or leg_side == -1: self.bot_dc_flux_line_left = CPWRLPath( origin=origin + DPoint( -pars.flux_line_dx / 2, -(pars.sq_dy / 4 + pars.flux_line_dy) - pars.flux_line_outer_width / 2), shape="LRL", cpw_parameters=[ CPWParameters(width=pars.flux_line_contact_width, gap=0), CPWParameters(smoothing=True), CPWParameters(width=pars.flux_line_outer_width, gap=0) ], turn_radiuses=max(pars.flux_line_outer_width, pars.flux_line_contact_width), segment_lengths=[ pars.flux_line_dy + pars.flux_line_outer_width, pars.flux_line_dx / 2 - self.bot_inter_lead_dx ], turn_angles=[-np.pi / 2], trans_in=Trans.R90) self.primitives["bot_dc_flux_line_left"] = \ self.bot_dc_flux_line_left
origin = DPoint(CHIP.dx / 2, CHIP.dy / 2) bridge = Bridge1(origin) bridge.place(cell, layer_photo1_bridges, "bridges_1") bridge.place(cell, layer_photo2_bridges, "bridges_2") p1 = DPoint(1 / 4 * CHIP.dx, CHIP.dy / 5) p2 = DPoint(3 / 4 * CHIP.dx, CHIP.dy / 4) width = 20e3 gap = 10e3 cpw = CPW(width, gap, p1, p2) cpw.place(cell, layer_photo) bridges_step = 50e3 Bridge1.bridgify_CPW(cpw, bridges_step, cell=cell, bridge_layer1=layer_photo1_bridges, bridge_layer2=layer_photo2_bridges) z2 = CPWParameters(width, gap) cpw2 = CPW_RL_Path(DPoint(400e3, 400e3), "LRLRL", z2, 60e3, 100e3, [pi / 4, pi / 3]) cpw2.place(cell, layer_photo) Bridge1.bridgify_CPW(cpw2, bridges_step, cell=cell, bridge_layer1=layer_photo1_bridges, bridge_layer2=layer_photo2_bridges) lv.zoom_fit() ### DRAWING SECTION END ###
def draw_readout_waveguide(self): ''' Subdividing horizontal waveguide adjacent to resonators into several waveguides. Even segments of this adjacent waveguide are adjacent to resonators. Bridges will be placed on odd segments later. Returns ------- None ''' # place readout waveguide ro_line_turn_radius = self.ro_line_turn_radius ro_line_dy = self.ro_line_dy ## calculating segment lengths of subdivided coupling part of ro coplanar ## # value that need to be added to `L_coupling` to get width of resonators bbox. def get_res_extension(resonator: EMResonatorTL3QbitWormRLTailXmonFork): return resonator.Z0.b + 2 * resonator.r def get_res_width(resonator: EMResonatorTL3QbitWormRLTailXmonFork): return (resonator.L_coupling + get_res_extension(resonator)) res_line_segments_lengths = [ self.resonators[0].origin.x - self.contact_pads[-1].end.x - get_res_extension(self.resonators[0]) / 2 ] # length from bend to first bbox of first resonator for i, resonator in enumerate(self.resonators[:-1]): resonator_extension = get_res_extension(resonator) resonator_width = get_res_width(resonator) next_resonator_extension = get_res_extension(self.resonators[i + 1]) # order of adding is from left to right (imagine chip geometry in your head to follow) res_line_segments_lengths.extend( [ resonator_width, # `resonator_extension` accounts for the next resonator extension # in this case all resonator's extensions are equal self.resonators_dx - (resonator_width - resonator_extension / 2) - next_resonator_extension / 2 ] ) res_line_segments_lengths.extend( [ get_res_width(self.resonators[-1]), self.resonators_dx / 2 ] ) # first and last segment will have length `self.resonator_dx/2` res_line_total_length = sum(res_line_segments_lengths) segment_lengths = [ro_line_dy] + res_line_segments_lengths + \ [ro_line_dy / 2, res_line_total_length - self.chip.pcb_feedline_d, ro_line_dy / 2] self.cpwrl_ro_line = CPW_RL_Path( self.contact_pads[-1].end, shape="LR" + ''.join(['L'] * len(res_line_segments_lengths)) + "RLRLRL", cpw_parameters=CPWParameters(self.Z0.width + 2 * FABRICATION.OVERETCHING, self.Z0.gap - 2 * FABRICATION.OVERETCHING), turn_radiuses=[ro_line_turn_radius] * 4, segment_lengths=segment_lengths, turn_angles=[pi / 2, pi / 2, pi / 2, -pi / 2], trans_in=Trans.R270 ) self.cpwrl_ro_line.place(self.region_ph)
def __init__(self, cell_name): super().__init__(cell_name) info_el2 = pya.LayerInfo(3, 0) # for DC contact deposition self.region_el2 = Region() self.layer_el2 = self.layout.layer(info_el2) info_bridges1 = pya.LayerInfo(4, 0) # bridge photo layer 1 self.region_bridges1 = Region() self.layer_bridges1 = self.layout.layer(info_bridges1) info_bridges2 = pya.LayerInfo(5, 0) # bridge photo layer 2 self.region_bridges2 = Region() self.layer_bridges2 = self.layout.layer(info_bridges2) # layer with polygons that will protect structures located # on the `self.region_el` - e-beam litography layer info_el_protection = pya.LayerInfo(6, 0) self.region_el_protection = Region() self.layer_el_protection = self.layout.layer(info_el_protection) self.lv.add_missing_layers() # has to call it once more to add new layers ### ADDITIONAL VARIABLES SECTION START ### # chip rectangle and contact pads self.chip = CHIP_10x10_12pads self.chip.pcb_gap -= 2 * FABRICATION.OVERETCHING self.chip.pcb_width += 2 * FABRICATION.OVERETCHING self.chip.pcb_Z = CPWParameters(self.chip.pcb_width, self.chip.pcb_gap) self.chip_box: pya.DBox = self.chip.box self.z_md_fl: CPWParameters = CPWParameters(11e3, 5.7e3) # Z = 50.09 E_eff = 6.235 (E = 11.45) self.ro_Z: CPWParameters = self.chip.chip_Z self.contact_pads: list[ContactPad] = self.chip.get_contact_pads( [self.z_md_fl] * 10 + [self.ro_Z] * 2, FABRICATION.OVERETCHING ) # readout line parameters self.ro_line_turn_radius: float = 200e3 self.ro_line_dy: float = 1600e3 self.cpwrl_ro_line: CPW_RL_Path = None self.Z0: CPWParameters = CHIP_10x10_12pads.chip_Z # resonators objects list self.resonators: List[EMResonatorTL3QbitWormRLTailXmonFork] = [] # distance between nearest resonators central conductors centers # constant step between resonators origin points along x-axis. self.resonators_dx: float = 900e3 # resonator parameters self.L_coupling_list: list[float] = [1e3 * x for x in [310, 320, 320, 310, 300]] # corresponding to resonanse freq is linspaced in interval [6,9) GHz self.L0 = 1150e3 self.L1_list = [1e3 * x for x in [60.7218, 91.3339, 133.001, 137.77, 79.9156]] self.r = 60e3 self.N_coils = [3] * len(self.L1_list) self.L2_list = [self.r] * len(self.L1_list) self.L3_list = [0e3] * len(self.L1_list) # to be constructed self.L4_list = [self.r] * len(self.L1_list) self.width_res = 20e3 self.gap_res = 10e3 self.Z_res = CPWParameters(self.width_res, self.gap_res) self.to_line_list = [56e3] * len(self.L1_list) self.fork_metal_width = 10e3 self.fork_gnd_gap = 15e3 self.xmon_fork_gnd_gap = 14e3 # resonator-fork parameters # for coarse C_qr evaluation self.fork_y_spans = [x * 1e3 for x in [8.73781, 78.3046, 26.2982, 84.8277, 35.3751]] # xmon parameters self.xmon_x_distance: float = 545e3 # from simulation of g_12 # for fine C_qr evaluation self.xmon_dys_Cg_coupling = [14e3] * 5 self.xmons: list[XmonCross] = [] self.cross_len_x = 180e3 self.cross_width_x = 60e3 self.cross_gnd_gap_x = 20e3 self.cross_len_y = 155e3 self.cross_width_y = 60e3 self.cross_gnd_gap_y = 20e3 # squids self.squids: List[AsymSquid] = [] self.test_squids: List[AsymSquid] = [] self.el_dc_contacts: List[List[ElementBase, ElementBase]] = [] # md and flux lines attributes self.shift_fl_y = self.cross_len_y + 60e3 self.shift_md_x = 60e3 self.shift_md_y = 510e3 self.cpwrl_md1: CPW_RL_Path = None self.cpwrl_md1_end: MDriveLineEnd = None self.cpwrl_fl1: CPW_RL_Path = None self.cpwrl_fl1_end: FluxLineEnd = None self.cpwrl_md2: CPW_RL_Path = None self.cpwrl_md2_end: MDriveLineEnd = None self.cpwrl_fl2: CPW_RL_Path = None self.cpwrl_fl2_end: FluxLineEnd = None self.cpwrl_md3: CPW_RL_Path = None self.cpwrl_md3_end: MDriveLineEnd = None self.cpwrl_fl3: CPW_RL_Path = None self.cpwrl_fl3_end: FluxLineEnd = None self.cpwrl_md4: CPW_RL_Path = None self.cpwrl_md4_end: MDriveLineEnd = None self.cpwrl_fl4: CPW_RL_Path = None self.cpwrl_fl4_end: FluxLineEnd = None self.cpwrl_md5: CPW_RL_Path = None self.cpwrl_md5_end: MDriveLineEnd = None self.cpwrl_fl5: CPW_RL_Path = None self.cpwrl_fl5_end: FluxLineEnd = None # marks self.marks: List[MarkBolgar] = []
def get_contact_pads(chip_Z_list: List[Union[CPWParameters, CPW, CPWArc]]=None, cpw_trans_list=[]): """ Constructs objects that represent contact pads. Each pad consists of cpw that matches PCB cpw dimension, then trapeziod transition region that ends with dimensions corresponding to on-chip cpw. Parameters ---------- chip_Z_list : List[Union[CPWParams, CPW, CPWArc]] list of 8 structures containing dimensions of the coplanar waveguides on chip-side of every contact pad. Order starts from top-left (index 0) in counter_clockwise direction: top contact pad at the left side of the chip has index 0. cpw_trans : List[DCplxTrans] List of transformations for every contact pad relative to the object coordinate system. Returns ------- list[ContactPad] List of contact pad objects indexed starting from top of the left corner in counter-clockwise direction. """ if len(cpw_trans_list) == 8: pass else: cpw_trans_list = [DTrans.R0 for x in range(8)] if chip_Z_list is None: chip_Z_list = [ CPWParameters( CHIP_10x5_8pads.chip_cpw_width, CHIP_10x5_8pads.chip_cpw_gap ) for i in range(8) ] elif len(chip_Z_list) != 8: raise ValueError("`cpw_params_list` length is not equal to number of pads (8).") else: chip_Z_list = [ CPWParameters( chip_z.width, chip_z.gap ) for chip_z in chip_Z_list ] dx = CHIP_10x5_8pads.dx dy = CHIP_10x5_8pads.dy pcb_feedline_d = CHIP_10x5_8pads.pcb_feedline_d pcb_Z = CHIP_10x5_8pads.pcb_Z k = 0 contact_pads_left = [ ContactPad( DPoint(0, dy - pcb_feedline_d * (i + 1)), pcb_cpw_params=pcb_Z, chip_cpw_params=chip_Z_list[k + i], pad_length=CHIP_10x5_8pads.pad_length, back_metal_width=CHIP_10x5_8pads.back_metal_width, back_metal_gap=CHIP_10x5_8pads.back_metal_gap, trans_in=cpw_trans_list[k+i] ) for i in range(3) if i == 0 ] k += 1 contact_pads_bottom = [ ContactPad( DPoint(pcb_feedline_d * (i + 1), 0), pcb_Z, chip_Z_list[k + i], back_metal_width=50e3, back_metal_gap=CHIP_10x5_8pads.back_metal_gap, trans_in=cpw_trans_list[k+i]*Trans.R90 ) for i in range(3) ] k += 3 contact_pads_right = [ ContactPad( DPoint(dx, pcb_feedline_d*(i+1)), pcb_Z, chip_Z_list[k + i], back_metal_width=50e3, back_metal_gap=CHIP_10x5_8pads.back_metal_gap, trans_in=cpw_trans_list[k+i]*Trans.R180 ) for i in range(3) if i == 0 ] k += 1 contact_pads_top = [ ContactPad( DPoint(dx - pcb_feedline_d * (i + 1), dy), pcb_Z, chip_Z_list[k + i], back_metal_width=50e3, back_metal_gap=CHIP_10x5_8pads.back_metal_gap, trans_in=cpw_trans_list[k+i]*Trans.R270 ) for i in range(3) ] # contact pads are ordered starting with top-left corner in counter-clockwise direction contact_pads = itertools.chain( contact_pads_left, contact_pads_bottom, contact_pads_right, contact_pads_top ) return list(contact_pads)
class CHIP_10x5_8pads: """ 10x5 mm chip PCB design located here: https://drive.google.com/file/d/1NHH-Gv3CaUzs8aymoRMFOllytAR4qpkV/view?usp=sharing """ dx = 10e6 dy = 5e6 pad_length = 300e3 pcb_width = 260e3 # 0.26 mm pcb_gap = 190e3 # (0.64 - 0.26) / 2 = 0.19 mm pcb_feedline_d = 2500e3 # 2.5 mm pcb_Z = CPWParameters(pcb_width, pcb_gap) back_metal_gap = 100e3 back_metal_width = 50e3 chip_cpw_width = 24e3 chip_cpw_gap = 12e3 chip_Z = CPWParameters(chip_cpw_width, chip_cpw_gap) @staticmethod def get_contact_pads(chip_Z_list: List[Union[CPWParameters, CPW, CPWArc]]=None, cpw_trans_list=[]): """ Constructs objects that represent contact pads. Each pad consists of cpw that matches PCB cpw dimension, then trapeziod transition region that ends with dimensions corresponding to on-chip cpw. Parameters ---------- chip_Z_list : List[Union[CPWParams, CPW, CPWArc]] list of 8 structures containing dimensions of the coplanar waveguides on chip-side of every contact pad. Order starts from top-left (index 0) in counter_clockwise direction: top contact pad at the left side of the chip has index 0. cpw_trans : List[DCplxTrans] List of transformations for every contact pad relative to the object coordinate system. Returns ------- list[ContactPad] List of contact pad objects indexed starting from top of the left corner in counter-clockwise direction. """ if len(cpw_trans_list) == 8: pass else: cpw_trans_list = [DTrans.R0 for x in range(8)] if chip_Z_list is None: chip_Z_list = [ CPWParameters( CHIP_10x5_8pads.chip_cpw_width, CHIP_10x5_8pads.chip_cpw_gap ) for i in range(8) ] elif len(chip_Z_list) != 8: raise ValueError("`cpw_params_list` length is not equal to number of pads (8).") else: chip_Z_list = [ CPWParameters( chip_z.width, chip_z.gap ) for chip_z in chip_Z_list ] dx = CHIP_10x5_8pads.dx dy = CHIP_10x5_8pads.dy pcb_feedline_d = CHIP_10x5_8pads.pcb_feedline_d pcb_Z = CHIP_10x5_8pads.pcb_Z k = 0 contact_pads_left = [ ContactPad( DPoint(0, dy - pcb_feedline_d * (i + 1)), pcb_cpw_params=pcb_Z, chip_cpw_params=chip_Z_list[k + i], pad_length=CHIP_10x5_8pads.pad_length, back_metal_width=CHIP_10x5_8pads.back_metal_width, back_metal_gap=CHIP_10x5_8pads.back_metal_gap, trans_in=cpw_trans_list[k+i] ) for i in range(3) if i == 0 ] k += 1 contact_pads_bottom = [ ContactPad( DPoint(pcb_feedline_d * (i + 1), 0), pcb_Z, chip_Z_list[k + i], back_metal_width=50e3, back_metal_gap=CHIP_10x5_8pads.back_metal_gap, trans_in=cpw_trans_list[k+i]*Trans.R90 ) for i in range(3) ] k += 3 contact_pads_right = [ ContactPad( DPoint(dx, pcb_feedline_d*(i+1)), pcb_Z, chip_Z_list[k + i], back_metal_width=50e3, back_metal_gap=CHIP_10x5_8pads.back_metal_gap, trans_in=cpw_trans_list[k+i]*Trans.R180 ) for i in range(3) if i == 0 ] k += 1 contact_pads_top = [ ContactPad( DPoint(dx - pcb_feedline_d * (i + 1), dy), pcb_Z, chip_Z_list[k + i], back_metal_width=50e3, back_metal_gap=CHIP_10x5_8pads.back_metal_gap, trans_in=cpw_trans_list[k+i]*Trans.R270 ) for i in range(3) ] # contact pads are ordered starting with top-left corner in counter-clockwise direction contact_pads = itertools.chain( contact_pads_left, contact_pads_bottom, contact_pads_right, contact_pads_top ) return list(contact_pads) origin = DPoint(0, 0) box = pya.DBox(origin, origin + DPoint(dx, dy)) @staticmethod def get_geometry_params_dict(prefix="", postfix=""): from collections import OrderedDict geometry_params = OrderedDict( [ ("dx, um", CHIP_10x10_12pads.dx / 1e3), ("dy, um", CHIP_10x10_12pads.dy / 1e3), ("nX", CHIP_10x10_12pads.nX), ("nY", CHIP_10x10_12pads.nY) ] ) modified_dict = OrderedDict() for key, val in geometry_params.items(): modified_dict[prefix + key + postfix] = val return modified_dict
def get_contact_pads(chip_Z_list: List[Union[CPWParameters, CPW, CPWArc]]=None, overetching: float =0.0e3): """ Constructs objects that represent contact pads. Each pad consists of cpw that matches PCB cpw dimension, then trapeziod transition region that ends with dimensions corresponding to on-chip cpw. Parameters ---------- chip_Z_list : List[Union[CPWParams, CPW, CPWArc]] list of 12 structures containing dimensions of the coplanar waveguides on chip-side of every contact pad. Order starts from top-left (index 0) in counter_clockwise direction: top contact pad at the left side of the chip has index 0. overetching : float parameter that is used to correct contact pad's dimension according to fabrication process Returns ------- list[ContactPad] List of contact pad objects indexed starting from top of the left corner in counter-clockwise direction. """ if chip_Z_list is None: chip_Z_list = [ CPWParameters( CHIP_10x10_12pads.chip_cpw_width, CHIP_10x10_12pads.chip_cpw_gap ) for i in range(12) ] elif len(chip_Z_list) != 12: raise ValueError("`cpw_params_list` length is not equal to number of pads (12).") else: chip_Z_list = [ CPWParameters( chip_z.width + 2*overetching, chip_z.gap - 2*overetching ) for chip_z in chip_Z_list ] dx = CHIP_10x10_12pads.dx dy = CHIP_10x10_12pads.dy pcb_feedline_d = CHIP_10x10_12pads.pcb_feedline_d pcb_Z = CHIP_10x10_12pads.pcb_Z back_metal_gap = 100e3 k = 0 contact_pads_left = [ ContactPad( DPoint(0, dy - pcb_feedline_d * (i + 1)), pcb_cpw_params=pcb_Z, chip_cpw_params=chip_Z_list[k + i], back_metal_width=50e3, back_metal_gap=back_metal_gap ) for i in range(3) ] k += 3 contact_pads_bottom = [ ContactPad( DPoint(pcb_feedline_d * (i + 1), 0), pcb_Z, chip_Z_list[k + i], back_metal_width=50e3, back_metal_gap=back_metal_gap, trans_in=Trans.R90 ) for i in range(3) ] k += 3 contact_pads_right = [ ContactPad( DPoint(dx, pcb_feedline_d*(i+1)), pcb_Z, chip_Z_list[k + i], back_metal_width=50e3, back_metal_gap=back_metal_gap, trans_in=Trans.R180 ) for i in range(3) ] k += 3 contact_pads_top = [ ContactPad( DPoint(dx - pcb_feedline_d * (i + 1), dy), pcb_Z, chip_Z_list[k + i], back_metal_width=50e3, back_metal_gap=back_metal_gap, trans_in=Trans.R270 ) for i in range(3) ] # contact pads are ordered starting with top-left corner in counter-clockwise direction contact_pads = itertools.chain( contact_pads_left, contact_pads_bottom, contact_pads_right, contact_pads_top ) return list(contact_pads)
class CHIP_10x10_12pads: """ 10x10 mm chip PCB design located here: https://drive.google.com/drive/folders/1TGjD5wwC28ZiLln_W8M6gFJpl6MoqZWF?usp=sharing """ dx = 10e6 dy = 10e6 pcb_width = 260e3 # 0.26 mm pcb_gap = 190e3 # (0.64 - 0.26) / 2 = 0.19 mm pcb_feedline_d = 2500e3 # 2.5 mm pcb_Z = CPWParameters(pcb_width, pcb_gap) chip_cpw_width = 24e3 chip_cpw_gap = 12e3 chip_Z = CPWParameters(chip_cpw_width, chip_cpw_gap) @staticmethod def get_contact_pads(chip_Z_list: List[Union[CPWParameters, CPW, CPWArc]]=None, overetching: float =0.0e3): """ Constructs objects that represent contact pads. Each pad consists of cpw that matches PCB cpw dimension, then trapeziod transition region that ends with dimensions corresponding to on-chip cpw. Parameters ---------- chip_Z_list : List[Union[CPWParams, CPW, CPWArc]] list of 12 structures containing dimensions of the coplanar waveguides on chip-side of every contact pad. Order starts from top-left (index 0) in counter_clockwise direction: top contact pad at the left side of the chip has index 0. overetching : float parameter that is used to correct contact pad's dimension according to fabrication process Returns ------- list[ContactPad] List of contact pad objects indexed starting from top of the left corner in counter-clockwise direction. """ if chip_Z_list is None: chip_Z_list = [ CPWParameters( CHIP_10x10_12pads.chip_cpw_width, CHIP_10x10_12pads.chip_cpw_gap ) for i in range(12) ] elif len(chip_Z_list) != 12: raise ValueError("`cpw_params_list` length is not equal to number of pads (12).") else: chip_Z_list = [ CPWParameters( chip_z.width + 2*overetching, chip_z.gap - 2*overetching ) for chip_z in chip_Z_list ] dx = CHIP_10x10_12pads.dx dy = CHIP_10x10_12pads.dy pcb_feedline_d = CHIP_10x10_12pads.pcb_feedline_d pcb_Z = CHIP_10x10_12pads.pcb_Z back_metal_gap = 100e3 k = 0 contact_pads_left = [ ContactPad( DPoint(0, dy - pcb_feedline_d * (i + 1)), pcb_cpw_params=pcb_Z, chip_cpw_params=chip_Z_list[k + i], back_metal_width=50e3, back_metal_gap=back_metal_gap ) for i in range(3) ] k += 3 contact_pads_bottom = [ ContactPad( DPoint(pcb_feedline_d * (i + 1), 0), pcb_Z, chip_Z_list[k + i], back_metal_width=50e3, back_metal_gap=back_metal_gap, trans_in=Trans.R90 ) for i in range(3) ] k += 3 contact_pads_right = [ ContactPad( DPoint(dx, pcb_feedline_d*(i+1)), pcb_Z, chip_Z_list[k + i], back_metal_width=50e3, back_metal_gap=back_metal_gap, trans_in=Trans.R180 ) for i in range(3) ] k += 3 contact_pads_top = [ ContactPad( DPoint(dx - pcb_feedline_d * (i + 1), dy), pcb_Z, chip_Z_list[k + i], back_metal_width=50e3, back_metal_gap=back_metal_gap, trans_in=Trans.R270 ) for i in range(3) ] # contact pads are ordered starting with top-left corner in counter-clockwise direction contact_pads = itertools.chain( contact_pads_left, contact_pads_bottom, contact_pads_right, contact_pads_top ) return list(contact_pads) origin = DPoint(0, 0) box = pya.DBox(origin, origin + DPoint(dx, dy)) @staticmethod def get_geometry_params_dict(prefix="", postfix=""): from collections import OrderedDict geometry_params = OrderedDict( [ ("dx, um", CHIP_10x10_12pads.dx / 1e3), ("dy, um", CHIP_10x10_12pads.dy / 1e3), ("nX", CHIP_10x10_12pads.nX), ("nY", CHIP_10x10_12pads.nY) ] ) modified_dict = OrderedDict() for key, val in geometry_params.items(): modified_dict[prefix + key + postfix] = val return modified_dict
def init_half(self, origin, side=-1): # side = -1 is width left half, 1 is width right half pars = self.params j_dy = pars.j1_dy if side < 0 else pars.j2_dy j_dx = pars.j1_dx if side < 0 else pars.j2_dx suff = "_left" if side < 0 else "_right" # euristic value is chosen to ensure that JJ lead do not suffer # overexposure due to proximity to top intermediate lead top_jj_lead_dy = 5 * pars.inter_leads_width ''' Logic of parameters formulas by solving following equations by := bot_inter_lead_dy - j_dy/2 ty := top_inter_lead_dy + top_jj_lead_dy + j_dy/2 + pars.bridge bx := bot_inter_lead_dx tx := top_inter_lead_dx phi := pars.intermediate_width/2 + 2/3*pars.b_ext L := pars.sq_dy A = pars.sq_area/2 system: tx * ty + bx * tx = A ty + by = L bx - tx = phi - JJ's are located at 2/3 b_ext from bottom intermediate leads by - ty = 0 - euristic, for completion If you will substitute values from definition above and look at the design of width SQUID's layout you will get the idea about this gives bx = A/L + phi/2 tx = A/L - phi/2 ty = L/2 by = L/2 and it follows that bot_inter_lead_dy = pars.sq_dy/2 + j_dy/2 top_inter_lead_dy = pars.sq_dy/2 - (top_jj_lead_dy + j_dy/2 + pars.bridge) bot_inter_lead_dx = pars.sq_area/pars.sq_dy/2 + (pars.inter_leads_width/2 + 2/3*pars.b_ext)/2 top_inter_lead_dx = pars.sq_area/pars.sq_dy/2 - (pars.inter_leads_width/2 + 2/3*pars.b_ext)/2 ''' bot_inter_lead_dy = pars.sq_dy / 2 + j_dy / 2 top_inter_lead_dy = pars.sq_dy / 2 - (top_jj_lead_dy + j_dy / 2 + pars.bridge) self.bot_inter_lead_dx = ( pars.sq_area / pars.sq_dy / 2 + (pars.inter_leads_width / 2 + 2 / 3 * pars.b_ext) / 2) top_inter_lead_dx = ( pars.sq_area / pars.sq_dy / 2 - (pars.inter_leads_width / 2 + 2 / 3 * pars.b_ext) / 2) ''' draw top intermediate lead''' # `pars.inter_leads_width/2` is made to ensure that SQUID countour # is connected at adjacent points lying on line x=0. top_inter_p1 = origin + DPoint(0, pars.sq_dy / 2) top_inter_p2 = top_inter_p1 + DPoint(side * top_inter_lead_dx, 0) top_inter_p3 = top_inter_p2 + DPoint(0, -top_inter_lead_dy) self.primitives["top_inter_lead" + suff] = DPathCL( pts=[top_inter_p1, top_inter_p2, top_inter_p3], width=pars.inter_leads_width, bgn_ext=pars.inter_leads_width / 2, end_ext=pars.inter_leads_width / 4, round=True, bendings_r=pars.inter_leads_width) ''' draw top JJ lead ''' top_jj_lead_cpw2cpw_p1 = top_inter_p3 top_jj_lead_cpw2cpw_p2 = top_jj_lead_cpw2cpw_p1 + DPoint( 0, -top_jj_lead_dy / 2) top_jj_rigid_lead = CPW2CPW(Z0=CPWParameters( width=pars.inter_leads_width, gap=0), Z1=CPWParameters(width=j_dx, gap=0), start=top_jj_lead_cpw2cpw_p1, end=top_jj_lead_cpw2cpw_p2) self.primitives["top_jj_rigid_lead" + suff] = top_jj_rigid_lead top_jj_lead_p1 = top_jj_rigid_lead.end top_jj_lead_p2 = top_jj_lead_p1 + DPoint(0, -top_jj_lead_dy / 2) self.primitives["top_jj_lead" + suff] = DPathCL( pts=[top_jj_lead_p1, top_jj_lead_p2], width=j_dx, bgn_ext=pars.inter_leads_width / 4, round=True) ''' draw buttom intermediate lead ''' bottom_y = top_jj_lead_p2.y - pars.bridge - bot_inter_lead_dy bot_inter_lead_p1 = DPoint(0, bottom_y) bot_inter_lead_p2 = bot_inter_lead_p1 + DPoint( side * self.bot_inter_lead_dx, 0) bot_inter_lead_p3 = bot_inter_lead_p2 + DPoint(0, bot_inter_lead_dy) self.primitives["bot_inter_lead" + suff] = CPWRLPath( origin=bot_inter_lead_p1, shape="LRL", cpw_parameters=[ CPWParameters(width=pars.flux_line_inner_width, gap=0), CPWParameters(smoothing=True), CPWParameters(width=pars.inter_leads_width, gap=0) ], turn_radiuses=pars.inter_leads_width, segment_lengths=[ bot_inter_lead_p1.distance(bot_inter_lead_p2), bot_inter_lead_p2.distance(bot_inter_lead_p3) + pars.inter_leads_width / 2 ], turn_angles=[np.pi / 2], trans_in=Trans.M90 if side == -1 else None) ''' draw bottom JJ lead ''' bot_jj_lead_rigid_p1 = bot_inter_lead_p3 + DPoint( -side * pars.inter_leads_width / 2, -j_dy / 2) bot_jj_lead_rigid_p2 = bot_jj_lead_rigid_p1 + DPoint( -side * pars.b_ext / 3, 0) bot_jj_lead_rigid = CPW2CPW(Z0=CPWParameters( width=pars.inter_leads_width, gap=0), Z1=CPWParameters(width=j_dy, gap=0), start=bot_jj_lead_rigid_p1, end=bot_jj_lead_rigid_p2) self.primitives["bot_jj_lead_rigid" + suff] = bot_jj_lead_rigid bot_jj_lead_p1 = bot_jj_lead_rigid_p1 bot_jj_lead_p2 = bot_jj_lead_rigid_p1 + DPoint(-side * pars.b_ext, 0) self.primitives["bot_jj_lead" + suff] = DPathCL( pts=[bot_jj_lead_p1, bot_jj_lead_p2], width=j_dy, bgn_ext=pars.inter_leads_width / 4, round=True)
def create_resonator_objects(self): # fork at the end of resonator parameters fork_x_span = self.cross_width_y + 2 * (self.xmon_fork_gnd_gap + self.fork_metal_width) ### RESONATORS TAILS CALCULATIONS SECTION START ### # key to the calculations can be found in hand-written format here: # https://drive.google.com/file/d/1wFmv5YmHAMTqYyeGfiqz79a9kL1MtZHu/view?usp=sharing # x span between left long vertical line and # right-most center of central conductors resonators_widths = [2 * self.r + L_coupling for L_coupling in self.L_coupling_list] x1 = 2 * self.resonators_dx + resonators_widths[2] / 2 - 2 * self.xmon_x_distance x2 = x1 + self.xmon_x_distance - self.resonators_dx x3 = resonators_widths[2] / 2 x4 = 3 * self.resonators_dx - (x1 + 3 * self.xmon_x_distance) x5 = 4 * self.resonators_dx - (x1 + 4 * self.xmon_x_distance) res_tail_shape = "LRLRL" tail_turn_radiuses = self.r # list corrected for resonator-qubit coupling geomtry, so all transmons centers are placed # along single horizontal line self.L0_list = [self.L0 - xmon_dy_Cg_coupling for xmon_dy_Cg_coupling in self.xmon_dys_Cg_coupling] self.L2_list[0] += 6 * self.Z_res.b self.L2_list[1] += 0 self.L2_list[3] += 3 * self.Z_res.b self.L2_list[4] += 6 * self.Z_res.b self.L3_list[0] = x1 self.L3_list[1] = x2 self.L3_list[2] = x3 self.L3_list[3] = x4 self.L3_list[4] = x5 self.L4_list[1] += 6 * self.Z_res.b self.L4_list[2] += 6 * self.Z_res.b self.L4_list[3] += 3 * self.Z_res.b tail_segment_lengths_list = [[L2, L3, L4 + FABRICATION.OVERETCHING] for L2, L3, L4 in zip(self.L2_list, self.L3_list, self.L4_list)] tail_turn_angles_list = [ [pi / 2, -pi / 2], [pi / 2, -pi / 2], [pi / 2, -pi / 2], [-pi / 2, pi / 2], [-pi / 2, pi / 2], ] tail_trans_in_list = [ Trans.R270, Trans.R270, Trans.R270, Trans.R270, Trans.R270 ] ### RESONATORS TAILS CALCULATIONS SECTION END ### pars = list( zip( self.L1_list, self.to_line_list, self.L_coupling_list, self.fork_y_spans, tail_segment_lengths_list, tail_turn_angles_list, tail_trans_in_list, self.L0_list, self.N_coils ) ) for res_idx, params in enumerate(pars): # parameters exctraction L1 = params[0] to_line = params[1] L_coupling = params[2] fork_y_span = params[3] tail_segment_lengths = params[4] tail_turn_angles = params[5] tail_trans_in = params[6] L0 = params[7] n_coils = params[8] # deduction for resonator placements # under condition that Xmon-Xmon distance equals # `xmon_x_distance` worm_x = self.contact_pads[-1].end.x + (res_idx + 1 / 2) * self.resonators_dx worm_y = self.contact_pads[-1].end.y - self.ro_line_dy - to_line resonator_cpw = CPWParameters(self.Z_res.width + 2 * FABRICATION.OVERETCHING, self.Z_res.gap - 2 * FABRICATION.OVERETCHING) self.resonators.append( EMResonatorTL3QbitWormRLTailXmonFork( resonator_cpw, DPoint(worm_x, worm_y), L_coupling, L0, L1, self.r, n_coils, tail_shape=res_tail_shape, tail_turn_radiuses=tail_turn_radiuses, tail_segment_lengths=tail_segment_lengths, tail_turn_angles=tail_turn_angles, tail_trans_in=tail_trans_in, fork_x_span=fork_x_span + 2 * FABRICATION.OVERETCHING, fork_y_span=fork_y_span, fork_metal_width=self.fork_metal_width + 2 * FABRICATION.OVERETCHING, fork_gnd_gap=self.fork_gnd_gap - 2 * FABRICATION.OVERETCHING ) )
sideX_length=cross_len_x, sideX_width=cross_width_x, sideX_gnd_gap=cross_gnd_gap_x, sideY_length=cross_len_y, sideY_width=cross_width_y, sideY_gnd_gap=cross_gnd_gap_y) tmp_reg = Region() worm_test.place(tmp_reg) xmonCross_test.place(tmp_reg) bbox = tmp_reg.bbox() import math # main drive line coplanar width = 20e3 gap = 10e3 z0_cpw_params = CPWParameters(width, gap) CHIP.dx = 1.2 * bbox.width() + 8 * Z_res.b CHIP.nX = int(CHIP.dx / 2.5e3) y = CHIP.dy - 150e3 - (width + 2 * gap) / 2 p1 = DPoint(0, y) p2 = DPoint(CHIP.dx, y) Z0 = CPW(start=p1, end=p2, cpw_params=z0_cpw_params) # clear this cell and layer cell.clear() fork_y_span = xmon_fork_penetration + xmon_fork_gnd_gap import math if math.copysign(1, tail_turn_angles[0]) > 0: worm_x = 5 * Z_res.b + Z_res.b / 2
def draw_md_and_flux_lines(self): """ Drawing of md (microwave drive) and flux tuning lines for 5 qubits Returns ------- """ contact_pads = self.contact_pads ctr_line_turn_radius = 100e3 xmon_center = self.xmons[-1].center xmon_x_distance = self.xmon_x_distance cross_width_y = self.cross_width_y cross_width_x = self.cross_width_x cross_len_x = self.cross_len_x cross_len_y = self.cross_len_y cross_gnd_gap_y = self.cross_gnd_gap_y cross_gnd_gap_x = self.cross_gnd_gap_x width_res = self.Z_res.width tmp_reg = self.region_ph z_md_fl_corrected = CPWParameters( self.z_md_fl.width + 2 * FABRICATION.OVERETCHING, self.z_md_fl.gap - 2 * FABRICATION.OVERETCHING ) shift_fl_y = self.shift_fl_y shift_md_x = self.shift_md_x shift_md_y = self.shift_md_y md0_md5_gnd = 5e3 flux_end_width = self.cross_width_x + 2 * self.cross_gnd_gap_x - 2 * FABRICATION.OVERETCHING md_transition = 25e3 md_z1_params = z_md_fl_corrected md_z1_length = 245e3 shift_md_x_side = md_z1_length + md_transition + md_z1_params.b / 2 + cross_len_x + cross_width_x / 2 + cross_gnd_gap_x # place caplanar line 1md self.cpwrl_md1 = CPW_RL_Path( contact_pads[0].end, shape="LRLRL", cpw_parameters=z_md_fl_corrected, turn_radiuses=[ctr_line_turn_radius] * 2, segment_lengths=[ 2 * (-contact_pads[0].end.x + xmon_center.x - 4 * xmon_x_distance - shift_md_x_side) / 16, ( (contact_pads[0].end.y - xmon_center.y) ** 2 + (9 * (-contact_pads[0].end.x + xmon_center.x - 4 * xmon_x_distance - shift_md_x_side) / 16) ** 2 ) ** 0.5, 5 * (-contact_pads[ 0].end.x + xmon_center.x - 4 * xmon_x_distance - shift_md_x_side) / 16 - md0_md5_gnd], turn_angles=[-atan2(contact_pads[0].end.y - xmon_center.y, 9 * (-contact_pads[ 0].end.x + xmon_center.x - 4 * xmon_x_distance - shift_md_x_side) / 16), atan2(contact_pads[0].end.y - xmon_center.y, 9 * (-contact_pads[ 0].end.x + xmon_center.x - 4 * xmon_x_distance - shift_md_x_side) / 16)], trans_in=Trans.R0 ) self.cpwrl_md1.place(tmp_reg) self.cpwrl_md1_end = MDriveLineEnd(list(self.cpwrl_md1.primitives.values())[-1], md_z1_params, md_transition, md_z1_length) self.cpwrl_md1_end.place(tmp_reg) # place caplanar line 1 fl self.cpwrl_fl1 = CPW_RL_Path( contact_pads[1].end, shape="LRL", cpw_parameters=z_md_fl_corrected, turn_radiuses=[ctr_line_turn_radius], segment_lengths=[ -contact_pads[1].end.x + xmon_center.x - 4 * xmon_x_distance - cross_len_x, xmon_center.y - contact_pads[1].end.y - cross_width_x / 2 - cross_gnd_gap_x - z_md_fl_corrected.width + FABRICATION.OVERETCHING ], turn_angles=[pi / 2], trans_in=Trans.R0 ) self.cpwrl_fl1.place(tmp_reg) self.cpwrl_fl1_end = FluxLineEnd(self.cpwrl_fl1.end, z_md_fl_corrected, width=flux_end_width, trans_in=Trans.R0) self.cpwrl_fl1_end.place(tmp_reg) # place caplanar line 2md self.cpwrl_md2 = CPW_RL_Path( contact_pads[3].end, shape="LRLRLRL", cpw_parameters=z_md_fl_corrected, turn_radiuses=[ctr_line_turn_radius] * 3, segment_lengths=[ (-contact_pads[3].end.y + xmon_center.y - shift_md_y) / 4, (-contact_pads[3].end.x + xmon_center.x + shift_md_x - 3 * xmon_x_distance) / 2, ( ( (-contact_pads[3].end.x + xmon_center.x + shift_md_x - 3 * xmon_x_distance) / 2 ) ** 2 + ( 5 * (-contact_pads[3].end.y + xmon_center.y - shift_md_y) / 8 ) ** 2 ) ** 0.5, (-contact_pads[3].end.y + xmon_center.y - shift_md_y) / 8 ], turn_angles=[-pi / 2, atan2(5 * (-contact_pads[3].end.y + xmon_center.y - shift_md_y) / 8, ( -contact_pads[3].end.x + xmon_center.x + shift_md_x - 3 * xmon_x_distance) / 2), pi / 2 - atan2(5 * (-contact_pads[3].end.y + xmon_center.y - shift_md_y) / 8, ( -contact_pads[3].end.x + xmon_center.x + shift_md_x - 3 * xmon_x_distance) / 2)], trans_in=Trans.R90 ) self.cpwrl_md2.place(tmp_reg) self.cpwrl_md2_end = MDriveLineEnd( list(self.cpwrl_md2.primitives.values())[-1], md_z1_params, md_transition, md_z1_length ) self.cpwrl_md2_end.place(tmp_reg) # place caplanar line 2 fl self.cpwrl_fl2 = CPW_RL_Path( contact_pads[2].end, shape="LRLRL", cpw_parameters=z_md_fl_corrected, turn_radiuses=[ctr_line_turn_radius] * 2, segment_lengths=[(-contact_pads[2].end.x + xmon_center.x - 3 * xmon_x_distance) / 4, ( (3 * (-contact_pads[2].end.x + xmon_center.x - 3 * xmon_x_distance) / 4) ** 2 + ( 7 * (-contact_pads[2].end.y + xmon_center.y - shift_fl_y) / 8) ** 2) ** 0.5, (-contact_pads[2].end.y + xmon_center.y - shift_fl_y) / 8], turn_angles=[atan2(7 * (-contact_pads[2].end.y + xmon_center.y - shift_fl_y) / 8, 3 * (-contact_pads[2].end.x + xmon_center.x - 3 * xmon_x_distance) / 4), pi / 2 - atan2(7 * (-contact_pads[2].end.y + xmon_center.y - shift_fl_y) / 8, 3 * (-contact_pads[2].end.x + xmon_center.x - 3 * xmon_x_distance) / 4)], trans_in=Trans.R0 ) self.cpwrl_fl2.place(tmp_reg) self.cpwrl_fl2_end = FluxLineEnd(self.cpwrl_fl2.end, z_md_fl_corrected, width=flux_end_width, trans_in=Trans.R0) self.cpwrl_fl2_end.place(tmp_reg) # place caplanar line 3md self.cpwrl_md3_1 = CPW_RL_Path( contact_pads[5].end, shape="LRLRLRL", cpw_parameters=z_md_fl_corrected, turn_radiuses=[ctr_line_turn_radius] * 3, segment_lengths=[ (-contact_pads[5].end.y + xmon_center.y - shift_md_y) / 4, (contact_pads[5].end.x - xmon_center.x - shift_md_x + 2 * xmon_x_distance) / 2, ( ( (contact_pads[5].end.x - xmon_center.x - shift_md_x + 2 * xmon_x_distance) / 2 ) ** 2 + ( 5 * (-contact_pads[5].end.y + xmon_center.y - shift_md_y) / 8 ) ** 2 ) ** 0.5 - 400e3, (-contact_pads[5].end.y + xmon_center.y - shift_md_y) / 8], turn_angles=[pi / 2, -atan2(5 * (-contact_pads[5].end.y + xmon_center.y - shift_md_y) / 8, (contact_pads[5].end.x - xmon_center.x - shift_md_x + 2 * xmon_x_distance) / 2), -pi / 2 + atan2(5 * (-contact_pads[5].end.y + xmon_center.y - shift_md_y) / 8, ( contact_pads[5].end.x - xmon_center.x - shift_md_x + 2 * xmon_x_distance) / 2)], trans_in=Trans.R90 ) self.cpwrl_md3_1.place(tmp_reg) dy = self.cpwrl_md2.end.y - self.cpwrl_md3_1.end.y dx = self.cpwrl_md3_1.end.x - (self.xmons[2].center.x + shift_md_x) md3_2_radius = ctr_line_turn_radius - 50e3 self.cpwrl_md3_2 = CPW_RL_Path( self.cpwrl_md3_1.end, shape="LRLR", cpw_parameters=z_md_fl_corrected, turn_radiuses=[md3_2_radius] * 2, segment_lengths=[dy - md3_2_radius, dx], turn_angles=[pi / 2, -pi / 2], trans_in=Trans.R90 ) self.cpwrl_md3_2.place(tmp_reg) self.cpwrl_md3_end = MDriveLineEnd( list(self.cpwrl_md3_2.primitives.values())[-1], md_z1_params, md_transition, md_z1_length ) self.cpwrl_md3_end.place(tmp_reg) # place caplanar line 3 fl fl_l1 = (self.xmons[2].cpw_bempt.end.y - contact_pads[4].end.y) / 4 fl_l3 = fl_l1 dr = self.xmons[2].cpw_bempt.end - contact_pads[4].end dr.y = dr.y - fl_l1 - fl_l3 - z_md_fl_corrected.width turn_angle = atan2(-dr.x, dr.y) fl_l2 = dr.abs() self.cpwrl_fl3 = CPW_RL_Path( self.contact_pads[4].end, shape="LRLRL", cpw_parameters=z_md_fl_corrected, turn_radiuses=[ctr_line_turn_radius] * 2, segment_lengths=[fl_l1, fl_l2, fl_l3], turn_angles=[turn_angle, -turn_angle], trans_in=Trans.R90 ) self.cpwrl_fl3.place(tmp_reg) self.cpwrl_fl3_end = FluxLineEnd(self.cpwrl_fl3.end, z_md_fl_corrected, width=flux_end_width, trans_in=Trans.R0) self.cpwrl_fl3_end.place(tmp_reg) # place caplanar line 4 md md4_len_y = -contact_pads[7].end.y + xmon_center.y - shift_md_y md4_fl4_dx = 100e3 self.cpwrl_md4 = CPW_RL_Path( contact_pads[7].end, shape="LRLRLRL", cpw_parameters=z_md_fl_corrected, turn_radiuses=ctr_line_turn_radius / 2, segment_lengths=[ contact_pads[7].end.x - xmon_center.x + xmon_x_distance - shift_md_x - md4_fl4_dx, md4_len_y - ctr_line_turn_radius / 2, md4_fl4_dx, ctr_line_turn_radius / 2 ], turn_angles=[-pi / 2, pi / 2, -pi / 2], trans_in=Trans.R180 ) self.cpwrl_md4.place(tmp_reg) self.cpwrl_md4_end = MDriveLineEnd( list(self.cpwrl_md4.primitives.values())[-1], md_z1_params, md_transition, md_z1_length ) self.cpwrl_md4_end.place(tmp_reg) # place caplanar line 4 fl self.cpwrl_fl4 = CPW_RL_Path( contact_pads[6].end, shape="LRLRL", cpw_parameters=z_md_fl_corrected, turn_radiuses=[ctr_line_turn_radius] * 2, segment_lengths=[(contact_pads[6].end.x - xmon_center.x + xmon_x_distance) / 4, ((6 * (-contact_pads[6].end.y + xmon_center.y - shift_fl_y) / 8) ** 2 + (3 * (contact_pads[6].end.x - xmon_center.x + xmon_x_distance) / 4) ** 2) ** 0.5, 2 * (-contact_pads[6].end.y + xmon_center.y - shift_fl_y) / 8], turn_angles=[-atan2(6 * (-contact_pads[6].end.y + xmon_center.y - shift_fl_y) / 8, 3 * (contact_pads[6].end.x - xmon_center.x + xmon_x_distance) / 4), -pi / 2 + atan2(6 * (-contact_pads[6].end.y + xmon_center.y - shift_fl_y) / 8, 3 * (contact_pads[6].end.x - xmon_center.x + xmon_x_distance) / 4)], trans_in=Trans.R180 ) self.cpwrl_fl4.place(tmp_reg) self.cpwrl_fl4_end = FluxLineEnd(self.cpwrl_fl4.end, z_md_fl_corrected, width=flux_end_width, trans_in=Trans.R0) self.cpwrl_fl4_end.place(tmp_reg) # place caplanar line 5 md md5_l1 = 2 * (contact_pads[9].end.y - xmon_center.y) / 3 md5_dy = 400e3 md5_dx = 400e3 md5_angle = atan2( 2 * (contact_pads[9].end.x - xmon_center.x - shift_md_x_side) / 3, (contact_pads[9].end.y - xmon_center.y) / 3 ) self.cpwrl_md5 = CPW_RL_Path( contact_pads[9].end, shape="LRLRLRLRL", cpw_parameters=z_md_fl_corrected, turn_radiuses=[ctr_line_turn_radius] * 4, segment_lengths=[ md5_dy, md5_dx / sin(pi / 4), md5_l1 - md5_dy - md5_dx / tan(pi / 4) - md5_dx / tan(md5_angle), md5_dx / sin(md5_angle) + ( ( (contact_pads[9].end.y - xmon_center.y) / 3 ) ** 2 + ( 2 * (contact_pads[9].end.x - xmon_center.x - shift_md_x_side) / 3 ) ** 2 ) ** (0.5), (contact_pads[9].end.x - xmon_center.x - shift_md_x_side) / 3 - md0_md5_gnd ], turn_angles=[ pi / 4, -pi / 4, -md5_angle, -(pi / 2 - md5_angle) ], trans_in=Trans.R270 ) # self.cpwrl_md5 = CPW_RL_Path( # contact_pads[9].end, shape="LRLRL", cpw_parameters=z_md_fl_corrected, # turn_radiuses=[ctr_line_turn_radius] * 2, # segment_lengths=[ # md5_l1, # ( # ( # (contact_pads[9].end.y - xmon_center.y) / 3 # ) ** 2 + # ( # 2 * (contact_pads[9].end.x - xmon_center.x - shift_md_x_side) / 3 # ) ** 2 # ) ** (0.5), # (contact_pads[9].end.x - xmon_center.x - shift_md_x_side) / 3 - md0_md5_gnd # ], # turn_angles=[ # md5_angle, # -md5_angle - pi / 2 # ], # trans_in=Trans.R270 # ) self.cpwrl_md5.place(tmp_reg) self.cpwrl_md5_end = MDriveLineEnd( list(self.cpwrl_md5.primitives.values())[-1], md_z1_params, md_transition, md_z1_length ) self.cpwrl_md5_end.place(tmp_reg) # place caplanar line 5 fl self.cpwrl_fl5_1 = CPW_RL_Path( contact_pads[8].end, shape="LRLRLR", cpw_parameters=z_md_fl_corrected, turn_radiuses=[ctr_line_turn_radius] * 3, segment_lengths=[ (contact_pads[8].end.x - xmon_center.x) / 4, ((contact_pads[8].end.y - xmon_center.y) + 250e3) / 3 + 50e3, ( (2 * ((contact_pads[8].end.y - xmon_center.y) + 250e3) / 3) ** 2 + ((contact_pads[8].end.x - xmon_center.x) / 2) ** 2 ) ** 0.5 ], turn_angles=[ pi / 2, -atan2((contact_pads[8].end.x - xmon_center.x) / 2, 2 * ((contact_pads[8].end.y - xmon_center.y) + 250e3) / 3), - pi / 2 + atan2((contact_pads[8].end.x - xmon_center.x) / 2, 2 * ((contact_pads[8].end.y - xmon_center.y) + 250e3) / 3) ], trans_in=Trans.R180 ) self.cpwrl_fl5_1.place(tmp_reg) self.cpwrl_fl5_2 = CPW_RL_Path( self.cpwrl_fl5_1.end, shape="LRL", cpw_parameters=z_md_fl_corrected, turn_radiuses=[ctr_line_turn_radius], segment_lengths=[ self.cpwrl_fl5_1.end.x - (self.xmons[4].center.x + cross_width_y / 2 + cross_len_x + cross_gnd_gap_x - flux_end_width / 2), self.xmons[4].center.y - self.cpwrl_fl5_1.end.y - cross_width_x / 2 - cross_gnd_gap_x - z_md_fl_corrected.width + FABRICATION.OVERETCHING ], turn_angles=[-pi / 2], trans_in=Trans.R180 ) self.cpwrl_fl5_2.place(tmp_reg) self.cpwrl_fl5_end = FluxLineEnd(self.cpwrl_fl5_2.end, z_md_fl_corrected, width=flux_end_width, trans_in=Trans.R0) self.cpwrl_fl5_end.place(tmp_reg)
def __init__(self, cell_name): super().__init__(cell_name) info_el2 = pya.LayerInfo(3, 0) # for DC contact deposition self.region_el2 = Region() self.layer_el2 = self.layout.layer(info_el2) info_bridges1 = pya.LayerInfo(4, 0) # bridge photo layer 1 self.region_bridges1 = Region() self.layer_bridges1 = self.layout.layer(info_bridges1) info_bridges2 = pya.LayerInfo(5, 0) # bridge photo layer 2 self.region_bridges2 = Region() self.layer_bridges2 = self.layout.layer(info_bridges2) self.lv.add_missing_layers( ) # has to call it once more to add new layers ### ADDITIONAL VARIABLES SECTION START ### self.contact_pads: list[ContactPad] = None # chip rectangle and contact pads self.chip = CHIP_10x10_12pads self.chip_box = self.chip.box # readout line parameters self.ro_line_turn_radius: float = 200e3 self.ro_line_dy: float = 1600e3 self.cpwrl_ro_line: CPW_RL_Path = None self.Z0 = CPWParameters(CHIP_10x10_12pads.chip_cpw_width, CHIP_10x10_12pads.chip_cpw_gap) # resonators objects list self.resonators: List[EMResonatorTL3QbitWormRLTailXmonFork] = [] # distance between nearest resonators central conductors centers # constant step between resonators origin points along x-axis. self.resonators_dx = 790e3 # resonator parameters self.L_coupling_list = [1e3 * x for x in [230, 225, 225, 220, 215]] # corresponding to resonanse freq is linspaced in interval [6,9) GHz self.L0 = 1600e3 self.L1_list = [1e3 * x for x in [53.7163, 73, 91, 87, 48]] self.r = 60e3 self.N = 5 self.L2_list = [self.r] * len(self.L1_list) self.L3_list = [None] * len(self.L1_list) # to be constructed self.L4_list = [self.r] * len(self.L1_list) self.width_res = 20e3 self.gap_res = 10e3 self.Z_res = CPWParameters(self.width_res, self.gap_res) self.to_line_list = [53e3] * len(self.L1_list) self.fork_metal_width = 20e3 self.fork_gnd_gap = 10e3 self.xmon_fork_gnd_gap = 25e3 # resonator-fork parameters # -20e3 for Xmons in upper sweet-spot # -10e3 for Xmons in lower sweet-spot self.xmon_fork_penetration_list = [-25e3] * len(self.L1_list) # xmon parameters self.cross_width: float = 60e3 self.cross_len: float = 60e3 self.cross_gnd_gap: float = 20e3 self.xmon_x_distance: float = 485e3 # from simulation of g_12 self.xmon_dys_Cg_coupling = [ 1e3 * x for x in [11.2065, 9.31433, 12.0965, 10.0777, 12.9573] ] self.xmons: list[XmonCross] = [] self.cross_len_x = 180e3 self.cross_width_x = 60e3 self.cross_gnd_gap_x = 20e3 self.cross_len_y = 60e3 self.cross_width_y = 60e3 self.cross_gnd_gap_y = 20e3 # squids self.squids: List[AsymSquid] = [] self.el_dc_contacts: List[List[ElementBase, ElementBase]] = [] # md and flux lines attributes self.shift_fl_y = self.cross_len_y + 70e3 self.shift_md_x = 150e3 self.shift_md_y = 360e3 self.cpwrl_md1: CPW_RL_Path = None self.cpwrl_md1_end: MDriveLineEnd = None self.cpwrl_fl1: CPW_RL_Path = None self.cpwrl_fl1_end: FluxLineEnd = None self.cpwrl_md2: CPW_RL_Path = None self.cpwrl_md2_end: MDriveLineEnd = None self.cpwrl_fl2: CPW_RL_Path = None self.cpwrl_fl2_end: FluxLineEnd = None self.cpwrl_md3: CPW_RL_Path = None self.cpwrl_md3_end: MDriveLineEnd = None self.cpwrl_fl3: CPW_RL_Path = None self.cpwrl_fl3_end: FluxLineEnd = None self.cpwrl_md4: CPW_RL_Path = None self.cpwrl_md4_end: MDriveLineEnd = None self.cpwrl_fl4: CPW_RL_Path = None self.cpwrl_fl4_end: FluxLineEnd = None self.cpwrl_md5: CPW_RL_Path = None self.cpwrl_md5_end: MDriveLineEnd = None self.cpwrl_fl5: CPW_RL_Path = None self.cpwrl_fl5_end: FluxLineEnd = None # marks self.marks: List[Mark2] = []
class CHIP: """ 10x10 mm chip PCB design located here: https://drive.google.com/drive/folders/1TGjD5wwC28ZiLln_W8M6gFJpl6MoqZWF?usp=sharing """ dx = 5e6 dy = 5e6 origin = DPoint(0, 0) box = pya.Box().from_dbox(pya.DBox(origin, origin + DPoint(dx, dy))) pcb_width = 260e3 # 0.26 mm pcb_gap = 190e3 # (0.64 - 0.26) / 2 = 0.19 mm pcb_feedline_d = 2500e3 # 2.5 mm pcb_Z = CPWParameters(pcb_width, pcb_gap) cpw_width = 24.1e3 cpw_gap = 12.95e3 chip_Z = CPWParameters(cpw_width, cpw_gap) @staticmethod def get_contact_pads(): dx = CHIP.dx dy = CHIP.dy pcb_feedline_d = CHIP.pcb_feedline_d pcb_Z = CHIP.pcb_Z chip_Z = CHIP.chip_Z contact_pads_left = [ ContactPad(DPoint(0, dy - pcb_feedline_d * (i + 1)), pcb_Z, chip_Z, back_metal_width=50e3, back_metal_gap=100e3) for i in range(3) ] contact_pads_bottom = [ ContactPad(DPoint(pcb_feedline_d * (i + 1), 0), pcb_Z, chip_Z, back_metal_width=50e3, back_metal_gap=100e3, trans_in=Trans.R90) for i in range(3) ] contact_pads_right = [ ContactPad(DPoint(dx, pcb_feedline_d * (i + 1)), pcb_Z, chip_Z, back_metal_width=50e3, back_metal_gap=100e3, trans_in=Trans.R180) for i in range(3) ] contact_pads_top = [ ContactPad(DPoint(dx - pcb_feedline_d * (i + 1), dy), pcb_Z, chip_Z, back_metal_width=50e3, back_metal_gap=100e3, trans_in=Trans.R270) for i in range(3) ] # contact pads are ordered starting with top-left corner in counter-clockwise direction contact_pads = itertools.chain(contact_pads_left, contact_pads_bottom, contact_pads_right, contact_pads_top) return list(contact_pads) @staticmethod def get_geometry_params_dict(prefix="", postfix=""): from collections import OrderedDict geometry_params = OrderedDict([("dx, um", CHIP.dx / 1e3), ("dy, um", CHIP.dy / 1e3), ("nX", CHIP.nX), ("nY", CHIP.nY)]) modified_dict = OrderedDict() for key, val in geometry_params.items(): modified_dict[prefix + key + postfix] = val return modified_dict
def draw_md_and_flux_lines(self): """ Drawing of md (microwave drive) and flux tuning lines for 5 qubits Returns ------- """ contact_pads = self.contact_pads ctr_line_turn_radius = 200e3 xmon_center = self.xmons[-1].center xmon_x_distance = self.xmon_x_distance cross_width_y = self.cross_width_y cross_width_x = self.cross_width_x cross_len_x = self.cross_len_x cross_gnd_gap_y = self.cross_gnd_gap_y cross_gnd_gap_x = self.cross_gnd_gap_x width_res = self.Z_res.width tmp_reg = self.region_ph z_md_fl = self.Z0 shift_fl_y = self.shift_fl_y shift_md_x = self.shift_md_x shift_md_y = self.shift_md_y flux_end_width = self.cross_width_x + 2 * self.cross_gnd_gap_x md_transition = 25e3 md_z1_params = CPWParameters( 7e3, 4e3 ) # Z = 50.04 Ohm, E_eff = 6.237 (E_0 = 11.45) (8e3, 4.15e3) md_z1_length = 100e3 shift_md_x_side = md_z1_length + md_transition + md_z1_params.b / 2 + cross_len_x + cross_width_x / 2 + cross_gnd_gap_x # place caplanar line 1md self.cpwrl_md1 = CPW_RL_Path( contact_pads[0].end, shape="LRLRL", cpw_parameters=z_md_fl, turn_radiuses=[ctr_line_turn_radius] * 2, segment_lengths=[ 2 * (-contact_pads[0].end.x + xmon_center.x - 4 * xmon_x_distance - shift_md_x_side) / 16, ((contact_pads[0].end.y - xmon_center.y)**2 + (9 * (-contact_pads[0].end.x + xmon_center.x - 4 * xmon_x_distance - shift_md_x_side) / 16)**2)**0.5, 5 * (-contact_pads[0].end.x + xmon_center.x - 4 * xmon_x_distance - shift_md_x_side) / 16 - 140e3 ], turn_angles=[ -atan2( contact_pads[0].end.y - xmon_center.y, 9 * (-contact_pads[0].end.x + xmon_center.x - 4 * xmon_x_distance - shift_md_x_side) / 16), atan2( contact_pads[0].end.y - xmon_center.y, 9 * (-contact_pads[0].end.x + xmon_center.x - 4 * xmon_x_distance - shift_md_x_side) / 16) ], trans_in=Trans.R0) self.cpwrl_md1.place(tmp_reg) self.cpwrl_md1_end = MDriveLineEnd( list(self.cpwrl_md1.primitives.values())[-1], md_z1_params, md_transition, md_z1_length) self.cpwrl_md1_end.place(tmp_reg) # place caplanar line 1 fl self.cpwrl_fl1 = CPW_RL_Path( contact_pads[1].end, shape="LRL", cpw_parameters=z_md_fl, turn_radiuses=[ctr_line_turn_radius], segment_lengths=[(-contact_pads[1].end.x + xmon_center.x - 4 * xmon_x_distance - cross_len_x), (-contact_pads[1].end.y + xmon_center.y - cross_width_y / 2 - cross_gnd_gap_y - width_res) ], turn_angles=[pi / 2], trans_in=Trans.R0) self.cpwrl_fl1.place(tmp_reg) self.cpwrl_fl1_end = FluxLineEnd(self.cpwrl_fl1.end, z_md_fl, width=flux_end_width, trans_in=Trans.R0) self.cpwrl_fl1_end.place(tmp_reg) # place caplanar line 2md self.cpwrl_md2 = CPW_RL_Path( contact_pads[3].end, shape="LRLRLRL", cpw_parameters=z_md_fl, turn_radiuses=[ctr_line_turn_radius] * 3, segment_lengths=[ (-contact_pads[3].end.y + xmon_center.y - shift_md_y) / 4, (-contact_pads[3].end.x + xmon_center.x + shift_md_x - 3 * xmon_x_distance) / 2, (((-contact_pads[3].end.x + xmon_center.x + shift_md_x - 3 * xmon_x_distance) / 2)**2 + (5 * (-contact_pads[3].end.y + xmon_center.y - shift_md_y) / 8)**2)**0.5, (-contact_pads[3].end.y + xmon_center.y - shift_md_y) / 8 ], turn_angles=[ -pi / 2, atan2( 5 * (-contact_pads[3].end.y + xmon_center.y - shift_md_y) / 8, (-contact_pads[3].end.x + xmon_center.x + shift_md_x - 3 * xmon_x_distance) / 2), pi / 2 - atan2( 5 * (-contact_pads[3].end.y + xmon_center.y - shift_md_y) / 8, (-contact_pads[3].end.x + xmon_center.x + shift_md_x - 3 * xmon_x_distance) / 2) ], trans_in=Trans.R90) self.cpwrl_md2.place(tmp_reg) self.cpwrl_md2_end = MDriveLineEnd( list(self.cpwrl_md2.primitives.values())[-1], md_z1_params, md_transition, md_z1_length) self.cpwrl_md2_end.place(tmp_reg) # place caplanar line 2 fl self.cpwrl_fl2 = CPW_RL_Path( contact_pads[2].end, shape="LRLRL", cpw_parameters=z_md_fl, turn_radiuses=[ctr_line_turn_radius] * 2, segment_lengths=[ (-contact_pads[2].end.x + xmon_center.x - 3 * xmon_x_distance) / 4, ((3 * (-contact_pads[2].end.x + xmon_center.x - 3 * xmon_x_distance) / 4)**2 + (7 * (-contact_pads[2].end.y + xmon_center.y - shift_fl_y) / 8)**2)**0.5, (-contact_pads[2].end.y + xmon_center.y - shift_fl_y) / 8 ], turn_angles=[ atan2( 7 * (-contact_pads[2].end.y + xmon_center.y - shift_fl_y) / 8, 3 * (-contact_pads[2].end.x + xmon_center.x - 3 * xmon_x_distance) / 4), pi / 2 - atan2( 7 * (-contact_pads[2].end.y + xmon_center.y - shift_fl_y) / 8, 3 * (-contact_pads[2].end.x + xmon_center.x - 3 * xmon_x_distance) / 4) ], trans_in=Trans.R0) self.cpwrl_fl2.place(tmp_reg) self.cpwrl_fl2_end = FluxLineEnd(self.cpwrl_fl2.end, z_md_fl, width=flux_end_width, trans_in=Trans.R0) self.cpwrl_fl2_end.place(tmp_reg) # place caplanar line 3md self.cpwrl_md3 = CPW_RL_Path( contact_pads[5].end, shape="LRLRLRL", cpw_parameters=z_md_fl, turn_radiuses=[ctr_line_turn_radius] * 3, segment_lengths=[ (-contact_pads[5].end.y + xmon_center.y - shift_md_y) / 4, (contact_pads[5].end.x - xmon_center.x - shift_md_x + 2 * xmon_x_distance) / 2, (((contact_pads[5].end.x - xmon_center.x - shift_md_x + 2 * xmon_x_distance) / 2)**2 + (5 * (-contact_pads[5].end.y + xmon_center.y - shift_md_y) / 8)**2)**0.5, (-contact_pads[5].end.y + xmon_center.y - shift_md_y) / 8 ], turn_angles=[ pi / 2, -atan2( 5 * (-contact_pads[5].end.y + xmon_center.y - shift_md_y) / 8, (contact_pads[5].end.x - xmon_center.x - shift_md_x + 2 * xmon_x_distance) / 2), -pi / 2 + atan2( 5 * (-contact_pads[5].end.y + xmon_center.y - shift_md_y) / 8, (contact_pads[5].end.x - xmon_center.x - shift_md_x + 2 * xmon_x_distance) / 2) ], trans_in=Trans.R90) self.cpwrl_md3.place(tmp_reg) self.cpwrl_md3_end = MDriveLineEnd( list(self.cpwrl_md3.primitives.values())[-1], md_z1_params, md_transition, md_z1_length) self.cpwrl_md3_end.place(tmp_reg) # place caplanar line 3 fl fl_l1 = (self.xmons[2].cpw_bempt.end.y - contact_pads[4].end.y) / 4 fl_l3 = fl_l1 dr = self.xmons[2].cpw_bempt.end - contact_pads[4].end dr.y = dr.y - fl_l1 - fl_l3 - z_md_fl.width turn_angle = atan2(-dr.x, dr.y) fl_l2 = dr.abs() self.cpwrl_fl3 = CPW_RL_Path(self.contact_pads[4].end, shape="LRLRL", cpw_parameters=z_md_fl, turn_radiuses=[ctr_line_turn_radius] * 2, segment_lengths=[fl_l1, fl_l2, fl_l3], turn_angles=[turn_angle, -turn_angle], trans_in=Trans.R90) self.cpwrl_fl3.place(tmp_reg) self.cpwrl_fl3_end = FluxLineEnd(self.cpwrl_fl3.end, z_md_fl, width=flux_end_width, trans_in=Trans.R0) self.cpwrl_fl3_end.place(tmp_reg) # place caplanar line 4 md self.cpwrl_md4 = CPW_RL_Path( contact_pads[7].end, shape="LRL", cpw_parameters=z_md_fl, turn_radiuses=[ctr_line_turn_radius], segment_lengths=[ contact_pads[7].end.x - xmon_center.x + xmon_x_distance - shift_md_x, -contact_pads[7].end.y + xmon_center.y - shift_md_y ], turn_angles=[-pi / 2], trans_in=Trans.R180) self.cpwrl_md4.place(tmp_reg) self.cpwrl_md4_end = MDriveLineEnd( list(self.cpwrl_md4.primitives.values())[-1], md_z1_params, md_transition, md_z1_length) self.cpwrl_md4_end.place(tmp_reg) # place caplanar line 4 fl self.cpwrl_fl4 = CPW_RL_Path( contact_pads[6].end, shape="LRLRL", cpw_parameters=z_md_fl, turn_radiuses=[ctr_line_turn_radius] * 2, segment_lengths=[ (contact_pads[6].end.x - xmon_center.x + xmon_x_distance) / 4, ((6 * (-contact_pads[6].end.y + xmon_center.y - shift_fl_y) / 8)**2 + (3 * (contact_pads[6].end.x - xmon_center.x + xmon_x_distance) / 4)**2)**0.5, 2 * (-contact_pads[6].end.y + xmon_center.y - shift_fl_y) / 8 ], turn_angles=[ -atan2( 6 * (-contact_pads[6].end.y + xmon_center.y - shift_fl_y) / 8, 3 * (contact_pads[6].end.x - xmon_center.x + xmon_x_distance) / 4), -pi / 2 + atan2( 6 * (-contact_pads[6].end.y + xmon_center.y - shift_fl_y) / 8, 3 * (contact_pads[6].end.x - xmon_center.x + xmon_x_distance) / 4) ], trans_in=Trans.R180) self.cpwrl_fl4.place(tmp_reg) self.cpwrl_fl4_end = FluxLineEnd(self.cpwrl_fl4.end, z_md_fl, width=flux_end_width, trans_in=Trans.R0) self.cpwrl_fl4_end.place(tmp_reg) # place caplanar line 5 md self.cpwrl_md5 = CPW_RL_Path( contact_pads[9].end, shape="LRLRL", cpw_parameters=z_md_fl, turn_radiuses=[ctr_line_turn_radius] * 2, segment_lengths=[ 2 * (contact_pads[9].end.y - xmon_center.y) / 3, (((contact_pads[9].end.y - xmon_center.y) / 3)**2 + (2 * (contact_pads[9].end.x - xmon_center.x - shift_md_x_side) / 3)**2)**(0.5), (contact_pads[9].end.x - xmon_center.x - shift_md_x_side) / 3 - 140e3 ], turn_angles=[ -atan2( 2 * (contact_pads[9].end.x - xmon_center.x - shift_md_x_side) / 3, (contact_pads[9].end.y - xmon_center.y) / 3), atan2( 2 * (contact_pads[9].end.x - xmon_center.x - shift_md_x_side) / 3, (contact_pads[9].end.y - xmon_center.y) / 3) - pi / 2 ], trans_in=Trans.R270) self.cpwrl_md5.place(tmp_reg) self.cpwrl_md5_end = MDriveLineEnd( list(self.cpwrl_md5.primitives.values())[-1], md_z1_params, md_transition, md_z1_length) self.cpwrl_md5_end.place(tmp_reg) # place caplanar line 5 fl self.cpwrl_fl5 = CPW_RL_Path( contact_pads[8].end, shape="LRLRLRLRL", cpw_parameters=z_md_fl, turn_radiuses=[ctr_line_turn_radius] * 4, segment_lengths=[ (contact_pads[8].end.x - xmon_center.x) / 4, ((contact_pads[8].end.y - xmon_center.y) + 250e3) / 3 + 50e3, ((2 * ((contact_pads[8].end.y - xmon_center.y) + 250e3) / 3)**2 + ((contact_pads[8].end.x - xmon_center.x) / 2)**2)**0.5, (contact_pads[8].end.x - xmon_center.x) / 4 - cross_len_x, 230e3 ], turn_angles=[ pi / 2, -atan2( (contact_pads[8].end.x - xmon_center.x) / 2, 2 * ((contact_pads[8].end.y - xmon_center.y) + 250e3) / 3), -pi / 2 + atan2( (contact_pads[8].end.x - xmon_center.x) / 2, 2 * ((contact_pads[8].end.y - xmon_center.y) + 250e3) / 3), -pi / 2 ], trans_in=Trans.R180) self.cpwrl_fl5.place(tmp_reg) self.cpwrl_fl5_end = FluxLineEnd(self.cpwrl_fl5.end, z_md_fl, width=flux_end_width, trans_in=Trans.R0) self.cpwrl_fl5_end.place(tmp_reg)