API Reference¶
This section documents the public Python API for openseespy-solvers.
The public modules are:
| Module | Purpose |
|---|---|
openseespy_solvers.scipy |
CPU linear and eigen solver constructors |
openseespy_solvers.scipy.precond |
CPU built-in preconditioners |
openseespy_solvers.cupy |
CUDA linear and eigen solver constructors |
openseespy_solvers.cupy.precond |
CUDA built-in preconditioners |
openseespy_solvers.nvmath |
NVIDIA nvmath.sparse direct solver constructor |
openseespy_solvers.hybrid |
Hybrid direct-factorization/GMRES solver constructor |
openseespy_solvers.exceptions |
Public exception types |
Private modules and names beginning with _ are implementation details.
Importing¶
Use the backend namespace that matches the solver you want:
For optional GPU backends:
All solver constructors return solver objects. Register those objects with OpenSeesPy by
passing solver.to_openseespy() to ops.system("PythonSparse", ...) or
ops.eigen("PythonSparse", ...).
Linear Solvers¶
| Constructor | Backend | Purpose |
|---|---|---|
scipy.spsolve |
scipy.sparse.linalg / SuperLU |
CPU sparse direct solve |
scipy.umfpack |
scikit-umfpack | CPU sparse direct solve using UMFPACK |
scipy.cg |
scipy.sparse.linalg |
CPU Conjugate Gradient |
scipy.gmres |
scipy.sparse.linalg |
CPU GMRES |
cupy.spsolve |
cupyx.scipy.sparse.linalg |
CUDA sparse direct solve |
cupy.cg |
cupyx.scipy.sparse.linalg |
CUDA Conjugate Gradient |
cupy.gmres |
cupyx.scipy.sparse.linalg |
CUDA GMRES |
nvmath.direct_solver |
NVIDIA nvmath.sparse |
CUDA sparse direct solve |
hybrid |
scipy-compatible direct solver + GMRES |
Reuse a direct factorization as a GMRES preconditioner |
Eigen Solvers¶
| Constructor | Backend | Purpose |
|---|---|---|
scipy.eigsh |
scipy.sparse.linalg / ARPACK |
CPU generalized symmetric eigen solve |
scipy.lobpcg |
scipy.sparse.linalg |
CPU LOBPCG eigen solve |
cupy.eigsh |
cupyx.scipy.sparse.linalg + scipy.sparse.linalg |
CUDA-assisted generalized symmetric eigen solve |
cupy.lobpcg |
cupyx.scipy.sparse.linalg |
CUDA LOBPCG eigen solve |
Preconditioners¶
| Preconditioner | Backend | Purpose |
|---|---|---|
scipy.precond.jacobi |
scipy.sparse |
Diagonal/Jacobi preconditioner |
scipy.precond.ilu |
scipy.sparse.linalg |
Incomplete LU preconditioner |
scipy.precond.direct |
scipy.sparse.linalg |
Direct-solver preconditioner |
cupy.precond.jacobi |
cupyx.scipy.sparse |
Diagonal/Jacobi preconditioner |
cupy.precond.ilu |
cupyx.scipy.sparse.linalg |
Incomplete LU preconditioner |
cupy.precond.direct |
cupyx.scipy.sparse.linalg |
Direct-solver preconditioner |
API compatibility with scipy, cupy, and nvmath¶
If you already use scipy.sparse.linalg
or cupyx.scipy.sparse.linalg,
the solver constructors in openseespy_solvers.scipy and
openseespy_solvers.cupy follow the same names and keyword arguments. The only
routine change is that you do not pass A and b (or K and M) — OpenSees
assembles those during analysis — and you register the solver with OpenSeesPy
instead of calling the solve function yourself.
Direct solve¶
spsolve() in openseespy_solvers.scipy — same solver options, no matrix or RHS at construction:
import openseespy.opensees as ops
from openseespy_solvers.scipy import spsolve
solver = spsolve() # e.g. permc_spec=... like splu
ops.system("PythonSparse", solver.to_openseespy())
ops.analyze(num_steps)
Iterative solve¶
cg() in openseespy_solvers.scipy — same rtol, atol, maxiter, M, and related keywords:
import openseespy.opensees as ops
from openseespy_solvers.scipy import cg, precond
solver = cg(rtol=1e-8, M=precond.jacobi, maxiter=1000)
ops.system("PythonSparse", solver.to_openseespy())
ops.analyze(num_steps)
openseespy_solvers.cupy mirrors the same pattern (spsolve(), cg(), …) for GPU backends.
nvmath direct solve¶
nvmath.sparse.advanced.DirectSolver
takes the sparse matrix a, dense RHS b, and optional options, execution, and
stream keyword arguments:
import nvmath
solver = nvmath.sparse.advanced.DirectSolver(a, b, execution=execution)
with solver:
solver.plan()
solver.factorize()
x = solver.solve()
direct_solver() in openseespy_solvers.nvmath — pass the nvmath keywords you need at construction; OpenSees
supplies a and b on each solve and runs the plan / factorize / solve workflow
for you:
import openseespy.opensees as ops
from openseespy_solvers.nvmath import direct_solver
solver = direct_solver(execution=execution, plan_algorithm=plan_algorithm)
ops.system("PythonSparse", solver.to_openseespy())
ops.analyze(num_steps)
direct_solver() exposes execution=, multithreading_lib=, and plan_algorithm=;
stream and other DirectSolverOptions fields are not. See nvmath for
details.
See Solver objects and PythonSparse interface for lifecycle details.