Source code for qiskit_metal.qlibrary.resonator.resonator_lumped

# -*- 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.
"""Lumped Resonator, as shown in Phys. Rev. Appl. 10, 034050 (2018).
"""
from math import sin, cos
import numpy as np
from qiskit_metal import draw, Dict
from qiskit_metal.qlibrary.core import QComponent


[docs] class ResonatorLumped(QComponent): ''' The base ResonatorLumped class Inherits the QComponent class .. image:: resonator_lumped.png .. meta:: Lumped Resonator Default Options: * pos_x: '0um' -- x-coordinate of the bottom center of the resonator * pos_y: '0um' -- y-coordinate of the bottom center of the resonator * orientation: '0' -- angle of rotation of the resonator * box_width: '5mm' -- the width of the rectangular resonator structure * box_height: '5mm' -- the height of the rectangular resonator structure * perimeter_thicknes: '0.01mm' -- the width of the resonator along the perimeter * res_width: '0.01m' -- the width of the resonator * initial: '0.1m' -- the length of the lower straight resonator segment * n_turns: '10' -- the number of turns in the curved resonator segment * turn_radius: '0.1mm' - the radius of the turns in the curved resonator segment * inner_space: '0.1mm' - the space between the curved resonator * outer_space: '0.1mm' -- the space between rectangular and curved resonator turns * final: '2.5mm' -- the length of the upper straight segment of the resonator * break_width: '0.2mm' -- the width of the "break" in the top of the rectangular resonator * layer: '1' -- the layer of the component ''' default_options = Dict( pos_x='0 um', pos_y='0 um', orientation='0', box_width='5mm', box_height='5mm', perimeter_thickness='0.01mm', res_width='0.01mm', initial='0.1mm', n_turns='10', turn_radius='0.1mm', inner_space='0.1mm', outer_space='0.1mm', final='2.5mm', break_width='0.2mm', layer='1', ) ##########################
[docs] def make(self): """Builds the component.""" """Convert self.options into QGeometry.""" p = self.parse_options() # Parse the string options into numbers # draw the perimeter box_out = draw.rectangle(p.box_width, p.box_height, 0.0, 0.0) box_in = draw.rectangle(p.box_width - 2.0 * p.perimeter_thickness, p.box_height - 2.0 * p.perimeter_thickness, 0.0, 0.0) perimeter = draw.subtract(box_out, box_in) perimeter = draw.translate(perimeter, xoff=0.0, yoff=0.5 * p.box_height) break_rect = draw.rectangle(p.break_width, p.break_width, 0.0, p.box_height) perimeter = draw.subtract(perimeter, break_rect) # start the resonator initial = draw.LineString([(0.0, p.perimeter_thickness), (0.0, p.perimeter_thickness + p.initial)]) # Draw the first quarter turn centerx, centery = -1.0 * p.turn_radius, p.perimeter_thickness + p.initial radius = p.turn_radius start_angle, end_angle = 0, 90 # In degrees numsegments = 1000 # The coordinates of the arc theta = np.radians(np.linspace(start_angle, end_angle, numsegments)) x = centerx + radius * np.cos(theta) y = centery + radius * np.sin(theta) arc = draw.LineString(np.column_stack([x, y])) # Draw the first half-turn (left); this gets repeated centerx2 = -0.5 * p.box_width + p.outer_space + p.turn_radius centery2 = p.perimeter_thickness + p.initial + 2.0 * p.turn_radius radius2 = p.turn_radius start_angle2, end_angle2 = 270, 90 # In degrees numsegments2 = 1000 # The coordinates of the arc theta2 = np.radians(np.linspace(start_angle2, end_angle2, numsegments2)) x2 = centerx2 + radius2 * np.cos(theta2) y2 = centery2 + radius2 * np.sin(theta2) arc_left_1 = draw.LineString(np.column_stack([x2, y2])) # Draw the first half-turn (right); this gets repeated centerx3 = 0.5 * p.box_width - p.outer_space - p.turn_radius centery3 = p.perimeter_thickness + p.initial + 4.0 * p.turn_radius radius3 = p.turn_radius start_angle3, end_angle3 = 90, -90 # In degrees numsegments3 = 1000 # The coordinates of the arc theta3 = np.radians(np.linspace(start_angle3, end_angle3, numsegments3)) x3 = centerx3 + radius3 * np.cos(theta3) y3 = centery3 + radius3 * np.sin(theta3) arc_right_1 = draw.LineString(np.column_stack([x3, y3])) # bottom half-line line1 = draw.LineString([ (-1.0 * p.turn_radius - 0.0 * p.res_width, p.perimeter_thickness + p.initial + p.turn_radius), (-0.5 * p.box_width + p.outer_space + p.turn_radius, p.perimeter_thickness + p.initial + p.turn_radius) ]) # bottom full-line (this one gets repeated) line2 = draw.LineString([ (-0.5 * p.box_width + p.outer_space + p.turn_radius, p.initial + 3.0 * p.turn_radius + p.res_width), (0.5 * p.box_width - p.outer_space - p.turn_radius, p.initial + 3.0 * p.turn_radius + p.res_width) ]) # repeat the full fline line3 = draw.translate(line2, 0.0, 2.0 * p.turn_radius) line4 = draw.translate(line3, 0.0, 2.0 * p.turn_radius) line5 = draw.translate(line4, 0.0, 2.0 * p.turn_radius) line6 = draw.translate(line5, 0.0, 2.0 * p.turn_radius) line7 = draw.translate(line6, 0.0, 2.0 * p.turn_radius) line8 = draw.translate(line7, 0.0, 2.0 * p.turn_radius) line9 = draw.translate(line8, 0.0, 2.0 * p.turn_radius) line10 = draw.translate(line9, 0.0, 2.0 * p.turn_radius) line11 = draw.translate(line10, 0.0, 2.0 * p.turn_radius) line12 = draw.translate(line11, 0.0, 2.0 * p.turn_radius) line13 = draw.translate(line12, 0.0, 2.0 * p.turn_radius) line14 = draw.translate(line13, 0.0, 2.0 * p.turn_radius) # hard code the position for now; make it adjustable later line_last = draw.translate( line1, 0.5 * p.box_width - 0.0 * p.turn_radius - p.outer_space, 28 * p.turn_radius) # draw the line exiting the rectangle final = draw.LineString([ (0.0, p.perimeter_thickness + p.initial + 30.0 * p.turn_radius), (0.0, p.perimeter_thickness + p.initial + 30.0 * p.turn_radius + p.final) ]) arc_last = draw.rotate(arc, 180, origin=(0.0, p.perimeter_thickness + p.initial + 1.5 * p.turn_radius)) arc_last = draw.translate(arc_last, 0.0, p.initial + 26 * p.turn_radius) # repeat the left turns arc_left_2 = draw.translate(arc_left_1, 0.0, 4.0 * p.turn_radius) arc_left_3 = draw.translate(arc_left_2, 0.0, 4.0 * p.turn_radius) arc_left_4 = draw.translate(arc_left_3, 0.0, 4.0 * p.turn_radius) arc_left_5 = draw.translate(arc_left_4, 0.0, 4.0 * p.turn_radius) arc_left_6 = draw.translate(arc_left_5, 0.0, 4.0 * p.turn_radius) arc_left_7 = draw.translate(arc_left_6, 0.0, 4.0 * p.turn_radius) # repeat the right turns arc_right_2 = draw.translate(arc_right_1, 0.0, 4.0 * p.turn_radius) arc_right_3 = draw.translate(arc_right_2, 0.0, 4.0 * p.turn_radius) arc_right_4 = draw.translate(arc_right_3, 0.0, 4.0 * p.turn_radius) arc_right_5 = draw.translate(arc_right_4, 0.0, 4.0 * p.turn_radius) arc_right_6 = draw.translate(arc_right_5, 0.0, 4.0 * p.turn_radius) arc_right_7 = draw.translate(arc_right_6, 0.0, 4.0 * p.turn_radius) # Translate and rotate all shapes objects = [ perimeter, initial, arc, arc_left_1, arc_left_2, arc_left_3, arc_left_4, arc_left_5, arc_left_6, arc_left_7, arc_right_1, arc_right_2, arc_right_2, arc_right_3, arc_right_4, arc_right_4, arc_right_5, arc_right_6, arc_right_7, arc_last, final, line1, line2, line3, line4, line5, line6, line7, line8, line9, line10, line11, line12, line13, line14, line_last ] # first translate so that the origin is at the middle of the loop objects = draw.translate(objects, 0.0, -0.5 * p.box_height) # now translate and rotate according to the values specified in the dictionary objects = draw.rotate(objects, p.orientation, origin=(0, 0)) objects = draw.translate(objects, xoff=p.pos_x, yoff=p.pos_y) [ perimeter, initial, arc, arc_left_1, arc_left_2, arc_left_3, arc_left_4, arc_left_5, arc_left_6, arc_left_7, arc_right_1, arc_right_2, arc_right_2, arc_right_3, arc_right_4, arc_right_4, arc_right_5, arc_right_6, arc_right_7, arc_last, final, line1, line2, line3, line4, line5, line6, line7, line8, line9, line10, line11, line12, line13, line14, line_last ] = objects # give polys names for qgeometry geom_perimeter = {'poly1': perimeter} geom_initial = {'poly2': initial} geom_arc = {'poly3': arc} geom_arc_left_1 = {'poly4': arc_left_1} geom_arc_left_2 = {'poly4': arc_left_2} geom_arc_left_3 = {'poly4': arc_left_3} geom_arc_left_4 = {'poly4': arc_left_4} geom_arc_left_5 = {'poly4': arc_left_5} geom_arc_left_6 = {'poly4': arc_left_6} geom_arc_left_7 = {'poly4': arc_left_7} geom_arc_right_1 = {'poly4': arc_right_1} geom_arc_right_2 = {'poly4': arc_right_2} geom_arc_right_3 = {'poly4': arc_right_3} geom_arc_right_4 = {'poly4': arc_right_4} geom_arc_right_5 = {'poly4': arc_right_5} geom_arc_right_6 = {'poly4': arc_right_6} geom_arc_right_7 = {'poly4': arc_right_7} geom_arc_last = {'poly4': arc_last} geom_final = {'poly': final} geom_line1 = {'poly5': line1} geom_line2 = {'poly6': line2} geom_line3 = {'poly7': line3} geom_line4 = {'poly8': line4} geom_line5 = {'poly9': line5} geom_line6 = {'poly10': line6} geom_line7 = {'poly11': line7} geom_line8 = {'poly11': line8} geom_line9 = {'poly9': line9} geom_line10 = {'poly10': line10} geom_line11 = {'poly11': line11} geom_line12 = {'poly12': line12} geom_line13 = {'poly13': line13} geom_line14 = {'poly14': line14} geom_line_last = {'poly14': line_last} # add to qgeometry self.add_qgeometry('poly', geom_perimeter, layer=p.layer, subtract=False) self.add_qgeometry('path', geom_initial, layer=p.layer, subtract=False, width=p.res_width) self.add_qgeometry('path', geom_arc, layer=p.layer, subtract=False, width=p.res_width) self.add_qgeometry('path', geom_arc_left_1, layer=p.layer, subtract=False, width=p.res_width) self.add_qgeometry('path', geom_arc_left_2, layer=p.layer, subtract=False, width=p.res_width) self.add_qgeometry('path', geom_arc_left_3, layer=p.layer, subtract=False, width=p.res_width) self.add_qgeometry('path', geom_arc_left_4, layer=p.layer, subtract=False, width=p.res_width) self.add_qgeometry('path', geom_arc_left_5, layer=p.layer, subtract=False, width=p.res_width) self.add_qgeometry('path', geom_arc_left_6, layer=p.layer, subtract=False, width=p.res_width) self.add_qgeometry('path', geom_arc_left_7, layer=p.layer, subtract=False, width=p.res_width) self.add_qgeometry('path', geom_arc_right_1, layer=p.layer, subtract=False, width=p.res_width) self.add_qgeometry('path', geom_arc_right_2, layer=p.layer, subtract=False, width=p.res_width) self.add_qgeometry('path', geom_arc_right_3, layer=p.layer, subtract=False, width=p.res_width) self.add_qgeometry('path', geom_arc_right_4, layer=p.layer, subtract=False, width=p.res_width) self.add_qgeometry('path', geom_arc_right_5, layer=p.layer, subtract=False, width=p.res_width) self.add_qgeometry('path', geom_arc_right_6, layer=p.layer, subtract=False, width=p.res_width) self.add_qgeometry('path', geom_arc_right_7, layer=p.layer, subtract=False, width=p.res_width) self.add_qgeometry('path', geom_arc_last, layer=p.layer, subtract=False, width=p.res_width) self.add_qgeometry('path', geom_line1, layer=p.layer, subtract=False, width=p.res_width) self.add_qgeometry('path', geom_line2, layer=p.layer, subtract=False, width=p.res_width) self.add_qgeometry('path', geom_line3, layer=p.layer, subtract=False, width=p.res_width) self.add_qgeometry('path', geom_line4, layer=p.layer, subtract=False, width=p.res_width) self.add_qgeometry('path', geom_line5, layer=p.layer, subtract=False, width=p.res_width) self.add_qgeometry('path', geom_line6, layer=p.layer, subtract=False, width=p.res_width) self.add_qgeometry('path', geom_line7, layer=p.layer, subtract=False, width=p.res_width) self.add_qgeometry('path', geom_line8, layer=p.layer, subtract=False, width=p.res_width) self.add_qgeometry('path', geom_line9, layer=p.layer, subtract=False, width=p.res_width) self.add_qgeometry('path', geom_line10, layer=p.layer, subtract=False, width=p.res_width) self.add_qgeometry('path', geom_line11, layer=p.layer, subtract=False, width=p.res_width) self.add_qgeometry('path', geom_line12, layer=p.layer, subtract=False, width=p.res_width) self.add_qgeometry('path', geom_line13, layer=p.layer, subtract=False, width=p.res_width) self.add_qgeometry('path', geom_line14, layer=p.layer, subtract=False, width=p.res_width) self.add_qgeometry('path', geom_line_last, layer=p.layer, subtract=False, width=p.res_width) self.add_qgeometry('path', geom_final, layer=p.layer, subtract=False, width=p.res_width) ########################## # Add Qpin connections # define a function that both rotates and translates the qpin coordinates def qpin_rotate_translate(x): 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 # East pin qp1a = (0.5 * p.box_width - p.perimeter_thickness, 0.0) qp1b = (0.5 * p.box_width, 0.0) qp1a = qpin_rotate_translate(qp1a) qp1b = qpin_rotate_translate(qp1b) self.add_pin('pin_east', points=np.array([qp1a, qp1b]), width=0.01, input_as_norm=True) # North-East pin qpa_ne = (0.5 * p.box_width - p.perimeter_thickness, 0.5 * p.box_height - p.perimeter_thickness) qpb_ne = (0.5 * p.box_width, 0.5 * p.box_height) qpa_ne = qpin_rotate_translate(qpa_ne) qpb_ne = qpin_rotate_translate(qpb_ne) self.add_pin('pin_ne', points=np.array([qpa_ne, qpb_ne]), width=0.01, input_as_norm=True) # South-East pin qpa_se = (0.5 * p.box_width - p.perimeter_thickness, -0.5 * p.box_height + p.perimeter_thickness) qpb_se = (0.5 * p.box_width, -0.5 * p.box_height) qpa_se = qpin_rotate_translate(qpa_se) qpb_se = qpin_rotate_translate(qpb_se) self.add_pin('pin_se', points=np.array([qpa_se, qpb_se]), width=0.01, input_as_norm=True) # North-West pin qpa_nw = (-0.5 * p.box_width + p.perimeter_thickness, 0.5 * p.box_height - p.perimeter_thickness) qpb_nw = (-0.5 * p.box_width, 0.5 * p.box_height) qpa_nw = qpin_rotate_translate(qpa_nw) qpb_nw = qpin_rotate_translate(qpb_nw) self.add_pin('pin_nw', points=np.array([qpa_nw, qpb_nw]), width=0.01, input_as_norm=True) # West pin qp2a = (-0.5 * p.box_width + p.perimeter_thickness, 0.0) qp2b = (-0.5 * p.box_width, 0.0) qp2a = qpin_rotate_translate(qp2a) qp2b = qpin_rotate_translate(qp2b) self.add_pin('pin_west', points=np.array([qp2a, qp2b]), width=0.01, input_as_norm=True) # South-West pin qpa_sw = (-0.5 * p.box_width + p.perimeter_thickness, -0.5 * p.box_height + p.perimeter_thickness) qpb_sw = (-0.5 * p.box_width, -0.5 * p.box_height) qpa_sw = qpin_rotate_translate(qpa_sw) qpb_sw = qpin_rotate_translate(qpb_sw) self.add_pin('pin_sw', points=np.array([qpa_sw, qpb_sw]), width=0.01, input_as_norm=True) # South pin qpa_s = (0.0, -0.5 * p.box_height + p.perimeter_thickness) qpb_s = (0.0, -0.5 * p.box_height) qpa_s = qpin_rotate_translate(qpa_s) qpb_s = qpin_rotate_translate(qpb_s) self.add_pin('pin_s', points=np.array([qpa_s, qpb_s]), width=0.01, input_as_norm=True) # north pin qpa_n = (0.0, -0.5 * p.box_height + p.perimeter_thickness + p.initial + 30.0 * p.turn_radius) qpb_n = (0.0, -0.5 * p.box_height + p.perimeter_thickness + p.initial + 30.0 * p.turn_radius + p.final) qpa_n = qpin_rotate_translate(qpa_n) qpb_n = qpin_rotate_translate(qpb_n) self.add_pin('pin_n', points=np.array([qpa_n, qpb_n]), width=0.01, input_as_norm=True)