pyfebiopt.xplt.views
====================

.. py:module:: pyfebiopt.xplt.views

.. autoapi-nested-parse::

   Sliceable result views for XPLT data.

   Philosophy
   ----------
   Views delay all heavy lifting until evaluation. Selections are chained, carry no
   copies, and respect FEBio's storage format. When you finally call ``comp(...)`` or
   ``eval()``, indices are applied in order: time → region/item → node/enode →
   component. Returned arrays are ``float32`` and keep the ranks written by FEBio.

   Selector cheatsheet
   -------------------
   - ``time(sel)`` narrows time indices; pass ``":"`` for all.
   - ``region(name)``/``domain(name)``/``surface(name)`` switch to a stored block.
   - ``nodes(...)`` or ``items(...)``/``elems(...)``/``faces(...)``/``enodes(...)``
     limit rows inside a region or stream.
   - ``comp(...)`` picks components; names like ``"x"`` or ``"zz"`` are accepted when
     FEBio exposes them.
   - ``__getitem__`` mirrors the same axis order for quick slicing.

   Component name mapping
   ^^^^^^^^^^^^^^^^^^^^^^
   - VEC3F → ``x, y, z``
   - MAT3FD → ``xx, yy, zz``
   - MAT3FS → ``xx, yy, zz, xy, yz, xz``
   - MAT3F → full 3x3 row-major names
   - TENS4FS → Voigt-6 pairs such as ``xxyy`` or ``yzzz`` (order-insensitive)

   Examples.
   ---------
   .. code-block:: python

      U = results["displacement"]
      U_tip = U.time(-1).nodes(-1).comp("z")
      U_fast = U[0, ":", "x"]               # shorthand

   .. code-block:: python

      S = results["stress"].domain("arteria")
      S_last = S.time(-1).items(slice(0, 10)).comp("xx")

   .. code-block:: python

      Q = results["strain"].domain("arteria")
      q = Q.time(0).items(0).enodes(":").comp("xx")

   Notes.
   ------
   - Missing data for a step/region returns the right shape filled with ``NaN``.
   - Slices are applied on demand, so you can compose selections in any order before
     requesting data.



Classes
-------

.. autoapisummary::

   pyfebiopt.xplt.views.NodeResultView
   pyfebiopt.xplt.views.NodeRegionResultView
   pyfebiopt.xplt.views.ItemResultView
   pyfebiopt.xplt.views.MultResultView
   pyfebiopt.xplt.views.RegionResultView


Module Contents
---------------

.. py:class:: NodeResultView(meta: _FieldMeta, times: numpy.ndarray, per_t: list[numpy.ndarray | None], mesh: pyfebiopt.mesh.mesh.Mesh)

   Bases: :py:obj:`_BaseView`


   Global nodal results (FMT_NODE).

   Axes follow ``(time, node, component)``. Component names are resolved when FEBio
   provides them; otherwise numeric indices work. ``nodes(...)`` accepts integer
   indices, slices, boolean masks, or numpy arrays matching the mesh node order.

   Create a nodal view backed by per-time arrays.


   .. py:attribute:: __slots__
      :value: ('_mesh', '_node_idx', '_per_t')



   .. py:method:: nodes(ids: pyfebiopt.xplt.types.Index) -> Self

      Select node rows by indices, slices, masks, or lists.

      :returns: View for chaining.



   .. py:method:: nodeset(name: str) -> Self

      Select by nodeset name from the mesh.

      :returns: View for chaining.

      .. rubric:: Example

      ``view.nodeset("base").comp("z")`` selects nodeset ``base``.



   .. py:method:: dims() -> tuple[str, Ellipsis]

      Describe array axes.

      :returns: Axis labels as ``("time", "node", "component")``.



   .. py:method:: eval() -> numpy.ndarray

      Return an array with the current selections applied.



   .. py:method:: __getitem__(key: Any) -> numpy.ndarray

      Shorthand selection: ``[time, nodes, comp]``.

      :param key: Tuple of selectors or single selector for time.

      :returns: Array with selections applied.



   .. py:method:: __repr__() -> str


   .. py:attribute:: __str__


.. py:class:: NodeRegionResultView(meta: _FieldMeta, times: numpy.ndarray, per_name: dict[str, list[numpy.ndarray | None]], region_nodes: dict[str, numpy.ndarray])

   Bases: :py:obj:`_BaseView`


   Per-domain nodal results (FMT_NODE split by region).

   Axes follow ``(time, node_in_region, component)``. Use ``regions()`` to list
   domains then call ``region(name)`` or ``domain(name)`` to focus on one block.
   ``nodes(...)`` is relative to the region-local node order stored in FEBio.

   Create a per-region nodal view.


   .. py:attribute:: __slots__
      :value: ('_node_idx', '_per_name', '_region_nodes')



   .. py:method:: regions() -> list[str]

      Return available region names.



   .. py:attribute:: domains


   .. py:method:: region(name: str) -> NodeRegionResultView

      Restrict the view to a single region.

      :returns: View for the selected region.



   .. py:attribute:: domain


   .. py:method:: region_nodes() -> numpy.ndarray

      Return node ids for the selected region.



   .. py:method:: nodes(ids: pyfebiopt.xplt.types.Index) -> Self

      Select nodes by indices relative to the region list.

      :returns: View for chaining.



   .. py:method:: dims() -> tuple[str, Ellipsis]

      Describe array axes.

      :returns: Axis labels as ``("time", "node_in_region", "component")``.



   .. py:method:: eval(*, region: str | None = None) -> numpy.ndarray

      Return array with current selections.



   .. py:method:: __repr__() -> str


   .. py:attribute:: __str__


.. py:class:: ItemResultView(meta: _FieldMeta, times: numpy.ndarray, per_name: dict[str, list[numpy.ndarray | None]])

   Bases: :py:obj:`_BaseView`


   Per-item results (FMT_ITEM).

   Axes follow ``(time, item, component)``. Items correspond to elements or faces
   depending on where the variable was defined. Region-aware variables expose one
   block per domain or surface; call ``regions()`` and ``region(name)`` to pick.

   Create an item view backed by per-region arrays.


   .. py:attribute:: __slots__
      :value: ('_item_idx', '_per_name')



   .. py:method:: regions() -> list[str]

      Return available regions.



   .. py:attribute:: domains


   .. py:attribute:: surfaces


   .. py:method:: region(name: str) -> ItemResultView

      Restrict the view to a single region.

      :returns: View limited to ``name``.



   .. py:attribute:: domain


   .. py:method:: items(idx: pyfebiopt.xplt.types.Index) -> ItemResultView

      Select items by indices, slices, masks, or lists.

      :returns: View for chaining.



   .. py:attribute:: elems


   .. py:attribute:: faces


   .. py:method:: dims() -> tuple[str, Ellipsis]

      Describe array axes.

      :returns: Axis labels as ``("time", "item", "component")``.



   .. py:method:: eval(*, region: str | None = None) -> numpy.ndarray

      Return array with current selections.



   .. py:method:: __repr__() -> str


   .. py:attribute:: __str__


.. py:class:: MultResultView(meta: _FieldMeta, times: numpy.ndarray, per_name: dict[str, list[pyfebiopt.xplt.types.MultLike | None]])

   Bases: :py:obj:`_BaseView`


   Per-item per-element-node results (FMT_MULT).

   Axes follow ``(time, item, enode, component)``. Use ``items(...)`` to select
   elements/faces and ``enodes(...)`` to pick a position inside each connectivity
   list. Region-aware streams need an explicit ``region(name)`` before evaluation.

   Create a per-item per-enode view backed by region blocks.


   .. py:attribute:: __slots__
      :value: ('_enode_idx', '_item_idx', '_per_name')



   .. py:method:: regions() -> list[str]

      Return available regions.



   .. py:attribute:: domains


   .. py:attribute:: surfaces


   .. py:method:: region(name: str) -> MultResultView

      Restrict the view to a single region.

      :returns: View limited to ``name``.



   .. py:attribute:: domain


   .. py:method:: items(idx: pyfebiopt.xplt.types.Index) -> MultResultView

      Select items by indices, slices, masks, or lists.

      :returns: View for chaining.



   .. py:attribute:: elems


   .. py:attribute:: faces


   .. py:method:: enodes(idx: pyfebiopt.xplt.types.Index) -> MultResultView

      Select element-node positions by indices or slices.

      :returns: View for chaining.



   .. py:attribute:: nodes


   .. py:method:: dims() -> tuple[str, Ellipsis]

      Describe array axes.

      :returns: Axis labels as ``("time", "item", "enode", "component")``.



   .. py:method:: eval(*, region: str | None = None) -> numpy.ndarray

      Return array with current selections.



   .. py:method:: __repr__() -> str


   .. py:attribute:: __str__


.. py:class:: RegionResultView(meta: _FieldMeta, times: numpy.ndarray, per_name: dict[str, list[numpy.ndarray | None]])

   Bases: :py:obj:`_BaseView`


   Per-region vector results (FMT_REGION).

   Axes follow ``(time, component)``. Each region stores a compact vector, often
   integrals or aggregated values. Use ``regions()`` to list and ``region(name)``
   to focus on one block before evaluating.

   Create a per-region vector view.


   .. py:attribute:: __slots__
      :value: ('_per_name', '_region_idx')



   .. py:method:: regions() -> list[str]

      Return available regions.



   .. py:attribute:: domains


   .. py:attribute:: surfaces


   .. py:method:: region(name: str) -> RegionResultView

      Restrict the view to a single region.

      :returns: View limited to ``name``.



   .. py:attribute:: domain


   .. py:method:: dims() -> tuple[str, Ellipsis]

      Describe array axes.

      :returns: Axis labels as ``("time", "component")``.



   .. py:method:: eval() -> numpy.ndarray

      Return array with current selections.



   .. py:method:: __repr__() -> str


   .. py:attribute:: __str__


