FEA in three phases =================== Every finite-element simulation, regardless of the solver, decomposes into three phases. femorph-solver's user guide is organised around them because that organisation is *the* mental model of the subject and the library's API mirrors it directly. .. grid:: 1 3 3 3 :gutter: 3 .. grid-item-card:: 1. Pre-process Describe the physics: geometry, discretisation, materials, loads, and constraints. The output is a system of equations ready to solve. .. grid-item-card:: 2. Solve Turn the handle. A direct or iterative algorithm converts the equations into numbers — displacements for a static solve, eigenpairs for modal, a time history for transient. .. grid-item-card:: 3. Post-process Interpret. Compute derived quantities (stress, strain energy, reactions), visualise mode shapes, compare against a reference, write artefacts for downstream tools. .. _phase-preprocess: Pre-process ----------- The pre-processing phase asks one question: *Given what I want to model, what system of equations describes it?* That question decomposes into sub-problems: - **Geometry & discretisation.** Meshing happens upstream of femorph-solver — you arrive with a :class:`pyvista.UnstructuredGrid` or a :class:`mapdl_archive.Archive` already in hand. See :doc:`pre-processing/model`. - **Element choice.** Which class of element interpolates the field? femorph-solver registers a kernel for each topology-first element name (``HEX8`` / ``TET10`` / ``BEAM2`` / …); see :doc:`pre-processing/elements/index`. - **Constitutive laws.** What material behaviour? Today linear elastic only; see :doc:`pre-processing/materials`. - **Element data.** Cross-sections for BEAM / LINK / SHELL; see :doc:`pre-processing/real-constants`. - **Constraints & loads.** Dirichlet displacements and nodal forces; see :doc:`pre-processing/boundary-conditions`. The output of pre-processing is a :class:`~femorph_solver.Model` with a fully-stamped grid, a material table, and the constraint / load records. From it the library can assemble the global sparse matrices ``K`` and ``M`` on demand (``Model.stiffness_matrix()`` and ``Model.mass_matrix()``). .. _phase-solve: Solve ----- The solve phase is where all the heavy compute lives. The API is deliberately small: - :func:`~femorph_solver.solvers.static.solve_static` — ``K u = F`` with Dirichlet BCs. - :func:`~femorph_solver.solvers.modal.solve_modal` — ``K ϕ = ω² M ϕ``. - :func:`~femorph_solver.solvers.transient.solve_transient` — ``M ü + C u̇ + K u = F(t)`` with Newmark-β. - :func:`~femorph_solver.solvers.cyclic.solve_cyclic_modal` — sector modal with harmonic-index phase constraints. Every solver accepts a ``thread_limit`` kwarg and dispatches internally to a pluggable linear / eigen backend — see :doc:`solving/choosing-a-solver` and :doc:`solving/performance`. .. _phase-postprocess: Post-process ------------ The solve returns a lightweight dataclass (:class:`ModalResult`, :class:`StaticResult`, etc.). From there the workflow is conventional Python: - Index into ``result.displacement`` / ``result.mode_shapes`` to get per-DOF values. - Feed ``result.frequency`` into a Campbell diagram. - Call :meth:`Model.eel` for elastic strain at every element node. - Attach result arrays to the model's grid and hand the grid to pyvista for rendering or to VTK / Paraview for further analysis. See :doc:`post-processing/index` for the catalogue of recipes. ---- Why this structure? ------------------- The three-phase decomposition is not femorph-solver's invention. It's the organising principle of every FEM textbook (Bathe §1.2, Zienkiewicz ch. 1-2, Cook §1.1) and of every commercial solver — the preprocess → solve → post-process split has the same shape across NASTRAN, Abaqus, MAPDL, and OptiStruct. We mirror it because it makes the library easier to learn: you already know the structure, and the API method names line up with each phase.