qiskit_metal.qlibrary.QNLMetal.junctionarray
JunctionArray.
`wire1`
________________|_______________
‾‾‾‾‾‾‾‾‾‾‾|‾‾‾|‾|‾‾‾‾‾‾‾‾‾‾‾‾‾‾
___________|___|_|______________
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾|‾|‾‾‾|‾‾‾‾‾‾‾‾‾‾
_______________|_|___|__________
‾‾‾‾‾‾‾‾‾‾‾|‾‾‾|‾|‾‾‾‾‾‾‾‾‾‾‾‾‾‾
___________|___|_|______________
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾|‾|‾‾‾|‾‾‾‾‾‾‾‾‾‾
_______________|*|___|__________
‾‾‾‾‾‾‾‾‾‾‾|‾‾‾|‾|‾‾‾‾‾‾‾‾‾‾‾‾‾‾
___________|___|_|______________
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾|‾|‾‾‾|‾‾‾‾‾‾‾‾‾‾
_______________|_|___|__________
‾‾‾‾‾‾‾‾‾‾‾|‾‾‾|‾|‾‾‾‾‾‾‾‾‾‾‾‾‾‾
___________|___|_|______________
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾|‾|‾‾‾|‾‾‾‾‾‾‾‾‾‾
_______________|_|___|__________
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾|‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
`wire2`
1# This code was written by Deval Deliwala. 2# 3# This code is to be used by QNL. 4# 5# Any modifications or derivative works of this code must retain this 6# notice, and modified files need to carry a notice indicating 7# that they have been altered from the originals. 8 9""" JunctionArray. 10 11.. code-block:: 12 13 `wire1` 14 ________________|_______________ 15 ‾‾‾‾‾‾‾‾‾‾‾|‾‾‾|‾|‾‾‾‾‾‾‾‾‾‾‾‾‾‾ 16 ___________|___|_|______________ 17 ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾|‾|‾‾‾|‾‾‾‾‾‾‾‾‾‾ 18 _______________|_|___|__________ 19 ‾‾‾‾‾‾‾‾‾‾‾|‾‾‾|‾|‾‾‾‾‾‾‾‾‾‾‾‾‾‾ 20 ___________|___|_|______________ 21 ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾|‾|‾‾‾|‾‾‾‾‾‾‾‾‾‾ 22 _______________|*|___|__________ 23 ‾‾‾‾‾‾‾‾‾‾‾|‾‾‾|‾|‾‾‾‾‾‾‾‾‾‾‾‾‾‾ 24 ___________|___|_|______________ 25 ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾|‾|‾‾‾|‾‾‾‾‾‾‾‾‾‾ 26 _______________|_|___|__________ 27 ‾‾‾‾‾‾‾‾‾‾‾|‾‾‾|‾|‾‾‾‾‾‾‾‾‾‾‾‾‾‾ 28 ___________|___|_|______________ 29 ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾|‾|‾‾‾|‾‾‾‾‾‾‾‾‾‾ 30 _______________|_|___|__________ 31 ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾|‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ 32 `wire2` 33 34 35""" 36 37import numpy as np 38from qiskit_metal import draw, Dict 39from qiskit_metal.qlibrary.core import QComponent 40from qiskit_metal.toolbox_python.utility_functions import rotate_point 41 42 43class JunctionArray(QComponent): 44 """ 45 Inherits from `QComponent` Class. 46 47 Description: 48 A two-angle bridge free junction array. 49 This implements a junction array superinductor, primarily for fluxonium qubits. 50 Designed in the style of Masluk et al. 2020. 51 52 Options: 53 * n (int): Number of junction lines 54 * jx/jy : Dimensions for junction lines 55 * wx/wy : Dimensions for central vertical wire pads 56 `wy` determines the gap between the junction lines 57 * undercut: length of the undercut leads on junction line edges 58 AND alternating central pads 59 * orientation : 0-> is parallel to x-axis, with orientation (in degrees) counterclockwise 60 * pos_x/_y : `origin` position of junction lead on chip 61 `origin` is the left-edge-center of the wide-section 62 * layer : The layer number for the junction lines 63 * undercut_layer : The layer number for the edge undercut leads 64 * alternating_layer: The layer number for the alternating undercut pads 65 66 67 """ 68 69 # Default drawing options 70 default_options = Dict( 71 n=20, 72 jx='100um', 73 jy='10um', 74 wx='20um', 75 wy='10um', 76 undercut='15um', 77 orientation='0', 78 pos_x='0um', 79 pos_y='0um', 80 layer='1', 81 undercut_layer='2', 82 alternating_layer='2' 83 ) 84 85 # Component metadata 86 # Name prefix for component, if user doesn't provide name 87 component_metadata = Dict( 88 short_name='JunctionArray', 89 _qgeometry_table_poly='True', 90 ) 91 92 def make(self): 93 """ Converts self.options into QGeometry. """ 94 p = self.parse_options() 95 nodes = Dict() 96 97 spacing = p.jy + p.wy 98 positions = (np.arange(p.n) - (p.n-1)/2)*spacing 99 100 # Junction lines and edge undercut leads 101 junction_rects = [] 102 lead_rects = [] 103 for y in positions: 104 junction_rect = draw.rectangle(p.jx, p.jy) 105 junction_rect = draw.translate(junction_rect, 0, y) 106 107 base_undercut = draw.rectangle(p.undercut, p.jy) 108 undercuts = [ 109 draw.translate(base_undercut, -(p.undercut + p.jx)/2, y), 110 draw.translate(base_undercut, +(p.undercut + p.jx)/2, y), 111 ] 112 113 junction_rects.append(junction_rect) 114 lead_rects.extend(undercuts) 115 116 # Combining all junction lines into one component 117 # Combining all edge undercut leads into one component 118 junction_rects = draw.union(*junction_rects) 119 lead_rects = draw.union(*lead_rects) 120 121 122 wire_rects = [] 123 pad_rects = [] 124 for i, y in enumerate(positions[:-1]): 125 wire_rect = draw.rectangle(p.wx, p.wy) 126 wire_rect = draw.translate(wire_rect, 0, y + (p.jy + p.wy)/2) 127 128 undercut = draw.rectangle(p.undercut, p.wy) 129 if i%2: 130 undercut = draw.translate(undercut, +(p.wx + p.undercut)/2, y + (p.jy + p.wy)/2) 131 else: 132 undercut = draw.translate(undercut, -(p.wx + p.undercut)/2, y + (p.jy + p.wy)/2) 133 134 wire_rects.append(wire_rect) 135 pad_rects.append(undercut) 136 137 wire_rects = draw.union(*wire_rects) 138 pad_rects = draw.union(*pad_rects) 139 140 # Translations & Rotations 141 geom_list = [junction_rects, wire_rects, lead_rects, pad_rects] 142 geom_list = draw.rotate(geom_list, p.orientation) 143 geom_list = draw.translate(geom_list, p.pos_x, p.pos_y) 144 [junction_rects, wire_rects, lead_rects, pad_rects] = geom_list 145 146 # Converting drawings to qgeometry 147 self.add_qgeometry('poly', {'junction_rects': junction_rects}, layer = p.layer) 148 self.add_qgeometry('poly', {'wire_rects': wire_rects}, layer=p.layer) 149 self.add_qgeometry('poly', {'edge_leads': lead_rects}, layer=p.undercut_layer) 150 self.add_qgeometry('poly', {'inner_pads': pad_rects}, layer=p.alternating_layer) 151 152 # Positioning nodes 153 nodes.origin = np.zeros(2) 154 nodes.wire1 = np.array((0, max(positions) + p.jy/2)) 155 nodes.wire2 = np.array((0, min(positions) - p.jy/2)) 156 157 # Moving nodes along with component 158 translation_vec = np.array((p.pos_x, p.pos_y)) 159 theta = np.deg2rad(p.orientation) 160 161 for key, point in nodes.items(): 162 rotated = rotate_point(point, theta) 163 nodes[key] = rotated + translation_vec 164 165 self.nodes = nodes 166 return 167 168 def node(self, key): 169 return self.nodes.get(key, None)
44class JunctionArray(QComponent): 45 """ 46 Inherits from `QComponent` Class. 47 48 Description: 49 A two-angle bridge free junction array. 50 This implements a junction array superinductor, primarily for fluxonium qubits. 51 Designed in the style of Masluk et al. 2020. 52 53 Options: 54 * n (int): Number of junction lines 55 * jx/jy : Dimensions for junction lines 56 * wx/wy : Dimensions for central vertical wire pads 57 `wy` determines the gap between the junction lines 58 * undercut: length of the undercut leads on junction line edges 59 AND alternating central pads 60 * orientation : 0-> is parallel to x-axis, with orientation (in degrees) counterclockwise 61 * pos_x/_y : `origin` position of junction lead on chip 62 `origin` is the left-edge-center of the wide-section 63 * layer : The layer number for the junction lines 64 * undercut_layer : The layer number for the edge undercut leads 65 * alternating_layer: The layer number for the alternating undercut pads 66 67 68 """ 69 70 # Default drawing options 71 default_options = Dict( 72 n=20, 73 jx='100um', 74 jy='10um', 75 wx='20um', 76 wy='10um', 77 undercut='15um', 78 orientation='0', 79 pos_x='0um', 80 pos_y='0um', 81 layer='1', 82 undercut_layer='2', 83 alternating_layer='2' 84 ) 85 86 # Component metadata 87 # Name prefix for component, if user doesn't provide name 88 component_metadata = Dict( 89 short_name='JunctionArray', 90 _qgeometry_table_poly='True', 91 ) 92 93 def make(self): 94 """ Converts self.options into QGeometry. """ 95 p = self.parse_options() 96 nodes = Dict() 97 98 spacing = p.jy + p.wy 99 positions = (np.arange(p.n) - (p.n-1)/2)*spacing 100 101 # Junction lines and edge undercut leads 102 junction_rects = [] 103 lead_rects = [] 104 for y in positions: 105 junction_rect = draw.rectangle(p.jx, p.jy) 106 junction_rect = draw.translate(junction_rect, 0, y) 107 108 base_undercut = draw.rectangle(p.undercut, p.jy) 109 undercuts = [ 110 draw.translate(base_undercut, -(p.undercut + p.jx)/2, y), 111 draw.translate(base_undercut, +(p.undercut + p.jx)/2, y), 112 ] 113 114 junction_rects.append(junction_rect) 115 lead_rects.extend(undercuts) 116 117 # Combining all junction lines into one component 118 # Combining all edge undercut leads into one component 119 junction_rects = draw.union(*junction_rects) 120 lead_rects = draw.union(*lead_rects) 121 122 123 wire_rects = [] 124 pad_rects = [] 125 for i, y in enumerate(positions[:-1]): 126 wire_rect = draw.rectangle(p.wx, p.wy) 127 wire_rect = draw.translate(wire_rect, 0, y + (p.jy + p.wy)/2) 128 129 undercut = draw.rectangle(p.undercut, p.wy) 130 if i%2: 131 undercut = draw.translate(undercut, +(p.wx + p.undercut)/2, y + (p.jy + p.wy)/2) 132 else: 133 undercut = draw.translate(undercut, -(p.wx + p.undercut)/2, y + (p.jy + p.wy)/2) 134 135 wire_rects.append(wire_rect) 136 pad_rects.append(undercut) 137 138 wire_rects = draw.union(*wire_rects) 139 pad_rects = draw.union(*pad_rects) 140 141 # Translations & Rotations 142 geom_list = [junction_rects, wire_rects, lead_rects, pad_rects] 143 geom_list = draw.rotate(geom_list, p.orientation) 144 geom_list = draw.translate(geom_list, p.pos_x, p.pos_y) 145 [junction_rects, wire_rects, lead_rects, pad_rects] = geom_list 146 147 # Converting drawings to qgeometry 148 self.add_qgeometry('poly', {'junction_rects': junction_rects}, layer = p.layer) 149 self.add_qgeometry('poly', {'wire_rects': wire_rects}, layer=p.layer) 150 self.add_qgeometry('poly', {'edge_leads': lead_rects}, layer=p.undercut_layer) 151 self.add_qgeometry('poly', {'inner_pads': pad_rects}, layer=p.alternating_layer) 152 153 # Positioning nodes 154 nodes.origin = np.zeros(2) 155 nodes.wire1 = np.array((0, max(positions) + p.jy/2)) 156 nodes.wire2 = np.array((0, min(positions) - p.jy/2)) 157 158 # Moving nodes along with component 159 translation_vec = np.array((p.pos_x, p.pos_y)) 160 theta = np.deg2rad(p.orientation) 161 162 for key, point in nodes.items(): 163 rotated = rotate_point(point, theta) 164 nodes[key] = rotated + translation_vec 165 166 self.nodes = nodes 167 return 168 169 def node(self, key): 170 return self.nodes.get(key, None)
Inherits from QComponent
Class.
Description: A two-angle bridge free junction array. This implements a junction array superinductor, primarily for fluxonium qubits. Designed in the style of Masluk et al. 2020.
Options:
* n (int): Number of junction lines
* jx/jy : Dimensions for junction lines
* wx/wy : Dimensions for central vertical wire pads
wy
determines the gap between the junction lines
* undercut: length of the undercut leads on junction line edges
AND alternating central pads
* orientation : 0-> is parallel to x-axis, with orientation (in degrees) counterclockwise
* pos_x/_y : origin
position of junction lead on chip
origin
is the left-edge-center of the wide-section
* layer : The layer number for the junction lines
* undercut_layer : The layer number for the edge undercut leads
* alternating_layer: The layer number for the alternating undercut pads
Default drawing options
Component metadata
93 def make(self): 94 """ Converts self.options into QGeometry. """ 95 p = self.parse_options() 96 nodes = Dict() 97 98 spacing = p.jy + p.wy 99 positions = (np.arange(p.n) - (p.n-1)/2)*spacing 100 101 # Junction lines and edge undercut leads 102 junction_rects = [] 103 lead_rects = [] 104 for y in positions: 105 junction_rect = draw.rectangle(p.jx, p.jy) 106 junction_rect = draw.translate(junction_rect, 0, y) 107 108 base_undercut = draw.rectangle(p.undercut, p.jy) 109 undercuts = [ 110 draw.translate(base_undercut, -(p.undercut + p.jx)/2, y), 111 draw.translate(base_undercut, +(p.undercut + p.jx)/2, y), 112 ] 113 114 junction_rects.append(junction_rect) 115 lead_rects.extend(undercuts) 116 117 # Combining all junction lines into one component 118 # Combining all edge undercut leads into one component 119 junction_rects = draw.union(*junction_rects) 120 lead_rects = draw.union(*lead_rects) 121 122 123 wire_rects = [] 124 pad_rects = [] 125 for i, y in enumerate(positions[:-1]): 126 wire_rect = draw.rectangle(p.wx, p.wy) 127 wire_rect = draw.translate(wire_rect, 0, y + (p.jy + p.wy)/2) 128 129 undercut = draw.rectangle(p.undercut, p.wy) 130 if i%2: 131 undercut = draw.translate(undercut, +(p.wx + p.undercut)/2, y + (p.jy + p.wy)/2) 132 else: 133 undercut = draw.translate(undercut, -(p.wx + p.undercut)/2, y + (p.jy + p.wy)/2) 134 135 wire_rects.append(wire_rect) 136 pad_rects.append(undercut) 137 138 wire_rects = draw.union(*wire_rects) 139 pad_rects = draw.union(*pad_rects) 140 141 # Translations & Rotations 142 geom_list = [junction_rects, wire_rects, lead_rects, pad_rects] 143 geom_list = draw.rotate(geom_list, p.orientation) 144 geom_list = draw.translate(geom_list, p.pos_x, p.pos_y) 145 [junction_rects, wire_rects, lead_rects, pad_rects] = geom_list 146 147 # Converting drawings to qgeometry 148 self.add_qgeometry('poly', {'junction_rects': junction_rects}, layer = p.layer) 149 self.add_qgeometry('poly', {'wire_rects': wire_rects}, layer=p.layer) 150 self.add_qgeometry('poly', {'edge_leads': lead_rects}, layer=p.undercut_layer) 151 self.add_qgeometry('poly', {'inner_pads': pad_rects}, layer=p.alternating_layer) 152 153 # Positioning nodes 154 nodes.origin = np.zeros(2) 155 nodes.wire1 = np.array((0, max(positions) + p.jy/2)) 156 nodes.wire2 = np.array((0, min(positions) - p.jy/2)) 157 158 # Moving nodes along with component 159 translation_vec = np.array((p.pos_x, p.pos_y)) 160 theta = np.deg2rad(p.orientation) 161 162 for key, point in nodes.items(): 163 rotated = rotate_point(point, theta) 164 nodes[key] = rotated + translation_vec 165 166 self.nodes = nodes 167 return
Converts self.options into QGeometry.