Linear-solver backends#
Every analysis path that factors a sparse symmetric matrix —
static (\(\mathbf{K}\mathbf{u} = \mathbf{f}\)), modal
(shift-invert \((\mathbf{K} - \sigma \mathbf{M})\)),
cyclic (per-harmonic factor) — dispatches the factorisation
through the linear-solver registry in
femorph_solver.solvers.linear. The registry caches a
preferred-order chain so a missing dependency cleanly falls
through to the next backend without user code changes.
Auto-chain dispatch order#
When the caller passes linear_solver="auto" (the default
for every solver entry point), the registry walks the chain
Pardiso → CHOLMOD → MUMPS → UMFPACK → SuperLU and uses
the first backend whose Python bindings + native library are
both importable at runtime.
Backend-by-backend#
Pardiso (Intel MKL) — multi-threaded supernodal LDLᵀ. The fastest SPD path on x86_64 with MKL installed. Used via
pypardiso. Cite: Schenk, O. and Gärtner, K. (2004) Solving unsymmetric sparse systems of linear equations with PARDISO, Future Generation Computer Systems 20 (3), 475–487.CHOLMOD (SuiteSparse) — supernodal Cholesky for SPD systems. The standard scientific-Python SPD backend (
scikit-sparse); BSD-3. Cite: Chen, Y., Davis, T. A., Hager, W. W. and Rajamanickam, S. (2008) “Algorithm 887: CHOLMOD, supernodal sparse Cholesky factorization and update / downdate,” ACM TOMS 35 (3), Article 22.MUMPS (Multifrontal Massively Parallel Sparse) — multifrontal direct solver with a redistributable license (CeCILL-C). Useful as a Pardiso fallback when MKL isn’t available; ships out-of-core for very large problems (TA-roadmap). Cite: Amestoy, P. R., Duff, I. S., L’Excellent, J.-Y. and Koster, J. (2001) “A fully asynchronous multifrontal solver using distributed dynamic scheduling,” SIAM J. Matrix Anal. Appl. 23 (1), 15–41.
UMFPACK (SuiteSparse) — multifrontal LU for general sparse systems. Used via
scikit-umfpack; useful fallback for non-SPD systems (e.g., the future contact-coupled stiffness).SuperLU —
scipy’s built-in LU solver. The guaranteed-available terminal fallback; pure-Python wheels carry it everywhere SciPy ships.
Selecting an explicit backend#
Every solver entry point that factors a matrix accepts a
linear_solver keyword:
res = model.solve(linear_solver="pardiso")
modal = model.modal_solve(linear_solver="cholmod")
If the named backend isn’t installed, the call raises a
clear RuntimeError listing the backends that are
installed plus a pip install hint for the missing one.
Inspecting the registry#
from femorph_solver.solvers.linear import list_linear_solvers
print(list_linear_solvers())
# → {"pardiso": True, "cholmod": True, "mumps": False,
# "umfpack": False, "superlu": True}
Symmetric vs general#
The current static / modal / cyclic paths assemble symmetric (usually positive-definite) matrices, so the SPD-capable backends (Pardiso, CHOLMOD) win on memory and FLOPs. General- purpose LU backends (UMFPACK, SuperLU) work too — they’re a ~2× memory and FLOP overhead on a symmetric problem because they store both triangles + the L / U factor pair, but they’re the right choice for non-symmetric problems (contact, large- displacement consistent stiffness — both roadmap).
Implementation: femorph_solver.solvers.linear (registry
+ auto-chain) plus per-backend wrappers in
femorph_solver.solvers.linear._pardiso,
femorph_solver.solvers.linear._cholmod, etc.
References#
Davis, T. A. (2006) Direct Methods for Sparse Linear Systems, SIAM (foundational treatment of multifrontal / supernodal methods).
Saad, Y. (2003) Iterative Methods for Sparse Linear Systems, 2nd ed., SIAM, §3 (sparse direct solvers).
George, A. and Liu, J. W. H. (1981) Computer Solution of Large Sparse Positive Definite Systems, Prentice-Hall (envelope / Cholesky theory).
(Per-backend citations live in each wrapper module’s
References block; the top-level cites here orient the
user across the whole chain.)