Eigenmode simulation: floating transmon
Eigenmode simulation and EPR analysis of a floating transmon qubit coupled to a \(\lambda/2\) readout resonator in hanger-mode with a \(50\Omega\)-terminated transmission line segment.
Creates Qiskit Metal design
Exports design to
.gdsfileCreates GMSH mesh file (
.msh) with ports
[ ]:
import qiskit_metal as metal
from qiskit_metal import MetalGUI, Dict
from qiskit_metal.qlibrary.tlines.meandered import RouteMeander
from qiskit_metal.qlibrary.couplers.coupled_line_tee import CoupledLineTee
from qiskit_metal.qlibrary.terminations.open_to_ground import OpenToGround
from qiskit_metal.analyses import cpw_calculations
from SQDMetal.Utilities.Materials import Material
from SQDMetal.Utilities.QUtilities import QUtilities
from SQDMetal.Utilities.CpwParams import CpwParams
from SQDMetal.Utilities.QubitDesigner import ResonatorHalfWave
from qiskit_metal.qlibrary.tlines.straight_path import RouteStraight
from SQDMetal.Utilities.MakeGDS import MakeGDS
from pathlib import Path
%matplotlib inline
[ ]:
### DESIGN NAME (UPDATE)
name = "example_floatingTransmon"
### Qubit, resonator frequencies
qubit_freq_GHz = 4.5
res_freq_GHZ = 6.8
Design
[ ]:
# Create a DesignPlanar (class to handle 2D designs)
design = metal.designs.DesignPlanar(metadata=Dict(design_name=name))
design.overwrite_enabled = True # Enables overwriting components
design.chips.main.size.size_x = "4mm"
design.chips.main.size.size_y = "4mm"
design.chips.main.size.size_z = "500um"
design.chips.main.size.center_x = "0mm"
design.chips.main.size.center_y = "0mm"
# Resonator parameters
resonator = ResonatorHalfWave(res_freq_GHZ * 1e9)
m = Material("siliconcryo")
# CPW parameters
cpw_width = 10e-6
cpw = CpwParams(m.permittivity, 500e-6)
cpw_gap = cpw.get_gap_from_width(cpw_width)
l_fullwave, _, _ = cpw_calculations.guided_wavelength(
freq=resonator.f0,
line_width=cpw_width,
line_gap=cpw_gap,
substrate_thickness=cpw.dielectric_thickness,
film_thickness=200e-9,
)
l_halfwave = l_fullwave / 2
Draw components
[ ]:
# Import the modules and reload
import SQDMetal.Comps.Qubits as Qubits
TransmonTaperedInsets = Qubits.TransmonTaperedInsets
# tapered transmon
Q1 = TransmonTaperedInsets(design,
"Q1",
options=dict(
pos_x="0.5mm",
pos_y="1mm",
orientation='90',
connection_pads=dict(
readout=dict(
pad_gap="100um",
)
),
inductor_height='100um',
pad_gap='100um',
taper_height='0um',
)
)
##Coupling region
q1_read_T = CoupledLineTee(
design,
"Q1_Read_T",
options=dict(
pos_x="-1mm",
pos_y="0mm",
orientation="180",
coupling_space="5um",
coupling_length="220um",
down_length="100um",
prime_width=f"{cpw_width*1e6}um",
prime_gap=f"{cpw_gap*1e6}um",
second_width=f"{cpw_width*1e6}um",
second_gap=f"{cpw_gap*1e6}um",
open_termination=True,
),
)
##Feedline
# Left open
otg_left = OpenToGround(
design,
"otg_left",
options=dict(
pos_x='-1.8mm',
pos_y='0um',
orientation='180',
width=f"{cpw_width*1e6}um",
gap=f"{cpw_gap*1e6}um",
)
)
# Right open
otg_right = OpenToGround(
design,
"otg_right",
options=dict(
pos_x='0mm',
pos_y='0um',
orientation='0',
width=f"{cpw_width*1e6}um",
gap=f"{cpw_gap*1e6}um",
)
)
feedline = RouteStraight(
design,
"feedline_main",
options=dict(
pin_inputs=dict(
start_pin=dict(component='otg_left', pin='open'),
end_pin=dict(component='otg_right', pin='open'),
),
trace_width=f"{cpw_width*1e6}um",
trace_gap=f"{cpw_gap*1e6}um",
),
)
##Readout resonator
#calculate extra lengths on resonator from coupling regions
res_coupler_l_mm = QUtilities.calc_points_on_path([0], design, component_name="Q1_Read_T", trace_name='prime_cpw_sub')[-1]
q_coupler_l_mm = QUtilities.calc_points_on_path([0], design, component_name="Q1", trace_name='readout_wire')[-1]
extra_length_mm = res_coupler_l_mm + q_coupler_l_mm
read_q1 = RouteMeander(
design,
"Read_Q1",
options=dict(
hfss_wire_bonds=True,
pin_inputs=Dict(
start_pin=Dict(component="Q1", pin="readout"),
end_pin=Dict(component="Q1_Read_T", pin="second_end"),
),
lead=Dict(
start_straight="125um",
end_straight="125um",
),
meander=Dict(
asymmetry="0um",
spacing="100um",
),
trace_width=f"{cpw_width*1e6}um",
trace_gap=f"{cpw_gap*1e6}um",
fillet="40um",
total_length=f"{(l_halfwave * 1e3) - extra_length_mm:.2f}mm",
),
)
[ ]:
# create directories for saving if not present
gds_dir = Path("gds")
gds_dir.mkdir(exist_ok=True)
##GDS export
design.rebuild()
export_name = design.get_design_name() + ".gds"
gds_out = MakeGDS(design)
gds_out.export("gds/" + export_name, export_type="positive")
Capacitance simulation
[ ]:
from SQDMetal.PALACE.Capacitance_Simulation import PALACE_Capacitance_Simulation
############################################################
# Create the Palace Eigenmode simulation
sim_name = design.get_design_name()
# Palace simulation options
user_defined_options = {
"mesh_refinement": 0, #refines mesh in PALACE - essetially divides every mesh element in half
"dielectric_material": "silicon", #choose dielectric material - 'silicon' or 'sapphire'
"starting_freq": 3e9, #starting frequency in Hz
"number_of_freqs": 3, #number of eigenmodes to find
"solns_to_save": 3, #number of electromagnetic field visualizations to save
"solver_order": 2, #increasing solver order increases accuracy of simulation, but significantly increases sim time
"solver_tol": 1.0e-8, #error residual tolerance foriterative solver
"solver_maxits": 200, #number of solver iterations
"mesh_sampling": 130, #number of points to mesh along a geometry
"fillet_resolution":12, #number of vertices per quarter turn on a filleted path
'palace_mode': 'wsl',
'palace_wsl_spack_repo_directory': '~/repo',
'palace_dir': '~/repo/spack/opt/spack/linux-zen2/palace-develop-5zmriht6rd6ijchmfjmtl3a7pol3ijfn/bin/palace', # ADD YOUR PATH TO THE PALACE BINARY
'num_cpus': 16
}
cap_sim = PALACE_Capacitance_Simulation(name = "example_floatingTransmon", #name of simulation
metal_design = design, #feed in qiskit metal design
sim_parent_directory = "", #choose directory where mesh file, config file and HPC batch file will be saved
mode = 'simPC', #choose simulation mode 'HPC' or 'simPC'
meshing = 'GMSH', #choose meshing 'GMSH' or 'COMSOL'
user_options = user_defined_options, #provide options chosen above
view_design_gmsh_gui = False, #view design in GMSH gui
create_files = True)
#Add geometries
cap_sim.add_metallic(1)
cap_sim.add_ground_plane()
#Define meshing
cap_sim.fine_mesh_components(
design.components.keys(),
mesh_sampling=160,
min_size=12e-6,
max_size=250e-6,
taper_dist_min=12e-6,
taper_dist_max=250e-6,
metals_only=True,
)
#Prepare simulation (and mesh)
cap_sim.prepare_simulation()
#Run simulation
capMat = cap_sim.run()
[ ]:
# cap_sim.display_conductor_indices()
# Test E_C calculation from cap matrix
r = cap_sim.floatingTransmon_calc_params(res=resonator, qubit_freq=(qubit_freq_GHz * 1e9), print_all_capacitances=True)
Eigenmode simulation
[ ]:
from SQDMetal.PALACE.Eigenmode_Simulation import PALACE_Eigenmode_Simulation
from SQDMetal.Utilities.Materials import MaterialInterface
eigen_sim = PALACE_Eigenmode_Simulation(
name="example_floatingTransmon", # name of simulation
metal_design=design, # feed in qiskit metal design
sim_parent_directory="", # choose directory where mesh file, config file and HPC batch file will be saved
mode="simPC", # choose simulation mode 'HPC' or 'simPC'
meshing="GMSH", # choose meshing 'GMSH' or 'COMSOL'
user_options=user_defined_options, # provide options chosen above
view_design_gmsh_gui=False, # view design in GMSH gui
create_files=True,
) # create mesh, config and HPC batch files
# add components and ports
eigen_sim.add_metallic(1)
eigen_sim.add_ground_plane()
eigen_sim.create_port_JosephsonJunction("Q1", L_J=r['L_J_nH'] * 1e-9)
eigen_sim.create_port_CPW_on_Route("feedline_main", "start")
eigen_sim.create_port_CPW_on_Route("feedline_main", "end")
eigen_sim.fine_mesh_components(
design.components.keys(),
mesh_sampling=160,
min_size=10e-6,
max_size=200e-6,
taper_dist_min=12e-6,
metals_only=True,
)
# Run post-processing for participation ratios for lossy interfaces
eigen_sim.setup_EPR_interfaces(
metal_air=MaterialInterface("Aluminium-Vacuum"),
substrate_air=MaterialInterface("Silicon-Vacuum"),
substrate_metal=MaterialInterface("Silicon-Aluminium"),
)
# prepare and run simulation
eigen_sim.prepare_simulation()
eigen_sim.run()
[ ]:
# calculate EPR parameters
e = eigen_sim.calculate_hamiltonian_parameters_EPR(print_output=True)
[ ]:
# plot fields with eigenmode data
eigen_sim.plot_fields_with_data()