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