Linear static analyses#

A linear static analysis solves \(\boldsymbol{K}_{C0} \boldsymbol{u} = \boldsymbol{f}\) for the dofs whose displacements are unknown, with the matrix KC0 assembled as in Overview and workflow. This page gives the partition of the dofs, with zero or prescribed displacements, the reactions, and the solvers.

Partition of the dofs#

At each dof either the load or the displacement is known. The Boolean array bu marks the free dofs, \(u\), whose displacements are unknown, and its complement bk = ~bu the known ones, \(k\), with the prescribed displacements uk[bk], \(\boldsymbol{u}_k\), zero at a fixed support. Bathe (2014, Sec. 4.2.2, Eqs. (4.42) to (4.45)) writes the same partition with other subscripts. Without reordering the dofs, the system reads

\[\begin{split}\begin{bmatrix} \boldsymbol{K}_{{C0}_{uu}} & \boldsymbol{K}_{{C0}_{uk}} \\ \boldsymbol{K}_{{C0}_{ku}} & \boldsymbol{K}_{{C0}_{kk}} \end{bmatrix} \begin{Bmatrix} \boldsymbol{u}_u \\ \boldsymbol{u}_k \end{Bmatrix} = \begin{Bmatrix} \boldsymbol{f}_u \\ \boldsymbol{f}_k + \boldsymbol{R}_k \end{Bmatrix}\end{split}\]

with \(\boldsymbol{f}_k\) the loads applied at the known dofs and \(\boldsymbol{R}_k\) the unknown reactions. The first row gives the system of the free dofs, where the prescribed displacements act as the forces \(-\boldsymbol{K}_{{C0}_{uk}} \boldsymbol{u}_k\), and the second row the reactions:

\[\boldsymbol{K}_{{C0}_{uu}} \boldsymbol{u}_u = \boldsymbol{f}_u - \boldsymbol{K}_{{C0}_{uk}} \boldsymbol{u}_k, \qquad \boldsymbol{R}_k = \boldsymbol{K}_{{C0}_{ku}} \boldsymbol{u}_u + \boldsymbol{K}_{{C0}_{kk}} \boldsymbol{u}_k - \boldsymbol{f}_k\]

which, with SciPy:

KC0uu = KC0[bu, :][:, bu]
KC0uk = KC0[bu, :][:, bk]
u = np.zeros(N)
u[bk] = uk[bk]
u[bu] = solve(KC0uu, f[bu] - KC0uk @ uk[bk])
Rk = KC0[bk, :] @ u - f[bk]

KC0[bk, :] @ u is \(\boldsymbol{K}_{{C0}_{ku}} \boldsymbol{u}_u + \boldsymbol{K}_{{C0}_{kk}} \boldsymbol{u}_k\), the internal forces at the known dofs, which update_fint of the elements also gives, \(\boldsymbol{F}_{{int}_k} - \boldsymbol{f}_k\), see step 7 of Overview and workflow. For fixed supports, uk is zero and the system is \(\boldsymbol{K}_{{C0}_{uu}} \boldsymbol{u}_u = \boldsymbol{f}_u\). The same partition gives the matrices of the eigenvalue analyses, see Linear buckling and natural frequencies.

Solvers#

  • solve() solves a sparse system with an LU factorization and raises an error for a singular matrix, where scipy.sparse.linalg.spsolve() returns NaN values.

  • linear_static() solves K @ u = fext of the free dofs, checks that a symmetric K is positive definite and returns [1.] and [u], the outputs of Analysis.static().

  • Analysis.static() with NLgeom=False solves the same system from the callables of a model, see Non-linear static analyses, in a single increment. With Analysis(..., bu=bu, uk=uk), the callables work with all the N dofs, the system of the free dofs above is formed by FreeDofs.linear_fext(), and cs[0] has size N, with uk[bk] at the known dofs; the reactions are calc_fint(u) - calc_fext() at the known dofs. A configuration-dependent load is corrected by iterations, see Analysis.static().

The worked example Tutorial: prescribed displacement at the tip of a cantilever solves a cantilever with a prescribed tip deflection both ways, and Linear static analysis of a plate a plate under a point load.

Errors of the supports#

The solvers of pyfe3d.solver do not remove null rows and columns: a dof left without stiffness, e.g. an unattached node, an unstiffened drilling rotation or a missing boundary condition, raises a numpy.linalg.LinAlgError naming the dofs, see check_null_rows_cols(). Insufficient boundary conditions, a mechanism or re-entrant elements leave \(\boldsymbol{K}_{{C0}_{uu}}\) not positive definite, which linear_static(), linear_buckling() and the linear Analysis.static() report with a numpy.linalg.LinAlgError naming the likely causes, see Linear buckling and natural frequencies. A structure that has no supports, e.g. in flight, is solved with apply_inertia_relief(), whose reference support is a set of prescribed null displacements, see Inertia relief.

References#

  • Bathe, K. J., Finite Element Procedures, 2nd ed., K. J. Bathe, Watertown, MA, 2014.