# This code is part of KQCircuits
# Copyright (C) 2022 IQM Finland Oy
#
# This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
# License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with this program. If not, see
# https://www.gnu.org/licenses/gpl-3.0.html.
#
# The software distribution should follow IQM trademark policy for open-source software
# (meetiqm.com/iqm-open-source-trademark-policy). IQM welcomes contributions to the code.
# Please see our contribution agreements for individuals (meetiqm.com/iqm-individual-contributor-license-agreement)
# and organizations (meetiqm.com/iqm-organization-contributor-license-agreement).
from kqcircuits.util.geometry_helper import bspline_points
from kqcircuits.util.parameters import Param, pdt
from kqcircuits.qubits.double_pads import DoublePads
from kqcircuits.pya_resolver import pya
[docs]
class DoublePadsSplines(DoublePads):
"""A two-island qubit, consisting of two spline-constructed islands shunted by a junction,
with one capacitive coupler.
Contains a coupler on the north edge and two separate qubit islands in the center
joined by a junction or SQUID loaded from another library.
Refpoint for a readout line at the opening to the coupler and a modifiable refpoint for
a driveline outside of the rectangle.
"""
island_spline = Param(
pdt.TypeList,
"Control points of a B-Spline that defines left half of the island",
[-250, 20, -250, 80, -100, 100, 0, 100],
)
island_spline_samples = Param(
pdt.TypeInt,
"Number of samples taken from each island spline",
100,
docstring=(
"Number of samples taken from each island spline. "
"There is a spline for each consequent series of four control points"
),
)
def _build_island1(self, squid_height, taper_height):
island1_bottom = self.squid_offset + squid_height / 2
curve_start = pya.DPoint(0, island1_bottom + taper_height)
island1_control_points = [curve_start + pya.DPoint(-self.island1_taper_width / 2, 0)] + [
curve_start + pya.DPoint(float(self.island_spline[idx]), float(self.island_spline[idx + 1]))
for idx in range(0, len(self.island_spline), 2)
]
island1_control_points += [pya.DPoint(-p.x, p.y) for p in reversed(island1_control_points[:-1])]
for i, p in enumerate(island1_control_points):
self.refpoints[f"island1_control_point_{i}"] = p
island1_polygon = pya.DPolygon(
bspline_points(island1_control_points, self.island_spline_samples, startpoint=True, endpoint=True)
)
island1_region = pya.Region(island1_polygon.to_itype(self.layout.dbu))
island1_taper = pya.Region(
pya.DPolygon(
[
# pertrude taper into island in case of precision errors
pya.DPoint(self.island1_taper_width / 2, island1_bottom + taper_height + 1),
pya.DPoint(self.island1_taper_width / 2, island1_bottom + taper_height),
pya.DPoint(self.island1_taper_junction_width / 2, island1_bottom),
pya.DPoint(-self.island1_taper_junction_width / 2, island1_bottom),
pya.DPoint(-self.island1_taper_width / 2, island1_bottom + taper_height),
# pertrude taper into island in case of precision errors
pya.DPoint(-self.island1_taper_width / 2, island1_bottom + taper_height + 1),
]
).to_itype(self.layout.dbu)
)
return island1_region + island1_taper
def _build_island2(self, squid_height, taper_height):
island2_top = self.squid_offset - squid_height / 2
curve_start = pya.DPoint(0, island2_top - taper_height)
island2_control_points = [curve_start + pya.DPoint(-self.island2_taper_width / 2, 0)] + [
curve_start + pya.DPoint(float(self.island_spline[idx]), -float(self.island_spline[idx + 1]))
for idx in range(0, len(self.island_spline), 2)
]
island2_control_points += [pya.DPoint(-p.x, p.y) for p in reversed(island2_control_points[:-1])]
for i, p in enumerate(island2_control_points):
self.refpoints[f"island2_control_point_{i}"] = p
island2_polygon = pya.DPolygon(
bspline_points(island2_control_points, self.island_spline_samples, startpoint=True, endpoint=True)
)
island2_region = pya.Region(island2_polygon.to_itype(self.layout.dbu))
island2_taper = pya.Region(
pya.DPolygon(
[
# pertrude taper into island in case of precision errors
pya.DPoint(self.island2_taper_width / 2, island2_top - taper_height - 1),
pya.DPoint(self.island2_taper_width / 2, island2_top - taper_height),
pya.DPoint(self.island2_taper_junction_width / 2, island2_top),
pya.DPoint(-self.island2_taper_junction_width / 2, island2_top),
pya.DPoint(-self.island2_taper_width / 2, island2_top - taper_height),
# pertrude taper into island in case of precision errors
pya.DPoint(-self.island2_taper_width / 2, island2_top - taper_height - 1),
]
).to_itype(self.layout.dbu)
)
return island2_region + island2_taper