🧹 Sweeping over a paramter range in HFSS with pyEPR
Analyzing the cavity is nice and all, but it very likely that you’ll want to modify and optimize the cavity and it’s properties for your needs. For this you can simulate many different possibilities and choose the best paramters for you.
Let’s say, for example, you want the coupling between the readout resonator and transmon would be around $1$ MHz, what should be the distance between them? Let’s check!
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import pyEPR as epr
plt.style.use('ggplot')
plt.style.use('seaborn-darkgrid')
🔹 Connecting to HFSS
pinfo = epr.Project_Info(project_path = '.',
project_name = 'transmon-cavity-ro', # File name
design_name = 'design')
INFO 10:58PM [connect]: Connecting to Ansys Desktop API...
INFO 10:58PM [load_ansys_project]: File path to HFSS project found.
INFO 10:58PM [load_ansys_project]: Opened Ansys App
INFO 10:58PM [load_ansys_project]: Opened Ansys Desktop v2020.1.0
INFO 10:58PM [load_ansys_project]: Opened Ansys Project
Folder: C:/Users/rosengrp/Downloads/sweep-ro/
Project: transmon-cavity-ro
INFO 10:58PM [connect]: Opened active design
Design: design [Solution type: Eigenmode]
INFO 10:58PM [get_setup]: Opened setup `Setup1` (<class 'pyEPR.ansys.HfssEMSetup'>)
INFO 10:58PM [connect]: Connection to Ansys established successfully. 😀
🧹 Sweep over the parameter
The parameter defining the distance between the transmon and readout is ro_gap
, let’s see what’s it’s value in the design
ro_gap = pinfo.design.get_variable_value('ro_gap')
ro_gap
'2mm'
Let’s sweep then between $0.5$mm and $3$mm and see which is the best value
swp_var = 'ro_gap' # Sweep ove 'ro_gap'
def to_swp_val(x): return f'{x}mm'
for swp_param in np.linspace(0.5, 3, 6):
swp_val = to_swp_val(swp_param)
epr.logger.info(f'Setting sweep variable {swp_var}={swp_val}')
pinfo.design.set_variable(swp_var, swp_val)
pinfo.setup.analyze()
INFO 10:58PM [<module>]: Setting sweep variable ro_gap=0.5mm
INFO 10:58PM [analyze]: Analyzing setup Setup1
INFO 11:00PM [<module>]: Setting sweep variable ro_gap=1.0mm
INFO 11:00PM [analyze]: Analyzing setup Setup1
INFO 11:01PM [<module>]: Setting sweep variable ro_gap=1.5mm
INFO 11:01PM [analyze]: Analyzing setup Setup1
INFO 11:02PM [<module>]: Setting sweep variable ro_gap=2.0mm
INFO 11:02PM [analyze]: Analyzing setup Setup1
INFO 11:02PM [<module>]: Setting sweep variable ro_gap=2.5mm
INFO 11:02PM [analyze]: Analyzing setup Setup1
INFO 11:04PM [<module>]: Setting sweep variable ro_gap=3.0mm
INFO 11:04PM [analyze]: Analyzing setup Setup1
🔹 Define the junction (and any other non-linear component)
pinfo.junctions['j1'] = {'Lj_variable' : 'Lj_1',
'rect' : 'rect_jj1',
'line' : 'line_jj1',
'length' : epr.parse_units('100um')}
# Check that valid names of variables and objects have been supplied.
# An error is raised with a message if something is wrong.
pinfo.validate_junction_info()
🔹 Distributed Analysis (not quantum)
Note that 3 modes is the maximum we can analyze fully❗ See this issue
Also, now when we do the EPR analysis we can see that there are 6 variations, one for each value of the parameter we check
eprh = epr.DistributedAnalysis(pinfo)
eprh.do_EPR_analysis(modes=[0,1,4]);
Design "design" info:
# eigenmodes 5
# variations 6
Variation 0 [1/6]
[1mMode 0 at 4.57 GHz [1/5][0m
Calculating ℰ_magnetic,ℰ_electric
(ℰ_E-ℰ_H)/ℰ_E ℰ_E ℰ_H
97.4% 1.776e-24 4.61e-26
Calculating junction energy participation ration (EPR)
method=`line_voltage`. First estimates:
junction EPR p_0j sign s_0j (p_capacitive)
Energy fraction (Lj over Lj&Cj)= 98.70%
j1 0.972288 (+) 0.0128067
(U_tot_cap-U_tot_ind)/mean=0.72%
[1mMode 1 at 4.85 GHz [2/5][0m
Calculating ℰ_magnetic,ℰ_electric
(ℰ_E-ℰ_H)/ℰ_E ℰ_E ℰ_H
0.1% 9.56e-21 9.554e-21
Calculating junction energy participation ration (EPR)
method=`line_voltage`. First estimates:
junction EPR p_1j sign s_1j (p_capacitive)
Energy fraction (Lj over Lj&Cj)= 98.54%
j1 0.000159513 (+) 2.36977e-06
(U_tot_cap-U_tot_ind)/mean=0.02%
[1mMode 4 at 7.62 GHz [5/5][0m
Calculating ℰ_magnetic,ℰ_electric
(ℰ_E-ℰ_H)/ℰ_E ℰ_E ℰ_H
2.0% 3.223e-22 3.159e-22
Calculating junction energy participation ration (EPR)
method=`line_voltage`. First estimates:
junction EPR p_4j sign s_4j (p_capacitive)
Energy fraction (Lj over Lj&Cj)= 96.46%
j1 0.00097423 (+) 3.57338e-05
(U_tot_cap-U_tot_ind)/mean=0.95%
Variation 1 [2/6]
[1mMode 0 at 4.51 GHz [1/5][0m
Calculating ℰ_magnetic,ℰ_electric
(ℰ_E-ℰ_H)/ℰ_E ℰ_E ℰ_H
96.6% 1.298e-24 4.413e-26
Calculating junction energy participation ration (EPR)
method=`line_voltage`. First estimates:
junction EPR p_0j sign s_0j (p_capacitive)
Energy fraction (Lj over Lj&Cj)= 98.73%
j1 0.963758 (+) 0.0123721
(U_tot_cap-U_tot_ind)/mean=0.73%
[1mMode 1 at 4.85 GHz [2/5][0m
Calculating ℰ_magnetic,ℰ_electric
(ℰ_E-ℰ_H)/ℰ_E ℰ_E ℰ_H
0.1% 5.605e-21 5.602e-21
Calculating junction energy participation ration (EPR)
method=`line_voltage`. First estimates:
junction EPR p_1j sign s_1j (p_capacitive)
Energy fraction (Lj over Lj&Cj)= 98.54%
j1 0.000192748 (+) 2.8636e-06
(U_tot_cap-U_tot_ind)/mean=0.02%
[1mMode 4 at 7.61 GHz [5/5][0m
Calculating ℰ_magnetic,ℰ_electric
(ℰ_E-ℰ_H)/ℰ_E ℰ_E ℰ_H
2.9% 5.051e-23 4.907e-23
Calculating junction energy participation ration (EPR)
method=`line_voltage`. First estimates:
junction EPR p_4j sign s_4j (p_capacitive)
Energy fraction (Lj over Lj&Cj)= 96.47%
j1 0.00849854 (+) 0.000311068
(U_tot_cap-U_tot_ind)/mean=1.03%
Variation 2 [3/6]
[1mMode 0 at 4.58 GHz [1/5][0m
Calculating ℰ_magnetic,ℰ_electric
(ℰ_E-ℰ_H)/ℰ_E ℰ_E ℰ_H
97.1% 4.169e-24 1.21e-25
Calculating junction energy participation ration (EPR)
method=`line_voltage`. First estimates:
junction EPR p_0j sign s_0j (p_capacitive)
Energy fraction (Lj over Lj&Cj)= 98.69%
j1 0.968802 (+) 0.0128262
(U_tot_cap-U_tot_ind)/mean=0.75%
[1mMode 1 at 4.85 GHz [2/5][0m
Calculating ℰ_magnetic,ℰ_electric
(ℰ_E-ℰ_H)/ℰ_E ℰ_E ℰ_H
0.1% 2.031e-20 2.03e-20
Calculating junction energy participation ration (EPR)
method=`line_voltage`. First estimates:
junction EPR p_1j sign s_1j (p_capacitive)
Energy fraction (Lj over Lj&Cj)= 98.54%
j1 0.000177361 (+) 2.63501e-06
(U_tot_cap-U_tot_ind)/mean=0.02%
[1mMode 4 at 7.62 GHz [5/5][0m
Calculating ℰ_magnetic,ℰ_electric
(ℰ_E-ℰ_H)/ℰ_E ℰ_E ℰ_H
2.5% 2.581e-22 2.517e-22
Calculating junction energy participation ration (EPR)
method=`line_voltage`. First estimates:
junction EPR p_4j sign s_4j (p_capacitive)
Energy fraction (Lj over Lj&Cj)= 96.47%
j1 0.00397624 (+) 0.000145655
(U_tot_cap-U_tot_ind)/mean=1.07%
Variation 3 [4/6]
[1mMode 0 at 4.57 GHz [1/5][0m
Calculating ℰ_magnetic,ℰ_electric
(ℰ_E-ℰ_H)/ℰ_E ℰ_E ℰ_H
97.3% 3.277e-24 8.999e-26
Calculating junction energy participation ration (EPR)
method=`line_voltage`. First estimates:
junction EPR p_0j sign s_0j (p_capacitive)
Energy fraction (Lj over Lj&Cj)= 98.70%
j1 0.969842 (+) 0.0127802
(U_tot_cap-U_tot_ind)/mean=0.77%
[1mMode 1 at 4.85 GHz [2/5][0m
Calculating ℰ_magnetic,ℰ_electric
(ℰ_E-ℰ_H)/ℰ_E ℰ_E ℰ_H
0.1% 1.808e-20 1.807e-20
Calculating junction energy participation ration (EPR)
method=`line_voltage`. First estimates:
junction EPR p_1j sign s_1j (p_capacitive)
Energy fraction (Lj over Lj&Cj)= 98.54%
j1 0.000155679 (+) 2.31278e-06
(U_tot_cap-U_tot_ind)/mean=0.02%
[1mMode 4 at 7.62 GHz [5/5][0m
Calculating ℰ_magnetic,ℰ_electric
(ℰ_E-ℰ_H)/ℰ_E ℰ_E ℰ_H
2.0% 3.358e-22 3.291e-22
Calculating junction energy participation ration (EPR)
method=`line_voltage`. First estimates:
junction EPR p_4j sign s_4j (p_capacitive)
Energy fraction (Lj over Lj&Cj)= 96.46%
j1 0.00201137 (+) 7.37939e-05
(U_tot_cap-U_tot_ind)/mean=0.91%
Variation 4 [5/6]
[1mMode 0 at 4.52 GHz [1/5][0m
Calculating ℰ_magnetic,ℰ_electric
(ℰ_E-ℰ_H)/ℰ_E ℰ_E ℰ_H
97.6% 3.637e-24 8.818e-26
Calculating junction energy participation ration (EPR)
method=`line_voltage`. First estimates:
junction EPR p_0j sign s_0j (p_capacitive)
Energy fraction (Lj over Lj&Cj)= 98.72%
j1 0.973094 (+) 0.0125819
(U_tot_cap-U_tot_ind)/mean=0.76%
[1mMode 1 at 4.85 GHz [2/5][0m
Calculating ℰ_magnetic,ℰ_electric
(ℰ_E-ℰ_H)/ℰ_E ℰ_E ℰ_H
0.0% 1.664e-20 1.663e-20
Calculating junction energy participation ration (EPR)
method=`line_voltage`. First estimates:
junction EPR p_1j sign s_1j (p_capacitive)
Energy fraction (Lj over Lj&Cj)= 98.54%
j1 0.000184762 (+) 2.74508e-06
(U_tot_cap-U_tot_ind)/mean=0.01%
[1mMode 4 at 7.64 GHz [5/5][0m
Calculating ℰ_magnetic,ℰ_electric
(ℰ_E-ℰ_H)/ℰ_E ℰ_E ℰ_H
1.9% 2.04e-22 2.002e-22
Calculating junction energy participation ration (EPR)
method=`line_voltage`. First estimates:
junction EPR p_4j sign s_4j (p_capacitive)
Energy fraction (Lj over Lj&Cj)= 96.44%
j1 0.000473822 (+) 1.74688e-05
(U_tot_cap-U_tot_ind)/mean=0.93%
Variation 5 [6/6]
[1mMode 0 at 4.54 GHz [1/5][0m
Calculating ℰ_magnetic,ℰ_electric
(ℰ_E-ℰ_H)/ℰ_E ℰ_E ℰ_H
97.6% 2.615e-24 6.398e-26
Calculating junction energy participation ration (EPR)
method=`line_voltage`. First estimates:
junction EPR p_0j sign s_0j (p_capacitive)
Energy fraction (Lj over Lj&Cj)= 98.72%
j1 0.973765 (+) 0.0126657
(U_tot_cap-U_tot_ind)/mean=0.72%
[1mMode 1 at 4.85 GHz [2/5][0m
Calculating ℰ_magnetic,ℰ_electric
(ℰ_E-ℰ_H)/ℰ_E ℰ_E ℰ_H
0.1% 1.432e-20 1.431e-20
Calculating junction energy participation ration (EPR)
method=`line_voltage`. First estimates:
junction EPR p_1j sign s_1j (p_capacitive)
Energy fraction (Lj over Lj&Cj)= 98.54%
j1 0.000156612 (+) 2.32669e-06
(U_tot_cap-U_tot_ind)/mean=0.02%
[1mMode 4 at 7.64 GHz [5/5][0m
Calculating ℰ_magnetic,ℰ_electric
(ℰ_E-ℰ_H)/ℰ_E ℰ_E ℰ_H
2.1% 3.809e-22 3.731e-22
Calculating junction energy participation ration (EPR)
method=`line_voltage`. First estimates:
junction EPR p_4j sign s_4j (p_capacitive)
Energy fraction (Lj over Lj&Cj)= 96.45%
j1 0.000255005 (+) 9.39298e-06
(U_tot_cap-U_tot_ind)/mean=1.03%
ANALYSIS DONE. Data saved to:
D:\data-pyEPR\transmon-cavity-ro\design\2020-09-22 23-05-39.npz
🔹 Quantum Analysis (yes quantum)
epra = epr.QuantumAnalysis(eprh.data_filename)
epra.analyze_all_variations(cos_trunc = 8, fock_trunc = 15);
Differences in variations:
variation | 0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|
_ro_gap | 2mm | 0.5mm | 1mm | 1.5mm | 2.5mm | 3mm |
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Variation 0
Starting the diagonalization
Finished the diagonalization
Pm_norm=
modes
0 1.014784
1 2.373458
4 10.808200
dtype: float64
Pm_norm idx =
j1
0 True
1 False
4 False
*** Different parameters
_ro_gap 2mm
Name: 0, dtype: object
*** P (participation matrix, not normlz.)
j1
0 0.959994
1 0.000160
4 0.000974
*** S (sign-bit matrix)
s_j1
0 1
1 1
4 1
*** P (participation matrix, normalized.)
0.97
0.00016
0.00097
*** Chi matrix O1 PT (MHz)
Diag is anharmonicity, off diag is full cross-Kerr.
121 0.0421 0.404
0.0421 3.66e-06 7.03e-05
0.404 7.03e-05 0.000337
*** Chi matrix ND (MHz)
129 0.0164 0.381
0.0164 7.82e-07 3.2e-05
0.381 3.2e-05 0.000297
*** Frequencies O1 PT (MHz)
0 4445.186438
1 4849.678816
2 7620.046235
dtype: float64
*** Frequencies ND (MHz)
0 4441.791707
1 4849.684856
2 7620.048491
dtype: float64
*** Q_coupling
Empty DataFrame
Columns: []
Index: [0, 1, 4]
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Variation 1
Starting the diagonalization
Finished the diagonalization
Pm_norm=
modes
0 1.014906
1 2.168980
4 2.217915
dtype: float64
Pm_norm idx =
j1
0 True
1 False
4 False
*** Different parameters
_ro_gap 0.5mm
Name: 1, dtype: object
*** P (participation matrix, not normlz.)
j1
0 0.951980
1 0.000193
4 0.008496
*** S (sign-bit matrix)
s_j1
0 1
1 1
4 1
*** P (participation matrix, normalized.)
0.97
0.00019
0.0085
*** Chi matrix O1 PT (MHz)
Diag is anharmonicity, off diag is full cross-Kerr.
116 0.0498 3.45
0.0498 5.35e-06 0.00074
3.45 0.00074 0.0256
*** Chi matrix ND (MHz)
124 0.0229 3.27
0.0229 1.49e-06 0.000381
3.27 0.000381 0.0226
*** Frequencies O1 PT (MHz)
0 4390.336639
1 4849.752351
2 7610.547454
dtype: float64
*** Frequencies ND (MHz)
0 4387.018415
1 4849.758446
2 7610.564399
dtype: float64
*** Q_coupling
Empty DataFrame
Columns: []
Index: [0, 1, 4]
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Variation 2
Starting the diagonalization
Finished the diagonalization
Pm_norm=
modes
0 1.015272
1 2.038642
4 3.691355
dtype: float64
Pm_norm idx =
j1
0 True
1 False
4 False
*** Different parameters
_ro_gap 1mm
Name: 2, dtype: object
*** P (participation matrix, not normlz.)
j1
0 0.956533
1 0.000177
4 0.003976
*** S (sign-bit matrix)
s_j1
0 1
1 1
4 1
*** P (participation matrix, normalized.)
0.97
0.00018
0.004
*** Chi matrix O1 PT (MHz)
Diag is anharmonicity, off diag is full cross-Kerr.
121 0.0468 1.65
0.0468 4.53e-06 0.000319
1.65 0.000319 0.00561
*** Chi matrix ND (MHz)
129 0.0177 1.55
0.0177 9.11e-07 0.000141
1.55 0.000141 0.00492
*** Frequencies O1 PT (MHz)
0 4456.383436
1 4849.755344
2 7614.458066
dtype: float64
*** Frequencies ND (MHz)
0 4452.934948
1 4849.762324
2 7614.467588
dtype: float64
*** Q_coupling
Empty DataFrame
Columns: []
Index: [0, 1, 4]
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Variation 3
Starting the diagonalization
Finished the diagonalization
Pm_norm=
modes
0 1.015738
1 2.455907
4 5.536927
dtype: float64
Pm_norm idx =
j1
0 True
1 False
4 False
*** Different parameters
_ro_gap 1.5mm
Name: 3, dtype: object
*** P (participation matrix, not normlz.)
j1
0 0.957604
1 0.000156
4 0.002011
*** S (sign-bit matrix)
s_j1
0 1
1 1
4 1
*** P (participation matrix, normalized.)
0.97
0.00016
0.002
*** Chi matrix O1 PT (MHz)
Diag is anharmonicity, off diag is full cross-Kerr.
121 0.041 0.833
0.041 3.49e-06 0.000142
0.833 0.000142 0.00144
*** Chi matrix ND (MHz)
129 0.016 0.787
0.016 7.42e-07 6.44e-05
0.787 6.44e-05 0.00126
*** Frequencies O1 PT (MHz)
0 4446.307215
1 4849.653175
2 7620.797354
dtype: float64
*** Frequencies ND (MHz)
0 4442.910030
1 4849.659084
2 7620.802016
dtype: float64
*** Q_coupling
Empty DataFrame
Columns: []
Index: [0, 1, 4]
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Variation 4
Starting the diagonalization
Finished the diagonalization
Pm_norm=
modes
0 1.015473
1 1.798462
4 20.613832
dtype: float64
Pm_norm idx =
j1
0 True
1 False
4 False
*** Different parameters
_ro_gap 2.5mm
Name: 4, dtype: object
*** P (participation matrix, not normlz.)
j1
0 0.961003
1 0.000185
4 0.000474
*** S (sign-bit matrix)
s_j1
0 1
1 1
4 1
*** P (participation matrix, normalized.)
0.98
0.00018
0.00047
*** Chi matrix O1 PT (MHz)
Diag is anharmonicity, off diag is full cross-Kerr.
119 0.0484 0.196
0.0484 4.91e-06 3.97e-05
0.196 3.97e-05 8.02e-05
*** Chi matrix ND (MHz)
127 0.0212 0.185
0.0212 1.27e-06 1.99e-05
0.185 1.99e-05 7.09e-05
*** Frequencies O1 PT (MHz)
0 4404.970690
1 4849.858772
2 7639.745937
dtype: float64
*** Frequencies ND (MHz)
0 4401.653775
1 4849.864919
2 7639.746894
dtype: float64
*** Q_coupling
Empty DataFrame
Columns: []
Index: [0, 1, 4]
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Variation 5
Starting the diagonalization
Finished the diagonalization
Pm_norm=
modes
0 1.014646
1 2.203604
4 41.495446
dtype: float64
Pm_norm idx =
j1
0 True
1 False
4 False
*** Different parameters
_ro_gap 3mm
Name: 5, dtype: object
*** P (participation matrix, not normlz.)
j1
0 0.961586
1 0.000157
4 0.000255
*** S (sign-bit matrix)
s_j1
0 1
1 1
4 1
*** P (participation matrix, normalized.)
0.98
0.00016
0.00026
*** Chi matrix O1 PT (MHz)
Diag is anharmonicity, off diag is full cross-Kerr.
120 0.0411 0.105
0.0411 3.53e-06 1.81e-05
0.105 1.81e-05 2.32e-05
*** Chi matrix ND (MHz)
128 0.0174 0.0999
0.0174 8.63e-07 8.81e-06
0.0999 8.81e-06 2.05e-05
*** Frequencies O1 PT (MHz)
0 4417.824694
1 4849.694794
2 7636.332029
dtype: float64
*** Frequencies ND (MHz)
0 4414.488101
1 4849.700220
2 7636.332566
dtype: float64
*** Q_coupling
Empty DataFrame
Columns: []
Index: [0, 1, 4]
Does this make sense?🤔
We can plot the results and see weather or not they make sense. We expect two things:
- The anharmonicities should not change, since we don’t change the structure of the devices
- The cross-kerr frequencies should drop exponentialy, since electromagnetic waves decay exponentialy in a waveguide and the cross-kerr (aka the coupling) between the components is how much can they interact through the electric field, which is closely related to how much of the electric field ‘survives’ when going from one component to the other
epra.plot_hamiltonian_results();
C:\Users\rosengrp\anaconda3\lib\site-packages\pandas\plotting\_matplotlib\core.py:1235: UserWarning: FixedFormatter should only be used together with FixedLocator
ax.set_xticklabels(xticklabels)
C:\Users\rosengrp\anaconda3\lib\site-packages\pandas\plotting\_matplotlib\core.py:1235: UserWarning: FixedFormatter should only be used together with FixedLocator
ax.set_xticklabels(xticklabels)
C:\Users\rosengrp\anaconda3\lib\site-packages\pandas\plotting\_matplotlib\core.py:1235: UserWarning: FixedFormatter should only be used together with FixedLocator
ax.set_xticklabels(xticklabels)
C:\Users\rosengrp\anaconda3\lib\site-packages\pandas\plotting\_matplotlib\core.py:1235: UserWarning: FixedFormatter should only be used together with FixedLocator
ax.set_xticklabels(xticklabels)
Success 🎉🎈🎊🥳💃
OK, maybe $0.5$ mm is too close but as you can see, if we want the coupling between the readout and transmon to be around $1$ MHz we need the distance between them to be roughly $1.8$ mm