Skip to content

Commit 146ed7f

Browse files
Paul/0605 (#119)
Co-authored-by: Roberto Pastor Muela <[email protected]>
1 parent ab4826e commit 146ed7f

File tree

4 files changed

+462
-0
lines changed

4 files changed

+462
-0
lines changed

doc/source/api/analysis.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ The ``analysis`` module contains all analysis capabilities.
1414
ansys.sherlock.core.analysis.Analysis.get_random_vibe_input_fields
1515
ansys.sherlock.core.analysis.Analysis.run_analysis
1616
ansys.sherlock.core.analysis.Analysis.run_strain_map_analysis
17+
ansys.sherlock.core.analysis.Analysis.update_harmonic_vibe_props
1718
ansys.sherlock.core.analysis.Analysis.update_natural_frequency_props
1819
ansys.sherlock.core.analysis.Analysis.update_pcb_modeling_props
1920
ansys.sherlock.core.analysis.Analysis.update_random_vibe_props

src/ansys/sherlock/core/analysis.py

Lines changed: 289 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from ansys.sherlock.core.errors import (
1414
SherlockRunAnalysisError,
1515
SherlockRunStrainMapAnalysisError,
16+
SherlockUpdateHarmonicVibePropsError,
1617
SherlockUpdateNaturalFrequencyPropsError,
1718
SherlockUpdatePcbModelingPropsError,
1819
SherlockUpdateRandomVibePropsError,
@@ -196,6 +197,294 @@ def get_harmonic_vibe_input_fields(self):
196197

197198
return fields
198199

200+
def update_harmonic_vibe_props(
201+
self,
202+
project,
203+
harmonic_vibe_properties,
204+
):
205+
"""Update properties for a harmonic vibe analysis.
206+
207+
Parameters
208+
----------
209+
project : str
210+
Name of the Sherlock project.
211+
harmonic_vibe_properties : list
212+
List of harmonic vibe properties for a CCA consisting of these properties:
213+
214+
- cca_name : str
215+
Name of the CCA.
216+
- harmonic_vibe_count : int
217+
Number of harmonic vibe result layers to generate.
218+
- harmonic_vibe_damping: str
219+
One or more modal damping ratios. The default is ``None``.
220+
Separate multiple float values with commas.
221+
- part_validation_enabled: bool
222+
Whether to enable part validation. The default is ``None``.
223+
- require_material_assignment_enabled: bool
224+
Whether to require material assignment. The default is ``None``.
225+
- analysis_temp: double
226+
Temperature. The default is ``None``.
227+
- analysis_temp_units: str
228+
Temperature units. The default is ``None``.
229+
Options are ``"C"``, ``"F"``, and ``"K"``.
230+
- force_model_rebuild: str
231+
How to handle rebuilding of the model. The default is ``None``.
232+
Options are ``"FORCE"`` and ``"AUTO"``.
233+
- filter_by_event_frequency: bool
234+
Indicates if harmonic results outside analysis event range are included.
235+
This parameter is not used for NX Nastran analysis.
236+
- natural_freq_min: double
237+
Minimum frequency. The default is ``None``.
238+
This parameter is for NX Nastran analysis only.
239+
- natural_freq_min_units: str
240+
Minimum frequency units. The default is ``None``.
241+
Options are ``"HZ"``, ``"KHZ"``, ``"MHZ"``, and ``"GHZ"``.
242+
This parameter is for NX Nastran analysis only.
243+
- natural_freq_max: double
244+
Maximum frequency. The default is ``None``.
245+
This parameter is for NX Nastran analysis only.
246+
- natural_freq_max_units: str
247+
Maximum frequency units. The default is ``None``.
248+
Options are ``"HZ"``, ``"KHZ"``, ``"MHZ"``, and ``"GHZ"``.
249+
This parameter is for NX Nastran analysis only.
250+
- reuse_modal_analysis: bool
251+
Whether to reuse the natural frequency for modal analysis. The
252+
default is ``None``. This parameter is for NX Nastran analysis only.
253+
254+
Examples
255+
--------
256+
>>> from ansys.sherlock.core.launcher import launch_sherlock
257+
>>> sherlock = launch_sherlock()
258+
>>> sherlock.project.import_odb_archive(
259+
"ODB++ Tutorial.tgz",
260+
True,
261+
True,
262+
True,
263+
True,
264+
project="Test",
265+
cca_name="Card",
266+
)
267+
>>> sherlock.analysis.update_harmonic_vibe_props(
268+
"Test",
269+
[{
270+
'cca_name': 'Card',
271+
'harmonic_vibe_count': 2,
272+
'harmonic_vibe_damping': '0.01, 0.05',
273+
'part_validation_enabled': False,
274+
'require_material_assignment_enabled': False,
275+
'analysis_temp': 20,
276+
'analysis_temp_units': 'C',
277+
'filter_by_event_frequency': False,
278+
},
279+
]
280+
)
281+
282+
"""
283+
if self.FREQ_UNIT_LIST is None:
284+
self._init_freq_units()
285+
if self.TEMP_UNIT_LIST is None:
286+
self._init_temp_units()
287+
try:
288+
if project == "":
289+
raise SherlockUpdateHarmonicVibePropsError(message="Project name is invalid.")
290+
291+
if not isinstance(harmonic_vibe_properties, list):
292+
raise SherlockUpdateHarmonicVibePropsError(
293+
message="Harmonic vibe properties argument is invalid."
294+
)
295+
296+
if len(harmonic_vibe_properties) == 0:
297+
raise SherlockUpdateHarmonicVibePropsError(
298+
message="One or more harmonic vibe properties are required."
299+
)
300+
301+
request = SherlockAnalysisService_pb2.UpdateHarmonicVibePropsRequest(project=project)
302+
303+
for i, harmonic_vibe_props in enumerate(harmonic_vibe_properties):
304+
if not isinstance(harmonic_vibe_props, dict):
305+
raise SherlockUpdateHarmonicVibePropsError(
306+
f"Harmonic vibe props argument is invalid for harmonic vibe properties {i}."
307+
)
308+
309+
if "cca_name" not in harmonic_vibe_props.keys():
310+
raise SherlockUpdateHarmonicVibePropsError(
311+
message=f"CCA name is invalid for harmonic vibe properties {i}."
312+
)
313+
314+
cca_name = harmonic_vibe_props["cca_name"]
315+
if cca_name == "":
316+
raise SherlockUpdateHarmonicVibePropsError(
317+
message=f"CCA name is invalid for harmonic vibe properties {i}."
318+
)
319+
320+
if "harmonic_vibe_count" in harmonic_vibe_props.keys():
321+
harmonic_vibe_count = harmonic_vibe_props["harmonic_vibe_count"]
322+
else:
323+
harmonic_vibe_count = None
324+
325+
if "harmonic_vibe_damping" in harmonic_vibe_props.keys():
326+
harmonic_vibe_damping = harmonic_vibe_props["harmonic_vibe_damping"]
327+
if harmonic_vibe_damping is not None:
328+
for value in harmonic_vibe_damping.split(","):
329+
try:
330+
float(value.strip())
331+
except ValueError:
332+
raise SherlockUpdateHarmonicVibePropsError(
333+
message=f"Harmonic vibe damping value is invalid"
334+
f" for harmonic vibe properties {i}: " + value.strip()
335+
)
336+
else:
337+
harmonic_vibe_damping = None
338+
339+
if "part_validation_enabled" in harmonic_vibe_props.keys():
340+
part_validation_enabled = harmonic_vibe_props["part_validation_enabled"]
341+
else:
342+
part_validation_enabled = None
343+
344+
if "require_material_assignment_enabled" in harmonic_vibe_props.keys():
345+
require_material_assignment_enabled = harmonic_vibe_props[
346+
"require_material_assignment_enabled"
347+
]
348+
else:
349+
require_material_assignment_enabled = None
350+
351+
if "analysis_temp" in harmonic_vibe_props.keys():
352+
analysis_temp = harmonic_vibe_props["analysis_temp"]
353+
else:
354+
analysis_temp = None
355+
356+
if "analysis_temp_units" in harmonic_vibe_props.keys():
357+
analysis_temp_units = harmonic_vibe_props["analysis_temp_units"]
358+
if (
359+
(self.TEMP_UNIT_LIST is not None)
360+
and (analysis_temp_units is not None)
361+
and (analysis_temp_units not in self.TEMP_UNIT_LIST)
362+
):
363+
raise SherlockUpdateHarmonicVibePropsError(
364+
message=f"Analysis temperature units are invalid for "
365+
f"harmonic vibe properties {i}: " + analysis_temp_units
366+
)
367+
else:
368+
analysis_temp_units = None
369+
370+
if "force_model_rebuild" in harmonic_vibe_props.keys():
371+
force_model_rebuild = harmonic_vibe_props["force_model_rebuild"]
372+
else:
373+
force_model_rebuild = None
374+
375+
if "filter_by_event_frequency" in harmonic_vibe_props.keys():
376+
filter_by_event_frequency = harmonic_vibe_props["filter_by_event_frequency"]
377+
else:
378+
filter_by_event_frequency = None
379+
380+
if "natural_freq_min" in harmonic_vibe_props.keys():
381+
natural_freq_min = harmonic_vibe_props["natural_freq_min"]
382+
else:
383+
natural_freq_min = None
384+
385+
if "natural_freq_min_units" in harmonic_vibe_props.keys():
386+
natural_freq_min_units = harmonic_vibe_props["natural_freq_min_units"]
387+
if (
388+
(self.FREQ_UNIT_LIST is not None)
389+
and (natural_freq_min_units is not None)
390+
and (natural_freq_min_units not in self.FREQ_UNIT_LIST)
391+
):
392+
raise SherlockUpdateHarmonicVibePropsError(
393+
message=f"Minimum natural frequency units are invalid for "
394+
f"harmonic vibe properties {i}: " + natural_freq_min_units
395+
)
396+
else:
397+
natural_freq_min_units = None
398+
399+
if "natural_freq_max" in harmonic_vibe_props.keys():
400+
natural_freq_max = harmonic_vibe_props["natural_freq_max"]
401+
else:
402+
natural_freq_max = None
403+
404+
if "natural_freq_max_units" in harmonic_vibe_props.keys():
405+
natural_freq_max_units = harmonic_vibe_props["natural_freq_max_units"]
406+
if (
407+
(self.FREQ_UNIT_LIST is not None)
408+
and (natural_freq_max_units is not None)
409+
and (natural_freq_max_units not in self.FREQ_UNIT_LIST)
410+
):
411+
raise SherlockUpdateHarmonicVibePropsError(
412+
message=f"Maximum natural frequency units are invalid for "
413+
f"harmonic vibe properties {i}: " + natural_freq_max_units
414+
)
415+
else:
416+
natural_freq_max_units = None
417+
418+
if "reuse_modal_analysis" in harmonic_vibe_props.keys():
419+
reuse_modal_analysis = harmonic_vibe_props["reuse_modal_analysis"]
420+
else:
421+
reuse_modal_analysis = None
422+
423+
props_request = request.harmonicVibeProperties.add()
424+
props_request.ccaName = cca_name
425+
props_request.modelSource = SherlockAnalysisService_pb2.ModelSource.GENERATED
426+
427+
if harmonic_vibe_count is not None:
428+
props_request.harmonicVibeCount = harmonic_vibe_count
429+
430+
if harmonic_vibe_damping is not None:
431+
props_request.harmonicVibeDamping = harmonic_vibe_damping
432+
433+
if part_validation_enabled is not None:
434+
props_request.partValidationEnabled = part_validation_enabled
435+
436+
if require_material_assignment_enabled is not None:
437+
props_request.requireMaterialAssignmentEnabled = (
438+
require_material_assignment_enabled
439+
)
440+
441+
if analysis_temp is not None:
442+
props_request.analysisTemp = analysis_temp
443+
444+
if analysis_temp_units is not None:
445+
props_request.analysisTempUnits = analysis_temp_units
446+
447+
if force_model_rebuild is not None:
448+
props_request.forceModelRebuild = force_model_rebuild
449+
450+
if filter_by_event_frequency is not None:
451+
props_request.filterByEventFrequency = filter_by_event_frequency
452+
453+
if natural_freq_min is not None:
454+
props_request.naturalFreqMin = natural_freq_min
455+
456+
if natural_freq_min_units is not None:
457+
props_request.naturalFreqMinUnits = natural_freq_min_units
458+
459+
if natural_freq_max is not None:
460+
props_request.naturalFreqMax = natural_freq_max
461+
462+
if natural_freq_max_units is not None:
463+
props_request.naturalFreqMaxUnits = natural_freq_max_units
464+
465+
if reuse_modal_analysis is not None:
466+
props_request.reuseModalAnalysis = reuse_modal_analysis
467+
468+
except SherlockUpdateHarmonicVibePropsError as e:
469+
LOG.error(str(e))
470+
raise e
471+
472+
if not self._is_connection_up():
473+
LOG.error("There is no connection to a gRPC service.")
474+
return
475+
476+
response = self.stub.updateHarmonicVibeProps(request)
477+
478+
try:
479+
if response.value == -1:
480+
raise SherlockUpdateHarmonicVibePropsError(response.message)
481+
else:
482+
LOG.info(response.message)
483+
return response.value
484+
except SherlockUpdateHarmonicVibePropsError as e:
485+
LOG.error(str(e))
486+
raise e
487+
199488
def get_random_vibe_input_fields(self, model_source=None):
200489
"""Get random vibe property fields based on the user configuration.
201490

src/ansys/sherlock/core/errors.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -771,3 +771,15 @@ def __init__(self, message):
771771
def __str__(self):
772772
"""Initialize error message."""
773773
return f"Update PCB Modeling Error: {self.message}"
774+
775+
776+
class SherlockUpdateHarmonicVibePropsError(Exception):
777+
"""Contains the error raised when properties for harmonic vibe analysis cannot be updated."""
778+
779+
def __init__(self, message):
780+
"""Initialize error message."""
781+
self.message = message
782+
783+
def __str__(self):
784+
"""Format error message."""
785+
return f"Update harmonic vibe properties error: {self.message}"

0 commit comments

Comments
 (0)