Static analysis#
femorph_solver.solvers.static.solve_static() solves the standard
linear-elastic problem
with Dirichlet constraints imposed at a set of DOFs. It’s the fastest path in femorph-solver — one sparse factorisation, one back-solve — and the starting point for more involved analyses (static + gravity, static + thermal preload, static pre-stress for modal).
Partitioning#
Given a prescribed set \(c\) of DOFs with fixed values \(u_c\) and the complementary free set \(f\), the system partitions as
where \(R_c\) is the reaction force at constrained DOFs. The solve factors \(K_{ff}\) once, solves for
and then back-substitutes
to recover the reactions.
API#
from femorph_solver.solvers.static import solve_static
K = m.stiffness_matrix()
F = np.zeros(K.shape[0]) # full-length load vector
F[load_dof] = -1000.0 # 1 kN somewhere
prescribed = {d: 0.0 for d in fixed_dofs} # e.g. a clamped face
result = solve_static(K, F, prescribed=prescribed)
result.displacement # (N,) — every DOF, zeros where clamped
result.reaction # (N,) — non-zero only at constrained DOFs
result.free_mask # (N,) bool — True where we solved
Or from a Model that already carries D and F records:
m.d(1, "UX", 0.0) # ... pin some DOFs ...
m.f(10, "FZ", -1000.0)
result = m.solve() # wraps solve_static with the record data
Backend selection#
solve_static accepts linear_solver="auto" (default) which
picks the fastest available SPD direct solver in this order:
PARDISO → CHOLMOD → UMFPACK → SuperLU. Override with any name from
femorph_solver.solvers.linear.list_linear_solvers():
result = solve_static(K, F, prescribed, linear_solver="cholmod")
See Solvers for the full backend table, and Performance for measured wall times.
Thread control#
thread_limit: int | None = None caps BLAS / OpenMP threads for
the factorisation and back-solve. None defers to the process-wide
default set by femorph_solver.set_thread_limit() or the
FEMORPH_SOLVER_NUM_THREADS environment variable. See
Thread control.
Non-zero Dirichlet#
Any non-zero u_c is fine — the RHS correction
\(F_f - K_{fc} u_c\) flows through automatically, and the
reaction recovery produces the force needed to hold the prescribed
displacement.
Zero-diagonal DOFs (rigid bodies)#
Some element formulations produce DOFs with zero diagonal stiffness
(e.g. the transverse DOFs of a pure-axial truss). solve_static
detects them via |K_ii| <= 1e-12 * max(|K_ii|) and folds them
into the Dirichlet set — they drop from the factorisation and return
u_i = 0 automatically. This matches MAPDL’s default behaviour.
See also#
Solvers — which backend for what problem size.
Performance — wall-time numbers across backends and meshes.
Thread control — BLAS / OpenMP thread capping.
Boundary conditions and loads — how to set
DandFon a Model.