pyfebiopt.mesh.mesh

Mesh container for pyFEBiOpt.

This module defines small data classes to store nodes, elements, and surfaces. It also provides helpers to export FEBio XML blocks and to build a mesh from Gmsh .msh files or from an already parsed xplt reader.

Classes

MeshProvider

Minimal protocol for objects exposing a mesh attribute.

NodeArray

Dense node table with slice-friendly access.

ElementArray

Mixed-element connectivity with padding.

SurfaceArray

Facet connectivity with padding.

FebNodeCache

Cached node numbering for FEBio XML writers.

Mesh

Unified mesh container.

Module Contents

class pyfebiopt.mesh.mesh.MeshProvider

Bases: Protocol

Minimal protocol for objects exposing a mesh attribute.

mesh: Mesh
class pyfebiopt.mesh.mesh.NodeArray

Dense node table with slice-friendly access.

Attributes:

xyz

Array of shape (N, 3). Stored as float64.

xyz: numpy.ndarray
__post_init__() None
__len__() int

Return the number of nodes.

__getitem__(idx: slice | int | numpy.ndarray | list[int]) NodeArray

Return a sliced view.

The returned object is a new NodeArray pointing to a view of the original array when possible.

take(ids: numpy.ndarray | list[int]) NodeArray

Return a new node table with the given node ids.

Parameters:

ids – 0-based node ids to select.

class pyfebiopt.mesh.mesh.ElementArray

Mixed-element connectivity with padding.

Elements live in a 2D integer array with -1 padding on the right. The valid size of each row is stored in nper. This keeps slicing and vectorized operations simple while still allowing mixed arity.

Attributes:

conn

Array of shape (E, Kmax) with 0-based node ids. Unused slots are -1.

nper

Array of shape (E,) with the valid count per row.

etype

Array of shape (E,) with labels like 'hex8' or 'tet4'.

conn: numpy.ndarray
nper: numpy.ndarray
etype: numpy.ndarray
__post_init__() None
__len__() int

Return the number of elements.

__getitem__(idx: slice | int | numpy.ndarray | list[int]) ElementArray

Return a sliced view.

nodes_of(ei: int) numpy.ndarray

Return node ids for a single element.

Parameters:

ei – Element row index.

Returns:

Array of length nper[ei] with node ids.

unique_nodes() numpy.ndarray

Return sorted unique node ids used by the selection.

Empty selections return an empty array with int64 dtype.

as_ragged() list[numpy.ndarray]

Return a Python list with one 1D array of node ids per element.

Useful when downstream code expects per-element lists.

class pyfebiopt.mesh.mesh.SurfaceArray

Facet connectivity with padding.

Facets are stored like elements: a padded 2D array plus an nper vector.

Attributes:

faces

Array of shape (F, Kmax) with 0-based node ids. Unused slots are -1.

nper

Array of shape (F,) with valid count per facet.

faces: numpy.ndarray
nper: numpy.ndarray
__post_init__() None
__len__() int

Return the number of facets.

__getitem__(idx: slice | int | numpy.ndarray | list[int]) SurfaceArray

Return a sliced view.

nodes_of(fi: int) numpy.ndarray

Return node ids for a single facet.

Parameters:

fi – Facet row index.

Returns:

Array of length nper[fi] with node ids.

unique_nodes() numpy.ndarray

Return sorted unique node ids used by the selection.

Empty selections return an empty array with int64 dtype.

class pyfebiopt.mesh.mesh.FebNodeCache

Bases: TypedDict

Cached node numbering for FEBio XML writers.

Keys

object_name

Name used when no parts exist.

part_nodes

List of tuples (part_name, node_ids_sorted).

part_map

Mapping part_name -> {old_node_id: new_node_id}.

part_node_sets

Mapping part_name -> set(old_node_id) for quick membership checks.

global_map

Mapping old_node_id -> new_node_id across all parts.

max_node_id

Highest assigned node id in the cache.

Initialize self. See help(type(self)) for accurate signature.

object_name: str
part_nodes: list[tuple[str, numpy.ndarray]]
part_map: dict[str, dict[int, int]]
part_node_sets: dict[str, set[int]]
global_map: dict[int, int]
max_node_id: int
class pyfebiopt.mesh.mesh.Mesh(nodes: NodeArray, elements: ElementArray, parts: dict[str, numpy.ndarray] | None = None, surfaces: dict[str, SurfaceArray] | None = None, nodesets: dict[str, numpy.ndarray] | None = None)

Unified mesh container.

Holds node, element, surface, and set tables. Keeps each concern in its own class. Provides name-first access and FEBio XML builders.

Attributes:

nodes

Node table.

elements

Element table for the full mesh.

parts

Mapping name -> element indices selecting rows of elements.

surfaces

Mapping name -> SurfaceArray.

nodesets

Mapping name -> node ids.

Initialize the mesh.

param nodes:

Node table.

param elements:

Element table.

param parts:

Optional mapping name -> element indices.

param surfaces:

Optional mapping name -> SurfaceArray.

param nodesets:

Optional mapping name -> node ids.

nodes: NodeArray
elements: ElementArray
parts: dict[str, numpy.ndarray]
surfaces: dict[str, SurfaceArray]
nodesets: dict[str, numpy.ndarray]
property nelems: int

Return the number of elements in the mesh.

property nnodes: int

Return the number of nodes in the mesh.

bounds() tuple[numpy.ndarray, numpy.ndarray]

Return the axis-aligned bounding box.

Returns:

A tuple (min_xyz, max_xyz) with two arrays of shape (3,).

getDomain(name: str) ElementArray

Return a slice of elements for a named part.

Parameters:

name – Part name.

Returns:

Slice view of elements for the requested domain.

getSurface(name: str) SurfaceArray

Return a surface by name.

Parameters:

name – Surface name.

Returns: Surface table.

getNodeset(name: str) NodeArray

Return a nodeset by name as a node slice.

Parameters:

name – Nodeset name.

Returns:

Node slice view.

to_feb_nodes_xml(object_name: str = 'Object1') list[xml.etree.ElementTree.Element]

Build FEBio <Nodes> elements grouped by part.

Node ids are re-numbered per part in ascending order of original ids. If no parts exist, a single group named object_name is created.

Parameters:

object_name – Name used when no parts are present.

Returns:

List of <Nodes> elements. Order follows the internal part order.

Notes:

Node ids in XML are 1-based. Coordinates are written as comma-separated values x,y,z.

to_feb_elements_xml() list[xml.etree.ElementTree.Element]

Build one FEBio <Elements> element per part.

Returns:

List of <Elements> elements.

Notes:

Element ids in XML are 1-based and follow the original element order. Element type is taken as the first unique etype in the part. Mixed types in one part are not expanded.

to_feb_surfaces_xml() list[xml.etree.ElementTree.Element]

Build one FEBio <Surface> per named surface.

Returns:

List of <Surface> elements.

Notes:

Facet tags are chosen by node count: line2, tri3, or quad4. Fallback tag is facet when the count is unknown.

to_feb_nodesets_xml() list[xml.etree.ElementTree.Element]

Build FEBio <NodeSet> elements.

Returns:

List of <NodeSet> elements.

Notes:

Node ids are re-numbered using the same rules as for nodes and surfaces.

classmethod from_gmsh_msh(path: str, include: collections.abc.Sequence[str] | None = None, scale: collections.abc.Sequence[float] | numpy.ndarray = (1.0, 1.0, 1.0), quiet: bool = False) Mesh

Create a mesh from a Gmsh 2.0/2.2 ASCII .msh file.

The reader: - Supports physical groups for volumes, surfaces, and lines. - Builds parts from volume groups. Optionally filters by include. - Builds surfaces and nodesets from surface/line groups. - Reindexes node ids to 0-based and preserves original ordering. - Pads connectivity to a common width for simple slicing.

Parameters:
  • path – Path to the .msh file.

  • include – Physical names to include as parts. When None, include all volumes.

  • scale – Per-axis scale for node coordinates. Applied as (sx, sy, sz).

  • quiet – When True, suppress warnings about unsupported types.

Returns:

New Mesh instance.

Notes:

Only Gmsh ASCII formats 2.0 and 2.2 are supported. Quadratic types are kept as-is but not expanded. Unknown element types are skipped.

classmethod from_xplt(xplt_reader: MeshProvider) Mesh

Create a mesh from an xplt reader that already parsed a mesh.

Parameters:

xplt_reader – Reader whose mesh attribute is an instance compatible with Mesh.

Returns:

Detached copy of the reader mesh.

Raises:

TypeError

When xplt_reader.mesh is not compatible with this class.