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 .gds file

  • Creates 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()