Fem palace qpdk transmon
import gdsfactory as gf
from qpdk import PDK, cells
from qpdk.tech import LAYER
from qpdk.utils import apply_additive_metals
PDK.activate()
@gf.cell
def transmon_component() -> gf.Component:
"""Create a qubit with resonator layout."""
c = gf.Component()
ref = c << cells.transmon_with_resonator(
qubit="double_pad_transmon_with_bbox",
resonator_length=5000.0,
resonator_meanders=5,
qubit_rotation=90,
)
c.add_ports(ref.ports)
# Add simulation area around the component
c.kdb_cell.shapes(LAYER.SIM_AREA).insert(c.bbox().enlarged(100, 100))
return c
component = transmon_component()
_c = component.copy()
_c.draw_ports()
_c
Inspect raw layers and apply additive metals¶
# inspect_layers(component, filename="transmon_raw_layers.png")
# Apply additive metals processing (QPDK-specific step)
processed = apply_additive_metals(component.copy())
# inspect_layers(processed, filename="transmon_processed_layers.png")
Convert QPDK etch layers to conductor geometry¶
import warnings
import klayout.db as kdb
from qpdk.tech import LAYER as QPDK_LAYER
from gsim.common.polygon_utils import decimate
sim_area_layer = (QPDK_LAYER.SIM_AREA[0], QPDK_LAYER.SIM_AREA[1])
etch_layer = (QPDK_LAYER.M1_ETCH[0], QPDK_LAYER.M1_ETCH[1])
CPW_LAYERS = {"SUBSTRATE": (1, 0), "SUPERCONDUCTOR": (2, 0), "VACUUM": (3, 0)}
layout = processed.kdb_cell.layout()
sim_region = kdb.Region(
processed.kdb_cell.begin_shapes_rec(layout.layer(*sim_area_layer))
)
etch_region = kdb.Region(processed.kdb_cell.begin_shapes_rec(layout.layer(*etch_layer)))
etch_polys = decimate(list(etch_region.each()))
etch_region = kdb.Region()
for poly in etch_polys:
etch_region.insert(poly)
if sim_region.is_empty():
warnings.warn("No polygons found on SIM_AREA", stacklevel=2)
if etch_region.is_empty():
warnings.warn("No polygons found on M1_ETCH", stacklevel=2)
conductor_region = sim_region - etch_region
etched = gf.Component("etched_component")
el = etched.kdb_cell.layout()
for name, region in [
("SUPERCONDUCTOR", conductor_region),
("SUBSTRATE", sim_region),
("VACUUM", sim_region),
]:
idx = el.layer(*CPW_LAYERS[name])
etched.kdb_cell.shapes(idx).insert(region)
for port in processed.ports:
etched.add_port(name=port.name, port=port)
# inspect_layers(etched, filename="transmon_etched_layers.png")
etched
Configure Simulation¶
from gsim.common.stack import Layer, LayerStack
from gsim.common.stack.materials import MATERIALS_DB
from gsim.palace import DrivenSim
# Build a CPW stack matching the etched component layers
substrate_thickness = 500
vacuum_thickness = 500
stack = LayerStack(pdk_name="qpdk")
stack.layers["SUBSTRATE"] = Layer(
name="SUBSTRATE",
gds_layer=(1, 0),
zmin=0.0,
zmax=substrate_thickness,
thickness=substrate_thickness,
material="sapphire",
layer_type="dielectric",
)
stack.layers["SUPERCONDUCTOR"] = Layer(
name="SUPERCONDUCTOR",
gds_layer=(2, 0),
zmin=substrate_thickness,
zmax=substrate_thickness,
thickness=0,
material="aluminum",
layer_type="conductor",
)
stack.layers["VACUUM"] = Layer(
name="VACUUM",
gds_layer=(3, 0),
zmin=substrate_thickness,
zmax=substrate_thickness + vacuum_thickness,
thickness=vacuum_thickness,
material="vacuum",
layer_type="dielectric",
)
stack.dielectrics = [
{
"name": "substrate",
"zmin": 0.0,
"zmax": substrate_thickness,
"material": "sapphire",
},
{
"name": "vacuum",
"zmin": substrate_thickness,
"zmax": substrate_thickness + vacuum_thickness,
"material": "vacuum",
},
]
stack.materials = {
"sapphire": MATERIALS_DB["sapphire"].to_dict(),
"aluminum": MATERIALS_DB["aluminum"].to_dict(),
"vacuum": MATERIALS_DB["vacuum"].to_dict(),
}
sim = DrivenSim()
sim.set_geometry(etched)
sim.set_stack(stack)
Configure eigenmode simulation¶
The junction port is modelled as a lumped element with a 10 nH inductance.
# Junction port with 10 nH inductance
sim.add_port("junction", layer="SUPERCONDUCTOR", length=5.0, inductance=10e-9)
# CPW feed ports
sim.add_cpw_port(
"o1", layer="SUPERCONDUCTOR", s_width=10.0, gap_width=6.0, length=5.0, offset=-30
)
sim.set_driven(fmin=7.75e9, fmax=7.8e9, num_points=100)
Mesh and run¶
sim.set_output_dir("./sim_qpdk_qubit_resonator")
sim.mesh(preset="fine", margin=0)
print(sim.validate_mesh())