# -*- 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.
import numpy as np
from qiskit_metal import draw, Dict
from qiskit_metal.qlibrary.core import BaseQubit
[docs]
class TunableCoupler01(BaseQubit):
"""One of the tunable couplers Based off the implementation in
https://arxiv.org/pdf/2011.01261.pdf.
WIP - initial test structure
Inherits `BaseQubit` class
Description:
Creates a tunable coupler, interdigitated capacitor to ground, with a junction to ground and a coupler arm.
The shapes origin is shown with 0. X the location of the SQUID.
::
connection claw
_____
X | |
| | | | | | | |
| | | | | | | | charge island
| | | | | |
--------------------0--------------------
.. image::
TunableCoupler01.png
.. meta::
:description: Tunable Coupler 01
Options:
Convention: Values (unless noted) are strings with units included,
(e.g., '30um')
BaseQubit Default Options:
* connection_pads: empty Dict -- Currently not used, connection count is static. (WIP)
* _default_connection_pads: empty Dict -- The default values for the (if any) connection lines of the qubit.
Default Options:
* c_width: '400um' -- The width (x-axis) of the interdigitated charge island
* l_width: '20um' -- The width of lines forming the body and arms of the charge island
* l_gap: '10um' -- The dielectric gap of the charge island to ground
* a_height: '60um' -- The length of the arms forming the 'fingers' of the charge island
* cp_height: '15um' -- The thickness (y-axis) of the connection claw
* cp_arm_length: '30um' -- The length of the 'fingers' of the connection claw (Warning: can break
the component if they are too long)
* cp_arm_width: '6um' -- The width of the 'fingers' of the connection claw (Warning: can break
the component if too wide)
* cp_gap: '6um' -- The dielectric gap of the connection claw
* cp_gspace: '3um' -- How much ground remains between the connection claw and the charge island
* fl_width: '5um' -- Width of the flux line
* fl_gap: '3um' -- Dielectric gap of the flux line
* fl_length: '10um' -- Length of the flux line for mutual inductance to the SQUID
* fl_ground: '2um' -- Amount of ground between the SQUID and the flux line
* _default_connection_pads: Currently empty
"""
default_options = Dict(
c_width="400um",
l_width="20um",
l_gap="10um",
a_height="60um",
cp_height="15um",
cp_arm_length="30um",
cp_arm_width="6um",
cp_gap="6um",
cp_gspace="3um",
fl_width="5um",
fl_gap="3um",
fl_length="10um",
fl_ground="2um",
)
component_metadata = Dict(
short_name="Pocket",
_qgeometry_table_path="True",
_qgeometry_table_poly="True",
_qgeometry_table_junction="True",
)
TOOLTIP = """One of the tunable couplers"""
[docs]
def make(self):
"""Builds the component."""
p = self.p
# Draw the charge island
btm = draw.shapely.geometry.box(
-p.c_width / 2, -p.l_width / 2, 0, p.l_width / 2
)
x_spot = p.c_width / 2 - p.l_width / 2
arm1 = draw.shapely.geometry.box(
-(x_spot + p.l_width / 2),
p.l_width / 2,
-(x_spot - p.l_width / 2),
p.a_height,
)
arm2 = draw.shapely.geometry.box(
-((x_spot) * 3 / 5 + p.l_width / 2),
p.l_width / 2,
-((x_spot) * 3 / 5 - p.l_width / 2),
p.a_height,
)
arm3 = draw.shapely.geometry.box(
-((x_spot) * 1 / 5 + p.l_width / 2),
p.l_width / 2,
-((x_spot) * 1 / 5 - p.l_width / 2),
p.a_height,
)
left_side = draw.shapely.ops.unary_union([btm, arm1, arm2, arm3])
cap_island = draw.shapely.ops.unary_union(
[
left_side,
draw.shapely.affinity.scale(
left_side, xfact=-1, yfact=1, origin=(0, 0)
),
]
)
cap_subtract = cap_island.buffer(p.l_gap, cap_style=3, join_style=2)
# Reference coordinates
cpl_x = 1 / 5 * x_spot
cpl_y = p.a_height + p.l_gap + p.cp_gap + p.cp_gspace
fl_y = p.a_height + p.l_gap + p.fl_ground + p.fl_gap + p.fl_width / 2
# Draw the junction and flux line
rect_jj = draw.LineString(
[(-cpl_x * 3, p.a_height), (-cpl_x * 3, p.a_height + p.l_gap)]
)
flux_line = draw.LineString(
[
[-cpl_x * 3 - p.fl_length, fl_y],
[-cpl_x * 3, fl_y],
[-cpl_x * 3, fl_y + 0.01],
]
)
# Draw the connector
cpl_x = 1 / 5 * x_spot
cpl_y = p.a_height + p.l_gap + p.cp_gap + p.cp_gspace
con_pad = draw.shapely.geometry.box(
cpl_x - 1 / 5 * x_spot - p.cp_arm_width / 2,
cpl_y,
cpl_x + 1 / 5 * x_spot + p.cp_arm_width / 2,
cpl_y + p.cp_height,
)
con_arm_l = draw.shapely.geometry.box(
cpl_x - 1 / 5 * x_spot - p.cp_arm_width / 2,
cpl_y - p.cp_arm_length,
cpl_x - 1 / 5 * x_spot + p.cp_arm_width / 2,
cpl_y,
)
con_arm_r = draw.shapely.geometry.box(
cpl_x + 1 / 5 * x_spot - p.cp_arm_width / 2,
cpl_y - p.cp_arm_length,
cpl_x + 1 / 5 * x_spot + p.cp_arm_width / 2,
cpl_y,
)
con_body = draw.shapely.ops.unary_union([con_pad, con_arm_l, con_arm_r])
con_sub = con_body.buffer(p.cp_gap, cap_style=3, join_style=2)
con_pin = draw.LineString([[cpl_x, cpl_y], [cpl_x, cpl_y + p.cp_height]])
# Rotate and translate.
c_items = [
cap_island,
cap_subtract,
rect_jj,
con_body,
con_sub,
flux_line,
con_pin,
]
c_items = draw.rotate(c_items, p.orientation, origin=(0, 0))
c_items = draw.translate(c_items, p.pos_x, p.pos_y)
[cap_island, cap_subtract, rect_jj, con_body, con_sub, flux_line, con_pin] = (
c_items
)
# Add to qgeometry
self.add_qgeometry(
"poly",
{"cap_island": cap_island, "connector_body": con_body},
layer=p.layer,
)
self.add_qgeometry(
"poly",
{"cap_subtract": cap_subtract, "connector_sub": con_sub},
layer=p.layer,
subtract=True,
)
self.add_qgeometry(
"path", {"flux_line": flux_line}, width=p.fl_width, layer=p.layer
)
self.add_qgeometry(
"path",
{"flux_line_sub": flux_line},
width=p.fl_width + 2 * p.fl_gap,
subtract=True,
layer=p.layer,
)
self.add_qgeometry("junction", dict(rect_jj=rect_jj), width=p.l_width)
# Add pin
self.add_pin(
"Control",
points=np.array(con_pin.coords),
width=p.l_width,
input_as_norm=True,
)
self.add_pin(
"Flux",
points=np.array(flux_line.coords[-2:]),
width=p.l_width,
input_as_norm=True,
)