{ "cells": [ { "cell_type": "markdown", "id": "35d27b44", "metadata": {}, "source": [ "# 4.16 S21 simulation of a resonator\n", "\n", "Authors: Sara Buhktari, Christian Kraglund Andersen\n" ] }, { "cell_type": "markdown", "id": "37f48909", "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": "code", "execution_count": null, "id": "0b0da17a", "metadata": {}, "outputs": [], "source": [ "# Import useful packages\n", "import qiskit_metal as metal\n", "from qiskit_metal import designs, draw\n", "from qiskit_metal import MetalGUI, Dict, open_docs\n", "from qiskit_metal.toolbox_metal import math_and_overrides\n", "from qiskit_metal.qlibrary.core import QComponent\n", "from collections import OrderedDict\n", "\n", "# To create plots after geting solution data.\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "\n", "# Packages for the simple design\n", "from qiskit_metal.qlibrary.tlines.meandered import RouteMeander\n", "from qiskit_metal.qlibrary.tlines.pathfinder import RoutePathfinder\n", "from qiskit_metal.qlibrary.terminations.launchpad_wb_driven import (\n", " LaunchpadWirebondDriven,\n", ")\n", "from qiskit_metal.qlibrary.terminations.open_to_ground import OpenToGround\n", "from qiskit_metal.qlibrary.terminations.short_to_ground import ShortToGround\n", "\n", "# Analysis\n", "# from qiskit_metal.renderers.renderer_gds.gds_renderer import QGDSRenderer\n", "# from qiskit_metal.analyses.quantization import EPRanalysis\n", "from qiskit_metal.analyses.quantization import EPRanalysis\n", "from qiskit_metal.analyses.simulation import ScatteringImpedanceSim\n", "from qiskit_metal.analyses.sweep_and_optimize.sweeping import Sweeping\n", "import pyEPR as epr" ] }, { "cell_type": "markdown", "id": "c6e244f8", "metadata": {}, "source": [ "## Set up the design" ] }, { "cell_type": "code", "execution_count": null, "id": "3983eac9", "metadata": {}, "outputs": [], "source": [ "# Set up chip dimensions\n", "design = designs.DesignPlanar()\n", "design._chips[\"main\"][\"size\"][\"size_x\"] = \"9mm\"\n", "design._chips[\"main\"][\"size\"][\"size_y\"] = \"9mm\"\n", "\n", "# Resonator and feedline gap width (W) and center conductor width (S) from reference 2\n", "design.variables[\"cpw_width\"] = \"15 um\" # S from reference 2\n", "design.variables[\"cpw_gap\"] = \"9 um\" # W from reference 2\n", "\n", "\n", "design.overwrite_enabled = True\n", "\n", "hfss = design.renderers.hfss\n", "\n", "# Open GUI\n", "gui = MetalGUI(design)" ] }, { "cell_type": "code", "execution_count": null, "id": "cc2c100f", "metadata": {}, "outputs": [], "source": [ "# Define for renderer\n", "eig_qres = EPRanalysis(design, \"hfss\")\n", "hfss = design.renderers.hfss\n", "hfss = eig_qres.sim.renderer\n", "q3d = design.renderers.q3d" ] }, { "cell_type": "markdown", "id": "055c0bef", "metadata": {}, "source": [ "## Define the geometry\n", "\n", "Here we will have a single feedline couple to a single CPW resonator.\n", "\n", "The lauchpad should be included in the driven model simulations.\n", "\n", "For that reason, we use the LaunchpadWirebondDriven component which has an extra pin for input/output" ] }, { "cell_type": "code", "execution_count": null, "id": "ef570ed8", "metadata": {}, "outputs": [], "source": [ "###################\n", "# Single feedline #\n", "###################\n", "\n", "# Driven Lauchpad 1\n", "x = \"-1.5mm\"\n", "y = \"2.0mm\"\n", "launch_options = dict(\n", " chip=\"main\", pos_x=x, pos_y=y, orientation=\"360\", lead_length=\"30um\"\n", ")\n", "LP1 = LaunchpadWirebondDriven(design, \"LP1\", options=launch_options)\n", "\n", "# Driven Launchpad 2\n", "x = \"1.5mm\"\n", "y = \"2.0mm\"\n", "launch_options = dict(\n", " chip=\"main\", pos_x=x, pos_y=y, orientation=\"180\", lead_length=\"30um\"\n", ")\n", "LP2 = LaunchpadWirebondDriven(design, \"LP2\", options=launch_options)\n", "\n", "# Using path finder to connect the two launchpads\n", "TL_LP1_LP2 = RoutePathfinder(\n", " design,\n", " \"TL_LP1_LP2\",\n", " options=dict(\n", " chip=\"main\",\n", " trace_width=\"15um\",\n", " trace_gap=\"9um\",\n", " fillet=\"99um\",\n", " hfss_wire_bonds=True,\n", " lead=dict(end_straight=\"1.972mm\"),\n", " pin_inputs=Dict(\n", " start_pin=Dict(component=\"LP1\", pin=\"tie\"),\n", " end_pin=Dict(component=\"LP2\", pin=\"tie\"),\n", " ),\n", " ),\n", ")\n", "\n", "\n", "# Rebuild the GUI\n", "gui.rebuild()" ] }, { "cell_type": "code", "execution_count": null, "id": "92b1570a", "metadata": {}, "outputs": [], "source": [ "######################\n", "# lambda/2 resonator #\n", "######################\n", "\n", "# First we define the two end-points\n", "otg1 = OpenToGround(\n", " design,\n", " \"otg1s\",\n", " options=dict(chip=\"main\", pos_x=\"-0.3mm\", pos_y=\"1.968mm\", orientation=\"180\"),\n", ")\n", "otg2 = OpenToGround(\n", " design,\n", " \"otg1e\",\n", " options=dict(chip=\"main\", pos_x=\"0.0mm\", pos_y=\"0.0mm\", orientation=\"270\"),\n", ")\n", "\n", "# Use RouteMeander to fix the total length of the resonator\n", "rt_meander = RouteMeander(\n", " design,\n", " \"meander\",\n", " Dict(\n", " trace_width=\"12um\",\n", " trace_gap=\"5um\",\n", " total_length=\"8.0mm\",\n", " hfss_wire_bonds=True,\n", " fillet=\"99 um\",\n", " lead=dict(start_straight=\"250um\"),\n", " pin_inputs=Dict(\n", " start_pin=Dict(component=\"otg1s\", pin=\"open\"),\n", " end_pin=Dict(component=\"otg1e\", pin=\"open\"),\n", " ),\n", " ),\n", ")\n", "\n", "# rebuild the GUI\n", "gui.rebuild()" ] }, { "cell_type": "code", "execution_count": null, "id": "9956dd38", "metadata": {}, "outputs": [], "source": [ "gui.autoscale()\n", "gui.screenshot()" ] }, { "cell_type": "markdown", "id": "8bd2910a", "metadata": {}, "source": [ "## Scattering Analysis" ] }, { "cell_type": "code", "execution_count": null, "id": "be209d2e", "metadata": {}, "outputs": [], "source": [ "from qiskit_metal.analyses.simulation import ScatteringImpedanceSim\n", "\n", "em1 = ScatteringImpedanceSim(design, \"hfss\")" ] }, { "cell_type": "code", "execution_count": null, "id": "504994dd", "metadata": {}, "outputs": [], "source": [ "design_name = \"Sweep_DrivenModal\"\n", "qcomp_render = [] # Means to render everything in qgeometry table.\n", "open_terminations = []\n", "\n", "# Here, pin LP1_in and LP2_in are converted into lumped ports,\n", "# each with an impedance of 50 Ohms.
\n", "port_list = [(\"LP1\", \"in\", 50), (\"LP2\", \"in\", 50)]\n", "box_plus_buffer = True" ] }, { "cell_type": "code", "execution_count": null, "id": "be7762a9", "metadata": {}, "outputs": [], "source": [ "# we use HFSS as rendere\n", "hfss = em1.renderer\n", "hfss.start()" ] }, { "cell_type": "code", "execution_count": null, "id": "6bd25114", "metadata": {}, "outputs": [], "source": [ "# Here we activate the design for a drivenmodal solution\n", "hfss.activate_ansys_design(\"HangingResonator\", \"drivenmodal\")\n", "setup_args = Dict(max_delta_s=0.001)\n", "setup_args.name = \"Setup\"\n", "hfss.edit_drivenmodal_setup(setup_args)" ] }, { "cell_type": "code", "execution_count": null, "id": "5c8fc60c", "metadata": {}, "outputs": [], "source": [ "# set buffer\n", "hfss.options[\"x_buffer_width_mm\"] = 0.1\n", "hfss.options[\"y_buffer_width_mm\"] = 0.1" ] }, { "cell_type": "code", "execution_count": null, "id": "522ca07a", "metadata": {}, "outputs": [], "source": [ "# clean the design if needed\n", "hfss.clean_active_design()" ] }, { "cell_type": "code", "execution_count": null, "id": "d685f9fc", "metadata": {}, "outputs": [], "source": [ "# render the design\n", "hfss.render_design(\n", " selection=[],\n", " open_pins=open_terminations,\n", " port_list=port_list,\n", " box_plus_buffer=box_plus_buffer,\n", ")" ] }, { "cell_type": "code", "execution_count": null, "id": "8a316652", "metadata": {}, "outputs": [], "source": [ "# for acurate simulations, make sure the mesh is fine enough for the meander\n", "hfss.modeler.mesh_length(\"cpw_mesh\", [\"trace_meander\"], MaxLength=\"0.01mm\")" ] }, { "cell_type": "markdown", "id": "9ad348ed", "metadata": {}, "source": [ "## Broad sweet to find the resonance" ] }, { "cell_type": "code", "execution_count": null, "id": "e65e1ab2", "metadata": {}, "outputs": [], "source": [ "hfss.add_sweep(\n", " setup_name=\"Setup\",\n", " name=\"Sweep\",\n", " start_ghz=4.0,\n", " stop_ghz=8.0,\n", " count=2001,\n", " type=\"Interpolating\",\n", ")" ] }, { "cell_type": "code", "execution_count": null, "id": "bdeac158", "metadata": {}, "outputs": [], "source": [ "hfss.analyze_sweep(\"Sweep\", \"Setup\")" ] }, { "cell_type": "code", "execution_count": null, "id": "522904f7", "metadata": {}, "outputs": [], "source": [ "hfss.plot_params([\"S11\", \"S21\"])" ] }, { "cell_type": "code", "execution_count": null, "id": "c1f26b38", "metadata": {}, "outputs": [], "source": [ "# extract the S21 parameters\n", "freqs, Pcurves, Pparams = hfss.get_params([\"S21\"])" ] }, { "cell_type": "code", "execution_count": null, "id": "1c71579a", "metadata": {}, "outputs": [], "source": [ "# find armin\n", "f_res = freqs[np.argmin(np.abs(Pparams.S21.values))]\n", "f_res" ] }, { "cell_type": "markdown", "id": "43df3d00", "metadata": {}, "source": [ "## Narrow sweep around the resonance found above" ] }, { "cell_type": "code", "execution_count": null, "id": "50ddb791", "metadata": {}, "outputs": [], "source": [ "# fine sweep\n", "hfss.add_sweep(\n", " setup_name=\"Setup\",\n", " name=\"Sweep_narrow\",\n", " start_ghz=np.round(f_res / 1e9, 3) - 0.01,\n", " stop_ghz=np.round(f_res / 1e9, 3) + 0.01,\n", " count=1001,\n", " type=\"Fast\",\n", ") # slow but precise" ] }, { "cell_type": "code", "execution_count": null, "id": "ffea4175", "metadata": {}, "outputs": [], "source": [ "hfss.analyze_sweep(\"Sweep_narrow\", \"Setup\")" ] }, { "cell_type": "code", "execution_count": null, "id": "f06626b4", "metadata": {}, "outputs": [], "source": [ "hfss.plot_params([\"S11\", \"S21\"])" ] }, { "cell_type": "code", "execution_count": null, "id": "743b8dcf", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "id": "c72f2f6d", "metadata": {}, "source": [ "## Close connections" ] }, { "cell_type": "code", "execution_count": null, "id": "80694931", "metadata": {}, "outputs": [], "source": [ "em1.close()" ] }, { "cell_type": "code", "execution_count": null, "id": "13927800", "metadata": {}, "outputs": [], "source": [ "hfss.disconnect_ansys()" ] }, { "cell_type": "code", "execution_count": null, "id": "dc2621b9", "metadata": {}, "outputs": [], "source": [ "gui.main_window.close()" ] }, { "cell_type": "code", "execution_count": null, "id": "6d7375c2", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "id": "81863bcc", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python [conda env:metal]", "language": "python", "name": "conda-env-metal-py" }, "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.7.8" }, "latex_envs": { "LaTeX_envs_menu_present": true, "autoclose": false, "autocomplete": true, "bibliofile": "biblio.bib", "cite_by": "apalike", "current_citInitial": 1, "eqLabelWithNumbers": true, "eqNumInitial": 1, "hotkeys": { "equation": "Ctrl-E", "itemize": "Ctrl-I" }, "labels_anchors": false, "latex_user_defs": false, "report_style_numbering": false, "user_envs_cfg": false }, "toc": { "base_numbering": 1, "nav_menu": {}, "number_sections": true, "sideBar": true, "skip_h1_title": false, "title_cell": "Table of Contents", "title_sidebar": "Contents", "toc_cell": false, "toc_position": {}, "toc_section_display": true, "toc_window_display": false } }, "nbformat": 4, "nbformat_minor": 5 }