Skip to content

Commit 85fa093

Browse files
Merge branch 'main' into fix_issue1176
2 parents ede5968 + eb82201 commit 85fa093

File tree

13 files changed

+395
-227
lines changed

13 files changed

+395
-227
lines changed

_unittest/test_11_Setup.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,11 @@ def test_03_non_valid_setup(self):
6767
assert not setup1.enable_adaptive_setup_broadband(1, 2.5, 10, 0.01)
6868
assert not setup1.enable_adaptive_setup_single(3.5)
6969
self.aedtapp.solution_type = sol
70+
71+
def test_04_delete_setup(self):
72+
self.aedtapp.duplicate_design("delete_setups")
73+
setup1 = self.aedtapp.create_setup("My_HFSS_Setup2", self.aedtapp.SETUPS.HFSSDrivenAuto)
74+
assert len(self.aedtapp.setups) == 1
75+
assert setup1.delete()
76+
assert len(self.aedtapp.setups) == 0
77+
assert not self.aedtapp.get_setups()

_unittest/test_12_PostProcessing.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,26 @@ def test_03_get_solution_data(self):
147147
assert os.path.exists(os.path.join(self.local_scratch.path, "output.csv"))
148148

149149
def test_04_export_touchstone(self):
150-
self.aedtapp.export_touchstone("Setup1", "Sweep", os.path.join(self.local_scratch.path, "Setup1_Sweep.S2p"))
150+
setup_name = "Setup1"
151+
sweep_name = "Sweep"
152+
self.aedtapp.export_touchstone(
153+
setup_name, sweep_name, os.path.join(self.local_scratch.path, "Setup1_Sweep.S2p")
154+
)
151155
assert os.path.exists(os.path.join(self.local_scratch.path, "Setup1_Sweep.S2p"))
152156

157+
sweep_name = None
158+
self.aedtapp.export_touchstone(
159+
setup_name, sweep_name, os.path.join(self.local_scratch.path, "Setup1_Sweep2.S2p")
160+
)
161+
assert os.path.exists(os.path.join(self.local_scratch.path, "Setup1_Sweep2.S2p"))
162+
setup_name = None
163+
self.aedtapp.export_touchstone(
164+
setup_name, sweep_name, os.path.join(self.local_scratch.path, "Setup1_Sweep3.S2p")
165+
)
166+
assert os.path.exists(os.path.join(self.local_scratch.path, "Setup1_Sweep3.S2p"))
167+
168+
assert self.aedtapp.export_touchstone(setup_name, sweep_name)
169+
153170
@pytest.mark.skipif(config["build_machine"] == True, reason="Not running in non-graphical mode")
154171
def test_05_export_report_to_jpg(self):
155172

@@ -698,3 +715,10 @@ def test_60_test_parse_vector(self):
698715
local_path = os.path.dirname(os.path.realpath(__file__))
699716
out = _parse_streamline(os.path.join(local_path, "example_models", "test_streamline.fldplt"))
700717
assert isinstance(out, list)
718+
719+
def test_61_delete_variations(self):
720+
assert self.q3dtest.cleanup_solution()
721+
vars = self.field_test.available_variations.get_variation_strings()
722+
assert self.field_test.available_variations.variations()
723+
assert self.field_test.cleanup_solution(vars, entire_solution=False)
724+
assert self.field_test.cleanup_solution(vars, entire_solution=True)

_unittest/test_20_HFSS.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,7 @@ def test_25_create_parametrics(self):
597597
)
598598
oo = self.aedtapp.get_oo_object(self.aedtapp.odesign, r"Optimetrics\ParametricsfromFile")
599599
assert oo
600+
assert self.aedtapp.parametrics.delete("ParametricsfromFile")
600601

601602
def test_26_create_optimization(self):
602603
calculation = "db(S(Cir1,Cir1))"
@@ -626,13 +627,15 @@ def test_26_create_optimization(self):
626627
if "NAME:Ranges" in el:
627628
break
628629
assert "rd" in el[2]
630+
assert self.aedtapp.optimizations.delete(setup2.name)
629631

630632
def test_27_create_doe(self):
631633
setup2 = self.aedtapp.optimizations.add("db(S(1,1))", ranges={"Freq": "2.5GHz"}, optim_type="DXDOE")
632634
assert setup2.add_variation("w1", 0.1, 10, 51)
633635
assert setup2
634636
assert setup2.add_goal(calculation="dB(S(1,1))", ranges={"Freq": "2.6GHz"})
635637
assert setup2.add_calculation(calculation="dB(S(1,1))", ranges={"Freq": "2.5GHz"})
638+
assert setup2.delete()
636639

637640
def test_28A_create_dx(self):
638641
setup2 = self.aedtapp.optimizations.add(None, {"w1": "1mm", "w2": "2mm"}, optim_type="optiSLang")

_unittest/test_21_Circuit.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,14 @@ def test_17_create_setup(self):
203203
def test_18_export_touchstone(self):
204204
assert self.aedtapp.analyze_nominal()
205205
time.sleep(30)
206-
assert self.aedtapp.export_touchstone("Dom_LNA", "Dom_LNA", os.path.join(self.local_scratch.path, "new.s2p"))
206+
solution_name = "Dom_LNA"
207+
sweep_name = None
208+
file_name = os.path.join(self.local_scratch.path, "new.s2p")
209+
assert self.aedtapp.export_touchstone(solution_name, sweep_name, file_name)
210+
assert os.path.exists(file_name)
211+
assert self.aedtapp.existing_analysis_sweeps[0] == solution_name
212+
assert self.aedtapp.setup_names[0] == solution_name
213+
assert self.aedtapp.export_touchstone(solution_name, sweep_name)
207214

208215
def test_19A_create_sweeps(self):
209216
setup_name = "Sweep_LNA"

_unittest/test_41_3dlayout_modeler.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,8 +364,13 @@ def test_19B_analyze_setup(self):
364364
@pytest.mark.skipif(os.name == "posix", reason="To be investigated on linux.")
365365
def test_19C_export_touchsthone(self):
366366
filename = os.path.join(scratch_path, "touchstone.s2p")
367-
assert self.aedtapp.export_touchstone("RFBoardSetup3", "Last Adaptive", filename, [], [])
367+
solution_name = "RFBoardSetup3"
368+
sweep_name = "Last Adaptive"
369+
assert self.aedtapp.export_touchstone(solution_name, sweep_name, filename)
368370
assert os.path.exists(filename)
371+
assert self.aedtapp.export_touchstone(solution_name)
372+
sweep_name = None
373+
assert self.aedtapp.export_touchstone(solution_name, sweep_name)
369374

370375
def test_19D_export_to_hfss(self):
371376
with Scratch(scratch_path) as local_scratch:

pyaedt/application/Analysis.py

Lines changed: 130 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -928,21 +928,20 @@ def variations(self, setup_sweep=None):
928928
929929
>>> oModule.GetAvailableVariations
930930
"""
931-
if not setup_sweep:
932-
setup_sweep = self._app.existing_analysis_sweeps[0]
933-
vs = self._app.osolution.GetAvailableVariations(setup_sweep)
931+
vs = self.get_variation_strings(setup_sweep)
934932
families = []
935-
for v in vs:
936-
variations = v.split(" ")
937-
family = []
938-
for el in self.variables:
939-
family.append(el + ":=")
940-
i = 0
941-
while i < len(variations):
942-
if variations[i][0 : len(el)] == el:
943-
family.append([variations[i][len(el) + 2 : -1]])
944-
i += 1
945-
families.append(family)
933+
if vs:
934+
for v in vs:
935+
variations = v.split(" ")
936+
family = []
937+
for el in self.variables:
938+
family.append(el + ":=")
939+
i = 0
940+
while i < len(variations):
941+
if variations[i][0 : len(el)] == el:
942+
family.append([variations[i][len(el) + 2 : -1]])
943+
i += 1
944+
families.append(family)
946945
return families
947946

948947
@pyaedt_function_handler()
@@ -1709,3 +1708,120 @@ def submit_job(
17091708
f1.write(line)
17101709
f1.close()
17111710
return self.odesktop.SubmitJob(os.path.join(project_path, "Job_settings.areg"), project_file)
1711+
1712+
@pyaedt_function_handler()
1713+
def _export_touchstone(
1714+
self, solution_name=None, sweep_name=None, file_name=None, variations=None, variations_value=None
1715+
):
1716+
"""Export the Touchstone file to a local folder.
1717+
1718+
Parameters
1719+
----------
1720+
solution_name : str, optional
1721+
Name of the solution that has been solved.
1722+
sweep_name : str, optional
1723+
Name of the sweep that has been solved.
1724+
This parameter has to be ignored or set with same value as solution_name
1725+
file_name : str, optional
1726+
Full path and name for the Touchstone file. The default is ``None``,
1727+
which exports the file to the working directory.
1728+
variations : list, optional
1729+
List of all parameter variations. For example, ``["$AmbientTemp", "$PowerIn"]``.
1730+
The default is ``None``.
1731+
variations_value : list, optional
1732+
List of all parameter variation values. For example, ``["22cel", "100"]``.
1733+
The default is ``None``.
1734+
1735+
Returns
1736+
-------
1737+
bool
1738+
``True`` when successful, ``False`` when failed.
1739+
"""
1740+
if variations is None:
1741+
variations = list(self.available_variations.nominal_w_values_dict.keys())
1742+
if variations_value is None:
1743+
variations_value = [str(x) for x in list(self.available_variations.nominal_w_values_dict.values())]
1744+
1745+
if solution_name is None:
1746+
nominal_sweep_list = [x.strip() for x in self.nominal_sweep.split(":")]
1747+
solution_name = nominal_sweep_list[0]
1748+
if self.design_type == "Circuit Design":
1749+
sweep_name = solution_name
1750+
else:
1751+
if sweep_name is None:
1752+
for sol in self.existing_analysis_sweeps:
1753+
if solution_name == sol.split(":")[0].strip():
1754+
sweep_name = sol.split(":")[1].strip()
1755+
break
1756+
1757+
if self.design_type == "HFSS 3D Layout Design":
1758+
n = str(len(self.port_list))
1759+
else:
1760+
n = str(len(self.excitations))
1761+
# Normalize the save path
1762+
if not file_name:
1763+
appendix = ""
1764+
for v, vv in zip(variations, variations_value):
1765+
appendix += "_" + v + vv.replace("'", "")
1766+
ext = ".S" + n + "p"
1767+
filename = os.path.join(self.working_directory, solution_name + "_" + sweep_name + appendix + ext)
1768+
else:
1769+
filename = file_name.replace("//", "/").replace("\\", "/")
1770+
self.logger.info("Exporting Touchstone " + filename)
1771+
DesignVariations = ""
1772+
for i in range(len(variations)):
1773+
DesignVariations += str(variations[i]) + "='" + str(variations_value[i].replace("'", "")) + "' "
1774+
# DesignVariations = "$AmbientTemp=\'22cel\' $PowerIn=\'100\'"
1775+
# array containing "SetupName:SolutionName" pairs (note that setup and solution are separated by a colon)
1776+
SolutionSelectionArray = [solution_name + ":" + sweep_name]
1777+
# 2=tab delimited spreadsheet (.tab), 3= touchstone (.sNp), 4= CitiFile (.cit),
1778+
# 7=Matlab (.m), 8=Terminal Z0 spreadsheet
1779+
FileFormat = 3
1780+
OutFile = filename # full path of output file
1781+
# array containin the frequencies to export, use ["all"] for all frequencies
1782+
FreqsArray = ["all"]
1783+
DoRenorm = True # perform renormalization before export
1784+
RenormImped = 50 # Real impedance value in ohm, for renormalization
1785+
DataType = "S" # Type: "S", "Y", or "Z" matrix to export
1786+
Pass = -1 # The pass to export. -1 = export all passes.
1787+
ComplexFormat = 0 # 0=Magnitude/Phase, 1=Real/Immaginary, 2=dB/Phase
1788+
DigitsPrecision = 15 # Touchstone number of digits precision
1789+
IncludeGammaImpedance = True # Include Gamma and Impedance in comments
1790+
NonStandardExtensions = False # Support for non-standard Touchstone extensions
1791+
1792+
if self.design_type == "HFSS":
1793+
self.osolution.ExportNetworkData(
1794+
DesignVariations,
1795+
SolutionSelectionArray,
1796+
FileFormat,
1797+
OutFile,
1798+
FreqsArray,
1799+
DoRenorm,
1800+
RenormImped,
1801+
DataType,
1802+
Pass,
1803+
ComplexFormat,
1804+
DigitsPrecision,
1805+
False,
1806+
IncludeGammaImpedance,
1807+
NonStandardExtensions,
1808+
)
1809+
else:
1810+
self.odesign.ExportNetworkData(
1811+
DesignVariations,
1812+
SolutionSelectionArray,
1813+
FileFormat,
1814+
OutFile,
1815+
FreqsArray,
1816+
DoRenorm,
1817+
RenormImped,
1818+
DataType,
1819+
Pass,
1820+
ComplexFormat,
1821+
DigitsPrecision,
1822+
False,
1823+
IncludeGammaImpedance,
1824+
NonStandardExtensions,
1825+
)
1826+
self.logger.info("Touchstone correctly exported to %s", filename)
1827+
return True

pyaedt/application/Analysis3D.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -798,3 +798,36 @@ def assignmaterial_from_sherlock_files(self, csv_component, csv_material):
798798
i += 1
799799
all_objs = [ao for ao in all_objs if ao not in list_mat_obj]
800800
return True
801+
802+
@pyaedt_function_handler()
803+
def cleanup_solution(self, variations="All", entire_solution=True, field=True, mesh=True, linked_data=True):
804+
"""Delete a set of Solution Variations or part of them.
805+
806+
Parameters
807+
----------
808+
variations : List, str, optional
809+
All variations to delete. Default is `"All"` which deletes all available solutions.
810+
entire_solution : bool, optional
811+
Either if delete entire Solution or part of it. If `True` other booleans will be ignored
812+
as solution will be entirely deleted.
813+
field : bool, optional
814+
Either if delete entire Fields of variation or not. Default is `True`.
815+
mesh : bool, optional
816+
Either if delete entire Mesh of variation or not. Default is `True`.
817+
linked_data : bool, optional
818+
Either if delete entire Linked Data of variation or not. Default is `True`.
819+
820+
Returns
821+
-------
822+
bool
823+
`True` if Delete operation succeeded.
824+
"""
825+
if isinstance(variations, str):
826+
variations = [variations]
827+
if entire_solution:
828+
self.odesign.DeleteFullVariation(variations, linked_data)
829+
elif field:
830+
self.odesign.DeleteFieldVariation(variations, mesh, linked_data)
831+
elif linked_data:
832+
self.odesign.DeleteLinkedDataVariation(variations)
833+
return True

pyaedt/circuit.py

Lines changed: 15 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -762,19 +762,21 @@ def import_touchstone_solution(self, filename, solution_name="Imported_Data"):
762762
return portnames
763763

764764
@pyaedt_function_handler()
765-
def export_touchstone(self, solutionname, sweepname, filename=None, variation=None, variations_value=None):
765+
def export_touchstone(
766+
self, solution_name=None, sweep_name=None, file_name=None, variations=None, variations_value=None
767+
):
766768
"""Export the Touchstone file to a local folder.
767769
768770
Parameters
769771
----------
770-
solutionname : str
772+
solution_name : str, optional
771773
Name of the solution that has been solved.
772-
sweepname : str
774+
sweep_name : str, optional
773775
Name of the sweep that has been solved.
774-
filename : str, optional
775-
Full path and name for the Touchstone file. The default is ``None``,
776-
which exports the file to the working directory.
777-
variation : list, optional
776+
file_name : str, optional
777+
Full path and name for the Touchstone file.
778+
The default is ``None``, in which case the file is exported to the working directory.
779+
variations : list, optional
778780
List of all parameter variations. For example, ``["$AmbientTemp", "$PowerIn"]``.
779781
The default is ``None``.
780782
variations_value : list, optional
@@ -791,62 +793,13 @@ def export_touchstone(self, solutionname, sweepname, filename=None, variation=No
791793
792794
>>> oDesign.ExportNetworkData
793795
"""
794-
if variation == None:
795-
variation = []
796-
if variations_value == None:
797-
variations_value = []
798-
799-
# Normalize the save path
800-
if not filename:
801-
appendix = ""
802-
for v, vv in zip(variation, variations_value):
803-
appendix += "_" + v + vv.replace("'", "")
804-
ext = ".S" + str(self.oboundary.GetNumExcitations()) + "p"
805-
filename = os.path.join(self.working_directory, solutionname + "_" + sweepname + appendix + ext)
806-
else:
807-
filename = filename.replace("//", "/").replace("\\", "/")
808-
self.logger.info("Exporting Touchstone " + filename)
809-
DesignVariations = ""
810-
i = 0
811-
for el in variation:
812-
DesignVariations += str(variation[i]) + "='" + str(variations_value[i].replace("'", "")) + "' "
813-
i += 1
814-
# DesignVariations = "$AmbientTemp=\'22cel\' $PowerIn=\'100\'"
815-
# array containing "SetupName:SolutionName" pairs (note that setup and solution are separated by a colon)
816-
SolutionSelectionArray = [solutionname + ":" + sweepname]
817-
# 2=tab delimited spreadsheet (.tab), 3= touchstone (.sNp), 4= CitiFile (.cit),
818-
# 7=Matlab (.m), 8=Terminal Z0 spreadsheet
819-
FileFormat = 3
820-
OutFile = filename # full path of output file
821-
# array containin the frequencies to export, use ["all"] for all frequencies
822-
FreqsArray = ["all"]
823-
DoRenorm = True # perform renormalization before export
824-
RenormImped = 50 # Real impedance value in ohm, for renormalization
825-
DataType = "S" # Type: "S", "Y", or "Z" matrix to export
826-
Pass = -1 # The pass to export. -1 = export all passes.
827-
ComplexFormat = 0 # 0=Magnitude/Phase, 1=Real/Immaginary, 2=dB/Phase
828-
DigitsPrecision = 15 # Touchstone number of digits precision
829-
IncludeGammaImpedance = True # Include Gamma and Impedance in comments
830-
NonStandardExtensions = False # Support for non-standard Touchstone extensions
831-
832-
self.odesign.ExportNetworkData(
833-
DesignVariations,
834-
SolutionSelectionArray,
835-
FileFormat,
836-
OutFile,
837-
FreqsArray,
838-
DoRenorm,
839-
RenormImped,
840-
DataType,
841-
Pass,
842-
ComplexFormat,
843-
DigitsPrecision,
844-
False,
845-
IncludeGammaImpedance,
846-
NonStandardExtensions,
796+
return self._export_touchstone(
797+
solution_name=solution_name,
798+
sweep_name=sweep_name,
799+
file_name=file_name,
800+
variations=variations,
801+
variations_value=variations_value,
847802
)
848-
self.logger.info("Touchstone correctly exported to %s", filename)
849-
return True
850803

851804
@pyaedt_function_handler()
852805
def export_fullwave_spice(

0 commit comments

Comments
 (0)