Skip to content

Commit

Permalink
Implement Ability to Extract Q-factors from Eigenmode Simulations (#794)
Browse files Browse the repository at this point in the history
* Implement Ability to Extract Q-factors from Eigenmode Simulations

* Updated tests

* Added Tutorial

* Revert "Updated tests"

This reverts commit 146b0e9.
Tests would be restored to the one in main.

* When one plot_convergences(), then the frequiences are gathered so they gotten by get_frequencies().

* Removed solution_type variable. Replaced by pyEPR implementation

* Updated tests

Co-authored-by: Priti Ashvin Shah <74020801+priti-ashvin-shah-ibm@users.noreply.github.com>
Co-authored-by: Priti A Shah <Priti.Ashvin.Shah@ibm.com>
  • Loading branch information
3 people authored Jun 3, 2022
1 parent b4ab51e commit 8726fc6
Show file tree
Hide file tree
Showing 4 changed files with 426 additions and 12 deletions.
21 changes: 18 additions & 3 deletions qiskit_metal/renderers/renderer_ansys/ansys_renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ class QAnsysRenderer(QRendererAnalysis):
* _Rj: 0 -- _Rj *must* be 0 for pyEPR analysis! _Rj has units of Ohms
* max_mesh_length_jj: '7um' -- Maximum mesh length for Josephson junction elements
* project_path: None -- Default project path; if None --> get active
* max_mesh_length_port: '7um' -- Maximum mesh length for Ports in Eigenmode Simulations
* project_name: None -- Default project name
* design_name: None -- Default design name
* ansys_file_extension: '.aedt' -- Ansys file extension for 2016 version and newer
Expand All @@ -122,6 +123,7 @@ class QAnsysRenderer(QRendererAnalysis):
Cj=0, # Cj *must* be 0 for pyEPR analysis! Cj has units of femtofarads (fF)
_Rj=0, # _Rj *must* be 0 for pyEPR analysis! _Rj has units of Ohms
max_mesh_length_jj='7um', # maximum mesh length for Josephson junction elements
max_mesh_length_port='7um', # maximum mesh length for Ports in Eigenmode Simulations
project_path=None, # default project path; if None --> get active
project_name=None, # default project name
design_name=None, # default design name
Expand Down Expand Up @@ -748,6 +750,7 @@ def execute_design(
self.clean_active_design()
else:
self.new_ansys_design(design_name, solution_type)

self.set_variables(vars_to_initialize)
self.render_design(**design_selection)
return self.pinfo.design.name
Expand Down Expand Up @@ -987,9 +990,10 @@ def render_design(
Chip_subtract_dict consists of component names (keys) and a set of all elements within each component that
will eventually be subtracted from the ground plane. Add objects that are perfect conductors and/or have
meshing to self.assign_perfE and self.assign_mesh, respectively; both are initialized as empty lists. Note
that these objects are "refreshed" each time render_design is called (as opposed to in the init function)
to clear QAnsysRenderer of any leftover items from the last call to render_design.
meshing to self.assign_perfE and self.assign_mesh, respectively; both are initialized as empty lists. Similarly,
if the object is a port in an eigenmode simulation, add it to self.assign_port_mesh, which is initialized
as an empty list. Note that these objects are "refreshed" each time render_design is called (as opposed to
in the init function) to clear QAnsysRenderer of any leftover items from the last call to render_design.
Among the components selected for export, there may or may not be unused (unconnected) pins.
The second parameter, open_pins, contains tuples of the form (component_name, pin_name) that
Expand Down Expand Up @@ -1573,6 +1577,17 @@ def add_mesh(self):
MaxLength=self._options["max_mesh_length_jj"],
)

try:
exists_port_mesh = (len(self.assign_port_mesh) > 0)
except:
exists_port_mesh = False

if exists_port_mesh:
self.modeler.mesh_length(
'port_mesh',
self.assign_port_mesh,
MaxLength=self._options['max_mesh_length_port'])

# Still implementing
def auto_wirebonds(self, table):
"""
Expand Down
26 changes: 18 additions & 8 deletions qiskit_metal/renderers/renderer_ansys/hfss_renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# that they have been altered from the originals.

# modified by Chalmers/SK/20210621
# modified by Samarth Hawaldar

from collections import defaultdict
from pathlib import Path
Expand Down Expand Up @@ -40,6 +41,7 @@ class QHFSSRenderer(QAnsysRenderer):
* Cj: 0 -- Cj *must* be 0 for pyEPR analysis! Cj has units of femtofarads (fF)
* _Rj: 0 -- _Rj *must* be 0 for pyEPR analysis! _Rj has units of Ohms
* max_mesh_length_jj: '7um' -- Maximum mesh length for Josephson junction elements
* max_mesh_length_port: '7um' -- Maximum mesh length for Ports in Eigenmode Simulations
* project_path: None -- Default project path; if None --> get active
* project_name: None -- Default project name
* design_name: None -- Default design name
Expand Down Expand Up @@ -164,6 +166,7 @@ def render_design(self,
self.chip_subtract_dict = defaultdict(set)
self.assign_perfE = []
self.assign_mesh = []
self.assign_port_mesh = []
self.jj_lumped_ports = {}
self.jj_to_ignore = set()

Expand All @@ -185,10 +188,10 @@ def render_design(self,

self.render_chips(box_plus_buffer=box_plus_buffer)
self.subtract_from_ground()
self.add_mesh()
self.metallize()
if port_list:
self.create_ports(port_list)
self.add_mesh()
self.metallize()

def create_ports(self, port_list: list):
"""Add ports and their respective impedances in Ohms to designated pins
Expand Down Expand Up @@ -224,10 +227,17 @@ def create_ports(self, port_list: list):
y_max - y_min, 0,
**dict(transparency=0.0))
axis = 'x' if abs(x1 - x0) > abs(y1 - y0) else 'y'
poly_ansys.make_lumped_port(axis,
z0=str(impedance) + 'ohm',
name=f'LumpPort_{qcomp}_{pin}')
self.modeler.rename_obj(poly_ansys, port_name)
if self.pinfo.design.solution_type != 'Eigenmode':
poly_ansys.make_lumped_port(axis,
z0=str(impedance) + 'ohm',
name=f'LumpPort_{qcomp}_{pin}')
self.modeler.rename_obj(poly_ansys, port_name)
else:
poly_ansys.make_rlc_boundary(axis,
r=str(impedance) + 'ohm',
name=f'RLCBoundary_{qcomp}_{pin}')
self.modeler.rename_obj(poly_ansys, port_name)
self.assign_port_mesh.append(port_name)

# Draw line
lump_line = self.modeler.draw_polyline(
Expand Down Expand Up @@ -435,8 +445,8 @@ def add_drivenmodal_setup(self,
*args,
**kwargs):
"""Create a solution setup in Ansys HFSS Driven Modal. If user does
not provide arguments, they will be obtained from default_setup dict.
not provide arguments, they will be obtained from default_setup dict.
Args:
name (str, optional): Name of driven modal setup. Defaults to None.
freq_ghz (int, optional): Frequency in GHz. Defaults to None.
Expand Down
3 changes: 2 additions & 1 deletion qiskit_metal/tests/test_renderers.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,12 @@ def test_renderer_qansys_renderer_options(self):
renderer = QAnsysRenderer(design, initiate=False)
options = renderer.default_options

self.assertEqual(len(options), 13)
self.assertEqual(len(options), 14)
self.assertEqual(options['Lj'], '10nH')
self.assertEqual(options['Cj'], 0)
self.assertEqual(options['_Rj'], 0)
self.assertEqual(options['max_mesh_length_jj'], '7um')
self.assertEqual(options['max_mesh_length_port'], '7um')
self.assertEqual(options['project_path'], None)
self.assertEqual(options['project_name'], None)
self.assertEqual(options['design_name'], None)
Expand Down
Loading

0 comments on commit 8726fc6

Please sign in to comment.