{ "cells": [ { "cell_type": "markdown", "id": "075bd937-5d0c-4e29-8351-faa413a5f7d1", "metadata": {}, "source": [ "# 4.19 Analyse a Transmon Qubit using ElmerFEM\n", "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](https://github.com/Qiskit/qiskit-metal/blob/elmer_renderer/tutorials/4%20Analysis/B.%20Advanced%20-%20Direct%20use%20of%20the%20renderers/Gmsh-Elmer-install-instructions.md) The tutorial has the following steps:\n", "\n", "## Contents\n", "### 1. Creating a Transmon Qubit in Qiskit Metal\n", "### 2. Rendering and meshing your design in the `QGmshRenderer`\n", "- Rendering the design wireframe\n", "- Applying a basic mesh\n", "- Customizing the mesh\n", " - Setting initial mesh size parameters\n", " - Using the Intelli-mesh feature in `QGmshRenderer`\n", "- Saving your mesh to a file\n", "\n", "### 3. Rendering your design in `QElmerRenderer` (uses `QGmshRenderer`)\n", "- Render design and generate mesh\n", "- Export the mesh\n", "- Run the capacitance simulation\n", " - Add solution setup\n", " - Run the solver\n", " - Export capacitance matrix\n", "\n", "### 4. Perform LOM 2.0 Analysis\n", "- Import the capacitance matrix\n", "- Define cells and subsystems\n", "- Define the composite system\n", "- Compute the results:\n", " - Qubit Frequency ($f_Q$)\n", " - Anharmonicity ($\\alpha$)\n", " - Readout $\\chi$\n", " - Coupling $g$" ] }, { "cell_type": "markdown", "id": "cfbf8541", "metadata": {}, "source": [ "> 💡 **Using this tutorial without the Qt GUI**\n", "> \n", "> 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 matplotlib `Figure` you can display inline or save with `fig.savefig(...)`.\n", "> \n", "> See [1.4 Headless quick view](../1-Overview/1.4-Headless-quick-view-%28no-Qt-GUI%29.ipynb) for a complete runnable walkthrough and [`docs/headless-usage.rst`](../../../docs/headless-usage.rst) for the full reference." ] }, { "cell_type": "markdown", "id": "be3cbb43-2c24-4139-b690-1d56047a03c5", "metadata": {}, "source": [ "## Necessary Imports" ] }, { "cell_type": "code", "execution_count": null, "id": "28f8c32e-5341-49d6-b63f-0e16419b162c", "metadata": {}, "outputs": [], "source": [ "%load_ext autoreload\n", "%autoreload 2\n", "\n", "# Import basic things of Qiskit Metal\n", "from qiskit_metal import MetalGUI, designs\n", "from qiskit_metal.qlibrary.qubits.transmon_pocket_6 import TransmonPocket6\n", "\n", "# Import the Gmsh renderer\n", "from qiskit_metal.renderers.renderer_gmsh.gmsh_renderer import QGmshRenderer\n", "\n", "# Import the Elmer renderer\n", "from qiskit_metal.renderers.renderer_elmer.elmer_renderer import QElmerRenderer\n", "from qiskit_metal.renderers.renderer_elmer.elmer_renderer import (\n", " load_capacitance_matrix_from_file,\n", ")" ] }, { "cell_type": "code", "execution_count": null, "id": "a76242c0-3b42-4157-bbcb-a99b3c47937a", "metadata": {}, "outputs": [], "source": [ "%metal_heading 1. Create a Transmon Qubit in Qiskit Metal" ] }, { "cell_type": "code", "execution_count": null, "id": "31a7b793-64a5-44c6-9176-718f9b7c1c66", "metadata": {}, "outputs": [], "source": [ "# Instantiate a design object\n", "design = designs.MultiPlanar({}, True)\n", "\n", "# Invoke the Qiskit Metal GUI\n", "gui = MetalGUI(design)" ] }, { "cell_type": "code", "execution_count": null, "id": "6fe517d6-d32f-417c-a8fa-33061c2e54c6", "metadata": {}, "outputs": [], "source": [ "# Define a dictionary for connection pad options for the transmon\n", "conn_pads = dict(\n", " connection_pads=dict(\n", " readout=dict(loc_W=0, loc_H=-1),\n", " coupler1=dict(loc_W=-1, loc_H=1),\n", " coupler2=dict(loc_W=1, loc_H=1),\n", " )\n", ")\n", "\n", "# Create a TransmonPocket6 object\n", "q1 = TransmonPocket6(design, \"Q1\", options=dict(**conn_pads))\n", "\n", "# Rebuild and autoscale the GUI\n", "gui.rebuild()\n", "gui.autoscale()" ] }, { "cell_type": "code", "execution_count": null, "id": "d97e061c-fbcc-4419-a30c-8854b8c63444", "metadata": {}, "outputs": [], "source": [ "%metal_heading 2. Rendering and meshing your design in the `QGmshRenderer`" ] }, { "cell_type": "markdown", "id": "2f118489-71a8-494f-8c1b-b6cc837382c3", "metadata": {}, "source": [ "## Rendering the design wireframe" ] }, { "cell_type": "code", "execution_count": null, "id": "713202e1-dedc-469d-8dc3-9fe99496e42e", "metadata": {}, "outputs": [], "source": [ "# Instantiate the Gmsh renderer\n", "gmsh_renderer = QGmshRenderer(design)\n", "\n", "# Render the design\n", "# Tip: `mesh_geoms = False` will not mesh the design,\n", "# but only draw the wire-frame of the geomtries\n", "gmsh_renderer.render_design(\n", " open_pins=[(\"Q1\", \"coupler1\"), (\"Q1\", \"coupler2\"), (\"Q1\", \"readout\")],\n", " mesh_geoms=False,\n", ")" ] }, { "cell_type": "code", "execution_count": null, "id": "eef5a352-24f3-4257-968f-be197eeba30d", "metadata": {}, "outputs": [], "source": [ "# Launch Gmsh GUI to see the rendererd design\n", "gmsh_renderer.launch_gui()" ] }, { "cell_type": "markdown", "id": "cea57dd6-816f-4649-a77c-e9b774dcc153", "metadata": { "tags": [] }, "source": [ "## Applying a basic mesh" ] }, { "cell_type": "code", "execution_count": null, "id": "545d393c-8d57-4914-9dbc-92e8a0f32b0e", "metadata": { "scrolled": true, "tags": [] }, "outputs": [], "source": [ "# Add a basic mesh to the design and luanch the GUI to view\n", "gmsh_renderer.add_mesh(dim=3, intelli_mesh=False)\n", "gmsh_renderer.launch_gui()" ] }, { "cell_type": "markdown", "id": "6347235c-d319-4c61-a981-7e4005b25d15", "metadata": { "tags": [] }, "source": [ "## Customizing the mesh\n", "### Setting initial mesh size parameters" ] }, { "cell_type": "code", "execution_count": null, "id": "b851f19f-e8d0-479e-b0ae-056fa8a47e9f", "metadata": { "scrolled": true, "tags": [] }, "outputs": [], "source": [ "# Update the mesh options\n", "gmsh_renderer.options.mesh.min_size = \"5um\"\n", "gmsh_renderer.options.mesh.max_size = \"20um\"\n", "\n", "# Render the design\n", "gmsh_renderer.render_design(\n", " open_pins=[(\"Q1\", \"coupler1\"), (\"Q1\", \"coupler2\"), (\"Q1\", \"readout\")],\n", " mesh_geoms=False,\n", ")\n", "\n", "# Mesh the design (without intelli-mesh)\n", "gmsh_renderer.add_mesh(intelli_mesh=False)\n", "gmsh_renderer.launch_gui()" ] }, { "cell_type": "markdown", "id": "44bc0221-43d2-4551-b69d-4ab4f3f5b416", "metadata": { "tags": [] }, "source": [ "### Using the Intelli-mesh feature in QGmshRenderer" ] }, { "cell_type": "code", "execution_count": null, "id": "4b02fbf9-2717-45b8-9293-3bd1121862f9", "metadata": { "scrolled": true, "tags": [] }, "outputs": [], "source": [ "# Update the mesh options\n", "gmsh_renderer.options.mesh.min_size = \"5um\"\n", "gmsh_renderer.options.mesh.max_size = \"50um\"\n", "\n", "# Render and mesh the design (with intelli-mesh)\n", "gmsh_renderer.render_design(\n", " open_pins=[(\"Q1\", \"coupler1\"), (\"Q1\", \"coupler2\"), (\"Q1\", \"readout\")],\n", " mesh_geoms=True,\n", ")\n", "gmsh_renderer.launch_gui()" ] }, { "cell_type": "markdown", "id": "f441adcc-510f-4c8a-8516-1caf7dcb9166", "metadata": {}, "source": [ "## Saving your mesh to a file" ] }, { "cell_type": "code", "execution_count": null, "id": "af6556de-1546-47b5-8f26-9227af19ff86", "metadata": {}, "outputs": [], "source": [ "# Export the Gmsh generated mesh to a file\n", "gmsh_renderer.export_mesh(\"test.msh\")" ] }, { "cell_type": "code", "execution_count": null, "id": "3672846f-b035-4eab-80a9-3c199eb4fd7c", "metadata": {}, "outputs": [], "source": [ "# Close the Gmsh renderer\n", "gmsh_renderer.close()" ] }, { "cell_type": "code", "execution_count": null, "id": "88883f88-342e-449c-a1ce-c253a28c0145", "metadata": {}, "outputs": [], "source": [ "%metal_heading 3. Rendering your design in `QElmerRenderer` (uses `QGmshRenderer`)" ] }, { "cell_type": "code", "execution_count": null, "id": "8c2f7a6a-f6ed-4892-96c3-a62f866ef37c", "metadata": {}, "outputs": [], "source": [ "# Instantiate the Elmer renderer\n", "elmer_renderer = QElmerRenderer(design)\n", "\n", "# Elmer renderer uses the Gmsh renderer to\n", "# generate a mesh for the design\n", "# Set initial parameters for meshing in Gmsh (IMPORTANT step!!)\n", "elmer_renderer.gmsh.options.mesh.min_size = \"5um\"\n", "elmer_renderer.gmsh.options.mesh.max_size = \"50um\"" ] }, { "cell_type": "code", "execution_count": null, "id": "e7c297c2-be7e-495b-b98a-4062cab91be0", "metadata": { "scrolled": true, "tags": [] }, "outputs": [], "source": [ "# Render the design\n", "elmer_renderer.render_design(\n", " open_pins=[(\"Q1\", \"coupler1\"), (\"Q1\", \"coupler2\"), (\"Q1\", \"readout\")],\n", " skip_junctions=True,\n", ")" ] }, { "cell_type": "code", "execution_count": null, "id": "43145408-a90f-4e75-921d-ca8eafd5ea7e", "metadata": {}, "outputs": [], "source": [ "# View the generated mesh\n", "elmer_renderer.launch_gmsh_gui()" ] }, { "cell_type": "code", "execution_count": null, "id": "ab7e7c7a-9207-4943-bf0f-1d183a8d007c", "metadata": {}, "outputs": [], "source": [ "# Export the generated mesh\n", "elmer_renderer.export_mesh()" ] }, { "cell_type": "code", "execution_count": null, "id": "5cc8b22f-f281-45c3-a53a-f2a7c9a29fed", "metadata": {}, "outputs": [], "source": [ "# Add a solution setup to solve for the capacitance matrix\n", "elmer_renderer.add_solution_setup(\"capacitance\")" ] }, { "cell_type": "code", "execution_count": null, "id": "020dc57e-d668-4d7b-b8fc-62fcceb6468d", "metadata": {}, "outputs": [], "source": [ "# Run the simulation in ElmerFEM\n", "elmer_renderer.run(\"capacitance\")" ] }, { "cell_type": "code", "execution_count": null, "id": "b250b918-1cd7-429d-b015-92b114bf2594", "metadata": {}, "outputs": [], "source": [ "# Display the capacitnce matrix obtained after the simulation\n", "elmer_renderer.capacitance_matrix" ] }, { "cell_type": "code", "execution_count": null, "id": "07625769-38c4-4be7-9c64-9e4e7b993506", "metadata": {}, "outputs": [], "source": [ "# Run this, and in the Gmsh window,\n", "# Right click on an empty area, click on \"Toggle mesh visibility\"\n", "# Next, go to: Tools -> Visibility, select \"Physical groups\" in drop down menu\n", "# Select \"Volume 2\", click on apply\n", "# On the left pane, click on \"Post-processing\", and select the views that you want to observe\n", "elmer_renderer.display_post_processing_data()" ] }, { "cell_type": "code", "execution_count": null, "id": "ca5cf807-4323-48d8-b6cd-f5e38f3b24d3", "metadata": {}, "outputs": [], "source": [ "# Export the capacitance matrix\n", "elmer_renderer.save_capacitance_matrix(\"cap_matrix.txt\")\n", "\n", "# Close the elmer renderer\n", "elmer_renderer.close()" ] }, { "cell_type": "code", "execution_count": null, "id": "b20674ae-918f-4aa7-b4f7-1a337ae714a5", "metadata": {}, "outputs": [], "source": [ "%metal_heading 4. Perform LOM 2.0 Analysis" ] }, { "cell_type": "code", "execution_count": null, "id": "603f8d95-ac34-40e0-9574-53d0f6cde2b8", "metadata": {}, "outputs": [], "source": [ "# Import necessary things for LOM 2.0 Analysis\n", "import numpy as np\n", "from qiskit_metal.analyses.quantization.lom_core_analysis import (\n", " CompositeSystem,\n", " Cell,\n", " Subsystem,\n", ")\n", "from scipy.constants import speed_of_light as c_light\n", "import matplotlib.pyplot as plt\n", "\n", "%matplotlib inline" ] }, { "cell_type": "code", "execution_count": null, "id": "cf3df357-f1fe-4bd0-9510-02fd7e2a55bf", "metadata": {}, "outputs": [], "source": [ "# Load the saved capacitance matrix\n", "cap_matrix = load_capacitance_matrix_from_file(\"cap_matrix.txt\")" ] }, { "cell_type": "code", "execution_count": null, "id": "9705e531-ef68-4b6b-bbc6-6a8b69ba0a12", "metadata": {}, "outputs": [], "source": [ "# Define cells\n", "opt1 = dict(\n", " node_rename={\n", " \"Q1_coupler1_connector_pad\": \"coupler1\",\n", " \"Q1_coupler2_connector_pad\": \"coupler2\",\n", " \"Q1_readout_connector_pad\": \"readout\",\n", " },\n", " cap_mat=cap_matrix,\n", " ind_dict={(\"Q1_pad_top\", \"Q1_pad_bot\"): 12}, # junction inductance in nH\n", " jj_dict={(\"Q1_pad_top\", \"Q1_pad_bot\"): \"j1\"},\n", " cj_dict={(\"Q1_pad_top\", \"Q1_pad_bot\"): 2}, # junction capacitance in fF\n", ")\n", "cell_1 = Cell(opt1)" ] }, { "cell_type": "code", "execution_count": null, "id": "d5c8c296-13f9-4ec9-8daf-96f2f882b923", "metadata": {}, "outputs": [], "source": [ "# Define subsystems\n", "# subsystem 1: Transmon\n", "transmon = Subsystem(name=\"transmon1_sys\", sys_type=\"TRANSMON\", nodes=[\"j1\"])\n", "\n", "# subsystem 2: Coupler 1\n", "q_opts = dict(\n", " f_res=7.4, # resonator dressed frequency in GHz\n", " Z0=50, # characteristic impedance in Ohm\n", " vp=0.404314 * c_light, # phase velocity\n", ")\n", "coup1 = Subsystem(\n", " name=\"coup1_sys\", sys_type=\"TL_RESONATOR\", nodes=[\"coupler1\"], q_opts=q_opts\n", ")\n", "\n", "# subsystem 3: Coupler 2\n", "q_opts = dict(\n", " f_res=7.2, # resonator dressed frequency in GHz\n", " Z0=50, # characteristic impedance in Ohm\n", " vp=0.404314 * c_light, # phase velocity\n", ")\n", "coup2 = Subsystem(\n", " name=\"coup2_sys\", sys_type=\"TL_RESONATOR\", nodes=[\"coupler2\"], q_opts=q_opts\n", ")\n", "\n", "# subsystem 4: Readout\n", "q_opts = dict(\n", " f_res=7, # resonator dressed frequency in GHz\n", " Z0=50, # characteristic impedance in Ohm\n", " vp=0.404314 * c_light, # phase velocity\n", ")\n", "readout = Subsystem(\n", " name=\"readout_sys\", sys_type=\"TL_RESONATOR\", nodes=[\"readout\"], q_opts=q_opts\n", ")" ] }, { "cell_type": "code", "execution_count": null, "id": "4f44c894-aa2b-4632-b513-da391f101b93", "metadata": {}, "outputs": [], "source": [ "# Define the composite system\n", "composite_sys = CompositeSystem(\n", " subsystems=[transmon, coup1, coup2, readout],\n", " cells=[cell_1],\n", " grd_node=\"ground_plane\",\n", " nodes_force_keep=[\"coupler1\", \"coupler2\", \"readout\"],\n", ")" ] }, { "cell_type": "code", "execution_count": null, "id": "86f39d01-c88f-4300-987f-0384703daf61", "metadata": {}, "outputs": [], "source": [ "# Get the circuit graph object\n", "cg = composite_sys.circuitGraph()\n", "print(cg)" ] }, { "cell_type": "code", "execution_count": null, "id": "19fee4da-5659-4b3b-ad29-182565ee8933", "metadata": {}, "outputs": [], "source": [ "# Create a hilbert space with the composite system\n", "hilbertspace = composite_sys.create_hilbertspace()\n", "print(hilbertspace)" ] }, { "cell_type": "code", "execution_count": null, "id": "c18d596f-1778-4bf1-852c-6a3c7c8dc927", "metadata": {}, "outputs": [], "source": [ "# Add interaction between the subsystems\n", "hilbertspace = composite_sys.add_interaction()\n", "\n", "# Get the total hamiltonian of the composite system\n", "hilbertspace.hamiltonian()" ] }, { "cell_type": "code", "execution_count": null, "id": "b4c2cdfb-6ede-46eb-bbaf-c19f75b9a5d5", "metadata": {}, "outputs": [], "source": [ "# Get the reults from the hamiltonian\n", "# Qubit frequency\n", "# Chi matrix (having anharmonicity and readout chi values)\n", "hamiltonian_results = composite_sys.hamiltonian_results(hilbertspace, evals_count=30)" ] }, { "cell_type": "code", "execution_count": null, "id": "8c01e33b-c8fa-464a-bd02-fa8e87f48b5a", "metadata": {}, "outputs": [], "source": [ "chi_df = hamiltonian_results[\"chi_in_MHz\"].to_dataframe()\n", "print(\n", " \"Transmon frequency :\", hamiltonian_results[\"fQ_in_Ghz\"][\"transmon1_sys\"], \"GHz\"\n", ")\n", "print(\"Transmon Anharmonicity :\", chi_df[\"transmon1_sys\"][\"transmon1_sys\"], \"MHz\")\n", "print(\"Readou chi :\", chi_df[\"readout_sys\"][\"transmon1_sys\"], \"MHz\")" ] }, { "cell_type": "code", "execution_count": null, "id": "afdfe557-8d48-4a18-85bf-923aa2b63c07", "metadata": {}, "outputs": [], "source": [ "# Get the coupling 'g' values between qubit and resonators\n", "composite_sys.compute_gs().to_dataframe()" ] }, { "cell_type": "code", "execution_count": null, "id": "963212c4-b31f-48c0-ac56-0058e477b9e0", "metadata": {}, "outputs": [], "source": [ "# Hamiltonian parameters for the transmon\n", "transmon.h_params" ] }, { "cell_type": "code", "execution_count": null, "id": "44627014-50d7-4f5c-b873-c7c438d6c6da", "metadata": {}, "outputs": [], "source": [ "# Close the Qiskit Metal GUI\n", "gui.main_window.close()" ] }, { "cell_type": "code", "execution_count": null, "id": "9c3428fa-7009-451d-9032-a54ecf888791", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.6" } }, "nbformat": 4, "nbformat_minor": 5 }