mask_base
mask_base
Post-assembly mesh query types used by femora.core.mask_manager.
Classes
MeshIndex
dataclass
MeshIndex(node_ids: ndarray, node_coords: ndarray, node_ndf: ndarray, node_core_map: List[List[int]], element_ids: ndarray, element_connectivity: List[ndarray], element_centroids: ndarray, element_types: ndarray, material_tags: ndarray, section_tags: ndarray, region_tags: ndarray, core_ids: ndarray, element_id_to_index: Dict[int, int], node_tag_start: int = 1, element_tag_start: int = 1)
Immutable snapshot of assembled mesh data for efficient masking/filtering.
This structure is created after mesh assembly and stores the minimal arrays needed to perform fast vectorized spatial and attribute-based queries.
Attributes:
| Name | Type | Description |
|---|---|---|
node_ids |
ndarray
|
1D array of node IDs, zero-based indices derived from the assembled grid ordering. Shape (N,). |
node_coords |
ndarray
|
Nodal coordinates. Shape (N, 3). |
node_ndf |
ndarray
|
Degrees of freedom per node. Shape (N,). |
node_core_map |
List[List[int]]
|
List where each item is a list of core IDs that the corresponding node belongs to (a node can be part of multiple cores). Shape (N,). |
element_ids |
ndarray
|
1D array of element IDs, which can be cell indices or explicit identifiers. Shape (M,). |
element_connectivity |
List[ndarray]
|
A list where each item is a 1D
array of node indices (referencing |
element_centroids |
ndarray
|
Precomputed centroid coordinates for each element. Shape (M, 3). |
element_types |
ndarray
|
Array of string or object types for each element. Shape (M,). |
material_tags |
ndarray
|
Material tag for each element. Shape (M,). |
section_tags |
ndarray
|
Section tag for each element. Shape (M,). |
region_tags |
ndarray
|
Region tag for each element. Shape (M,). |
core_ids |
ndarray
|
Partition/core ID for each element. Shape (M,). |
element_id_to_index |
Dict[int, int]
|
A mapping from an explicit
element ID to its 0-based row index in the |
Example
import numpy as np
from femora.components.mask.mask_base import MeshIndex
# Assuming a simple mesh has been assembled
mesh_index = MeshIndex(
node_ids=np.array([0, 1, 2]),
node_coords=np.array([[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]),
node_ndf=np.array([3, 3, 3]),
node_core_map=[[0], [0], [0]],
element_ids=np.array([0]),
element_connectivity=[np.array([0, 1, 2])],
element_centroids=np.array([[0.33, 0.33, 0.0]]),
element_types=np.array(["TRIANGLE"]),
material_tags=np.array([1]),
section_tags=np.array([1]),
region_tags=np.array([0]),
core_ids=np.array([0]),
element_id_to_index={0: 0}
)
print(mesh_index.node_ids.shape)
# Output: (3,)
_BaseMask
Base class for typed masks over nodes or elements.
This mask holds a reference to the MeshIndex and a 1D array of selected
entity IDs (node IDs for NodeMask, element IDs for ElementMask).
Attributes:
| Name | Type | Description |
|---|---|---|
_mesh |
MeshIndex
|
The |
_ids |
ndarray
|
1D array of unique, sorted integer IDs of the selected entities (nodes or elements). |
Initializes a new _BaseMask instance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mesh
|
MeshIndex
|
Immutable snapshot of the assembled mesh to query. |
required |
ids
|
ndarray
|
A 1D array of selected entity IDs (node or element IDs depending on the concrete mask). The array will be normalized to sorted unique integers upon initialization. |
required |
Methods:
to_list
Returns the selection as a Python list of IDs.
Returns:
| Type | Description |
|---|---|
List[int]
|
List[int]: List of selected IDs in ascending order. |
to_set
Returns the selection as a Python set of IDs.
Returns:
| Name | Type | Description |
|---|---|---|
set |
set
|
Set of selected IDs. |
__len__
Returns the number of selected entities.
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
The count of IDs in this mask. |
NodeMask
Bases: _BaseMask
A mask of node IDs with chainable spatial and predicate-based filters.
All methods return a new NodeMask instance, ensuring immutability at the API level.
Example
import numpy as np
from femora.components.mask.mask_base import MeshIndex, NodeMask
mesh_index = MeshIndex(
node_ids=np.array([0, 1, 2, 3]),
node_coords=np.array([[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [2.0, 2.0, 2.0]]),
node_ndf=np.array([3, 3, 3, 3]),
node_core_map=[[0], [0], [0], [0]],
element_ids=np.array([0]),
element_connectivity=[np.array([0, 1, 2])],
element_centroids=np.array([[0.33, 0.33, 0.0]]),
element_types=np.array(["TRIANGLE"]),
material_tags=np.array([1]),
section_tags=np.array([1]),
region_tags=np.array([0]),
core_ids=np.array([0]),
element_id_to_index={0: 0}
)
all_nodes = NodeMask(mesh_index, mesh_index.node_ids)
filtered_nodes = all_nodes.by_bbox(0.5, 1.5, -0.5, 0.5, -0.5, 0.5)
print(filtered_nodes.to_list())
# Output: [1]
Methods:
by_ids
Intersects the current node mask with specific node IDs.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ids
|
Sequence[int]
|
A sequence of node IDs to retain. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
NodeMask |
'NodeMask'
|
A new mask containing the intersection of the current
mask's IDs and the provided |
by_bbox
Filters nodes inside an axis-aligned bounding box.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
xmin
|
float
|
The minimum x-coordinate of the bounding box. |
required |
xmax
|
float
|
The maximum x-coordinate of the bounding box. |
required |
ymin
|
float
|
The minimum y-coordinate of the bounding box. |
required |
ymax
|
float
|
The maximum y-coordinate of the bounding box. |
required |
zmin
|
float
|
The minimum z-coordinate of the bounding box. |
required |
zmax
|
float
|
The maximum z-coordinate of the bounding box. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
NodeMask |
'NodeMask'
|
A new mask containing only nodes whose coordinates are within the specified bounding box. |
near_point
Filters nodes within a specified distance from a given point.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
point
|
Tuple[float, float, float]
|
The reference point (x, y, z) from which to measure the distance. |
required |
radius
|
float
|
The radial distance threshold. Nodes within this radius will be included. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
NodeMask |
'NodeMask'
|
A new mask containing only nodes that are within the
specified radial distance from the |
along_line
along_line(point1: Tuple[float, float, float], point2: Tuple[float, float, float], radius: float) -> 'NodeMask'
Filters nodes within a specified distance from a line segment.
The line segment is defined by two endpoints. Nodes within a cylindrical region around this segment will be included.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
point1
|
Tuple[float, float, float]
|
The first endpoint of the line segment (x, y, z). |
required |
point2
|
Tuple[float, float, float]
|
The second endpoint of the line segment (x, y, z). |
required |
radius
|
float
|
The radial distance threshold from the line segment. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
NodeMask |
'NodeMask'
|
A new mask containing nodes that are within the cylindrical region around the line segment. |
along_axis
Filters nodes whose coordinate along a specified axis lies within a range.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
axis
|
str
|
The name of the axis ('x', 'y', or 'z') to filter along. Case-insensitive. |
required |
vmin
|
float
|
The minimum coordinate value (inclusive) for the specified axis. |
required |
vmax
|
float
|
The maximum coordinate value (inclusive) for the specified axis. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
NodeMask |
'NodeMask'
|
A new mask containing only nodes whose coordinate along the
given axis falls within the |
by_predicate
Filters nodes using a custom predicate function.
The predicate function will be called for each node, and only nodes for which the function returns True will be included in the new mask.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fn
|
Callable[[int, ndarray], bool]
|
A callable that accepts two arguments:
- |
required |
Returns:
| Name | Type | Description |
|---|---|---|
NodeMask |
'NodeMask'
|
A new mask containing only nodes that pass the predicate. |
touching_elements
Converts the current node mask to an element mask.
The resulting mask will contain all elements that are connected to any
of the nodes currently selected in this NodeMask.
Returns:
| Name | Type | Description |
|---|---|---|
ElementMask |
'ElementMask'
|
A new |
to_tags
Converts selected node IDs to OpenSees node tags.
This method applies an offset to the internal zero-based node IDs to generate application-specific node tags, typically for OpenSees.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_tag
|
int | None
|
Optional. The starting node tag. If |
None
|
Returns:
| Type | Description |
|---|---|
List[int]
|
List[int]: A list of OpenSees-compatible node tags for the selected nodes. |
ElementMask
Bases: _BaseMask
A mask of element IDs with chainable attribute and spatial filters.
All methods return a new ElementMask instance, ensuring immutability at the API level.
Example
import numpy as np
from femora.components.mask.mask_base import MeshIndex, ElementMask
mesh_index = MeshIndex(
node_ids=np.array([0, 1, 2, 3]),
node_coords=np.array([[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [2.0, 2.0, 2.0]]),
node_ndf=np.array([3, 3, 3, 3]),
node_core_map=[[0], [0], [0], [0]],
element_ids=np.array([10, 11, 12]),
element_connectivity=[np.array([0, 1]), np.array([1, 2]), np.array([2, 3])],
element_centroids=np.array([[0.5, 0.0, 0.0], [0.5, 0.5, 0.0], [1.0, 1.5, 1.0]]),
element_types=np.array(["BEAM", "BEAM", "TRUSS"]),
material_tags=np.array([1, 2, 1]),
section_tags=np.array([1, 1, 2]),
region_tags=np.array([0, 1, 0]),
core_ids=np.array([0, 0, 1]),
element_id_to_index={10: 0, 11: 1, 12: 2}
)
all_elements = ElementMask(mesh_index, mesh_index.element_ids)
filtered_elements = all_elements.by_material(1)
print(filtered_elements.to_list())
# Output: [10, 12]
Methods:
by_ids
Intersects the current element mask with specific element IDs.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ids
|
Sequence[int]
|
A sequence of element IDs to retain. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
ElementMask |
'ElementMask'
|
A new mask containing the intersection of the current
mask's IDs and the provided |
by_type
Filters elements by their type name (case-insensitive).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The element type name to match. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
ElementMask |
'ElementMask'
|
A new mask containing only elements whose type name
matches the provided |
by_material
Filters elements by their associated material tag.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tag
|
int
|
The integer material tag value to match. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
ElementMask |
'ElementMask'
|
A new mask containing only elements that have the
specified material |
by_section
Filters elements by their associated section tag.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tag
|
int
|
The integer section tag value to match. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
ElementMask |
'ElementMask'
|
A new mask containing only elements that have the
specified section |
by_region
Filters elements by their associated region tag.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tag
|
int
|
The integer region tag value to match. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
ElementMask |
'ElementMask'
|
A new mask containing only elements that are associated
with the specified region |
by_core
Filters elements by their partition or core ID.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
core
|
int
|
The integer core/partition identifier to match. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
ElementMask |
'ElementMask'
|
A new mask containing only elements that belong to the specified core. |
by_bbox
by_bbox(xmin: float, xmax: float, ymin: float, ymax: float, zmin: float, zmax: float, *, use_centroid: bool = True) -> 'ElementMask'
Filters elements inside an axis-aligned bounding box.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
xmin
|
float
|
The minimum x-coordinate of the bounding box. |
required |
xmax
|
float
|
The maximum x-coordinate of the bounding box. |
required |
ymin
|
float
|
The minimum y-coordinate of the bounding box. |
required |
ymax
|
float
|
The maximum y-coordinate of the bounding box. |
required |
zmin
|
float
|
The minimum z-coordinate of the bounding box. |
required |
zmax
|
float
|
The maximum z-coordinate of the bounding box. |
required |
use_centroid
|
bool
|
If True (default), elements are filtered based on whether their centroid lies within the bounding box. If False, an element is included if any of its nodes lies within the bounding box. |
True
|
Returns:
| Name | Type | Description |
|---|---|---|
ElementMask |
'ElementMask'
|
A new mask containing elements that are located within the specified bounding box. |
by_predicate
Filters elements using a custom predicate function.
The predicate function will be called for each element, and only elements for which the function returns True will be included in the new mask.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fn
|
Callable[[int, ndarray, str, int, int, int], bool]
|
A callable that accepts six arguments:
- |
required |
Returns:
| Name | Type | Description |
|---|---|---|
ElementMask |
'ElementMask'
|
A new mask containing only elements that pass the predicate. |
to_nodes
Converts to a node mask containing all nodes in the mesh.
This method currently returns all nodes found in the underlying
mesh, regardless of which elements are selected in the current
ElementMask. This behavior is due to an internal implementation
detail where it iterates over all mesh elements' connectivity.
Returns:
| Name | Type | Description |
|---|---|---|
NodeMask |
'NodeMask'
|
A new |
to_tags
Converts selected element IDs to OpenSees element tags.
This method offsets the existing explicit element IDs (which are already
considered tags within Femora) by a start_tag value, primarily for
compatibility with external tools like OpenSees that might use a
different tagging scheme or require a specific offset.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_tag
|
int | None
|
Optional. The value to add to each selected element ID.
If |
None
|
Returns:
| Type | Description |
|---|---|
List[int]
|
List[int]: A list of OpenSees-compatible element tags for the
selected elements. These are the original element IDs plus the
|