Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add update potting region #435

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/changelog.d/428.documentation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Update unit test for HV strain map analysis.
1 change: 1 addition & 0 deletions doc/changelog.d/435.documentation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add update potting region
78 changes: 78 additions & 0 deletions src/ansys/sherlock/core/layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,20 @@
CircularShape,
PCBShape,
PolygonalShape,
PottingRegionUpdateData,
RectangularShape,
SlotShape,
)

try:
import SherlockCommonService_pb2
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 import SherlockCommonService_pb2
from ansys.api.sherlock.v0.SherlockLayerService_pb2 import ModelingRegion

from typing import Dict, List, Union
Expand Down Expand Up @@ -235,6 +238,81 @@ def add_potting_region(
LOG.error(str(e))
raise e

def update_potting_region(
self, project: str, update_potting_region_requests: list[PottingRegionUpdateData]
) -> list[SherlockCommonService_pb2.ReturnCode]:
"""Update one or more potting regions in a specific project.

Parameters:
----------
project: str
Name of the Sherlock project.
update_potting_region_requests: list[PottingRegionUpdateData]
List of data used to update potting regions.

Returns
-------
list[SherlockCommonService_pb2.ReturnCode]
Return codes for each request

Examples
--------
>>> from ansys.sherlock.core.launcher import launch_sherlock
>>> from ansys.sherlock.core.types.layer_types import PolygonalShape
>>> from ansys.sherlock.core.types.layer_types import PottingRegionUpdateData
>>> from ansys.sherlock.core.types.layer_types import PottingRegionData
>>> sherlock = launch_sherlock()
>>>
>>> update_request1 = PottingRegionUpdateData(
potting_region_id_to_update=potting_id,
potting_region=PottingRegionData(
cca_name=cca_name,
potting_id=potting_id,
potting_side=potting_side,
potting_material=potting_material,
potting_units=potting_units,
potting_thickness=potting_thickness,
potting_standoff=potting_standoff,
shape=PolygonalShape(
points=[(0, 1), (5, 1), (5, 5), (1, 5)],
rotation=45.0
)
)
)
>>> update_request2 = PottingRegionUpdateData(
potting_region_id_to_update=potting_id,
potting_region=PottingRegionData(
cca_name=cca_name,
potting_id=potting_id,
potting_side=potting_side,
potting_material=potting_material,
potting_units=potting_units,
potting_thickness=potting_thickness,
potting_standoff=potting_standoff,
shape=PolygonalShape(
points=[(0, 1), (5, 1), (5, 5), (1, 5)],
rotation=0.0
)
)
)
>>> potting_region_requests = [
update_request1,
update_request2
]
>>> responses = sherlock.layer.update_potting_region(project, potting_region_requests)
"""
update_request = SherlockLayerService_pb2.UpdatePottingRegionRequest()
update_request.project = project

for update_potting_region_request in update_potting_region_requests:
update_request.updatePottingRegions.append(
update_potting_region_request._convert_to_grpc()
)
responses = []
for grpc_return_code in self.stub.updatePottingRegion(update_request):
responses.append(grpc_return_code)
return responses

def update_mount_points_by_file(
self,
project,
Expand Down
7 changes: 7 additions & 0 deletions src/ansys/sherlock/core/types/common_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@
from ansys.api.sherlock.v0 import SherlockCommonService_pb2


def basic_str_validator(value: str, field_name: str):
"""Apply basic string validation."""
if value is None or value == "":
raise ValueError(field_name + " is invalid because it is None or empty.")
return value


class ListUnitsRequestUnitType:
"""Constants for Unit Type in the List Units request."""

Expand Down
231 changes: 175 additions & 56 deletions src/ansys/sherlock/core/types/layer_types.py
Original file line number Diff line number Diff line change
@@ -1,71 +1,190 @@
# © 2023 ANSYS, Inc. All rights reserved.

"""Module containing types for the Layer Service."""


class PolygonalShape:
from typing import Union

from ansys.api.sherlock.v0 import SherlockLayerService_pb2
from pydantic import BaseModel, ValidationInfo, field_validator

from ansys.sherlock.core.types.common_types import basic_str_validator


class PolygonalShape(BaseModel):
"""Contains the properties for a polygonal shape."""

def __init__(self, points, rotation):
"""Initialize the shape properties."""
self.points = points
"""points (length two tuples of the form (x, y)) : list[tuple[float, float]]"""
self.rotation = rotation
"""rotation (in degrees) : float"""
points: list[tuple[float, float]]
"""points (length two tuples of the form (x, y)) : list[tuple[float, float]]"""
rotation: float
"""rotation (in degrees) : float"""

def _convert_to_grpc(self) -> SherlockLayerService_pb2.PolygonalShape:
grpc_polygonal_shape = SherlockLayerService_pb2.PolygonalShape()
for x, y in self.points:
p = grpc_polygonal_shape.points.add()
p.x = x
p.y = y
grpc_polygonal_shape.rotation = self.rotation
return grpc_polygonal_shape

class RectangularShape:

class RectangularShape(BaseModel):
"""Contains the properties for a rectangular shape."""

def __init__(self, length, width, center_x, center_y, rotation):
"""Initialize the shape properties."""
self.length = length
"""length : float"""
self.width = width
"""width : float"""
self.center_x = center_x
"""x coordinate of center : float"""
self.center_y = center_y
"""y coordinate of center : float"""
self.rotation = rotation
"""rotation (in degrees) : float"""


class SlotShape:
length: float
"""length : float"""
width: float
"""width : float"""
center_x: float
"""x coordinate of center : float"""
center_y: float
"""y coordinate of center : float"""
rotation: float
"""rotation (in degrees) : float"""

def _convert_to_grpc(self) -> SherlockLayerService_pb2.RectangularShape:
grpc_rectangular_shape = SherlockLayerService_pb2.RectangularShape()
grpc_rectangular_shape.length = self.length
grpc_rectangular_shape.width = self.width
grpc_rectangular_shape.centerX = self.center_x
grpc_rectangular_shape.centerY = self.center_y
grpc_rectangular_shape.rotation = self.rotation
return grpc_rectangular_shape


class SlotShape(BaseModel):
"""Contains the properties for a slot shape."""

def __init__(self, length, width, node_count, center_x, center_y, rotation):
"""Initialize the shape properties."""
self.length = length
"""length : float"""
self.width = width
"""width : float"""
self.node_count = node_count
"""node count : int"""
self.center_x = center_x
"""x coordinate of center : float"""
self.center_y = center_y
"""y coordinate of center : float"""
self.rotation = rotation
"""rotation (in degrees) : float"""


class CircularShape:
length: float
"""length : float"""
width: float
"""width : float"""
node_count: int
"""node count : int"""
center_x: float
"""x coordinate of center : float"""
center_y: float
"""y coordinate of center : float"""
rotation: float
"""rotation (in degrees) : float"""

def _convert_to_grpc(self) -> SherlockLayerService_pb2.SlotShape:
grpc_slot_shape = SherlockLayerService_pb2.SlotShape

grpc_slot_shape.length = self.length
grpc_slot_shape.width = self.width
grpc_slot_shape.nodeCount = self.node_count
grpc_slot_shape.centerX = self.center_x
grpc_slot_shape.centerY = self.center_y
grpc_slot_shape.rotation = self.rotation

return grpc_slot_shape


class CircularShape(BaseModel):
"""Contains the properties for a circular shape."""

def __init__(self, diameter, node_count, center_x, center_y, rotation):
"""Initialize the shape properties."""
self.diameter = diameter
"""diameter : float"""
self.node_count = node_count
"""node count : int"""
self.center_x = center_x
"""x coordinate of center : float"""
self.center_y = center_y
"""y coordinate of center : float"""
self.rotation = rotation
"""rotation (in degrees) : float"""


class PCBShape:
diameter: float
"""diameter : float"""
node_count: int
"""node count : int"""
center_x: float
"""x coordinate of center : float"""
center_y: float
"""y coordinate of center : float"""
rotation: float
"""rotation (in degrees) : float"""

def _convert_to_grpc(self) -> SherlockLayerService_pb2.CircularShape:
grpc_circular_shape = SherlockLayerService_pb2.CircularShape()
grpc_circular_shape.diameter = self.diameter
grpc_circular_shape.nodeCount = self.node_count
grpc_circular_shape.centerX = self.center_x
grpc_circular_shape.centerY = self.center_y
grpc_circular_shape.rotation = self.rotation
return grpc_circular_shape


class PCBShape(BaseModel):
"""Contains the properties for a PCB shape."""

def _convert_to_grpc(self) -> SherlockLayerService_pb2.PCBShape:
return SherlockLayerService_pb2.PCBShape()


class PottingRegionData(BaseModel):
"""Contains the properties of a Potting Region add or update request."""

cca_name: str
"""The name of the CCA."""
potting_id: str
"""The potting ID."""
potting_side: str
"""The potting side, options are "TOP", "BOT", or "BOTTOM"."""
potting_material: str
"""The potting material."""
potting_units: str
"""The units to use for the potting region."""
potting_thickness: float
"""The potting thickness."""
potting_standoff: float
"""The potting standoff."""
shape: Union[CircularShape, PCBShape, PolygonalShape, RectangularShape, SlotShape]
"""The shape of the potting region."""

def _convert_to_grpc(self) -> SherlockLayerService_pb2.PottingRegion:
grpc_potting_region_data = SherlockLayerService_pb2.PottingRegion()

grpc_potting_region_data.ccaName = self.cca_name
grpc_potting_region_data.pottingID = self.potting_id
grpc_potting_region_data.pottingSide = self.potting_side
grpc_potting_region_data.pottingMaterial = self.potting_material
grpc_potting_region_data.pottingUnits = self.potting_units
grpc_potting_region_data.pottingThickness = self.potting_thickness
grpc_potting_region_data.pottingStandoff = self.potting_standoff

if isinstance(self.shape, CircularShape):
grpc_potting_region_data.circularShape.CopyFrom(self.shape._convert_to_grpc())
elif isinstance(self.shape, PCBShape):
grpc_potting_region_data.pcbShape.CopyFrom(self.shape._convert_to_grpc())
elif isinstance(self.shape, PolygonalShape):
grpc_potting_region_data.polygonalShape.CopyFrom(self.shape._convert_to_grpc())
elif isinstance(self.shape, RectangularShape):
grpc_potting_region_data.rectangularShape.CopyFrom(self.shape._convert_to_grpc())
elif isinstance(self.shape, SlotShape):
grpc_potting_region_data.slotShape.CopyFrom(self.shape._convert_to_grpc())
else:
raise ValueError("Unsupported shape given '" + type(self.shape).__name__ + "'")

return grpc_potting_region_data

@field_validator("cca_name", "potting_id", "potting_side", "potting_material", "potting_units")
@classmethod
def str_validation(cls, value: str, info: ValidationInfo):
"""Validate string fields listed."""
return basic_str_validator(value, info.field_name)


class PottingRegionUpdateData(BaseModel):
"""Contains the properties of a potting region update request."""

potting_region_id_to_update: str
potting_region: PottingRegionData

def _convert_to_grpc(
self,
) -> SherlockLayerService_pb2.UpdatePottingRegionRequest.PottingRegionUpdateData:

grpc_potting_update_data = (
SherlockLayerService_pb2.UpdatePottingRegionRequest.PottingRegionUpdateData()
)

grpc_potting_update_data.pottingRegionIDToUpdate = self.potting_region_id_to_update
grpc_potting_update_data.pottingRegion.CopyFrom(self.potting_region._convert_to_grpc())
return grpc_potting_update_data

@field_validator("potting_region_id_to_update")
@classmethod
def str_validation(cls, value: str, info: ValidationInfo):
"""Validate string fields listed."""
return basic_str_validator(value, info.field_name)
2 changes: 1 addition & 1 deletion tests/test_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ def helper_test_run_strain_map_analysis(analysis):
"Main Board",
[
[
analysis_type_enum.RandomVibe,
analysis_type_enum.HarmonicVibe,
[
["Phase 1", "Harmonic Vibe", "TOP", "MainBoardStrain - Top"],
["Phase 1", "Harmonic Vibe", "BOTTOM", "MainBoardStrain - Bottom"],
Expand Down
Loading
Loading