High-performance sparse solvers for symmetric FEM matrices
Multiple RHS simultaneously, sharing Krylov subspace for 4× fewer iterations
Quasi inner product ⟨x,y⟩ = Σxₖyₖ — natural for A = Aᵀ systems
Built-in ILU, Jacobi, and split preconditioners
Outperforms direct solvers for large systems
Short three-term recurrences, not full Krylov basis
Monotonic quasi-minimal residual reduction
# pip install blocksolver from blocksolver import blqmr from scipy.sparse import diags # Complex symmetric FEM matrix n = 5000 A = diags([-1, 4+0.1j, -1], [-1, 0, 1], shape=(n, n), dtype=complex) # Block solve: 16 RHS at once B = np.random.randn(n, 16) + 0j result = blqmr(A, B, tol=1e-10, precond_type='diag') print(f"Converged: {result.converged}")
% Complex symmetric FEM matrix n = 5000; K = spdiags([-ones(n,1) 4*ones(n,1) -ones(n,1)], -1:1, n, n); A = K + 0.1i * speye(n); % Block solve: 16 RHS at once B = rand(n, 16) + 1i*rand(n, 16); opt.precond = 'diag'; [X, flag] = blqmr(A, B, 1e-10, 1000, [], [], [], opt);
program solve_fem use blit_blqmr_real implicit none type(BLQMRSolver) :: qmr integer :: n, nnz, nrhs integer, allocatable :: Ap(:), Ai(:) real(8), allocatable :: Ax(:), B(:,:), X(:,:) n = 5000; nnz = 14998; nrhs = 16 ! ... allocate and fill CSC arrays ... call BLQMRCreate(qmr, n) qmr%maxit = 1000 qmr%qtol = 1.0d-10 qmr%pcond_type = 3 ! Jacobi call BLQMRPrep(qmr, Ap, Ai, Ax, nnz) call BLQMRSolve(qmr, Ap, Ai, Ax, nnz, X, B, nrhs) call BLQMRDestroy(qmr) end program
#include "blit_solvers.h" int main() { const int n = 5000, nnz = 14998, nrhs = 16; std::vector<int> Ap(n+1), Ai(nnz); std::vector<double> Ax(nnz), b(n*nrhs), x(n*nrhs); BlitBLQMR<double> solver(n, nrhs, 1000, 1e-3); solver.Prepare(Ap.data(), Ai.data(), Ax.data(), nnz); solver.Solve(x.data(), b.data(), nrhs); return 0; }
Speedup = Direct_time / BLQMR_time. Green (>1.0) = BLQMR wins.
| Grid | 1 RHS | 2 RHS | 4 RHS | 8 RHS | 16 RHS | 32 RHS | 64 RHS | 128 RHS |
|---|---|---|---|---|---|---|---|---|
| 10³ (1K) | 0.65 | 0.45 | 0.44 | 0.29 | 0.19 | 0.16 | 0.15 | 0.13 |
| 15³ (3K) | 4.4 | 1.3 | 0.96 | 0.61 | 0.34 | 0.26 | 0.22 | 0.20 |
| 20³ (8K) | 6.5 | 3.3 | 2.2 | 1.3 | 0.69 | 0.53 | 0.42 | 0.35 |
| 25³ (16K) | 10.3 | 4.4 | 2.7 | 1.5 | 0.94 | 0.73 | 0.57 | 0.51 |
| 30³ (27K) | 16.3 | 9.1 | 5.4 | 3.2 | 1.9 | 1.3 | 1.0 | 0.77 |
pip install blocksolver
Linux: apt install gfortran libsuitesparse-dev
addpath('/path/to/blit/matlab')