Note
This page was generated from tut//4-Analysis//4.01-Capacitance-and-LOM.ipynb.
Capacitance matrix and LOM analysis#
Prerequisite#
You need to have a working local installation of Ansys.
1. Create the design in Metal#
[1]:
%reload_ext autoreload
%autoreload 2
[2]:
import qiskit_metal as metal
from qiskit_metal import designs, draw
from qiskit_metal import MetalGUI, Dict, Headings
[3]:
design = designs.DesignPlanar()
gui = MetalGUI(design)
from qiskit_metal.qlibrary.qubits.transmon_pocket import TransmonPocket
from qiskit_metal.qlibrary.tlines.meandered import RouteMeander
[4]:
design.variables['cpw_width'] = '15 um'
design.variables['cpw_gap'] = '9 um'
In this example, the design consists of 4 qubits and 4 CPWs#
[5]:
# Allow running the same cell here multiple times to overwrite changes
design.overwrite_enabled = True
## Custom options for all the transmons
options = dict(
# Some options we want to modify from the defaults
# (see below for defaults)
pad_width = '425 um',
pocket_height = '650um',
# Adding 4 connectors (see below for defaults)
connection_pads=dict(
readout = dict(loc_W=+1,loc_H=-1, pad_width='200um'),
bus1 = dict(loc_W=-1,loc_H=+1, pad_height='30um'),
bus2 = dict(loc_W=-1,loc_H=-1, pad_height='50um')
)
)
## Create 4 transmons
q1 = TransmonPocket(design, 'Q1', options = dict(
pos_x='+2.42251mm', pos_y='+0.0mm', **options))
q2 = TransmonPocket(design, 'Q2', options = dict(
pos_x='+0.0mm', pos_y='-0.95mm', orientation = '270', **options))
q3 = TransmonPocket(design, 'Q3', options = dict(
pos_x='-2.42251mm', pos_y='+0.0mm', orientation = '180', **options))
q4 = TransmonPocket(design, 'Q4', options = dict(
pos_x='+0.0mm', pos_y='+0.95mm', orientation = '90', **options))
RouteMeander.get_template_options(design)
options = Dict(
lead=Dict(
start_straight='0.2mm',
end_straight='0.2mm'),
trace_gap='9um',
trace_width='15um')
def connect(component_name: str, component1: str, pin1: str, component2: str, pin2: str,
length: str, asymmetry='0 um', flip=False, fillet='90um'):
"""Connect two pins with a CPW."""
myoptions = Dict(
fillet=fillet,
hfss_wire_bonds = True,
pin_inputs=Dict(
start_pin=Dict(
component=component1,
pin=pin1),
end_pin=Dict(
component=component2,
pin=pin2)),
total_length=length)
myoptions.update(options)
myoptions.meander.asymmetry = asymmetry
myoptions.meander.lead_direction_inverted = 'true' if flip else 'false'
return RouteMeander(design, component_name, myoptions)
asym = 140
cpw1 = connect('cpw1', 'Q1', 'bus2', 'Q2', 'bus1', '6.0 mm', f'+{asym}um')
cpw2 = connect('cpw2', 'Q3', 'bus1', 'Q2', 'bus2', '6.1 mm', f'-{asym}um', flip=True)
cpw3 = connect('cpw3', 'Q3', 'bus2', 'Q4', 'bus1', '6.0 mm', f'+{asym}um')
cpw4 = connect('cpw4', 'Q1', 'bus1', 'Q4', 'bus2', '6.1 mm', f'-{asym}um', flip=True)
gui.rebuild()
gui.autoscale()
[6]:
gui.screenshot()
2. Capacitance Analysis and LOM derivation using the analysis package - most users#
Capacitance Analysis#
Select the analysis you intend to run from the qiskit_metal.analyses
collection. Select the design to analyze and the tool to use for any external simulation
[7]:
from qiskit_metal.analyses.quantization import LOManalysis
c1 = LOManalysis(design, "q3d")
(optional) You can review and update the Analysis default setup following the examples in the next two cells.
[8]:
c1.sim.setup
[8]:
{'name': 'Setup',
'reuse_selected_design': True,
'freq_ghz': 5.0,
'save_fields': False,
'enabled': True,
'max_passes': 15,
'min_passes': 2,
'min_converged_passes': 2,
'percent_error': 0.5,
'percent_refinement': 30,
'auto_increase_solution_order': True,
'solution_order': 'High',
'solver_type': 'Iterative'}
[9]:
# example: update single setting
c1.sim.setup.max_passes = 6
# example: update multiple settings
c1.sim.setup_update(solution_order = 'Medium', auto_increase_solution_order = 'False')
c1.sim.setup
[9]:
{'name': 'Setup',
'reuse_selected_design': True,
'freq_ghz': 5.0,
'save_fields': False,
'enabled': True,
'max_passes': 6,
'min_passes': 2,
'min_converged_passes': 2,
'percent_error': 0.5,
'percent_refinement': 30,
'auto_increase_solution_order': 'False',
'solution_order': 'Medium',
'solver_type': 'Iterative'}
Analyze a single qubit with 2 endcaps using the default (or edited) analysis setup. Then show the capacitance matrix (from the last pass).
You can use the method run()
instead of sim.run()
in the following cell if you want to run both cap extraction and lom analysis in a single step. If so, make sure to also tweak the setup for the lom analysis. The input parameters are otherwise the same for the two methods.
[10]:
c1.sim.run(components=['Q1'], open_terminations=[('Q1', 'readout'), ('Q1', 'bus1'), ('Q1', 'bus2')])
c1.sim.capacitance_matrix
INFO 08:32AM [connect_project]: Connecting to Ansys Desktop API...
INFO 08:32AM [load_ansys_project]: Opened Ansys App
INFO 08:32AM [load_ansys_project]: Opened Ansys Desktop v2020.2.0
INFO 08:32AM [load_ansys_project]: Opened Ansys Project
Folder: C:/Ansoft/
Project: Project22
INFO 08:32AM [connect_design]: No active design found (or error getting active design).
INFO 08:32AM [connect]: Connected to project "Project22". No design detected
INFO 08:32AM [connect_design]: Opened active design
Design: Design_q3d [Solution type: Q3D]
WARNING 08:32AM [connect_setup]: No design setup detected.
WARNING 08:32AM [connect_setup]: Creating Q3D default setup.
INFO 08:32AM [get_setup]: Opened setup `Setup` (<class 'pyEPR.ansys.AnsysQ3DSetup'>)
INFO 08:32AM [get_setup]: Opened setup `Setup1` (<class 'pyEPR.ansys.AnsysQ3DSetup'>)
INFO 08:32AM [analyze]: Analyzing setup Setup1
INFO 08:33AM [get_matrix]: Exporting matrix data to (C:\Temp\tmp9kdob592.txt, C, , Setup1:LastAdaptive, "Original", "ohm", "nH", "fF", "mSie", 5000000000, Maxwell, 1, False
INFO 08:33AM [get_matrix]: Exporting matrix data to (C:\Temp\tmpsk8_aon5.txt, C, , Setup1:AdaptivePass, "Original", "ohm", "nH", "fF", "mSie", 5000000000, Maxwell, 1, False
INFO 08:33AM [get_matrix]: Exporting matrix data to (C:\Temp\tmp6zdkc4y0.txt, C, , Setup1:AdaptivePass, "Original", "ohm", "nH", "fF", "mSie", 5000000000, Maxwell, 2, False
INFO 08:33AM [get_matrix]: Exporting matrix data to (C:\Temp\tmp2hpfznmn.txt, C, , Setup1:AdaptivePass, "Original", "ohm", "nH", "fF", "mSie", 5000000000, Maxwell, 3, False
INFO 08:33AM [get_matrix]: Exporting matrix data to (C:\Temp\tmpj38u4y4a.txt, C, , Setup1:AdaptivePass, "Original", "ohm", "nH", "fF", "mSie", 5000000000, Maxwell, 4, False
INFO 08:33AM [get_matrix]: Exporting matrix data to (C:\Temp\tmpknqz7sw0.txt, C, , Setup1:AdaptivePass, "Original", "ohm", "nH", "fF", "mSie", 5000000000, Maxwell, 5, False
INFO 08:33AM [get_matrix]: Exporting matrix data to (C:\Temp\tmp9mj4v6i8.txt, C, , Setup1:AdaptivePass, "Original", "ohm", "nH", "fF", "mSie", 5000000000, Maxwell, 6, False
INFO 08:33AM [get_matrix]: Exporting matrix data to (C:\Temp\tmpj0mu6o1u.txt, C, , Setup1:AdaptivePass, "Original", "ohm", "nH", "fF", "mSie", 5000000000, Maxwell, 7, False
[10]:
bus1_connector_pad_Q1 | bus2_connector_pad_Q1 | ground_main_plane | pad_bot_Q1 | pad_top_Q1 | readout_connector_pad_Q1 | |
---|---|---|---|---|---|---|
bus1_connector_pad_Q1 | 49.77794 | -0.42560 | -33.50861 | -1.57029 | -13.15538 | -0.20494 |
bus2_connector_pad_Q1 | -0.42560 | 54.01885 | -35.77522 | -13.99741 | -1.82852 | -1.01319 |
ground_main_plane | -33.50861 | -35.77522 | 237.69029 | -31.53485 | -37.88741 | -36.55732 |
pad_bot_Q1 | -1.57029 | -13.99741 | -31.53485 | 98.20667 | -30.07382 | -18.86490 |
pad_top_Q1 | -13.15538 | -1.82852 | -37.88741 | -30.07382 | 87.85076 | -2.20122 |
readout_connector_pad_Q1 | -0.20494 | -1.01319 | -36.55732 | -18.86490 | -2.20122 | 59.92347 |
The last variables you pass to the run()
or sim.run()
methods, will be stored in the sim.setup
dictionary under the key run
. You can recall the information passed by either accessing the dictionary directly, or by using the print handle below.
[11]:
# c1.setup.run <- direct access
c1.print_run_args()
This analysis object run with the following kwargs:
{}
You can re-run the analysis after varying the parameters. Not passing the parameter components
to the sim.run()
method, skips the rendering and tries to run the analysis on the latest design. If a design is not found, the full metal design is rendered.
[12]:
c1.sim.setup.freq_ghz = 4.8
c1.sim.run()
c1.sim.capacitance_matrix
INFO 08:33AM [get_setup]: Opened setup `Setup2` (<class 'pyEPR.ansys.AnsysQ3DSetup'>)
INFO 08:33AM [analyze]: Analyzing setup Setup2
INFO 08:34AM [get_matrix]: Exporting matrix data to (C:\Temp\tmp2zqpsp70.txt, C, , Setup2:LastAdaptive, "Original", "ohm", "nH", "fF", "mSie", 4800000000, Maxwell, 1, False
INFO 08:34AM [get_matrix]: Exporting matrix data to (C:\Temp\tmp5r0te98b.txt, C, , Setup2:AdaptivePass, "Original", "ohm", "nH", "fF", "mSie", 4800000000, Maxwell, 1, False
INFO 08:34AM [get_matrix]: Exporting matrix data to (C:\Temp\tmpvakd3cxo.txt, C, , Setup2:AdaptivePass, "Original", "ohm", "nH", "fF", "mSie", 4800000000, Maxwell, 2, False
INFO 08:34AM [get_matrix]: Exporting matrix data to (C:\Temp\tmppo2b9z67.txt, C, , Setup2:AdaptivePass, "Original", "ohm", "nH", "fF", "mSie", 4800000000, Maxwell, 3, False
INFO 08:34AM [get_matrix]: Exporting matrix data to (C:\Temp\tmpskxpuv4a.txt, C, , Setup2:AdaptivePass, "Original", "ohm", "nH", "fF", "mSie", 4800000000, Maxwell, 4, False
INFO 08:34AM [get_matrix]: Exporting matrix data to (C:\Temp\tmprf7et9ty.txt, C, , Setup2:AdaptivePass, "Original", "ohm", "nH", "fF", "mSie", 4800000000, Maxwell, 5, False
INFO 08:34AM [get_matrix]: Exporting matrix data to (C:\Temp\tmpuooj6mi9.txt, C, , Setup2:AdaptivePass, "Original", "ohm", "nH", "fF", "mSie", 4800000000, Maxwell, 6, False
INFO 08:34AM [get_matrix]: Exporting matrix data to (C:\Temp\tmpm9a1sk65.txt, C, , Setup2:AdaptivePass, "Original", "ohm", "nH", "fF", "mSie", 4800000000, Maxwell, 7, False
[12]:
bus1_connector_pad_Q1 | bus2_connector_pad_Q1 | ground_main_plane | pad_bot_Q1 | pad_top_Q1 | readout_connector_pad_Q1 | |
---|---|---|---|---|---|---|
bus1_connector_pad_Q1 | 49.77794 | -0.42560 | -33.50861 | -1.57029 | -13.15538 | -0.20494 |
bus2_connector_pad_Q1 | -0.42560 | 54.01885 | -35.77522 | -13.99741 | -1.82852 | -1.01319 |
ground_main_plane | -33.50861 | -35.77522 | 237.69029 | -31.53485 | -37.88741 | -36.55732 |
pad_bot_Q1 | -1.57029 | -13.99741 | -31.53485 | 98.20667 | -30.07382 | -18.86490 |
pad_top_Q1 | -13.15538 | -1.82852 | -37.88741 | -30.07382 | 87.85076 | -2.20122 |
readout_connector_pad_Q1 | -0.20494 | -1.01319 | -36.55732 | -18.86490 | -2.20122 | 59.92347 |
[13]:
type(c1.sim.capacitance_matrix)
[13]:
pandas.core.frame.DataFrame
Lumped oscillator model (LOM)#
Using capacitance matrices obtained from each pass, save the many parameters of the Hamiltonian of the system. get_lumped_oscillator()
operates on 4 setup parameters: Lj: float Cj: float fr: Union[list, float] fb: Union[list, float]
[14]:
c1.setup.junctions = Dict({'Lj': 12.31, 'Cj': 2})
c1.setup.freq_readout = 7.0
c1.setup.freq_bus = [6.0, 6.2]
c1.run_lom()
c1.lumped_oscillator_all
[3, 4] [5 0 1]
Predicted Values
Transmon Properties
f_Q 5.424935 [GHz]
EC 311.976959 [MHz]
EJ 13.273404 [GHz]
alpha -363.792421 [MHz]
dispersion 46.550369 [KHz]
Lq 12.305036 [nH]
Cq 62.088650 [fF]
T1 35.336766 [us]
**Coupling Properties**
tCqbus1 7.383750 [fF]
gbus1_in_MHz 114.265793 [MHz]
χ_bus1 -3.174191 [MHz]
1/T1bus1 2809.277762 [Hz]
T1bus1 56.653331 [us]
tCqbus2 -6.455281 [fF]
gbus2_in_MHz -85.831803 [MHz]
χ_bus2 -9.970470 [MHz]
1/T1bus2 1205.469467 [Hz]
T1bus2 132.027353 [us]
tCqbus3 5.372192 [fF]
gbus3_in_MHz 73.765178 [MHz]
χ_bus3 -4.515417 [MHz]
1/T1bus3 489.200415 [Hz]
T1bus3 325.336893 [us]
Bus-Bus Couplings
gbus1_2 7.097123 [MHz]
gbus1_3 9.957495 [MHz]
gbus2_3 5.377146 [MHz]
[14]:
fQ | EC | EJ | alpha | dispersion | gbus | chi_in_MHz | χr MHz | gr MHz | |
---|---|---|---|---|---|---|---|---|---|
1 | 5.748104 | 353.230672 | 13.273404 | -417.375147 | 135.208268 | [108.79200978040816, -73.21708181328188, 76.45... | [-4.790610087146514, -26.5770698752867, -12.45... | 4.790610 | 108.792010 |
2 | 5.664672 | 342.295447 | 13.273404 | -403.045739 | 103.898327 | [112.48401834623373, -82.16156406673579, 68.80... | [-4.4594265208402275, -22.018835553935766, -7.... | 4.459427 | 112.484018 |
3 | 5.574019 | 330.639537 | 13.273404 | -387.872732 | 77.330688 | [111.33612864790418, -84.09226785308748, 71.77... | [-3.7804661114555205, -15.865600375824991, -6.... | 3.780466 | 111.336129 |
4 | 5.523032 | 324.186357 | 13.273404 | -379.516629 | 65.212167 | [110.99790102064628, -84.10822360591214, 72.87... | [-3.4720716615303537, -13.185856349486748, -5.... | 3.472072 | 110.997901 |
5 | 5.463772 | 316.778339 | 13.273404 | -369.962716 | 53.275261 | [113.07905190117796, -84.87724687606234, 72.79... | [-3.293717894242756, -11.011779798984726, -4.8... | 3.293718 | 113.079052 |
6 | 5.424935 | 311.976959 | 13.273404 | -363.792421 | 46.550369 | [114.26579286281127, -85.83180315154853, 73.76... | [-3.1741912468040616, -9.970469520050226, -4.5... | 3.174191 | 114.265793 |
[15]:
c1.plot_convergence();
c1.plot_convergence_chi()
Design "Design_q3d" info:
# eigenmodes 0
# variations 1
INFO 08:34AM [hfss_report_full_convergence]: Creating report for variation 0
Once you are done with your analysis, please close it with close()
. This will free up resources currently occupied by qiskit-metal to communiate with the tool.
[16]:
c1.sim.close()
3. Directly access the renderer to modify other parameters#
[17]:
c1.sim.start()
c1.sim.renderer
INFO 08:34AM [connect_project]: Connecting to Ansys Desktop API...
INFO 08:34AM [load_ansys_project]: Opened Ansys App
INFO 08:34AM [load_ansys_project]: Opened Ansys Desktop v2020.2.0
INFO 08:34AM [load_ansys_project]: Opened Ansys Project
Folder: C:/Ansoft/
Project: Project22
INFO 08:34AM [connect_design]: Opened active design
Design: Design_q3d [Solution type: Q3D]
INFO 08:34AM [get_setup]: Opened setup `Setup` (<class 'pyEPR.ansys.AnsysQ3DSetup'>)
INFO 08:34AM [connect]: Connected to project "Project22" and design "Design_q3d" 😀
[17]:
<qiskit_metal.renderers.renderer_ansys.q3d_renderer.QQ3DRenderer at 0x268898f7fc8>
Every renderer will have its own collection of methods. Below an example with q3d
Prepare and run a collection of predefined setups#
This is equivalent to going to the Project Manager panel in Ansys, right clicking on Analysis within the active Q3D design, selecting “Add Solution Setup…”, and choosing/entering default values in the resulting popup window. You might want to do this to keep track of different solution setups, giving each of them a different/specific name.
[18]:
setup = c1.sim.renderer.new_ansys_setup(name = "Setup_demo", max_passes = 6)
You can directly pass to new_ansys_setup
all the setup parameters. Of course you will then need to run the individual setups by name as well.
[19]:
c1.sim.renderer.analyze_setup(setup.name)
INFO 08:34AM [get_setup]: Opened setup `Setup_demo` (<class 'pyEPR.ansys.AnsysQ3DSetup'>)
INFO 08:34AM [analyze]: Analyzing setup Setup_demo
Get the capactiance matrix at a different pass#
You might want to use this if you intend to know what was the matrix at a different pass of the simulation.
[20]:
# Using the analysis results, get its capacitance matrix as a dataframe.
c1.sim.renderer.get_capacitance_matrix(variation = '', solution_kind = 'AdaptivePass', pass_number = 5)
INFO 08:34AM [get_matrix]: Exporting matrix data to (C:\Temp\tmp3caa8vjk.txt, C, , Setup_demo:AdaptivePass, "Original", "ohm", "nH", "fF", "mSie", 5000000000, Maxwell, 5, False
[20]:
( bus1_connector_pad_Q1 bus2_connector_pad_Q1 \
bus1_connector_pad_Q1 48.92803 -0.42235
bus2_connector_pad_Q1 -0.42235 53.06961
ground_main_plane -33.01607 -35.14374
pad_bot_Q1 -1.53861 -13.67515
pad_top_Q1 -12.84517 -1.81368
readout_connector_pad_Q1 -0.20677 -0.99928
ground_main_plane pad_bot_Q1 pad_top_Q1 \
bus1_connector_pad_Q1 -33.01607 -1.53861 -12.84517
bus2_connector_pad_Q1 -35.14374 -13.67515 -1.81368
ground_main_plane 234.01567 -31.50558 -37.64437
pad_bot_Q1 -31.50558 96.95568 -29.44070
pad_top_Q1 -37.64437 -29.44070 86.62922
readout_connector_pad_Q1 -36.15710 -18.48102 -2.19686
readout_connector_pad_Q1
bus1_connector_pad_Q1 -0.20677
bus2_connector_pad_Q1 -0.99928
ground_main_plane -36.15710
pad_bot_Q1 -18.48102
pad_top_Q1 -2.19686
readout_connector_pad_Q1 59.14496 ,
'fF')
Code to swap rows and columns in capacitance matrix#
from qiskit_metal.analyses.quantization.lumped_capacitive import df_reorder_matrix_basis
df_reorder_matrix_basis(fourq_q3d.get_capacitance_matrix(), 1, 2)
[22]:
c1.sim.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 |