MAPDL interop#

femorph-solver is a general-purpose structural solver with a secondary MAPDL compatibility layer. If your starting point is a MAPDL workflow (a CDB deck, an RST result, an APDL-style declaration sequence), this page is where to start. If you’re building from scratch, use the native Model primitives shown in the Quickstart — they’re the primary API and will stay so.

Equivalent compatibility layers ship for NASTRAN BDF (femorph_solver.interop.nastran), Abaqus INP (femorph_solver.interop.abaqus), and Altair OptiStruct FEM (femorph_solver.interop.optistruct). This page focuses on MAPDL because it’s the most-frequently-exercised path and the one with the deepest binary-format coverage; the BDF / INP / FEM readers follow the same boundary-translation pattern.

The deep dive on MAPDL format compatibility lives in MAPDL compatibility.

Load a CDB deck#

One call (from_cdb) reads MAPDL’s ASCII deck format and returns a Model ready to assemble:

from femorph_solver.interop.mapdl import from_cdb

model = from_cdb("rotor_sector.cdb")
result = model.modal_solve(n_modes=12)

The CDB’s ET table is translated on load — every element id declared with ET, i, SOLID186 is registered against the HEX20 kernel automatically. /UNITS is detected and stamped onto model.unit_system. mapdl-archive (MIT) handles the parse; MAPDL itself is never invoked.

APDL-style declaration commands#

When porting a deck line-by-line, the femorph_solver.interop.mapdl.APDL wrapper exposes the APDL command set one-for-one. MAPDL element catalogue names ("SOLID185" etc.) are translated to their neutral kernel counterparts at this boundary; nothing downstream sees foreign-deck spelling.

APDL

Native equivalent

Notes

ET, id, name

apdl.et(id, name)

MAPDL catalogue names are rewritten to neutral kernel names ("SOLID185""HEX8" etc.) at this entry point.

MP, prop, mat_id, value

apdl.mp(prop, mat_id, value)

One property at a time. Prefer assign() for native code.

R, id, v1, v2,

apdl.r(id, v1, v2, …)

Real-constant arrays.

D, node, label, value

apdl.d(node, label, value)

Native shortcut: fix().

F, node, label, value

apdl.f(node, label, value)

Native shortcut: apply_force().

An APDL-literal quickstart equivalent:

import femorph_solver as fs
from femorph_solver.interop.mapdl import APDL

model = fs.Model.from_grid(fs.examples.quarter_arc_sector())

with APDL(model) as apdl:
    # APDL-literal declaration; SOLID185 is rewritten to HEX8 here.
    apdl.et(1, "SOLID185")              # ET, 1, SOLID185
    apdl.mp("EX",   1, 2.1e11)          # MP, EX,   1, 2.1e11
    apdl.mp("PRXY", 1, 0.30)            # MP, PRXY, 1, 0.30
    apdl.mp("DENS", 1, 7850.0)          # MP, DENS, 1, 7850.0

    # One D per pinned node — hence why the native `fix(where=...)`
    # is preferable when not porting from an APDL macro.
    for nn in (1, 2, 3, 4):
        apdl.d(nn, "ALL", 0.0)          # D, nn, ALL, 0

result = model.modal_solve(n_modes=10)

The wrapper and the native Model primitives share state, so mixing styles is allowed; the test test_native_api_equivalent_to_mapdl_verbs pins round-trip equivalence.

Format status#

Format

Read

Write

Notes

CDB

Via mapdl-archive. Supports SOLID185/186/187 → HEX8 / HEX20 / TET10, SHELL181 → QUAD4_SHELL, BEAM188 → BEAM2, LINK180 → TRUSS2, COMBIN14 → SPRING, MASS21 → POINT_MASS, PLANE182 → QUAD4_PLANE, plus the degenerate SOLID186 wedge / pyramid forms (→ WEDGE15 / PYR13).

RST

🚧

Read via ansys-mapdl-reader; progressive write in femorph_solver.mapdl_api.io.rst_schema.

FULL

🚧

K / M matrix export; femorph_solver.mapdl_api.io.full_schema.

EMAT

🚧

Per-element K / M; femorph_solver.mapdl_api.io.emat_schema.

MODE / SUB / DB

Planned.

Element compatibility#

Each registered element targets the same observable behaviour as its MAPDL counterpart under MAPDL’s default options, so an existing deck modal-spectrum agreement carries over without re-tuning. See the Elements for the per-element migration checks and the Element library for the formulation knobs each kernel exposes.