Skip to content

Commit

Permalink
fix: avoid changing entities ids after plotting (#3421)
Browse files Browse the repository at this point in the history
* feat: using only one instance of `save_selection`.

* Revert "feat: using only one instance of `save_selection`."

This reverts commit 51e514f.

* fix: changing the ids, but not restoring correctly the components

* refactor: small cosmetic changes

* tests: adding tests

* revert: avoiding mute amesh.

* feat: using only one instance of `save_selection`.

* Revert "feat: using only one instance of `save_selection`."

This reverts commit 51e514f.

* fix: changing the ids, but not restoring correctly the components

* refactor: small cosmetic changes

* tests: adding tests

* revert: avoiding mute amesh.

* chore: adding changelog file 3421.fixed.md

* chore: adding changelog file 3421.fixed.md

* doc: typos

* refactor: Avoiding components for saving selections or for performing multiple selections.

* fix: test and adding test for quality

* fix: quality value in test_aplot

* fix: wrong fixture name

* fix: rerun function if fail because of midside nodes

* feat: using 'has_dependency' to avoid another 'try'

* fix: test being skipped because wrong library name

* refactor: test match and removing duplicity

* fix: find_version test

* fix: example calling get_areas with "r"

* test: reducing the tests to only one

* fix: ci logging mapdl names

* fix: test

* fix: example

* ci: fixing artifact upload path

* fix: commit message

* chore: removing f-string format

* fix: test

* test: cherry picking only main changes

* feat: adding a retry method for checking the channel is alive on parsing chunks

* feat: removing warning

* test: disabling some tests

* feat: returning empty grid when mesh has no nodes or elements

* test: skipping tet

* fix: commit message on PR image cache submitter

* chore: update the image cache

* chore: empty commit to trigger CICD

---------

Co-authored-by: pyansys-ci-bot <[email protected]>
Co-authored-by: germa89 <[email protected]>
  • Loading branch information
3 people authored Sep 27, 2024
1 parent 1a1cfd4 commit 2354e68
Show file tree
Hide file tree
Showing 16 changed files with 279 additions and 147 deletions.
18 changes: 9 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ jobs:
- name: "Display files structure"
if: always()
env:
MAPDL_INSTANCE: mapdl
MAPDL_INSTANCE: MAPDL_0
LOG_NAMES: logs-build-docs
run: |
.ci/display_logs.sh
Expand Down Expand Up @@ -548,23 +548,23 @@ jobs:
if: always()
env:
MAPDL_VERSION: ${{ matrix.mapdl-version }}
MAPDL_INSTANCE: mapdl
LOG_NAMES: logs-${{ matrix.mapdl-version }}
MAPDL_INSTANCE: MAPDL_0
LOG_NAMES: logs-remote-${{ matrix.mapdl-version }}
run: |
.ci/collect_mapdl_logs.sh
- name: "Upload logs to GitHub"
if: always()
uses: actions/upload-artifact@v4
with:
name: logs-${{ matrix.mapdl-version }}.tgz
path: ./logs-${{ matrix.mapdl-version }}.tgz
name: logs-remote-${{ matrix.mapdl-version }}.tgz
path: ./logs-remote-${{ matrix.mapdl-version }}.tgz

- name: "Display files structure"
if: always()
env:
MAPDL_INSTANCE: mapdl
LOG_NAMES: logs-${{ matrix.mapdl-version }}
MAPDL_INSTANCE: MAPDL_0
LOG_NAMES: logs-remote-${{ matrix.mapdl-version }}
run: |
.ci/display_logs.sh
Expand Down Expand Up @@ -695,7 +695,7 @@ jobs:
id: attatch-to-pr
uses: EndBug/add-and-commit@v9
with:
message: Update the image cache
message: "chore: update the image cache"
committer_name: GitHub Actions
committer_email: [email protected]
add: './tests/.image_cache/*.png'
Expand All @@ -711,7 +711,7 @@ jobs:
This commit does not re-run the CICD workflows (since no changes are made in the codebase) therefore you will see the actions showing in their status `Expected — Waiting for status to be reported`. Do not worry. You commit workflow is still running [here](https://github.com/ansys/pymapdl/pull/${{ github.event.pull_request.number }}/checks?sha=${{ github.event.pull_request.head.sha }}) :smile:
You might want to rerun the test to make sure that everything is passing. You can retrigger the CICD sending an empty commit `git commit -m "Empty comment to trigger CICD" --allow-empty`.
You might want to rerun the test to make sure that everything is passing. You can retrigger the CICD sending an empty commit `git commit -m "chore: empty comment to trigger CICD" --allow-empty`.
You will see this message everytime your commit changes the image cache but you are not attaching the updated cache. :nerd_face:
Expand Down
1 change: 1 addition & 0 deletions doc/changelog.d/3421.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fix: avoid changing entities ids after plotting
10 changes: 5 additions & 5 deletions doc/source/user_guide/components.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Managing components
*******************

MAPDL components can be retrieved and set using
:attr:`Mapdl.components <ansys.mapdl.core.Mapdl.components>`.
:attr:`Mapdl.components <ansys.mapdl.core.component.ComponentManager>`.


There are several ways to create a component in MAPDL.
Expand Down Expand Up @@ -42,7 +42,7 @@ Set a component without specifying the type, by default it is ``NODE``:
warnings.warn(
You can change the default type by changing
:attr:`Mapdl.components.default_entity <ansys.mapdl.core.Mapdl.components.default_entity>`
:attr:`Mapdl.components.default_entity <ansys.mapdl.core.component.ComponentManager.default_entity>`

.. code:: pycon
Expand Down Expand Up @@ -78,10 +78,10 @@ Selecting a component and retrieving it:
Component object
================

The `Component object <ansys.mapdl.core.component.Component>` is the object returned by
The :class:`Component object <ansys.mapdl.core.component.Component>` is the object returned by
:attr:`Mapdl.components <ansys.mapdl.core.Mapdl.components>` when you query it with a component name.
This object has two main attributes: `type <Component.type>` and `items <Component.items>`.
The former returns the component type (`"ELEM"`, `"NODE"`, `"KP"`, etc) and the later returns
This object has two main attributes: :attr:`type <Component.type>` and :attr:`items <Component.items>`.
The former returns the component type (``"ELEM"``, ``"NODE"``, ``"KP"``, etc) and the later returns
a tuple with the index of the entities which belong to that component.

.. code:: pycon
Expand Down
4 changes: 2 additions & 2 deletions examples/00-mapdl-examples/composite_dcb.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,15 +174,15 @@
mapdl.allsel()
mapdl.asel("s", "loc", "z", 1.7)
areas = mapdl.geometry.anum
mapdl.geometry.area_select(areas[0], "r")
mapdl.asel("r", vmin=areas[0])
mapdl.nsla("r", 1)
mapdl.nsel("r", "loc", "x", pre_crack, length + pre_crack + eps)
mapdl.components["cm_1"] = "node"

mapdl.allsel()
mapdl.asel("s", "loc", "z", 1.7)
areas = mapdl.geometry.anum
mapdl.geometry.area_select(areas[1], "r")
mapdl.asel("r", vmin=areas[1])
mapdl.nsla("r", 1)
mapdl.nsel("r", "loc", "x", pre_crack, length + pre_crack + eps)
mapdl.components["cm_2"] = "node"
Expand Down
11 changes: 9 additions & 2 deletions src/ansys/mapdl/core/common_grpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
# SOFTWARE.

"""Common gRPC functions"""
from time import sleep
from typing import List, Literal, get_args

import numpy as np
Expand Down Expand Up @@ -184,8 +185,14 @@ def parse_chunks(chunks, dtype=None):
Deserialized numpy array.
"""
if not chunks.is_active():
raise MapdlConnectionError("The channel is not alive.")
time_int = 0
time_step = 0.01
time_max = 3 # seconds
while not chunks.is_active():
time_int += 1
sleep(time_step)
if time_int > time_max / time_step:
raise MapdlConnectionError("The channel is not alive.")

try:
chunk = chunks.next()
Expand Down
8 changes: 5 additions & 3 deletions src/ansys/mapdl/core/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,8 @@ class ComponentManager:
-----
**Components need to be selected** using
:attr:`Mapdl.cmsel() <ansys.mapdl.core.Mapdl.cmsel>` before
being listed in :attr:`Mapdl.components <ansys.mapdl.core.Mapdl.components>`
:attr:`Mapdl.cmsel() <ansys.mapdl.core.Mapdl.cmsel>` before being listed in
:class:`Mapdl.components <ansys.mapdl.core.component.ComponentManager>`
Examples
--------
Expand Down Expand Up @@ -507,7 +507,9 @@ def items(self):
"""
return self._comp.items()

def select(self, names: Union[str, list[str], tuple[str]], mute=False) -> None:
def select(
self, names: Union[str, list[str], tuple[str]], mute: bool = False
) -> None:
"""Select Select components given their names
Select components given their names.
Expand Down
76 changes: 35 additions & 41 deletions src/ansys/mapdl/core/mapdl_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ def __init__(
self._default_file_type_for_plots = file_type_for_plots
self._version = None # cached version
self._mute = False
self._save_selection_obj = None

if _HAS_PYVISTA:
if use_vtk is not None: # pragma: no cover
Expand Down Expand Up @@ -959,7 +960,9 @@ def save_selection(self):
when exit returns to that selection.
"""
return self._save_selection(self)
if self._save_selection_obj is None:
self._save_selection_obj = self._save_selection(self)
return self._save_selection_obj

@property
def solution(self) -> "Solution":
Expand Down Expand Up @@ -1395,44 +1398,40 @@ class _save_selection:

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

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
# Storing components
selection = {
"cmsel": mapdl.components.names,
# "components_type": mapdl.components.types,
"nsel": mapdl.mesh.nnum,
"esel": mapdl.mesh.enum,
"ksel": mapdl.geometry.knum,
"lsel": mapdl.geometry.lnum,
"asel": mapdl.geometry.anum,
"vsel": mapdl.geometry.vnum,
}

self.selection.append(selection)

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()

selection = self.selection.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)
cmps = selection.pop("cmsel")

mapdl.ignore_errors = prev_ier
if cmps:
mapdl.components.select(cmps)

# 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)
for select_cmd, ids in selection.items():
if ids.size > 0:
func = getattr(mapdl, select_cmd)
func(vmin=ids)

class _chain_commands:
"""Store MAPDL commands and send one chained command."""
Expand All @@ -1445,7 +1444,7 @@ def __enter__(self):
self._parent()._store_commands = True

def __exit__(self, *args):
self._parent()._log.debug("Entering chained command mode")
self._parent()._log.debug("Exiting chained command mode")
self._parent()._chain_stored()
self._parent()._store_commands = False

Expand Down Expand Up @@ -2713,22 +2712,17 @@ def _perform_entity_list_selection(
self, entity, selection_function, type_, item, comp, vmin, kabs
):
"""Select entities using CM, and the supplied selection function."""
self.cm(f"__temp_{entity}s__", f"{entity}") # Saving previous selection

# Getting new selection
for id_, each_ in enumerate(vmin):
selection_function(
self, "S" if id_ == 0 else "A", item, comp, each_, "", "", kabs
)

self.cm(f"__temp_{entity}s_1__", f"{entity}")

self.cmsel("S", f"__temp_{entity}s__")
self.cmsel(type_, f"__temp_{entity}s_1__")
if type_ == "S" or not type_:
type__ = "S" if id_ == 0 else "A"
# R is an issue, because first iteration will clean up the rest.
elif type_ == "R":
raise NotImplementedError("Mode R is not supported.")
else:
type__ = type_

# Cleaning
self.cmdele(f"__temp_{entity}s__")
self.cmdele(f"__temp_{entity}s_1__")
selection_function(self, type__, item, comp, each_, "", "", kabs)

def _raise_errors(self, text):
# to make sure the following error messages are caught even if a breakline is in between.
Expand Down
4 changes: 0 additions & 4 deletions src/ansys/mapdl/core/mapdl_extended.py
Original file line number Diff line number Diff line change
Expand Up @@ -733,10 +733,6 @@ def aplot(
pl.plot([], [], [], **kwargs)
return pl.show(**kwargs)

if quality > 10:
quality = 10
if quality < 1:
quality = 1
surfs = self.geometry.get_areas(return_as_list=True, quality=quality)
meshes = []
labels = []
Expand Down
26 changes: 13 additions & 13 deletions src/ansys/mapdl/core/mapdl_geometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -594,10 +594,9 @@ def get_areas(
...
"""
quality = int(quality)
if quality > 10:
if not isinstance(quality, int) or (quality > 10 or quality < 1):
raise ValueError(
"The ``quality`` parameter must be a value between 0 and 10."
"The argument 'quality' can only be an integer between 1 and 10 (both included)."
)

surf = self.generate_surface(11 - quality)
Expand Down Expand Up @@ -650,24 +649,25 @@ def generate_surface(

# reselect from existing selection to mimic APDL behavior
if amin or amax:
if amax is None:
amax = amin

if amin is None: # amax is non-zero
amin = 1

if ninc is None:
ninc = ""
amax = amax or amin
amin = amin or 1
ninc = ninc or ""

self._mapdl.asel("R", "AREA", vmin=amin, vmax=amax, vinc=ninc)

## Duplication
# duplicate areas to avoid affecting existing areas
# Getting the maximum area ID
a_num = int(self._mapdl.get(entity="AREA", item1="NUM", it1num="MAXD"))
# Setting the new areas ID starting number
self._mapdl.numstr("AREA", a_num, mute=True)
# Generating new areas
self._mapdl.agen(2, "ALL", noelem=1, mute=True)
a_max = int(self._mapdl.get(entity="AREA", item1="NUM", it1num="MAXD"))

# Getting the new maximum area ID
a_max = int(self._mapdl.get(entity="AREA", item1="NUM", it1num="MAXD"))
self._mapdl.asel("S", "AREA", vmin=a_num + 1, vmax=a_max, mute=True)

# necessary to reset element/area meshing association
self._mapdl.aatt(mute=True)

Expand All @@ -692,7 +692,7 @@ def generate_surface(

self._mapdl.esla("S")
grid = self._mapdl.mesh._grid.linear_copy()
pd = pv.PolyData(grid.points, grid.cells, n_faces=grid.n_cells)
pd = pv.PolyData(grid.points, grid.cells)

# pd['ansys_node_num'] = grid['ansys_node_num']
# pd['vtkOriginalPointIds'] = grid['vtkOriginalPointIds']
Expand Down
2 changes: 1 addition & 1 deletion src/ansys/mapdl/core/mesh/mesh.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ def _parse_vtk(
"""
if not mesh._has_nodes or not mesh._has_elements:
# warnings.warn('Missing nodes or elements. Unable to parse to vtk')
return
return pv.UnstructuredGrid()

etype_map = ETYPE_MAP
if allowable_types is not None:
Expand Down
28 changes: 20 additions & 8 deletions src/ansys/mapdl/core/mesh_grpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -804,14 +804,26 @@ def _parse_vtk(
):
from ansys.mapdl.core.mesh.mesh import _parse_vtk

return _parse_vtk(
self,
allowable_types,
force_linear,
null_unallowed,
fix_midside,
additional_checking,
)
try:
return _parse_vtk(
self,
allowable_types,
force_linear,
null_unallowed,
fix_midside,
additional_checking,
)
except ValueError:
# In case we fail to detect/apply midside nodes in cuadratic
# elements
return _parse_vtk(
self,
allowable_types,
force_linear,
null_unallowed,
not fix_midside,
additional_checking,
)

def _parse_rlist(self) -> Dict[int, float]:
# mapdl.rmore(*list)
Expand Down
Binary file modified tests/.image_cache/plot_element_values.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 2354e68

Please sign in to comment.