Skip to content

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.