Skip to content

Commit 019103d

Browse files
committed
Merge branch 'main' into release/0.2
2 parents 8826c30 + d891323 commit 019103d

File tree

14 files changed

+645
-46
lines changed

14 files changed

+645
-46
lines changed

.github/workflows/ci_cd.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ jobs:
6969
python-version: [ '3.8', '3.9', '3.10', '3.11' ]
7070

7171
steps:
72-
- uses: actions/checkout@v3
72+
- uses: actions/checkout@v4
7373

7474
- name: Set up Python
7575
uses: actions/setup-python@v4

.github/workflows/label.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
name: Syncer
1717
runs-on: ubuntu-latest
1818
steps:
19-
- uses: actions/checkout@v3
19+
- uses: actions/checkout@v4
2020
- uses: micnncim/action-label-syncer@v1
2121
env:
2222
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

doc/source/api/analysis.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,14 @@ The ``analysis`` module contains all analysis capabilities.
1111
:toctree: _autosummary
1212

1313
ansys.sherlock.core.analysis.Analysis.get_harmonic_vibe_input_fields
14+
ansys.sherlock.core.analysis.Analysis.get_ict_analysis_input_fields
1415
ansys.sherlock.core.analysis.Analysis.get_mechanical_shock_input_fields
1516
ansys.sherlock.core.analysis.Analysis.get_random_vibe_input_fields
1617
ansys.sherlock.core.analysis.Analysis.get_solder_fatigue_input_fields
1718
ansys.sherlock.core.analysis.Analysis.run_analysis
1819
ansys.sherlock.core.analysis.Analysis.run_strain_map_analysis
1920
ansys.sherlock.core.analysis.Analysis.update_harmonic_vibe_props
21+
ansys.sherlock.core.analysis.Analysis.update_ict_analysis_props
2022
ansys.sherlock.core.analysis.Analysis.update_mechanical_shock_props
2123
ansys.sherlock.core.analysis.Analysis.update_natural_frequency_props
2224
ansys.sherlock.core.analysis.Analysis.update_part_modeling_props

doc/source/api/parts.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@ The ``parts`` module contains all parts management capabilities.
1616
ansys.sherlock.core.parts.Parts.update_parts_list
1717
ansys.sherlock.core.parts.Parts.update_parts_locations
1818
ansys.sherlock.core.parts.Parts.update_parts_locations_by_file
19-
ansys.sherlock.core.parts.Parts.get_part_location
19+
ansys.sherlock.core.parts.Parts.get_part_location
20+
ansys.sherlock.core.parts.Parts.update_parts_from_AVL

doc/source/api/parts_types.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,7 @@ Constants and classes used for the Parts API.
1111
:toctree: _autosummary
1212

1313
PartLocation
14+
PartsListSearchMatchingMode
15+
PartsListSearchDuplicationMode
16+
AVLPartNum
17+
AVLDescription

doc/source/getting_started/installation.rst

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,14 @@ The ``ansys-sherlock-core`` package supports Python 3.8 through Python 3.11 on W
99
To use PySherlock, you must download and install both the ``ansys-api-sherlock``
1010
and ``ansys-sherlock-core`` packages. By using ``pip``, ``ansys-api-sherlock`` is
1111
installed as part of ``ansys-sherlock-core``. Run the following to install
12-
1312
the publicly distributed version of the package.
1413

1514
.. code::
1615
1716
pip install ansys-sherlock-core
1817
1918
If you want to install the ``ansys-api-sherlock`` and ``ansys-sherlock-core`` packages
20-
from its source code directly, follow the upcoming instructions:
19+
from its source code directly, follow these instructions.
2120

2221
#. Download the latest ``ansys-api-sherlock`` package by running this
2322
``git clone`` command:

doc/source/user_guide/index.rst

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -117,14 +117,16 @@ method to add a random vibe profile:
117117

118118
.. code::
119119
120-
sherlock.lifecycle.add_random_vibe_profile(
120+
sherlock.lifecycle.add_random_vibe_profiles(
121121
"Tutorial",
122-
"Phase 1",
123-
"RVEvent 1",
124-
"Profile 1",
125-
"HZ",
126-
"G2/Hz",
127-
[(30.4, 7.61e-5), (204, 0.1), (296, 0.06), (385, 0.06), (454, 0.03), (497, 0.06)]
122+
[(
123+
"Phase 1",
124+
"RVEvent 1",
125+
"Profile 1",
126+
"HZ",
127+
"G2/Hz",
128+
[(30.4, 7.61e-5), (204, 0.1), (296, 0.06), (385, 0.06), (454, 0.03), (497, 0.06)],
129+
)]
128130
)
129131
130132
For information on the ``lifecycle`` module and its methods, see :ref:`ref_lifecycle_module`.
@@ -140,7 +142,7 @@ to run a random vibe analysis:
140142
"Tutorial",
141143
"Main Board",
142144
[
143-
("RANDOMVIBE",
145+
(RunAnalysisRequestAnalysisType.RANDOM_VIBE,
144146
[
145147
("Phase 1", ["RVEvent 1"])
146148
]

pyproject.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,21 +24,21 @@ classifiers = [
2424
]
2525

2626
dependencies = [
27-
"ansys-api-sherlock==0.1.20",
27+
"ansys-api-sherlock==0.1.21",
2828
"grpcio>=1.17",
2929
"importlib-metadata>=4.0,<5; python_version<='3.8'",
3030
"protobuf~=3.20",
3131
]
3232

3333
[project.optional-dependencies]
3434
tests = [
35-
"grpcio==1.57.0",
35+
"grpcio==1.58.0",
3636
"protobuf==3.20.3",
37-
"pytest==7.4.0",
37+
"pytest==7.4.2",
3838
"pytest-cov==4.1.0",
3939
]
4040
doc = [
41-
"ansys-sphinx-theme==0.10.4",
41+
"ansys-sphinx-theme==0.11.2",
4242
"numpydoc==1.5.0",
4343
"Sphinx==6.2.1", # BLOCKED BY sphinx-design - Cannot upgrade to Sphinx 7 for now
4444
"sphinx-copybutton==0.5.2",

src/ansys/sherlock/core/analysis.py

Lines changed: 183 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
SherlockRunAnalysisError,
1515
SherlockRunStrainMapAnalysisError,
1616
SherlockUpdateHarmonicVibePropsError,
17+
SherlockUpdateICTAnalysisPropsError,
1718
SherlockUpdateMechanicalShockPropsError,
1819
SherlockUpdateNaturalFrequencyPropsError,
1920
SherlockUpdatePartModelingPropsError,
@@ -42,6 +43,10 @@ def __init__(self, channel):
4243
"forceModelRebuild": "force_model_rebuild",
4344
"harmonicVibeDamping": "harmonic_vibe_damping",
4445
"harmonicVibeCount": "harmonic_vibe_count",
46+
"ictApplicationTime": "ict_application_time",
47+
"ictApplicationTimeUnits": "ict_application_time_units",
48+
"ictNumberOfEvents": "ict_number_of_events",
49+
"ictResultCount": "ict_result_count",
4550
"modelSource": "model_source",
4651
"naturalFreqCount": "natural_freq_count",
4752
"naturalFreqMin": "natural_freq_min",
@@ -333,7 +338,7 @@ def update_harmonic_vibe_props(
333338

334339
if "cca_name" not in harmonic_vibe_props.keys():
335340
raise SherlockUpdateHarmonicVibePropsError(
336-
message=f"CCA name is invalid for harmonic vibe properties {i}."
341+
message=f"CCA name is missing for harmonic vibe properties {i}."
337342
)
338343

339344
cca_name = harmonic_vibe_props["cca_name"]
@@ -483,6 +488,183 @@ def update_harmonic_vibe_props(
483488
LOG.error(str(e))
484489
raise e
485490

491+
def get_ict_analysis_input_fields(self):
492+
"""Get ICT analysis property fields based on the user configuration.
493+
494+
Parameters
495+
----------
496+
None
497+
498+
Returns
499+
-------
500+
list
501+
List of ICT analysis property fields based on the user configuration.
502+
503+
Examples
504+
--------
505+
>>> from ansys.sherlock.core.launcher import launch_sherlock
506+
>>> sherlock = launch_sherlock()
507+
>>> sherlock.analysis.get_ict_analysis_input_fields()
508+
"""
509+
if not self._is_connection_up():
510+
LOG.error("There is no connection to a gRPC service.")
511+
return
512+
513+
message = SherlockAnalysisService_pb2.GetICTAnalysisInputFieldsRequest()
514+
response = self.stub.getICTAnalysisInputFields(message)
515+
516+
fields = self._translate_field_names(response.fieldName)
517+
LOG.info(fields)
518+
519+
return fields
520+
521+
def update_ict_analysis_props(
522+
self,
523+
project,
524+
ict_analysis_properties,
525+
):
526+
"""Update properties for an ICT analysis.
527+
528+
Parameters
529+
----------
530+
project : str
531+
Name of the Sherlock project.
532+
ict_analysis_properties : list
533+
List of ICT analysis properties for a CCA consisting of these properties:
534+
535+
- cca_name : str
536+
Name of the CCA.
537+
- ict_application_time : double
538+
Specifies the amount of time to complete one ICT event.
539+
- ict_application_time_units : str
540+
Application time units.
541+
Options are ``"ms"``, ``"sec"``, ``"min"``, ``"hr"``, ``"day"``, ``"year"``.
542+
- ict_number_of_events: int
543+
Specifies the number of events to apply to the application time when computing
544+
the time to failure for a component.
545+
- part_validation_enabled: bool
546+
Whether to enable part validation. The default is ``None``.
547+
- require_material_assignment_enabled: bool
548+
Whether to require material assignment. The default is ``None``.
549+
- ict_result_count: int
550+
The number of ICT result layers to generate. This parameter is for use with
551+
thermal analysis.
552+
553+
Returns
554+
-------
555+
int
556+
Status code of the response. 0 for success.
557+
558+
Examples
559+
--------
560+
>>> from ansys.sherlock.core.launcher import launch_sherlock
561+
>>> sherlock = launch_sherlock()
562+
>>> sherlock.project.import_odb_archive(
563+
"ODB++ Tutorial.tgz",
564+
True,
565+
True,
566+
True,
567+
True,
568+
project="Test",
569+
cca_name="Card",
570+
)
571+
>>> sherlock.analysis.update_ict_analysis_props(
572+
"Test",
573+
[{
574+
'cca_name': 'Card',
575+
'ict_application_time': 2,
576+
'ict_application_time_units': 'sec',
577+
'ict_number_of_events': 10,
578+
'part_validation_enabled': False,
579+
'require_material_assignment_enabled': False,
580+
},
581+
]
582+
)
583+
584+
"""
585+
try:
586+
if project == "":
587+
raise SherlockUpdateICTAnalysisPropsError(message="Project name is invalid.")
588+
589+
if not isinstance(ict_analysis_properties, list):
590+
raise SherlockUpdateICTAnalysisPropsError(
591+
message="ICT analysis properties argument is invalid."
592+
)
593+
594+
if len(ict_analysis_properties) == 0:
595+
raise SherlockUpdateICTAnalysisPropsError(
596+
message="One or more ICT analysis properties are required."
597+
)
598+
599+
request = SherlockAnalysisService_pb2.UpdateICTAnalysisPropsRequest(project=project)
600+
601+
for i, ict_analysis_props in enumerate(ict_analysis_properties):
602+
if not isinstance(ict_analysis_props, dict):
603+
raise SherlockUpdateICTAnalysisPropsError(
604+
f"ICT analysis props argument is invalid for ICT analysis properties {i}."
605+
)
606+
607+
if "cca_name" not in ict_analysis_props.keys():
608+
raise SherlockUpdateICTAnalysisPropsError(
609+
message=f"CCA name is missing for ICT analysis properties {i}."
610+
)
611+
612+
cca_name = ict_analysis_props["cca_name"]
613+
if cca_name == "":
614+
raise SherlockUpdateICTAnalysisPropsError(
615+
message=f"CCA name is invalid for ICT analysis properties {i}."
616+
)
617+
618+
props_request = request.ictAnalysisProperties.add()
619+
props_request.ccaName = cca_name
620+
621+
if "ict_analysis_count" in ict_analysis_props.keys():
622+
props_request.ictAnalysisCount = ict_analysis_props["ict_analysis_count"]
623+
624+
if "ict_application_time" in ict_analysis_props.keys():
625+
props_request.applicationTime = ict_analysis_props["ict_application_time"]
626+
627+
if "ict_application_time_units" in ict_analysis_props.keys():
628+
props_request.applicationTimeUnits = ict_analysis_props[
629+
"ict_application_time_units"
630+
]
631+
632+
if "ict_number_of_events" in ict_analysis_props.keys():
633+
props_request.numberOfEvents = ict_analysis_props["ict_number_of_events"]
634+
635+
if "part_validation_enabled" in ict_analysis_props.keys():
636+
props_request.partValidationEnabled = ict_analysis_props[
637+
"part_validation_enabled"
638+
]
639+
640+
if "require_material_assignment_enabled" in ict_analysis_props.keys():
641+
props_request.requireMaterialAssignmentEnabled = ict_analysis_props[
642+
"require_material_assignment_enabled"
643+
]
644+
645+
if "force_model_rebuild" in ict_analysis_props.keys():
646+
props_request.forceModelRebuild = ict_analysis_props["force_model_rebuild"]
647+
648+
except SherlockUpdateICTAnalysisPropsError as e:
649+
LOG.error(str(e))
650+
raise e
651+
652+
if not self._is_connection_up():
653+
LOG.error("There is no connection to a gRPC service.")
654+
return
655+
656+
response = self.stub.updateICTAnalysisProps(request)
657+
658+
try:
659+
if response.value == -1:
660+
raise SherlockUpdateICTAnalysisPropsError(response.message)
661+
else:
662+
LOG.info(response.message)
663+
return response.value
664+
except SherlockUpdateICTAnalysisPropsError as e:
665+
LOG.error(str(e))
666+
raise e
667+
486668
def get_mechanical_shock_input_fields(self, model_source=None):
487669
"""Get mechanical shock property fields based on the user configuration.
488670

src/ansys/sherlock/core/errors.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -810,6 +810,18 @@ def __str__(self):
810810
return f"Update harmonic vibe properties error: {self.message}"
811811

812812

813+
class SherlockUpdateICTAnalysisPropsError(Exception):
814+
"""Contains the error raised when properties for ICT analysis cannot be updated."""
815+
816+
def __init__(self, message):
817+
"""Initialize error message."""
818+
self.message = message
819+
820+
def __str__(self):
821+
"""Format error message."""
822+
return f"Update ICT analysis properties error: {self.message}"
823+
824+
813825
class SherlockUpdateMechanicalShockPropsError(Exception):
814826
"""Contains the error raised when properties for mechanical shock analysis cannot be updated."""
815827

@@ -880,3 +892,20 @@ def __init__(self, message):
880892
def __str__(self):
881893
"""Format error message."""
882894
return f"Update part modeling props error: {self.message}"
895+
896+
897+
class SherlockUpdatePartsFromAVLError(Exception):
898+
"""Contains the error raised when parts list cannot be updated by AVL."""
899+
900+
def __init__(self, message=None, error_array=None):
901+
"""Initialize error message."""
902+
self.message = message
903+
self.error_array = error_array
904+
905+
def str_itr(self):
906+
"""Create list of error messages."""
907+
if self.message is None:
908+
return [f"Update part from AVL error: {error}" for error in self.error_array]
909+
910+
assert self.error_array is None
911+
return [f"Update part from AVL error: {self.message}"]

0 commit comments

Comments
 (0)