Skip to content

Commit

Permalink
Implementing save_selection and small change in Components API (#2454)
Browse files Browse the repository at this point in the history
* Implementing `save_selection`
Fixing selection bug.
Adding `components.select`.
Making some methods, properties.

* Adding image cache for new test

* fixing name
  • Loading branch information
germa89 authored Oct 27, 2023
1 parent 6f42c68 commit 387e428
Show file tree
Hide file tree
Showing 9 changed files with 357 additions and 209 deletions.
2 changes: 1 addition & 1 deletion doc/source/api/unit_testing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ Here are some examples of how you use ``pytest``:
def test_dunder_methods_keys(mapdl, basic_components):
assert ["MYCOMP1", "MYCOMP2"] == list(mapdl.components.list())
assert ["MYCOMP1", "MYCOMP2"] == list(mapdl.components.names())
def test_dunder_methods_types(mapdl, basic_components):
Expand Down
25 changes: 24 additions & 1 deletion src/ansys/mapdl/core/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,8 @@ def __iter__(self):
"""
yield from self._comp.keys()

def list(self):
@property
def names(self):
"""
Return a tuple that contains the components.
Expand All @@ -453,6 +454,7 @@ def list(self):
"""
return tuple(self._comp.keys())

@property
def types(self):
"""
Return the types of the components.
Expand All @@ -476,3 +478,24 @@ def items(self):
"""
return self._comp.items()

def select(self, names: Union[str, list[str], tuple[str]], mute=False) -> None:
"""Select Select components given their names
Select components given their names.
Parameters
----------
names : Union[str, list[str], tuple[str]]
Name(s) of the components
mute : bool, optional
Whether to mute the `/CMSEL` command output or not, by default False.
"""
if isinstance(names, str):
names = [names]

for i, each_name in enumerate(names):
if i == 0:
self._mapdl.cmsel("S", each_name, mute=mute)
else:
self._mapdl.cmsel("A", each_name, mute=mute)
128 changes: 89 additions & 39 deletions src/ansys/mapdl/core/mapdl.py
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,17 @@ def force_output(self):
"""
return self._force_output(self)

@property
def save_selection(self):
"""Save selection
Save the current selection (nodes, elements, keypoints, lines, areas,
volumes and components) before entering in the context manager, and
when exit returns to that selection.
"""
return self._save_selection(self)

@property
def solution(self) -> "Solution":
"""Solution parameters of MAPDL.
Expand Down Expand Up @@ -816,6 +827,50 @@ def __exit__(self, *args):
self._parent()._flush_stored()
self._parent()._store_commands = False

class _save_selection:
"""Save the selection and returns to it when exiting"""

def __init__(self, parent):
self._parent = weakref.ref(parent)
self.selection_sets = []
self.selection_sets_comps = []

def __enter__(self):
self._parent()._log.debug("Entering saving selection context")

selection_set_name = random_string(10)
self.selection_sets.append(selection_set_name)
self.selection_sets_comps.append(self._parent().components.names)

mapdl = self._parent()

prev_ier = mapdl.ignore_errors
mapdl.ignore_errors = True
for entity in ["kp", "lines", "area", "volu", "node", "elem"]:
mapdl.cm(f"_{selection_set_name}_{entity}_", f"{entity}", mute=True)
mapdl.ignore_errors = prev_ier

def __exit__(self, *args):
self._parent()._log.debug("Exiting saving selection context")
last_selection_name = self.selection_sets.pop()
last_selection_cmps = self.selection_sets_comps.pop()

mapdl = self._parent()

# probably this is redundant
prev_ier = mapdl.ignore_errors
mapdl.ignore_errors = True
for entity in ["kp", "lines", "area", "volu", "node", "elem"]:
cmp_name = f"_{last_selection_name}_{entity}_"
mapdl.cmsel("s", cmp_name, f"{entity}", mute=True)
mapdl.cmdele(cmp_name)

mapdl.ignore_errors = prev_ier

# mute to avoid getting issues when the component wasn't created in
# first place because there was no entities.
self._parent().components.select(last_selection_cmps, mute=True)

class _chain_commands:
"""Store MAPDL commands and send one chained command."""

Expand Down Expand Up @@ -1718,45 +1773,39 @@ def vplot(
)
return general_plotter([], [], [], **kwargs)

cm_name_area = "__tmp_area2__"
cm_name_volu = "__tmp_volu2__"
self.cm(cm_name_area, "AREA", mute=True)
self.cm(cm_name_volu, "VOLU", mute=True)

volumes = self.geometry.vnum
meshes = []
points = []
labels = []

return_plotter = kwargs.pop("return_plotter", False)
color_areas = True

for each_volu in volumes:
self.vsel("S", vmin=each_volu)
self.aslv("S", mute=True) # select areas attached to active volumes

pl = self.aplot(
vtk=True,
color_areas=color_areas,
quality=quality,
show_area_numbering=show_area_numbering,
show_line_numbering=show_line_numbering,
show_lines=show_lines,
return_plotter=True,
**kwargs,
)

meshes_ = get_meshes_from_plotter(pl)
# Storing entities selection
with self.save_selection:
volumes = self.geometry.vnum
meshes = []
points = []
labels = []

return_plotter = kwargs.pop("return_plotter", False)
color_areas = True

for each_volu in volumes:
self.vsel("S", vmin=each_volu)
self.aslv("S", mute=True) # select areas attached to active volumes

pl = self.aplot(
vtk=True,
color_areas=color_areas,
quality=quality,
show_area_numbering=show_area_numbering,
show_line_numbering=show_line_numbering,
show_lines=show_lines,
return_plotter=True,
**kwargs,
)

for each_mesh in meshes_:
each_mesh.cell_data["entity_num"] = int(each_volu)
meshes_ = get_meshes_from_plotter(pl)

meshes.extend(meshes_)
for each_mesh in meshes_:
each_mesh.cell_data["entity_num"] = int(each_volu)

meshes = [{"mesh": meshes}]
meshes.extend(meshes_)

self.cmsel("S", cm_name_area, "AREA", mute=True)
self.cmsel("S", cm_name_volu, "VOLU", mute=True)
meshes = [{"mesh": meshes}]

return general_plotter(
meshes, points, labels, return_plotter=return_plotter, **kwargs
Expand Down Expand Up @@ -1973,11 +2022,10 @@ def aplot(
if show_lines or show_line_numbering:
kwargs.setdefault("line_width", 2)
# subselect lines belonging to the current areas
self.cm("__area__", "AREA", mute=True)
self.lsla("S", mute=True)

lines = self.geometry.get_lines()
self.cmsel("S", "__area__", "AREA", mute=True)
with self.save_selection:
self.lsla("S", mute=True)
lines = self.geometry.get_lines()

if show_lines:
meshes.append(
Expand Down Expand Up @@ -4933,6 +4981,7 @@ def cmplot(self, label: str = "", entity: str = "", keyword: str = "", **kwargs)
if entity[:4] not in ["NODE", "ELEM", "KP", "LINE", "AREA", "VOLU"]:
raise ValueError(f"The entity '{entity}' is not allowed.")

cmps_names = self.components.names
self.cm("__tmp_cm__", entity=entity)
if label == "ALL":
self.cmsel("ALL", entity=entity)
Expand All @@ -4954,4 +5003,5 @@ def cmplot(self, label: str = "", entity: str = "", keyword: str = "", **kwargs)

# returning to previous selection
self.cmsel("s", "__tmp_cm__", entity=entity)
self.components.select(cmps_names)
return output
Loading

0 comments on commit 387e428

Please sign in to comment.