Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixing plot indexing #2476

Merged
merged 10 commits into from
Nov 6, 2023
58 changes: 47 additions & 11 deletions src/ansys/mapdl/core/post.py
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ def element_values(self, item, comp="", option="AVG") -> np.ndarray:
Returns
-------
numpy.ndarray
Numpy array containing the requested element values for ta
Numpy array containing the requested element values for a
given item and component.

Notes
Expand Down Expand Up @@ -632,27 +632,63 @@ def _plot_cell_scalars(self, scalars, show_elem_numbering=False, **kwargs):

surf = self._mapdl.mesh._surf

# as ``disp`` returns the result for all nodes, we need all node numbers
# as ``disp`` returns the result for all nodes/elems, we need all node/elem numbers
# and to index to the output node numbers
if hasattr(self._mapdl.mesh, "enum_all"):
enum = self._mapdl.mesh.enum
enum = self._mapdl.mesh.enum_all
else:
enum = self._all_enum

# it's possible that there are duplicated element numbers,
# therefore we need to get the unique values and a reverse index
#######################################################################
# Bool operations
# ===============
# I'm going to explain this clearly because it can be confusing for the
# future developers (me).
# This explanation is based in scalars (`element_values`) NOT having the
# full elements (selected and not selected) size.
#
# First, it's possible that there are duplicated element numbers,
# in the surf object returned by Pyvista.
# Therefore we need to get the unique values and a reverse index, to
# later convert the MAPDL values to Pyvista values.
uni, ridx = np.unique(surf["ansys_elem_num"], return_inverse=True)
mask = np.isin(enum, uni, assume_unique=True)

if scalars.size != mask.size:
scalars = scalars[self.selected_elements]
scalars = scalars[mask][ridx]
# which means that, uni is the id of mapdl elements in the polydata
# object. These elements does not need to be in order, and there can be
# duplicated!
# Hence:
# uni[ridx] = surf["ansys_elem_num"]
#
# Let's notice that:
# * enum[self.selected_elements] is mapdl selected elements ids in MAPDL notation.
#
# Theoretical approach
# --------------------
# The theoretical approach will be using an intermediate array of the
# size of the MAPDL total number of elements (we do not care about selected).
#
values = np.zeros(enum.shape)
#
# Then assign the MAPDL values for the selected element (scalars)
#
values[self.selected_elements] = scalars
#
# Because values are in order, but with python notation, then we can do:
#
surf_values = values[
uni - 1
] # -1 to set MAPDL element indexing to python indexing
#
# Then to account for the original Pyvista object:
#
surf_values = surf_values[ridx]
#
#######################################################################

meshes = [
{
"mesh": surf.copy(deep=False), # deep=False for ipyvtk-simple
"scalar_bar_args": {"title": kwargs.pop("stitle", "")},
"scalars": scalars,
"scalars": surf_values,
}
]

Expand Down
35 changes: 33 additions & 2 deletions tests/test_post.py
Original file line number Diff line number Diff line change
Expand Up @@ -765,13 +765,44 @@ def test_plot_incomplete_element_selection(mapdl, contact_solve):
mapdl.esel("S", "ELEM", "", 1, mapdl.mesh.n_elem // 2)
assert mapdl.post_processing.plot_element_displacement() is None

mapdl.nsel("S", "NODE", "", 1, mapdl.mesh.n_elem // 2, 2)
assert mapdl.post_processing.plot_element_displacement() is None

mapdl.nsel("S", "NODE", "", 5, mapdl.mesh.n_elem // 2, 2)
assert mapdl.post_processing.plot_element_displacement() is None

mapdl.vsel("s", "", "", 1)
mapdl.eslv("s")
assert mapdl.post_processing.plot_element_displacement() is None

mapdl.vsel("s", "", "", 2)
mapdl.eslv("s")
assert mapdl.post_processing.plot_element_displacement() is None


@requires("pyvista")
@pytest.mark.xfail(strict=False, reason="The image regression is failing. See #2435")
def test_plot_incomplete_nodal_selection(mapdl, contact_solve):
def test_plot_incomplete_nodal_selection(mapdl, contact_solve, verify_image_cache):
verify_image_cache.skip = True

mapdl.nsel("S", "NODE", "", 1, mapdl.mesh.n_node // 2)
assert mapdl.post_processing.plot_nodal_displacement() is None

mapdl.nsel("S", "NODE", "", 1, mapdl.mesh.n_node // 2, 2)
assert mapdl.post_processing.plot_nodal_displacement() is None

mapdl.nsel("S", "NODE", "", 5, mapdl.mesh.n_node // 2, 2)
assert mapdl.post_processing.plot_nodal_displacement() is None

mapdl.vsel("s", "", "", 1)
mapdl.eslv("S")
mapdl.nsle("S")
assert mapdl.post_processing.plot_nodal_displacement() is None

mapdl.vsel("s", "", "", 2)
mapdl.eslv("S")
mapdl.nsle("S")
assert mapdl.post_processing.plot_nodal_displacement() is None


@requires("pyvista")
def test_general_plotter_returns(mapdl, static_solve, verify_image_cache):
Expand Down
Loading