Skip to content

Commit b6654b4

Browse files
Merge branch 'main' into pyside6-v2
2 parents 0cfd93a + dd95a13 commit b6654b4

File tree

12 files changed

+518
-217
lines changed

12 files changed

+518
-217
lines changed

.github/workflows/main.yml

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -70,34 +70,34 @@ jobs:
7070
run: python -m pip install -U tox setuptools virtualenv wheel
7171
- name: Install and Run Tests
7272
run: tox -e py
73-
# windows-tests:
74-
# name: tests-python${{ matrix.python-version }}-windows
75-
# runs-on: windows-latest
76-
# strategy:
77-
# matrix:
78-
# python-version: ["3.9", "3.10"]
79-
# steps:
80-
# - uses: actions/checkout@v3
81-
# - name: Set up Python ${{ matrix.python-version }}
82-
# uses: actions/setup-python@v4
83-
# with:
84-
# python-version: ${{ matrix.python-version }}
85-
# - name: Pip cache
86-
# uses: actions/cache@v3
87-
# with:
88-
# path: ~\AppData\Local\pip\Cache
89-
# key: ${{ runner.os }}-${{ matrix.python-version }}-pip-tests-${{ hashFiles('setup.py','requirements-dev.txt','requirements.txt') }}
90-
# restore-keys: |
91-
# ${{ runner.os }}-${{ matrix.python-version }}-pip-tests-
92-
# ${{ runner.os }}-${{ matrix.python-version }}-pip-
93-
# ${{ runner.os }}-${{ matrix.python-version }}-
94-
# - name: Install deps
95-
# run: |
96-
# python -m pip install -U tox cvxopt setuptools virtualenv wheel
97-
# shell: pwsh
98-
# - name: Install and Run Tests
99-
# run: tox --sitepackages -e py
100-
# shell: bash -l {0}
73+
windows-tests:
74+
name: tests-python${{ matrix.python-version }}-windows
75+
runs-on: windows-latest
76+
strategy:
77+
matrix:
78+
python-version: ["3.9", "3.10"]
79+
steps:
80+
- uses: actions/checkout@v3
81+
- name: Set up Python ${{ matrix.python-version }}
82+
uses: actions/setup-python@v4
83+
with:
84+
python-version: ${{ matrix.python-version }}
85+
- name: Pip cache
86+
uses: actions/cache@v3
87+
with:
88+
path: ~\AppData\Local\pip\Cache
89+
key: ${{ runner.os }}-${{ matrix.python-version }}-pip-tests-${{ hashFiles('setup.py','requirements-dev.txt','requirements.txt') }}
90+
restore-keys: |
91+
${{ runner.os }}-${{ matrix.python-version }}-pip-tests-
92+
${{ runner.os }}-${{ matrix.python-version }}-pip-
93+
${{ runner.os }}-${{ matrix.python-version }}-
94+
- name: Install deps
95+
run: |
96+
python -m pip install -U tox cvxopt setuptools virtualenv wheel
97+
shell: pwsh
98+
- name: Install and Run Tests
99+
run: tox --sitepackages -e py
100+
shell: bash -l {0}
101101
lint:
102102
name: lint
103103
runs-on: ubuntu-latest

README_Tutorials.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,5 @@ Join the [Qiskit](https://ibm.co/joinqiskitslack) `#metal` slack channel to requ
3838
| Mar 24, 2022 | Tutorial | [Time Evolution for the CR gate](https://www.youtube.com/watch?v=icDryjZrUQ4)|
3939
| Aug 4, 2022 | Tutorial | [Open-Source Rendering and Simulation Solution for Qiskit Metal](https://youtu.be/sA0uXtCAhWw)|
4040
| Aug 11, 2022 | Tutorial | [Qiskit Metal E21. Quantum Spice Web App - Sneak Peak](https://youtu.be/3UE57DaG-HI)|
41+
| Feb 2, 2023 | Tutorial | [Qiskit Metal E22. Open-Source Simulation Renderers for Metal — Gmsh and ElmerFEM](https://youtu.be/84j3l_9fHko)|
4142
| 2022 &rightarrow; ... | TBD | Topics to potentially schedule:<ul><li>Analysis deep dives (as needed)</li><li>What happens frequently when analyzing a chip.</li><li>Metal use cases: Common problems with pins, ports, fillet matches meander distance</li><li>GDS fabrication option, use cases</li><li>QRenderers: How to use, modify and add new renderers</li><li>New QAnalysis/QRenderer structure and usage</li><li>...</li></ul> |

docs/index.rst

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ Qiskit Metal | Quantum Device Design & Analysis (Q-EDA) |version|
44

55
.. attention::
66

7-
This is an alpha version of Qiskit Metal, the code is still under development.
8-
Please let us know about anything you might want us to add or elaborate upon in the
7+
This is an alpha version of Qiskit Metal, the code is still under development.
8+
Please let us know about anything you might want us to add or elaborate upon in the
99
Slack channel `#metal <https://qiskit.slack.com/archives/C01R8KP5WP7>`_ in the `qiskit workspace <https://ibm.co/joinqiskitslack>`_.
1010

1111
.. hint::
@@ -22,7 +22,7 @@ Qiskit Metal | Quantum Device Design & Analysis (Q-EDA) |version|
2222
.. rubric:: **About**
2323

2424
**Qiskit Metal | for quantum device design & analysis (`Qiskit Metal`)**
25-
is an open-source framework (and library) for the design of superconducting quantum
25+
is an open-source framework (and library) for the design of superconducting quantum
2626
chips and devices.
2727
Call it quantum EDA (Q-EDA) and analysis. Qiskit Metal is:
2828

@@ -34,21 +34,20 @@ Call it quantum EDA (Q-EDA) and analysis. Qiskit Metal is:
3434
* Community-oriented and tutorial-driven, join the `#metal <https://qiskit.slack.com/archives/C01R8KP5WP7>`_ Slack.
3535

3636

37-
Use the slack channel. Join `qiskit slack <https://ibm.co/joinqiskitslack>`_ and
38-
then join the `#metal <https://qiskit.slack.com/archives/C01R8KP5WP7>`_ channel to communicate with the developers and other participants.
37+
Use the slack channel. Join `qiskit slack <https://ibm.co/joinqiskitslack>`_ and
38+
then join the `#metal <https://qiskit.slack.com/archives/C01R8KP5WP7>`_ channel to communicate with the developers and other participants.
3939
You may also use this channel to learn about upcoming weekly tutorials and to inquire about potential collaborations.
4040

4141

4242
.. rubric:: **Live tutorials and Q&A**:
43-
We host live tutorials and Q&A sessions, `sign up here <https://airtable.com/shrxQEgKqZCf319F3>`_ to receive an invite to the upcoming sessions.
44-
For past sessions & videos, see `here <https://github.com/Qiskit/qiskit-metal/blob/main/README_Tutorials.md>`_.
43+
We host live tutorials and Q&A sessions. Announcements for future tutorials are posted in the #metal channel.
4544

4645
.. rubric:: **Qiskit Metal Vision**:
4746

48-
Designing quantum devices is the bedrock of the quantum ecosystem,
47+
Designing quantum devices is the bedrock of the quantum ecosystem,
4948
but it is a difficult, multi-step process that connects traditionally disparate worlds.
50-
Metal is automating and streamlining this process.
51-
Our vision is to develop a community-driven universal platform capable
49+
Metal is automating and streamlining this process.
50+
Our vision is to develop a community-driven universal platform capable
5251
of orchestrating quantum chip development from concept to fabrication in
5352
a simple and open framework.
5453

docs/tut/4-Analysis/4.21-Capacitance-matrix.ipynb

Lines changed: 172 additions & 139 deletions
Large diffs are not rendered by default.

qiskit_metal/analyses/simulation/lumped_elements.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class LumpedElementsSim(QSimulation):
5959
"""Default setup."""
6060

6161
# supported labels for data generated from the simulation
62-
data_labels = ['cap_matrix', 'cap_all_passes', 'units']
62+
data_labels = ['cap_matrix', 'cap_all_passes', 'units', 'is_converged']
6363
"""Default data labels."""
6464

6565
def __init__(self, design: 'QDesign' = None, renderer_name: str = 'q3d'):
@@ -94,6 +94,8 @@ def _get_results_from_renderer(self):
9494
# extract the capacitance matrices for all passes
9595
self.capacitance_all_passes, _ = self.renderer.get_capacitance_all_passes(
9696
)
97+
# extract convergence
98+
self.is_converged = self.renderer.get_convergence()
9799
else:
98100
self.logger.error(
99101
"Please initialize renderer before trying to load the simulation results."
@@ -216,3 +218,26 @@ def units(self, data: str):
216218
{type(data)})
217219
return
218220
self.set_data('units', data)
221+
222+
@property
223+
def is_converged(self) -> bool:
224+
"""Getter
225+
226+
Returns:
227+
bool: Boolean indicating whether simulation has converged
228+
"""
229+
return self.get_data('is_converged')
230+
231+
@is_converged.setter
232+
def is_converged(self, data: bool):
233+
"""Setter
234+
235+
Args:
236+
data (bool): Sets convergence of simulation for
237+
"""
238+
if not isinstance(data, bool):
239+
self.logger.warning(
240+
'Unsupported type %s. Only accepts boolean. Please try again.',
241+
{type(data)})
242+
return
243+
self.set_data('is_converged', data)

qiskit_metal/analyses/sweep_and_optimize/sweeper.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,9 @@ def iterate_option_sweep(self, args: list, all_dicts: Dict,
164164
template = "An exception of type {0} occurred. Arguments:\n{1!r}"
165165
message = template.format(type(ex).__name__, ex.args)
166166
self.design.logger.warning(
167-
f'For class {self.parent.__class__.__name__}, run() did not execute as expected: {message}'
168-
)
167+
f'For class {self.parent.__class__.__name__}, '
168+
f'option_name={".".join(option_path)}, key={item}, '
169+
f'run() did not execute as expected: {message}')
169170

170171
self.populate_all_sweep(all_sweep, item, args[1])
171172

qiskit_metal/renderers/renderer_ansys/q3d_renderer.py

Lines changed: 153 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
# copyright notice, and modified files need to carry a notice indicating
1313
# that they have been altered from the originals.
1414

15-
from typing import List, Union
15+
from typing import List, Tuple, Union
1616

1717
import pandas as pd
1818
from collections import defaultdict
@@ -443,6 +443,158 @@ def lumped_oscillator_vs_passes(self, *args, **kwargs):
443443
'This method is deprecated. Change your scripts to use'
444444
'analysis.quantitative.capacitance_lom.run_lom()')
445445

446+
def get_convergence(self) -> bool:
447+
"""Extracts convergence from Ansys simulation result
448+
"""
449+
# If 'LastAdaptive' is used, then the pass_number won't affect anything.
450+
# If 'AdaptivePass' is used, then the pass_number is used.
451+
convergence_df, convergence_txt = self._pinfo.setup.get_convergence()
452+
target, current, pass_min = self._parse_text_from_q3d_convergence(
453+
convergence_txt)
454+
is_converged = self._test_if_q3d_analysis_converged(
455+
target, current, pass_min)
456+
457+
return is_converged
458+
459+
def _test_if_q3d_analysis_converged(cls, target: float, current: float,
460+
passes_min: int) -> Union[bool, None]:
461+
"""Use solution-data from Ansys-Q3d to determine if converged.
462+
463+
Args:
464+
target (float): Delta percentage for target. Default is None.
465+
current (float): Delta percentage for current. Default is None.
466+
passes_min (int): Regarding convergence, minimum number of passes.
467+
Default is None.
468+
469+
Returns:
470+
Union[bool, None]: Had solution data converged. Default is None.
471+
"""
472+
473+
if None not in (target, current, passes_min):
474+
# Confirm that all three numbers have an value.
475+
if current <= target and passes_min > 1:
476+
is_converged = True
477+
return is_converged
478+
is_converged = False
479+
return is_converged
480+
481+
is_converged = None
482+
return is_converged
483+
484+
def _parse_text_from_q3d_convergence(
485+
self,
486+
gui_text: str) -> Tuple[Union[None, float], Union[None, float]]:
487+
"""Parse gui_text using a priori known formatting. Ansys-Q3D
488+
solution-data provides gui_text.
489+
490+
Args:
491+
gui_text (str): From Ansys-GUI-SolutionData.
492+
493+
Returns:
494+
1st Union[None, float]: Delta percentage for target. Default is None.
495+
2nd Union[None, float]: Delta percentage for current. Default is None.
496+
"""
497+
498+
text_list = gui_text.splitlines()
499+
500+
# Find Target information in text.
501+
target_all = [string for string in text_list if 'Target' in string]
502+
503+
# Find Current information in text.
504+
current_all = [string for string in text_list if 'Current' in string]
505+
506+
# Find Minimum number of passes from solution-data.
507+
min_passes_all = [string for string in text_list if 'Minimum' in string]
508+
509+
target = self._extract_target_delta(target_all)
510+
current = self._extract_current_delta(current_all)
511+
min_passes = self._extract_min_passes(min_passes_all)
512+
513+
return target, current, min_passes
514+
515+
def _extract_min_passes(self, min_passes_all: list) -> Union[None, float]:
516+
"""Given a pre-formatted list, search and return the "Minimum Number
517+
Of Passes."
518+
519+
Args:
520+
min_passes_all (list): Result of search through string returned from Ansys-Q3D.
521+
522+
Returns:
523+
Union[None, float]: Regarding convergence, minimum number of passes.
524+
Default is None.
525+
"""
526+
527+
min_num_of_passes = None
528+
if len(min_passes_all) == 1:
529+
if min_passes_all[0]:
530+
_, _, min_passes_str = min_passes_all[0].partition(':')
531+
try:
532+
min_num_of_passes = int(min_passes_str)
533+
except ValueError:
534+
self.design.logger.warning(
535+
f'Target={min_passes_str} in GUI is not an int.'
536+
'Force Minimum Number Of Passes to be None.')
537+
else:
538+
self.design.logger.warning(
539+
'Either could not find Minimum Number of Passes '
540+
'information or too many entries in text. '
541+
'Force Minimum Number of Passes to be None.')
542+
return min_num_of_passes
543+
544+
def _extract_target_delta(self, target_all: list) -> Union[None, float]:
545+
"""Given a pre-formatted list, search and return the target-delta
546+
percentage for convergence.
547+
548+
Args:
549+
target_all (list): Result of search through string returned from Ansys-Q3D.
550+
551+
Returns:
552+
Union[None, float]: Delta percentage for target. Default is None.
553+
"""
554+
555+
target = None
556+
if len(target_all) == 1:
557+
if target_all[0]:
558+
_, _, target_str = target_all[0].partition(':')
559+
try:
560+
target = float(target_str)
561+
except ValueError:
562+
self.design.logger.warning(
563+
f'Target={target_str} in GUI is not a float.'
564+
'Force Target Delta to be None.')
565+
else:
566+
self.design.logger.warning(
567+
'Either could not find Target Delta information or too many '
568+
'entries in text. Force Target Delta to be None.')
569+
return target
570+
571+
def _extract_current_delta(self, current_all: list) -> Union[None, float]:
572+
"""Given a pre-formatted list, search and return the current-delta
573+
percentage for convergence.
574+
575+
Args:
576+
current_all (list): Result of search through string returned from Ansys-Q3D.
577+
578+
Returns:
579+
Union[None, float]: Delta percentage for current. Default is None.
580+
"""
581+
582+
current = None
583+
if len(current_all) == 1:
584+
if current_all[0]:
585+
_, _, current_str = current_all[0].partition(':')
586+
try:
587+
current = float(current_str)
588+
except ValueError:
589+
self.design.logger.warning(
590+
f'Target={current_str} in GUI is not a float.'
591+
'Force Current Delta to be None.')
592+
else:
593+
self.design.logger.warning(
594+
'Either could not find Current Delta information or too many '
595+
'entries in text. Force Current Delta to be None.')
596+
return current
597+
446598
def plot_convergence_main(self, RES: pd.DataFrame):
447599
"""Plot alpha and frequency versus pass number, as well as convergence
448600
of delta (in %).

0 commit comments

Comments
 (0)