ds.dat and native C API audit
Date: 2026-09-03
Decision
This repository can be engineered as a clean compatibility shim, but it cannot truthfully promise zero legal risk. Its defensible boundary is public file interfaces and appropriately licensed source: read explicit state from user-controlled files, preserve records that a downstream adapter may need, and never reproduce solver, element, material, meshing, or APDL-runtime behavior. Distribution terms and the exact release commit still require counsel review.
The implementation has two necessary tiers:
- typed neutral records for published, resolved model data; and
- a lossless native record stream for documented commands that do not yet have a neutral type, forward-version commands, and arbitrary Commands object input.
The second tier is not optional. Mechanical explicitly documents that data
and instructions, including Commands object content, are written into
ds.dat. Consequently, no finite command allowlist can describe every valid
ds.dat. Unknown records must remain visible and must never be executed or
silently interpreted.
Primary sources: Mechanical Commands object, coded database commands, and 2025 R2 input-format change.
Exhaustive coded-database coverage
The Programmer's Reference enumerates 27 commands whose CDB representation is special. This table is the admission matrix; ordinary commands continue to use their Command Reference syntax.
| Published coded form | Neutral/Python status | Native C status | Remaining issue |
|---|---|---|---|
BFBLOCK |
typed nodal body loads, numeric/table | C-owned numeric CSR values; lossless block fallback for table/text rows | broader table-row acceptance |
BFEBLOCK |
typed element body loads, numeric/table | same | native columnar load model |
/BLOCK |
ignored framing, reported | command record | none |
CE,UNBL |
typed equations and terms | lossless fields | native typed equation model |
CP,UNBL |
typed coupled sets | lossless fields | native typed coupling model |
CMBLOCK NODE/ELEM |
typed, compact ranges | lossless block records | native range expansion |
CMBLOCK EFACE |
standard names/bitmaps and compact entries retained | lossless multi-phase block records | broader real-file acceptance |
CYCLIC,CDWR |
retained setup | lossless command | target-adapter interpretation only |
DBLOCK |
typed real/imaginary/table constraints | lossless block records | native columnar model |
EBLOCK |
SOLID, plain, continuation, and 2025 R2 COMPACT typed | native typed connectivity/attributes | none for resolved mesh projection |
EN,UNBL |
every ATTR/NODE card retained losslessly | native stateful ATTR/NODE builder | none for resolved mesh projection |
ETBLOCK |
element type and KEYOPT typed | lossless block records | native typed table |
FBLOCK |
typed real/imaginary/table loads | lossless block records | native columnar model |
LOCAL,UNBL |
origin, angles, parameters typed | lossless fields | native typed model |
M,UNBL |
losslessly retained | lossless fields | neutral master-DOF type |
MPDATA,UNBL |
typed material tables | lossless fields | native typed table |
MPTEMP,UNBL |
typed temperature locations | lossless fields | native typed table |
N,UNBL |
LOC and ANG typed | native direct-node arrays | none for LOC/ANG projection |
NBLOCK |
coordinates/rotations and Workbench short form typed | native typed node arrays | component membership remains in lossless stream |
NSMBLOCK |
eight published payload slots retained per element | lossless block records | resolve documentation's 7-field/8-descriptor inconsistency |
*PREAD |
typed scalar/string parameter arrays | lossless block records | native typed arrays |
R,UNBL |
typed positional real constants | lossless fields | native typed arrays |
RLBLOCK |
typed continuation records | lossless two-format block records | native typed arrays |
SE,UNBL |
losslessly retained external superelement reference | lossless fields | no .sub interpretation claim yet |
SECBLOCK |
shell and user-meshed beam blocks typed positionally; reinforcing retained by header/count | lossless block records | reinforcing Format2 state machine |
SFBEAM |
header offsets and following four-value row typed | lossless header/data records | native typed load model |
SFE,UNBL |
typed header and following value row | lossless header/data records | native typed load model |
SFEBLOCK |
typed numeric/table surface loads | lossless block records | native columnar load model |
The EFACE and NSMBLOCK additions are forward-version features supported from
their current public layouts. They are not represented as MAPDL v15 syntax.
The 2025 R2 Mechanical release notes specifically identify compact CMBLOCK
and EBLOCK as new ds.dat output forms.
Native architecture and performance
The CMake build now produces OmniMapdl::interop from C11 sources without a
Python or C++ requirement. The installed package exports a versioned CMake
config and public header. A standalone consumer configure/build/run test has
passed against the installed tree.
The C ABI presently includes:
- zero-copy
mmaptext scanning on POSIX and a bounded growing buffer on Windows; - lossless deck record classification for fixed-format blocks, EFACE's two
representations, following-line load records,
*PREAD, and unknown future commands; - allocation-free comma-field and
$-statement spans; - compiled nested Fortran descriptors such as
(3i9,6e21.13e3)and(i10,8(pg20.9)), plus checked integer andD/Ereal conversion; - bounds-checked, byte-order-aware binary record views; and
- caller-buffer decoding for dense, bit-sparse, and window-sparse scalar records;
- C-owned contiguous mesh and CSR-connectivity arrays for direct and blocked node
and element records, numeric
BFBLOCKbody-load CSR values, and literal Workbench pointer parameters; and - typed standard/result/geometry/solution, FULL, EMAT, and EMAT-element headers, result LOC nodes, EID elements, NSL nodal values, exact stored real or complex symbolic FULL COO matrices, result ESL element-record locations, and documented EMAT element-record locations.
On the transient public issue-401 Workbench deck (31,414,882 bytes excluding line endings; 374,487 records), warm-cache local measurements were:
| Path | Wall time | Approximate throughput | Meaning |
|---|---|---|---|
| raw C line scan | 0.010-0.012 s | 2.6-3.1 GB/s | line boundaries and command token only |
| C deck/block classification | 0.053-0.064 s | 0.49-0.59 GB/s | all records classified, no neutral allocation |
| C native mesh projection | 0.130-0.145 s | 217-242 MB/s | 149,203 nodes, 107,564 elements, 1,075,640 connectivity IDs |
| Python semantic neutral parse | 0.881 s median | 36.5 MB/s | 149,203 node and 107,564 element objects plus all setup |
These are cached measurements on one machine, not product guarantees. They show that I/O/tokenization is already fast and that Python object construction is the dominant cost.
Private acceptance inputs contribute no published size, topology, or timing. The semantic path constructs and validates Python objects; consumers that need maximum ingestion speed can remain on the public C arrays.
Binary-family boundary
Ansys publicly documents the standard 100-integer header and the record maps
for results and matrix families. The official Programmer's Reference lists
.rst, .rth, .rmg, .mode, .rdsp, .rfrq, .emat, .sub, .cms,
.tcms, .full, and .dsub. The present high-level Python surface is limited
to .rst, .rth, .full, and .emat, matching the reused MIT reader subset.
The native C layer now decodes the published standard and family headers,
result-set and geometry pointers, result LOC nodes, EID element descriptions,
NSL values, ESL element-result locations, real/complex symbolic FULL row/value
pairs, and EMAT IDX/EHD record sequences. It is bounds checked and does not
accept .db. Applicable public MIT-reader fixtures and the confidential
predecessor gate exercised each of these paths; native projections agreed with
the retained licensed reader wherever a documented record was present. No
confidential corpus statistics or identifiers are retained here. Positive-fun04
FULL bodies are deliberately rejected
because the current Programmer's Reference says they use frontal assembly but
does not publish that body layout.
Zlib compression remains an explicit gap: /FCOMP documents that zlib levels
exist and directs third-party readers to BINLIB, but it does not publish the
compressed payload envelope. The current public EMAT chapter likewise says
that substructure-matrix EMAT records use an alternate, undocumented format.
Neither form is inferred from sample files. Published complex FULL values are
surfaced as separate real and imaginary arrays in the language-neutral C ABI.
Sources: binary-file overview, results-file format, binary access routines, /FCOMP, and MIT PyMAPDL Reader.
Known boundaries and release controls
The native interoperability contract is complete at the record layer: a pure-C consumer can stream every text record, identify all published special CDB payloads, split ordinary commands and fields, decode their documented fixed formats, and access all supported binary records without Python or C++. Typed C-owned mesh and major binary projections cover the high-volume paths. The Python neutral model provides optional convenience projections for the many lower-volume model-state commands; this is layering, not a requirement to reimplement an APDL runtime in C.
The following boundaries and hardening work must remain explicit:
- Additional C-owned columnar projections for element types, materials,
sections, constraints, non-
BFBLOCKloads, couplings, and components would reduce work for specialized C consumers, but their records are already losslessly available through the C ABI and typed by the optional Python neutral layer. - Some high-level element-result and EMAT-value conveniences remain in the retained MIT Python/C++ reader. Pure-C callers already have the documented record locations and generic decoded-record API needed to consume them.
- Positive-
fun04frontal FULL, substructure-matrix EMAT, and zlib record envelopes remain rejected unless a public layout or appropriately licensed implementation source becomes available. - Reinforcing-element
SECBLOCKFormat2 remains lossless rather than typed until the public documentation defines more than its negative element-ID start flag. Example files must not be used to infer the missing continuation length or fields. - Persistent fuzz/property lanes and benchmark thresholds tied to repeatable hardware remain optional hardening. The current AddressSanitizer/UndefinedBehaviorSanitizer C suite, build-tree and installed-tree CMake consumer checks, and Linux/Windows native wheel builds pass.
- License, secret, absolute-path, and artifact-manifest scans must run on the exact release commit. Counsel must review the intended commercial distribution and the applicable customer/vendor agreements; engineering controls cannot guarantee zero legal risk.
Acceptance and provenance rules
- Commit only project-authored synthetic text and binary fixtures, clearly labeled as such.
- A v15 binary may be retained only when generated from an independently authored synthetic deck, its generation recipe and ownership are recorded, and its redistribution is approved. Current v15 result artifacts remain transient.
- Public and customer decks are acceptance inputs, not specifications and not redistribution candidates unless their licenses expressly permit it.
- Customer details, paths, hashes, snippets, or derived model fragments never enter tests or documentation. Recreate only the abstract documented edge case as a synthetic record.
- Offline side-by-side runs test file acceptance only. Numerical output must never select a formulation, constant, tolerance, or algorithm.
Claim-to-source ledger
| Claim | Evidence |
|---|---|
| Special CDB command inventory and fields | Ansys, Programmer's Reference, Coded Database File Commands, accessed 2026-09-03 |
| Arbitrary Commands object content enters ds.dat | Ansys, Mechanical User's Guide, Commands Object, accessed 2026-09-03 |
| Compact CMBLOCK/EBLOCK are 2025 R2 ds.dat changes | Ansys, Mechanical Application Release Notes, Changes in Product Behavior, accessed 2026-09-03 |
| Binary-family standard header and formats | Ansys, Programmer's Reference, Understanding Mechanical APDL Binary Files, accessed 2026-09-03 |
| Results record organization | Ansys, Programmer's Reference, Description of the Results File, accessed 2026-09-03 |
| EMAT IDX/EHD/matrix sequence and undocumented substructure exception | Ansys, Programmer's Reference, Description of the Element Matrices File, accessed 2026-09-03 |
Symbolic FULL row/value sequence and non-published positive-fun04 body |
Ansys, Programmer's Reference, Description of the Full Stiffness-Mass File, accessed 2026-09-03 |
| Public third-party binary access surface | Ansys, Programmer's Reference, Accessing Mechanical APDL Binary Files, accessed 2026-09-03 |
| Compression behavior and zlib levels | Ansys, Command Reference, /FCOMP, accessed 2026-09-03 |
| Reused reader file support and license | Ansys, PyMAPDL Reader, accessed 2026-09-03 |