From 08911a6e0fced4bf24b889980aad6a7ab90e2109 Mon Sep 17 00:00:00 2001 From: Devin Date: Sat, 14 Dec 2024 08:11:29 -0800 Subject: [PATCH 01/28] Fix MeshOperation.name when mesh op isn't defined. When a mesh operation wasn't defined in desktop, invkoking the name property thew an error in AEDT. --- src/ansys/aedt/core/application/design.py | 15 ++++++++++++--- src/ansys/aedt/core/modules/mesh.py | 5 ++++- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/ansys/aedt/core/application/design.py b/src/ansys/aedt/core/application/design.py index 67c5b19daf2..0f44f1b0de7 100644 --- a/src/ansys/aedt/core/application/design.py +++ b/src/ansys/aedt/core/application/design.py @@ -1412,9 +1412,18 @@ def get_oo_object(self, aedt_object, object_name): Aedt Object if Any. """ try: - return aedt_object.GetChildObject(object_name) - except Exception: - return False + # Retrieve the child object. If the child object doesn't exist, AEDT + # will throw an error. + if '/' in object_name: + child_names = aedt_object.GetChildNames(object_name.split('/')[0]) # Get names of valid objects. + if object_name in child_names: + return aedt_object.GetChildObject(object_name) + else: + return None + else: # Base objects like "Mesh" and "Boundaries" always exist. + return aedt_object.GetChildObject(object_name) + except AttributeError: + return None @pyaedt_function_handler() def get_oo_properties(self, aedt_object, object_name): diff --git a/src/ansys/aedt/core/modules/mesh.py b/src/ansys/aedt/core/modules/mesh.py index 19c54c21dca..b6f001cd49f 100644 --- a/src/ansys/aedt/core/modules/mesh.py +++ b/src/ansys/aedt/core/modules/mesh.py @@ -200,6 +200,8 @@ def name(self): self._name = self.properties["Name"] except KeyError: pass + except AttributeError: # If the mesh operation has not yet been defined in AEDT. + return self._name return self._name @name.setter @@ -1131,7 +1133,7 @@ def assign_length_mesh(self, assignment, inside_selection=True, maximum_length=1 assignment = self._modeler.convert_to_selections(assignment, True) if name: for m in self.meshoperations: - if name == m.name: + if name == m.name: # If the mesh operation name exists, find a new, unique name. name = generate_unique_name(name) else: name = generate_unique_name("length") @@ -1176,6 +1178,7 @@ def assign_length_mesh(self, assignment, inside_selection=True, maximum_length=1 ) mop = MeshOperation(self, name, props, "LengthBased") + # if hasattr(mop, "name"): for meshop in self.meshoperations[:]: if meshop.name == mop.name: meshop.delete() From 74bfde1ad58057fb2860eb0d3953671a9f7f1556 Mon Sep 17 00:00:00 2001 From: Devin Date: Sun, 15 Dec 2024 13:02:02 -0800 Subject: [PATCH 02/28] Update get_oo_object Fix issue because GetChildObject() method does not behave consistently among AEDT solvers. --- src/ansys/aedt/core/application/design.py | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/ansys/aedt/core/application/design.py b/src/ansys/aedt/core/application/design.py index 0f44f1b0de7..976a73bec8f 100644 --- a/src/ansys/aedt/core/application/design.py +++ b/src/ansys/aedt/core/application/design.py @@ -1411,19 +1411,26 @@ def get_oo_object(self, aedt_object, object_name): object Aedt Object if Any. """ + # Retrieve the child object. If the child object doesn't exist, AEDT + # will throw an error. try: - # Retrieve the child object. If the child object doesn't exist, AEDT - # will throw an error. + child_object = aedt_object.GetChildObject(object_name) + except: + child_object = None if '/' in object_name: child_names = aedt_object.GetChildNames(object_name.split('/')[0]) # Get names of valid objects. if object_name in child_names: - return aedt_object.GetChildObject(object_name) + child_object = aedt_object.GetChildObject(object_name) else: - return None - else: # Base objects like "Mesh" and "Boundaries" always exist. - return aedt_object.GetChildObject(object_name) - except AttributeError: + child_object = None + if not child_object: return None + else: + return child_object + #else: # Base objects like "Mesh" and "Boundaries" always exist. + # return aedt_object.GetChildObject(object_name) + #except AttributeError: + # return None @pyaedt_function_handler() def get_oo_properties(self, aedt_object, object_name): From 2f17d0281fb31241f36152f6c6a524e03df0a977 Mon Sep 17 00:00:00 2001 From: Devin Date: Sun, 15 Dec 2024 18:03:13 -0800 Subject: [PATCH 03/28] Update get_oo_object Fix issue because GetChildObject() method does not behave consistently among AEDT solvers. --- src/ansys/aedt/core/application/design.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/ansys/aedt/core/application/design.py b/src/ansys/aedt/core/application/design.py index 976a73bec8f..c82d7284c71 100644 --- a/src/ansys/aedt/core/application/design.py +++ b/src/ansys/aedt/core/application/design.py @@ -1415,9 +1415,9 @@ def get_oo_object(self, aedt_object, object_name): # will throw an error. try: child_object = aedt_object.GetChildObject(object_name) - except: + except Exception as e: # Exception type is always GRPC Error. child_object = None - if '/' in object_name: + if '/' in object_name: # Enable extraction of sub-objects using GetChildObject child_names = aedt_object.GetChildNames(object_name.split('/')[0]) # Get names of valid objects. if object_name in child_names: child_object = aedt_object.GetChildObject(object_name) @@ -1427,10 +1427,6 @@ def get_oo_object(self, aedt_object, object_name): return None else: return child_object - #else: # Base objects like "Mesh" and "Boundaries" always exist. - # return aedt_object.GetChildObject(object_name) - #except AttributeError: - # return None @pyaedt_function_handler() def get_oo_properties(self, aedt_object, object_name): From bcf15289ae9bc418a1da34e65cfe94262dcbb12c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2024 02:07:00 +0000 Subject: [PATCH 04/28] CHORE: Auto fixes from pre-commit.com hooks For more information, see https://pre-commit.ci --- src/ansys/aedt/core/application/design.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ansys/aedt/core/application/design.py b/src/ansys/aedt/core/application/design.py index c82d7284c71..f5a40c3bb8d 100644 --- a/src/ansys/aedt/core/application/design.py +++ b/src/ansys/aedt/core/application/design.py @@ -1417,8 +1417,8 @@ def get_oo_object(self, aedt_object, object_name): child_object = aedt_object.GetChildObject(object_name) except Exception as e: # Exception type is always GRPC Error. child_object = None - if '/' in object_name: # Enable extraction of sub-objects using GetChildObject - child_names = aedt_object.GetChildNames(object_name.split('/')[0]) # Get names of valid objects. + if "/" in object_name: # Enable extraction of sub-objects using GetChildObject + child_names = aedt_object.GetChildNames(object_name.split("/")[0]) # Get names of valid objects. if object_name in child_names: child_object = aedt_object.GetChildObject(object_name) else: From b168cade12b0ee42b14ab6def3d84814d208a0af Mon Sep 17 00:00:00 2001 From: Devin <38879940+Devin-Crawford@users.noreply.github.com> Date: Mon, 16 Dec 2024 11:49:17 -0600 Subject: [PATCH 05/28] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implemented code review suggestions. Co-authored-by: Sébastien Morais <146729917+SMoraisAnsys@users.noreply.github.com> --- src/ansys/aedt/core/modules/mesh.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/ansys/aedt/core/modules/mesh.py b/src/ansys/aedt/core/modules/mesh.py index b6f001cd49f..99dcd3c4293 100644 --- a/src/ansys/aedt/core/modules/mesh.py +++ b/src/ansys/aedt/core/modules/mesh.py @@ -198,10 +198,8 @@ def name(self): """ try: self._name = self.properties["Name"] - except KeyError: + except (KeyError, AttributeError): pass - except AttributeError: # If the mesh operation has not yet been defined in AEDT. - return self._name return self._name @name.setter @@ -1178,7 +1176,6 @@ def assign_length_mesh(self, assignment, inside_selection=True, maximum_length=1 ) mop = MeshOperation(self, name, props, "LengthBased") - # if hasattr(mop, "name"): for meshop in self.meshoperations[:]: if meshop.name == mop.name: meshop.delete() From e36795b705d1623f22361f709cf71dfa88bbe3cf Mon Sep 17 00:00:00 2001 From: Devin Date: Mon, 16 Dec 2024 11:49:58 -0600 Subject: [PATCH 06/28] Update get_oo_object Simplify syntax --- src/ansys/aedt/core/application/design.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/ansys/aedt/core/application/design.py b/src/ansys/aedt/core/application/design.py index c82d7284c71..c6368ddce86 100644 --- a/src/ansys/aedt/core/application/design.py +++ b/src/ansys/aedt/core/application/design.py @@ -1413,20 +1413,16 @@ def get_oo_object(self, aedt_object, object_name): """ # Retrieve the child object. If the child object doesn't exist, AEDT # will throw an error. + + child_object = None try: child_object = aedt_object.GetChildObject(object_name) except Exception as e: # Exception type is always GRPC Error. - child_object = None if '/' in object_name: # Enable extraction of sub-objects using GetChildObject child_names = aedt_object.GetChildNames(object_name.split('/')[0]) # Get names of valid objects. if object_name in child_names: child_object = aedt_object.GetChildObject(object_name) - else: - child_object = None - if not child_object: - return None - else: - return child_object + return child_object @pyaedt_function_handler() def get_oo_properties(self, aedt_object, object_name): From e92953851c2e83d2458f6d65056719619632ba6c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2024 17:57:12 +0000 Subject: [PATCH 07/28] CHORE: Auto fixes from pre-commit.com hooks For more information, see https://pre-commit.ci --- src/ansys/aedt/core/application/design.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ansys/aedt/core/application/design.py b/src/ansys/aedt/core/application/design.py index c6368ddce86..ca56216e31e 100644 --- a/src/ansys/aedt/core/application/design.py +++ b/src/ansys/aedt/core/application/design.py @@ -1418,8 +1418,8 @@ def get_oo_object(self, aedt_object, object_name): try: child_object = aedt_object.GetChildObject(object_name) except Exception as e: # Exception type is always GRPC Error. - if '/' in object_name: # Enable extraction of sub-objects using GetChildObject - child_names = aedt_object.GetChildNames(object_name.split('/')[0]) # Get names of valid objects. + if "/" in object_name: # Enable extraction of sub-objects using GetChildObject + child_names = aedt_object.GetChildNames(object_name.split("/")[0]) # Get names of valid objects. if object_name in child_names: child_object = aedt_object.GetChildObject(object_name) return child_object From 220de9e96c2f9407eea95c747f523eecf243edde Mon Sep 17 00:00:00 2001 From: Samuelopez-ansys Date: Wed, 18 Dec 2024 15:40:50 +0100 Subject: [PATCH 08/28] Update child object --- src/ansys/aedt/core/application/design.py | 14 ++---- .../aedt/core/modeler/cad/elements_3d.py | 18 ++++--- .../aedt/core/modules/boundary/common.py | 31 +++++++----- .../core/modules/boundary/hfss_boundary.py | 39 +++++++++++---- .../core/modules/boundary/layout_boundary.py | 43 +++++++++++------ .../core/modules/boundary/maxwell_boundary.py | 17 ++++--- src/ansys/aedt/core/modules/mesh.py | 48 +++++++++++++------ src/ansys/aedt/core/modules/solve_setup.py | 40 +++++++++++----- src/ansys/aedt/core/rmxprt.py | 4 +- tests/system/general/test_07_Object3D.py | 4 +- 10 files changed, 166 insertions(+), 92 deletions(-) diff --git a/src/ansys/aedt/core/application/design.py b/src/ansys/aedt/core/application/design.py index ca56216e31e..67c5b19daf2 100644 --- a/src/ansys/aedt/core/application/design.py +++ b/src/ansys/aedt/core/application/design.py @@ -1411,18 +1411,10 @@ def get_oo_object(self, aedt_object, object_name): object Aedt Object if Any. """ - # Retrieve the child object. If the child object doesn't exist, AEDT - # will throw an error. - - child_object = None try: - child_object = aedt_object.GetChildObject(object_name) - except Exception as e: # Exception type is always GRPC Error. - if "/" in object_name: # Enable extraction of sub-objects using GetChildObject - child_names = aedt_object.GetChildNames(object_name.split("/")[0]) # Get names of valid objects. - if object_name in child_names: - child_object = aedt_object.GetChildObject(object_name) - return child_object + return aedt_object.GetChildObject(object_name) + except Exception: + return False @pyaedt_function_handler() def get_oo_properties(self, aedt_object, object_name): diff --git a/src/ansys/aedt/core/modeler/cad/elements_3d.py b/src/ansys/aedt/core/modeler/cad/elements_3d.py index 4ed7b4f483e..5e80e4f8b92 100644 --- a/src/ansys/aedt/core/modeler/cad/elements_3d.py +++ b/src/ansys/aedt/core/modeler/cad/elements_3d.py @@ -1398,7 +1398,7 @@ def __init__(self, node, child_object, first_level=False, get_child_obj_arg=None if not root_name: root_name = node saved_root_name = node if first_level else root_name - self.node = node + self._node = node self.child_object = child_object self.children = {} self.auto_update = True @@ -1495,17 +1495,23 @@ def update_property(self, prop_name, prop_value): ``True`` when successful, ``False`` when failed. """ try: - self.child_object.SetPropValue(prop_name, prop_value) - return True + result = self.child_object.SetPropValue(prop_name, prop_value) + if result: + if prop_name == "Name" and getattr(self, "_name", False): + setattr(self, "_name", prop_value) + else: + # Property Name duplicated + raise KeyError except Exception: # pragma: no cover - return False + # Property read-only + raise KeyError @pyaedt_function_handler def _jsonalize_tree(self, binary_tree_node): childrend_dict = {} for _, node in binary_tree_node.children.items(): childrend_dict.update(self._jsonalize_tree(node)) - return {binary_tree_node.node: {"Props": binary_tree_node.properties, "Children": childrend_dict}} + return {binary_tree_node._node: {"Props": binary_tree_node.properties, "Children": childrend_dict}} @pyaedt_function_handler def jsonalize_tree(self): @@ -1526,7 +1532,7 @@ def _suppress(self, node, app, suppress): "NAME:AllTabs", [ "NAME:Geometry3DCmdTab", - ["NAME:PropServers", node.child_object.GetObjPath().split("/")[3] + ":" + node.node], + ["NAME:PropServers", node.child_object.GetObjPath().split("/")[3] + ":" + node._node], ["NAME:ChangedProps", ["NAME:Suppress Command", "Value:=", suppress]], ], ] diff --git a/src/ansys/aedt/core/modules/boundary/common.py b/src/ansys/aedt/core/modules/boundary/common.py index 8be386d7e31..7bd02a94cd5 100644 --- a/src/ansys/aedt/core/modules/boundary/common.py +++ b/src/ansys/aedt/core/modules/boundary/common.py @@ -240,28 +240,28 @@ def _child_object(self): if "Thermal" in design_childs: cc = self._app.get_oo_object(self._app.odesign, "Thermal") cc_names = self._app.get_oo_name(cc) - if self.name in cc_names: - child_object = cc.GetChildObject(self.name) + if self._name in cc_names: + child_object = cc.GetChildObject(self._name) elif "Boundaries" in design_childs: cc = self._app.get_oo_object(self._app.odesign, "Boundaries") - if self.name in cc.GetChildNames(): - child_object = cc.GetChildObject(self.name) - elif "Excitations" in design_childs and self.name in self._app.get_oo_name( + if self._name in cc.GetChildNames(): + child_object = cc.GetChildObject(self._name) + elif "Excitations" in design_childs and self._name in self._app.get_oo_name( self._app.odesign, "Excitations" ): - child_object = self._app.get_oo_object(self._app.odesign, "Excitations").GetChildObject(self.name) + child_object = self._app.get_oo_object(self._app.odesign, "Excitations").GetChildObject(self._name) elif self._app.design_type in ["Maxwell 3D", "Maxwell 2D"] and "Model" in design_childs: model = self._app.get_oo_object(self._app.odesign, "Model") - if self.name in model.GetChildNames(): - child_object = model.GetChildObject(self.name) + if self._name in model.GetChildNames(): + child_object = model.GetChildObject(self._name) elif "Excitations" in design_childs and self._app.get_oo_name(self._app.odesign, "Excitations"): for port in self._app.get_oo_name(self._app.odesign, "Excitations"): terminals = self._app.get_oo_name(self._app.odesign, f"Excitations\\{port}") - if self.name in terminals: - child_object = self._app.get_oo_object(self._app.odesign, f"Excitations\\{port}\\{self.name}") + if self._name in terminals: + child_object = self._app.get_oo_object(self._app.odesign, f"Excitations\\{port}\\{self._name}") elif "Conductors" in design_childs and self._app.get_oo_name(self._app.odesign, "Conductors"): for port in self._app.get_oo_name(self._app.odesign, "Conductors"): - if self.name == port: + if self._name == port: child_object = self._app.get_oo_object(self._app.odesign, f"Conductors\\{port}") return child_object @@ -312,12 +312,17 @@ def type(self, value): @property def name(self): """Boundary Name.""" + if self._child_object: + self._name = self.properties["Name"] return self._name @name.setter def name(self, value): - self._name = value - self.update() + if self._child_object: + try: + self.properties["Name"] = value + except KeyError: + self._app.logger.error("Name %s already assigned in the design", value) @pyaedt_function_handler() def _get_args(self, props=None): diff --git a/src/ansys/aedt/core/modules/boundary/hfss_boundary.py b/src/ansys/aedt/core/modules/boundary/hfss_boundary.py index 7cbab30d372..eec74a73450 100644 --- a/src/ansys/aedt/core/modules/boundary/hfss_boundary.py +++ b/src/ansys/aedt/core/modules/boundary/hfss_boundary.py @@ -52,9 +52,26 @@ def __init__(self, app, component_name, props, component_type): self._name = component_name self.__props = BoundaryProps(self, props) if props else {} self.auto_update = True - child_object = self._app.get_oo_object(self._app.odesign, f"Radiation/{self._name}") - if child_object: - BinaryTreeNode.__init__(self, self._name, child_object, False) + self._initialize_bynary_tree() + + @property + def _child_object(self): + """Object-oriented properties. + + Returns + ------- + class:`ansys.aedt.core.modeler.cad.elements_3d.BinaryTreeNode` + + """ + child_object = None + design_childs = self._app.get_oo_name(self._app.odesign) + + if "Radiation" in design_childs: + cc = self._app.get_oo_object(self._app.odesign, "Radiation") + cc_names = self._app.get_oo_name(cc) + if self._name in cc_names: + child_object = cc.GetChildObject(self._name) + return child_object @property def props(self): @@ -76,13 +93,18 @@ def props(self): @property def name(self): - """Variable name.""" + """Boundary Name.""" + if self._child_object: + self._name = self.properties["Name"] return self._name @name.setter def name(self, value): - self._app.oradfield.RenameSetup(self._name, value) - self._name = value + if self._child_object: + try: + self.properties["Name"] = value + except KeyError: + self._app.logger.error("Name %s already assigned in the design", value) @pyaedt_function_handler() def _get_args(self, props=None): @@ -102,7 +124,6 @@ def create(self): ``True`` when successful, ``False`` when failed. """ - if self.type == "FarFieldSphere": self._app.oradfield.InsertInfiniteSphereSetup(self._get_args()) elif self.type == "NearFieldBox": @@ -117,9 +138,7 @@ def create(self): self._app.oradfield.AddAntennaOverlay(self._get_args()) elif self.type == "FieldSourceGroup": self._app.oradfield.AddRadFieldSourceGroup(self._get_args()) - child_object = self._app.get_oo_object(self._app.odesign, f"Radiation/{self._name}") - if child_object: - BinaryTreeNode.__init__(self, self._name, child_object, False) + self._initialize_bynary_tree() return True @pyaedt_function_handler() diff --git a/src/ansys/aedt/core/modules/boundary/layout_boundary.py b/src/ansys/aedt/core/modules/boundary/layout_boundary.py index 41df52a5e97..e4d9280d113 100644 --- a/src/ansys/aedt/core/modules/boundary/layout_boundary.py +++ b/src/ansys/aedt/core/modules/boundary/layout_boundary.py @@ -105,9 +105,24 @@ def __init__(self, app, component_type, component_name, props): self._update_props(self.__props, props) self.native_properties = self.__props["NativeComponentDefinitionProvider"] self.auto_update = True - child_object = self._app.get_oo_object(self._app.oeditor, self._name) - if child_object: - BinaryTreeNode.__init__(self, self._name, child_object, False) + + self._initialize_bynary_tree() + + @property + def _child_object(self): + """Object-oriented properties. + + Returns + ------- + class:`ansys.aedt.core.modeler.cad.elements_3d.BinaryTreeNode` + + """ + child_object = None + design_childs = self._app.get_oo_name(self._app.oeditor) + + if self._name in design_childs: + child_object = self._app.get_oo_object(self._app.oeditor, self._name) + return child_object @property def props(self): @@ -128,14 +143,16 @@ def name(self): @name.setter def name(self, component_name): if component_name != self._name: - if component_name not in self._app.native_component_names: - self.properties["Name"] = component_name - self._app.native_components.update({component_name: self}) - del self._app.native_components[self._name] - del self._app.modeler.user_defined_components[self._name] - self._name = component_name - else: # pragma: no cover - self._app._logger.warning("Name %s already assigned in the design", component_name) + if component_name not in self._app.native_component_names and self._child_object: + try: + self.properties["Name"] = component_name + self._app.native_components.update({component_name: self}) + del self._app.native_components[self._name] + del self._app.modeler.user_defined_components[self._name] + except KeyError: + self._app.logger.error("Name %s already assigned in the design", component_name) + else: # pragma: no cover + self._app._logger.warning("Name %s already assigned in the design", component_name) @property def definition_name(self): @@ -208,9 +225,7 @@ def create(self): self.excitation_name = a[0].split(":")[0] except (GrpcApiError, IndexError): self.excitation_name = self.name - child_object = self._app.get_oo_object(self._app.oeditor, self._name) - if child_object: - BinaryTreeNode.__init__(self, self._name, child_object, False) + self._initialize_bynary_tree() return True @pyaedt_function_handler() diff --git a/src/ansys/aedt/core/modules/boundary/maxwell_boundary.py b/src/ansys/aedt/core/modules/boundary/maxwell_boundary.py index cdad30d395a..9fca5ea8d8f 100644 --- a/src/ansys/aedt/core/modules/boundary/maxwell_boundary.py +++ b/src/ansys/aedt/core/modules/boundary/maxwell_boundary.py @@ -66,8 +66,7 @@ def __init__(self, app, name, props=None, boundarytype=None): self.auto_update = True self.__reduced_matrices = None self.matrix_assignment = None - if self._child_object: - BinaryTreeNode.__init__(self, self.name, self._child_object, False) + self._initialize_bynary_tree() @property def reduced_matrices(self): @@ -125,13 +124,18 @@ def props(self): @property def name(self): - """Boundary name.""" + """Boundary Name.""" + if self._child_object: + self._name = self.properties["Name"] return self._name @name.setter def name(self, value): - self._name = value - self.update() + if self._child_object: + try: + self.properties["Name"] = value + except KeyError: + self._app.logger.error("Name %s already assigned in the design", value) @pyaedt_function_handler() def _get_args(self, props=None): @@ -174,8 +178,7 @@ def create(self): self._app.o_maxwell_parameters.AssignLayoutForce(self._get_args()) else: return False - if self._child_object: - BinaryTreeNode.__init__(self, self.name, self._child_object, False) + self._initialize_bynary_tree() return True @pyaedt_function_handler() diff --git a/src/ansys/aedt/core/modules/mesh.py b/src/ansys/aedt/core/modules/mesh.py index 99dcd3c4293..da474c90913 100644 --- a/src/ansys/aedt/core/modules/mesh.py +++ b/src/ansys/aedt/core/modules/mesh.py @@ -125,11 +125,26 @@ def __init__(self, mesh, name, props, meshoptype): self._type = meshoptype self._name = name self.auto_update = True + self._initialize_bynary_tree() - child_object = self._app.get_oo_object(self._app.odesign, f"Mesh/{self._name}") + @property + def _child_object(self): + """Object-oriented properties. - if child_object: - BinaryTreeNode.__init__(self, self._name, child_object, False) + Returns + ------- + class:`ansys.aedt.core.modeler.cad.elements_3d.BinaryTreeNode` + + """ + child_object = None + design_childs = self._app.get_oo_name(self._app.odesign) + + if "Mesh" in design_childs: + cc = self._app.get_oo_object(self._app.odesign, "Mesh") + cc_names = self._app.get_oo_name(cc) + if self._name in cc_names: + child_object = cc.GetChildObject(self._name) + return child_object @property def type(self): @@ -182,7 +197,7 @@ def props(self): def _get_args(self): """Retrieve arguments.""" props = self.props - arg = ["NAME:" + self._name] + arg = ["NAME:" + self.name] _dict2arg(props, arg) return arg @@ -196,18 +211,17 @@ def name(self): Name of the mesh operation. """ - try: + if self._child_object: self._name = self.properties["Name"] - except (KeyError, AttributeError): - pass return self._name @name.setter def name(self, meshop_name): - try: - self.properties["Name"] = meshop_name - except KeyError: - self._mesh.logger.warning("Name %s already assigned in the design", meshop_name) + if self._child_object: + try: + self.properties["Name"] = meshop_name + except KeyError: + self._mesh.logger.error("Name %s already assigned in the design", meshop_name) @pyaedt_function_handler() def create(self): @@ -245,10 +259,7 @@ def create(self): self._mesh.omeshmodule.AssignCylindricalGapOp(self._get_args()) else: return False - child_object = self._app.get_oo_object(self._app.odesign, f"Mesh/{self._name}") - - if child_object: - BinaryTreeNode.__init__(self, self._name, child_object, False) + self._initialize_bynary_tree() return True @pyaedt_function_handler() @@ -395,6 +406,11 @@ def delete(self): self._mesh.meshoperations.remove(el) return True + @pyaedt_function_handler() + def _initialize_bynary_tree(self): + if self._child_object: + BinaryTreeNode.__init__(self, self._name, self._child_object, False) + class Mesh(object): """Manages AEDT mesh functions for 2D and 3D solvers (HFSS, Maxwell, and Q3D). @@ -1176,10 +1192,12 @@ def assign_length_mesh(self, assignment, inside_selection=True, maximum_length=1 ) mop = MeshOperation(self, name, props, "LengthBased") + for meshop in self.meshoperations[:]: if meshop.name == mop.name: meshop.delete() break + mop.create() self.meshoperations.append(mop) return mop diff --git a/src/ansys/aedt/core/modules/solve_setup.py b/src/ansys/aedt/core/modules/solve_setup.py index 8e0d590accc..424efee6de8 100644 --- a/src/ansys/aedt/core/modules/solve_setup.py +++ b/src/ansys/aedt/core/modules/solve_setup.py @@ -53,6 +53,7 @@ class CommonSetup(PropsManager, BinaryTreeNode): + def __init__(self, app, solution_type, name="MySetupAuto", is_new_setup=True): self.auto_update = False self._app = None @@ -71,10 +72,31 @@ def __init__(self, app, solution_type, name="MySetupAuto", is_new_setup=True): self._is_new_setup = is_new_setup # self._init_props(is_new_setup) self.auto_update = True - child_object = self._app.get_oo_object(self._app.odesign, f"Analysis/{self._name}") + self._initialize_bynary_tree() + + @property + def _child_object(self): + """Object-oriented properties. - if child_object: - BinaryTreeNode.__init__(self, self._name, child_object, False) + Returns + ------- + class:`ansys.aedt.core.modeler.cad.elements_3d.BinaryTreeNode` + + """ + child_object = None + design_childs = self._app.get_oo_name(self._app.odesign) + + if "Analysis" in design_childs: + cc = self._app.get_oo_object(self._app.odesign, "Analysis") + cc_names = self._app.get_oo_name(cc) + if self._name in cc_names: + child_object = cc.GetChildObject(self._name) + return child_object + + @pyaedt_function_handler() + def _initialize_bynary_tree(self): + if self._child_object: + BinaryTreeNode.__init__(self, self._name, self._child_object, False) @property def sweeps(self): @@ -548,11 +570,7 @@ def create(self): arg = ["NAME:" + self._name] _dict2arg(self.props, arg) self.omodule.InsertSetup(soltype, arg) - child_object = self._app.get_oo_object(self._app.odesign, f"Analysis/{self._name}") - - if child_object: - BinaryTreeNode.__init__(self, self._name, child_object, False) - + self._initialize_bynary_tree() return arg @pyaedt_function_handler(update_dictionary="properties") @@ -1163,10 +1181,7 @@ def create(self): arg = ["NAME:SimSetup"] _dict2arg(self.props, arg) self._setup(soltype, arg) - child_object = self._app.get_oo_object(self._app.odesign, f"Analysis/{self._name}") - - if child_object: - BinaryTreeNode.__init__(self, self._name, child_object, False) + self._initialize_bynary_tree() return arg @pyaedt_function_handler() @@ -1918,6 +1933,7 @@ def create(self): arg = ["NAME:" + self.name] _dict2arg(self.props, arg) self.omodule.Add(arg) + self._initialize_bynary_tree() return True @pyaedt_function_handler(update_dictionary="properties") diff --git a/src/ansys/aedt/core/rmxprt.py b/src/ansys/aedt/core/rmxprt.py index 9187023884d..279b292c879 100644 --- a/src/ansys/aedt/core/rmxprt.py +++ b/src/ansys/aedt/core/rmxprt.py @@ -347,10 +347,10 @@ def export_configuration(self, output_file): """ def jsonalize(dict_in, dict_out): - dict_out[dict_in.node] = {} + dict_out[dict_in._node] = {} for k, v in dict_in.properties.items(): if not k.endswith("/Choices"): - dict_out[dict_in.node][k] = v + dict_out[dict_in._node][k] = v for _, c in dict_in.children.items(): jsonalize(c, dict_out) diff --git a/tests/system/general/test_07_Object3D.py b/tests/system/general/test_07_Object3D.py index 3cd578af1f7..128f1d4e612 100644 --- a/tests/system/general/test_07_Object3D.py +++ b/tests/system/general/test_07_Object3D.py @@ -660,11 +660,11 @@ def test_27_get_object_history_properties(self): box_subtract.split("XY") box_history = box.history() box_clone_history = box_clone.history() - assert box_history.node == "box_history" + assert box_history._node == "box_history" assert box_history.command == "CreateBox" assert box_history.properties["Command"] == "CreateBox" assert box_history.children == {} - assert box_clone_history.node == "box_history1" + assert box_clone_history._node == "box_history1" assert box_clone_history.command == box_history.command assert box_clone_history.properties["Command"] == box_history.properties["Command"] assert box_clone_history.properties["Position/X"] == box_history.properties["Position/X"] From 6be2f829aef70d2d92ae07851517a1dbc9075318 Mon Sep 17 00:00:00 2001 From: Samuelopez-ansys Date: Thu, 19 Dec 2024 07:47:11 +0100 Subject: [PATCH 09/28] Apply #5590 --- src/ansys/aedt/core/application/analysis_3d.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/aedt/core/application/analysis_3d.py b/src/ansys/aedt/core/application/analysis_3d.py index 37228551970..58377f595e5 100644 --- a/src/ansys/aedt/core/application/analysis_3d.py +++ b/src/ansys/aedt/core/application/analysis_3d.py @@ -1377,7 +1377,7 @@ def import_gds_3d(self, input_file: str, mapping_layers: dict, units: str = "um" input_file : str Path to the GDS file. mapping_layers : dict - Dictionary keys are GDS layer numbers, and the value is a tuple with the thickness and elevation. + Dictionary keys are GDS layer numbers, and the value is a tuple with the elevation and thickness. units : str, optional Length unit values. The default is ``"um"``. import_method : integer, optional From 8e1a9a9f282ad923213c34430443489dc3709ddd Mon Sep 17 00:00:00 2001 From: Samuelopez-ansys Date: Thu, 19 Dec 2024 08:38:47 +0100 Subject: [PATCH 10/28] RMxpert solution type fixed in test_10_export_to_maxwell --- tests/system/solvers/test_00_analyze.py | 2 +- tests/system/solvers/test_31_Q3D.py | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/system/solvers/test_00_analyze.py b/tests/system/solvers/test_00_analyze.py index 346ac718ce0..58ac97c911b 100644 --- a/tests/system/solvers/test_00_analyze.py +++ b/tests/system/solvers/test_00_analyze.py @@ -649,6 +649,6 @@ def test_10_export_to_maxwell(self, add_app): m3d = app.create_maxwell_design("Setup1", maxwell_2d=False) assert m3d.design_type == "Maxwell 3D" config = app.export_configuration(os.path.join(self.local_scratch.path, "assm.json")) - app2 = add_app("assm_test2", application=Rmxprt) + app2 = add_app("assm_test2", application=Rmxprt, solution_type="ASSM") app2.import_configuration(config) assert app2.circuit diff --git a/tests/system/solvers/test_31_Q3D.py b/tests/system/solvers/test_31_Q3D.py index 2a12b0b9b31..1c1bf6b86b3 100644 --- a/tests/system/solvers/test_31_Q3D.py +++ b/tests/system/solvers/test_31_Q3D.py @@ -151,17 +151,17 @@ def test_06b_create_setup(self): mysetup = self.aedtapp.create_setup() mysetup.props["SaveFields"] = True assert mysetup.update() - sweep2 = mysetup.create_frequency_sweep(sweepname="mysweep2", unit="GHz", freqstart=1, freqstop=4) + sweep2 = mysetup.create_frequency_sweep(name="mysweep2", unit="GHz", start_frequency=1, stop_frequency=4) assert sweep2 - sweep2_1 = mysetup.create_frequency_sweep(sweepname="mysweep2", unit="GHz", freqstart=1, freqstop=4) + sweep2_1 = mysetup.create_frequency_sweep(name="mysweep2", unit="GHz", start_frequency=1, stop_frequency=4) assert sweep2_1 assert sweep2.name != sweep2_1.name assert sweep2.props["RangeEnd"] == "4GHz" - sweep3 = mysetup.create_frequency_sweep(unit="GHz", freqstart=1, freqstop=4) + sweep3 = mysetup.create_frequency_sweep(unit="GHz", start_frequency=1, stop_frequency=4) assert sweep3 with pytest.raises(AttributeError) as execinfo: mysetup.create_frequency_sweep( - sweepname="mysweep4", unit="GHz", freqstart=1, freqstop=4, sweep_type="Invalid" + name="mysweep4", unit="GHz", start_frequency=1, stop_frequency=4, sweep_type="Invalid" ) assert ( execinfo.args[0] @@ -206,6 +206,7 @@ def test_07B_create_source_tosheet(self): source = self.aedtapp.source(["Source1", "Sink1"], name="Cylinder1", net_name="GND") source.props["Objects"] = ["Source1"] sink = self.aedtapp.sink("Sink1", net_name="GND") + sink.properties assert source assert sink sink.name = "My_new_name" From 1542eb8ffb550f917c1ff13fe8cb030ac4905b77 Mon Sep 17 00:00:00 2001 From: Samuelopez-ansys Date: Thu, 19 Dec 2024 08:56:20 +0100 Subject: [PATCH 11/28] Try and except read only properties --- src/ansys/aedt/core/rmxprt.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ansys/aedt/core/rmxprt.py b/src/ansys/aedt/core/rmxprt.py index 5366043ac0c..f4c1d7a83f5 100644 --- a/src/ansys/aedt/core/rmxprt.py +++ b/src/ansys/aedt/core/rmxprt.py @@ -73,7 +73,10 @@ def _apply_val(dict_in, name, value): prps = dict_in.properties[name][::] prps[1] = value value = prps - dict_in.properties[name] = value + try: + dict_in.properties[name] = value + except KeyError: + self._app.logger.error(f"{name} is read only.") return True else: for _, child in dict_in.children.items(): From 682596b929dae4c8c874088a155ff9ede0b0119a Mon Sep 17 00:00:00 2001 From: Samuelopez-ansys Date: Thu, 19 Dec 2024 10:00:00 +0100 Subject: [PATCH 12/28] Fix Q3D source and sink rename --- src/ansys/aedt/core/application/analysis.py | 10 ++ .../aedt/core/modules/boundary/common.py | 137 +++++++++--------- .../core/modules/boundary/layout_boundary.py | 1 - tests/system/solvers/test_31_Q3D.py | 1 - 4 files changed, 79 insertions(+), 70 deletions(-) diff --git a/src/ansys/aedt/core/application/analysis.py b/src/ansys/aedt/core/application/analysis.py index 424497c7247..494e4b58d8c 100644 --- a/src/ansys/aedt/core/application/analysis.py +++ b/src/ansys/aedt/core/application/analysis.py @@ -530,6 +530,16 @@ def excitation_objects(self): if el.name in exc_names: self._excitation_objects[el.name] = el + # Delete objects that are not anymore available + keys_to_remove = [ + internal_excitation + for internal_excitation in self._excitation_objects + if internal_excitation not in self.excitations + ] + + for key in keys_to_remove: + del self._excitation_objects[key] + return self._excitation_objects @pyaedt_function_handler() diff --git a/src/ansys/aedt/core/modules/boundary/common.py b/src/ansys/aedt/core/modules/boundary/common.py index 55d2cc67e2e..eef718c1e7e 100644 --- a/src/ansys/aedt/core/modules/boundary/common.py +++ b/src/ansys/aedt/core/modules/boundary/common.py @@ -219,7 +219,6 @@ def __init__(self, app, name, props=None, boundarytype=None, auto_update=True): self.__props = None self.__props = BoundaryProps(self, props) if props else {} self._type = boundarytype - self._boundary_name = self.name self.auto_update = auto_update self._initialize_bynary_tree() @@ -261,6 +260,13 @@ def _child_object(self): for port in self._app.get_oo_name(self._app.odesign, "Conductors"): if self._name == port: child_object = self._app.get_oo_object(self._app.odesign, f"Conductors\\{port}") + + if not child_object and "Nets" in design_childs: + cc = self._app.get_oo_object(self._app.odesign, "Nets") + cc_names = self._app.get_oo_name(cc) + if self._name in cc_names: + child_object = cc.GetChildObject(self._name) + return child_object @property @@ -521,6 +527,7 @@ def create(self): self._app.oboundary.AssignResistiveSheet(self._get_args()) else: return False + self._initialize_bynary_tree() return True @@ -537,95 +544,91 @@ def update(self): """ bound_type = self.type if bound_type == "Perfect E": - self._app.oboundary.EditPerfectE(self._boundary_name, self._get_args()) + self._app.oboundary.EditPerfectE(self.name, self._get_args()) elif bound_type == "Perfect H": - self._app.oboundary.EditPerfectH(self._boundary_name, self._get_args()) + self._app.oboundary.EditPerfectH(self.name, self._get_args()) elif bound_type == "Aperture": - self._app.oboundary.EditAperture(self._boundary_name, self._get_args()) + self._app.oboundary.EditAperture(self.name, self._get_args()) elif bound_type == "Radiation": - self._app.oboundary.EditRadiation(self._boundary_name, self._get_args()) + self._app.oboundary.EditRadiation(self.name, self._get_args()) elif bound_type == "Finite Conductivity": - self._app.oboundary.EditFiniteCond(self._boundary_name, self._get_args()) + self._app.oboundary.EditFiniteCond(self.name, self._get_args()) elif bound_type == "Lumped RLC": - self._app.oboundary.EditLumpedRLC(self._boundary_name, self._get_args()) + self._app.oboundary.EditLumpedRLC(self.name, self._get_args()) elif bound_type == "Impedance": - self._app.oboundary.EditImpedance(self._boundary_name, self._get_args()) + self._app.oboundary.EditImpedance(self.name, self._get_args()) elif bound_type == "Layered Impedance": - self._app.oboundary.EditLayeredImpedance(self._boundary_name, self._get_args()) + self._app.oboundary.EditLayeredImpedance(self.name, self._get_args()) elif bound_type == "Anisotropic Impedance": - self._app.oboundary.EditAssignAnisotropicImpedance( - self._boundary_name, self._get_args() - ) # pragma: no cover + self._app.oboundary.EditAssignAnisotropicImpedance(self.name, self._get_args()) # pragma: no cover elif bound_type == "Primary": - self._app.oboundary.EditPrimary(self._boundary_name, self._get_args()) + self._app.oboundary.EditPrimary(self.name, self._get_args()) elif bound_type == "Secondary": - self._app.oboundary.EditSecondary(self._boundary_name, self._get_args()) + self._app.oboundary.EditSecondary(self.name, self._get_args()) elif bound_type == "Lattice Pair": - self._app.oboundary.EditLatticePair(self._boundary_name, self._get_args()) + self._app.oboundary.EditLatticePair(self.name, self._get_args()) elif bound_type == "HalfSpace": - self._app.oboundary.EditHalfSpace(self._boundary_name, self._get_args()) + self._app.oboundary.EditHalfSpace(self.name, self._get_args()) elif bound_type == "Multipaction SEE": - self._app.oboundary.EditMultipactionSEE(self._boundary_name, self._get_args()) # pragma: no cover + self._app.oboundary.EditMultipactionSEE(self.name, self._get_args()) # pragma: no cover elif bound_type == "Fresnel": - self._app.oboundary.EditFresnel(self._boundary_name, self._get_args()) # pragma: no cover + self._app.oboundary.EditFresnel(self.name, self._get_args()) # pragma: no cover elif bound_type == "Symmetry": - self._app.oboundary.EditSymmetry(self._boundary_name, self._get_args()) + self._app.oboundary.EditSymmetry(self.name, self._get_args()) elif bound_type == "Zero Tangential H Field": - self._app.oboundary.EditZeroTangentialHField(self._boundary_name, self._get_args()) # pragma: no cover + self._app.oboundary.EditZeroTangentialHField(self.name, self._get_args()) # pragma: no cover elif bound_type == "Zero Integrated Tangential H Field": - self._app.oboundary.EditIntegratedZeroTangentialHField( - self._boundary_name, self._get_args() - ) # pragma: no cover + self._app.oboundary.EditIntegratedZeroTangentialHField(self.name, self._get_args()) # pragma: no cover elif bound_type == "Tangential H Field": - self._app.oboundary.EditTangentialHField(self._boundary_name, self._get_args()) # pragma: no cover + self._app.oboundary.EditTangentialHField(self.name, self._get_args()) # pragma: no cover elif bound_type == "Insulating": - self._app.oboundary.EditInsulating(self._boundary_name, self._get_args()) # pragma: no cover + self._app.oboundary.EditInsulating(self.name, self._get_args()) # pragma: no cover elif bound_type == "Independent": - self._app.oboundary.EditIndependent(self._boundary_name, self._get_args()) # pragma: no cover + self._app.oboundary.EditIndependent(self.name, self._get_args()) # pragma: no cover elif bound_type == "Dependent": - self._app.oboundary.EditDependent(self._boundary_name, self._get_args()) # pragma: no cover + self._app.oboundary.EditDependent(self.name, self._get_args()) # pragma: no cover elif bound_type == "Band": - self._app.omodelsetup.EditMotionSetup(self._boundary_name, self._get_args()) # pragma: no cover + self._app.omodelsetup.EditMotionSetup(self.name, self._get_args()) # pragma: no cover elif bound_type == "InfiniteGround": - self._app.oboundary.EditInfiniteGround(self._boundary_name, self._get_args()) + self._app.oboundary.EditInfiniteGround(self.name, self._get_args()) elif bound_type == "ThinConductor": - self._app.oboundary.EditThinConductor(self._boundary_name, self._get_args()) + self._app.oboundary.EditThinConductor(self.name, self._get_args()) elif bound_type == "Stationary Wall": - self._app.oboundary.EditStationaryWallBoundary(self._boundary_name, self._get_args()) # pragma: no cover + self._app.oboundary.EditStationaryWallBoundary(self.name, self._get_args()) # pragma: no cover elif bound_type == "Symmetry Wall": - self._app.oboundary.EditSymmetryWallBoundary(self._boundary_name, self._get_args()) # pragma: no cover + self._app.oboundary.EditSymmetryWallBoundary(self.name, self._get_args()) # pragma: no cover elif bound_type == "Recirculating": - self._app.oboundary.EditRecircBoundary(self._boundary_name, self._get_args()) + self._app.oboundary.EditRecircBoundary(self.name, self._get_args()) elif bound_type == "Resistance": - self._app.oboundary.EditResistanceBoundary(self._boundary_name, self._get_args()) # pragma: no cover + self._app.oboundary.EditResistanceBoundary(self.name, self._get_args()) # pragma: no cover elif bound_type == "Conducting Plate": - self._app.oboundary.EditConductingPlateBoundary(self._boundary_name, self._get_args()) # pragma: no cover + self._app.oboundary.EditConductingPlateBoundary(self.name, self._get_args()) # pragma: no cover elif bound_type == "Adiabatic Plate": - self._app.oboundary.EditAdiabaticPlateBoundary(self._boundary_name, self._get_args()) # pragma: no cover + self._app.oboundary.EditAdiabaticPlateBoundary(self.name, self._get_args()) # pragma: no cover elif bound_type == "Network": - self._app.oboundary.EditNetworkBoundary(self._boundary_name, self._get_args()) # pragma: no cover + self._app.oboundary.EditNetworkBoundary(self.name, self._get_args()) # pragma: no cover elif bound_type == "Grille": - self._app.oboundary.EditGrilleBoundary(self._boundary_name, self._get_args()) + self._app.oboundary.EditGrilleBoundary(self.name, self._get_args()) elif bound_type == "Opening": - self._app.oboundary.EditOpeningBoundary(self._boundary_name, self._get_args()) + self._app.oboundary.EditOpeningBoundary(self.name, self._get_args()) elif bound_type == "EMLoss": - self._app.oboundary.EditEMLoss(self._boundary_name, self._get_args()) # pragma: no cover + self._app.oboundary.EditEMLoss(self.name, self._get_args()) # pragma: no cover elif bound_type == "Block": - self._app.oboundary.EditBlockBoundary(self._boundary_name, self._get_args()) + self._app.oboundary.EditBlockBoundary(self.name, self._get_args()) elif bound_type == "Blower": - self._app.oboundary.EditBlowerBoundary(self._boundary_name, self._get_args()) + self._app.oboundary.EditBlowerBoundary(self.name, self._get_args()) elif bound_type == "SourceIcepak": - self._app.oboundary.EditSourceBoundary(self._boundary_name, self._get_args()) + self._app.oboundary.EditSourceBoundary(self.name, self._get_args()) elif bound_type == "HeatFlux": - self._app.oboundary.EditHeatFlux(self._boundary_name, self._get_args()) + self._app.oboundary.EditHeatFlux(self.name, self._get_args()) elif bound_type == "HeatGeneration": - self._app.oboundary.EditHeatGeneration(self._boundary_name, self._get_args()) + self._app.oboundary.EditHeatGeneration(self.name, self._get_args()) elif bound_type == "Voltage": - self._app.oboundary.EditVoltage(self._boundary_name, self._get_args()) + self._app.oboundary.EditVoltage(self.name, self._get_args()) elif bound_type == "VoltageDrop": - self._app.oboundary.EditVoltageDrop(self._boundary_name, self._get_args()) + self._app.oboundary.EditVoltageDrop(self.name, self._get_args()) elif bound_type == "Current": - self._app.oboundary.EditCurrent(self._boundary_name, self._get_args()) + self._app.oboundary.EditCurrent(self.name, self._get_args()) elif bound_type == "CurrentDensity": self._app.oboundary.AssignCurrentDensity(self._get_args()) elif bound_type == "CurrentDensityGroup": @@ -635,45 +638,43 @@ def update(self): elif bound_type == "CurrentDensityTerminalGroup": self._app.oboundary.AssignCurrentDensityTerminalGroup(self._get_args()[2], self._get_args()[3]) elif bound_type == "Winding" or bound_type == "Winding Group": - self._app.oboundary.EditWindingGroup(self._boundary_name, self._get_args()) # pragma: no cover + self._app.oboundary.EditWindingGroup(self.name, self._get_args()) # pragma: no cover elif bound_type == "Vector Potential": - self._app.oboundary.EditVectorPotential(self._boundary_name, self._get_args()) # pragma: no cover + self._app.oboundary.EditVectorPotential(self.name, self._get_args()) # pragma: no cover elif bound_type == "CoilTerminal" or bound_type == "Coil Terminal": - self._app.oboundary.EditCoilTerminal(self._boundary_name, self._get_args()) + self._app.oboundary.EditCoilTerminal(self.name, self._get_args()) elif bound_type == "Coil": - self._app.oboundary.EditCoil(self._boundary_name, self._get_args()) + self._app.oboundary.EditCoil(self.name, self._get_args()) elif bound_type == "Source": - self._app.oboundary.EditTerminal(self._boundary_name, self._get_args()) # pragma: no cover + self._app.oboundary.EditTerminal(self.name, self._get_args()) # pragma: no cover elif bound_type == "Sink": - self._app.oboundary.EditTerminal(self._boundary_name, self._get_args()) + self._app.oboundary.EditTerminal(self.name, self._get_args()) elif bound_type == "SignalNet" or bound_type == "GroundNet" or bound_type == "FloatingNet": - self._app.oboundary.EditTerminal(self._boundary_name, self._get_args()) + self._app.oboundary.EditTerminal(self.name, self._get_args()) elif bound_type in "Circuit Port": - self._app.oboundary.EditCircuitPort(self._boundary_name, self._get_args()) + self._app.oboundary.EditCircuitPort(self.name, self._get_args()) elif bound_type in "Lumped Port": - self._app.oboundary.EditLumpedPort(self._boundary_name, self._get_args()) + self._app.oboundary.EditLumpedPort(self.name, self._get_args()) elif bound_type in "Wave Port": - self._app.oboundary.EditWavePort(self._boundary_name, self._get_args()) + self._app.oboundary.EditWavePort(self.name, self._get_args()) elif bound_type == "SetSBRTxRxSettings": self._app.oboundary.SetSBRTxRxSettings(self._get_args()) # pragma: no cover elif bound_type == "Floquet Port": - self._app.oboundary.EditFloquetPort(self._boundary_name, self._get_args()) # pragma: no cover + self._app.oboundary.EditFloquetPort(self.name, self._get_args()) # pragma: no cover elif bound_type == "End Connection": - self._app.oboundary.EditEndConnection(self._boundary_name, self._get_args()) + self._app.oboundary.EditEndConnection(self.name, self._get_args()) elif bound_type == "Hybrid": - self._app.oboundary.EditHybridRegion(self._boundary_name, self._get_args()) + self._app.oboundary.EditHybridRegion(self.name, self._get_args()) elif bound_type == "Terminal": - self._app.oboundary.EditTerminal(self._boundary_name, self._get_args()) + self._app.oboundary.EditTerminal(self.name, self._get_args()) elif bound_type == "Plane Incident Wave": - self._app.oboundary.EditIncidentWave(self._boundary_name, self._get_args()) + self._app.oboundary.EditIncidentWave(self.name, self._get_args()) elif bound_type == "ResistiveSheet": - self._app.oboundary.EditResistiveSheet(self._boundary_name, self._get_args()) + self._app.oboundary.EditResistiveSheet(self.name, self._get_args()) else: return False # pragma: no cover - - self._app._boundaries[self.name] = self._app._boundaries.pop(self._boundary_name) - self._boundary_name = self.name - + # self._app._boundaries[self.name] = self._app._boundaries.pop(self._boundary_name) + # self._boundary_name = self.name return True @pyaedt_function_handler() diff --git a/src/ansys/aedt/core/modules/boundary/layout_boundary.py b/src/ansys/aedt/core/modules/boundary/layout_boundary.py index e4d9280d113..51320093b04 100644 --- a/src/ansys/aedt/core/modules/boundary/layout_boundary.py +++ b/src/ansys/aedt/core/modules/boundary/layout_boundary.py @@ -302,7 +302,6 @@ def __init__(self, app, name, props, boundarytype): if props: self.__props = BoundaryProps(self, props) self.type = boundarytype - self._boundary_name = self.name self.auto_update = True if self._child_object: BinaryTreeNode.__init__(self, self.name, self._child_object, False) diff --git a/tests/system/solvers/test_31_Q3D.py b/tests/system/solvers/test_31_Q3D.py index 1c1bf6b86b3..4a4027a7914 100644 --- a/tests/system/solvers/test_31_Q3D.py +++ b/tests/system/solvers/test_31_Q3D.py @@ -206,7 +206,6 @@ def test_07B_create_source_tosheet(self): source = self.aedtapp.source(["Source1", "Sink1"], name="Cylinder1", net_name="GND") source.props["Objects"] = ["Source1"] sink = self.aedtapp.sink("Sink1", net_name="GND") - sink.properties assert source assert sink sink.name = "My_new_name" From 7b70c8f328d9acbd427dbd98f0519353c9d707fe Mon Sep 17 00:00:00 2001 From: Samuelopez-ansys Date: Thu, 19 Dec 2024 10:59:37 +0100 Subject: [PATCH 13/28] Fix _child_object --- .../aedt/core/modules/boundary/common.py | 56 +++++++++++-------- tests/system/solvers/test_31_Q3D.py | 36 +++++++++--- 2 files changed, 60 insertions(+), 32 deletions(-) diff --git a/src/ansys/aedt/core/modules/boundary/common.py b/src/ansys/aedt/core/modules/boundary/common.py index eef718c1e7e..2583a196ce0 100644 --- a/src/ansys/aedt/core/modules/boundary/common.py +++ b/src/ansys/aedt/core/modules/boundary/common.py @@ -231,43 +231,50 @@ def _child_object(self): class:`ansys.aedt.core.modeler.cad.elements_3d.BinaryTreeNode` """ - child_object = None design_childs = self._app.get_oo_name(self._app.odesign) + if "Nets" in design_childs: + cc = self._app.get_oo_object(self._app.odesign, "Nets") + cc_names = self._app.get_oo_name(cc) + if self._name in cc_names: + return cc.GetChildObject(self._name) + for name in cc_names: + cc = self._app.get_oo_object(self._app.odesign, f"Nets\\{name}") + cc_names = self._app.get_oo_name(cc) + if self._name in cc_names: + return cc.GetChildObject(self._name) + if "Thermal" in design_childs: cc = self._app.get_oo_object(self._app.odesign, "Thermal") cc_names = self._app.get_oo_name(cc) if self._name in cc_names: - child_object = cc.GetChildObject(self._name) - elif "Boundaries" in design_childs: + return cc.GetChildObject(self._name) + + if "Boundaries" in design_childs: cc = self._app.get_oo_object(self._app.odesign, "Boundaries") if self._name in cc.GetChildNames(): - child_object = cc.GetChildObject(self._name) - elif "Excitations" in design_childs and self._name in self._app.get_oo_name( - self._app.odesign, "Excitations" - ): - child_object = self._app.get_oo_object(self._app.odesign, "Excitations").GetChildObject(self._name) - elif self._app.design_type in ["Maxwell 3D", "Maxwell 2D"] and "Model" in design_childs: - model = self._app.get_oo_object(self._app.odesign, "Model") - if self._name in model.GetChildNames(): - child_object = model.GetChildObject(self._name) - elif "Excitations" in design_childs and self._app.get_oo_name(self._app.odesign, "Excitations"): + return cc.GetChildObject(self._name) + + if "Excitations" in design_childs: + if self._name in self._app.get_oo_name(self._app.odesign, "Excitations"): + return self._app.get_oo_object(self._app.odesign, "Excitations").GetChildObject(self._name) + elif self._app.get_oo_name(self._app.odesign, "Excitations"): for port in self._app.get_oo_name(self._app.odesign, "Excitations"): terminals = self._app.get_oo_name(self._app.odesign, f"Excitations\\{port}") if self._name in terminals: - child_object = self._app.get_oo_object(self._app.odesign, f"Excitations\\{port}\\{self._name}") - elif "Conductors" in design_childs and self._app.get_oo_name(self._app.odesign, "Conductors"): - for port in self._app.get_oo_name(self._app.odesign, "Conductors"): - if self._name == port: - child_object = self._app.get_oo_object(self._app.odesign, f"Conductors\\{port}") + return self._app.get_oo_object(self._app.odesign, f"Excitations\\{port}\\{self._name}") - if not child_object and "Nets" in design_childs: - cc = self._app.get_oo_object(self._app.odesign, "Nets") - cc_names = self._app.get_oo_name(cc) - if self._name in cc_names: - child_object = cc.GetChildObject(self._name) + if self._app.design_type in ["Maxwell 3D", "Maxwell 2D"] and "Model" in design_childs: + model = self._app.get_oo_object(self._app.odesign, "Model") + if self._name in model.GetChildNames(): + return model.GetChildObject(self._name) + + if "Conductors" in design_childs and self._app.get_oo_name(self._app.odesign, "Conductors"): + for port in self._app.get_oo_name(self._app.odesign, "Conductors"): + if self._name == port: + return self._app.get_oo_object(self._app.odesign, f"Conductors\\{port}") - return child_object + return None @property def props(self): @@ -325,6 +332,7 @@ def name(self, value): if self._child_object: try: self.properties["Name"] = value + self._app._boundaries[value] = self except KeyError: self._app.logger.error("Name %s already assigned in the design", value) diff --git a/tests/system/solvers/test_31_Q3D.py b/tests/system/solvers/test_31_Q3D.py index 4a4027a7914..6881893fc4f 100644 --- a/tests/system/solvers/test_31_Q3D.py +++ b/tests/system/solvers/test_31_Q3D.py @@ -180,12 +180,31 @@ def test_07_create_source_sinks(self): assert sink.name == "Sink1" assert len(self.aedtapp.excitations) > 0 - def test_07B_create_source_tosheet(self): + def test_07b_create_source_to_sheet(self): + self.aedtapp.insert_design("source_to_sheet") + + udp = self.aedtapp.modeler.Position(0, 0, 0) + coax_dimension = 30 + o1 = self.aedtapp.modeler.create_cylinder( + self.aedtapp.PLANE.XY, udp, 3, coax_dimension, 0, name="MyCylinder", material="brass" + ) + + udp = self.aedtapp.modeler.Position(10, 10, 0) + coax_dimension = 30 + o2 = self.aedtapp.modeler.create_cylinder( + self.aedtapp.PLANE.XY, udp, 3, coax_dimension, 0, name="GND", material="brass" + ) + + self.aedtapp.auto_identify_nets() self.aedtapp.modeler.create_circle(self.aedtapp.PLANE.XY, [0, 0, 0], 4, name="Source1") - self.aedtapp.modeler.create_circle(self.aedtapp.PLANE.XY, [10, 10, 10], 4, name="Sink1") + self.aedtapp.modeler.create_circle(self.aedtapp.PLANE.XY, [0, 0, coax_dimension], 4, name="Sink1") + + self.aedtapp.modeler.create_circle(self.aedtapp.PLANE.XY, [10, 10, 0], 4, name="Source2") + self.aedtapp.modeler.create_circle(self.aedtapp.PLANE.XY, [10, 10, coax_dimension], 4, name="Sink2") source = self.aedtapp.source("Source1", name="Source3") sink = self.aedtapp.sink("Sink1", name="Sink3") + assert source.name == "Source3" assert sink.name == "Sink3" assert source.props["TerminalType"] == "ConstantVoltage" @@ -193,19 +212,20 @@ def test_07B_create_source_tosheet(self): self.aedtapp.modeler.delete("Source1") self.aedtapp.modeler.delete("Sink1") + self.aedtapp.modeler.create_circle(self.aedtapp.PLANE.XY, [0, 0, 0], 4, name="Source1") - self.aedtapp.modeler.create_circle(self.aedtapp.PLANE.XY, [10, 10, 10], 4, name="Sink1") + self.aedtapp.modeler.create_circle(self.aedtapp.PLANE.XY, [0, 0, coax_dimension], 4, name="Sink1") + source = self.aedtapp.source("Source1", name="Source3", terminal_type="current") sink = self.aedtapp.sink("Sink1", name="Sink3", terminal_type="current") + assert source.props["TerminalType"] == "UniformCurrent" assert sink.props["TerminalType"] == "UniformCurrent" - self.aedtapp.modeler.create_circle(self.aedtapp.PLANE.XY, [0, 0, 0], 4, name="Source1") - self.aedtapp.modeler.create_circle(self.aedtapp.PLANE.XY, [10, 10, 10], 4, name="Sink1") + source = self.aedtapp.source("Source2", name="Cylinder1", net_name="GND") + source.props["Objects"] = ["Source2"] + sink = self.aedtapp.sink("Sink2", net_name="GND") - source = self.aedtapp.source(["Source1", "Sink1"], name="Cylinder1", net_name="GND") - source.props["Objects"] = ["Source1"] - sink = self.aedtapp.sink("Sink1", net_name="GND") assert source assert sink sink.name = "My_new_name" From d7ab57e354414feb712afca87a9776d2456a6f95 Mon Sep 17 00:00:00 2001 From: Samuelopez-ansys Date: Thu, 19 Dec 2024 11:33:37 +0100 Subject: [PATCH 14/28] Fix HFSS test --- tests/system/general/test_20_HFSS.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/system/general/test_20_HFSS.py b/tests/system/general/test_20_HFSS.py index 5968ce166e5..572799e5995 100644 --- a/tests/system/general/test_20_HFSS.py +++ b/tests/system/general/test_20_HFSS.py @@ -1488,7 +1488,7 @@ def test_61_create_lumped_ports_on_object_driven_terminal(self): ) term = [term for term in self.aedtapp.boundaries if term.type == "Terminal"][0] - assert self.aedtapp.boundaries[0].type == "Terminal" + assert term.type == "Terminal" term.name = "test" assert term.name == "test" term.props["TerminalResistance"] = "1ohm" From 96c48f9302da6c414cf6fb96199e8b804bf2b905 Mon Sep 17 00:00:00 2001 From: Samuelopez-ansys Date: Thu, 19 Dec 2024 13:09:03 +0100 Subject: [PATCH 15/28] Fix Layout boundary --- src/ansys/aedt/core/application/design.py | 7 ++++++- src/ansys/aedt/core/modules/boundary/layout_boundary.py | 7 +++---- tests/system/solvers/test_31_Q3D.py | 4 ++-- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/ansys/aedt/core/application/design.py b/src/ansys/aedt/core/application/design.py index d3884f1f8cd..54795763700 100644 --- a/src/ansys/aedt/core/application/design.py +++ b/src/ansys/aedt/core/application/design.py @@ -85,6 +85,7 @@ from ansys.aedt.core.generic.load_aedt_file import load_entire_aedt_file from ansys.aedt.core.modules.boundary.common import BoundaryObject from ansys.aedt.core.modules.boundary.icepak_boundary import NetworkObject +from ansys.aedt.core.modules.boundary.layout_boundary import BoundaryObject3dLayout from ansys.aedt.core.modules.boundary.maxwell_boundary import MaxwellParameters if sys.version_info.major > 2: @@ -492,10 +493,14 @@ def boundaries(self) -> List[BoundaryObject]: self._boundaries[boundary] = NetworkObject(self, boundary) else: self._boundaries[boundary] = BoundaryObject(self, boundary, boundarytype=boundarytype) + try: for k, v in zip(current_excitations, current_excitation_types): if k not in self._boundaries: - self._boundaries[k] = BoundaryObject(self, k, boundarytype=v) + if self.design_type == "HFSS 3D Layout Design" and v == "Port": + self._boundaries[k] = BoundaryObject3dLayout(self, k, props=None, boundarytype=v) + else: + self._boundaries[k] = BoundaryObject(self, k, boundarytype=v) except Exception: self.logger.info("Failed to design boundary object.") return list(self._boundaries.values()) diff --git a/src/ansys/aedt/core/modules/boundary/layout_boundary.py b/src/ansys/aedt/core/modules/boundary/layout_boundary.py index 51320093b04..937d58a4dd1 100644 --- a/src/ansys/aedt/core/modules/boundary/layout_boundary.py +++ b/src/ansys/aedt/core/modules/boundary/layout_boundary.py @@ -288,13 +288,13 @@ class BoundaryObject3dLayout(BoundaryCommon, BinaryTreeNode): An AEDT application from ``ansys.aedt.core.application``. name : str Name of the boundary. - props : dict + props : dict, optional Properties of the boundary. boundarytype : str Type of the boundary. """ - def __init__(self, app, name, props, boundarytype): + def __init__(self, app, name, props=None, boundarytype="Port"): self.auto_update = False self._app = app self._name = name @@ -303,8 +303,7 @@ def __init__(self, app, name, props, boundarytype): self.__props = BoundaryProps(self, props) self.type = boundarytype self.auto_update = True - if self._child_object: - BinaryTreeNode.__init__(self, self.name, self._child_object, False) + self._initialize_bynary_tree() @property def _child_object(self): diff --git a/tests/system/solvers/test_31_Q3D.py b/tests/system/solvers/test_31_Q3D.py index 6881893fc4f..e3e797308e5 100644 --- a/tests/system/solvers/test_31_Q3D.py +++ b/tests/system/solvers/test_31_Q3D.py @@ -185,13 +185,13 @@ def test_07b_create_source_to_sheet(self): udp = self.aedtapp.modeler.Position(0, 0, 0) coax_dimension = 30 - o1 = self.aedtapp.modeler.create_cylinder( + self.aedtapp.modeler.create_cylinder( self.aedtapp.PLANE.XY, udp, 3, coax_dimension, 0, name="MyCylinder", material="brass" ) udp = self.aedtapp.modeler.Position(10, 10, 0) coax_dimension = 30 - o2 = self.aedtapp.modeler.create_cylinder( + self.aedtapp.modeler.create_cylinder( self.aedtapp.PLANE.XY, udp, 3, coax_dimension, 0, name="GND", material="brass" ) From 720e5b5a5a146e33def19e9f5657818e13ca345c Mon Sep 17 00:00:00 2001 From: mcapodif Date: Thu, 19 Dec 2024 15:50:04 +0100 Subject: [PATCH 16/28] Fix unit tests --- .../aedt/core/modeler/cad/elements_3d.py | 6 ++- .../aedt/core/modules/boundary/common.py | 3 +- .../core/modules/boundary/layout_boundary.py | 43 ++++++++----------- .../core/modules/boundary/maxwell_boundary.py | 16 +++---- tests/system/general/test_98_Icepak.py | 6 +++ 5 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/ansys/aedt/core/modeler/cad/elements_3d.py b/src/ansys/aedt/core/modeler/cad/elements_3d.py index c62acd0a44a..15781a39df1 100644 --- a/src/ansys/aedt/core/modeler/cad/elements_3d.py +++ b/src/ansys/aedt/core/modeler/cad/elements_3d.py @@ -1464,14 +1464,18 @@ def update_property(self, prop_name, prop_value): bool ``True`` when successful, ``False`` when failed. """ + if prop_value is None: + settings.logger.warning(f"Property {prop_name} set to None ignored.") + return try: result = self.child_object.SetPropValue(prop_name, prop_value) if result: if prop_name == "Name" and getattr(self, "_name", False): setattr(self, "_name", prop_value) else: + settings.logger.warning(f"Property {prop_name} is read-only.") # Property Name duplicated - raise KeyError + return except Exception: # pragma: no cover # Property read-only raise KeyError diff --git a/src/ansys/aedt/core/modules/boundary/common.py b/src/ansys/aedt/core/modules/boundary/common.py index 2583a196ce0..9bb6c2bc9cf 100644 --- a/src/ansys/aedt/core/modules/boundary/common.py +++ b/src/ansys/aedt/core/modules/boundary/common.py @@ -681,8 +681,7 @@ def update(self): self._app.oboundary.EditResistiveSheet(self.name, self._get_args()) else: return False # pragma: no cover - # self._app._boundaries[self.name] = self._app._boundaries.pop(self._boundary_name) - # self._boundary_name = self.name + return True @pyaedt_function_handler() diff --git a/src/ansys/aedt/core/modules/boundary/layout_boundary.py b/src/ansys/aedt/core/modules/boundary/layout_boundary.py index 937d58a4dd1..cf8f8de4987 100644 --- a/src/ansys/aedt/core/modules/boundary/layout_boundary.py +++ b/src/ansys/aedt/core/modules/boundary/layout_boundary.py @@ -118,10 +118,11 @@ def _child_object(self): """ child_object = None - design_childs = self._app.get_oo_name(self._app.oeditor) - - if self._name in design_childs: - child_object = self._app.get_oo_object(self._app.oeditor, self._name) + for el in self._app.oeditor.GetChildNames("ComponentDefinition"): + design_childs = self._app.get_oo_object(self._app.oeditor, el).GetChildNames() + if self._name in design_childs: + child_object = self._app.get_oo_object(self._app.oeditor, f"{el}\\{self._name}") + break return child_object @property @@ -130,29 +131,21 @@ def props(self): @property def name(self): - """Name of the object. - - Returns - ------- - str - Name of the object. - - """ + """Boundary Name.""" + if self._child_object: + self._name = self.properties["Name"] return self._name @name.setter - def name(self, component_name): - if component_name != self._name: - if component_name not in self._app.native_component_names and self._child_object: - try: - self.properties["Name"] = component_name - self._app.native_components.update({component_name: self}) - del self._app.native_components[self._name] - del self._app.modeler.user_defined_components[self._name] - except KeyError: - self._app.logger.error("Name %s already assigned in the design", component_name) - else: # pragma: no cover - self._app._logger.warning("Name %s already assigned in the design", component_name) + def name(self, value): + if self._child_object: + try: + legacy_name = self._name + self.properties["Name"] = value + self._app.modeler.user_defined_components[self._name] = self + del self._app.modeler.user_defined_components[legacy_name] + except KeyError: + self._app.logger.error("Name %s already assigned in the design", value) @property def definition_name(self): @@ -224,7 +217,7 @@ def create(self): a = [i for i in self._app.excitations if i not in names] self.excitation_name = a[0].split(":")[0] except (GrpcApiError, IndexError): - self.excitation_name = self.name + self.excitation_name = self._name self._initialize_bynary_tree() return True diff --git a/src/ansys/aedt/core/modules/boundary/maxwell_boundary.py b/src/ansys/aedt/core/modules/boundary/maxwell_boundary.py index 4577dcf09f7..e7fb6013269 100644 --- a/src/ansys/aedt/core/modules/boundary/maxwell_boundary.py +++ b/src/ansys/aedt/core/modules/boundary/maxwell_boundary.py @@ -62,7 +62,6 @@ def __init__(self, app, name, props=None, boundarytype=None): self._name = name self.__props = BoundaryProps(self, props) if props else {} self.type = boundarytype - self._boundary_name = self.name self.auto_update = True self.__reduced_matrices = None self.matrix_assignment = None @@ -98,10 +97,10 @@ def _child_object(self): cc = self._app.odesign.GetChildObject("Parameters") child_object = None - if self.name in cc.GetChildNames(): - child_object = self._app.odesign.GetChildObject("Parameters").GetChildObject(self.name) - elif self.name in self._app.odesign.GetChildObject("Parameters").GetChildNames(): - child_object = self._app.odesign.GetChildObject("Parameters").GetChildObject(self.name) + if self._name in cc.GetChildNames(): + child_object = self._app.odesign.GetChildObject("Parameters").GetChildObject(self._name) + elif self._name in self._app.odesign.GetChildObject("Parameters").GetChildNames(): + child_object = self._app.odesign.GetChildObject("Parameters").GetChildObject(self._name) return child_object @@ -192,14 +191,13 @@ def update(self): """ if self.type == "Matrix": - self._app.o_maxwell_parameters.EditMatrix(self._boundary_name, self._get_args()) + self._app.o_maxwell_parameters.EditMatrix(self.name, self._get_args()) elif self.type == "Force": - self._app.o_maxwell_parameters.EditForce(self._boundary_name, self._get_args()) + self._app.o_maxwell_parameters.EditForce(self.name, self._get_args()) elif self.type == "Torque": - self._app.o_maxwell_parameters.EditTorque(self._boundary_name, self._get_args()) + self._app.o_maxwell_parameters.EditTorque(self.name, self._get_args()) else: return False - self._boundary_name = self.name return True @pyaedt_function_handler() diff --git a/tests/system/general/test_98_Icepak.py b/tests/system/general/test_98_Icepak.py index 7fddff4754f..54848cda534 100644 --- a/tests/system/general/test_98_Icepak.py +++ b/tests/system/general/test_98_Icepak.py @@ -659,6 +659,12 @@ def test_35_create_fan(self): fan = self.aedtapp.create_fan("Fan1", cross_section="YZ", radius="15mm", hub_radius="5mm", origin=[5, 21, 1]) assert fan assert fan.name in self.aedtapp.modeler.oeditor.Get3DComponentInstanceNames(fan.definition_name)[0] + fan.name = "Fan2" + assert fan.name in self.aedtapp.modeler.oeditor.Get3DComponentInstanceNames(fan.definition_name)[0] + assert fan.name in self.aedtapp.modeler.user_defined_components + assert fan.name in self.aedtapp.native_components + assert not "Fan1" in self.aedtapp.native_components + assert not "Fan1" in self.aedtapp.modeler.user_defined_components self.aedtapp.delete_design() def test_36_create_heat_sink(self): From 07476909a6b9f0a226989f701307f9730195d7e4 Mon Sep 17 00:00:00 2001 From: mcapodif Date: Thu, 19 Dec 2024 17:00:24 +0100 Subject: [PATCH 17/28] Fix unit tests --- .../aedt/core/modules/boundary/common.py | 10 ++++++---- .../core/modules/boundary/hfss_boundary.py | 5 ++--- .../core/modules/boundary/layout_boundary.py | 5 ++--- .../core/modules/boundary/maxwell_boundary.py | 5 ++--- src/ansys/aedt/core/modules/mesh.py | 7 ++++--- src/ansys/aedt/core/modules/solve_setup.py | 19 +++++++++---------- .../general/test_01_configuration_files.py | 1 + 7 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/ansys/aedt/core/modules/boundary/common.py b/src/ansys/aedt/core/modules/boundary/common.py index 9bb6c2bc9cf..74596de741b 100644 --- a/src/ansys/aedt/core/modules/boundary/common.py +++ b/src/ansys/aedt/core/modules/boundary/common.py @@ -96,6 +96,8 @@ def _get_args(self, props=None): def _initialize_bynary_tree(self): if self._child_object: BinaryTreeNode.__init__(self, self._name, self._child_object, False) + return True + return False @pyaedt_function_handler() def delete(self): @@ -324,7 +326,7 @@ def type(self, value): def name(self): """Boundary Name.""" if self._child_object: - self._name = self.properties["Name"] + self._name = str(self.properties["Name"]) return self._name @name.setter @@ -523,10 +525,12 @@ def create(self): ) elif bound_type == "SBRTxRxSettings": self._app.oboundary.SetSBRTxRxSettings(self._get_args()) + return True elif bound_type == "EndConnection": self._app.oboundary.AssignEndConnection(self._get_args()) elif bound_type == "Hybrid": self._app.oboundary.AssignHybridRegion(self._get_args()) + return True elif bound_type == "FluxTangential": self._app.oboundary.AssignFluxTangential(self._get_args()) elif bound_type == "Plane Incident Wave": @@ -536,9 +540,7 @@ def create(self): else: return False - self._initialize_bynary_tree() - - return True + return self._initialize_bynary_tree() @pyaedt_function_handler() def update(self): diff --git a/src/ansys/aedt/core/modules/boundary/hfss_boundary.py b/src/ansys/aedt/core/modules/boundary/hfss_boundary.py index eec74a73450..3932aec0fd3 100644 --- a/src/ansys/aedt/core/modules/boundary/hfss_boundary.py +++ b/src/ansys/aedt/core/modules/boundary/hfss_boundary.py @@ -95,7 +95,7 @@ def props(self): def name(self): """Boundary Name.""" if self._child_object: - self._name = self.properties["Name"] + self._name = str(self.properties["Name"]) return self._name @name.setter @@ -138,8 +138,7 @@ def create(self): self._app.oradfield.AddAntennaOverlay(self._get_args()) elif self.type == "FieldSourceGroup": self._app.oradfield.AddRadFieldSourceGroup(self._get_args()) - self._initialize_bynary_tree() - return True + return self._initialize_bynary_tree() @pyaedt_function_handler() def update(self): diff --git a/src/ansys/aedt/core/modules/boundary/layout_boundary.py b/src/ansys/aedt/core/modules/boundary/layout_boundary.py index cf8f8de4987..18a77b1fa40 100644 --- a/src/ansys/aedt/core/modules/boundary/layout_boundary.py +++ b/src/ansys/aedt/core/modules/boundary/layout_boundary.py @@ -133,7 +133,7 @@ def props(self): def name(self): """Boundary Name.""" if self._child_object: - self._name = self.properties["Name"] + self._name = str(self.properties["Name"]) return self._name @name.setter @@ -218,8 +218,7 @@ def create(self): self.excitation_name = a[0].split(":")[0] except (GrpcApiError, IndexError): self.excitation_name = self._name - self._initialize_bynary_tree() - return True + return self._initialize_bynary_tree() @pyaedt_function_handler() def update(self): diff --git a/src/ansys/aedt/core/modules/boundary/maxwell_boundary.py b/src/ansys/aedt/core/modules/boundary/maxwell_boundary.py index e7fb6013269..b21f8c8697b 100644 --- a/src/ansys/aedt/core/modules/boundary/maxwell_boundary.py +++ b/src/ansys/aedt/core/modules/boundary/maxwell_boundary.py @@ -125,7 +125,7 @@ def props(self): def name(self): """Boundary Name.""" if self._child_object: - self._name = self.properties["Name"] + self._name = str(self.properties["Name"]) return self._name @name.setter @@ -177,8 +177,7 @@ def create(self): self._app.o_maxwell_parameters.AssignLayoutForce(self._get_args()) else: return False - self._initialize_bynary_tree() - return True + return self._initialize_bynary_tree() @pyaedt_function_handler() def update(self): diff --git a/src/ansys/aedt/core/modules/mesh.py b/src/ansys/aedt/core/modules/mesh.py index d95d5b4d9c0..7c5fbcf5772 100644 --- a/src/ansys/aedt/core/modules/mesh.py +++ b/src/ansys/aedt/core/modules/mesh.py @@ -212,7 +212,7 @@ def name(self): """ if self._child_object: - self._name = self.properties["Name"] + self._name = str(self.properties["Name"]) return self._name @name.setter @@ -259,8 +259,7 @@ def create(self): self._mesh.omeshmodule.AssignCylindricalGapOp(self._get_args()) else: return False - self._initialize_bynary_tree() - return True + return self._initialize_bynary_tree() @pyaedt_function_handler() def update(self, key_name=None, value=None): @@ -409,6 +408,8 @@ def delete(self): def _initialize_bynary_tree(self): if self._child_object: BinaryTreeNode.__init__(self, self._name, self._child_object, False) + return True + return False class Mesh(object): diff --git a/src/ansys/aedt/core/modules/solve_setup.py b/src/ansys/aedt/core/modules/solve_setup.py index 584c7fa3027..f27e155f0e3 100644 --- a/src/ansys/aedt/core/modules/solve_setup.py +++ b/src/ansys/aedt/core/modules/solve_setup.py @@ -97,6 +97,8 @@ def _child_object(self): def _initialize_bynary_tree(self): if self._child_object: BinaryTreeNode.__init__(self, self._name, self._child_object, False) + return True + return False @property def sweeps(self): @@ -556,8 +558,8 @@ def create(self): Returns ------- - dict - Dictionary of arguments. + bool + Result of operation. References ---------- @@ -567,8 +569,7 @@ def create(self): arg = ["NAME:" + self._name] _dict2arg(self.props, arg) self.omodule.InsertSetup(soltype, arg) - self._initialize_bynary_tree() - return arg + return self._initialize_bynary_tree() @pyaedt_function_handler(update_dictionary="properties") def update(self, properties=None): @@ -1155,8 +1156,8 @@ def create(self): Returns ------- - dict - Dictionary of the arguments. + bool + Result of operation. References ---------- @@ -1171,8 +1172,7 @@ def create(self): arg = ["NAME:SimSetup"] _dict2arg(self.props, arg) self._setup(soltype, arg) - self._initialize_bynary_tree() - return arg + return self._initialize_bynary_tree() @pyaedt_function_handler() def _setup(self, soltype, arg, newsetup=True): @@ -1913,8 +1913,7 @@ def create(self): arg = ["NAME:" + self.name] _dict2arg(self.props, arg) self.omodule.Add(arg) - self._initialize_bynary_tree() - return True + return self._initialize_bynary_tree() @pyaedt_function_handler(update_dictionary="properties") def update(self, properties=None): diff --git a/tests/system/general/test_01_configuration_files.py b/tests/system/general/test_01_configuration_files.py index 05168479c8e..27045e04704 100644 --- a/tests/system/general/test_01_configuration_files.py +++ b/tests/system/general/test_01_configuration_files.py @@ -97,6 +97,7 @@ def hfss3dl_b(add_app): class TestClass: def test_01_hfss_export(self, aedtapp, add_app): aedtapp.mesh.assign_length_mesh("sub") + aedtapp.boundaries[-1].props conf_file = aedtapp.configurations.export_config() assert aedtapp.configurations.validate(conf_file) filename = aedtapp.design_name From e6c0e3957c609a3cc0d851fe6328fa28b2711ea1 Mon Sep 17 00:00:00 2001 From: mcapodif Date: Thu, 19 Dec 2024 17:06:36 +0100 Subject: [PATCH 18/28] Fix unit tests --- src/ansys/aedt/core/modules/boundary/common.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ansys/aedt/core/modules/boundary/common.py b/src/ansys/aedt/core/modules/boundary/common.py index 74596de741b..d3cbb5119dc 100644 --- a/src/ansys/aedt/core/modules/boundary/common.py +++ b/src/ansys/aedt/core/modules/boundary/common.py @@ -380,6 +380,7 @@ def create(self): self._app.oboundary.AssignRadiation(self._get_args()) elif bound_type == "FE-BI": self._app.oboundary.AssignFEBI(self._get_args()) + return True elif bound_type == "Finite Conductivity": self._app.oboundary.AssignFiniteCond(self._get_args()) elif bound_type == "Lumped RLC": From 6ebf83000bbe81b47a02ff6cd0cdd14ab8b4fe97 Mon Sep 17 00:00:00 2001 From: mcapodif Date: Thu, 19 Dec 2024 17:50:57 +0100 Subject: [PATCH 19/28] Fix unit tests --- src/ansys/aedt/core/modules/boundary/common.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ansys/aedt/core/modules/boundary/common.py b/src/ansys/aedt/core/modules/boundary/common.py index d3cbb5119dc..f98878761cd 100644 --- a/src/ansys/aedt/core/modules/boundary/common.py +++ b/src/ansys/aedt/core/modules/boundary/common.py @@ -419,6 +419,7 @@ def create(self): self._app.oboundary.AssignDependent(self._get_args()) elif bound_type == "Band": self._app.omodelsetup.AssignBand(self._get_args()) + return True elif bound_type == "InfiniteGround": self._app.oboundary.AssignInfiniteGround(self._get_args()) elif bound_type == "ThinConductor": From 9144bf7bba61044843c9948cc44824ea1c34ddb2 Mon Sep 17 00:00:00 2001 From: mcapodif Date: Thu, 19 Dec 2024 18:52:26 +0100 Subject: [PATCH 20/28] Fix unit tests --- src/ansys/aedt/core/modules/boundary/common.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ansys/aedt/core/modules/boundary/common.py b/src/ansys/aedt/core/modules/boundary/common.py index f98878761cd..d3cbb5119dc 100644 --- a/src/ansys/aedt/core/modules/boundary/common.py +++ b/src/ansys/aedt/core/modules/boundary/common.py @@ -419,7 +419,6 @@ def create(self): self._app.oboundary.AssignDependent(self._get_args()) elif bound_type == "Band": self._app.omodelsetup.AssignBand(self._get_args()) - return True elif bound_type == "InfiniteGround": self._app.oboundary.AssignInfiniteGround(self._get_args()) elif bound_type == "ThinConductor": From c983ef5318b0bbbf81a8521e93024d369be60121 Mon Sep 17 00:00:00 2001 From: mcapodif Date: Thu, 19 Dec 2024 20:25:58 +0100 Subject: [PATCH 21/28] Fix unit tests --- src/ansys/aedt/core/modules/boundary/common.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ansys/aedt/core/modules/boundary/common.py b/src/ansys/aedt/core/modules/boundary/common.py index d3cbb5119dc..f98878761cd 100644 --- a/src/ansys/aedt/core/modules/boundary/common.py +++ b/src/ansys/aedt/core/modules/boundary/common.py @@ -419,6 +419,7 @@ def create(self): self._app.oboundary.AssignDependent(self._get_args()) elif bound_type == "Band": self._app.omodelsetup.AssignBand(self._get_args()) + return True elif bound_type == "InfiniteGround": self._app.oboundary.AssignInfiniteGround(self._get_args()) elif bound_type == "ThinConductor": From bb447e765c88933313e5431229387cb11ea0472f Mon Sep 17 00:00:00 2001 From: mcapodif Date: Thu, 19 Dec 2024 21:32:12 +0100 Subject: [PATCH 22/28] Fix unit tests --- src/ansys/aedt/core/modeler/cad/elements_3d.py | 2 ++ src/ansys/aedt/core/modules/boundary/common.py | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ansys/aedt/core/modeler/cad/elements_3d.py b/src/ansys/aedt/core/modeler/cad/elements_3d.py index 15781a39df1..faef147fac4 100644 --- a/src/ansys/aedt/core/modeler/cad/elements_3d.py +++ b/src/ansys/aedt/core/modeler/cad/elements_3d.py @@ -1417,6 +1417,8 @@ def properties(self): :class:``ansys.aedt.coree.modeler.cad.elements_3d.HistoryProps`` """ self._props = {} + if not getattr(self, "child_object", None): + return self._props if settings.aedt_version >= "2024.2": try: from ansys.aedt.core.application import _get_data_model diff --git a/src/ansys/aedt/core/modules/boundary/common.py b/src/ansys/aedt/core/modules/boundary/common.py index f98878761cd..b6cb0e6872f 100644 --- a/src/ansys/aedt/core/modules/boundary/common.py +++ b/src/ansys/aedt/core/modules/boundary/common.py @@ -325,13 +325,13 @@ def type(self, value): @property def name(self): """Boundary Name.""" - if self._child_object: + if getattr(self, "child_object", None): self._name = str(self.properties["Name"]) return self._name @name.setter def name(self, value): - if self._child_object: + if getattr(self, "child_object", None): try: self.properties["Name"] = value self._app._boundaries[value] = self From 7c8a449f869af235d95ee4d47ea04df456199a9d Mon Sep 17 00:00:00 2001 From: mcapodif Date: Thu, 19 Dec 2024 21:45:47 +0100 Subject: [PATCH 23/28] Fix unit tests --- src/ansys/aedt/core/visualization/report/common.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ansys/aedt/core/visualization/report/common.py b/src/ansys/aedt/core/visualization/report/common.py index 21f67485d8a..b4365ce54f9 100644 --- a/src/ansys/aedt/core/visualization/report/common.py +++ b/src/ansys/aedt/core/visualization/report/common.py @@ -418,7 +418,7 @@ def _initialize_tree_node(self): if self._is_created: oo = self._post.oreportsetup.GetChildObject(self._legacy_props["plot_name"]) if oo: - BinaryTreeNode.__init__(self, self.plot_name, oo, False) + BinaryTreeNode.__init__(self, self._legacy_props["plot_name"], oo, False) @property def __all_props(self): @@ -1314,6 +1314,7 @@ def create(self, name=None): bool ``True`` when successful, ``False`` when failed. """ + self._is_created = False if not name: self.plot_name = generate_unique_name("Plot") else: From fbbcc24166160d7bfc6a3745fb7bd8fd7447991e Mon Sep 17 00:00:00 2001 From: mcapodif Date: Thu, 19 Dec 2024 22:30:01 +0100 Subject: [PATCH 24/28] Speedup BinaryTreeNode --- .../aedt/core/modeler/cad/elements_3d.py | 44 +++++++++++++------ .../core/visualization/post/solution_data.py | 12 +++-- 2 files changed, 39 insertions(+), 17 deletions(-) diff --git a/src/ansys/aedt/core/modeler/cad/elements_3d.py b/src/ansys/aedt/core/modeler/cad/elements_3d.py index faef147fac4..0971702026f 100644 --- a/src/ansys/aedt/core/modeler/cad/elements_3d.py +++ b/src/ansys/aedt/core/modeler/cad/elements_3d.py @@ -1370,43 +1370,59 @@ def __init__(self, node, child_object, first_level=False, get_child_obj_arg=None self._props = None if not root_name: root_name = node - saved_root_name = node if first_level else root_name + self._saved_root_name = node if first_level else root_name + self._get_child_obj_arg = get_child_obj_arg self._node = node self.child_object = child_object - self.children = {} self.auto_update = True + self._first_level = first_level + self._children = {} + + def _update_children(self): + self._children = {} name = None try: - if get_child_obj_arg is None: - child_names = [i for i in list(child_object.GetChildNames()) if not i.startswith("CachedBody")] + if self._get_child_obj_arg is None: + child_names = [i for i in list(self.child_object.GetChildNames()) if not i.startswith("CachedBody")] else: child_names = [ - i for i in list(child_object.GetChildNames(get_child_obj_arg)) if not i.startswith("CachedBody") + i + for i in list(self.child_object.GetChildNames(self._get_child_obj_arg)) + if not i.startswith("CachedBody") ] except Exception: # pragma: no cover child_names = [] for i in child_names: if not name: name = i - if i == "OperandPart_" + saved_root_name or i == "OperandPart_" + saved_root_name.split("_")[0]: + if i == "OperandPart_" + self._saved_root_name or i == "OperandPart_" + self._saved_root_name.split("_")[0]: continue elif not i.startswith("OperandPart_"): try: - self.children[i] = BinaryTreeNode(i, self.child_object.GetChildObject(i), root_name=saved_root_name) + self._children[i] = BinaryTreeNode( + i, self.child_object.GetChildObject(i), root_name=self._saved_root_name + ) except Exception: # nosec pass else: names = self.child_object.GetChildObject(i).GetChildNames() for name in names: - self.children[name] = BinaryTreeNode( - name, self.child_object.GetChildObject(i).GetChildObject(name), root_name=saved_root_name + self._children[name] = BinaryTreeNode( + name, self.child_object.GetChildObject(i).GetChildObject(name), root_name=self._saved_root_name ) - if first_level: - self.child_object = self.children[name].child_object - self._props = self.children[name]._props + if self._first_level: + + self.child_object = self._children[name].child_object + self._props = self._children[name].properties if name == "CreatePolyline:1": - self.segments = self.children[name].children - del self.children[name] + self.segments = self._children[name].children + del self._children[name] + + @property + def children(self): + if not self._children: + self._update_children() + return self._children @property def properties(self): diff --git a/src/ansys/aedt/core/visualization/post/solution_data.py b/src/ansys/aedt/core/visualization/post/solution_data.py index ef9e3a6e6de..aa24e3212ad 100644 --- a/src/ansys/aedt/core/visualization/post/solution_data.py +++ b/src/ansys/aedt/core/visualization/post/solution_data.py @@ -962,9 +962,15 @@ def plot_3d( min_r = 1e12 max_r = -1e12 - for el in r: - min_r = min(min_r, el.values.min()) - max_r = max(max_r, el.values.max()) + if self.enable_pandas_output: + for el in r: + min_r = min(min_r, el.values.min()) + max_r = max(max_r, el.values.max()) + else: + for el in r: + min_r = min(min_r, min(el)) + max_r = max(max_r, max(el)) + if min_r < 0: r = [i + np.abs(min_r) for i in r] theta_grid, phi_grid = np.meshgrid(theta, phi) From 5eaea717c5727994f435290ad10e5a3c25406bdb Mon Sep 17 00:00:00 2001 From: mcapodif Date: Thu, 19 Dec 2024 22:55:14 +0100 Subject: [PATCH 25/28] Speedup BinaryTreeNode --- src/ansys/aedt/core/modeler/cad/elements_3d.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ansys/aedt/core/modeler/cad/elements_3d.py b/src/ansys/aedt/core/modeler/cad/elements_3d.py index 0971702026f..68a9da74c44 100644 --- a/src/ansys/aedt/core/modeler/cad/elements_3d.py +++ b/src/ansys/aedt/core/modeler/cad/elements_3d.py @@ -1377,6 +1377,8 @@ def __init__(self, node, child_object, first_level=False, get_child_obj_arg=None self.auto_update = True self._first_level = first_level self._children = {} + if self._first_level: + self._update_children() def _update_children(self): self._children = {} From 2a6bef15ea94910d0594a4ebfb5dca2badab51d3 Mon Sep 17 00:00:00 2001 From: mcapodif Date: Thu, 19 Dec 2024 22:56:49 +0100 Subject: [PATCH 26/28] Speedup BinaryTreeNode --- src/ansys/aedt/core/hfss.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ansys/aedt/core/hfss.py b/src/ansys/aedt/core/hfss.py index b77bf3aa13d..3183bbaa4cf 100644 --- a/src/ansys/aedt/core/hfss.py +++ b/src/ansys/aedt/core/hfss.py @@ -251,6 +251,7 @@ def field_setups(self): List of :class:`ansys.aedt.core.modules.boundary.hfss_boundary.FarFieldSetup` and :class:`ansys.aedt.core.modules.hfss_boundary.NearFieldSetup` """ + self._field_setups = [] for field in self.field_setup_names: obj_field = self.odesign.GetChildObject("Radiation").GetChildObject(field) type_field = obj_field.GetPropValue("Type") From 89a230c7aa3fa02967754afdc4474297a1876851 Mon Sep 17 00:00:00 2001 From: mcapodif Date: Thu, 19 Dec 2024 23:07:18 +0100 Subject: [PATCH 27/28] Speedup BinaryTreeNode --- src/ansys/aedt/core/modeler/cad/elements_3d.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ansys/aedt/core/modeler/cad/elements_3d.py b/src/ansys/aedt/core/modeler/cad/elements_3d.py index 68a9da74c44..bcc07872cae 100644 --- a/src/ansys/aedt/core/modeler/cad/elements_3d.py +++ b/src/ansys/aedt/core/modeler/cad/elements_3d.py @@ -1375,9 +1375,9 @@ def __init__(self, node, child_object, first_level=False, get_child_obj_arg=None self._node = node self.child_object = child_object self.auto_update = True - self._first_level = first_level self._children = {} - if self._first_level: + self.__first_level = first_level + if first_level: self._update_children() def _update_children(self): @@ -1412,7 +1412,7 @@ def _update_children(self): self._children[name] = BinaryTreeNode( name, self.child_object.GetChildObject(i).GetChildObject(name), root_name=self._saved_root_name ) - if self._first_level: + if self.__first_level: self.child_object = self._children[name].child_object self._props = self._children[name].properties From 923eb3e307b86eeed3b53cef9357018c367853c2 Mon Sep 17 00:00:00 2001 From: mcapodif Date: Thu, 19 Dec 2024 23:20:49 +0100 Subject: [PATCH 28/28] Speedup BinaryTreeNode --- src/ansys/aedt/core/modeler/cad/elements_3d.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ansys/aedt/core/modeler/cad/elements_3d.py b/src/ansys/aedt/core/modeler/cad/elements_3d.py index bcc07872cae..78c25db6661 100644 --- a/src/ansys/aedt/core/modeler/cad/elements_3d.py +++ b/src/ansys/aedt/core/modeler/cad/elements_3d.py @@ -1412,8 +1412,7 @@ def _update_children(self): self._children[name] = BinaryTreeNode( name, self.child_object.GetChildObject(i).GetChildObject(name), root_name=self._saved_root_name ) - if self.__first_level: - + if name and self.__first_level: self.child_object = self._children[name].child_object self._props = self._children[name].properties if name == "CreatePolyline:1":