Binary MAPDL File Explorer#

This tutorial will demonstrate how to explore the content of binary files generated by a MAPDL Session and extract pertinent records.

These files include most of the binary files generated by APDL (e.g. .RST, .FULL, etc.).

from ansys.mapdl.core import launch_mapdl

# Start MAPDL as a service and disable all but error messages.
from ansys.mapdl.core.examples import vmfiles

mapdl = launch_mapdl()

# A specific property under the mapdl class is dedicated for XPL. It's
# based on the APDLMath `*XPL` command.
xpl = mapdl.xpl

# Many commands are directly accessible through the xpl class:
help(xpl)
Help on ansXpl in module ansys.mapdl.core.xpl object:

class ansXpl(builtins.object)
 |  ansXpl(mapdl)
 |
 |  ANSYS database explorer.
 |
 |  Examples
 |  --------
 |  >>> from ansys.mapdl.core import launch_mapdl
 |  >>> mapdl = launch_mapdl()
 |  >>> xpl = mapdl.xpl
 |
 |  Open a mode file and extract a vector.
 |
 |  >>> xpl.open('file.mode')
 |  >>> vec = xpl.read('MASS')
 |  >>> vec.asarray()
 |  array([ 4,  7, 10, 13, 16, 19, 22, 25, 28, 31, 34, 37, 40, 43,
 |          46, 49, 52, 55, 58,  1], dtype=int32)
 |
 |  Methods defined here:
 |
 |  __init__(self, mapdl)
 |      Initialize the class.
 |
 |  __repr__(self)
 |      Return repr(self).
 |
 |  close(self)
 |      Close the MAPDL file after opening.
 |
 |      Returns
 |      -------
 |      str
 |          Response from MAPDL.
 |
 |      Examples
 |      --------
 |      >>> xpl.open("file.mode")
 |      >>> xpl.close()
 |      =====      ANSYS File Xplorer : Close the file.mode ANSYS File
 |
 |  copy(self, newfile, option='')
 |      Copy the current opened as a new file.
 |
 |      Parameters
 |      ----------
 |      newfile : str
 |          Name of the new file to create
 |
 |      option: str
 |          Option.
 |
 |      Examples
 |      --------
 |      >>> xpl.copy('tmpfile.full')
 |       =====      ANSYS File Xplorer : Copy file.full ANSYS file to file tmpfile.full
 |          >>      Remove existing output file tmpfile.full
 |
 |  extract(self, recordname, sets='ALL', asarray=False)
 |      Import a Matrix/Vector from a MAPDL result file.
 |
 |      At the moment, this only supports reading the displacement vectors from
 |      a result file.
 |
 |      Parameters
 |      ----------
 |      recordname : str
 |          Record name. Currently only supports the ``"NSL"`` record,
 |          displacement vectors.
 |
 |      sets : str or int
 |          Number of sets. Can be ``"ALL"`` or the number of sets to load.
 |
 |      asarray : bool, optional
 |          Return a :class:`numpy.ndarray` rather than a :class:`AnsMath
 |          <ansy.math.core.math.AnsMath>`. Default ``False``.
 |
 |      Returns
 |      -------
 |      numpy.ndarray or ansys.math.core.math.AnsMath
 |          A :class:`numpy.ndarray` or :class:`AnsMath
 |          <ansys.math.core.math.AnsMath>` of the displacement vectors,
 |          depending on the value of ``asarray``.
 |
 |      Notes
 |      -----
 |      This only works on the ``"NSL"`` record of MAPDL result files.
 |
 |      Examples
 |      --------
 |      First, open a result file and extract the displacement vectors for all
 |      sets.
 |
 |      >>> xpl.open("file.rst")
 |      >>> mat = xpl.extract("NSL")
 |      >>> mat
 |      Dense APDLMath Matrix (243, 10)
 |
 |      Convert to a dense numpy array
 |
 |      >>> arr = mat.asarray()
 |      >>> arr
 |      array([[-9.30806802e-03, -2.39600770e-02, -5.37856729e-03, ...,
 |              -5.61188243e-03, -7.17686067e-11,  3.71893252e-03],
 |             [-1.60960014e-02,  2.00410618e-02,  8.05822565e-03, ...,
 |              -1.26917511e-02, -5.14133724e-11, -1.38783485e-03],
 |             [ 2.54040694e-02,  3.91901513e-03, -2.67965796e-03, ...,
 |              -1.46365178e-02,  8.31735188e-11, -2.33109771e-03],
 |             ...,
 |             [-2.80679551e-03, -1.45686692e-02,  8.05466291e-03, ...,
 |               5.88196684e-03,  1.72211103e-02,  6.10079082e-03],
 |             [-7.06675717e-03,  1.30455037e-02, -6.31685295e-03, ...,
 |               1.08619340e-02, -1.72211102e-02,  2.52199472e-03],
 |             [ 2.29726170e-02,  3.54392176e-03, -1.87020162e-03, ...,
 |               1.20642736e-02,  2.58299321e-11,  9.14504940e-04]])
 |
 |  goto(self, path)
 |      Go directly to a new location in the file.
 |
 |      Parameters
 |      ----------
 |      path : str
 |          Absolute path to the new location.
 |
 |      Examples
 |      --------
 |      >>> print(xpl.goto('MASS'))
 |       =====      ANSYS File Xplorer : Go up to top level(s)
 |       =====      ANSYS File Xplorer : Step into Block MASS
 |
 |  help(self)
 |      XPL help message.
 |
 |      Examples
 |      --------
 |      >>> print(xpl.help())
 |
 |  info(self, recname, option='')
 |      Gives details on a specific record, or all records (using ``"*"``)
 |
 |      Parameters
 |      ----------
 |      recname : str
 |          Record of interest
 |
 |      option : str
 |          Options string.
 |
 |      Returns
 |      -------
 |      str
 |          Response from MAPDL.
 |
 |      Examples
 |      --------
 |      >>> xpl.open('file.full')
 |      >>> print(xpl.info('NGPH'))
 |      =====      ANSYS File Xplorer : Information about Block NGPH
 |      ::NGPH                 Size =      6.289 KB
 |               - Record Size   : 81
 |               - Data type     : integer values
 |
 |  json(self)
 |      Return a JSON representation of the tree or records.
 |
 |      Examples
 |      --------
 |      >>> xpl.json()
 |      {'name': 'FULL',
 |       'children': [{'name': 'DOFSBYNOD', 'size': 24},
 |       {'name': 'BACK', 'size': 336},
 |       {'name': 'STIFF', 'size': 120132},
 |       {'name': 'RHS', 'size': 1956},
 |       {'name': 'DIAGK', 'size': 1956},
 |       {'name': 'SCLK', 'size': 36},
 |       {'name': 'NODEEXT', 'size': 32},
 |       {'name': 'PCGDOFS', 'size': 984},
 |       {'name': 'BCDOFS', 'size': 984},
 |       {'name': 'BCVALUES', 'size': 20},
 |       {'name': 'MASS', 'size': 52020},
 |       {'name': 'DIAGM', 'size': 1236},
 |       {'name': 'NGPH', 'size': 6440}]}
 |
 |  list(self, nlev=1)
 |      List the records at the current level.
 |
 |      Parameters
 |      ----------
 |      nlev: int
 |          Number of levels to recursively explore.
 |
 |      Returns
 |      -------
 |      str
 |          Listing of records from the current level.
 |
 |      Examples
 |      --------
 |      Open a full file and list the current records.
 |
 |      >>> xpl.open("file.full")
 |      >>> xpl.list()
 |      =====      ANSYS File Xplorer : List Blocks in File file.full
 |       ::FULL::HEADER         Size =        652  B     Total  Size =    180.297 KB
 |       ::FULL::DOFSBYNOD            Size =         24  B
 |       ::FULL::BACK                 Size =        336  B
 |
 |       ::FULL::STIFF::HEADER        Size =    117.316 KB
 |       ::FULL::RHS                  Size =      1.910 KB
 |       ::FULL::DIAGK                Size =      1.910 KB
 |       ::FULL::SCLK                 Size =      1.910 KB
 |       ::FULL::MRK                  Size =        984  B
 |       ::FULL::NODEEXT              Size =        336  B
 |       ::FULL::PCGDOFS              Size =        984  B
 |       ::FULL::BCDOFS               Size =        984  B
 |       ::FULL::BCVALUES             Size =         12  B
 |
 |       ::FULL::MASS::HEADER         Size =     50.801 KB
 |       ::FULL::DIAGM                Size =      1.910 KB
 |       ::FULL::NGPH                 Size =        336  B
 |
 |  open(self, filename, option='')
 |      Open an MAPDL file to explore.
 |
 |      Parameters
 |      ----------
 |      filename : str
 |          Name of the file to open.
 |
 |      Returns
 |      -------
 |      str
 |          Response from MAPDL.
 |
 |      Examples
 |      --------
 |      >>> xpl.open('file.mode')
 |      ===============================================
 |      =====      ANSYS File Xplorer            ======
 |      ===============================================
 |
 |      Opening the file.mode ANSYS File
 |
 |  print(self, recname)
 |      Print values of a given records, or all records (using ``"*"``).
 |
 |      Parameters
 |      ----------
 |      recname : str
 |          Record of interest
 |
 |      option : str
 |          Options string.
 |
 |      Returns
 |      -------
 |      str
 |          Response from MAPDL.
 |
 |      Examples
 |      --------
 |      >>> xpl.open('file.full')
 |      >>> print(xpl.print('DOFSBYNOD'))
 |      =====      ANSYS File Xplorer : Print Block DOFSBYNOD
 |      DOFSBYNOD :
 |      Size : 3
 |             1         2         3
 |
 |  read(self, recordname, asarray=False)
 |      Read a record and return either an APDL math matrix or an APDL math vector.
 |
 |      Returns
 |      -------
 |      ansys.mapdl.AnsMath or ansys.mapdl.AnsVec
 |          A handle to the APDLMath object.
 |
 |      asarray : bool, optional
 |          Return a :class:`numpy.ndarray` rather than a :class:`AnsMath
 |          <ansys.math.core.math.AnsMath>`. Default ``False``.
 |
 |      Examples
 |      --------
 |      >>> vec = xpl.read('MASS')
 |      >>> vec.asarray()
 |      array([ 4,  7, 10, 13, 16, 19, 22, 25, 28, 31, 34, 37, 40, 43,
 |             46, 49, 52, 55, 58,  1], dtype=int32)
 |      >>> vec = xpl.read('MASS', asarray=True)
 |      array([ 4,  7, 10, 13, 16, 19, 22, 25, 28, 31, 34, 37, 40, 43,
 |             46, 49, 52, 55, 58,  1], dtype=int32)
 |
 |  save(self)
 |      Save the current file, ignoring the marked records.
 |
 |  step(self, where)
 |      Go down in the tree of records
 |
 |      Parameters
 |      ----------
 |      where : str
 |          Path to follow. This path can be composed of several
 |          levels, for example ``"BRANCH1::SUBBRANCH2::.."``
 |
 |      Returns
 |      -------
 |      str
 |          Response from MAPDL.
 |
 |      Examples
 |      --------
 |      >>> xpl.step('MASS')
 |      >>> print(xpl.where())
 |       =====      ANSYS File Xplorer : Display Current Location
 |       Current Location : FULL::MASS
 |          File Location : 7644
 |
 |  up(self, nlev=1)
 |      Go up in the tree.
 |
 |      nlev : int
 |          Number of levels to recursively go up, or TOP
 |
 |      Examples
 |      --------
 |      >>> print(xpl.up())
 |       =====      ANSYS File Xplorer : Go up to 1 level(s)
 |                   -> Already at the top level. Command is ignored
 |
 |  where(self)
 |      Returns the current location in the MAPDL file.
 |
 |      Returns
 |      -------
 |      str
 |          String containing the current location.
 |
 |      Examples
 |      --------
 |      >>> print(xpl.where())
 |       =====      ANSYS File Xplorer : Display Current Location
 |       Current Location : FULL
 |          File Location : 412
 |
 |  write(self, recordname, vecname)
 |      Write a given record back to an MAPDL file.
 |
 |      Use the write function at your own risk, you may corrupt an existing
 |      file by changing the size of a record in the file.  This method must be
 |      used only on a non-compressed file.
 |
 |      Parameters
 |      ----------
 |      recordname : str
 |          Name of the record you want to overwrite. Your position
 |          in the file must be set accordingly to this record location
 |          (same as if you want to read it).
 |
 |      vecname : str
 |          Name of the APDLMath vector you want to write in the MAPDL
 |          file. Its size must be consistent with the existing record.
 |
 |      Returns
 |      -------
 |      str
 |          Response from MAPDL.
 |
 |      Examples
 |      --------
 |      >>> xpl.write('MASS', vecname)
 |
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |
 |  __dict__
 |      dictionary for instance variables (if defined)
 |
 |  __weakref__
 |      list of weak references to the object (if defined)
 |
 |  ----------------------------------------------------------------------
 |  Data and other attributes defined here:
 |
 |  __annotations__ = {}

Open and explore a file#

First you need to open an existing file. We can create an example result file by running a verification manual input file and then opening the result file that it creates.

NOTE: for now only one file can be opened at a time

# run Verification Manual 1 and opening the result file it creates
mapdl.input(vmfiles["vm1"])
print(xpl.open("file.rst"))
===============================================
 =====      ANSYS File Xplorer            ======
 ===============================================

 Opening the file.rst ANSYS File

Using the list function, you can list the records available at the current level.

print(xpl.list())
=====      ANSYS File Xplorer : List Blocks in File file.rst

 ::RST::HEADER          Size =        332  B     Total  Size =    319.598 KB
 ::RST::DOF                  Size =         24  B
 ::RST::NOD                  Size =         28  B
 ::RST::ELM                  Size =         24  B

 ::RST::DSI::HEADER          Size =     78.137 KB        Total  Size =    120.137 KB
 ::RST::TIM                  Size =     78.137 KB
 ::RST::LSP                  Size =    117.199 KB

 ::RST::GEO::HEADER          Size =        332  B        Total  Size =      3.727 KB

Using the step and up functions, you can go down into a specific branch of the tree, or go up to the top level

xpl.step("GEO")
print(xpl.list())
=====      ANSYS File Xplorer : List Blocks in File file.rst

 ::GEO::HEADER          Size =        332  B     Total  Size =      3.727 KB

 ::GEO::ETY::HEADER          Size =         16  B        Total  Size =        844  B
 ::GEO::LOC                  Size =        272  B

 ::GEO::EID::HEADER          Size =        216  B
 ::GEO::CENT                 Size =        180  B

 ::GEO::SEC::HEADER          Size =         16  B        Total  Size =        284  B

 ::GEO::MAT::HEADER          Size =        816  B        Total  Size =      1.598 KB
 ::GEO::NOD                  Size =         28  B
 ::GEO::ELM                  Size =         24  B

Display where you are in the tree or records:

print(xpl.where())
=====      ANSYS File Xplorer : Display Current Location

 Current Location : RST::GEO
    File Location : 280856

Go up one level to move back to the top and then list the records at the current point.

xpl.up()
print(xpl.list())
=====      ANSYS File Xplorer : List Blocks in File file.rst

 ::RST::HEADER          Size =        332  B     Total  Size =    319.598 KB
 ::RST::DOF                  Size =         24  B
 ::RST::NOD                  Size =         28  B
 ::RST::ELM                  Size =         24  B

 ::RST::DSI::HEADER          Size =     78.137 KB        Total  Size =    120.137 KB
 ::RST::TIM                  Size =     78.137 KB
 ::RST::LSP                  Size =    117.199 KB

 ::RST::GEO::HEADER          Size =        332  B        Total  Size =      3.727 KB

Read a record into an APDLMath Vector#

The info method will give you information about a record (e.g. length, data type, etc.)

Using the read method, you can read a specific record and fill an APDLMath object.

print(xpl.info("DOF"))
v = xpl.read("DOF")
print(v)
=====      ANSYS File Xplorer : Information about Block DOF

 ::DOF                  Size =         24  B

         - Record Size   : 3
         - Data type     : integer values
NILOOU :
 Size : 3
        1         2         3

To get this vector into a NumPy array you need to explicitly use asarray:

nod = v.asarray()
print(nod)
[1 2 3]

Read the first nodal solution First we go into the first solution set

print(xpl.goto("DSI::SET1"))
print(xpl.list())
=====      ANSYS File Xplorer : Go up to top level(s)
 =====      ANSYS File Xplorer : Step into Block DSI::SET1
=====      ANSYS File Xplorer : List Blocks in File file.rst

 ::SET1::HEADER         Size =        812  B     Total  Size =     42.000 KB
 ::SET1::DPHEAD               Size =        812  B
 ::SET1::EXT                  Size =        812  B
 ::SET1::NSL                  Size =        108  B
 ::SET1::RFDOFS               Size =         60  B
 ::SET1::RFVALS               Size =         60  B

 ::SET1::BC::HEADER           Size =        172  B       Total  Size =        564  B

 ::SET1::ESL::HEADER          Size =     38.848 KB

Then we read the Nodal solution vector “NSL” into a numpy array

u = xpl.read("NSL")
un = u.asarray()
print(un)
[ 1.2676506e+30 -9.0000000e-05  1.2676506e+30  0.0000000e+00
  0.0000000e+00  0.0000000e+00  0.0000000e+00  0.0000000e+00
  0.0000000e+00  1.2676506e+30 -8.0000000e-05  1.2676506e+30]

Close an opened file

print(xpl.close())
=====      ANSYS File Xplorer : Close the file.rst ANSYS File

Stop mapdl#

mapdl.exit()

Total running time of the script: (0 minutes 0.341 seconds)