Linear static solution (pyfe3d.solver.static)#

solve() solves a sparse linear system, raising an error for a singular matrix, and linear_static() is the linear static analysis based on it, with the outputs of Analysis.static(). The linear and non-linear static analyses of a model given by callables are done with Analysis.

pyfe3d.solver.static.linear_static(K, fext)#

Linear static analysis

Solves K @ u = fext with solve() and returns the solution with the outputs of Analysis.static(), a single increment of load factor 1..

Parameters:
Ksparse_matrix

Stiffness matrix of the free degrees-of-freedom, shape (n, n). It should include the constant terms that apply, e.g. a constant geometric stiffness matrix of a preload or an aerodynamic matrix. It may be unsymmetric, e.g. KC0 + KF for a follower load affine in the displacements on a geometrically linear structure, whose load stiffness is KF = -dfext/du.

fextnp.ndarray

External force vector, 1-D array of size n.

Returns:
incrementslist

[1.], the load factor of the solution.

cslist

List with the solution vector, 1-D array of size n.

Raises:
numpy.linalg.LinAlgError

When K is singular, see solve().

Notes

The system solved is \(\boldsymbol{K} \boldsymbol{u} = \boldsymbol{F}_{ext}\), the first Newton-Raphson iteration of the non-linear problem from \(\boldsymbol{u} = \boldsymbol{0}\), where the tangent stiffness matrix is the linear constitutive stiffness matrix \(\boldsymbol{K}_{C0}\). For a follower load affine in the displacements, \(\boldsymbol{F}(\boldsymbol{u}) = \boldsymbol{F}_0 - \boldsymbol{K}_F \boldsymbol{u}\), the linear solution is that of \((\boldsymbol{K}_{C0} + \boldsymbol{K}_F) \boldsymbol{u} = \boldsymbol{F}_0\).

pyfe3d.solver.static.solve(A, b, **kwargs)#

Solve a linear system, raising an error for a singular matrix

The system is solved with the LU factorization of scipy.sparse.linalg.splu(). A must have only the free degrees-of-freedom, e.g. KC0uu = KC0[bu, :][:, bu]: a null row or column, see check_null_rows_cols(), and an exactly singular matrix raise an error instead of giving a solution with NaN values, as scipy.sparse.linalg.spsolve() does.

Parameters:
Asparse_matrix or np.ndarray

Square matrix, shape (n, n). It may be unsymmetric, e.g. with the load stiffness of a follower load, since the factorization is an LU factorization.

bnp.ndarray

Right-hand side, real or complex, 1-D array of size n.

kwargskeyword arguments, optional

Passed to scipy.sparse.linalg.splu(), e.g. permc_spec.

Returns:
xnp.ndarray

Solution, 1-D array of size n.

Raises:
numpy.linalg.LinAlgError

When A has a null row or column, with the indices of these degrees-of-freedom, see check_null_rows_cols(), or when it is exactly singular, i.e. when scipy.sparse.linalg.splu() raises a RuntimeError.

See also

linear_static

the linear static analysis based on it.

Notes

The system \(\boldsymbol{A} \boldsymbol{x} = \boldsymbol{b}\) is solved as given. In a finite element model the known displacements are partitioned out beforehand, and a null row or column of \(\boldsymbol{A}\) is a degree-of-freedom without stiffness, i.e. a modelling error, which is reported instead of being removed. This deliberately differs from structsolve, whose solvers remove the null rows and columns left by the boundary conditions of its semi-analytical models, see check_null_rows_cols().

An exactly singular matrix is detected by the factorization, which raises, instead of the scipy.sparse.linalg.MatrixRankWarning and the NaN values of scipy.sparse.linalg.spsolve(). Turning that warning into an error needs a warnings.catch_warnings() block, whose exit resets the registry of the warnings already shown, of every module, such that the warnings of the caller shown once per location would be shown again after each call.