Source code for squadds.components.jjs

import shapely
from qiskit_metal import Dict, draw
from qiskit_metal.qlibrary.core.base import QComponent

#!TODO: make JJ_length a parameter


[docs] class JjDolan(QComponent): """ The base "JjDolan" inherits the "QComponent" class. NOTE TO USER: Please be aware that when designing with this qcomponent, one must take care in accounting for the junction qgeometry when exporting to to GDS and/or to a simulator. This qcomponent should not be rendered for EM simulation. This creates a "Dolan"-style Josephson Junction consisting a single junction slightly separated, adhearing to LFL's prefererances. Default Options: * bridge_length: '28um' -- lenght between pads * JJ_width: '0.188um' -- Josephson Junction width * bridge_layer: 1 -- GDS layer for bridge, make sure it's different from qubit + JJs * JJ_layer: 2 -- GDS layer for JJ, make sure it's different from qubit + bridge """ default_options = Dict(bridge_length="28um", JJ_width="0.188um", bridge_layer=20, JJ_layer=60) """Default options.""" component_metadata = Dict(short_name="Cross", _qgeometry_table_poly="True", _qgeometry_table_junction="True") """Component metadata""" TOOLTIP = """Josephson Junctions used at LFL"""
[docs] def make(self): pad_length = 0.007 # mm pad_width = 0.010 # mm triangle_width = 0.006 # mm triangle_height = 0.003 # mm bridge_width = 0.002 # mm # Here's our user defined variables p = self.parse_options() ### Bridge Layer # Bottom pad pad = draw.rectangle(pad_width, pad_length, 0, 0) triangle = draw.Polygon([(-triangle_width / 2, 0), (triangle_width / 2, 0), (0, triangle_height)]) triangle = draw.translate(triangle, 0, pad_length / 2) pad = draw.union(pad, triangle) pad = draw.translate(pad, 0, -p.bridge_length / 2 - pad_length / 2) # Top pad t_pad = draw.rotate(pad, 180, origin=(0, 0)) # Bridge bridge = draw.rectangle(bridge_width, p.bridge_length, 0, 0) # Final bridge bridge = draw.union(bridge, pad, t_pad) ### JJ Layer jjl2 = 0.002 # 2.0um finger_length = 0.00136 # 1.36um JJ_taper = jjl2 - finger_length # 0.5um jj1_gap = 0.000140 # 140nm # Make cutout on the bridge JJ = draw.Polygon( [ (-bridge_width / 2, 0), (bridge_width / 2, 0), (p.JJ_width / 2, JJ_taper), (p.JJ_width / 2, JJ_taper + finger_length - jj1_gap), (-p.JJ_width / 2, JJ_taper + finger_length - jj1_gap), (-p.JJ_width / 2, JJ_taper), ] ) cutout = draw.Polygon( [(-bridge_width / 2, 0), (bridge_width / 2, 0), (bridge_width / 2, jjl2), (-bridge_width / 2, jjl2)] ) cutout = draw.subtract(cutout, JJ) bridge = draw.subtract(bridge, cutout) # Now you can draw your JJ JJ = draw.Polygon( [ (-bridge_width / 2, 0), (bridge_width / 2, 0), (p.JJ_width / 2, JJ_taper), (p.JJ_width / 2, JJ_taper + finger_length), (-p.JJ_width / 2, JJ_taper + finger_length), (-p.JJ_width / 2, JJ_taper), ] ) polys = [bridge, JJ] polys = draw.rotate(polys, p.orientation, origin=(0, 0)) polys = draw.translate(polys, p.pos_x, p.pos_y) bridge, JJ = polys ### Add everything to QGeometry self.add_qgeometry("poly", {"bridge": bridge}, layer=p.bridge_layer, subtract=False) self.add_qgeometry("poly", {"JJ": JJ}, layer=p.JJ_layer, subtract=False) # Add a LineString for the junction coords = list(JJ.exterior.coords) # Use the midpoints of the two short sides (indices 0-1 and 3-4 for this polygon) mid1 = ((coords[0][0] + coords[1][0]) / 2, (coords[0][1] + coords[1][1]) / 2) mid2 = ((coords[3][0] + coords[4][0]) / 2, (coords[3][1] + coords[4][1]) / 2) ls = shapely.geometry.LineString([mid1, mid2]) self.add_qgeometry("junction", {"design": ls}, width=p.JJ_width, layer=p.JJ_layer)
[docs] class SquidLoopDolan(QComponent): """ The base "SquidLoopDolan" inherits the "QComponent" class. NOTE TO USER: Please be aware that when designing with this qcomponent, one must take care in accounting for the junction qgeometry when exporting to to GDS and/or to a simulator. This qcomponent should not be rendered for EM simulation. This creates a "Dolan"-style SQUID loop consisting of a slightly separated loop with 2 symmetrical JJs on each side. Default Options: * SQUID_width: '63um' -- inner width (x-axis) of SQUID loop * SQUID_length: '9um' -- inner length (y-axis) of SQUID loop * stem1_length: '7um' -- length between bottom pad and loop * stem2_length: '7um' -- length between side pad and loop * stem1_offset: '0um' -- aligns stem1 some distance away from center * stem2_offset: '0um' -- aligns stem2 some distance away from center * JJ_width: '0.3um' -- correlated to setting the Lj of your SQUID * JJ_offset: '0um' -- aligns the JJs some distance away from center * mirror: 0 -- input 0 or 1, want to mirror about the x-axis? * SQUID_layer: 1 -- GDS layer for loop, make sure it's different from qubit + JJs * JJ_layer: 2 -- GDS layer for JJs, make sure it's different from qubit + loop """ # Default drawing options default_options = Dict( SQUID_width="63um", SQUID_length="9um", SQUID_thickness="2um", stem1_length="7um", stem2_length="7um", stem1_offset="0um", stem2_offset="0um", JJ_width="0.3um", JJ_offset="0um", JJ_flip=False, mirror=0, SQUID_layer=20, JJ_layer=60, ) """Default drawing options""" # Name prefix of component, if user doesn't provide name component_metadata = Dict(short_name="component") """Component metadata"""
[docs] def make(self): self.make_loop() self.make_junction()
[docs] def make_loop(self): """ Makes the SQUID loop structure """ p = self.parse_options() ### Make first pad pad = draw.Polygon([(0, 0), (0.010, 0), (0.010, 0.016), (0, 0.016)]) pad = draw.translate(pad, -0.005, 0) ### Make first tappered structure tapper = draw.Polygon([(-0.0062 / 2, 0), (0.0062 / 2, 0), (0, 0.003125)]) stem1 = draw.Polygon( [ (-p.SQUID_thickness / 2, 0), (p.SQUID_thickness / 2, 0), (p.SQUID_thickness / 2, p.stem1_length), (-p.SQUID_thickness / 2, p.stem1_length), ] ) tapper = draw.translate(tapper, 0, 0.016) stem1 = draw.translate(stem1, 0, 0.016) tappered_stem = draw.union(stem1, tapper) checkpoint = draw.union(tappered_stem, pad) ### make loop by subtracting inner rectangle from outter rectangle outter = draw.Polygon( [ (-p.SQUID_width / 2 - p.SQUID_thickness, -p.SQUID_length / 2 - p.SQUID_thickness), (-p.SQUID_width / 2 - p.SQUID_thickness, p.SQUID_length / 2 + p.SQUID_thickness), (p.SQUID_width / 2 + p.SQUID_thickness, p.SQUID_length / 2 + p.SQUID_thickness), (p.SQUID_width / 2 + p.SQUID_thickness, -p.SQUID_length / 2 - p.SQUID_thickness), ] ) inner = draw.Polygon( [ (-p.SQUID_width / 2, -p.SQUID_length / 2), (-p.SQUID_width / 2, p.SQUID_length / 2), (p.SQUID_width / 2, p.SQUID_length / 2), (p.SQUID_width / 2, -p.SQUID_length / 2), ] ) loop = draw.subtract(outter, inner) loop = draw.translate(loop, 0, p.SQUID_length / 2 + p.SQUID_thickness + 0.016 + p.stem1_length) ### Checkpoint, let's prep to make the 2nd and final stem total = [checkpoint, loop] total = draw.rotate(total, 90, origin=(0, 0)) total = draw.translate( total, 0.016 + p.stem1_length + p.SQUID_length / 2 + 2 * p.SQUID_thickness / 2, p.SQUID_width / 2 + p.SQUID_thickness, ) checkpoint, loop = total ### Make the 2nd stemp stem2 = draw.Polygon( [ (-p.SQUID_thickness / 2, 0), (p.SQUID_thickness / 2, 0), (p.SQUID_thickness / 2, p.stem2_length), (-p.SQUID_thickness / 2, p.stem2_length), ] ) stem2 = draw.translate(stem2, -(p.SQUID_length / 2 + p.SQUID_thickness / 2), 0.016) tapper = draw.translate(tapper, -(p.SQUID_length / 2 + p.SQUID_thickness / 2), 0) pad = draw.translate(pad, -(p.SQUID_length / 2 + p.SQUID_thickness / 2), 0) checkpoint2 = draw.union(stem2, tapper, pad) checkpoint2 = draw.translate(checkpoint2, 0, -p.stem2_length - 0.016) ### Choose offsets for pads checkpoint = draw.translate(checkpoint, 0, p.stem1_offset) checkpoint2 = draw.translate(checkpoint2, p.stem2_offset, 0) ### We the general structure, we just need to remove ### part of the loop for the JJs. Centering middle of loop. final_loop = [checkpoint, checkpoint2, loop] final_loop = draw.translate( final_loop, -(0.016 + p.stem1_length + p.SQUID_length / 2 + 2 * p.SQUID_thickness / 2), -(p.SQUID_width / 2 + p.SQUID_thickness), ) final_loop = draw.rotate(final_loop, -90, origin=(0, 0)) checkpoint, checkpoint2, loop = final_loop if p.mirror == 1: checkpoint2 = draw.scale(checkpoint2, -1, 1, origin=(0, 0)) final_loop = draw.union(checkpoint, checkpoint2, loop) final_loop = draw.translate(final_loop, 0, -(0.016 + p.stem1_length + p.SQUID_thickness + p.SQUID_length / 2)) ### Subtract pocket for JJs JJ_taper = 0.002 - 0.00136 # 0.5um finger_length = 0.00136 # 1.36um x_gap = 0.00015 # 0.14um JJ = draw.Polygon( [ (-p.SQUID_thickness / 2, 0), (p.SQUID_thickness / 2, 0), (p.JJ_width / 2, JJ_taper), (p.JJ_width / 2, JJ_taper + finger_length - x_gap), (-p.JJ_width / 2, JJ_taper + finger_length - x_gap), (-p.JJ_width / 2, JJ_taper), ] ) # I added this x_gap as buffer to fully subtract part of 'final_loop', # I noticed that when i set 'JJ_flip = True', it would leave some residual loop # Scuffed fix, but will have to suffice for now pocket = draw.Polygon( [ (-p.SQUID_thickness / 2 - x_gap, 0), (p.SQUID_thickness / 2 + x_gap, 0), (p.SQUID_thickness / 2 + x_gap, JJ_taper + finger_length), (-p.SQUID_thickness / 2 - x_gap, JJ_taper + finger_length), ] ) pocket = draw.subtract(pocket, JJ) if p.JJ_flip: pocket = draw.rotate(pocket, 180, origin=(0, (JJ_taper + finger_length - x_gap) / 2)) pocket2 = draw.translate(pocket, p.SQUID_width / 2 + p.SQUID_thickness / 2, -(JJ_taper + finger_length) / 2) pocket = draw.translate(pocket, -(p.SQUID_width / 2 + p.SQUID_thickness / 2), -(JJ_taper + finger_length) / 2) final_loop = draw.subtract(final_loop, pocket2) final_loop = draw.subtract(final_loop, pocket) final_loop = draw.rotate(final_loop, p.orientation, origin=(0, 0)) final_loop = draw.translate(final_loop, p.pos_x, p.pos_y) ### Add to QGeometry! self.add_qgeometry("poly", {"final_loop": final_loop}, layer=p.SQUID_layer, subtract=False)
[docs] def make_junction(self): """Makes the JJs""" p = self.parse_options() # These are some parameters given by LFL's design prefererances JJ_taper = 0.002 - 0.00136 # 0.5um finger_length = 0.00136 # 1.36um x_gap = 0.00015 # 0.14um JJ = draw.Polygon( [ (-p.SQUID_thickness / 2, 0), (p.SQUID_thickness / 2, 0), (p.JJ_width / 2, JJ_taper), (p.JJ_width / 2, JJ_taper + finger_length), (-p.JJ_width / 2, JJ_taper + finger_length), (-p.JJ_width / 2, JJ_taper), ] ) if p.JJ_flip: JJ = draw.rotate(JJ, 180, origin=(0, (JJ_taper + finger_length - x_gap) / 2)) JJ2 = draw.translate(JJ, p.SQUID_width / 2 + p.SQUID_thickness / 2, -(JJ_taper + finger_length) / 2) JJ = draw.translate(JJ, -(p.SQUID_width / 2 + p.SQUID_thickness / 2), -(JJ_taper + finger_length) / 2) final_design = [JJ, JJ2] final_design = draw.rotate(final_design, p.orientation, origin=(0, 0)) final_design = draw.translate(final_design, p.pos_x, p.pos_y) JJ, JJ2 = final_design ### Add to QGeometry self.add_qgeometry("poly", {"JJ": JJ}, layer=p.JJ_layer, subtract=False) self.add_qgeometry("poly", {"JJ2": JJ2}, layer=p.JJ_layer, subtract=False) # Add LineStrings for both junctions coords1 = list(JJ.exterior.coords) mid1a = ((coords1[0][0] + coords1[1][0]) / 2, (coords1[0][1] + coords1[1][1]) / 2) mid1b = ((coords1[3][0] + coords1[4][0]) / 2, (coords1[3][1] + coords1[4][1]) / 2) ls1 = shapely.geometry.LineString([mid1a, mid1b]) self.add_qgeometry("junction", {"JJ": ls1}, width=p.JJ_width, layer=p.JJ_layer) coords2 = list(JJ2.exterior.coords) mid2a = ((coords2[0][0] + coords2[1][0]) / 2, (coords2[0][1] + coords2[1][1]) / 2) mid2b = ((coords2[3][0] + coords2[4][0]) / 2, (coords2[3][1] + coords2[4][1]) / 2) ls2 = shapely.geometry.LineString([mid2a, mid2b]) self.add_qgeometry("junction", {"JJ2": ls2}, width=p.JJ_width, layer=p.JJ_layer)