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).

  • SuperLUscipy’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.)