Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Ability to Extract Q-factors from Eigenmode Simulations #794

Merged
merged 11 commits into from
Jun 3, 2022
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
ThomasGM4 marked this conversation as resolved.
Show resolved Hide resolved
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