Skip to content

Commit

Permalink
"Calculate chi & Sweep Functionality for Whole Designs" - from Evange…
Browse files Browse the repository at this point in the history
…los' PR (NEEDS TESTING)
  • Loading branch information
shanto268 committed Feb 12, 2024
1 parent 10274e4 commit 4e52dba
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 11 deletions.
16 changes: 16 additions & 0 deletions squadds/calcs/qubit.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,4 +201,20 @@ def add_cavity_coupled_H_params(self):
"""
Add parameters for cavity-coupled Hamiltonian.
"""
pass

@abstractmethod
def chi(self):
"""
Calculate the full cavity frequency shift between |0> and |1> states of a qubit using g, f_r, f_q, and alpha. It uses the result derived using 2nd-order pertubation theory (equation 9 in SquaDDs paper).
Args:
- EJ (float): Josephson energy of the transmon qubit.
- EC (float): Charging energy of the transmon qubit.
- g (float): The coupling strength between the qubit and the cavity.
- f_r (float): The resonant frequency of the cavity.
- f_q (float): The frequency spacing between the first two qubit levels.
Returns:
- chi (float): The full dispersive shift of the cavity
"""
pass
26 changes: 25 additions & 1 deletion squadds/calcs/transmon_cross.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,4 +325,28 @@ def add_cavity_coupled_H_params(self):
EJ=row['EJ'],
f_r=row['cavity_frequency_GHz'],
res_type=row['resonator_type'],
Z0=50), axis=1)
Z0=50), axis=1)

def chi(self, EJ, EC, g, f_r):
"""
Calculate the full cavity frequency shift between |0> and |1> states of a qubit using g, f_r, f_q, and alpha. It uses the result derived using 2nd-order pertubation theory (equation 9 in SquaDDs paper).
Args:
- EJ (float): Josephson energy of the transmon qubit.
- EC (float): Charging energy of the transmon qubit.
- g (float): The coupling strength between the qubit and the cavity.
- f_r (float): The resonant frequency of the cavity.
- f_q (float): The frequency spacing between the first two qubit levels.
Returns:
- chi (float): The full dispersive shift of the cavity
"""
omega_r = 2 * np.pi * f_r * 1e9
transmon = Transmon(EJ=EJ, EC=EC, ng=0, ncut=30)
alpha = transmon.anharmonicity() * 1E3 # MHz, linear or angular
omega_q = transmon.E01() # is this in linear or angular frequency units
delta = omega_r - omega_q
sigma = omega_r + omega_q

chi = 2 * g**2 * (alpha /(delta * (delta - alpha))- alpha/(sigma * (sigma + alpha)))

return chi
31 changes: 28 additions & 3 deletions squadds/simulations/ansys_simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@ class AnsysSimulator:
gui: The MetalGUI object.
"""

def __init__(self, analyzer, design_options):
def __init__(self, analyzer, design_options, **kwargs):
"""
Initialize the AnsysSimulator object.
Args:
analyzer: The analyzer object.
design_options: The design options.
Optional arguments:
open_gui (bool): If True, a MetalGUI instance is created and assigned to self.gui. Default is False.
"""
self.analyzer = analyzer
self.design_options = design_options
Expand Down Expand Up @@ -74,7 +76,8 @@ def __init__(self, analyzer, design_options):
}

self.design = metal.designs.design_planar.DesignPlanar()
self.gui = metal.MetalGUI(self.design)
if kwargs.get("open_gui", False):
self.gui = metal.MetalGUI(self.design)
self.design.overwrite_enabled = True
self._warnings()

Expand All @@ -97,6 +100,7 @@ def get_design_screenshot(self):
Returns:
None
"""
self.gui = metal.MetalGUI(self.design)
self.gui.rebuild()
self.gui.autoscale()
self.gui.screenshot()
Expand Down Expand Up @@ -200,10 +204,31 @@ def plot_device(self, device_dict):
Returns:
None
"""
self.gui = metal.MetalGUI(self.design)
self.design.delete_all_components()
if "g" in device_dict["sim_results"]:
qc = QubitCavity(self.design, "qubit_cavity", options=device_dict["design"]["design_options"])

self.gui.rebuild()
self.gui.autoscale()
self.gui.screenshot()
self.gui.screenshot()

def sweep_qubit_cavity(self, device_dict, emode_setup=None, lom_setup=None):
"""
Sweeps a single geometric parameter of the qubit and cavity system based on the provided sweep dictionary.
Args:
device_dict (dict): A dictionary containing the device design options and setup.
emode_setup (dict): A dictionary containing the eigenmode setup options.
lom_setup (dict): A dictionary containing the LOM setup options.
Returns:
results: The sweep results.
"""

if emode_setup == None:
emode_setup=self.default_eigenmode_options
if lom_setup == None:
lom_setup=self.default_lom_options

results = run_qubit_cavity_sweep(self.design, device_dict, emode_setup, lom_setup, filename="qubit_cavity_sweep")
35 changes: 33 additions & 2 deletions squadds/simulations/objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
========================================================================================================================
"""

from datetime import datetime

from qiskit_metal.analyses.quantization import EPRanalysis, LOManalysis

from .sweeper_helperfunctions import extract_QSweep_parameters
Expand Down Expand Up @@ -52,7 +54,7 @@ def __init__(self, design_name="CavitySweep", renderer_type="hfss", sim_type="ei
self.Lj = Lj
self.Cj = Cj

def simulate_whole_device(design, device_dict, eigenmode_options, LOM_options):
def simulate_whole_device(design, device_dict, eigenmode_options, LOM_options, open_gui=False):
"""
Simulates the whole device by running eigenmode and LOM simulations.
Expand All @@ -62,6 +64,7 @@ def simulate_whole_device(design, device_dict, eigenmode_options, LOM_options):
cavity_dict (dict): Dictionary containing cavity options.
LOM_options (dict): Dictionary containing LOM setup options.
eigenmode_options (dict): Dictionary containing eigenmode setup options.
open_gui (bool, optional): If True, the Metal GUI is opened. Default is False.
Returns:
tuple: A tuple containing the simulation results, LOM analysis object, and eigenmode analysis object.
Expand Down Expand Up @@ -93,7 +96,10 @@ def simulate_whole_device(design, device_dict, eigenmode_options, LOM_options):
)

design = metal.designs.design_planar.DesignPlanar()
gui = metal.MetalGUI(design)
if open_gui:
gui = metal.MetalGUI(design)
else:
pass
design.overwrite_enabled = True
QC = create_qubitcavity(device_dict_format, design)

Expand Down Expand Up @@ -428,6 +434,31 @@ def run_sweep(design, sweep_opts, emode_options, lom_options, filename="default_
filename = f"filename_{datetime.now().strftime('%d%m%Y_%H.%M.%S')}"
save_simulation_data_to_json(cpw_claw_df, filename)

def run_qubit_cavity_sweep(design, device_options, emode_setup=None, lom_setup=None, filename="default_sweep"):
"""
Runs a parameter sweep for the specified design.
Args:
design (Design): The design object.
sweep_opts (dict): The sweep options.
device_dict (dict): The device dictionary containing the design options and setup.
emode_setup (dict): The eigenmode setup options.
lom_setup (dict): The LOM setup options.
filename (str): The filename for the simulation results.
Returns:"""

simulated_params_list = []
for param in extract_QSweep_parameters(device_options):
# print(param)
# print(param['design_options_qubit'])
cpw_claw_qubit_df, _, _ = simulate_whole_device(design, param, emode_setup, lom_setup)
filename = f"filename_{datetime.now().strftime('%d%m%Y_%H.%M.%S')}"
simulated_params_list.append(cpw_claw_qubit_df)
save_simulation_data_to_json(cpw_claw_qubit_df, filename)

return simulated_params_list

def start_simulation(design, config):
"""
Starts the simulation with the specified design and configuration.
Expand Down
13 changes: 8 additions & 5 deletions squadds/simulations/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,12 +164,15 @@ def get_freq_Q_kappa(epra, test_hfss):

setMaterialProperties(project_name, design_name, solutiontype="Eigenmode")
epra.sim._analyze()
# epra.sim.plot_convergences()
epra.sim.save_screenshot()
# epra.sim.plot_fields('main')
# epra.sim.save_screenshot()
f = epra.get_frequencies()
try:
epra.sim.plot_convergences()
epra.sim.save_screenshot()
epra.sim.plot_fields('main')
epra.sim.save_screenshot()
except:
print("couldn't generate plots.")

f = epra.get_frequencies()
freq = f.values[0][0] * 1e9
Q = f.values[0][1]
kappa = freq / Q
Expand Down

0 comments on commit 4e52dba

Please sign in to comment.