Source code for qiskit_metal.qlibrary.qubits.Transmon_Interdigitated

# -*- coding: utf-8 -*-

# This code is part of Qiskit.
#
# (C) Copyright IBM 2017, 2021.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.
"""Interdigitated Transmon."""

from math import sin, cos
import numpy as np
from qiskit_metal import draw, Dict
from qiskit_metal.qlibrary.core.base import QComponent

# from ... import config
# if not config.is_building_docs():
#    from qiskit_metal import is_true


[docs] class TransmonInterdigitated(QComponent): """ The base "TransmonInterdigitated" inherits the "QComponent" class. This creates a transmon pocket with two large pads connected by a Josephson junction. Both pads have four interdigitated "fingers" which increase the capacitance of the structure. There are three coupling capacitor pads with qpins defined; these can be connected to other structures in a design using CPWs. .. image:: TransmonInterdigitated.png .. meta:: :description: Transmon Interdigitated Default Options: * pad_width: '1000um' -- width of the large rectangular pads on either side of the junction * pad_height: '300um' -- height of the large rectangular pads on either side of the junction * finger_width: '50um' -- width of the "finger" on either side of the junction * finger_height: '100um' -- height of the "finger" on the side of the junction * finger_space: '50um' -- height of the Josephson Junction (equivalently; space between two fingers) * pad_pos_x: '0um' -- the internal coordinate defining the center of the bottom rectangular pad * pad_pos_y: '0um' -- the internal coordinate defining the center of the bottom rectangular pad * comb_width: '50um' -- the width of the four interdigitated combs connected to either pad * comb_space_vert: '50um' -- the space between the edge of a comb and the edge of the opposite rectangular pad * comb_space_hor: '50um' -- the space between adjacent interdigitated comb structures * jj_width: '20um' -- the width of the Josephson Junction located between the two fingers of the device * cc_space: '50um' -- the space between the lower rectangular pad and the coupling capacitor below it * cc_width: '100um' -- the width of the coupling capacitor located below the bottom rectangular pad * cc_height: '100um' -- the height of the coupling capacitor located below the bottom rectangular pad * cc_topleft_space: '50um' -- the space between the upper rectangular pad and the top left coupling capacitor * cc_topleft_width: '100um' -- the width of the top left coupling capacitor pad * cc_topleft_height: '100um' -- the height of the top left coupling capacitor pad * cc_topright_space: '50um' -- the space between the upper rectangular pad and the top right coupling capacitor * cc_topright_width: '100um' -- the width of the top right coupling capacitor pad * cc_topright_height: '100um' -- the height of the top right coupling capacitor pad * rotation_top_pad: '180' -- internal coordinate defining the angle of rotation between top and bottom pads * inductor_width: '20.0um' -- the width of the Josephson Junction """ # Default drawing options default_options = Dict( pad_width="1000um", pad_height="300um", finger_width="50um", finger_height="100um", finger_space="50um", pad_pos_x="0um", pad_pos_y="0um", comb_width="50um", comb_space_vert="50um", comb_space_hor="50um", jj_width="20um", cc_space="50um", cc_width="100um", cc_height="100um", cc_topleft_space="50um", cc_topleft_width="100um", cc_topleft_height="100um", cc_topright_space="50um", cc_topright_width="100um", cc_topright_height="100um", rotation_top_pad="180", inductor_width="20um", ) """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): """Convert self.options into QGeometry.""" p = self.parse_options() # Parse the string options into numbers # draw the lower pad as a rectangle pad_lower = draw.rectangle(p.pad_width, p.pad_height, p.pad_pos_x, p.pad_pos_y) # draw the lower finger as a rectangle finger_lower = draw.rectangle( p.finger_width, p.finger_height, p.pad_pos_x, p.pad_pos_y + 0.49999 * (p.pad_height) + 0.49999 * (p.finger_height), ) # draw the Josephson Junction as a LineString rect_jj = draw.LineString( [ (0, 0.5 * p.pad_height + p.finger_height), (0, 0.5 * p.pad_height + p.finger_height + p.finger_space), ] ) # draw the first comb to the right of the lower finger as a rectangle comb1_lower = draw.rectangle( p.comb_width, (2 * p.finger_height), (0.5 * p.finger_width + p.comb_space_hor + 0.5 * p.comb_width), (p.pad_pos_y + 0.5 * p.pad_height + 1.0 * p.finger_height), ) # draw the second comb to the right of the lower finger by translating the first comb comb2_lower = draw.translate( comb1_lower, 2.0 * (p.comb_space_hor + p.comb_width), 0.0 ) # draw the first comb to the left of the lower finger comb3_lower = draw.rectangle( p.comb_width, (2 * p.finger_height), (-0.5 * p.finger_width - 2.0 * p.comb_space_hor - 1.5 * p.comb_width), (p.pad_pos_y + 0.5 * p.pad_height + 1.0 * p.finger_height), ) # draw the second comb to the left of the lower finger comb4_lower = draw.translate( comb3_lower, -2.0 * (p.comb_space_hor + p.comb_width), 0.0 ) coupling_capacitor = draw.rectangle( p.cc_width, p.cc_height, p.pad_pos_x, p.pad_pos_y - 0.5 * (p.pad_height) - p.cc_space - 0.5 * p.cc_height, ) cc_topleft = draw.rectangle( p.cc_topleft_width, p.cc_topleft_height, p.pad_pos_x - 0.5 * p.pad_width + 0.5 * p.cc_topleft_width, p.pad_pos_y + 1.5 * p.pad_height + 2.0 * p.finger_height + p.finger_space + p.cc_topleft_space + 0.5 * p.cc_topleft_height, ) cc_topright = draw.translate( cc_topleft, p.pad_width - 0.5 * p.cc_topleft_width - 0.5 * p.cc_topright_width, 0.0, ) # merge the bottom elements bottom = draw.union( pad_lower, finger_lower, comb1_lower, comb2_lower, comb3_lower, comb4_lower ) # create the top portion of the comb by translating and rotating # the bottom portion of the comb top = draw.translate(bottom, 0.0, p.pad_height + p.finger_space) top = draw.rotate(top, p.rotation_top_pad) # draw the transmon pocket bounding box pocket = draw.rectangle(1.5 * p.pad_width, 5.0 * p.pad_height) # the origin is originally set to the middle of the lower pad. # Let's move it to the center of the JJ. bottom = draw.translate( bottom, 0.0, -0.5 * p.pad_height - p.finger_height - 0.5 * p.finger_space ) top = draw.translate( top, 0.0, -0.5 * p.pad_height - p.finger_height - 0.5 * p.finger_space ) coupling_capacitor = draw.translate( coupling_capacitor, 0.0, -0.5 * p.pad_height - p.finger_height - 0.5 * p.finger_space, ) cc_topleft = draw.translate( cc_topleft, 0.0, -0.5 * p.pad_height - p.finger_height - 0.5 * p.finger_space, ) cc_topright = draw.translate( cc_topright, 0.0, -0.5 * p.pad_height - p.finger_height - 0.5 * p.finger_space, ) rect_jj = draw.translate( rect_jj, 0.0, -0.5 * p.pad_height - p.finger_height - 0.5 * p.finger_space ) # now translate the final structure according to the user input bottom = draw.rotate(bottom, p.orientation, origin=(0, 0)) bottom = draw.translate(bottom, p.pos_x, p.pos_y) top = draw.rotate(top, p.orientation, origin=(0, 0)) top = draw.translate(top, p.pos_x, p.pos_y) coupling_capacitor = draw.rotate( coupling_capacitor, p.orientation, origin=(0, 0) ) coupling_capacitor = draw.translate(coupling_capacitor, p.pos_x, p.pos_y) cc_topleft = draw.rotate(cc_topleft, p.orientation, origin=(0, 0)) cc_topleft = draw.translate(cc_topleft, p.pos_x, p.pos_y) cc_topright = draw.rotate(cc_topright, p.orientation, origin=(0, 0)) cc_topright = draw.translate(cc_topright, p.pos_x, p.pos_y) rect_jj = draw.rotate(rect_jj, p.orientation, origin=(0, 0)) rect_jj = draw.translate(rect_jj, p.pos_x, p.pos_y) pocket = draw.rotate(pocket, p.orientation, origin=(0, 0)) pocket = draw.translate(pocket, p.pos_x, p.pos_y) # add each shape separately geom1 = {"pad_bot": bottom} geom2 = {"pad_top": top} geom3 = {"readout": coupling_capacitor} geom4 = {"bus1": cc_topleft} geom5 = {"bus2": cc_topright} geom_pocket = {"pocket": pocket} geom_jj = {"design": rect_jj} # add to qgeometry self.add_qgeometry("poly", geom1, layer=p.layer, subtract=False) self.add_qgeometry("poly", geom2, layer=p.layer, subtract=False) self.add_qgeometry("poly", geom3, layer=p.layer, subtract=False) self.add_qgeometry("poly", geom4, layer=p.layer, subtract=False) self.add_qgeometry("poly", geom5, layer=p.layer, subtract=False) self.add_qgeometry("poly", geom_pocket, layer=p.layer, subtract=True) self.add_qgeometry( "junction", geom_jj, layer=p.layer, subtract=False, width=p.inductor_width ) ################################################################### # Add Qpin connections for coupling capacitors # define a function that both rotates and translates the # qpin coordinates def qpin_rotate_translate(x): """This function rotates the coordinates of the three qpins according to the user inputs for "pos_x", "pos_y" and "orientation". """ y = list(x) z = [0.0, 0.0] z[0] = y[0] * cos(p.orientation * 3.14159 / 180) - y[1] * sin( p.orientation * 3.14159 / 180 ) z[1] = y[0] * sin(p.orientation * 3.14159 / 180) + y[1] * cos( p.orientation * 3.14159 / 180 ) z[0] = z[0] + p.pos_x z[1] = z[1] + p.pos_y x = (z[0], z[1]) return x # Add Qpin connections for the bottom coupling capacitor qp1a = (0.0, -0.5 * p.pad_height - p.finger_height - 0.5 * p.finger_space) qp1b = ( 0.0, -0.5 * p.pad_height - p.cc_space - p.cc_height - 0.5 * p.pad_height - p.finger_height - 0.5 * p.finger_space, ) # rotate and translate the qpin coordinates qp1a = qpin_rotate_translate(qp1a) qp1b = qpin_rotate_translate(qp1b) self.add_pin( "readout", points=np.array([qp1a, qp1b]), width=0.01, input_as_norm=True ) # Add Qpin connections for top left coupling capacitor qp2a = ( p.pad_pos_x - 0.5 * p.pad_width + 0.5 * p.cc_topleft_width, p.pad_pos_y + 1.5 * p.pad_height + 2.0 * p.finger_height + p.finger_space + p.cc_topleft_space + 0.5 * p.cc_topleft_height - 0.5 * p.pad_height - p.finger_height - 0.5 * p.finger_space, ) qp2b = ( p.pad_pos_x - 0.5 * p.pad_width, p.pad_pos_y + 1.5 * p.pad_height + 2.0 * p.finger_height + p.finger_space + p.cc_topleft_space + 0.5 * p.cc_topleft_height - 0.5 * p.pad_height - p.finger_height - 0.5 * p.finger_space, ) qp2a = qpin_rotate_translate(qp2a) qp2b = qpin_rotate_translate(qp2b) self.add_pin( "bus1", points=np.array([qp2a, qp2b]), width=0.01, input_as_norm=True ) # Add Qpin connections for top right coupling capacitor qp3a = ( p.pad_pos_x + 0.5 * p.pad_width - 0.5 * p.cc_topleft_width, p.pad_pos_y + 1.5 * p.pad_height + 2.0 * p.finger_height + p.finger_space + p.cc_topleft_space + 0.5 * p.cc_topleft_height - 0.5 * p.pad_height - p.finger_height - 0.5 * p.finger_space, ) qp3b = ( p.pad_pos_x + 0.5 * p.pad_width, p.pad_pos_y + 1.5 * p.pad_height + 2.0 * p.finger_height + p.finger_space + p.cc_topleft_space + 0.5 * p.cc_topleft_height - 0.5 * p.pad_height - p.finger_height - 0.5 * p.finger_space, ) qp3a = qpin_rotate_translate(qp3a) qp3b = qpin_rotate_translate(qp3b) self.add_pin( "bus2", points=np.array([qp3a, qp3b]), width=0.01, input_as_norm=True )