Repository navigation
Use a sparse matrix format during assembly - #99
Merged
Merged
Conversation
nikoscham
commented
Oct 28, 2026
Member
- Add SparseMatrix (numerics/sparseMatrix.js): row-wise storage during assembly, with conversion to CSC (mathjs LU), CSR (Jacobi) and dense (WebGPU Jacobi)
- Assemble every model into a SparseMatrix instead of a dense n x n array; Dirichlet boundary conditions clear a row in O(nnz) instead of O(n)
- LU solver: build the mathjs sparse matrix directly from CSC, without a dense intermediate
- Jacobi solver: iterate over CSR rows, O(nnz) per iteration instead of O(n^2)
- Assembly: build a local element matrix and add it to the global matrix once per element; precompute reference basis functions per integration point in initializeFEA; reuse the coordinates from the isoparametric mapping; reuse derivative arrays; hoist integration factors out of the inner loops
- Up to 3.7x faster with LU, 127x faster with Jacobi; at 6.5k DOFs the matrix needs 9 MB instead of 675 MB; solutions unchanged (within 1e-11)
- Tests: add sparseMatrix unit test; move the Euler-Bernoulli beam test to tests/verification/analytical/eulerBernoulliBeam1DCantilever (closed-form checks, not a unit test); read the matrix with toDense() in beam tests
- Add SparseMatrix (numerics/sparseMatrix.js): row-wise storage during assembly, with conversion to CSC (mathjs LU), CSR (Jacobi) and dense (WebGPU Jacobi) - Assemble every model into a SparseMatrix instead of a dense n x n array; Dirichlet boundary conditions clear a row in O(nnz) instead of O(n) - LU solver: build the mathjs sparse matrix directly from CSC, without a dense intermediate - Jacobi solver: iterate over CSR rows, O(nnz) per iteration instead of O(n^2) - Assembly: build a local element matrix and add it to the global matrix once per element; precompute reference basis functions per integration point in initializeFEA; reuse the coordinates from the isoparametric mapping; reuse derivative arrays; hoist integration factors out of the inner loops - Up to 3.7x faster with LU, 127x faster with Jacobi; at 6.5k DOFs the matrix needs 9 MB instead of 675 MB; solutions unchanged (within 1e-11) - Tests: add sparseMatrix unit test; move the Euler-Bernoulli beam test to tests/verification/analytical/eulerBernoulliBeam1DCantilever (closed-form checks, not a unit test); read the matrix with toDense() in beam tests
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.