Source code for squadds.components.jjs

import numpy as np
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)
[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 == True): 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 == True): 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)