From 61f1bf24f4fe4e6c9d8eaf46df824c4003bf600b Mon Sep 17 00:00:00 2001 From: Lorenzo Vecchietti <58366962+lorenzovecchietti@users.noreply.github.com> Date: Fri, 26 Apr 2024 14:45:42 +0200 Subject: [PATCH 1/5] Enhance docstring+fix backward compatiblity manipulation (#4585) Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- _unittest/test_09_Primitives2D.py | 8 +++- pyaedt/generic/configurations.py | 4 +- pyaedt/modeler/cad/Primitives2D.py | 15 +++++--- pyaedt/modules/MeshIcepak.py | 60 +++++++++++++++++++++++++----- 4 files changed, 67 insertions(+), 20 deletions(-) diff --git a/_unittest/test_09_Primitives2D.py b/_unittest/test_09_Primitives2D.py index 4cd695c39d1..1f5965accdd 100644 --- a/_unittest/test_09_Primitives2D.py +++ b/_unittest/test_09_Primitives2D.py @@ -74,10 +74,14 @@ def test_06_create_region(self): if self.aedtapp.modeler["Region"]: self.aedtapp.modeler.delete("Region") assert "Region" not in self.aedtapp.modeler.object_names - assert self.aedtapp.modeler.create_region([20, "50", "100mm", 20], False) + assert self.aedtapp.modeler.create_region([20, "50", "100mm", 20], "Absolute Offset") self.aedtapp.modeler["Region"].delete() - region = self.aedtapp.modeler.create_region("100", True) + region = self.aedtapp.modeler.create_region("100", "Percentage Offset") region.delete() + # test backward compatibility + region = self.aedtapp.modeler.create_region(pad_percent=[100, 10, 5, 2], pad_type=True) + region.delete() + # region = self.aedtapp.modeler.create_region([100, 100, 100, 100]) assert region.solve_inside assert region.model diff --git a/pyaedt/generic/configurations.py b/pyaedt/generic/configurations.py index 8a3170a6b60..f6ba8b0381e 100644 --- a/pyaedt/generic/configurations.py +++ b/pyaedt/generic/configurations.py @@ -1673,7 +1673,7 @@ def _export_objects_properties(self, dict_out): def _export_mesh_operations(self, dict_out): dict_out["mesh"] = {} args = ["NAME:Settings"] - args += self._app.mesh.global_mesh_region.settings.parse_settings() + args += self._app.mesh.global_mesh_region.settings.parse_settings_as_args() mop = OrderedDict({}) _arg2dict(args, mop) dict_out["mesh"]["Settings"] = mop["Settings"] @@ -1683,7 +1683,7 @@ def _export_mesh_operations(self, dict_out): args = ["NAME:Settings"] else: args = ["NAME:" + mesh.name, "Enable:=", mesh.Enable] - args += mesh.settings.parse_settings() + args += mesh.settings.parse_settings_as_args() args += getattr(mesh, "_parse_assignment_value")() args += ["UserSpecifiedSettings:=", not mesh.manual_settings] mop = OrderedDict({}) diff --git a/pyaedt/modeler/cad/Primitives2D.py b/pyaedt/modeler/cad/Primitives2D.py index 0d640ea7724..dbf284685a5 100644 --- a/pyaedt/modeler/cad/Primitives2D.py +++ b/pyaedt/modeler/cad/Primitives2D.py @@ -287,7 +287,8 @@ def create_region(self, pad_value=300, pad_type="Percentage Offset", name="Regio Padding values to apply. If a list is not provided, the same value is applied to all padding directions. If a list of floats or strings is provided, the values are - interpreted as padding for ``["+X", "-X", "+Y", "-Y", "+Z", "-Z"]``. + interpreted as padding for ``["+X", "-X", "+Y", "-Y"]`` for XY geometry mode, + and ``["+R", "+Z", "-Z"]`` for RZ geometry mode. pad_type : str, optional Padding definition. The default is ``"Percentage Offset"``. Options are ``"Absolute Offset"``, @@ -318,24 +319,26 @@ def create_region(self, pad_value=300, pad_type="Percentage Offset", name="Regio if kwarg.get("pad_percent", False): pad_percent = kwarg["pad_percent"] pad_value = pad_percent - if isinstance(pad_value, list) and len(pad_value) < 6: - pad_value = [pad_value[i // 2 + 3 * (i % 2)] for i in range(6)] + if isinstance(pad_value, list) and len(pad_value) == 4: + pad_value = [pad_value[i // 2 + 2 * (i % 2)] for i in range(4)] pad_type = ["Absolute Offset", "Percentage Offset"][int(is_percentage)] if isinstance(pad_type, bool): pad_type = ["Absolute Offset", "Percentage Offset"][int(pad_type)] - if not isinstance(pad_value, list): - pad_value = [pad_value] * 4 if self._app.design_type == "2D Extractor" or ( self._app.design_type == "Maxwell 2D" and self._app.odesign.GetGeometryMode() == "XY" ): + if not isinstance(pad_value, list): + pad_value = [pad_value] * 4 if len(pad_value) != 4: self.logger.error("Wrong padding list provided. Four values have to be provided.") return False pad_value = [pad_value[0], pad_value[2], pad_value[1], pad_value[3], 0, 0] else: - if len(pad_value) < 3: + if not isinstance(pad_value, list): + pad_value = [pad_value] * 3 + if len(pad_value) != 3: self.logger.error("Wrong padding list provided. Three values have to be provided for RZ geometry.") return False pad_value = [pad_value[0], 0, 0, 0, pad_value[1], pad_value[2]] diff --git a/pyaedt/modules/MeshIcepak.py b/pyaedt/modules/MeshIcepak.py index a0939fbae27..9712122c57c 100644 --- a/pyaedt/modules/MeshIcepak.py +++ b/pyaedt/modules/MeshIcepak.py @@ -274,7 +274,8 @@ def name(self): @name.setter def name(self, value): try: - self._app.modeler.objects_by_name[self._name].name = value + if self._app.modeler.objects_by_name[self._name].name != value: + self._app.modeler.objects_by_name[self._name].name = value except KeyError: if self._app.modeler.objects_by_name[value].history().command == "CreateSubRegion": self._name = value @@ -408,6 +409,13 @@ def parts(self, parts): class MeshSettings(object): + """ + Class for managing mesh settings. + + It can be used like a dictionary. Available keys change according + to the type of settings chosen (manual or automatic). + """ + _automatic_mesh_settings = {"MeshRegionResolution": 3} # min: 1, max: 5 _common_mesh_settings = { "ProximitySizeFunction": True, @@ -464,14 +472,14 @@ def _dim_arg(self, value): else: return _dim_arg(value, getattr(self._mesh_class, "_model_units")) - def parse_settings(self): + def parse_settings_as_args(self): """ Parse mesh region settings. Returns ------- - dict - List of strings containing all the parts that must be included in the subregion. + List + Arguments to pass to native APIs. """ out = [] for k, v in self._instance_settings.items(): @@ -481,6 +489,22 @@ def parse_settings(self): out.append(v) return out + def parse_settings_as_dictionary(self): + """ + Parse mesh region settings. + + Returns + ------- + dict + Settings of the subregion. + """ + out = {} + for k, v in self._instance_settings.items(): + if k in ["MaxElementSizeX", "MaxElementSizeY", "MaxElementSizeZ", "MinGapX", "MinGapY", "MinGapZ"]: + v = self._dim_arg(v) + out[k] = v + return out + def _key_in_dict(self, key): if self._mesh_class.manual_settings: ref_dict = self._manual_mesh_settings @@ -489,13 +513,29 @@ def _key_in_dict(self, key): return key in ref_dict or key in self._common_mesh_settings def keys(self): - return self.parse_settings().keys() + """ + Get mesh region settings keys. + + Returns + ------- + dict_keys + Available settings keys. + """ + return self.parse_settings_as_dictionary().keys() def values(self): - return self.parse_settings().values() + """ + Get mesh region settings values. + + Returns + ------- + dict_values + Settings values. + """ + return self.parse_settings_as_dictionary().values() def __repr__(self): - return repr(self.parse_settings()) + return repr(self.parse_settings_as_dictionary()) def __getitem__(self, key): if key == "Level": @@ -628,7 +668,7 @@ def update(self): >>> oModule.EditGlobalMeshRegion """ args = ["NAME:Settings"] - args += self.settings.parse_settings() + args += self.settings.parse_settings_as_args() args += ["UserSpecifiedSettings:=", self.manual_settings] try: self._app.omeshmodule.EditGlobalMeshRegion(args) @@ -754,7 +794,7 @@ def update(self): >>> oModule.EditMeshRegion """ args = ["NAME:" + self.name, "Enable:=", self.enable] - args += self.settings.parse_settings() + args += self.settings.parse_settings_as_args() args += self._parse_assignment_value() args += ["UserSpecifiedSettings:=", self.manual_settings] try: @@ -854,7 +894,7 @@ def create(self): self._app.logger.error("Cannot create a new mesh region with this Name") return False args = ["NAME:" + self.name, "Enable:=", self.enable] - args += self.settings.parse_settings() + args += self.settings.parse_settings_as_args() args += ["UserSpecifiedSettings:=", not self.manual_settings] args += self._parse_assignment_value() self._app.omeshmodule.AssignMeshRegion(args) From ed7dab2a3c3f720585cb26daebb0f45c6e90b530 Mon Sep 17 00:00:00 2001 From: gmalinve <103059376+gmalinve@users.noreply.github.com> Date: Fri, 26 Apr 2024 16:21:57 +0200 Subject: [PATCH 2/5] FIX: HFSS keyword argument deprecation (#4594) --- pyaedt/hfss.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pyaedt/hfss.py b/pyaedt/hfss.py index fd668db9f00..35e3bc7f001 100644 --- a/pyaedt/hfss.py +++ b/pyaedt/hfss.py @@ -1970,7 +1970,9 @@ def create_source_excitation(self, assignment, point1, point2, name, source_type props = OrderedDict({"Objects": [assignment], "Direction": OrderedDict({"Start": point1, "End": point2})}) return self._create_boundary(name, props, source_type) - @pyaedt_function_handler(face="assignment", nummodes="modes", portname="name", renorm="renormalize") + @pyaedt_function_handler( + face="assignment", nummodes="modes", portname="name", renorm="renormalize", deembed_dist="deembed_distance" + ) def create_floquet_port( self, assignment, From feb936993fe074a5b4426fe194ade554c6569837 Mon Sep 17 00:00:00 2001 From: Matthew Young <86373761+myoung301@users.noreply.github.com> Date: Fri, 26 Apr 2024 12:44:32 -0500 Subject: [PATCH 3/5] Fix active design selection behavior for Emit designs (#4587) --- _unittest_solvers/test_26_emit.py | 13 +++++++------ pyaedt/emit.py | 3 --- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/_unittest_solvers/test_26_emit.py b/_unittest_solvers/test_26_emit.py index 91cfc2b9fff..adabbac4cc8 100644 --- a/_unittest_solvers/test_26_emit.py +++ b/_unittest_solvers/test_26_emit.py @@ -7,6 +7,7 @@ import pytest from pyaedt import Emit +from pyaedt import generate_unique_project_name from pyaedt.emit_core.emit_constants import EmiCategoryFilter from pyaedt.emit_core.emit_constants import InterfererType from pyaedt.emit_core.emit_constants import ResultType @@ -373,7 +374,7 @@ def test_07_antenna_component(self, add_app): reason="Skipped on versions earlier than 2023.2", ) def test_08_revision_generation(self, add_app): - self.aedtapp = add_app(application=Emit) + self.aedtapp = add_app(application=Emit, project_name=generate_unique_project_name()) assert len(self.aedtapp.results.revisions) == 0 # place components and generate the appropriate number of revisions rad1 = self.aedtapp.modeler.components.create_component("UE - Handheld") @@ -443,7 +444,7 @@ def test_08_revision_generation(self, add_app): reason="Skipped on versions earlier than 2023.2", ) def test_09_manual_revision_access_test_getters(self, add_app): - self.aedtapp = add_app(application=Emit) + self.aedtapp = add_app(application=Emit, project_name=generate_unique_project_name()) rad1 = self.aedtapp.modeler.components.create_component("UE - Handheld") ant1 = self.aedtapp.modeler.components.create_component("Antenna") rad2 = self.aedtapp.modeler.components.create_component("Bluetooth") @@ -512,7 +513,7 @@ def test_09_manual_revision_access_test_getters(self, add_app): reason="Skipped on versions earlier than 2023.2", ) def test_10_radio_band_getters(self, add_app): - self.aedtapp = add_app(application=Emit) + self.aedtapp = add_app(application=Emit, project_name=generate_unique_project_name()) rad1, ant1 = self.aedtapp.modeler.components.create_radio_antenna("New Radio") rad2, ant2 = self.aedtapp.modeler.components.create_radio_antenna("Bluetooth Low Energy (LE)") rad3, ant3 = self.aedtapp.modeler.components.create_radio_antenna("WiFi - 802.11-2012") @@ -729,7 +730,7 @@ def test_14_version(self, add_app): reason="Skipped on versions earlier than 2023.2", ) def test_15_basic_run(self, add_app): - self.aedtapp = add_app(application=Emit) + self.aedtapp = add_app(application=Emit, project_name=generate_unique_project_name()) assert len(self.aedtapp.results.revisions) == 0 # place components and generate the appropriate number of revisions rad1 = self.aedtapp.modeler.components.create_component("UE - Handheld") @@ -811,7 +812,7 @@ def test_15_basic_run(self, add_app): reason="Skipped on versions earlier than 2024.1", ) def test_16_optimal_n_to_1_feature(self, add_app): - self.aedtapp = add_app(application=Emit) + self.aedtapp = add_app(application=Emit, project_name=generate_unique_project_name()) # place components and generate the appropriate number of revisions rad1 = self.aedtapp.modeler.components.create_component("Bluetooth") ant1 = self.aedtapp.modeler.components.create_component("Antenna") @@ -867,7 +868,7 @@ def test_16_optimal_n_to_1_feature(self, add_app): reason="Skipped on versions earlier than 2023.2", ) def test_17_availability_1_to_1(self, add_app): - self.aedtapp = add_app(application=Emit) + self.aedtapp = add_app(application=Emit, project_name=generate_unique_project_name()) # place components and generate the appropriate number of revisions rad1 = self.aedtapp.modeler.components.create_component("MD400C") ant1 = self.aedtapp.modeler.components.create_component("Antenna") diff --git a/pyaedt/emit.py b/pyaedt/emit.py index 70b37b3fa13..f67e403be6e 100644 --- a/pyaedt/emit.py +++ b/pyaedt/emit.py @@ -3,7 +3,6 @@ import warnings from pyaedt import emit_core -from pyaedt import generate_unique_project_name from pyaedt.application.Design import Design from pyaedt.emit_core.Couplings import CouplingsEmit from pyaedt.emit_core.emit_constants import EMIT_VALID_UNITS @@ -114,8 +113,6 @@ def __init__( port=0, aedt_process_id=None, ): - if projectname is None: - projectname = generate_unique_project_name() self.__emit_api_enabled = False self.results = None """Constructor for the ``FieldAnalysisEmit`` class""" From fe91a541349b7222b4d82955d86cbafbb4ccdcca Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Apr 2024 08:51:14 +0200 Subject: [PATCH 4/5] MAINT: Update pyedb requirement from <0.9,>=0.4.0 to >=0.4.0,<0.10 (#4596) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 02091f7a6a6..b3d60c5c275 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -50,7 +50,7 @@ tests = [ "pytest-cov>=4.0.0,<5.1", "pytest-xdist>=3.5.0,<3.7", "pyedb>=0.4.0,<0.9; python_version == '3.7'", - "pyedb>=0.5.0,<0.9; python_version > '3.7'", + "pyedb>=0.5.0,<0.10; python_version > '3.7'", "pyvista>=0.38.0,<0.44", "scikit-learn>=1.0.0,<1.5", "scikit-rf>=0.30.0,<1.1", From 7104268bacdd11c252257bdf1608b23f7e3660a3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Apr 2024 08:51:33 +0200 Subject: [PATCH 5/5] MAINT: Update ipython requirement from <8.24,>=7.30.0 to >=7.30.0,<8.25 (#4597) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index b3d60c5c275..6ea864fb060 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -70,7 +70,7 @@ doc = [ "imageio>=2.30.0,<2.35", #"imageio-ffmpeg>=0.4.0,<0.5", "ipython>=7.34.0; python_version == '3.7'", - "ipython>=8.13.0,<8.24; python_version > '3.7'", + "ipython>=8.13.0,<8.25; python_version > '3.7'", #"ipywidgets>=8.0.0,<8.2", "joblib>=1.3.0,<1.5", "jupyterlab>=4.0.0,<4.3",