Skip to content

Conversation

@ChrisRackauckas-Claude
Copy link

@ChrisRackauckas-Claude ChrisRackauckas-Claude commented Oct 17, 2025

Fixes #2892

Summary

This PR fixes an issue where Radau methods (RadauIIA3, RadauIIA5, RadauIIA9, and AdaptiveRadau) would fail when using KLUFactorization with a sparse jac_prototype.

Root Cause

The issue was caused by a limitation in LinearSolve's KLU interface: KLU doesn't properly support complex sparse matrices. When initializing a LinearSolve cache with a complex sparse matrix and KLU, the factorization is never created (remains Nothing), leading to a FieldError: type Nothing has no field colptr when trying to solve.

Solution

This PR implements a two-part fix:

  1. Proper initialization of complex W matrices: Use f.jac_prototype .* (1 + 0im) (when available) to create complex W matrices with the correct sparsity pattern from the user-provided prototype.

  2. Automatic fallback to UMFPACK: When KLU is specified as the linear solver, automatically use UMFPACKFactorization for the complex W matrices (W2/W3), while still using KLU for the real W1 matrix. UMFPACK fully supports complex sparse matrices.

Changes

  • lib/OrdinaryDiffEqFIRK/src/firk_caches.jl: Updated cache initialization for all four Radau methods to use jac_prototype and fallback to UMFPACK for complex matrices
  • lib/OrdinaryDiffEqFIRK/src/OrdinaryDiffEqFIRK.jl: Added imports for KLUFactorization and UMFPACKFactorization

Testing

Verified that all Radau methods now work correctly with:

  • KLUFactorization with sparse jac_prototype
  • LUFactorization
  • SparspakFactorization

The fix preserves the sparsity pattern correctly and allows users to benefit from KLU's performance for real matrices while seamlessly handling the complex matrix requirements of Radau methods.

🤖 Generated with Claude Code

Co-Authored-By: Claude [email protected]

- Added is_sparse and nonzeros imports to OrdinaryDiffEqFIRK
- Added SparseArrays as dependency
- Modified RadauIIA3, RadauIIA5, RadauIIA9, and AdaptiveRadau cache initialization
  to preserve sparsity pattern from jacobian prototype for complex matrices
- Added test cases to reproduce the issue

Addresses SciML#2892 where KLUFactorization fails with jacobian prototypes.
The fix preserves the sparsity structure but further work may be needed
to ensure KLU can properly initialize with the complex sparse matrices.

Issue: Complex sparse matrices initialized with zeros prevent KLU from
creating proper factorization cache, resulting in 'type Nothing has no field colptr' error.
@ChrisRackauckas-Claude ChrisRackauckas-Claude changed the title [WIP] Fix Radau methods to use jacobian prototype sparsity for KLU Fix Radau methods to support KLU with sparse jacobian prototypes Oct 17, 2025
@ChrisRackauckas-Claude ChrisRackauckas-Claude marked this pull request as ready for review October 17, 2025 13:09
J, W1_temp = build_J_W(alg, u, uprev, p, t, dt, f, jac_config, uEltypeNoUnits, Val(true))
# For sparse matrices, preserve sparsity pattern for KLU compatibility
if is_sparse(J)
W1 = similar(J, Complex{eltype(W1_temp)})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this line is the same between branches.

Comment on lines +72 to +73
SparseConnectivityTracer = "9f842d2f-2579-4b1d-911e-f412cf18a3f5"
Sparspak = "e56a9233-b9d6-4f03-8d0f-1825330902ac"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these should be in extras.

@ChrisRackauckas
Copy link
Member

I think the real answer is that we should generate the W via J .* (0 + 0im)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AdaptiveRadau produces error with KLUFactorization

3 participants