From 786a163403f0b8d1abcce267fcb396eb268cefd1 Mon Sep 17 00:00:00 2001 From: Nayane Fernandes <143632290+ansnfernand@users.noreply.github.com> Date: Thu, 1 Aug 2024 16:18:46 +0200 Subject: [PATCH 01/25] New API: add_modeling_region() --- src/ansys/sherlock/core/errors.py | 17 ++ src/ansys/sherlock/core/layer.py | 278 ++++++++++++++++++++++++++++++ tests/test_layer.py | 157 ++++++++++++++++- 3 files changed, 449 insertions(+), 3 deletions(-) diff --git a/src/ansys/sherlock/core/errors.py b/src/ansys/sherlock/core/errors.py index 08457e3a4..28e8b1162 100644 --- a/src/ansys/sherlock/core/errors.py +++ b/src/ansys/sherlock/core/errors.py @@ -1183,3 +1183,20 @@ def __init__(self, message): def __str__(self): """Format error message.""" return f"Export FEA model error: {self.message}" + + +class SherlockAddModelingRegionError(Exception): + """Contains the errors raised when modeling regions for a project cannot be added.""" + + def __init__(self, message=None, error_array=None): + """Initialize error message.""" + self.message = message + self.error_array = error_array + + def str_itr(self): + """Format error message.""" + if self.message is None: + return [f"Add modeling region error: {error}" for error in self.error_array] + + assert self.error_array is None + return [f"Add modeling region error: {self.message}"] diff --git a/src/ansys/sherlock/core/layer.py b/src/ansys/sherlock/core/layer.py index a7602eaa4..4dd691d9e 100644 --- a/src/ansys/sherlock/core/layer.py +++ b/src/ansys/sherlock/core/layer.py @@ -16,8 +16,13 @@ from ansys.api.sherlock.v0 import SherlockLayerService_pb2 from ansys.api.sherlock.v0 import SherlockLayerService_pb2_grpc +from typing import Dict, List, Union + +from SherlockLayerService_pb2 import ModelingRegion + from ansys.sherlock.core import LOG from ansys.sherlock.core.errors import ( + SherlockAddModelingRegionError, SherlockAddPottingRegionError, SherlockDeleteAllICTFixturesError, SherlockDeleteAllMountPointsError, @@ -889,3 +894,276 @@ def export_all_mount_points( raise e return response.value + + def add_modeling_region( + self, + project: str, + modeling_regions: List[Dict[str, Union[str, float, bool, dict]]], + ): + """Add one or more modeling regions to a specific project. + + Parameters + ---------- + project : str + Name of the Sherlock project. + modeling_regions : list of dict + List of modeling regions to add. Each dictionary should contain: + - cca_name : str + Name of the CCA. + - region_id : str + Unique region ID of the modeling region. + - region_units : str + Units of the modeling region. + - model_mode : str + Mode that specifies how the region is used. Valid values are ``Enabled``, + ``Disabled`` and ``Excluded``. + - shape: PolygonalShape|RectangularShape|SlotShape|CircularShape|PCBShape + The shape of the modeling region. + - pcb_model_props : list + List of the PCB model parameters consisting of these properties: + + - export_model_type : str + The type of model to be generated for a given modeling region. + Valid values are ``Default``, ``Sherlock``, ``Sweep`` and ``None``. + - elem_order: str + The type of 3D elements to be created for the PCB in the modeling region. + Valid values are ``First_Order``, ``Second_Order`` and ``Solid_Shell``. + - max_mesh_size : float + The maximum size of the mesh to be used in the region. + - max_mesh_size_units : str + Units for the maximum mesh size. + - quads_preferred : bool + Whether to generate quad-shaped elements when creating the mesh if true. + - trace_model_props : list + List of the trace model parameters consisting of these properties: + + - trace_model_type : str + The specification of whether trace modeling should be performed + within the region. Valid values are ``Default``, ``Enabled`` and + ``Disabled``. + - elem_order: str, optional + The type of 3D elements to be created for the PCB in the modeling region. + Valid values are ``First_Order``, ``Second_Order`` and ``Solid_Shell``. + - trace_mesh_size : float, optional + The maximum mesh size to be used in the region when trace modeling + is enabled. + - trace_mesh_size_units: str, optional + Units for the maximum mesh size when trace modeling is enabled. + - region_id_replacement : str, optional + Represents a unique region id that will replace the existing regionId + value during an update. + + + Returns + ------- + int + Status code of the response. 0 for success. + + Examples + -------- + >>> from ansys.sherlock.core.launcher import launch_sherlock + >>> sherlock = launch_sherlock() + >>> sherlock.project.import_odb_archive( + "ODB++ Tutorial.tgz", + True, + True, + True, + True, + project="Tutorial Project", + cca_name="Card", + ) + >>> modeling_regions = [ + { + "cca_name": "Card", + "region_id": "Region001", + "region_units": "mm", + "model_mode": "Enabled", + "shape": PolygonalShape(points=[ + (0, 0), + (0, 6.35), + (9.77, 0) + ], rotation=87.8), + "pcb_model_props": { + "export_model_type": "Sherlock", + "elem_order": "First_Order", + "max_mesh_size": 0.5, + "max_mesh_size_units": "mm", + "quads_preferred": True + }, + "trace_model_props": { + "trace_model_type": "Enabled", + "elem_order": "Second_Order", + "trace_mesh_size": 0.3, + "trace_mesh_size_units": "mm" + } + } + ] + >>> result = sherlock.project.add_modeling_region("Tutorial Project", modeling_regions) + """ + try: + if not project: + raise SherlockAddModelingRegionError(message="Project name is invalid.") + + if not modeling_regions: + raise SherlockAddModelingRegionError(message="Modeling regions list is empty.") + + for region in modeling_regions: + if "cca_name" not in region or not region["cca_name"]: + raise SherlockAddModelingRegionError(message="CCA name is invalid.") + if "region_id" not in region or not region["region_id"]: + raise SherlockAddModelingRegionError(message="Region ID is invalid.") + if "region_units" not in region or not region["region_units"]: + raise SherlockAddModelingRegionError(message="Region units are invalid.") + if "shape" not in region: + raise SherlockAddModelingRegionError(message="Shape is missing.") + elif not isinstance( + region["shape"], + ( + PolygonalShape, + RectangularShape, + SlotShape, + CircularShape, + PCBShape, + ), + ): + raise SherlockAddModelingRegionError(message="Shape is not of a valid type.") + + pcb_model_props = region.get("pcb_model_props", {}) + if pcb_model_props: + if ( + "export_model_type" not in pcb_model_props + or pcb_model_props["export_model_type"] == "" + ): + raise SherlockAddModelingRegionError( + message="PCB model export " "type is invalid." + ) + if "elem_order" not in pcb_model_props or pcb_model_props["elem_order"] == "": + raise SherlockAddModelingRegionError( + message="PCB element " "order is invalid." + ) + if "max_mesh_size" not in pcb_model_props or not isinstance( + pcb_model_props["max_mesh_size"], float + ): + raise SherlockAddModelingRegionError( + message="PCB max mesh size " "is invalid." + ) + if "quads_preferred" not in pcb_model_props or not isinstance( + pcb_model_props["quads_preferred"], bool + ): + raise SherlockAddModelingRegionError( + message="PCB quads preferred " "is invalid." + ) + + trace_model_props = region.get("trace_model_props", {}) + if trace_model_props: + if ( + "trace_model_type" not in trace_model_props + or trace_model_props["trace_model_type"] == "" + ): + raise SherlockAddModelingRegionError( + message="Trace model type is " "invalid." + ) + + if not self._is_connection_up(): + LOG.error("There is no connection to a gRPC service.") + return + + add_modeling_region_request = SherlockLayerService_pb2.AddModelingRegionRequest() + add_modeling_region_request.project = project + + for region_request in modeling_regions: + modeling_region = add_modeling_region_request.modelingRegions.add() + modeling_region.ccaName = region_request["cca_name"] + modeling_region.regionId = region_request["region_id"] + modeling_region.regionUnits = region_request["region_units"] + modeling_region.modelMode = getattr( + SherlockLayerService_pb2.ModelingRegion.ModelingMode, + region_request["model_mode"], + ) + + shape = region_request["shape"] + if isinstance(shape, PolygonalShape): + polygonal_shape = modeling_region.polygonalShape + for point in shape.points: + polygonal_point = polygonal_shape.points.add() + polygonal_point.x = point[0] + polygonal_point.y = point[1] + polygonal_shape.rotation = shape.rotation + elif isinstance(shape, RectangularShape): + rectangular_shape = modeling_region.rectangularShape + for point in shape.points: + rectangular_point = rectangular_shape.points.add() + rectangular_point.x = point[0] + rectangular_point.y = point[1] + rectangular_shape.rotation = shape.rotation + elif isinstance(shape, SlotShape): + slot_shape = modeling_region.slotShape + for point in shape.points: + slot_point = slot_shape.points.add() + slot_point.x = point[0] + slot_point.y = point[1] + slot_shape.rotation = shape.rotation + elif isinstance(shape, CircularShape): + circular_shape = modeling_region.circularShape + for point in shape.points: + circular_point = circular_shape.points.add() + circular_point.x = point[0] + circular_point.y = point[1] + circular_shape.rotation = shape.rotation + else: + raise SherlockAddModelingRegionError( + message="Shape is not of a valid type." + ) + + ExportModelType = ModelingRegion.PCBModelingProperties.ExportModelType + pcb_model_props = region_request.get("pcb_model_props", {}) + modeling_region.pcbModelProps.exportModelType = getattr( + ExportModelType, + pcb_model_props["export_model_type"], + ) + modeling_region.pcbModelProps.elemOrder = getattr( + SherlockLayerService_pb2.ModelingRegion.ElementOrder, + pcb_model_props["elem_order"], + ) + modeling_region.pcbModelProps.maxMeshSize = pcb_model_props["max_mesh_size"] + modeling_region.pcbModelProps.maxMeshSizeUnits = pcb_model_props[ + "max_mesh_size_units" + ] + modeling_region.pcbModelProps.quadsPreferred = pcb_model_props[ + "quads_preferred" + ] + + TraceModelingType = ModelingRegion.TraceModelingProperties.TraceModelingType + trace_model_props = region_request.get("trace_model_props", {}) + modeling_region.traceModelProps.traceModelType = getattr( + TraceModelingType, + trace_model_props["trace_model_type"], + ) + if "elem_order" in trace_model_props: + modeling_region.traceModelProps.elemOrder = getattr( + SherlockLayerService_pb2.ModelingRegion.ElementOrder, + trace_model_props["elem_order"], + ) + if "trace_mesh_size" in trace_model_props: + modeling_region.traceModelProps.traceMeshSize = trace_model_props[ + "trace_mesh_size" + ] + if "trace_mesh_size_units" in trace_model_props: + modeling_region.traceModelProps.traceMeshSizeUnits = trace_model_props[ + "trace_mesh_size_units" + ] + + if "region_id_replacement" in region_request: + modeling_region.regionIdReplacement = region_request[ + "region_id_replacement" + ] + + return_code = self.stub.addModelingRegion(add_modeling_region_request) + if return_code.value != 0: + raise SherlockAddModelingRegionError(message=return_code.message) + + return return_code.value + + except SherlockAddModelingRegionError as e: + LOG.error(str(e)) + raise e diff --git a/tests/test_layer.py b/tests/test_layer.py index ee0504277..b0edcc797 100644 --- a/tests/test_layer.py +++ b/tests/test_layer.py @@ -1,4 +1,5 @@ # © 2023-2024 ANSYS, Inc. All rights reserved +import copy import os import platform import uuid @@ -7,6 +8,7 @@ import pytest from ansys.sherlock.core.errors import ( + SherlockAddModelingRegionError, SherlockAddPottingRegionError, SherlockDeleteAllICTFixturesError, SherlockDeleteAllMountPointsError, @@ -35,9 +37,10 @@ def test_all(): helper_test_add_potting_region(layer) helper_test_update_test_fixtures_by_file(layer) helper_test_update_test_points_by_file(layer) - helper_test_export_all_mount_points(layer) - helper_test_export_all_test_fixtures(layer) - helper_test_export_all_test_points(layer) + # helper_test_export_all_mount_points(layer) + # helper_test_export_all_test_fixtures(layer) + # helper_test_export_all_test_points(layer) + helper_test_add_modeling_region(layer) def helper_test_add_potting_region(layer): @@ -718,5 +721,153 @@ def helper_test_export_all_mount_points(layer): assert type(e) == SherlockExportAllMountPoints +def helper_test_add_modeling_region(layer): + modeling_region_example = [ + { + "cca_name": "Card", + "region_id": "Region001", + "region_units": "mm", + "model_mode": "Enabled", + "shape": PolygonalShape(points=[(0, 0), (0, 6.35), (9.77, 0)], rotation=87.8), + "pcb_model_props": { + "export_model_type": "Sherlock", + "elem_order": "First_Order", + "max_mesh_size": 0.5, + "max_mesh_size_units": "mm", + "quads_preferred": True, + }, + "trace_model_props": { + "trace_model_type": "Enabled", + "elem_order": "Second_Order", + "trace_mesh_size": 0.3, + "trace_mesh_size_units": "mm", + }, + } + ] + + # Invalid project name + try: + layer.add_modeling_region("", modeling_region_example) + pytest.fail("No exception raised for invalid project name") + except SherlockAddModelingRegionError as e: + assert str(e.str_itr()) == "['Add modeling region error: Project name is invalid.']" + + # Empty modeling regions list + try: + layer.add_modeling_region("Tutorial Project", []) + pytest.fail("No exception raised for empty modeling regions list") + except SherlockAddModelingRegionError as e: + assert str(e.str_itr()) == "['Add modeling region error: Modeling regions list is empty.']" + + # Invalid CCA name + invalid_region = copy.deepcopy(modeling_region_example) + invalid_region[0]["cca_name"] = "" + try: + layer.add_modeling_region("Tutorial Project", invalid_region) + pytest.fail("No exception raised for invalid CCA name") + except SherlockAddModelingRegionError as e: + assert str(e.str_itr()) == "['Add modeling region error: CCA name is invalid.']" + + # Invalid region ID + invalid_region = copy.deepcopy(modeling_region_example) + invalid_region[0]["region_id"] = "" + try: + layer.add_modeling_region("Tutorial Project", invalid_region) + pytest.fail("No exception raised for invalid region ID") + except SherlockAddModelingRegionError as e: + assert str(e.str_itr()) == "['Add modeling region error: Region ID is invalid.']" + + # Invalid region units + invalid_region = copy.deepcopy(modeling_region_example) + invalid_region[0]["region_units"] = "" + try: + layer.add_modeling_region("Tutorial Project", invalid_region) + pytest.fail("No exception raised for invalid region units") + except SherlockAddModelingRegionError as e: + assert str(e.str_itr()) == "['Add modeling region error: Region units are invalid.']" + + # Missing shape + invalid_region = copy.deepcopy(modeling_region_example) + invalid_region[0].pop("shape") + try: + layer.add_modeling_region("Tutorial Project", invalid_region) + pytest.fail("No exception raised for missing shape") + except SherlockAddModelingRegionError as e: + assert str(e.str_itr()) == "['Add modeling region error: Shape is missing.']" + + # Invalid shape type + invalid_region = copy.deepcopy(modeling_region_example) + invalid_region[0]["shape"] = "InvalidShapeType" + try: + layer.add_modeling_region("Tutorial Project", invalid_region) + pytest.fail("No exception raised for invalid shape type") + except SherlockAddModelingRegionError as e: + assert str(e.str_itr()) == "['Add modeling region error: Shape is not of a valid type.']" + + # Invalid PCB model export type + invalid_region = copy.deepcopy(modeling_region_example) + invalid_region[0]["pcb_model_props"]["export_model_type"] = "" + try: + layer.add_modeling_region("Tutorial Project", invalid_region) + pytest.fail("No exception raised for invalid PCB model export type") + except SherlockAddModelingRegionError as e: + assert str(e.str_itr()) == ( + "['Add modeling region error: PCB model export type is " "invalid.']" + ) + + # Invalid PCB element order + invalid_region = copy.deepcopy(modeling_region_example) + invalid_region[0]["pcb_model_props"]["elem_order"] = "" + try: + layer.add_modeling_region("Tutorial Project", invalid_region) + pytest.fail("No exception raised for invalid PCB element order") + except SherlockAddModelingRegionError as e: + assert str(e.str_itr()) == "['Add modeling region error: PCB element order is invalid.']" + + # Invalid PCB max mesh size + invalid_region = copy.deepcopy(modeling_region_example) + invalid_region[0]["pcb_model_props"]["max_mesh_size"] = "not_a_float" + try: + layer.add_modeling_region("Tutorial Project", invalid_region) + pytest.fail("No exception raised for invalid PCB max mesh size") + except SherlockAddModelingRegionError as e: + assert str(e.str_itr()) == "['Add modeling region error: PCB max mesh size is invalid.']" + + # Invalid PCB quads preferred + invalid_region = copy.deepcopy(modeling_region_example) + invalid_region[0]["pcb_model_props"]["quads_preferred"] = "not_a_bool" + try: + layer.add_modeling_region("Tutorial Project", invalid_region) + pytest.fail("No exception raised for invalid PCB quads preferred") + except SherlockAddModelingRegionError as e: + assert str(e.str_itr()) == "['Add modeling region error: PCB quads preferred is invalid.']" + + # Invalid trace model type + invalid_region = copy.deepcopy(modeling_region_example) + invalid_region[0]["trace_model_props"]["trace_model_type"] = "" + try: + layer.add_modeling_region("Tutorial Project", invalid_region) + pytest.fail("No exception raised for invalid trace model type") + except SherlockAddModelingRegionError as e: + assert str(e.str_itr()) == "['Add modeling region error: Trace model type is invalid.']" + + if layer._is_connection_up(): + # Unhappy project name + try: + layer.add_modeling_region("Invalid Project", modeling_region_example) + pytest.fail("No exception raised for invalid project name") + except Exception as e: + assert type(e) == SherlockAddModelingRegionError + + # Valid request + try: + valid_region = copy.deepcopy(modeling_region_example) + valid_region[0]["cca_name"] = "Main Board" + result = layer.add_modeling_region("Tutorial Project", valid_region) + assert result == 0 + except SherlockAddModelingRegionError as e: + pytest.fail(str(e)) + + if __name__ == "__main__": test_all() From 2936523c36e6df8efcca44a71e908ca09449422a Mon Sep 17 00:00:00 2001 From: Nayane Fernandes <143632290+ansnfernand@users.noreply.github.com> Date: Thu, 1 Aug 2024 16:20:43 +0200 Subject: [PATCH 02/25] Fix unit tests --- tests/test_layer.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_layer.py b/tests/test_layer.py index b0edcc797..840ec8f5f 100644 --- a/tests/test_layer.py +++ b/tests/test_layer.py @@ -37,9 +37,9 @@ def test_all(): helper_test_add_potting_region(layer) helper_test_update_test_fixtures_by_file(layer) helper_test_update_test_points_by_file(layer) - # helper_test_export_all_mount_points(layer) - # helper_test_export_all_test_fixtures(layer) - # helper_test_export_all_test_points(layer) + helper_test_export_all_mount_points(layer) + helper_test_export_all_test_fixtures(layer) + helper_test_export_all_test_points(layer) helper_test_add_modeling_region(layer) From fde846e29d724c9af05ef70fdbba9c4c7259f16d Mon Sep 17 00:00:00 2001 From: Nayane Fernandes <143632290+ansnfernand@users.noreply.github.com> Date: Fri, 2 Aug 2024 10:21:08 +0200 Subject: [PATCH 03/25] Fix issues --- src/ansys/sherlock/core/layer.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ansys/sherlock/core/layer.py b/src/ansys/sherlock/core/layer.py index 4dd691d9e..0611ff3fe 100644 --- a/src/ansys/sherlock/core/layer.py +++ b/src/ansys/sherlock/core/layer.py @@ -900,7 +900,8 @@ def add_modeling_region( project: str, modeling_regions: List[Dict[str, Union[str, float, bool, dict]]], ): - """Add one or more modeling regions to a specific project. + """ + Add one or more modeling regions to a specific project. Parameters ---------- From d8bf4e8471375040eac2634e865fc8b959c452a8 Mon Sep 17 00:00:00 2001 From: Nayane Fernandes <143632290+ansnfernand@users.noreply.github.com> Date: Thu, 1 Aug 2024 16:18:46 +0200 Subject: [PATCH 04/25] New API: add_modeling_region() --- src/ansys/sherlock/core/layer.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ansys/sherlock/core/layer.py b/src/ansys/sherlock/core/layer.py index 0611ff3fe..f9c9e85ae 100644 --- a/src/ansys/sherlock/core/layer.py +++ b/src/ansys/sherlock/core/layer.py @@ -900,6 +900,7 @@ def add_modeling_region( project: str, modeling_regions: List[Dict[str, Union[str, float, bool, dict]]], ): + """ Add one or more modeling regions to a specific project. From 4e548fac447edd8ae06d37092b94aeaab6034fd2 Mon Sep 17 00:00:00 2001 From: Nayane Fernandes <143632290+ansnfernand@users.noreply.github.com> Date: Fri, 2 Aug 2024 18:28:50 +0200 Subject: [PATCH 05/25] Fix issue --- src/ansys/sherlock/core/layer.py | 51 +++++++++++++++----------------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/src/ansys/sherlock/core/layer.py b/src/ansys/sherlock/core/layer.py index f9c9e85ae..ced639c02 100644 --- a/src/ansys/sherlock/core/layer.py +++ b/src/ansys/sherlock/core/layer.py @@ -900,7 +900,6 @@ def add_modeling_region( project: str, modeling_regions: List[Dict[str, Union[str, float, bool, dict]]], ): - """ Add one or more modeling regions to a specific project. @@ -923,34 +922,32 @@ def add_modeling_region( The shape of the modeling region. - pcb_model_props : list List of the PCB model parameters consisting of these properties: - - - export_model_type : str - The type of model to be generated for a given modeling region. - Valid values are ``Default``, ``Sherlock``, ``Sweep`` and ``None``. - - elem_order: str - The type of 3D elements to be created for the PCB in the modeling region. - Valid values are ``First_Order``, ``Second_Order`` and ``Solid_Shell``. - - max_mesh_size : float - The maximum size of the mesh to be used in the region. - - max_mesh_size_units : str - Units for the maximum mesh size. - - quads_preferred : bool - Whether to generate quad-shaped elements when creating the mesh if true. + - export_model_type : str + The type of model to be generated for a given modeling region. + Valid values are ``Default``, ``Sherlock``, ``Sweep`` and ``None``. + - elem_order: str + The type of 3D elements to be created for the PCB in the modeling region. + Valid values are ``First_Order``, ``Second_Order`` and ``Solid_Shell``. + - max_mesh_size : float + The maximum size of the mesh to be used in the region. + - max_mesh_size_units : str + Units for the maximum mesh size. + - quads_preferred : bool + Whether to generate quad-shaped elements when creating the mesh if true. - trace_model_props : list List of the trace model parameters consisting of these properties: - - - trace_model_type : str - The specification of whether trace modeling should be performed - within the region. Valid values are ``Default``, ``Enabled`` and - ``Disabled``. - - elem_order: str, optional - The type of 3D elements to be created for the PCB in the modeling region. - Valid values are ``First_Order``, ``Second_Order`` and ``Solid_Shell``. - - trace_mesh_size : float, optional - The maximum mesh size to be used in the region when trace modeling - is enabled. - - trace_mesh_size_units: str, optional - Units for the maximum mesh size when trace modeling is enabled. + - trace_model_type : str + The specification of whether trace modeling should be performed + within the region. Valid values are ``Default``, ``Enabled`` and + ``Disabled``. + - elem_order: str, optional + The type of 3D elements to be created for the PCB in the modeling region. + Valid values are ``First_Order``, ``Second_Order`` and ``Solid_Shell``. + - trace_mesh_size : float, optional + The maximum mesh size to be used in the region when trace modeling + is enabled. + - trace_mesh_size_units: str, optional + Units for the maximum mesh size when trace modeling is enabled. - region_id_replacement : str, optional Represents a unique region id that will replace the existing regionId value during an update. From ddf0d85b1605b7509b2ccc5f80038a8b8f5deecb Mon Sep 17 00:00:00 2001 From: Nayane Fernandes <143632290+ansnfernand@users.noreply.github.com> Date: Thu, 8 Aug 2024 11:09:08 +0200 Subject: [PATCH 06/25] Fix after feedback --- src/ansys/sherlock/core/layer.py | 15 ++++----------- tests/test_layer.py | 2 +- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/src/ansys/sherlock/core/layer.py b/src/ansys/sherlock/core/layer.py index ced639c02..ac5e579f5 100644 --- a/src/ansys/sherlock/core/layer.py +++ b/src/ansys/sherlock/core/layer.py @@ -948,9 +948,6 @@ def add_modeling_region( is enabled. - trace_mesh_size_units: str, optional Units for the maximum mesh size when trace modeling is enabled. - - region_id_replacement : str, optional - Represents a unique region id that will replace the existing regionId - value during an update. Returns @@ -1075,9 +1072,10 @@ def add_modeling_region( modeling_region.ccaName = region_request["cca_name"] modeling_region.regionId = region_request["region_id"] modeling_region.regionUnits = region_request["region_units"] - modeling_region.modelMode = getattr( - SherlockLayerService_pb2.ModelingRegion.ModelingMode, - region_request["model_mode"], + modeling_region.modelMode = ( + SherlockLayerService_pb2.ModelingRegion.ModelingMode.Value( + region_request["model_mode"] + ) ) shape = region_request["shape"] @@ -1152,11 +1150,6 @@ def add_modeling_region( "trace_mesh_size_units" ] - if "region_id_replacement" in region_request: - modeling_region.regionIdReplacement = region_request[ - "region_id_replacement" - ] - return_code = self.stub.addModelingRegion(add_modeling_region_request) if return_code.value != 0: raise SherlockAddModelingRegionError(message=return_code.message) diff --git a/tests/test_layer.py b/tests/test_layer.py index 840ec8f5f..d3e1b1f9c 100644 --- a/tests/test_layer.py +++ b/tests/test_layer.py @@ -812,7 +812,7 @@ def helper_test_add_modeling_region(layer): pytest.fail("No exception raised for invalid PCB model export type") except SherlockAddModelingRegionError as e: assert str(e.str_itr()) == ( - "['Add modeling region error: PCB model export type is " "invalid.']" + "['Add modeling region error: PCB model export type is invalid.']" ) # Invalid PCB element order From bd3b8390e98e3d0c91ebf142626992cd78ff147d Mon Sep 17 00:00:00 2001 From: Nayane Fernandes <143632290+ansnfernand@users.noreply.github.com> Date: Thu, 1 Aug 2024 16:18:46 +0200 Subject: [PATCH 07/25] New API: add_modeling_region() --- src/ansys/sherlock/core/layer.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ansys/sherlock/core/layer.py b/src/ansys/sherlock/core/layer.py index ac5e579f5..b0756410d 100644 --- a/src/ansys/sherlock/core/layer.py +++ b/src/ansys/sherlock/core/layer.py @@ -900,6 +900,7 @@ def add_modeling_region( project: str, modeling_regions: List[Dict[str, Union[str, float, bool, dict]]], ): + """ Add one or more modeling regions to a specific project. From 70d096deb0122be94bfff65b65001acfdd79c2bf Mon Sep 17 00:00:00 2001 From: Nayane Fernandes <143632290+ansnfernand@users.noreply.github.com> Date: Fri, 2 Aug 2024 18:28:50 +0200 Subject: [PATCH 08/25] Fix issue --- src/ansys/sherlock/core/layer.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ansys/sherlock/core/layer.py b/src/ansys/sherlock/core/layer.py index b0756410d..ac5e579f5 100644 --- a/src/ansys/sherlock/core/layer.py +++ b/src/ansys/sherlock/core/layer.py @@ -900,7 +900,6 @@ def add_modeling_region( project: str, modeling_regions: List[Dict[str, Union[str, float, bool, dict]]], ): - """ Add one or more modeling regions to a specific project. From b83dc0f1b044d989defd436d2f4e196be38b2067 Mon Sep 17 00:00:00 2001 From: Nayane Fernandes <143632290+ansnfernand@users.noreply.github.com> Date: Fri, 9 Aug 2024 16:26:29 +0200 Subject: [PATCH 09/25] Update after feedback --- src/ansys/sherlock/core/layer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/sherlock/core/layer.py b/src/ansys/sherlock/core/layer.py index ac5e579f5..3da957d21 100644 --- a/src/ansys/sherlock/core/layer.py +++ b/src/ansys/sherlock/core/layer.py @@ -1031,7 +1031,7 @@ def add_modeling_region( or pcb_model_props["export_model_type"] == "" ): raise SherlockAddModelingRegionError( - message="PCB model export " "type is invalid." + message="PCB model export type is invalid." ) if "elem_order" not in pcb_model_props or pcb_model_props["elem_order"] == "": raise SherlockAddModelingRegionError( From 4fe8c2c19e061ede5bf7481913f4401665ab9ed8 Mon Sep 17 00:00:00 2001 From: Nayane Fernandes <143632290+ansnfernand@users.noreply.github.com> Date: Fri, 9 Aug 2024 16:28:36 +0200 Subject: [PATCH 10/25] Update after feedback --- src/ansys/sherlock/core/layer.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/ansys/sherlock/core/layer.py b/src/ansys/sherlock/core/layer.py index 3da957d21..df2d16adc 100644 --- a/src/ansys/sherlock/core/layer.py +++ b/src/ansys/sherlock/core/layer.py @@ -1035,19 +1035,19 @@ def add_modeling_region( ) if "elem_order" not in pcb_model_props or pcb_model_props["elem_order"] == "": raise SherlockAddModelingRegionError( - message="PCB element " "order is invalid." + message="PCB element order is invalid." ) if "max_mesh_size" not in pcb_model_props or not isinstance( pcb_model_props["max_mesh_size"], float ): raise SherlockAddModelingRegionError( - message="PCB max mesh size " "is invalid." + message="PCB max mesh size is invalid." ) if "quads_preferred" not in pcb_model_props or not isinstance( pcb_model_props["quads_preferred"], bool ): raise SherlockAddModelingRegionError( - message="PCB quads preferred " "is invalid." + message="PCB quads preferred is invalid." ) trace_model_props = region.get("trace_model_props", {}) @@ -1056,9 +1056,7 @@ def add_modeling_region( "trace_model_type" not in trace_model_props or trace_model_props["trace_model_type"] == "" ): - raise SherlockAddModelingRegionError( - message="Trace model type is " "invalid." - ) + raise SherlockAddModelingRegionError(message="Trace model type is invalid.") if not self._is_connection_up(): LOG.error("There is no connection to a gRPC service.") From f6354fd6ee66be8a5e0effe3abb26c0ce974850e Mon Sep 17 00:00:00 2001 From: Nayane Fernandes <143632290+ansnfernand@users.noreply.github.com> Date: Thu, 1 Aug 2024 16:18:46 +0200 Subject: [PATCH 11/25] New API: add_modeling_region() --- src/ansys/sherlock/core/errors.py | 17 ++ src/ansys/sherlock/core/layer.py | 278 ++++++++++++++++++++++++++++++ tests/test_layer.py | 157 ++++++++++++++++- 3 files changed, 449 insertions(+), 3 deletions(-) diff --git a/src/ansys/sherlock/core/errors.py b/src/ansys/sherlock/core/errors.py index 08457e3a4..28e8b1162 100644 --- a/src/ansys/sherlock/core/errors.py +++ b/src/ansys/sherlock/core/errors.py @@ -1183,3 +1183,20 @@ def __init__(self, message): def __str__(self): """Format error message.""" return f"Export FEA model error: {self.message}" + + +class SherlockAddModelingRegionError(Exception): + """Contains the errors raised when modeling regions for a project cannot be added.""" + + def __init__(self, message=None, error_array=None): + """Initialize error message.""" + self.message = message + self.error_array = error_array + + def str_itr(self): + """Format error message.""" + if self.message is None: + return [f"Add modeling region error: {error}" for error in self.error_array] + + assert self.error_array is None + return [f"Add modeling region error: {self.message}"] diff --git a/src/ansys/sherlock/core/layer.py b/src/ansys/sherlock/core/layer.py index a7602eaa4..4dd691d9e 100644 --- a/src/ansys/sherlock/core/layer.py +++ b/src/ansys/sherlock/core/layer.py @@ -16,8 +16,13 @@ from ansys.api.sherlock.v0 import SherlockLayerService_pb2 from ansys.api.sherlock.v0 import SherlockLayerService_pb2_grpc +from typing import Dict, List, Union + +from SherlockLayerService_pb2 import ModelingRegion + from ansys.sherlock.core import LOG from ansys.sherlock.core.errors import ( + SherlockAddModelingRegionError, SherlockAddPottingRegionError, SherlockDeleteAllICTFixturesError, SherlockDeleteAllMountPointsError, @@ -889,3 +894,276 @@ def export_all_mount_points( raise e return response.value + + def add_modeling_region( + self, + project: str, + modeling_regions: List[Dict[str, Union[str, float, bool, dict]]], + ): + """Add one or more modeling regions to a specific project. + + Parameters + ---------- + project : str + Name of the Sherlock project. + modeling_regions : list of dict + List of modeling regions to add. Each dictionary should contain: + - cca_name : str + Name of the CCA. + - region_id : str + Unique region ID of the modeling region. + - region_units : str + Units of the modeling region. + - model_mode : str + Mode that specifies how the region is used. Valid values are ``Enabled``, + ``Disabled`` and ``Excluded``. + - shape: PolygonalShape|RectangularShape|SlotShape|CircularShape|PCBShape + The shape of the modeling region. + - pcb_model_props : list + List of the PCB model parameters consisting of these properties: + + - export_model_type : str + The type of model to be generated for a given modeling region. + Valid values are ``Default``, ``Sherlock``, ``Sweep`` and ``None``. + - elem_order: str + The type of 3D elements to be created for the PCB in the modeling region. + Valid values are ``First_Order``, ``Second_Order`` and ``Solid_Shell``. + - max_mesh_size : float + The maximum size of the mesh to be used in the region. + - max_mesh_size_units : str + Units for the maximum mesh size. + - quads_preferred : bool + Whether to generate quad-shaped elements when creating the mesh if true. + - trace_model_props : list + List of the trace model parameters consisting of these properties: + + - trace_model_type : str + The specification of whether trace modeling should be performed + within the region. Valid values are ``Default``, ``Enabled`` and + ``Disabled``. + - elem_order: str, optional + The type of 3D elements to be created for the PCB in the modeling region. + Valid values are ``First_Order``, ``Second_Order`` and ``Solid_Shell``. + - trace_mesh_size : float, optional + The maximum mesh size to be used in the region when trace modeling + is enabled. + - trace_mesh_size_units: str, optional + Units for the maximum mesh size when trace modeling is enabled. + - region_id_replacement : str, optional + Represents a unique region id that will replace the existing regionId + value during an update. + + + Returns + ------- + int + Status code of the response. 0 for success. + + Examples + -------- + >>> from ansys.sherlock.core.launcher import launch_sherlock + >>> sherlock = launch_sherlock() + >>> sherlock.project.import_odb_archive( + "ODB++ Tutorial.tgz", + True, + True, + True, + True, + project="Tutorial Project", + cca_name="Card", + ) + >>> modeling_regions = [ + { + "cca_name": "Card", + "region_id": "Region001", + "region_units": "mm", + "model_mode": "Enabled", + "shape": PolygonalShape(points=[ + (0, 0), + (0, 6.35), + (9.77, 0) + ], rotation=87.8), + "pcb_model_props": { + "export_model_type": "Sherlock", + "elem_order": "First_Order", + "max_mesh_size": 0.5, + "max_mesh_size_units": "mm", + "quads_preferred": True + }, + "trace_model_props": { + "trace_model_type": "Enabled", + "elem_order": "Second_Order", + "trace_mesh_size": 0.3, + "trace_mesh_size_units": "mm" + } + } + ] + >>> result = sherlock.project.add_modeling_region("Tutorial Project", modeling_regions) + """ + try: + if not project: + raise SherlockAddModelingRegionError(message="Project name is invalid.") + + if not modeling_regions: + raise SherlockAddModelingRegionError(message="Modeling regions list is empty.") + + for region in modeling_regions: + if "cca_name" not in region or not region["cca_name"]: + raise SherlockAddModelingRegionError(message="CCA name is invalid.") + if "region_id" not in region or not region["region_id"]: + raise SherlockAddModelingRegionError(message="Region ID is invalid.") + if "region_units" not in region or not region["region_units"]: + raise SherlockAddModelingRegionError(message="Region units are invalid.") + if "shape" not in region: + raise SherlockAddModelingRegionError(message="Shape is missing.") + elif not isinstance( + region["shape"], + ( + PolygonalShape, + RectangularShape, + SlotShape, + CircularShape, + PCBShape, + ), + ): + raise SherlockAddModelingRegionError(message="Shape is not of a valid type.") + + pcb_model_props = region.get("pcb_model_props", {}) + if pcb_model_props: + if ( + "export_model_type" not in pcb_model_props + or pcb_model_props["export_model_type"] == "" + ): + raise SherlockAddModelingRegionError( + message="PCB model export " "type is invalid." + ) + if "elem_order" not in pcb_model_props or pcb_model_props["elem_order"] == "": + raise SherlockAddModelingRegionError( + message="PCB element " "order is invalid." + ) + if "max_mesh_size" not in pcb_model_props or not isinstance( + pcb_model_props["max_mesh_size"], float + ): + raise SherlockAddModelingRegionError( + message="PCB max mesh size " "is invalid." + ) + if "quads_preferred" not in pcb_model_props or not isinstance( + pcb_model_props["quads_preferred"], bool + ): + raise SherlockAddModelingRegionError( + message="PCB quads preferred " "is invalid." + ) + + trace_model_props = region.get("trace_model_props", {}) + if trace_model_props: + if ( + "trace_model_type" not in trace_model_props + or trace_model_props["trace_model_type"] == "" + ): + raise SherlockAddModelingRegionError( + message="Trace model type is " "invalid." + ) + + if not self._is_connection_up(): + LOG.error("There is no connection to a gRPC service.") + return + + add_modeling_region_request = SherlockLayerService_pb2.AddModelingRegionRequest() + add_modeling_region_request.project = project + + for region_request in modeling_regions: + modeling_region = add_modeling_region_request.modelingRegions.add() + modeling_region.ccaName = region_request["cca_name"] + modeling_region.regionId = region_request["region_id"] + modeling_region.regionUnits = region_request["region_units"] + modeling_region.modelMode = getattr( + SherlockLayerService_pb2.ModelingRegion.ModelingMode, + region_request["model_mode"], + ) + + shape = region_request["shape"] + if isinstance(shape, PolygonalShape): + polygonal_shape = modeling_region.polygonalShape + for point in shape.points: + polygonal_point = polygonal_shape.points.add() + polygonal_point.x = point[0] + polygonal_point.y = point[1] + polygonal_shape.rotation = shape.rotation + elif isinstance(shape, RectangularShape): + rectangular_shape = modeling_region.rectangularShape + for point in shape.points: + rectangular_point = rectangular_shape.points.add() + rectangular_point.x = point[0] + rectangular_point.y = point[1] + rectangular_shape.rotation = shape.rotation + elif isinstance(shape, SlotShape): + slot_shape = modeling_region.slotShape + for point in shape.points: + slot_point = slot_shape.points.add() + slot_point.x = point[0] + slot_point.y = point[1] + slot_shape.rotation = shape.rotation + elif isinstance(shape, CircularShape): + circular_shape = modeling_region.circularShape + for point in shape.points: + circular_point = circular_shape.points.add() + circular_point.x = point[0] + circular_point.y = point[1] + circular_shape.rotation = shape.rotation + else: + raise SherlockAddModelingRegionError( + message="Shape is not of a valid type." + ) + + ExportModelType = ModelingRegion.PCBModelingProperties.ExportModelType + pcb_model_props = region_request.get("pcb_model_props", {}) + modeling_region.pcbModelProps.exportModelType = getattr( + ExportModelType, + pcb_model_props["export_model_type"], + ) + modeling_region.pcbModelProps.elemOrder = getattr( + SherlockLayerService_pb2.ModelingRegion.ElementOrder, + pcb_model_props["elem_order"], + ) + modeling_region.pcbModelProps.maxMeshSize = pcb_model_props["max_mesh_size"] + modeling_region.pcbModelProps.maxMeshSizeUnits = pcb_model_props[ + "max_mesh_size_units" + ] + modeling_region.pcbModelProps.quadsPreferred = pcb_model_props[ + "quads_preferred" + ] + + TraceModelingType = ModelingRegion.TraceModelingProperties.TraceModelingType + trace_model_props = region_request.get("trace_model_props", {}) + modeling_region.traceModelProps.traceModelType = getattr( + TraceModelingType, + trace_model_props["trace_model_type"], + ) + if "elem_order" in trace_model_props: + modeling_region.traceModelProps.elemOrder = getattr( + SherlockLayerService_pb2.ModelingRegion.ElementOrder, + trace_model_props["elem_order"], + ) + if "trace_mesh_size" in trace_model_props: + modeling_region.traceModelProps.traceMeshSize = trace_model_props[ + "trace_mesh_size" + ] + if "trace_mesh_size_units" in trace_model_props: + modeling_region.traceModelProps.traceMeshSizeUnits = trace_model_props[ + "trace_mesh_size_units" + ] + + if "region_id_replacement" in region_request: + modeling_region.regionIdReplacement = region_request[ + "region_id_replacement" + ] + + return_code = self.stub.addModelingRegion(add_modeling_region_request) + if return_code.value != 0: + raise SherlockAddModelingRegionError(message=return_code.message) + + return return_code.value + + except SherlockAddModelingRegionError as e: + LOG.error(str(e)) + raise e diff --git a/tests/test_layer.py b/tests/test_layer.py index ee0504277..b0edcc797 100644 --- a/tests/test_layer.py +++ b/tests/test_layer.py @@ -1,4 +1,5 @@ # © 2023-2024 ANSYS, Inc. All rights reserved +import copy import os import platform import uuid @@ -7,6 +8,7 @@ import pytest from ansys.sherlock.core.errors import ( + SherlockAddModelingRegionError, SherlockAddPottingRegionError, SherlockDeleteAllICTFixturesError, SherlockDeleteAllMountPointsError, @@ -35,9 +37,10 @@ def test_all(): helper_test_add_potting_region(layer) helper_test_update_test_fixtures_by_file(layer) helper_test_update_test_points_by_file(layer) - helper_test_export_all_mount_points(layer) - helper_test_export_all_test_fixtures(layer) - helper_test_export_all_test_points(layer) + # helper_test_export_all_mount_points(layer) + # helper_test_export_all_test_fixtures(layer) + # helper_test_export_all_test_points(layer) + helper_test_add_modeling_region(layer) def helper_test_add_potting_region(layer): @@ -718,5 +721,153 @@ def helper_test_export_all_mount_points(layer): assert type(e) == SherlockExportAllMountPoints +def helper_test_add_modeling_region(layer): + modeling_region_example = [ + { + "cca_name": "Card", + "region_id": "Region001", + "region_units": "mm", + "model_mode": "Enabled", + "shape": PolygonalShape(points=[(0, 0), (0, 6.35), (9.77, 0)], rotation=87.8), + "pcb_model_props": { + "export_model_type": "Sherlock", + "elem_order": "First_Order", + "max_mesh_size": 0.5, + "max_mesh_size_units": "mm", + "quads_preferred": True, + }, + "trace_model_props": { + "trace_model_type": "Enabled", + "elem_order": "Second_Order", + "trace_mesh_size": 0.3, + "trace_mesh_size_units": "mm", + }, + } + ] + + # Invalid project name + try: + layer.add_modeling_region("", modeling_region_example) + pytest.fail("No exception raised for invalid project name") + except SherlockAddModelingRegionError as e: + assert str(e.str_itr()) == "['Add modeling region error: Project name is invalid.']" + + # Empty modeling regions list + try: + layer.add_modeling_region("Tutorial Project", []) + pytest.fail("No exception raised for empty modeling regions list") + except SherlockAddModelingRegionError as e: + assert str(e.str_itr()) == "['Add modeling region error: Modeling regions list is empty.']" + + # Invalid CCA name + invalid_region = copy.deepcopy(modeling_region_example) + invalid_region[0]["cca_name"] = "" + try: + layer.add_modeling_region("Tutorial Project", invalid_region) + pytest.fail("No exception raised for invalid CCA name") + except SherlockAddModelingRegionError as e: + assert str(e.str_itr()) == "['Add modeling region error: CCA name is invalid.']" + + # Invalid region ID + invalid_region = copy.deepcopy(modeling_region_example) + invalid_region[0]["region_id"] = "" + try: + layer.add_modeling_region("Tutorial Project", invalid_region) + pytest.fail("No exception raised for invalid region ID") + except SherlockAddModelingRegionError as e: + assert str(e.str_itr()) == "['Add modeling region error: Region ID is invalid.']" + + # Invalid region units + invalid_region = copy.deepcopy(modeling_region_example) + invalid_region[0]["region_units"] = "" + try: + layer.add_modeling_region("Tutorial Project", invalid_region) + pytest.fail("No exception raised for invalid region units") + except SherlockAddModelingRegionError as e: + assert str(e.str_itr()) == "['Add modeling region error: Region units are invalid.']" + + # Missing shape + invalid_region = copy.deepcopy(modeling_region_example) + invalid_region[0].pop("shape") + try: + layer.add_modeling_region("Tutorial Project", invalid_region) + pytest.fail("No exception raised for missing shape") + except SherlockAddModelingRegionError as e: + assert str(e.str_itr()) == "['Add modeling region error: Shape is missing.']" + + # Invalid shape type + invalid_region = copy.deepcopy(modeling_region_example) + invalid_region[0]["shape"] = "InvalidShapeType" + try: + layer.add_modeling_region("Tutorial Project", invalid_region) + pytest.fail("No exception raised for invalid shape type") + except SherlockAddModelingRegionError as e: + assert str(e.str_itr()) == "['Add modeling region error: Shape is not of a valid type.']" + + # Invalid PCB model export type + invalid_region = copy.deepcopy(modeling_region_example) + invalid_region[0]["pcb_model_props"]["export_model_type"] = "" + try: + layer.add_modeling_region("Tutorial Project", invalid_region) + pytest.fail("No exception raised for invalid PCB model export type") + except SherlockAddModelingRegionError as e: + assert str(e.str_itr()) == ( + "['Add modeling region error: PCB model export type is " "invalid.']" + ) + + # Invalid PCB element order + invalid_region = copy.deepcopy(modeling_region_example) + invalid_region[0]["pcb_model_props"]["elem_order"] = "" + try: + layer.add_modeling_region("Tutorial Project", invalid_region) + pytest.fail("No exception raised for invalid PCB element order") + except SherlockAddModelingRegionError as e: + assert str(e.str_itr()) == "['Add modeling region error: PCB element order is invalid.']" + + # Invalid PCB max mesh size + invalid_region = copy.deepcopy(modeling_region_example) + invalid_region[0]["pcb_model_props"]["max_mesh_size"] = "not_a_float" + try: + layer.add_modeling_region("Tutorial Project", invalid_region) + pytest.fail("No exception raised for invalid PCB max mesh size") + except SherlockAddModelingRegionError as e: + assert str(e.str_itr()) == "['Add modeling region error: PCB max mesh size is invalid.']" + + # Invalid PCB quads preferred + invalid_region = copy.deepcopy(modeling_region_example) + invalid_region[0]["pcb_model_props"]["quads_preferred"] = "not_a_bool" + try: + layer.add_modeling_region("Tutorial Project", invalid_region) + pytest.fail("No exception raised for invalid PCB quads preferred") + except SherlockAddModelingRegionError as e: + assert str(e.str_itr()) == "['Add modeling region error: PCB quads preferred is invalid.']" + + # Invalid trace model type + invalid_region = copy.deepcopy(modeling_region_example) + invalid_region[0]["trace_model_props"]["trace_model_type"] = "" + try: + layer.add_modeling_region("Tutorial Project", invalid_region) + pytest.fail("No exception raised for invalid trace model type") + except SherlockAddModelingRegionError as e: + assert str(e.str_itr()) == "['Add modeling region error: Trace model type is invalid.']" + + if layer._is_connection_up(): + # Unhappy project name + try: + layer.add_modeling_region("Invalid Project", modeling_region_example) + pytest.fail("No exception raised for invalid project name") + except Exception as e: + assert type(e) == SherlockAddModelingRegionError + + # Valid request + try: + valid_region = copy.deepcopy(modeling_region_example) + valid_region[0]["cca_name"] = "Main Board" + result = layer.add_modeling_region("Tutorial Project", valid_region) + assert result == 0 + except SherlockAddModelingRegionError as e: + pytest.fail(str(e)) + + if __name__ == "__main__": test_all() From 009cbde772e779fb70be42a49fb1d99295c51bb5 Mon Sep 17 00:00:00 2001 From: Nayane Fernandes <143632290+ansnfernand@users.noreply.github.com> Date: Thu, 1 Aug 2024 16:20:43 +0200 Subject: [PATCH 12/25] Fix unit tests --- tests/test_layer.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_layer.py b/tests/test_layer.py index b0edcc797..840ec8f5f 100644 --- a/tests/test_layer.py +++ b/tests/test_layer.py @@ -37,9 +37,9 @@ def test_all(): helper_test_add_potting_region(layer) helper_test_update_test_fixtures_by_file(layer) helper_test_update_test_points_by_file(layer) - # helper_test_export_all_mount_points(layer) - # helper_test_export_all_test_fixtures(layer) - # helper_test_export_all_test_points(layer) + helper_test_export_all_mount_points(layer) + helper_test_export_all_test_fixtures(layer) + helper_test_export_all_test_points(layer) helper_test_add_modeling_region(layer) From b1c993080f74242df400103ac3b20fae5c46b4f6 Mon Sep 17 00:00:00 2001 From: Nayane Fernandes <143632290+ansnfernand@users.noreply.github.com> Date: Fri, 2 Aug 2024 10:21:08 +0200 Subject: [PATCH 13/25] Fix issues --- src/ansys/sherlock/core/layer.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ansys/sherlock/core/layer.py b/src/ansys/sherlock/core/layer.py index 4dd691d9e..0611ff3fe 100644 --- a/src/ansys/sherlock/core/layer.py +++ b/src/ansys/sherlock/core/layer.py @@ -900,7 +900,8 @@ def add_modeling_region( project: str, modeling_regions: List[Dict[str, Union[str, float, bool, dict]]], ): - """Add one or more modeling regions to a specific project. + """ + Add one or more modeling regions to a specific project. Parameters ---------- From 935c235d5e429c2eee94ed4875896fd9ce4c1e91 Mon Sep 17 00:00:00 2001 From: Nayane Fernandes <143632290+ansnfernand@users.noreply.github.com> Date: Thu, 1 Aug 2024 16:18:46 +0200 Subject: [PATCH 14/25] New API: add_modeling_region() --- src/ansys/sherlock/core/layer.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ansys/sherlock/core/layer.py b/src/ansys/sherlock/core/layer.py index 0611ff3fe..f9c9e85ae 100644 --- a/src/ansys/sherlock/core/layer.py +++ b/src/ansys/sherlock/core/layer.py @@ -900,6 +900,7 @@ def add_modeling_region( project: str, modeling_regions: List[Dict[str, Union[str, float, bool, dict]]], ): + """ Add one or more modeling regions to a specific project. From 7772413beb9611c4213d75161470590bf3f9ac49 Mon Sep 17 00:00:00 2001 From: Nayane Fernandes <143632290+ansnfernand@users.noreply.github.com> Date: Fri, 2 Aug 2024 18:28:50 +0200 Subject: [PATCH 15/25] Fix issue --- src/ansys/sherlock/core/layer.py | 51 +++++++++++++++----------------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/src/ansys/sherlock/core/layer.py b/src/ansys/sherlock/core/layer.py index f9c9e85ae..ced639c02 100644 --- a/src/ansys/sherlock/core/layer.py +++ b/src/ansys/sherlock/core/layer.py @@ -900,7 +900,6 @@ def add_modeling_region( project: str, modeling_regions: List[Dict[str, Union[str, float, bool, dict]]], ): - """ Add one or more modeling regions to a specific project. @@ -923,34 +922,32 @@ def add_modeling_region( The shape of the modeling region. - pcb_model_props : list List of the PCB model parameters consisting of these properties: - - - export_model_type : str - The type of model to be generated for a given modeling region. - Valid values are ``Default``, ``Sherlock``, ``Sweep`` and ``None``. - - elem_order: str - The type of 3D elements to be created for the PCB in the modeling region. - Valid values are ``First_Order``, ``Second_Order`` and ``Solid_Shell``. - - max_mesh_size : float - The maximum size of the mesh to be used in the region. - - max_mesh_size_units : str - Units for the maximum mesh size. - - quads_preferred : bool - Whether to generate quad-shaped elements when creating the mesh if true. + - export_model_type : str + The type of model to be generated for a given modeling region. + Valid values are ``Default``, ``Sherlock``, ``Sweep`` and ``None``. + - elem_order: str + The type of 3D elements to be created for the PCB in the modeling region. + Valid values are ``First_Order``, ``Second_Order`` and ``Solid_Shell``. + - max_mesh_size : float + The maximum size of the mesh to be used in the region. + - max_mesh_size_units : str + Units for the maximum mesh size. + - quads_preferred : bool + Whether to generate quad-shaped elements when creating the mesh if true. - trace_model_props : list List of the trace model parameters consisting of these properties: - - - trace_model_type : str - The specification of whether trace modeling should be performed - within the region. Valid values are ``Default``, ``Enabled`` and - ``Disabled``. - - elem_order: str, optional - The type of 3D elements to be created for the PCB in the modeling region. - Valid values are ``First_Order``, ``Second_Order`` and ``Solid_Shell``. - - trace_mesh_size : float, optional - The maximum mesh size to be used in the region when trace modeling - is enabled. - - trace_mesh_size_units: str, optional - Units for the maximum mesh size when trace modeling is enabled. + - trace_model_type : str + The specification of whether trace modeling should be performed + within the region. Valid values are ``Default``, ``Enabled`` and + ``Disabled``. + - elem_order: str, optional + The type of 3D elements to be created for the PCB in the modeling region. + Valid values are ``First_Order``, ``Second_Order`` and ``Solid_Shell``. + - trace_mesh_size : float, optional + The maximum mesh size to be used in the region when trace modeling + is enabled. + - trace_mesh_size_units: str, optional + Units for the maximum mesh size when trace modeling is enabled. - region_id_replacement : str, optional Represents a unique region id that will replace the existing regionId value during an update. From 570c41594eaafe064bb8a0626b38b21ddf67a6cd Mon Sep 17 00:00:00 2001 From: Nayane Fernandes <143632290+ansnfernand@users.noreply.github.com> Date: Thu, 8 Aug 2024 11:09:08 +0200 Subject: [PATCH 16/25] Fix after feedback --- src/ansys/sherlock/core/layer.py | 15 ++++----------- tests/test_layer.py | 2 +- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/src/ansys/sherlock/core/layer.py b/src/ansys/sherlock/core/layer.py index ced639c02..ac5e579f5 100644 --- a/src/ansys/sherlock/core/layer.py +++ b/src/ansys/sherlock/core/layer.py @@ -948,9 +948,6 @@ def add_modeling_region( is enabled. - trace_mesh_size_units: str, optional Units for the maximum mesh size when trace modeling is enabled. - - region_id_replacement : str, optional - Represents a unique region id that will replace the existing regionId - value during an update. Returns @@ -1075,9 +1072,10 @@ def add_modeling_region( modeling_region.ccaName = region_request["cca_name"] modeling_region.regionId = region_request["region_id"] modeling_region.regionUnits = region_request["region_units"] - modeling_region.modelMode = getattr( - SherlockLayerService_pb2.ModelingRegion.ModelingMode, - region_request["model_mode"], + modeling_region.modelMode = ( + SherlockLayerService_pb2.ModelingRegion.ModelingMode.Value( + region_request["model_mode"] + ) ) shape = region_request["shape"] @@ -1152,11 +1150,6 @@ def add_modeling_region( "trace_mesh_size_units" ] - if "region_id_replacement" in region_request: - modeling_region.regionIdReplacement = region_request[ - "region_id_replacement" - ] - return_code = self.stub.addModelingRegion(add_modeling_region_request) if return_code.value != 0: raise SherlockAddModelingRegionError(message=return_code.message) diff --git a/tests/test_layer.py b/tests/test_layer.py index 840ec8f5f..d3e1b1f9c 100644 --- a/tests/test_layer.py +++ b/tests/test_layer.py @@ -812,7 +812,7 @@ def helper_test_add_modeling_region(layer): pytest.fail("No exception raised for invalid PCB model export type") except SherlockAddModelingRegionError as e: assert str(e.str_itr()) == ( - "['Add modeling region error: PCB model export type is " "invalid.']" + "['Add modeling region error: PCB model export type is invalid.']" ) # Invalid PCB element order From d237ceb32730dd785f7516b3ba35fdc6b0cf68e5 Mon Sep 17 00:00:00 2001 From: Nayane Fernandes <143632290+ansnfernand@users.noreply.github.com> Date: Thu, 1 Aug 2024 16:18:46 +0200 Subject: [PATCH 17/25] New API: add_modeling_region() --- src/ansys/sherlock/core/layer.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ansys/sherlock/core/layer.py b/src/ansys/sherlock/core/layer.py index ac5e579f5..b0756410d 100644 --- a/src/ansys/sherlock/core/layer.py +++ b/src/ansys/sherlock/core/layer.py @@ -900,6 +900,7 @@ def add_modeling_region( project: str, modeling_regions: List[Dict[str, Union[str, float, bool, dict]]], ): + """ Add one or more modeling regions to a specific project. From 4774092466cbb12b40b91ffd4b77b0c0ea4ab627 Mon Sep 17 00:00:00 2001 From: Nayane Fernandes <143632290+ansnfernand@users.noreply.github.com> Date: Fri, 2 Aug 2024 18:28:50 +0200 Subject: [PATCH 18/25] Fix issue --- src/ansys/sherlock/core/layer.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ansys/sherlock/core/layer.py b/src/ansys/sherlock/core/layer.py index b0756410d..ac5e579f5 100644 --- a/src/ansys/sherlock/core/layer.py +++ b/src/ansys/sherlock/core/layer.py @@ -900,7 +900,6 @@ def add_modeling_region( project: str, modeling_regions: List[Dict[str, Union[str, float, bool, dict]]], ): - """ Add one or more modeling regions to a specific project. From 520770054606d70a49ab7307dee263d5429ef649 Mon Sep 17 00:00:00 2001 From: Nayane Fernandes <143632290+ansnfernand@users.noreply.github.com> Date: Fri, 9 Aug 2024 16:26:29 +0200 Subject: [PATCH 19/25] Update after feedback --- src/ansys/sherlock/core/layer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/sherlock/core/layer.py b/src/ansys/sherlock/core/layer.py index ac5e579f5..3da957d21 100644 --- a/src/ansys/sherlock/core/layer.py +++ b/src/ansys/sherlock/core/layer.py @@ -1031,7 +1031,7 @@ def add_modeling_region( or pcb_model_props["export_model_type"] == "" ): raise SherlockAddModelingRegionError( - message="PCB model export " "type is invalid." + message="PCB model export type is invalid." ) if "elem_order" not in pcb_model_props or pcb_model_props["elem_order"] == "": raise SherlockAddModelingRegionError( From 3f1753a6e71515e6e76c0a1c3d18c09cd220d744 Mon Sep 17 00:00:00 2001 From: Nayane Fernandes <143632290+ansnfernand@users.noreply.github.com> Date: Fri, 9 Aug 2024 16:28:36 +0200 Subject: [PATCH 20/25] Update after feedback --- src/ansys/sherlock/core/layer.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/ansys/sherlock/core/layer.py b/src/ansys/sherlock/core/layer.py index 3da957d21..df2d16adc 100644 --- a/src/ansys/sherlock/core/layer.py +++ b/src/ansys/sherlock/core/layer.py @@ -1035,19 +1035,19 @@ def add_modeling_region( ) if "elem_order" not in pcb_model_props or pcb_model_props["elem_order"] == "": raise SherlockAddModelingRegionError( - message="PCB element " "order is invalid." + message="PCB element order is invalid." ) if "max_mesh_size" not in pcb_model_props or not isinstance( pcb_model_props["max_mesh_size"], float ): raise SherlockAddModelingRegionError( - message="PCB max mesh size " "is invalid." + message="PCB max mesh size is invalid." ) if "quads_preferred" not in pcb_model_props or not isinstance( pcb_model_props["quads_preferred"], bool ): raise SherlockAddModelingRegionError( - message="PCB quads preferred " "is invalid." + message="PCB quads preferred is invalid." ) trace_model_props = region.get("trace_model_props", {}) @@ -1056,9 +1056,7 @@ def add_modeling_region( "trace_model_type" not in trace_model_props or trace_model_props["trace_model_type"] == "" ): - raise SherlockAddModelingRegionError( - message="Trace model type is " "invalid." - ) + raise SherlockAddModelingRegionError(message="Trace model type is invalid.") if not self._is_connection_up(): LOG.error("There is no connection to a gRPC service.") From e5880fc225324d0401cdc1b8dacedbc12ed706b6 Mon Sep 17 00:00:00 2001 From: Jeff Moody <110494049+ansjmoody@users.noreply.github.com> Date: Fri, 9 Aug 2024 10:21:19 -0500 Subject: [PATCH 21/25] layer.add_modeling_region(): Add new lines after list entries in the method docs to fix errors when generating HTML documentation --- src/ansys/sherlock/core/layer.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ansys/sherlock/core/layer.py b/src/ansys/sherlock/core/layer.py index df2d16adc..8f0a6e180 100644 --- a/src/ansys/sherlock/core/layer.py +++ b/src/ansys/sherlock/core/layer.py @@ -909,6 +909,7 @@ def add_modeling_region( Name of the Sherlock project. modeling_regions : list of dict List of modeling regions to add. Each dictionary should contain: + - cca_name : str Name of the CCA. - region_id : str @@ -922,6 +923,7 @@ def add_modeling_region( The shape of the modeling region. - pcb_model_props : list List of the PCB model parameters consisting of these properties: + - export_model_type : str The type of model to be generated for a given modeling region. Valid values are ``Default``, ``Sherlock``, ``Sweep`` and ``None``. @@ -936,6 +938,7 @@ def add_modeling_region( Whether to generate quad-shaped elements when creating the mesh if true. - trace_model_props : list List of the trace model parameters consisting of these properties: + - trace_model_type : str The specification of whether trace modeling should be performed within the region. Valid values are ``Default``, ``Enabled`` and From 96e96213773a63fb39c6a3b9c73aaea4e9c77a4f Mon Sep 17 00:00:00 2001 From: Nayane Fernandes <143632290+ansnfernand@users.noreply.github.com> Date: Mon, 12 Aug 2024 16:52:33 +0200 Subject: [PATCH 22/25] Bump version ansys-api-sherlock --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index ac45564fa..27772df4b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,7 +24,7 @@ classifiers = [ ] dependencies = [ - "ansys-api-sherlock==0.1.29", + "ansys-api-sherlock==0.1.30", "grpcio>=1.17", "importlib-metadata>=4.0,<5; python_version<='3.8'", "protobuf~=3.20", From 881fd388b740be00330f41f6c1761af1ccc28365 Mon Sep 17 00:00:00 2001 From: Nayane Fernandes <143632290+ansnfernand@users.noreply.github.com> Date: Mon, 12 Aug 2024 17:30:55 +0200 Subject: [PATCH 23/25] Fix issue with import --- src/ansys/sherlock/core/layer.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/ansys/sherlock/core/layer.py b/src/ansys/sherlock/core/layer.py index 8f0a6e180..feadc7aa4 100644 --- a/src/ansys/sherlock/core/layer.py +++ b/src/ansys/sherlock/core/layer.py @@ -18,8 +18,6 @@ from typing import Dict, List, Union -from SherlockLayerService_pb2 import ModelingRegion - from ansys.sherlock.core import LOG from ansys.sherlock.core.errors import ( SherlockAddModelingRegionError, From a73b72c70578372929539c3d3d76710221a3ece7 Mon Sep 17 00:00:00 2001 From: Nayane Fernandes <143632290+ansnfernand@users.noreply.github.com> Date: Mon, 12 Aug 2024 17:42:29 +0200 Subject: [PATCH 24/25] Fix issue with import --- src/ansys/sherlock/core/layer.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ansys/sherlock/core/layer.py b/src/ansys/sherlock/core/layer.py index feadc7aa4..9de230dbc 100644 --- a/src/ansys/sherlock/core/layer.py +++ b/src/ansys/sherlock/core/layer.py @@ -11,10 +11,12 @@ try: import SherlockLayerService_pb2 + from SherlockLayerService_pb2 import ModelingRegion import SherlockLayerService_pb2_grpc except ModuleNotFoundError: from ansys.api.sherlock.v0 import SherlockLayerService_pb2 from ansys.api.sherlock.v0 import SherlockLayerService_pb2_grpc + from ansys.api.sherlock.v0.SherlockLayerService_pb2 import ModelingRegion from typing import Dict, List, Union From c90828bca8178046bf0fa30fbaa2f99ed54dd0c2 Mon Sep 17 00:00:00 2001 From: Nayane Fernandes <143632290+ansnfernand@users.noreply.github.com> Date: Mon, 12 Aug 2024 17:52:29 +0200 Subject: [PATCH 25/25] Fix issue --- src/ansys/sherlock/core/layer.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/ansys/sherlock/core/layer.py b/src/ansys/sherlock/core/layer.py index 9de230dbc..02d181bef 100644 --- a/src/ansys/sherlock/core/layer.py +++ b/src/ansys/sherlock/core/layer.py @@ -1073,10 +1073,8 @@ def add_modeling_region( modeling_region.ccaName = region_request["cca_name"] modeling_region.regionId = region_request["region_id"] modeling_region.regionUnits = region_request["region_units"] - modeling_region.modelMode = ( - SherlockLayerService_pb2.ModelingRegion.ModelingMode.Value( - region_request["model_mode"] - ) + modeling_region.modelMode = ModelingRegion.ModelingMode.Value( + region_request["model_mode"] ) shape = region_request["shape"] @@ -1120,7 +1118,7 @@ def add_modeling_region( pcb_model_props["export_model_type"], ) modeling_region.pcbModelProps.elemOrder = getattr( - SherlockLayerService_pb2.ModelingRegion.ElementOrder, + ModelingRegion.ElementOrder, pcb_model_props["elem_order"], ) modeling_region.pcbModelProps.maxMeshSize = pcb_model_props["max_mesh_size"] @@ -1139,7 +1137,7 @@ def add_modeling_region( ) if "elem_order" in trace_model_props: modeling_region.traceModelProps.elemOrder = getattr( - SherlockLayerService_pb2.ModelingRegion.ElementOrder, + ModelingRegion.ElementOrder, trace_model_props["elem_order"], ) if "trace_mesh_size" in trace_model_props: