Boundary-condition pitfalls =========================== The single most common source of "the solver is broken" support tickets is a mis-specified boundary condition. Three recurring patterns: 1. **Under-constrained** — too few BCs, leaving rigid-body modes unrestrained. Static solve produces enormous displacements (the matrix is singular and the linear backend either fails outright or returns garbage). 2. **Over-constrained** — too many BCs, locking the structure along a direction it should be free to move. Static solve succeeds but gives artificial stiffness; the answer is wrong and there's no obvious symptom. 3. **Symmetry done wrong** — a quarter-symmetry plane pinned in the *normal* direction (correct) plus the *tangential* directions (wrong); the tangential pin destroys the symmetry the model is supposed to exploit. Diagnostic — the rigid-body-mode check -------------------------------------- The cleanest one-shot diagnostic is a **6-mode modal solve on the un-loaded model**. An un-constrained 3-D solid has six rigid-body modes (three translations + three rotations) at :math:`f = 0`. Each Dirichlet constraint kills one of those modes: * A correctly-constrained model has **zero** rigid-body modes. * An under-constrained model has 1–6 rigid-body modes surviving — read off how many constraints are missing. * A model with extra constraints has zero rigid-body modes *and* an artificially-elevated lowest natural frequency. The recipe:: res = m.solve_modal(n_modes=6) print(res.frequency) # all > 1 Hz on a rigid steel structure → constraints are sufficient # any near 0 Hz → rigid-body mode survived Identifying *which* rigid-body mode survived -------------------------------------------- If a near-zero frequency appears, the corresponding mode shape tells you which DOF was left free: * :math:`u_x \ne 0` constant on every node → translation in x is unconstrained. * :math:`u_z = -y \cdot \theta + \text{const}` → rotation about x-axis is unconstrained. The mode-shape rendering in :ref:`sphx_glr_gallery_post-processing_example_mode_shape_plot.py` shows this visually for a free-free model — the first six "modes" are the rigid-body modes you'd recognise here. Common BC mistakes (and the right pattern) ------------------------------------------ **Cantilever under tip load** * Wrong: pin only the centroid node at :math:`x = 0`. Six DOFs pinned at one node don't restrain rotation of the cross- section about its centroid — the cross-section near the clamp will rotate freely under load. * Right: pin **all three translations on every node** of the :math:`x = 0` face. Use ``Model.fix(nodes=face_nodes, dof="ALL")``. **Simply-supported beam — knife-edge supports** * Wrong: pin :math:`u_y` and :math:`u_z` on every node of the end face. This **clamps** the end (zero rotation) instead of letting the cross-section rotate freely about the support axis. * Right: pin :math:`u_y, u_z` only on the lower (or upper) node row at each end. See :ref:`sphx_glr_gallery_verification_example_verify_ss_beam_central_load.py` for the full pattern. **Symmetry plane (quarter-model)** * Wrong: pin every DOF on the symmetry face. This is a clamp, not a symmetry plane. * Right: pin **only the through-plane translation** on the symmetry face — :math:`u_y = 0` on the :math:`y = 0` plane, :math:`u_x = 0` on the :math:`x = 0` plane. In-plane translations and rotations stay free. **Plane-strain solid model** * Wrong: extrude the 2-D geometry into a 3-D slab and forget the through-thickness BC. The slab will bulge under Poisson contraction and the answer drifts from the plane- strain closed form. * Right: pin :math:`u_z = 0` on **every node** of the slab. See :ref:`sphx_glr_gallery_verification_example_verify_lame_cylinder.py` for the canonical pattern. **Pure-moment loading on a 3-D solid** * Wrong: apply a tip moment via ``Model.apply_force(mz=)`` on a single node. The 3-D solid kernel has no rotational DOFs — the moment is silently dropped. * Right: distribute the moment as a tension/compression **mechanical couple** at the extreme fibres of the loaded face. See Tutorial 1 (cantilever combined loading) for the pattern. The rule of thumb ----------------- **Every BC you add must remove exactly one DOF that genuinely shouldn't be free.** Pin the symmetry-plane normal but not the tangentials. Pin the clamped face's translations but only the out-of-plane translation on a roller. Run the rigid-body-mode check before the static solve, every time.