Source code for nekmeshpy.core.selection

"""Resolving a ``select`` / ``remove`` argument to a mask over a mesh's elements."""

from __future__ import annotations

from collections.abc import Sequence
from typing import Union

import numpy as np

from .._typing import BoolArray, IntArray, StrArray
from ..tags import Tags

__all__ = ["Selection", "mask_for_selection"]

#: A ``select`` / ``remove`` argument: one tag name, several tag names, a boolean mask
#: over the elements, or element ids.
Selection = Union[str, Sequence[str], StrArray, BoolArray, IntArray,
                 Sequence[int]]


[docs] def mask_for_selection(which: Selection, tags: Tags) -> BoolArray: """The ``(n_elements,)`` boolean mask a ``select`` / ``remove`` argument names. ``which`` is a tag name or a list / array of them (resolved by :meth:`Tags.flatnonzero <nekmeshpy.tags.Tags.flatnonzero>`; a name absent from the mesh's vocabulary is an error, since a silent empty selection is almost always a typo), a ready ``(n_elements,)`` boolean mask, or an array of element ids.""" arr = np.asarray(which) n_elements = tags.size ids: IntArray if arr.dtype.kind == "U": # if str, check tags ids = tags.flatnonzero(arr, strict=True) elif arr.size == 0: ids = np.zeros(0, dtype=np.int64) elif arr.dtype == bool: if arr.ndim != 1 or arr.shape[0] != n_elements: raise ValueError("a boolean mask must cover all %d elements, got shape %s" % (n_elements, arr.shape)) return arr elif np.issubdtype(arr.dtype, np.integer): ids = arr.reshape(-1).astype(np.int64) if int(ids.min()) < 0 or int(ids.max()) >= n_elements: raise ValueError("element ids must lie in [0, %d); got [%d, %d]" % (n_elements, int(ids.min()), int(ids.max()))) else: raise TypeError( "select by tag names, a (%d,) boolean mask, or an array of element " "ids; got a %s array" % (n_elements, arr.dtype)) out: BoolArray = np.zeros(n_elements, dtype=bool) out[ids] = True return out