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) 
class JunctionArray(qiskit_metal.qlibrary.core.base.QComponent):
 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_options = {'n': 20, 'jx': '100um', 'jy': '10um', 'wx': '20um', 'wy': '10um', 'undercut': '15um', 'orientation': '0', 'pos_x': '0um', 'pos_y': '0um', 'layer': '1', 'undercut_layer': '2', 'alternating_layer': '2'}

Default drawing options

component_metadata = {'short_name': 'JunctionArray', '_qgeometry_table_poly': 'True'}

Component metadata

def make(self):
 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.

def node(self, key):
169    def node(self, key): 
170        return self.nodes.get(key, None)