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

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

.. autoapi-nested-parse::

   FEBio ``.xplt`` reader with regional FMT_NODE support and sliceable views.

   What it does
   ------------
   - Keeps FEBio shapes as written; no interpolation or reshaping.
   - Exposes a mesh, dictionary, and a registry of views tied together by names.
   - Lets you slice by time, region, items, nodes, and components without copies
     until evaluation.

   Reading workflow
   ----------------
   1) Header + dictionary: validate magic/version/compression; parse FEBio's
      dictionary into ``{name: {type, format}}`` and record whether each variable is
      nodal, elemental, or facial. Storage format decides the view type
      (FMT_NODE/FMT_ITEM/FMT_MULT/FMT_REGION).
   2) Mesh: read nodes, domains, surfaces, nodesets; normalize ids; pad connectivity
      for easy slicing; build a :class:`Mesh` while keeping names.
   3) States: load all with ``readAllStates()`` or selected with ``readSteps([...])``.
      Each state stores time plus node/element/face buffers; absent variables are
      stored as ``None``. Region ids keep per-domain nodal data split.
   4) Views: buffers become views on :class:`pyfebiopt.xplt.results.Results` at
      ``xplt.results``. Shapes mirror FEBio output.

   Dictionary → views
   ------------------
   - Nodal entries become :class:`NodeResultView` or :class:`NodeRegionResultView`.
   - Element/face entries become :class:`ItemResultView` (FMT_ITEM),
     :class:`MultResultView` (FMT_MULT), or :class:`RegionResultView` (FMT_REGION).
   - The original dictionary order is preserved.

   Selector quick reference
   ------------------------
   - ``time(sel)`` pick steps.
   - ``comp(sel)`` pick components by index or token (``"x"``, ``"zz"``); evaluates.
   - Region shortcuts: ``region(name)``/``domain(name)``/``surface(name)``.
   - Item/node shortcuts: ``items(...)``/``elems(...)``/``faces(...)``/``enodes(...)``/
     ``nodes(...)``; ``nodeset(name)`` on nodal views.
   - ``__getitem__`` mirrors axis order so ``view[t, item, comp]`` reads naturally.

   Component tokens
   ----------------
   - 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 like ``xxyy`` or ``yzzz`` (order-insensitive)

   Examples.
   ---------
   Read everything and slice later:

   .. code-block:: python

      from pyfebiopt.xplt import xplt

      xp = xplt("run.xplt")
      xp.readAllStates()         # or xp.readSteps([0, -1]) for endpoints
      U = xp.results["displacement"]
      tip = U.time(-1).nodes(-1).comp("z")

   Targeted subsets without extra copies:

   .. code-block:: python

      Uxz = U[0, ":", "x"]                        # shorthand
      Ubase = U.nodeset("base").comp(":")
      S = xp.results["von Mises"].domain("arteria").time(":").items([0, 5]).comp(":")

   Per-element-node and region vectors:

   .. code-block:: python

      Q = xp.results["strain"].domain("arteria")  # MultResultView
      q_slice = Q.time(0).items(0).enodes(":").comp("xx")

      vol = xp.results["domain volume"].domain("arteria")  # RegionResultView
      vol_all = vol.time(":").comp(":")

   Practical notes
   ---------------
   - ``readSteps(indices)`` helps on long runs; call multiple times to append more.
   - Views cast to ``float32`` for memory efficiency; masks follow numpy rules.
   - Connectivity and facet arrays are padded with ``-1`` for uniform width.
   - Missing variables on certain steps stay as ``NaN`` arrays with the right shape,
     keeping vectorized code stable.



Classes
-------

.. autoapisummary::

   pyfebiopt.xplt.xplt.xplt


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

.. py:class:: xplt(filename: str)

   User-facing entry point to read and slice FEBio ``.xplt`` files.

   Highlights
   ----------
   - Understands global and per-domain FMT_NODE plus item, mult, and region formats.
   - Builds a :class:`Mesh` with domains, surfaces, and node sets so you can map
     ids back to names.
   - Lazily slices results through views that mirror FEBio's storage.

   Example.
   --------
   .. code-block:: python

      xp = xplt("run.xplt")
      xp.readAllStates()           # parse all time steps
      disp = xp.results["displacement"]
      tip = disp.time(-1).nodes(-1).comp("z")

   .. code-block:: python

      # Partial loading: keep only selected steps
      xp = xplt("run.xplt")
      xp.readSteps([0, -1])
      stress = xp.results["stress"].domain("arteria")
      stress_end = stress.time(-1).items(":").comp("xx")

   Open and parse the xplt file header, dictionary, and mesh.


   .. py:attribute:: dictionary
      :type:  dict[str, dict[str, str]]


   .. py:attribute:: mesh
      :type:  pyfebiopt.mesh.mesh.Mesh


   .. py:attribute:: version
      :type:  int


   .. py:attribute:: compression
      :type:  int


   .. py:attribute:: results
      :type:  pyfebiopt.xplt.results.Results


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


   .. py:attribute:: __str__


   .. py:method:: readAllStates() -> None

      Read all states in order and finalize results.



   .. py:method:: readSteps(stepList: list[int]) -> None

      Read a selected list of step indices and finalize results.

      Steps are 0-based. The method advances by skipping blocks between
      requested steps.



