Skip to content

CalculiX external-behaviour target: dlopen'd .so plugin (no ccx recompile) - #126

Closed
petlenz wants to merge 2 commits into
feature-calculix-umat-targetfrom
feature-calculix-external
Closed

CalculiX external-behaviour target: dlopen'd .so plugin (no ccx recompile)#126
petlenz wants to merge 2 commits into
feature-calculix-umat-targetfrom
feature-calculix-external

Conversation

@petlenz

@petlenz petlenz commented Aug 1, 2026

Copy link
Copy Markdown
Member

Stacked on #125. Adds CalculiXExternalTarget (make_target("calculix_external")) — emits <Model>_ext.cpp compiling to lib<MODEL>.so that CalculiX loads at runtime via dlopen, so adding a new material needs no ccx recompile (build ccx once with external support; select materials by name in the deck).

Mechanism (verified against ccx 2.22 source)

A deck *MATERIAL, NAME=@<LIB>_<FUNC> makes ccx (which uppercases the name) dlopen("lib<LIB>.so") and dlsym("<FUNC>") (external.c, gated on -DCALCULIX_EXTERNAL_BEHAVIOURS_SUPPORT + -ldl). The STANDARD interface passes native quantities under Abaqus-flavored names — STRAN1 = emec (tensorial), STRESS = stre, DDSDDE = stiff(21) packed — so the same abq_std boundary as the compiled-in target (#125) reuses verbatim. The emitted plugin follows a per-thread lifecycle: a thread_local material instance built once per thread (ccx runs the element loop multithreaded), then per-call unpack → evaluate → pack.

Verification

  • In-repo gate (no deps): calculix_check_driver gains 3 tests that call the emitted NCG_UMAT through the exact calculixptr ABI and check stre/stiff against the isotropic oracle, plus an equivalence test proving the external entry matches the compiled-in umat_user_ bit-for-bit. Full suite 272/272.
  • Real ccx run: examples/calculix/build_and_run_external.sh builds ccx once with external support, compiles the codegen'd .so, and runs uniaxial_c3d8_external.inp by @-name. Confirmed S11=0.027, S22=S33=0.013 — same result as the compiled-in path, with no ccx recompile.

Scope

Stateless (elastic) — same guards as #125. The STATEV round-trip for stateful J2 (numsim-materials-backed evaluate()) is the next step; the thread_local /per-call scaffold is already in place for it.

🤖 Generated with Claude Code

@petlenz

petlenz commented Aug 1, 2026

Copy link
Copy Markdown
Member Author

Consolidated into a single PR against main (external .so target only).

@petlenz petlenz closed this Aug 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant