Best practices and troubleshooting#

A compact field guide for the things that go wrong on real models. Most FEA bugs aren’t bugs in the solver — they’re mis-specified BCs, marginal mesh quality, or a poorly-conditioned matrix the user didn’t realise was poorly conditioned. This chapter catalogues the patterns and how to diagnose each.

Pages:

Where to start when something looks wrong:

  1. Sanity-check the BCsBoundary-condition pitfalls. An under- constrained model produces enormous displacement nonsense; an over-constrained one produces artificial stiffness. Run a 6-mode modal solve on the un-loaded model: the rigid-body modes you find tell you exactly which constraints are missing or extra.

  2. Check the meshMesh quality. HEX8 with EAS tolerates moderate distortion but degenerates near-Jacobian- zero. TET10 / HEX20 are more robust but cost more per DOF.

  3. Look at the solver’s conditioning reportConditioning and performance. A condition number above ~1e10 is a red flag; the cause is almost always a BC or mesh issue, not a solver bug.

  4. If results look right but feel slow, see the performance section in the same page — switching from MUMPS to Pardiso or CHOLMOD can cut large-model solve time by 2-5×.

  5. When all else fails, walk the diagnostic flowchart in Troubleshooting flowchart — it’s a decision tree that catches the recurring failure modes in <5 questions.

Best solver, by analysis (TL;DR)#

Picked from the cross-vendor PBS-rotor benches. Both decisions beat MAPDL on the same mesh + thread budget on this workload.

  • Simple modal (Model.solve_modal) — let the autotune pick: it always returns ARPACK now, paired with the best available SPD direct backend (mkl_directpardisocholmodmumpssuperlu). ARPACK + mkl_direct beats MAPDL Block Lanczos by 25 % at 8 threads on the 494,766-DOF PBS sector. See PBS rotor — solver head-to-head at 8 threads.

  • Cyclic-symmetry modal (CyclicModel.modal_solve / solve_cyclic) — pass eigen_solver="primme", linear_solver="pardiso". PRIMME’s JDQMR amortises the Pardiso factor across the harmonic ladder; 2.5× faster than ARPACK on the same workload at +3.6 % memory. Install via pip install primme (sdist build) or the prebuilt manylinux wheel from femorph/pprime. See PBS rotor — cyclic-modal sweep at 8 threads.

  • Shared / multi-tenant host — add subprocess_isolated="auto" to solve_modal / solve_cyclic calls. The autotune gate (50k DOFs) keeps micro-solves in-process; large solves run in a fresh process where BLAS / MUMPS pools size correctly at init time. On contended hosts this is 1.4× faster than no isolation on the PBS rotor (mumps backend, ~6-load average). See Thread isolation modes — empirical comparison for the full matrix.