Skip to content

Commit

Permalink
feat: add Analysis.update_component_failure_mechanism_analysis_props()
Browse files Browse the repository at this point in the history
  • Loading branch information
ansjmoody committed Dec 20, 2024
1 parent 2a61d77 commit 40b49fc
Show file tree
Hide file tree
Showing 5 changed files with 223 additions and 2 deletions.
4 changes: 4 additions & 0 deletions doc/source/api/analysis_types.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,7 @@ Constants
:members:
.. autoclass:: UpdatePcbModelingPropsRequestPcbModelType
:members:
.. autoclass:: ComponentFailureMechanism
:members:
.. autoclass:: UpdateComponentFailureMechanismPropsRequest
:members:
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "flit_core.buildapi"

[project]
name = "ansys-sherlock-core"
version = "0.3.dev0"
version = "0.9.dev0"
description = "A python wrapper for Ansys Sherlock"
readme = "README.rst"
requires-python = ">=3.10,<4"
Expand All @@ -23,7 +23,7 @@ classifiers = [
]

dependencies = [
"ansys-api-sherlock==0.1.36",
"ansys-api-sherlock==0.1.37",
"grpcio>=1.17, <1.68.0",
"protobuf>=3.20",
"pydantic>=2.9.2",
Expand Down
68 changes: 68 additions & 0 deletions src/ansys/sherlock/core/analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
ModelSource,
RunAnalysisRequestAnalysisType,
RunStrainMapAnalysisRequestAnalysisType,
UpdateComponentFailureMechanismPropsRequest,
UpdatePcbModelingPropsRequestAnalysisType,
UpdatePcbModelingPropsRequestPcbMaterialModel,
UpdatePcbModelingPropsRequestPcbModelType,
Expand All @@ -18,7 +19,9 @@
try:
import SherlockAnalysisService_pb2
import SherlockAnalysisService_pb2_grpc
import SherlockCommonService_pb2
except ModuleNotFoundError:
from ansys.api.sherlock.v0 import SherlockCommonService_pb2
from ansys.api.sherlock.v0 import SherlockAnalysisService_pb2
from ansys.api.sherlock.v0 import SherlockAnalysisService_pb2_grpc

Expand Down Expand Up @@ -2166,3 +2169,68 @@ def get_parts_list_validation_analysis_props(
except SherlockGetPartsListValidationAnalysisPropsError as e:
LOG.error(str(e))
raise e

@require_version(252)
def update_component_failure_mechanism_analysis_props(
self,
request: UpdateComponentFailureMechanismPropsRequest,
) -> list[SherlockCommonService_pb2.ReturnCode]:
r"""Update properties for one or more Component Failure Mechanism analysis.
Parameters
----------
request: UpdateComponentFailureMechanismPropsRequest
Contains all the information needed to update the properties for one or more component
failure mechanism analyses per project.
Returns
-------
list[SherlockCommonService_pb2.ReturnCode]
Return codes for each request.
Examples
--------
>>> from ansys.sherlock.core.launcher import launch_sherlock
>>> from ansys.sherlock.core.types.analysis_types import (
ComponentFailureMechanism,
UpdateComponentFailureMechanismPropsRequest,
)
>>> sherlock = launch_sherlock()
>>> sherlock.project.import_project_zip_archive(
project="Assembly Tutorial",
category="category",
archive_file=\
"C:\\Program Files\\ANSYS Inc\\v252\\sherlock\\tutorial\\Assembly Tutorial.zip",
)
>>> update_request1 = ComponentFailureMechanism(
cca_name="Main Board",
default_part_temp_rise=1.5,
default_part_temp_rise_units="K",
part_temp_rise_min_enabled=True,
part_validation_enabled=False,
)
>>> update_request2 = ComponentFailureMechanism(
cca_name="Memory Card 1",
default_part_temp_rise=-3.25,
default_part_temp_rise_units="F",
part_temp_rise_min_enabled=False,
part_validation_enabled=True,
)
>>> request = UpdateComponentFailureMechanismPropsRequest(
project="Test",
component_failure_mechanism_properties_per_cca=[
update_request1,
update_request2
]
)
>>> return_codes = sherlock.analysis.\
update_component_failure_mechanism_analysis_props(request)
>>> for return_code in return_codes:
print(f"Return code: value={return_code.value}, message={return_code.message}")
"""
update_request = request._convert_to_grpc()

responses = []
for return_code in self.stub.updateComponentFailureMechanismProps(update_request):
responses.append(return_code)
return responses
65 changes: 65 additions & 0 deletions src/ansys/sherlock/core/types/analysis_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

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

from pydantic import BaseModel, ValidationInfo, field_validator

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

try:
import SherlockAnalysisService_pb2
except ModuleNotFoundError:
Expand Down Expand Up @@ -114,3 +118,64 @@ class UpdatePcbModelingPropsRequestPcbModelType:
__model_type = analysis_service.UpdatePcbModelingPropsRequest.Analysis.PcbModelType
BONDED = __model_type.Bonded
"BONDED"


class ComponentFailureMechanism(BaseModel):
"""Contains the properties of a component failure mechanism update request."""

cca_name: str
"""Name of the CCA."""
default_part_temp_rise: float
"""Default part temperature rise."""
default_part_temp_rise_units: str
"""Default part temperature rise units."""
part_temp_rise_min_enabled: bool
"""Whether part temperature rise value is applied to the minimum temperature defined in the
thermal cycle."""
part_validation_enabled: bool
"""Whether part validation should be performed."""

def _convert_to_grpc(
self,
) -> analysis_service.UpdateComponentFailureMechanismPropsRequest.ComponentFailureMechanism:

grpc_data = (
analysis_service.UpdateComponentFailureMechanismPropsRequest.ComponentFailureMechanism()
)

grpc_data.ccaName = self.cca_name
grpc_data.defaultPartTempRise = self.default_part_temp_rise
grpc_data.defaultPartTempRiseUnits = self.default_part_temp_rise_units
grpc_data.partTempRiseMinEnabled = self.part_temp_rise_min_enabled
grpc_data.partValidationEnabled = self.part_validation_enabled
return grpc_data

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


class UpdateComponentFailureMechanismPropsRequest(BaseModel):
"""Contains the properties of a component failure mechanism update per project."""

project: str
"""Name of the Sherlock project."""
component_failure_mechanism_properties_per_cca: list[ComponentFailureMechanism]
"""List of potting region data to update."""

@field_validator("project")
@classmethod
def str_validation(cls, value: str, info: ValidationInfo):
"""Validate string fields listed."""
return basic_str_validator(value, info.field_name)

def _convert_to_grpc(
self,
) -> analysis_service.UpdateComponentFailureMechanismPropsRequest:
request = analysis_service.UpdateComponentFailureMechanismPropsRequest()
request.project = self.project
for properties in self.component_failure_mechanism_properties_per_cca:
request.componentFailureMechanismProperties.append(properties._convert_to_grpc())
return request
84 changes: 84 additions & 0 deletions tests/test_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from unittest.mock import Mock

import grpc
import pydantic
import pytest

from ansys.sherlock.core.analysis import Analysis
Expand All @@ -26,10 +27,12 @@
SherlockUpdateSolderFatiguePropsError,
)
from ansys.sherlock.core.types.analysis_types import (
ComponentFailureMechanism,
ElementOrder,
ModelSource,
RunAnalysisRequestAnalysisType,
RunStrainMapAnalysisRequestAnalysisType,
UpdateComponentFailureMechanismPropsRequest,
UpdatePcbModelingPropsRequestAnalysisType,
UpdatePcbModelingPropsRequestPcbMaterialModel,
UpdatePcbModelingPropsRequestPcbModelType,
Expand Down Expand Up @@ -62,6 +65,7 @@ def test_all():
helper_test_update_part_modeling_props(analysis)
helper_test_update_parts_list_validation_props(analysis)
helper_test_get_parts_list_validation_analysis_props(analysis)
helper_test_update_component_failure_mechanism_props(analysis)


def helper_test_run_analysis(analysis: Analysis):
Expand Down Expand Up @@ -1942,5 +1946,85 @@ def helper_test_get_parts_list_validation_analysis_props(analysis: Analysis):
pytest.fail(str(e))


def helper_test_update_component_failure_mechanism_props(analysis: Analysis):
"""Test update component failure mechanism properties API."""
try:
ComponentFailureMechanism(
cca_name="",
default_part_temp_rise=0.1,
default_part_temp_rise_units="F",
part_temp_rise_min_enabled=True,
part_validation_enabled=False,
)
pytest.fail("No exception raised when using an invalid parameter")
except Exception as e:
assert isinstance(e, pydantic.ValidationError)
assert (
e.errors()[0]["msg"] == "Value error, cca_name is invalid because it is None or empty."
)

try:
UpdateComponentFailureMechanismPropsRequest(
project="",
)
pytest.fail("No exception raised when using an invalid parameter")
except Exception as e:
assert isinstance(e, pydantic.ValidationError)
assert (
e.errors()[0]["msg"] == "Value error, project is invalid because it is None or empty."
)

try:
UpdateComponentFailureMechanismPropsRequest(
project="Test",
component_failure_mechanism_properties_per_cca=["Not a ComponentFailureMechanism"],
)
pytest.fail("No exception raised when using an invalid parameter")
except Exception as e:
assert isinstance(e, pydantic.ValidationError)
assert (
e.errors()[0]["msg"]
== "Input should be a valid dictionary or instance of ComponentFailureMechanism"
)

component_failure_mechanism = ComponentFailureMechanism(
cca_name="Main Board",
default_part_temp_rise=1.2,
default_part_temp_rise_units="K",
part_temp_rise_min_enabled=False,
part_validation_enabled=False,
)
component_failure_mechanism2 = ComponentFailureMechanism(
cca_name="Memory Card 1",
default_part_temp_rise=2.1,
default_part_temp_rise_units="F",
part_temp_rise_min_enabled=False,
part_validation_enabled=False,
)
request = UpdateComponentFailureMechanismPropsRequest(
project="Invalid project",
component_failure_mechanism_properties_per_cca=[
component_failure_mechanism,
component_failure_mechanism2,
],
)

if analysis._is_connection_up():
responses = analysis.update_component_failure_mechanism_analysis_props(request)

assert len(responses) == 2
for return_code in responses:
assert return_code.value == -1
assert return_code.message == f"Cannot find project: {request.project}"

request.project = "AssemblyTutorial"
responses = analysis.update_component_failure_mechanism_analysis_props(request)

assert len(responses) == 2
for return_code in responses:
assert return_code.value == 0
assert return_code.message == ""


if __name__ == "__main__":
test_all()

0 comments on commit 40b49fc

Please sign in to comment.