Task 626: .RST File Format

Task 626: .RST File Format

1. Properties of the .RST File Format Intrinsic to Its File System

The .RST file format is a binary format used by ANSYS Mechanical APDL for storing simulation results (structural, thermal, or coupled-field analyses). It functions as a self-contained "file system" with a hierarchical structure of headers, index tables, pointers to data blocks, and repeated solution sets. This structure allows for efficient access to nodal and elemental data across multiple load cases, using relative pointers and bitmasks to indicate available data types. The format is direct-access unformatted binary, with records organized for buffered block access. Key intrinsic properties, derived from the ANSYS Programmer's Reference, are listed below in categories for clarity. These properties define the file's organization, metadata, and data availability.

Standard File Header Properties (First 100 Integers, 400 Bytes)

  • File Number: Fortran unit number (e.g., 12 for .RST).
  • File Format: Format type (1 = small, -1 = large, 0 = old internal, -1 = external IEEE).
  • Creation Time: Compact time encoding (HHMMSS).
  • Creation Date: Compact date encoding (YYYYMMDD).
  • Unit System: Measurement units (0 = user-defined, 1 = SI, 2 = CSG, 3 = U.S. feet, 4 = U.S. inches, 5 = MKS, 6 = MPA, 7 = μMKS).
  • Release Level: ANSYS release version (e.g., "X.X" encoded as integer).
  • Release Date: Release date as integer.
  • Machine Identifier: 3 × 4-character strings identifying the host machine.
  • Jobname: 8 × 4-character strings for the job name.
  • Product Name: 2 × 4-character strings for the product.
  • Special Version Label: 1 × 4-character string for special versions.
  • User Name: 3 × 4-character strings for the user.
  • System Record Size: Size of system records at file write time.
  • Maximum File Length: 64-bit long integer (split into high/low 32-bit parts).
  • Maximum Record Number: Maximum number of records.
  • Cores (Shared-Memory Parallel): Number of SMP cores used.
  • Cores (Distributed-Memory Parallel): Number of DMP cores used.
  • Main Analysis Title: 20 × 4-character strings for the main title.
  • First Subtitle: 20 × 4-character strings for the subtitle.
  • File Compression Level: Compression level used.
  • File Sparsification Key: Key for sparsification.
  • Split Point: Split point for large files (0 = no split).

.RST-Specific Header Properties (Next 80 Integers, 320 Bytes)

  • Maximum Node Number (maxn): Highest node ID.
  • Number of Nodes (nnod): Actual number of nodes in solution.
  • Maximum Data Sets (resmax): Maximum number of result sets (default 10000, min 10).
  • DOFs per Node (numdof): Number of degrees of freedom per node (up to 64).
  • Maximum Element Number (maxe): Highest element ID.
  • Number of Elements (nelm): Actual number of elements.
  • Analysis Type Driver (kan): Type of analysis.
  • Number of Data Sets (nsets): Actual number of result sets.
  • File End Pointer (ptrend, ptrEnd8): 64-bit pointer to file end.
  • Pointers to Tables: 64-bit pointers (low/high parts) to DSI (data set index), TIM (time/frequency), LSP (load step/substep), ELM (element table), NOD (node table), GEO (geometry), CYC (cyclic symmetry), TRAN (transformation vectors), GNOD (global node table), UDFRQ (undamped frequencies).
  • CMS Results Flag (CMSflg): Component mode synthesis flag (0 = non-CMS).
  • Cyclic Symmetry Elements in Master Sector (csEls): Number of elements in master sector.
  • Number of Sectors (nSector): Number of cyclic symmetry sectors.
  • Cyclic Symmetry Coordinate System (csCord): Coordinate system for cyclic symmetry.
  • FSI Flag (fsiflag): Fluid-structure interaction flag.
  • Node Offset (noffst): Offset for node numbering.
  • Element Offset (eoffst): Offset for element numbering.
  • Number of SE Transformation Vectors (nTrans): Number of transformation vectors.
  • Precision Key (PrecKey): Precision for results (0 = double, 1 = single for elements, 2 = single for all).
  • Cyclic Symmetry Nodes in Master Sector (csNds): Number of nodes in master sector.
  • Complex Results Flag (cpxrst): 0 = real, 1 = complex.
  • Mode Extraction Option (extopt): Extraction method for modes.
  • NLGEOM Key (nlgeom): Nonlinear geometry flag.
  • Available Data Bits (AvailDatal, AvailDatah, AvailDataELSV): Bitmasks indicating available nodal, elemental, averaged, and single-value results (per resucm.inc).
  • Missing Mass Responses (mmass): Number of missing mass responses.
  • Linear Perturbation Key (kPerturb): Perturbation analysis flag.
  • XFEM Key (XfemKey): Extended finite element method flag (0 = inactive, 1 = active).
  • Suppressed Items Bitmask (rstsprs): Bitmask for suppressed data.
  • Global Nodes (Glbnnod): Global number of nodes (for Distributed ANSYS).
  • QR Damped Key (qrDmpKy): QR damping calculation key.
  • MSUP Key (MSUPkey): MSUP results expansion flag.
  • PSD Key (PSDkey): Power spectral density key (1 = PSD, 2 = response spectrum).
  • Cyclic MSUP Key (cycMSUPkey): Cyclic MSUP format flag.
  • XFEM Crack Propagation Tech (XfemCrkPropTech): Crack technology (0 = phantom, 1 = singularity).
  • No Duplicate Sector (cycNoDup): Duplicate sector flag for cyclic.
  • Domain Decomposition Method (decompMth): DMP decomposition method (>=0 = MESH, -1 = FREQ, -2 = CYCHI).
  • Number of Processes per Frequency/Harmonic (nProcSol): DMP processes.
  • MPI World ID (mpiWrld): Unique identifier for results file.
  • Additive Manufacturing Type (AMtype): AM analysis flag.
  • Undamped Frequency Format Key (udfrqkey): Format for undamped frequencies.
  • ENG Record Format (cpxeng): Complex ENG record length (0 = 11, 1 = 21).
  • Harmonic Solution Method (hrmopt): Method (1 = FULL, 2 = MSUP, 4 = HBM, 5 = VT, 10 = Krylov).
  • Remote Files Flag (moddirF): Flag for remote files (MODDIR command).
  • Component Name Length Key (lngCmpKey): Name length (0 = <=32 chars, 1 = >32 chars).
  • SMART Crack Key (SmartKey): SMART crack propagation technology.
  • Linear Perturbation Generation Pass Key (LPGPkey): LP generation flag.
  • Analysis Type (antype): Overall analysis type.

Additional Intrinsic Properties

  • DOF Reference Array: Array of DOF codes (e.g., UX = 1, UY = 2, ..., TTOP = 64).
  • Data Types: Integer (i, 4 bytes), double precision (dp, 8 bytes), long integer (LONG, 4/8 bytes), complex (cmp, 16 bytes for real/imag).
  • Record Structure: Records with length (lrec), number (nrec), and type; supported up to 1000 result sets; NMISC <=120, nuval * nintp <=840 for state variables.
  • Access Modes: Global or local entity access; complex data as real/imag pairs.
  • Error Handling: E_ResultNotAvailable for missing data.
  • Limits: Max 1000 result sets in C++ reader; supports 64-bit pointers (split low/high).

These properties ensure the file's self-describing nature, enabling random access to results without an external index.

Based on public tutorials and examples, the following are direct links to archives containing sample .RST files (unzipped, they contain the .RST). These are from reputable engineering resources.

3. Ghost Blog Embedded HTML JavaScript for Drag-and-Drop .RST Property Dump

The following is a self-contained HTML snippet with embedded JavaScript for embedding in a Ghost blog post. It creates a drag-and-drop zone for .RST files. Upon drop, it parses the binary file using DataView, extracts the key properties from the standard and .RST headers, and dumps them to a

element on the screen. Only the first 720 bytes are parsed for headers (100 + 80 integers + DOF array). This is browser-compatible and does not require server-side processing.

Drag and drop a .RST file here to dump its properties.


Embed this in your Ghost post using the HTML card. It provides a professional, interactive tool for users to inspect .RST properties.

4. Python Class for .RST File Handling

The following Python class uses the struct module to parse, read, and write .RST files. It focuses on the headers and DOF array for property extraction. To write, it reconstructs the file from properties (basic implementation; full solution sets would require additional logic). Run rst.print_properties() to console-dump all properties.

import struct

class RSTFile:
    def __init__(self, filename=None):
        self.filename = filename
        self.data = None
        self.std_header = None  # List of 100 ints
        self.rst_header = None  # List of 80 ints
        self.dof_array = None
        if filename:
            self.read(filename)

    def read(self, filename):
        with open(filename, 'rb') as f:
            self.data = f.read()
        offset = 0
        # Standard header: 100 i (int32)
        self.std_header = struct.unpack_from('<100i', self.data, offset)
        offset += 400
        # RST header: 80 i
        self.rst_header = struct.unpack_from('<80i', self.data, offset)
        offset += 320
        # DOF array: numdof i
        numdof = self.rst_header[4]
        self.dof_array = struct.unpack_from(f'<{numdof}i', self.data, offset)
        print("RST file loaded successfully.")

    def print_properties(self):
        if not self.std_header or not self.rst_header:
            print("No data loaded. Call read() first.")
            return
        print("Standard Header Properties:")
        print(f"File Number: {self.std_header[0]}")
        print(f"File Format: {self.std_header[1]}")
        print(f"Creation Time: {self.std_header[2]}")
        print(f"Creation Date: {self.std_header[3]}")
        print(f"Unit System: {self.std_header[4]}")
        print(f"Release Level: {self.std_header[9]}")
        max_len = (self.std_header[97] << 32) | self.std_header[96]
        print(f"Maximum File Length: {max_len}")
        print("\nRST Header Properties:")
        print(f"Max Node: {self.rst_header[1]}")
        print(f"Num Nodes: {self.rst_header[2]}")
        print(f"Max Datasets: {self.rst_header[3]}")
        print(f"DOFs per Node: {self.rst_header[4]}")
        print(f"Max Element: {self.rst_header[5]}")
        print(f"Num Elements: {self.rst_header[6]}")
        print(f"Analysis Type: {self.rst_header[7]}")
        print(f"Num Datasets: {self.rst_header[8]}")
        print(f"Unit System: {self.rst_header[20]}")
        print(f"Complex Flag: {self.rst_header[31]}")
        print(f"Precision Key: {self.rst_header[29]}")
        print(f"Available Data Bits: {self.rst_header[34]}")
        print(f"XFEM Key: {self.rst_header[37]}")
        print(f"Global Nodes: {self.rst_header[39]}")
        print("\nDOF Array:")
        print(self.dof_array)

    def write(self, filename):
        if not self.std_header or not self.rst_header or not self.dof_array:
            raise ValueError("No data to write. Load properties first.")
        numdof = len(self.dof_array)
        # Pack standard header
        std_packed = struct.pack('<100i', *self.std_header)
        # Pack RST header (ensure numdof matches)
        rst_packed = struct.pack('<80i', *self.rst_header)
        # Pack DOF
        dof_packed = struct.pack(f'<{numdof}i', *self.dof_array)
        with open(filename, 'wb') as f:
            f.write(std_packed)
            f.write(rst_packed)
            f.write(dof_packed)
            # Append remaining data if available (stub for full write)
            if self.data:
                f.write(self.data[720:])  # Skip parsed part
        print(f"RST file written to {filename}.")

# Example usage:
# rst = RSTFile("sample.rst")
# rst.print_properties()
# # To write: rst.write("output.rst")

5. Java Class for .RST File Handling

The following Java class uses DataInputStream for little-endian int reads. It parses the headers and DOF array, prints properties to console, and supports basic write reconstruction. Compile and run with java RSTFile sample.rst.

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

public class RSTFile {
    private String filename;
    private int[] stdHeader = new int[100];
    private int[] rstHeader = new int[80];
    private int[] dofArray;

    public RSTFile(String filename) {
        this.filename = filename;
        read(filename);
    }

    public void read(String filename) {
        try (DataInputStream dis = new DataInputStream(new FileInputStream(filename))) {
            // Standard header: 100 int32 LE
            for (int i = 0; i < 100; i++) {
                stdHeader[i] = dis.readInt();
            }
            // RST header: 80 int32 LE
            for (int i = 0; i < 80; i++) {
                rstHeader[i] = dis.readInt();
            }
            // DOF array
            int numdof = rstHeader[4];
            dofArray = new int[numdof];
            for (int i = 0; i < numdof; i++) {
                dofArray[i] = dis.readInt();
            }
            System.out.println("RST file loaded successfully.");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void printProperties() {
        if (stdHeader[0] == 0) {
            System.out.println("No data loaded. Call read() first.");
            return;
        }
        System.out.println("Standard Header Properties:");
        System.out.println("File Number: " + stdHeader[0]);
        System.out.println("File Format: " + stdHeader[1]);
        System.out.println("Creation Time: " + stdHeader[2]);
        System.out.println("Creation Date: " + stdHeader[3]);
        System.out.println("Unit System: " + stdHeader[4]);
        System.out.println("Release Level: " + stdHeader[9]);
        long maxLen = ((long) stdHeader[97] << 32) | (stdHeader[96] & 0xFFFFFFFFL);
        System.out.println("Maximum File Length: " + maxLen);
        System.out.println("\nRST Header Properties:");
        System.out.println("Max Node: " + rstHeader[1]);
        System.out.println("Num Nodes: " + rstHeader[2]);
        System.out.println("Max Datasets: " + rstHeader[3]);
        System.out.println("DOFs per Node: " + rstHeader[4]);
        System.out.println("Max Element: " + rstHeader[5]);
        System.out.println("Num Elements: " + rstHeader[6]);
        System.out.println("Analysis Type: " + rstHeader[7]);
        System.out.println("Num Datasets: " + rstHeader[8]);
        System.out.println("Unit System: " + rstHeader[20]);
        System.out.println("Complex Flag: " + rstHeader[31]);
        System.out.println("Precision Key: " + rstHeader[29]);
        System.out.println("Available Data Bits: " + rstHeader[34]);
        System.out.println("XFEM Key: " + rstHeader[37]);
        System.out.println("Global Nodes: " + rstHeader[39]);
        System.out.println("\nDOF Array:");
        for (int dof : dofArray) {
            System.out.print(dof + " ");
        }
        System.out.println();
    }

    public void write(String outputFilename) {
        if (stdHeader[0] == 0) {
            throw new IllegalStateException("No data to write.");
        }
        try (DataOutputStream dos = new DataOutputStream(new FileOutputStream(outputFilename))) {
            // Write standard header
            ByteBuffer bb = ByteBuffer.allocate(400).order(ByteOrder.LITTLE_ENDIAN);
            for (int val : stdHeader) {
                bb.putInt(val);
            }
            dos.write(bb.array());
            // Write RST header
            bb = ByteBuffer.allocate(320).order(ByteOrder.LITTLE_ENDIAN);
            for (int val : rstHeader) {
                bb.putInt(val);
            }
            dos.write(bb.array());
            // Write DOF
            bb = ByteBuffer.allocate(dofArray.length * 4).order(ByteOrder.LITTLE_ENDIAN);
            for (int val : dofArray) {
                bb.putInt(val);
            }
            dos.write(bb.array());
            // Append remaining file if needed (stub)
            System.out.println("Basic headers written to " + outputFilename + ". Full write requires additional data.");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        if (args.length < 1) {
            System.out.println("Usage: java RSTFile <filename.rst>");
            return;
        }
        RSTFile rst = new RSTFile(args[0]);
        rst.printProperties();
        // rst.write("output.rst");
    }
}

6. JavaScript Class for .RST File Handling (Node.js)

The following Node.js class uses fs for file I/O and Buffer for binary parsing (little-endian). It reads, decodes, prints properties to console, and supports write. Run with node rstfile.js sample.rst.

const fs = require('fs');

class RSTFile {
  constructor(filename = null) {
    this.filename = filename;
    this.stdHeader = null;
    this.rstHeader = null;
    this.dofArray = null;
    if (filename) {
      this.read(filename);
    }
  }

  read(filename) {
    const buffer = fs.readFileSync(filename);
    let offset = 0;
    // Standard header: 100 int32 LE
    this.stdHeader = [];
    for (let i = 0; i < 100; i++) {
      this.stdHeader.push(buffer.readInt32LE(offset));
      offset += 4;
    }
    // RST header: 80 int32 LE
    this.rstHeader = [];
    for (let i = 0; i < 80; i++) {
      this.rstHeader.push(buffer.readInt32LE(offset));
      offset += 4;
    }
    // DOF array
    const numdof = this.rstHeader[4];
    this.dofArray = [];
    for (let i = 0; i < numdof; i++) {
      this.dofArray.push(buffer.readInt32LE(offset));
      offset += 4;
    }
    console.log('RST file loaded successfully.');
  }

  printProperties() {
    if (!this.stdHeader || !this.rstHeader) {
      console.log('No data loaded. Call read() first.');
      return;
    }
    console.log('Standard Header Properties:');
    console.log(`File Number: ${this.stdHeader[0]}`);
    console.log(`File Format: ${this.stdHeader[1]}`);
    console.log(`Creation Time: ${this.stdHeader[2]}`);
    console.log(`Creation Date: ${this.stdHeader[3]}`);
    console.log(`Unit System: ${this.stdHeader[4]}`);
    console.log(`Release Level: ${this.stdHeader[9]}`);
    const maxLen = (BigInt(this.stdHeader[97]) << 32n) | BigInt(this.stdHeader[96]);
    console.log(`Maximum File Length: ${maxLen}`);
    console.log('\nRST Header Properties:');
    console.log(`Max Node: ${this.rstHeader[1]}`);
    console.log(`Num Nodes: ${this.rstHeader[2]}`);
    console.log(`Max Datasets: ${this.rstHeader[3]}`);
    console.log(`DOFs per Node: ${this.rstHeader[4]}`);
    console.log(`Max Element: ${this.rstHeader[5]}`);
    console.log(`Num Elements: ${this.rstHeader[6]}`);
    console.log(`Analysis Type: ${this.rstHeader[7]}`);
    console.log(`Num Datasets: ${this.rstHeader[8]}`);
    console.log(`Unit System: ${this.rstHeader[20]}`);
    console.log(`Complex Flag: ${this.rstHeader[31]}`);
    console.log(`Precision Key: ${this.rstHeader[29]}`);
    console.log(`Available Data Bits: ${this.rstHeader[34]}`);
    console.log(`XFEM Key: ${this.rstHeader[37]}`);
    console.log(`Global Nodes: ${this.rstHeader[39]}`);
    console.log('\nDOF Array:');
    console.log(this.dofArray.join(' '));
  }

  write(filename) {
    if (!this.stdHeader || !this.rstHeader || !this.dofArray) {
      throw new Error('No data to write. Load properties first.');
    }
    const numdof = this.dofArray.length;
    let buffer = Buffer.alloc(400);
    for (let i = 0; i < 100; i++) {
      buffer.writeInt32LE(this.stdHeader[i], i * 4);
    }
    let rstBuffer = Buffer.alloc(320);
    for (let i = 0; i < 80; i++) {
      rstBuffer.writeInt32LE(this.rstHeader[i], i * 4);
    }
    let dofBuffer = Buffer.alloc(numdof * 4);
    for (let i = 0; i < numdof; i++) {
      dofBuffer.writeInt32LE(this.dofArray[i], i * 4);
    }
    fs.writeFileSync(filename, Buffer.concat([buffer, rstBuffer, dofBuffer]));
    console.log(`RST file written to ${filename}.`);
  }
}

// Example usage
if (require.main === module) {
  if (process.argv.length < 3) {
    console.log('Usage: node rstfile.js <filename.rst>');
    process.exit(1);
  }
  const rst = new RSTFile(process.argv[2]);
  rst.printProperties();
  // rst.write('output.rst');
}

7. C Class for .RST File Handling

The following C code defines a struct-based "class" with functions for read, print, and write. It uses fread and fwrite for binary I/O (little-endian assumed via byte order handling; use htole32 if needed). Compile with gcc rstfile.c -o rstfile. Run ./rstfile sample.rst.

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

#define STD_HEADER_SIZE 100
#define RST_HEADER_SIZE 80

typedef struct {
    int32_t std_header[STD_HEADER_SIZE];
    int32_t rst_header[RST_HEADER_SIZE];
    int32_t *dof_array;
    int num_dof;
    char *filename;
} RSTFile;

void rst_read(RSTFile *rst, const char *filename) {
    FILE *f = fopen(filename, "rb");
    if (!f) {
        perror("Error opening file");
        return;
    }
    rst->filename = strdup(filename);
    // Read standard header
    fread(rst->std_header, sizeof(int32_t), STD_HEADER_SIZE, f);
    // Read RST header
    fread(rst->rst_header, sizeof(int32_t), RST_HEADER_SIZE, f);
    // Read DOF array
    rst->num_dof = rst->rst_header[4];
    rst->dof_array = malloc(rst->num_dof * sizeof(int32_t));
    fread(rst->dof_array, sizeof(int32_t), rst->num_dof, f);
    fclose(f);
    printf("RST file loaded successfully.\n");
}

void rst_print_properties(RSTFile *rst) {
    if (rst->std_header[0] == 0) {
        printf("No data loaded. Call rst_read() first.\n");
        return;
    }
    printf("Standard Header Properties:\n");
    printf("File Number: %d\n", rst->std_header[0]);
    printf("File Format: %d\n", rst->std_header[1]);
    printf("Creation Time: %d\n", rst->std_header[2]);
    printf("Creation Date: %d\n", rst->std_header[3]);
    printf("Unit System: %d\n", rst->std_header[4]);
    printf("Release Level: %d\n", rst->std_header[9]);
    uint64_t max_len = ((uint64_t)rst->std_header[97] << 32) | rst->std_header[96];
    printf("Maximum File Length: %lu\n", max_len);
    printf("\nRST Header Properties:\n");
    printf("Max Node: %d\n", rst->rst_header[1]);
    printf("Num Nodes: %d\n", rst->rst_header[2]);
    printf("Max Datasets: %d\n", rst->rst_header[3]);
    printf("DOFs per Node: %d\n", rst->rst_header[4]);
    printf("Max Element: %d\n", rst->rst_header[5]);
    printf("Num Elements: %d\n", rst->rst_header[6]);
    printf("Analysis Type: %d\n", rst->rst_header[7]);
    printf("Num Datasets: %d\n", rst->rst_header[8]);
    printf("Unit System: %d\n", rst->rst_header[20]);
    printf("Complex Flag: %d\n", rst->rst_header[31]);
    printf("Precision Key: %d\n", rst->rst_header[29]);
    printf("Available Data Bits: %d\n", rst->rst_header[34]);
    printf("XFEM Key: %d\n", rst->rst_header[37]);
    printf("Global Nodes: %d\n", rst->rst_header[39]);
    printf("\nDOF Array:\n");
    for (int i = 0; i < rst->num_dof; i++) {
        printf("%d ", rst->dof_array[i]);
    }
    printf("\n");
}

void rst_write(RSTFile *rst, const char *output_filename) {
    if (rst->std_header[0] == 0) {
        fprintf(stderr, "No data to write.\n");
        return;
    }
    FILE *f = fopen(output_filename, "wb");
    if (!f) {
        perror("Error writing file");
        return;
    }
    // Write standard header
    fwrite(rst->std_header, sizeof(int32_t), STD_HEADER_SIZE, f);
    // Write RST header
    fwrite(rst->rst_header, sizeof(int32_t), RST_HEADER_SIZE, f);
    // Write DOF
    fwrite(rst->dof_array, sizeof(int32_t), rst->num_dof, f);
    fclose(f);
    printf("Basic headers written to %s.\n", output_filename);
}

void rst_free(RSTFile *rst) {
    free(rst->dof_array);
    free(rst->filename);
}

int main(int argc, char **argv) {
    if (argc < 2) {
        printf("Usage: %s <filename.rst>\n", argv[0]);
        return 1;
    }
    RSTFile rst = {0};
    rst_read(&rst, argv[1]);
    rst_print_properties(&rst);
    // rst_write(&rst, "output.rst");
    rst_free(&rst);
    return 0;
}