diff --git a/examples/02-Performance-Improvements/02-mesh-skin.py b/examples/02-Performance-Improvements/02-mesh-skin.py index ac93eebef..5922a3459 100644 --- a/examples/02-Performance-Improvements/02-mesh-skin.py +++ b/examples/02-Performance-Improvements/02-mesh-skin.py @@ -50,7 +50,7 @@ # Extract displacement data on the skin. displacement_skin = simulation.displacement(skin=True) -displacement_skin.plot() +displacement_skin.plot(text="U with skin=True") print(f"number of nodes with skin=True: {len(displacement_skin.index.mesh_index)}") print(f"number of nodes with skin=False: {len(simulation.mesh.node_ids)}") @@ -62,7 +62,7 @@ # Averaging, and invariants computation are done through a solid to skin connectivity mapping. elemental_stress_skin = simulation.stress_principal_elemental(components=[1], skin=True) -elemental_stress_skin.plot() +elemental_stress_skin.plot(text="S1 with skin=True") print( f"number of elements with skin=True: {len(elemental_stress_skin.index.mesh_index)}" @@ -71,15 +71,15 @@ elastic_strain_eqv_skin = simulation.elastic_strain_eqv_von_mises_nodal(skin=True) -elastic_strain_eqv_skin.plot() +elastic_strain_eqv_skin.plot(text="EE with skin=True") ############################################################################### -# Extract the external layer on a selection of elements -# ----------------------------------------------------- +# Extract on the skin of a selection of elements +# ---------------------------------------------- all_elements = simulation.mesh.element_ids elements = [] for i in range(0, int(all_elements.size / 2)): elements.append(all_elements[i]) elemental_stress_skin = simulation.stress_principal_elemental(skin=elements) -elemental_stress_skin.plot() +elemental_stress_skin.plot(text="S1 with skin=elements") diff --git a/src/ansys/dpf/post/post_utility.py b/src/ansys/dpf/post/post_utility.py index 292c73b17..0d8d9d281 100644 --- a/src/ansys/dpf/post/post_utility.py +++ b/src/ansys/dpf/post/post_utility.py @@ -223,10 +223,10 @@ def load_simulation( simulation_type = AvailableSimulationTypes.unsteady_fluid else: raise ValueError( - f"Unknown analysis type '{analysis_type}' for {physics_type}." + f"Unknown analysis type '{analysis_type}' for '{physics_type}'." ) else: - raise ValueError(f"Unknown physics type '{physics_type}.") + raise ValueError(f"Unknown physics type '{physics_type}'.") if simulation_type in [ getattr(AvailableSimulationTypes, x) for x in vars(AvailableSimulationTypes) diff --git a/src/ansys/dpf/post/selection.py b/src/ansys/dpf/post/selection.py index e2cad3f45..ed65e8421 100644 --- a/src/ansys/dpf/post/selection.py +++ b/src/ansys/dpf/post/selection.py @@ -45,6 +45,7 @@ class _WfNames: cyclic_sectors_to_expand = "cyclic_sectors_to_expand" cyclic_phase = "cyclic_phase" result = "result" + result_mesh = "result_mesh" def _is_model_cyclic(is_cyclic: str): @@ -68,6 +69,7 @@ def __init__(self, server: Union[BaseServer, None] = None): """ self._server = get_or_create_server(server) self._selection = Workflow(server=self._server) + self._selection.progress_bar = False def select_time_freq_indices(self, time_freq_indices: List[int]) -> None: """Select time frequency sets by their indices (zero-based indexing). @@ -219,10 +221,33 @@ def __init__( """ self._server = get_or_create_server(server) self._selection = Workflow(server=self._server) - + self._selection.progress_bar = False + self._current_initial_mesh_output = None if scoping is not None: self.select_with_scoping(scoping) + def reduce_mesh(self, element_ids: Union[Scoping, List[int]]): + """Reduce the mesh with consideration to the given list of elements. + + Parameters + ---------- + element_ids: + Scoping or list of IDs of elements to reduce the mesh to. + """ + if not isinstance(element_ids, Scoping): + element_ids = Scoping( + ids=element_ids, location=locations.elemental, server=self._server + ) + op = operators.mesh.from_scoping(element_ids, server=self._server) + self._selection.add_operator(op) + # If the workflow already has an initial_mesh output, connect this after + if self._current_initial_mesh_output: + op.inputs.mesh.connect(self._current_initial_mesh_output) + else: + self._selection.set_input_name(_WfNames.initial_mesh, op.inputs.mesh) + self._selection.set_output_name(_WfNames.initial_mesh, op.outputs.mesh) + self._current_initial_mesh_output = op.outputs.mesh + def select_named_selection( self, named_selection: Union[str, List[str]], @@ -393,7 +418,7 @@ def select_skin( Native (as found in the file) location of the output result. Used to pick the location of the scoping. elements: - List of elements to use to compute the external layer, + List of elements to use to compute the skin, default is all the elements of the model. Getting the skin on a selection of elements for cyclic symmetry is not supported. is_model_cyclic: @@ -443,14 +468,30 @@ def select_skin( elements = Scoping( server=self._server, ids=elements, location=locations.elemental ) - mesh_by_scop_op = operators.mesh.from_scoping( - scoping=elements, server=self._server + forward_op = operators.utility.forward() + mesh_input = forward_op.inputs.any + nodal_scoping = operators.scoping.transpose( + mesh_scoping=elements, server=self._server + ) + nodal_scoping.connect(1, forward_op) + op.connect(0, forward_op) + op.inputs.mesh_scoping.connect( + nodal_scoping.outputs.mesh_scoping_as_scoping ) - mesh_input = mesh_by_scop_op.inputs.mesh - op.inputs.mesh.connect(mesh_by_scop_op) if mesh_input is not None: - self._selection.set_input_name(_WfNames.initial_mesh, mesh_input) + # If the workflow already has an initial_mesh output, connect this after + if self._current_initial_mesh_output: + mesh_input.connect(self._current_initial_mesh_output) + else: + self._selection.set_input_name(_WfNames.initial_mesh, mesh_input) + # self._selection.set_output_name(_WfNames.initial_mesh, op.outputs.mesh) + # self._current_initial_mesh_output = op.outputs.mesh + + # pass + # else: + # # otherwise, set this as the initial_mesh input + # self._selection.set_input_name(_WfNames.initial_mesh, mesh_input) if location == result_native_location: self._selection.set_output_name(_WfNames.mesh, op.outputs.mesh) self._selection.set_output_name(_WfNames.skin, op.outputs.mesh) @@ -721,9 +762,14 @@ def requires_mesh(self) -> bool: """Whether the selection workflow requires a ``mesh`` as an input or not.""" return _WfNames.initial_mesh in self._selection.input_names + @property + def reduces_mesh(self) -> bool: + """Whether the selection workflow gives a reduced ``mesh`` as an output or not.""" + return _WfNames.initial_mesh in self._selection.output_names + @property def outputs_mesh(self) -> bool: - """Whether the selection workflow as an output named ``mesh``.""" + """Whether the selection workflow has an output named ``mesh``.""" return _WfNames.mesh in self._selection.output_names def requires_manual_averaging( @@ -798,6 +844,16 @@ def spatial_selection(self) -> SpatialSelection: def spatial_selection(self, value: SpatialSelection): self._spatial_selection = value + def reduce_mesh(self, element_ids: Union[List[int]]): + """Reduce the mesh with consideration to the given list of elements. + + Parameters + ---------- + element_ids: + List of IDs of elements to reduce the mesh to. + """ + self._spatial_selection.reduce_mesh(element_ids) + def select_time_freq_indices(self, time_freq_indices: List[int]) -> None: """Select time frequency sets by their indices (zero-based indexing). @@ -1016,6 +1072,11 @@ def requires_mesh(self) -> bool: """Whether the selection workflow requires a ``initial_mesh`` as an input or not.""" return self._spatial_selection.requires_mesh + @property + def reduces_mesh(self) -> bool: + """Whether the selection workflow gives a reduced ``mesh`` as an output or not.""" + return self._spatial_selection.reduces_mesh + @property def outputs_mesh(self) -> bool: """Whether the selection workflow as an output named ``mesh``.""" diff --git a/src/ansys/dpf/post/simulation.py b/src/ansys/dpf/post/simulation.py index 02536a8e6..3359f72cb 100644 --- a/src/ansys/dpf/post/simulation.py +++ b/src/ansys/dpf/post/simulation.py @@ -536,12 +536,12 @@ def _build_result_workflow( force_elemental_nodal: bool, ) -> (dpf.Workflow, dpf.Operator): op = self._model.operator(name=name) - op.connect(7, self.mesh._meshed_region) if force_elemental_nodal: op.connect(9, "ElementalNodal") elif location: op.connect(9, location) wf = Workflow(server=self._model._server) + wf.set_input_name(_WfNames.result_mesh, op, 7) wf.set_input_name(_WfNames.read_cyclic, op, 14) wf.set_input_name(_WfNames.cyclic_sectors_to_expand, op, 18) wf.set_input_name(_WfNames.cyclic_phase, op, 19) @@ -816,6 +816,7 @@ def _build_selection( external_layer: bool = False, skin: Union[bool, List[int]] = False, expand_cyclic: Union[bool, List[Union[int, List[int]]]] = True, + reduce_mesh: Union[bool, List[int]] = False, ) -> Selection: tot = ( (node_ids is not None) @@ -841,6 +842,34 @@ def _build_selection( selection = Selection(server=self._model._server) # Create the SpatialSelection + # Reduce mesh if necessary + if reduce_mesh is not False: + extract_scoping = None + # Reduce on the list of reduced + if not isinstance(reduce_mesh, bool): + # reduce_mesh=list + select_mesh = Selection() + select_mesh.select_elements(reduce_mesh) + extract_scoping = select_mesh.spatial_selection.apply_to(self) + else: + # reduce_mesh=True + if not isinstance(skin, bool): + select_mesh = Selection() + select_mesh.select_elements(skin) + extract_scoping = select_mesh.spatial_selection.apply_to(self) + else: + # reduce_mesh=True, skin=True|False + if element_ids is not None: + select_mesh = Selection() + select_mesh.select_elements(element_ids) + extract_scoping = select_mesh.spatial_selection.apply_to(self) + elif named_selections: + select_mesh = Selection() + select_mesh.select_named_selection(named_selections) + extract_scoping = select_mesh.spatial_selection.apply_to(self) + if extract_scoping is not None: + selection.reduce_mesh(extract_scoping) + # First: the skin and the external layer to be able to have both a mesh scoping and # the skin/external layer if (skin is not None and skin is not False) or ( diff --git a/src/ansys/dpf/post/static_mechanical_simulation.py b/src/ansys/dpf/post/static_mechanical_simulation.py index 2a254c61b..4d1bb4bb9 100644 --- a/src/ansys/dpf/post/static_mechanical_simulation.py +++ b/src/ansys/dpf/post/static_mechanical_simulation.py @@ -37,6 +37,7 @@ def _get_result( phase_angle_cyclic: Union[float, None] = None, external_layer: Union[bool, List[int]] = False, skin: Union[bool, List[int]] = False, + reduce_mesh: Union[bool, List[int]] = False, ) -> DataFrame: """Extract results from the simulation. @@ -104,6 +105,11 @@ def _get_result( is computed over list of elements (not supported for cyclic symmetry). Getting the skin on more than one result (several time freq sets, split data...) is only supported starting with Ansys 2023R2. + reduce_mesh: + Perform a reduction of the mesh based on, by order of priority: + - The list of element IDs given to this parameter + - Parameter skin if reduce_mesh=True + - Parameter element_ids if reduce_mesh=True and skin=None Returns ------- @@ -138,6 +144,7 @@ def _get_result( location=location, external_layer=external_layer, skin=skin, + reduce_mesh=reduce_mesh, ) comp, to_extract, columns = self._create_components( @@ -173,18 +180,30 @@ def _get_result( ) if selection.requires_mesh: mesh_wf = core.Workflow(server=self._model._server) + mesh_wf.progress_bar = False mesh_wf.set_output_name( - _WfNames.initial_mesh, self._model.metadata.mesh_provider + "initial_mesh_wf_out", self._model.metadata.mesh_provider ) selection.spatial_selection._selection.connect_with( mesh_wf, - output_input_names={_WfNames.initial_mesh: _WfNames.initial_mesh}, + output_input_names={"initial_mesh_wf_out": _WfNames.initial_mesh}, + ) + else: + result_op.connect(7, self.mesh._meshed_region) + + if selection.reduces_mesh: + wf.connect_with( + selection.spatial_selection._selection, + output_input_names={ + "scoping": "mesh_scoping", + "initial_mesh": _WfNames.result_mesh, + }, + ) + else: + wf.connect_with( + selection.spatial_selection._selection, + output_input_names={"scoping": "mesh_scoping"}, ) - - wf.connect_with( - selection.spatial_selection._selection, - output_input_names={"scoping": "mesh_scoping"}, - ) # Treat cyclic cases wf = self._treat_cyclic(expand_cyclic, phase_angle_cyclic, wf) @@ -1099,6 +1118,7 @@ def stress_eqv_von_mises_elemental( phase_angle_cyclic: Union[float, None] = None, external_layer: Union[bool, List[int]] = False, skin: Union[bool, List[int]] = False, + reduce_mesh: Union[bool, List[int]] = False, ) -> DataFrame: """Extract elemental equivalent von Mises stress results from the simulation. @@ -1137,17 +1157,22 @@ def stress_eqv_von_mises_elemental( If the problem is multi-stage, can take a list of lists of sector numbers, ordered by stage. phase_angle_cyclic: - For cyclic problems, phase angle to apply (in degrees). + For cyclic problems, phase angle to apply (in degrees). external_layer: - Select the external layer (last layer of solid elements under the skin) - of the mesh for plotting and data extraction. If a list is passed, the external - layer is computed over list of elements. + Select the external layer (last layer of solid elements under the skin) + of the mesh for plotting and data extraction. If a list is passed, the external + layer is computed over list of elements. skin: - Select the skin (creates new 2D elements connecting the external nodes) - of the mesh for plotting and data extraction. If a list is passed, the skin - is computed over list of elements (not supported for cyclic symmetry). Getting the - skin on more than one result (several time freq sets, split data...) is only - supported starting with Ansys 2023R2. + Select the skin (creates new 2D elements connecting the external nodes) + of the mesh for plotting and data extraction. If a list is passed, the skin + is computed over list of elements (not supported for cyclic symmetry). Getting the + skin on more than one result (several time freq sets, split data...) is only + supported starting with Ansys 2023 R2. + reduce_mesh: + Perform a reduction of the mesh based on, by order of priority: + - The list of element IDs given to this parameter + - Parameter skin if reduce_mesh=True + - Parameter element_ids if reduce_mesh=True and skin=None Returns ------- @@ -1171,6 +1196,7 @@ def stress_eqv_von_mises_elemental( phase_angle_cyclic=phase_angle_cyclic, external_layer=external_layer, skin=skin, + reduce_mesh=reduce_mesh, ) def stress_eqv_von_mises_nodal( diff --git a/tests/test_selection.py b/tests/test_selection.py index a9eaa1c62..09676050f 100644 --- a/tests/test_selection.py +++ b/tests/test_selection.py @@ -5,7 +5,7 @@ from ansys.dpf import core as dpf from ansys.dpf import post from ansys.dpf.post import examples -from ansys.dpf.post.selection import SpatialSelection +from ansys.dpf.post.selection import SpatialSelection, _WfNames from conftest import SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_7_0 @@ -50,6 +50,32 @@ def test_spatial_selection_select_named_selection(allkindofcomplexity): assert 14826 in ids +def test_spatial_selection_select_skin(static_rst): + simulation = post.StaticMechanicalSimulation(static_rst) + selection = SpatialSelection() + selection._selection.progress_bar = False + selection.select_skin( + location=post.locations.elemental_nodal, + result_native_location=post.locations.elemental_nodal, + elements=[1, 2, 3], + ) + mesh_wf = dpf.Workflow() + mesh_wf.set_output_name( + _WfNames.initial_mesh, simulation._model.metadata.mesh_provider + ) + selection._selection.connect_with( + mesh_wf, + output_input_names={_WfNames.initial_mesh: _WfNames.initial_mesh}, + ) + # This returns a scoping on the initial mesh (logic to change?) + scoping_ids = selection.apply_to(simulation) + assert len(scoping_ids) == 8 + + # This gives the skin mesh with its 9 shell elements + skin = selection._selection.get_output(_WfNames.skin, dpf.MeshedRegion) + assert len(skin.elements.scoping.ids) == 9 + + @pytest.mark.skipif( not SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_7_0, reason="Faces added with ansys-dpf-server 2024.1.pre0.", diff --git a/tests/test_simulation.py b/tests/test_simulation.py index 701f62662..04133760a 100644 --- a/tests/test_simulation.py +++ b/tests/test_simulation.py @@ -657,31 +657,38 @@ def test_skin_layer(self, static_simulation: post.StaticMechanicalSimulation): def test_skin_layer2(self, static_simulation: post.StaticMechanicalSimulation): result = static_simulation.displacement(set_ids=[1], skin=[1, 2, 3]) - assert len(result.index.mesh_index) == 44 + assert len(result.index.mesh_index) == 38 + static_simulation.plot() + result.plot() def test_skin_layer3(self, static_simulation: post.StaticMechanicalSimulation): result = static_simulation.elastic_strain_eqv_von_mises_elemental( skin=[1, 2, 3] ) - if SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_7_1: - assert len(result.index.mesh_index) == 14 - else: - assert len(result.index.mesh_index) == 18 + assert len(result.index.mesh_index) == 9 def test_skin_layer4(self, static_simulation: post.StaticMechanicalSimulation): result = static_simulation.stress_principal_nodal(skin=[1, 2, 3]) - assert len(result.index.mesh_index) == 44 + assert len(result.index.mesh_index) == 38 def test_skin_layer5(self, static_simulation: post.StaticMechanicalSimulation): result = static_simulation.elastic_strain_eqv_von_mises_nodal(skin=[1, 2, 3]) - assert len(result.index.mesh_index) == 44 + assert len(result.index.mesh_index) == 38 def test_skin_layer6(self, static_simulation: post.StaticMechanicalSimulation): result = static_simulation.stress_principal_elemental(skin=[1, 2, 3]) - if SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_7_1: - assert len(result.index.mesh_index) == 14 - else: - assert len(result.index.mesh_index) == 18 + assert len(result.index.mesh_index) == 9 + + def test_reduced_mesh(self, static_simulation: post.StaticMechanicalSimulation): + result = static_simulation.stress_eqv_von_mises_elemental(reduce_mesh=True) + print(result) + assert len(result.mesh_index) == static_simulation.mesh.num_elements + result = static_simulation.stress_eqv_von_mises_elemental( + reduce_mesh=static_simulation.mesh.element_ids[:-2] + ) + print(static_simulation.mesh.element_ids[:-2]) + print(result) + assert len(result.mesh_index) == static_simulation.mesh.num_elements - 2 class TestTransientMechanicalSimulation: @@ -1324,13 +1331,17 @@ def test_skin_layer2( self, transient_simulation: post.TransientMechanicalSimulation ): result = transient_simulation.displacement(set_ids=[1], skin=[1, 2, 3]) - assert len(result.index.mesh_index) == 44 + if SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_7_1: + assert len(result.index.mesh_index) == 42 + else: + assert len(result.index.mesh_index) == 44 def test_skin_layer3( self, transient_simulation: post.TransientMechanicalSimulation ): + print(transient_simulation.mesh.named_selections) result = transient_simulation.stress_principal_elemental( - skin=list(range(1, 100)) + skin=transient_simulation.mesh.element_ids ) if SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_7_1: assert len(result.index.mesh_index) == 124 @@ -1341,7 +1352,7 @@ def test_skin_layer4( self, transient_simulation: post.TransientMechanicalSimulation ): result = transient_simulation.elastic_strain_eqv_von_mises_elemental( - skin=list(range(1, 100)) + skin=transient_simulation.mesh.element_ids ) if SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_7_1: assert len(result.index.mesh_index) == 124 @@ -1351,7 +1362,9 @@ def test_skin_layer4( def test_skin_layer5( self, transient_simulation: post.TransientMechanicalSimulation ): - result = transient_simulation.stress_principal_nodal(skin=list(range(1, 100))) + result = transient_simulation.stress_principal_nodal( + skin=transient_simulation.mesh.element_ids + ) if SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_7_1: assert len(result.index.mesh_index) == 374 else: @@ -1361,7 +1374,7 @@ def test_skin_layer6( self, transient_simulation: post.TransientMechanicalSimulation ): result = transient_simulation.elastic_strain_eqv_von_mises_nodal( - skin=list(range(1, 100)) + skin=transient_simulation.mesh.element_ids ) if SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_7_1: assert len(result.index.mesh_index) == 374 @@ -1995,10 +2008,21 @@ def test_disp_skin(self, frame_modal_simulation: post.ModalMechanicalSimulation) assert np.allclose( result.max(axis="node_ids").array, [0.05656421, 9.59989137, 1.08656671] ) - result = frame_modal_simulation.displacement(set_ids=[1], skin=[1, 2, 3]) - assert len(result.index.mesh_index) == 21 + + fixed_nodes = frame_modal_simulation.mesh.named_selections["_FIXEDSU"]._scoping + fixed_elements = dpf.operators.scoping.transpose( + mesh_scoping=fixed_nodes, + meshed_region=frame_modal_simulation.mesh._meshed_region, + ).eval() + result = frame_modal_simulation.displacement( + set_ids=[1], skin=fixed_elements.ids + ) + if SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_7_1: + assert len(result.index.mesh_index) == 335 + else: + assert len(result.index.mesh_index) == 455 assert np.allclose( - result.max(axis="node_ids").array, [-0.77876072, 7.08211902, 0.05292333] + result.max(axis="node_ids").array, [0.05594125, 0.23687614, 0.21415196] ) def test_stress_skin(self, frame_modal_simulation: post.ModalMechanicalSimulation): @@ -2015,32 +2039,32 @@ def test_stress_skin(self, frame_modal_simulation: post.ModalMechanicalSimulatio ) assert len(result.columns.set_ids) == 1 if SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_7_1: - assert len(result.index.mesh_index) == 36 + assert len(result.index.mesh_index) == 72 assert np.allclose( result.max(axis="element_ids").array, [ [ - 36.52192259, - 58.73246002, - 371.72294617, - 12.80614456, - 134.60557556, - 38.0447108, + 88.09000492, + 426.21118164, + 747.8219401, + 30.50066868, + 412.80891927, + 109.25983429, ] ], ) else: - assert len(result.index.mesh_index) == 110 + assert len(result.index.mesh_index) == 497 assert np.allclose( result.max(axis="element_ids").array, [ [ - 36.52192259, - 58.73246002, - 371.72294617, - 25.97949378, - 139.83338165, - 69.25232569, + 145.15428162, + 426.21118164, + 840.23429362, + 34.79916509, + 415.22954305, + 109.25983429, ] ], ) @@ -2090,9 +2114,9 @@ def test_strain_skin(self, frame_modal_simulation: post.ModalMechanicalSimulatio set_ids=[1], skin=list(range(1, 100)) ) if SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_7_1: - assert len(result.index.mesh_index) == 36 + assert len(result.index.mesh_index) == 72 else: - assert len(result.index.mesh_index) == 110 + assert len(result.index.mesh_index) == 497 assert len(result.columns.set_ids) == 1 def test_strain_skin2(self, frame_modal_simulation: post.ModalMechanicalSimulation): @@ -2751,7 +2775,10 @@ def test_disp_skin(self, harmonic_simulation: post.HarmonicMechanicalSimulation) [2.76941713e-09, 2.76940199e-09, 4.10914311e-10], ) result = harmonic_simulation.displacement(set_ids=[1], skin=[1, 2, 3]) - assert len(result.index.mesh_index) == 44 + if SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_7_1: + assert len(result.index.mesh_index) == 40 + else: + assert len(result.index.mesh_index) == 44 def test_stress_skin(self, harmonic_simulation: post.HarmonicMechanicalSimulation): if harmonic_simulation._model._server.meet_version("6.2"): @@ -2761,21 +2788,28 @@ def test_stress_skin(self, harmonic_simulation: post.HarmonicMechanicalSimulatio else: assert len(result.index.mesh_index) == 3942 assert len(result.columns.set_ids) == 1 + outer_nodes = harmonic_simulation.mesh.named_selections[ + "OUTER_FACE" + ]._scoping + outer_elements = dpf.operators.scoping.transpose( + mesh_scoping=outer_nodes, + meshed_region=harmonic_simulation.mesh._meshed_region, + ).eval() result = harmonic_simulation.stress_elemental( - set_ids=[1], skin=list(range(1, 100)) + set_ids=[1], skin=outer_elements.ids ) if SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_7_1: - assert len(result.index.mesh_index) == 122 + assert len(result.index.mesh_index) == 240 else: - assert len(result.index.mesh_index) == 192 + assert len(result.index.mesh_index) == 560 assert len(result.columns.set_ids) == 1 result = harmonic_simulation.stress_eqv_von_mises_nodal( - set_ids=[1], skin=list(range(1, 100)) + set_ids=[1], skin=outer_elements.ids ) if SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_7_1: - assert len(result.index.mesh_index) == 520 + assert len(result.index.mesh_index) == 880 else: - assert len(result.index.mesh_index) == 530 + assert len(result.index.mesh_index) == 960 assert len(result.columns.set_ids) == 1 result = harmonic_simulation.stress_eqv_von_mises_nodal( set_ids=[1], skin=True @@ -2796,24 +2830,31 @@ def test_strain_skin(self, harmonic_simulation: post.HarmonicMechanicalSimulatio else: assert len(result.index.mesh_index) == 3942 assert len(result.columns.set_ids) == 1 + outer_nodes = harmonic_simulation.mesh.named_selections[ + "OUTER_FACE" + ]._scoping + outer_elements = dpf.operators.scoping.transpose( + mesh_scoping=outer_nodes, + meshed_region=harmonic_simulation.mesh._meshed_region, + ).eval() result = harmonic_simulation.stress_principal_elemental( - set_ids=[1], skin=list(range(1, 100)) + set_ids=[1], skin=outer_elements.ids ) if SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_7_1: - assert len(result.index.mesh_index) == 122 + assert len(result.index.mesh_index) == 240 else: - assert len(result.index.mesh_index) == 192 + assert len(result.index.mesh_index) == 560 assert len(result.columns.set_ids) == 1 result = harmonic_simulation.elastic_strain_eqv_von_mises_nodal( - set_ids=[1], skin=list(range(1, 100)) + set_ids=[1], skin=outer_elements.ids ) if SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_7_1: - assert len(result.index.mesh_index) == 520 + assert len(result.index.mesh_index) == 880 else: - assert len(result.index.mesh_index) == 530 + assert len(result.index.mesh_index) == 960 assert len(result.columns.set_ids) == 1 assert np.allclose( - result.select(complex=0).max(axis="node_ids").array, [1.34699501e-06] + result.select(complex=0).max(axis="node_ids").array, [1.22784309e-06] ) result = harmonic_simulation.elastic_strain_eqv_von_mises_nodal( set_ids=[1], skin=True @@ -2824,12 +2865,12 @@ def test_strain_skin(self, harmonic_simulation: post.HarmonicMechanicalSimulatio assert len(result.index.mesh_index) == 4802 assert len(result.columns.set_ids) == 1 result = harmonic_simulation.elastic_strain_principal_nodal( - set_ids=[1], skin=list(range(1, 100)) + set_ids=[1], skin=outer_elements.ids ) if SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_7_1: - assert len(result.index.mesh_index) == 520 + assert len(result.index.mesh_index) == 880 else: - assert len(result.index.mesh_index) == 530 + assert len(result.index.mesh_index) == 960 assert len(result.columns.set_ids) == 1 result = harmonic_simulation.elastic_strain_eqv_von_mises_elemental( set_ids=[1], skin=True