Note
This page was generated from tut/4-Analysis/4.19-Analyze-a-transmon-using-ElmerFEM.ipynb.
4.19 Analyse a Transmon Qubit using ElmerFEM¶
This notebook demonstrates the new open-source rendering and simulation capabilities of Qiskit Metal using Gmsh and ElmerFEM for tuning the performance parameters of a transmon qubit. instructions to download and install this branch of Qiskit Metal with Gmsh and ElmerFEM, can he found here The tutorial has the
following steps:
Contents¶
1. Creating a Transmon Qubit in Qiskit Metal¶
2. Rendering and meshing your design in the QGmshRenderer¶
Rendering the design wireframe
Applying a basic mesh
Customizing the mesh
Setting initial mesh size parameters
Using the Intelli-mesh feature in
QGmshRenderer
Saving your mesh to a file
3. Rendering your design in QElmerRenderer (uses QGmshRenderer)¶
Render design and generate mesh
Export the mesh
Run the capacitance simulation
Add solution setup
Run the solver
Export capacitance matrix
4. Perform LOM 2.0 Analysis¶
Import the capacitance matrix
Define cells and subsystems
Define the composite system
Compute the results:
Qubit Frequency (\(f_Q\))
Anharmonicity (\(\alpha\))
Readout \(\chi\)
Coupling \(g\)
💡 Using this tutorial without the Qt GUI
This tutorial uses the desktop
MetalGUI. To follow along on Colab, Binder, JupyterHub, or any environment where Qt isn’t available, replace any ``gui.rebuild()`` / ``gui.screenshot()`` call with ``qm.view(design)`` — it renders the design to a matplotlibFigureyou can display inline or save withfig.savefig(...).See 1.4 Headless quick view for a complete runnable walkthrough and
`docs/headless-usage.rst<../../../docs/headless-usage.rst>`__ for the full reference.
Necessary Imports¶
[ ]:
%load_ext autoreload
%autoreload 2
# Import basic things of Qiskit Metal
from qiskit_metal import MetalGUI, designs
from qiskit_metal.qlibrary.qubits.transmon_pocket_6 import TransmonPocket6
# Import the Gmsh renderer
from qiskit_metal.renderers.renderer_gmsh.gmsh_renderer import QGmshRenderer
# Import the Elmer renderer
from qiskit_metal.renderers.renderer_elmer.elmer_renderer import QElmerRenderer
from qiskit_metal.renderers.renderer_elmer.elmer_renderer import (
load_capacitance_matrix_from_file,
)
[ ]:
%metal_heading 1. Create a Transmon Qubit in Qiskit Metal
[ ]:
# Instantiate a design object
design = designs.MultiPlanar({}, True)
# Invoke the Qiskit Metal GUI
gui = MetalGUI(design)
[ ]:
# Define a dictionary for connection pad options for the transmon
conn_pads = dict(
connection_pads=dict(
readout=dict(loc_W=0, loc_H=-1),
coupler1=dict(loc_W=-1, loc_H=1),
coupler2=dict(loc_W=1, loc_H=1),
)
)
# Create a TransmonPocket6 object
q1 = TransmonPocket6(design, "Q1", options=dict(**conn_pads))
# Rebuild and autoscale the GUI
gui.rebuild()
gui.autoscale()
[ ]:
%metal_heading 2. Rendering and meshing your design in the `QGmshRenderer`
Rendering the design wireframe¶
[ ]:
# Instantiate the Gmsh renderer
gmsh_renderer = QGmshRenderer(design)
# Render the design
# Tip: `mesh_geoms = False` will not mesh the design,
# but only draw the wire-frame of the geomtries
gmsh_renderer.render_design(
open_pins=[("Q1", "coupler1"), ("Q1", "coupler2"), ("Q1", "readout")],
mesh_geoms=False,
)
[ ]:
# Launch Gmsh GUI to see the rendererd design
gmsh_renderer.launch_gui()
Applying a basic mesh¶
[ ]:
# Add a basic mesh to the design and luanch the GUI to view
gmsh_renderer.add_mesh(dim=3, intelli_mesh=False)
gmsh_renderer.launch_gui()
Customizing the mesh¶
Setting initial mesh size parameters¶
[ ]:
# Update the mesh options
gmsh_renderer.options.mesh.min_size = "5um"
gmsh_renderer.options.mesh.max_size = "20um"
# Render the design
gmsh_renderer.render_design(
open_pins=[("Q1", "coupler1"), ("Q1", "coupler2"), ("Q1", "readout")],
mesh_geoms=False,
)
# Mesh the design (without intelli-mesh)
gmsh_renderer.add_mesh(intelli_mesh=False)
gmsh_renderer.launch_gui()
Using the Intelli-mesh feature in QGmshRenderer¶
[ ]:
# Update the mesh options
gmsh_renderer.options.mesh.min_size = "5um"
gmsh_renderer.options.mesh.max_size = "50um"
# Render and mesh the design (with intelli-mesh)
gmsh_renderer.render_design(
open_pins=[("Q1", "coupler1"), ("Q1", "coupler2"), ("Q1", "readout")],
mesh_geoms=True,
)
gmsh_renderer.launch_gui()
Saving your mesh to a file¶
[ ]:
# Export the Gmsh generated mesh to a file
gmsh_renderer.export_mesh("test.msh")
[ ]:
# Close the Gmsh renderer
gmsh_renderer.close()
[ ]:
%metal_heading 3. Rendering your design in `QElmerRenderer` (uses `QGmshRenderer`)
[ ]:
# Instantiate the Elmer renderer
elmer_renderer = QElmerRenderer(design)
# Elmer renderer uses the Gmsh renderer to
# generate a mesh for the design
# Set initial parameters for meshing in Gmsh (IMPORTANT step!!)
elmer_renderer.gmsh.options.mesh.min_size = "5um"
elmer_renderer.gmsh.options.mesh.max_size = "50um"
[ ]:
# Render the design
elmer_renderer.render_design(
open_pins=[("Q1", "coupler1"), ("Q1", "coupler2"), ("Q1", "readout")],
skip_junctions=True,
)
[ ]:
# View the generated mesh
elmer_renderer.launch_gmsh_gui()
[ ]:
# Export the generated mesh
elmer_renderer.export_mesh()
[ ]:
# Add a solution setup to solve for the capacitance matrix
elmer_renderer.add_solution_setup("capacitance")
[ ]:
# Run the simulation in ElmerFEM
elmer_renderer.run("capacitance")
[ ]:
# Display the capacitnce matrix obtained after the simulation
elmer_renderer.capacitance_matrix
[ ]:
# Run this, and in the Gmsh window,
# Right click on an empty area, click on "Toggle mesh visibility"
# Next, go to: Tools -> Visibility, select "Physical groups" in drop down menu
# Select "Volume 2", click on apply
# On the left pane, click on "Post-processing", and select the views that you want to observe
elmer_renderer.display_post_processing_data()
[ ]:
# Export the capacitance matrix
elmer_renderer.save_capacitance_matrix("cap_matrix.txt")
# Close the elmer renderer
elmer_renderer.close()
[ ]:
%metal_heading 4. Perform LOM 2.0 Analysis
[ ]:
# Import necessary things for LOM 2.0 Analysis
import numpy as np
from qiskit_metal.analyses.quantization.lom_core_analysis import (
CompositeSystem,
Cell,
Subsystem,
)
from scipy.constants import speed_of_light as c_light
import matplotlib.pyplot as plt
%matplotlib inline
[ ]:
# Load the saved capacitance matrix
cap_matrix = load_capacitance_matrix_from_file("cap_matrix.txt")
[ ]:
# Define cells
opt1 = dict(
node_rename={
"Q1_coupler1_connector_pad": "coupler1",
"Q1_coupler2_connector_pad": "coupler2",
"Q1_readout_connector_pad": "readout",
},
cap_mat=cap_matrix,
ind_dict={("Q1_pad_top", "Q1_pad_bot"): 12}, # junction inductance in nH
jj_dict={("Q1_pad_top", "Q1_pad_bot"): "j1"},
cj_dict={("Q1_pad_top", "Q1_pad_bot"): 2}, # junction capacitance in fF
)
cell_1 = Cell(opt1)
[ ]:
# Define subsystems
# subsystem 1: Transmon
transmon = Subsystem(name="transmon1_sys", sys_type="TRANSMON", nodes=["j1"])
# subsystem 2: Coupler 1
q_opts = dict(
f_res=7.4, # resonator dressed frequency in GHz
Z0=50, # characteristic impedance in Ohm
vp=0.404314 * c_light, # phase velocity
)
coup1 = Subsystem(
name="coup1_sys", sys_type="TL_RESONATOR", nodes=["coupler1"], q_opts=q_opts
)
# subsystem 3: Coupler 2
q_opts = dict(
f_res=7.2, # resonator dressed frequency in GHz
Z0=50, # characteristic impedance in Ohm
vp=0.404314 * c_light, # phase velocity
)
coup2 = Subsystem(
name="coup2_sys", sys_type="TL_RESONATOR", nodes=["coupler2"], q_opts=q_opts
)
# subsystem 4: Readout
q_opts = dict(
f_res=7, # resonator dressed frequency in GHz
Z0=50, # characteristic impedance in Ohm
vp=0.404314 * c_light, # phase velocity
)
readout = Subsystem(
name="readout_sys", sys_type="TL_RESONATOR", nodes=["readout"], q_opts=q_opts
)
[ ]:
# Define the composite system
composite_sys = CompositeSystem(
subsystems=[transmon, coup1, coup2, readout],
cells=[cell_1],
grd_node="ground_plane",
nodes_force_keep=["coupler1", "coupler2", "readout"],
)
[ ]:
# Get the circuit graph object
cg = composite_sys.circuitGraph()
print(cg)
[ ]:
# Create a hilbert space with the composite system
hilbertspace = composite_sys.create_hilbertspace()
print(hilbertspace)
[ ]:
# Add interaction between the subsystems
hilbertspace = composite_sys.add_interaction()
# Get the total hamiltonian of the composite system
hilbertspace.hamiltonian()
[ ]:
# Get the reults from the hamiltonian
# Qubit frequency
# Chi matrix (having anharmonicity and readout chi values)
hamiltonian_results = composite_sys.hamiltonian_results(hilbertspace, evals_count=30)
[ ]:
chi_df = hamiltonian_results["chi_in_MHz"].to_dataframe()
print(
"Transmon frequency :", hamiltonian_results["fQ_in_Ghz"]["transmon1_sys"], "GHz"
)
print("Transmon Anharmonicity :", chi_df["transmon1_sys"]["transmon1_sys"], "MHz")
print("Readou chi :", chi_df["readout_sys"]["transmon1_sys"], "MHz")
[ ]:
# Get the coupling 'g' values between qubit and resonators
composite_sys.compute_gs().to_dataframe()
[ ]:
# Hamiltonian parameters for the transmon
transmon.h_params
[ ]:
# Close the Qiskit Metal GUI
gui.main_window.close()
[ ]:
For more information, review the Introduction to Quantum Computing and Quantum Hardware lectures below
|
Lecture Video | Lecture Notes | Lab |
|
Lecture Video | Lecture Notes | Lab |
|
Lecture Video | Lecture Notes | Lab |
|
Lecture Video | Lecture Notes | Lab |
|
Lecture Video | Lecture Notes | Lab |
|
Lecture Video | Lecture Notes | Lab |