"""Vocabulary-only ``HexMesh`` operations: rename the tags, touch nothing else.
Separate from :mod:`morph <nekmeshpy.hexmesh.morph>`, which is the delta-0 rung for
operations on the *geometry*. These change neither coordinates nor connectivity nor
numbering -- only what the two tag tables call things -- so a caller reading the
sibling list can tell at a glance that a retag cannot have moved a node.
"""
from __future__ import annotations
from collections.abc import Mapping, Sequence
from .._typing import IntArray, StrArray
from ..quadmesh import QuadMesh
from ..quadmesh import tag as quadmesh
from ..tags.tags import ElementTagSpec
from .hexmesh import HexMesh
[docs]
def retag_element(mesh: HexMesh, tags: ElementTagSpec) -> HexMesh:
"""The same mesh with its ``element_tags`` changed, by what ``tags`` is: a mapping
renames the existing names (a tag the map does not name is left alone, the map
applies simultaneously, a key naming nothing raises, a rename to ``NO_TAG`` untags);
a string names every element; a ``Tags`` or per-element sequence replaces the table.
Geometry and the side tags are untouched."""
return HexMesh(mesh.quad_mesh, mesh.hexes, mesh.orient, mesh.interior,
mesh.element_tags.retag(tags))
[docs]
def retag_face(mesh: HexMesh, mapping: Mapping[str, str]) -> HexMesh:
"""The same mesh with its ``face_tags`` renamed through ``mapping``, rows kept in
stored order (see :func:`retag_element` for the map's own rules).
Order matters here beyond tidiness: ``.re2`` writes boundary rows in it, and
``.vtu`` gives a node touched by several rows the last one's tag.
Renaming a tag to ``NO_TAG`` **drops** its rows rather than storing an empty name:
a side-tag table is a named subset of the boundary, so leaving it is leaving the
table. That is the way to retire a name that has stopped meaning anything --
an ``"inlet"`` welded shut into an interior plane, which would otherwise export
as a boundary condition on a face that is no longer on the boundary::
mesh = hexmesh.retag_face(mesh, {"inlet": "", "outlet": ""})
:func:`tag_report <nekmeshpy.hexmesh.query.tag_report>` is what finds those."""
return HexMesh(quadmesh.retag_element(mesh.quad_mesh, mapping),
mesh.hexes, mesh.orient, mesh.interior, mesh.element_tags)
[docs]
def tag_faces(mesh: HexMesh, faces: IntArray,
tags: str | Sequence[str] | StrArray) -> HexMesh:
"""The same mesh with the given shared **faces** named, by face id.
The entity-side authoring form, and the natural handle at this rung: after a
``merge`` or a weld the thing you have is a set of faces, not a set of
``(hex, side)`` pairs -- see :func:`boundary_face_ids
<nekmeshpy.hexmesh.query.boundary_face_ids>` and :func:`face_tag_rows
<nekmeshpy.hexmesh.query.face_tag_rows>` for the two ways to get them. (Its quad
counterpart :func:`tag_edges <nekmeshpy.quadmesh.tag.tag_edges>` takes
``(quad, side)`` rows instead, because the factories that use it genuinely think
element-locally.)
``tags`` is one name for all of them or one per face; ``NO_TAG`` names nothing, and
a face already named is overwritten."""
q = mesh.quad_mesh
return HexMesh(QuadMesh(q.line_mesh, q.quads, q.orient, q.interior,
mesh.face_tags.put(faces, tags)),
mesh.hexes, mesh.orient, mesh.interior, mesh.element_tags)
__all__ = [
"retag_element",
"retag_face",
"tag_faces",
]