Solving#

The solve phase turns a pre-processed Model into numbers. femorph-solver exposes five top-level analyses and shares a single backend registry underneath them:

Static

\(K u = F\) — one factorisation, one back-solve. The fastest path, and the pre-stress foundation for everything else.

Static analysis
Modal

\(K \varphi = \omega^2 M \varphi\) — free-vibration eigenpairs via ARPACK / LOBPCG / PRIMME / dense.

Modal analysis
Transient

\(M \ddot{u} + C \dot{u} + K u = F(t)\) — Newmark-β time integration with a one-time factorisation.

Transient analysis
Harmonic

\((K - \omega^2 M + i\omega C)\,u(\omega) = F\) — frequency-response sweeps via modal superposition.

Harmonic (frequency-response) analysis
Cyclic-symmetry modal

One-sector reduction + harmonic-index phase constraints for rotors and other periodic structures.

Cyclic-symmetry modal analysis

Backend and performance#

Choosing a solver

The linear / eigen backend registry, how "auto" picks, and when to override.

Solvers
Performance

Wall-time numbers for assembly, static, and modal across backends and mesh sizes.

Performance
Thread control

BLAS / OpenMP cap via femorph_solver.set_thread_limit(), FEMORPH_SOLVER_NUM_THREADS, and the per-call thread_limit kwarg.

Thread control

Extras#

Solver exploration

In-depth investigation of every sparse SPD direct solver we considered as an alternative to MKL Pardiso — measured results, the NixOS OpenBLAS 0.3.30 bug we hit, why STRUMPACK HSS didn’t land on hex elasticity, and a drop-in MumpsSolver adapter.

Solver exploration (extras)