C and CMake
The native reader is a versioned C11 ABI. Building with Python disabled does not enable a C++ compiler:
cmake -S . -B build-c \
-DOMNI_MAPDL_BUILD_PYTHON=OFF \
-DOMNI_MAPDL_BUILD_TESTING=ON
cmake --build build-c --config Release
ctest --test-dir build-c --output-on-failure
Installed consumers use the exported CMake package. The public header is safe to include from C++ because its declarations have C linkage.
find_package(OmniMapdlInterop CONFIG REQUIRED)
target_link_libraries(my_reader PRIVATE OmniMapdl::interop)
This ABI is a read-only interoperability surface in v0.1.0. It provides a
lossless record stream, checked fixed-field conversion, resolved bulk mesh
projection, and documented binary-record access. The Python layer owns
semantic model construction and deterministic .dat/.cdb writing. This
division keeps the native hot path small and does not imply a C APDL runtime or
a C semantic writer.
Binary calls address one physical file at a time. Distributed-result sibling files are not implicitly discovered by the C ABI; their exposed node and element IDs are the merge keys. The retained high-level Python reader provides the convenience multi-file assembly.
#include <omni_solver_interop_mapdl/capi.h>
omni_mapdl_deck_reader *reader = NULL;
omni_mapdl_deck_record record;
if (omni_mapdl_capi_version() != OMNI_MAPDL_CAPI_VERSION) {
return 2; /* header/library mismatch */
}
if (omni_mapdl_deck_open("ds.dat", &reader) == OMNI_MAPDL_OK) {
while (omni_mapdl_deck_next(reader, &record) == OMNI_MAPDL_OK) {
/* record.line is borrowed; copy only data the application retains. */
}
omni_mapdl_deck_close(reader);
}
Function families
| Need | Entry points | Data and ownership |
|---|---|---|
| Physical text lines | omni_mapdl_text_open, omni_mapdl_text_next, omni_mapdl_text_rewind |
omni_mapdl_line; its data span is borrowed until the next read |
| Lossless deck records | omni_mapdl_deck_open, omni_mapdl_deck_next, omni_mapdl_deck_rewind |
omni_mapdl_deck_record; each physical line is classified once and unknown commands remain visible |
| Command tokenization | omni_mapdl_split_fields, omni_mapdl_split_statements |
Caller-supplied omni_mapdl_span storage; quoted commas, parentheses, empty fields, and $ statements are preserved |
| Fixed-format conversion | omni_mapdl_parse_fixed_format, omni_mapdl_fixed_spans, omni_mapdl_span_i64, omni_mapdl_span_f64 |
Caller-owned descriptors and spans; integer and D/E real conversion is checked |
| Resolved mesh | omni_mapdl_mesh_read and omni_mapdl_mesh_* accessors |
Nodes, elements, CSR connectivity, and numeric BFBLOCK values owned by the mesh handle |
| Generic binary records | omni_mapdl_binary_open, omni_mapdl_binary_record_at, omni_mapdl_binary_decode_record |
Zero-copy record view or aligned caller-owned decode buffer |
| Result headers and sets | omni_mapdl_binary_read_*header, omni_mapdl_binary_result_set_pointer |
Caller-owned typed header structures |
| Result geometry and nodal values | omni_mapdl_binary_read_result_nodes, omni_mapdl_binary_read_result_elements, omni_mapdl_binary_read_result_nodal_solution |
Caller node buffer or dedicated elements/nodal-values handle |
| Element-result locations | omni_mapdl_binary_locate_result_element_solution and plural form |
Caller-owned stable 26-slot ESL location structures; an absent per-element pointer is an all-zero row and values are not interpreted |
| FULL matrices | omni_mapdl_binary_read_full_matrix and omni_mapdl_sparse_matrix_* |
Zero-based stored COO arrays owned by the sparse-matrix handle |
| EMAT locations | omni_mapdl_binary_read_emat_header, omni_mapdl_binary_read_emat_element_header, omni_mapdl_binary_locate_emat_element |
Caller-owned published header and record-location structures |
The
capi.h
header is the complete declaration and structure reference.
Lifetimes and buffers
Every handle returned by an open or read operation has a matching close
function. Mesh arrays remain valid until omni_mapdl_mesh_close.
Result-element, nodal-value, and sparse-matrix arrays remain valid until their
corresponding *_close call. A binary record view remains borrowed from its
binary reader until omni_mapdl_binary_close.
Functions that return variable-length data through a caller buffer use the
capacity arguments in the header. For binary record decoding, call
omni_mapdl_binary_decode_record first with out_data == NULL and a zero
capacity to obtain the required item count and scalar type, allocate a suitably
aligned buffer, and call again. The bulk element-location function follows the
same query-then-fill pattern through out_count.
Status and diagnostics
Operations return omni_mapdl_status. OMNI_MAPDL_OK means success and
OMNI_MAPDL_END is the normal end of a text or deck stream. Other status values
distinguish invalid arguments, I/O, allocation, binary input supplied to a text
reader, field overflow, unsupported encoding, range, buffer-capacity, and
malformed-record errors. omni_mapdl_status_string gives a static description;
reader-specific detail is available from omni_mapdl_text_error, omni_mapdl_deck_error,
omni_mapdl_mesh_error, or omni_mapdl_binary_error while the handle lives.
OMNI_MAPDL_CAPI_VERSION is the compile-time ABI number and
omni_mapdl_capi_version() is the loaded library's number. Compare them before
using a dynamically discovered library. Equality is the compatibility check
exposed by this API; callers should not assume different ABI numbers are
compatible.
Completeness and fail-closed behavior
omni_mapdl_mesh_body_loads_complete() is true only when every BFBLOCK used
the published numeric form and was projected. If it is false, use the lossless
deck stream for the unprojected records. The deck stream classifies unknown and
forward-version commands but never executes APDL. Generic binary decoding
reports compression flags and rejects zlib records because the public
file-layout documentation does not publish that payload envelope.