Skip to content

Commit e848dab

Browse files
maxcapodi78maxcapodi78
authored andcommitted
Added Model properties to Circuit Component with update method
Improved export_profile and export_convergence method to support Q3d and Q2D custom methods.
1 parent c0aafac commit e848dab

File tree

10 files changed

+6617
-26
lines changed

10 files changed

+6617
-26
lines changed

_unittest/example_models/via_gsg.aedt

Lines changed: 6321 additions & 0 deletions
Large diffs are not rendered by default.

_unittest/test_12_PostProcessing.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
from _unittest.conftest import config
66
from pyaedt import Circuit
77
from pyaedt import Hfss
8+
from pyaedt import Q2d
9+
from pyaedt import Q3d
810
from pyaedt.generic.general_methods import is_ironpython
911

1012
# Import required modules
@@ -26,6 +28,7 @@
2628
test_field_name = "Potter_Horn"
2729
test_circuit_name = "Switching_Speed_FET_And_Diode"
2830
sbr_file = "poc_scat_small"
31+
q3d_file = "via_gsg"
2932

3033

3134
class TestClass(BasisTest, object):
@@ -39,6 +42,8 @@ def setup_class(self):
3942
)
4043
self.diff_test = Circuit(designname="diff", projectname=self.circuit_test.project_name)
4144
self.sbr_test = BasisTest.add_app(self, project_name=sbr_file)
45+
self.q3dtest = BasisTest.add_app(self, project_name=q3d_file, application=Q3d)
46+
self.q2dtest = Q2d(projectname=q3d_file)
4247

4348
def teardown_class(self):
4449
BasisTest.my_teardown(self)
@@ -426,3 +431,13 @@ def test_55_time_plot(self):
426431
show=False,
427432
)
428433
assert os.path.exists(os.path.join(self.sbr_test.working_directory, "animation.gif"))
434+
435+
def test_56_test_export_q3d_results(self):
436+
self.q3dtest.analyze_nominal()
437+
assert os.path.exists(self.q3dtest.export_convergence("Setup1"))
438+
assert os.path.exists(self.q3dtest.export_profile("Setup1"))
439+
440+
def test_57_test_export_q2d_results(self):
441+
self.q2dtest.analyze_nominal()
442+
assert os.path.exists(self.q2dtest.export_convergence("Setup1"))
443+
assert os.path.exists(self.q2dtest.export_profile("Setup1"))

_unittest/test_21_Circuit.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,8 @@ def test_24_new_connect_components(self):
289289
mycap = self.aedtapp.modeler.components.create_capacitor("C100", 1e-12)
290290
myind2 = self.aedtapp.modeler.components.create_inductor("L101", 1e-9)
291291
port = self.aedtapp.modeler.components.create_interface_port("Port1")
292+
assert not myind2.model_name
293+
assert not myind2.model_data
292294
assert self.aedtapp.modeler.schematic.connect_components_in_series([myind, myres.composed_name])
293295
assert self.aedtapp.modeler.schematic.connect_components_in_parallel([mycap, port, myind2.id])
294296

@@ -298,8 +300,13 @@ def test_25_import_model(self):
298300
t1 = self.aedtapp.modeler.schematic.create_touchsthone_component(touch)
299301
assert t1
300302
assert len(t1.pins) == 6
303+
assert t1.model_data
304+
t1.model_data.props["NexximCustomization"]["Passivity"] = 7
305+
assert t1.model_data.update()
301306
t2 = self.aedtapp.modeler.schematic.create_touchsthone_component(touch)
302307
assert t2
308+
t2.model_data.props["NexximCustomization"]["Passivity"] = 0
309+
assert t2.model_data.update()
303310

304311
def test_25_zoom_to_fit(self):
305312
self.aedtapp.insert_design("zoom_test")

examples/05-Q3D/Q2D_Example_Stripline.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,11 +178,11 @@
178178

179179
# Create parametric sweep and analyze
180180

181-
parametric = q.parametrics.add({"sig_bot_w": "LIN 75um 100um 5um"})
181+
parametric = q.parametrics.add("sig_bot_w", 75, 100, 5, "LinearStep")
182182
parametric.add_variation("sig_gap", "100um", "200um", 5,variation_type="LinearCount")
183183
q.analyze_setup(name=parametric.name)
184184

185185
###############################################################################
186186
# Save the project and exit
187187
q.save_project()
188-
q.close_desktop()
188+
q.release_desktop()

pyaedt/aedt_logger.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import logging
22
import sys
33

4+
from pyaedt import is_ironpython
45
from pyaedt import log_handler
56
from pyaedt import settings
67

7-
88
message_levels = {"Global": 0, "Project": 1, "Design": 2}
99

1010

@@ -124,6 +124,8 @@ def __init__(self, level=logging.DEBUG, filename=None, to_stdout=False):
124124
self.level = level
125125
self.filename = filename or settings.logger_file_path
126126
settings.logger_file_path = self.filename
127+
if is_ironpython:
128+
logging.basicConfig()
127129
self._global = logging.getLogger("Global")
128130
self._file_handler = None
129131
self._std_out_handler = None

pyaedt/application/Analysis.py

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,8 @@ def export_results(self, analyze=False, export_folder=None):
676676
excitations = len(self.oexcitation.GetAllPortsList())
677677
elif self.design_type == "2D Extractor":
678678
excitations = self.oboundary.GetNumExcitations("SignalLine")
679+
elif self.design_type == "Q3D Extractor":
680+
excitations = self.oboundary.GetNumExcitations("Source")
679681
else:
680682
excitations = self.oboundary.GetNumExcitations()
681683
reportnames = self.post.oreportsetup.GetAllReportNames()
@@ -685,8 +687,11 @@ def export_results(self, analyze=False, export_folder=None):
685687
export_path = os.path.join(
686688
export_folder, "{0}_{1}_{2}.csv".format(self.project_name, self.design_name, name_no_space)
687689
)
688-
self.post.oreportsetup.ExportToFile(str(report_name), export_path)
689-
self.logger.info("Export Data: {}".format(export_path))
690+
try:
691+
self.post.oreportsetup.ExportToFile(str(report_name), export_path)
692+
self.logger.info("Export Data: {}".format(export_path))
693+
except:
694+
pass
690695
exported_files.append(export_path)
691696

692697
for s in setups:
@@ -800,8 +805,43 @@ def export_convergence(self, setup_name, variation_string="", file_path=None):
800805
"""
801806
if not file_path:
802807
file_path = os.path.join(self.working_directory, generate_unique_name("Convergence") + ".prop")
803-
self.odesign.ExportConvergence(setup_name, variation_string, file_path)
804-
self.logger.info("Export Convergence to %s", file_path)
808+
if not variation_string:
809+
val_str = []
810+
for el, val in self.available_variations.nominal_w_values_dict.items():
811+
val_str.append("{}={}".format(el, val))
812+
variation_string = ",".join(val_str)
813+
if self.design_type == "2D Extractor":
814+
for setup in self.setups:
815+
if setup.name == setup_name:
816+
if "CGDataBlock" in setup.props:
817+
file_path = os.path.splitext(file_path)[0] + "CG" + os.path.splitext(file_path)[1]
818+
self.odesign.ExportConvergence(setup_name, variation_string, "CG", file_path, True)
819+
self.logger.info("Export Convergence to %s", file_path)
820+
if "RLDataBlock" in setup.props:
821+
file_path = os.path.splitext(file_path)[0] + "RL" + os.path.splitext(file_path)[1]
822+
self.odesign.ExportConvergence(setup_name, variation_string, "RL", file_path, True)
823+
self.logger.info("Export Convergence to %s", file_path)
824+
825+
break
826+
elif self.design_type == "Q3D Extractor":
827+
for setup in self.setups:
828+
if setup.name == setup_name:
829+
if "Cap" in setup.props:
830+
file_path = os.path.splitext(file_path)[0] + "CG" + os.path.splitext(file_path)[1]
831+
self.odesign.ExportConvergence(setup_name, variation_string, "CG", file_path, True)
832+
self.logger.info("Export Convergence to %s", file_path)
833+
if "AC" in setup.props:
834+
file_path = os.path.splitext(file_path)[0] + "ACRL" + os.path.splitext(file_path)[1]
835+
self.odesign.ExportConvergence(setup_name, variation_string, "AC RL", file_path, True)
836+
self.logger.info("Export Convergence to %s", file_path)
837+
if "DC" in setup.props:
838+
file_path = os.path.splitext(file_path)[0] + "DC" + os.path.splitext(file_path)[1]
839+
self.odesign.ExportConvergence(setup_name, variation_string, "DC RL", file_path, True)
840+
self.logger.info("Export Convergence to %s", file_path)
841+
break
842+
else:
843+
self.odesign.ExportConvergence(setup_name, variation_string, file_path)
844+
self.logger.info("Export Convergence to %s", file_path)
805845
return file_path
806846

807847
@pyaedt_function_handler()

pyaedt/application/Design.py

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1145,13 +1145,49 @@ def export_profile(self, setup_name, variation_string="", file_path=None):
11451145
11461146
>>> oDesign.ExportProfile
11471147
"""
1148+
11481149
if not file_path:
11491150
file_path = os.path.join(self.working_directory, generate_unique_name("Profile") + ".prop")
1150-
try:
1151-
self.odesign.ExportProfile(setup_name, variation_string, file_path)
1152-
except:
1153-
self.odesign.ExportProfile(setup_name, variation_string, file_path, True)
1154-
self.logger.info("Exported Profile to file {}".format(file_path))
1151+
if not variation_string:
1152+
val_str = []
1153+
for el, val in self.available_variations.nominal_w_values_dict.items():
1154+
val_str.append("{}={}".format(el, val))
1155+
variation_string = ",".join(val_str)
1156+
if self.design_type == "2D Extractor":
1157+
for setup in self.setups:
1158+
if setup.name == setup_name:
1159+
if "CGDataBlock" in setup.props:
1160+
file_path = os.path.splitext(file_path)[0] + "CG" + os.path.splitext(file_path)[1]
1161+
self.odesign.ExportProfile(setup_name, variation_string, "CG", file_path, True)
1162+
self.logger.info("Exported Profile to file {}".format(file_path))
1163+
if "RLDataBlock" in setup.props:
1164+
file_path = os.path.splitext(file_path)[0] + "RL" + os.path.splitext(file_path)[1]
1165+
self.odesign.ExportProfile(setup_name, variation_string, "RL", file_path, True)
1166+
self.logger.info("Exported Profile to file {}".format(file_path))
1167+
break
1168+
elif self.design_type == "Q3D Extractor":
1169+
for setup in self.setups:
1170+
if setup.name == setup_name:
1171+
if "Cap" in setup.props:
1172+
file_path = os.path.splitext(file_path)[0] + "CG" + os.path.splitext(file_path)[1]
1173+
self.odesign.ExportProfile(setup_name, variation_string, "CG", file_path, True)
1174+
self.logger.info("Exported Profile to file {}".format(file_path))
1175+
if "AC" in setup.props:
1176+
file_path = os.path.splitext(file_path)[0] + "ACRL" + os.path.splitext(file_path)[1]
1177+
self.odesign.ExportProfile(setup_name, variation_string, "AC RL", file_path, True)
1178+
self.logger.info("Exported Profile to file {}".format(file_path))
1179+
if "DC" in setup.props:
1180+
file_path = os.path.splitext(file_path)[0] + "DC" + os.path.splitext(file_path)[1]
1181+
self.odesign.ExportProfile(setup_name, variation_string, "DC RL", file_path, True)
1182+
self.logger.info("Exported Profile to file {}".format(file_path))
1183+
1184+
break
1185+
else:
1186+
try:
1187+
self.odesign.ExportProfile(setup_name, variation_string, file_path)
1188+
except:
1189+
self.odesign.ExportProfile(setup_name, variation_string, file_path, True)
1190+
self.logger.info("Exported Profile to file {}".format(file_path))
11551191
return file_path
11561192

11571193
@pyaedt_function_handler()

pyaedt/desktop.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@
4545
IsWindows = True
4646
else:
4747
IsWindows = False
48-
logger = logging.getLogger(__name__)
4948

5049
if is_ironpython:
5150
import clr # IronPython C:\Program Files\AnsysEM\AnsysEM19.4\Win64\common\IronPython\ipy64.exe
@@ -170,6 +169,8 @@ def force_close_desktop():
170169
"""
171170
Module = sys.modules["__main__"]
172171
pid = Module.oDesktop.GetProcessID()
172+
logger = logging.getLogger(__name__)
173+
173174
if pid > 0:
174175
try:
175176
projects = Module.oDesktop.GetProjectList()

pyaedt/generic/general_methods.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,6 @@
1414
from collections import OrderedDict
1515
from functools import update_wrapper
1616

17-
try:
18-
logger = logging.getLogger("Global")
19-
except:
20-
logger = logging.getLogger(__name__)
2117
is_ironpython = "IronPython" in sys.version or ".NETFramework" in sys.version
2218
_pythonver = sys.version_info[0]
2319
inside_desktop = True
@@ -42,12 +38,8 @@ class MethodNotSupportedError(Exception):
4238
def _write_mes(mes_text):
4339
mes_text = str(mes_text)
4440
parts = [mes_text[i : i + 250] for i in range(0, len(mes_text), 250)]
45-
if logger:
46-
for el in parts:
47-
logger.error(el)
48-
elif settings.enable_screen_logs:
49-
for el in parts:
50-
print(el)
41+
for el in parts:
42+
settings.logger.error(el)
5143

5244

5345
def _exception(ex_info, func, args, kwargs, message="Type Error"):
@@ -212,7 +204,7 @@ def _log_method(func, new_args, new_kwargs):
212204
if new_kwargs:
213205
message.append(line_begin2 + str(new_kwargs)[1:-1])
214206
for m in message:
215-
logger.debug(m)
207+
settings.logger.debug(m)
216208

217209

218210
def pyaedt_function_handler(direct_func=None):
@@ -286,7 +278,7 @@ def wrapper(*args, **kwargs):
286278
print("**************************************************************")
287279
print("")
288280
if settings.enable_file_logs:
289-
logger.error(message)
281+
settings.logger.error(message)
290282
return False
291283
except BaseException:
292284
_exception(sys.exc_info(), user_function, args, kwargs, "General or AEDT Error")
@@ -682,6 +674,14 @@ def __init__(self):
682674
self._non_graphical = False
683675
self.aedt_version = None
684676

677+
@property
678+
def logger(self):
679+
"""Return the active logger."""
680+
try:
681+
return logging.getLogger("Global")
682+
except:
683+
return logging.getLogger(__name__)
684+
685685
@property
686686
def non_graphical(self):
687687
"""Return the non graphical flag."""

0 commit comments

Comments
 (0)