Skip to content

Commit ae4697e

Browse files
Do not turn element scoping into a nodal one (#898)
1 parent e9eba87 commit ae4697e

File tree

2 files changed

+70
-28
lines changed

2 files changed

+70
-28
lines changed

src/ansys/dpf/post/simulation.py

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434

3535
import ansys.dpf.core as dpf
3636
from ansys.dpf.core import DataSources, Model, TimeFreqSupport, errors
37-
from ansys.dpf.core.available_result import _result_properties
3837
from ansys.dpf.core.common import elemental_properties
3938
from ansys.dpf.core.plotter import DpfPlotter
4039
from ansys.dpf.core.server_types import BaseServer
@@ -600,14 +599,14 @@ def _build_selection(
600599
] = None,
601600
all_sets: bool = False,
602601
named_selections: Union[List[str], str, None] = None,
603-
element_ids: Union[List[int], None] = None,
602+
element_ids: Union[List[int], dpf.Scoping, None] = None,
604603
node_ids: Union[List[int], None] = None,
605604
location: Union[locations, str] = locations.nodal,
606605
external_layer: bool = False,
607606
skin: Union[bool, List[int]] = False,
608607
expand_cyclic: Union[bool, List[Union[int, List[int]]]] = True,
609608
average_per_body: Optional[bool] = False,
610-
) -> (Selection, Optional[_Rescoping]):
609+
) -> Tuple[Selection, Optional[_Rescoping]]:
611610
tot = (
612611
(node_ids is not None)
613612
+ (element_ids is not None)
@@ -659,26 +658,26 @@ def _build_selection(
659658
if requires_manual_averaging and location != locations.elemental_nodal:
660659
location = locations.elemental_nodal
661660

661+
available_results = self._model.metadata.result_info.available_results
662+
result_info = next(
663+
(r for r in available_results if r.operator_name == base_name), None
664+
)
665+
result_native_location = None
666+
if result_info is not None:
667+
result_native_location = result_info.native_location
668+
662669
# Create the SpatialSelection
663670

664671
# First: the skin and the external layer to be able to have both a mesh scoping and
665672
# the skin/external layer
666673
if (skin is not None and skin is not False) or (
667674
external_layer is not None and external_layer is not False
668675
):
669-
res = (
670-
_result_properties[base_name]
671-
if base_name in _result_properties
672-
else None
673-
)
674-
675676
if external_layer not in [None, False]:
676677
selection.select_external_layer(
677678
elements=external_layer if external_layer is not True else None,
678679
location=location,
679-
result_native_location=res["location"]
680-
if res is not None
681-
else location,
680+
result_native_location=result_native_location or location,
682681
is_model_cyclic=self._model.operator("is_cyclic").eval()
683682
if expand_cyclic is not False
684683
else "not_cyclic",
@@ -687,9 +686,7 @@ def _build_selection(
687686
selection.select_skin(
688687
elements=skin if skin is not True else None,
689688
location=location,
690-
result_native_location=res["location"]
691-
if res is not None
692-
else location,
689+
result_native_location=result_native_location or location,
693690
is_model_cyclic=self._model.operator("is_cyclic").eval()
694691
if expand_cyclic is not False
695692
else "not_cyclic",
@@ -701,7 +698,7 @@ def _build_selection(
701698
inclusive=requires_manual_averaging,
702699
)
703700
elif element_ids is not None:
704-
if location == locations.nodal:
701+
if result_native_location == locations.nodal:
705702
selection.select_nodes_of_elements(elements=element_ids, mesh=self.mesh)
706703
else:
707704
selection.select_elements(elements=element_ids)

tests/test_simulation.py

Lines changed: 57 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
from ansys.dpf.post.simulation import MechanicalSimulation, Simulation
5858
from conftest import (
5959
SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_4_0,
60+
SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_5_0,
6061
SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_6_2,
6162
SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_7_1,
6263
SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_8_0,
@@ -4646,24 +4647,15 @@ def test_build_selection(
46464647
set_ids=None,
46474648
times=None,
46484649
all_sets=True,
4649-
element_ids=scoping.ids,
4650+
element_ids=scoping,
46504651
)
46514652
selection_wf = selection.spatial_selection._selection
46524653
if selection.spatial_selection.requires_mesh:
46534654
selection_wf.connect(_WfNames.initial_mesh, simulation.mesh._meshed_region)
46544655
scoping_from_selection = selection_wf.get_output(_WfNames.scoping, Scoping)
46554656

4656-
if is_skin or average_per_body:
4657-
# If request is for skin or average per body, the location should be elemental
4658-
# because force_elemental_nodal is True
4659-
assert scoping_from_selection.location == locations.elemental
4660-
assert set(scoping_from_selection.ids) == set(scoping.ids)
4661-
else:
4662-
assert scoping_from_selection.location == requested_location
4663-
if requested_location == locations.nodal:
4664-
assert len(scoping_from_selection.ids) == 36
4665-
else:
4666-
assert set(scoping_from_selection.ids) == set(scoping.ids)
4657+
assert scoping_from_selection.location == locations.elemental
4658+
assert set(scoping_from_selection.ids) == set(scoping.ids)
46674659

46684660

46694661
def test_beam_results_on_skin(beam_example):
@@ -4694,3 +4686,56 @@ def test_beam_results_on_skin(beam_example):
46944686
assert element_count_dict[element_types.Line2.value] == 40
46954687

46964688
assert converted_field.max().data[0] == pytest.approx(190, 1e-2)
4689+
4690+
4691+
@pytest.mark.skipif(
4692+
not SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_5_0,
4693+
reason="The behavior of some operators was different before DPF 5.0.",
4694+
)
4695+
def test_nodal_averaging_on_elemental_scoping(average_per_body_two_cubes):
4696+
# reference results from Mechanical
4697+
rst_file = pathlib.Path(average_per_body_two_cubes)
4698+
simulation: StaticMechanicalSimulation = post.load_simulation(
4699+
data_sources=rst_file,
4700+
simulation_type=AvailableSimulationTypes.static_mechanical,
4701+
)
4702+
4703+
element_ids = [7]
4704+
4705+
# Test equivalent stress
4706+
result = simulation.stress_eqv_von_mises_nodal(
4707+
set_ids=[1], element_ids=element_ids, skin=False
4708+
)
4709+
assert len(result._fc) == 1
4710+
field = result._fc[0]
4711+
4712+
assert field.location == locations.nodal
4713+
assert field.size == 8
4714+
assert np.allclose(field.min().data[0], 0.7465022)
4715+
assert np.allclose(field.max().data[0], 1.733499)
4716+
4717+
# Test a strain component
4718+
result = simulation.elastic_strain_nodal(
4719+
set_ids=[1], element_ids=element_ids, skin=False, components=["YY"]
4720+
)
4721+
4722+
assert len(result._fc) == 1
4723+
field = result._fc[0]
4724+
4725+
assert field.location == locations.nodal
4726+
assert field.size == 8
4727+
assert np.allclose(field.min().data[0], -3.629157e-6)
4728+
assert np.allclose(field.max().data[0], -1.054446e-6)
4729+
4730+
# Let's also make sure a nodal quantity like displacement is correct
4731+
result = simulation.displacement(
4732+
set_ids=[1], element_ids=element_ids, skin=False, norm=True
4733+
)
4734+
4735+
assert len(result._fc) == 1
4736+
field = result._fc[0]
4737+
4738+
assert field.location == locations.nodal
4739+
assert field.size == 8
4740+
assert np.allclose(field.min().data[0], 1.724714e-5)
4741+
assert np.allclose(field.max().data[0], 6.407787e-5)

0 commit comments

Comments
 (0)