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: .. toctree:: :maxdepth: 1 bc-pitfalls mesh-quality conditioning-and-performance solver-defaults-and-threading pbs-rotor-comparison pbs-rotor-cyclic-comparison isolation-mode-bench element-pitfalls troubleshooting Where to start when something looks wrong: 1. Sanity-check the **BCs** — :doc:`bc-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 **mesh** — :doc:`mesh-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 report** — :doc:`conditioning-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 :doc:`troubleshooting` — 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_direct`` ≻ ``pardiso`` ≻ ``cholmod`` ≻ ``mumps`` ≻ ``superlu``). ARPACK + ``mkl_direct`` beats MAPDL Block Lanczos by 25 % at 8 threads on the 494,766-DOF PBS sector. See :doc:`pbs-rotor-comparison`. * **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 :doc:`pbs-rotor-cyclic-comparison`. * **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 :doc:`isolation-mode-bench` for the full matrix.