Tutorial¶
This page shows how to wire solvers from this package into OpenSeesPy. Model-building details are omitted; see the OpenSeesPy documentation and examples. For install steps, see Installation.
Linear analysis¶
The finite element method discretizes a continuous structural model into nodes and elements. After assembly, the governing equations can be written, without loss of generality, as
where \(\mathbf{M}\) is the mass matrix, \(\mathbf{C}\) is the damping matrix, \(\mathbf{u}\) is the vector of nodal displacements (and rotations), \(\mathbf{p}_r(\mathbf{u})\) collects resisting forces (which may be nonlinear in \(\mathbf{u}\)), and \(\mathbf{p}_f(t)\) is the applied load vector. For a static analysis the inertial term \(\mathbf{M} \ddot{\mathbf{u}}\) and the damping term \(\mathbf{C} \dot{\mathbf{u}}\) are absent.
OpenSees advances the solution in time with an incremental integrator. At each step the nonlinear equilibrium equations are linearized, typically in a Newton iteration, resulting in the linear system $$ \mathbf{A} \mathbf{x} = \mathbf{b}, $$
where \(\mathbf{A}\) is a matrix, and \(\mathbf{x}\) and \(\mathbf{b}\) are vectors. What they represent depends on the integrator and algorithm.
OpenSees assembles \(\mathbf{A}\) and \(\mathbf{b}\) from the model and passes them to a
linear solver selected with the system command.
A linear solver object from this library can be used in OpenSeesPy with the following syntax:
CPU direct solver¶
A good default on CPU is scipy.spsolve:
import openseespy.opensees as ops
from openseespy_solvers.scipy import spsolve
solver = spsolve()
ops.system("PythonSparse", solver.to_openseespy())
For larger sparse systems on CPU, scipy.umfpack
is often faster once UMFPACK is installed (installation — UMFPACK).
GPU direct solver¶
If you have an NVIDIA GPU and the matching optional wheels (GPU install),
use nvmath.direct_solver:
import openseespy.opensees as ops
from openseespy_solvers.nvmath import direct_solver
solver = direct_solver()
ops.system("PythonSparse", solver.to_openseespy())
When a full factorization is too expensive, try iterative solvers (cg, gmres) with a
preconditioner, or hybrid to reuse a
direct factorization as a GMRES preconditioner. See the API overview for all
solver constructors.
Generalized eigenvalue analysis¶
Modal analysis solves the generalized eigenvalue problem:
Here \(\lambda\) is an eigenvalue, \(\mathbf{\Phi}\) is the corresponding eigenvector, \(\mathbf{K}\) is the stiffness matrix, and \(\mathbf{M}\) is the mass matrix. The eigenvalue is the square of the natural angular frequency, \(\omega = \sqrt{\lambda}\) (rad/s); \(\mathbf{\Phi}\) gives the mode shape.
An eigen solver object from this library can be used in OpenSeesPy with the following syntax:
CPU eigen solver (scipy.eigsh)¶
A good default on CPU is scipy.eigsh:
import openseespy.opensees as ops
from openseespy_solvers.scipy import eigsh
eig_solver = eigsh()
num_modes = 5
lam = ops.eigen("PythonSparse", num_modes, eig_solver.to_openseespy())
GPU eigen solver (cupy.eigsh)¶
A good default on GPU is cupy.eigsh: