OrdinaryDiffEq.jl
OrdinaryDiffEq.jl copied to clipboard
Issues with KLUFactorization() and sparse matrices with SplitODEFunction
There are some issues when using a SplitODEFunction
with KLUFactorization()
. If using a MatrixOperator
:
using OrdinaryDiffEq, LinearSolve, SparseArrays
f2 = (du, u, p, t) -> u[2]
A = MatrixOperator([1.0 1.0; 1.0 1.0])
f = SplitFunction(A, f2)
prob = SplitODEProblem(f, [1.0, 1.0], (0.0, 1.0))
solve(prob, TRBDF2(linsolve=KLUFactorization()), saveat=0.1)
ERROR: type Nothing has no field f
Stacktrace:
[1] setproperty!(x::Nothing, f::Symbol, v::Function)
@ Base .\Base.jl:39
[2] calc_J!(J::Matrix{…}, integrator::OrdinaryDiffEq.ODEIntegrator{…}, cache::OrdinaryDiffEq.NLNewtonCache{…}, next_step::Bool)
@ OrdinaryDiffEq C:\Users\User\.julia\packages\OrdinaryDiffEq\NbEDr\src\derivative_utils.jl:138
[3] calc_W!(W::Matrix{…}, integrator::OrdinaryDiffEq.ODEIntegrator{…}, nlsolver::OrdinaryDiffEq.NLSolver{…}, cache::OrdinaryDiffEq.TRBDF2Cache{…}, dtgamma::Float64, repeat_step::Bool, W_transform::Bool, newJW::Nothing)
@ OrdinaryDiffEq C:\Users\User\.julia\packages\OrdinaryDiffEq\NbEDr\src\derivative_utils.jl:703
[4] update_W!(nlsolver::OrdinaryDiffEq.AbstractNLSolver, integrator::SciMLBase.DEIntegrator{…}, cache::Any, dtgamma::Any, repeat_step::Bool, newJW::Any)
@ OrdinaryDiffEq C:\Users\User\.julia\packages\OrdinaryDiffEq\NbEDr\src\derivative_utils.jl:813 [inlined]
[5] update_W!(nlsolver::OrdinaryDiffEq.AbstractNLSolver, integrator::SciMLBase.DEIntegrator{…}, cache::Any, dtgamma::Any, repeat_step::Bool, newJW::Any)
@ OrdinaryDiffEq C:\Users\User\.julia\packages\OrdinaryDiffEq\NbEDr\src\derivative_utils.jl:812 [inlined]
[6] nlsolve!(nlsolver::OrdinaryDiffEq.NLSolver{…}, integrator::OrdinaryDiffEq.ODEIntegrator{…}, cache::OrdinaryDiffEq.TRBDF2Cache{…}, repeat_step::Bool)
@ OrdinaryDiffEq C:\Users\User\.julia\packages\OrdinaryDiffEq\NbEDr\src\nlsolve\nlsolve.jl:27
[7] perform_step!(integrator::OrdinaryDiffEq.ODEIntegrator{…}, cache::OrdinaryDiffEq.TRBDF2Cache{…}, repeat_step::Bool)
@ OrdinaryDiffEq C:\Users\User\.julia\packages\OrdinaryDiffEq\NbEDr\src\perform_step\sdirk_perform_step.jl:490
[8] perform_step!(integrator::Any, cache::OrdinaryDiffEq.TRBDF2Cache{<:Array}, repeat_step::Any)
@ OrdinaryDiffEq C:\Users\User\.julia\packages\OrdinaryDiffEq\NbEDr\src\perform_step\sdirk_perform_step.jl:467 [inlined]
[9] solve!(integrator::OrdinaryDiffEq.ODEIntegrator{…})
@ OrdinaryDiffEq C:\Users\User\.julia\packages\OrdinaryDiffEq\NbEDr\src\solve.jl:526
[10] __solve(::ODEProblem{…}, ::TRBDF2{…}; kwargs::@Kwargs{…})
@ OrdinaryDiffEq C:\Users\User\.julia\packages\OrdinaryDiffEq\NbEDr\src\solve.jl:6
[11] __solve
@ OrdinaryDiffEq C:\Users\User\.julia\packages\OrdinaryDiffEq\NbEDr\src\solve.jl:1 [inlined]
[12] #solve_call#34
@ DiffEqBase C:\Users\User\.julia\packages\DiffEqBase\d8Zv9\src\solve.jl:539 [inlined]
[13] solve_up(prob::ODEProblem{…}, sensealg::Nothing, u0::Vector{…}, p::SciMLBase.NullParameters, args::TRBDF2{…}; kwargs::@Kwargs{…})
@ DiffEqBase C:\Users\User\.julia\packages\DiffEqBase\d8Zv9\src\solve.jl:1000
[14] solve_up
@ DiffEqBase C:\Users\User\.julia\packages\DiffEqBase\d8Zv9\src\solve.jl:973 [inlined]
[15] solve(prob::ODEProblem{…}, args::TRBDF2{…}; sensealg::Nothing, u0::Nothing, p::Nothing, wrap::Val{…}, kwargs::@Kwargs{…})
@ DiffEqBase C:\Users\User\.julia\packages\DiffEqBase\d8Zv9\src\solve.jl:910
[16] top-level scope
@ c:\Users\User\.julia\dev\FiniteVolumeMethod\docs\src\literate_wyos\semilinear_equations.jl:295
Some type information was truncated. Use `show(err)` to see complete types.
If just using normal functions:
using OrdinaryDiffEq, LinearSolve, SparseArrays
f1 = (du, u, p, t) -> u[1]
f2 = (du, u, p, t) -> u[2]
f = SplitFunction(f1, f2, jac_prototype = sparse([1.0 1.0; 1.0 1.0]))
prob = SplitODEProblem(f, [1.0, 1.0], (0.0, 1.0))
solve(prob, TRBDF2(linsolve=KLUFactorization()), saveat=0.1)
ERROR: MethodError: no method matching getcolptr(::Matrix{Float64})
Closest candidates are:
getcolptr(::SubArray{Tv, 2, <:SparseArrays.AbstractSparseMatrixCSC{Tv, Ti}, Tuple{Base.Slice{Base.OneTo{Int64}}, I}} where {Tv, Ti, I<:AbstractUnitRange})
@ SparseArrays C:\Users\User\.julia\juliaup\julia-1.10.0-beta2+0.x64.w64.mingw32\share\julia\stdlib\v1.10\SparseArrays\src\sparsematrix.jl:186
getcolptr(::Union{SparseArrays.FixedSparseCSC, SparseMatrixCSC})
@ SparseArrays C:\Users\User\.julia\juliaup\julia-1.10.0-beta2+0.x64.w64.mingw32\share\julia\stdlib\v1.10\SparseArrays\src\sparsematrix.jl:185
Stacktrace:
[1] solve!(cache::LinearSolve.LinearCache{…}, alg::KLUFactorization; kwargs::@Kwargs{…})
@ LinearSolve C:\Users\User\.julia\packages\LinearSolve\19ohw\src\factorization.jl:829
[2] solve!(::LinearSolve.LinearCache{…}; kwargs::@Kwargs{…})
@ LinearSolve C:\Users\User\.julia\packages\LinearSolve\19ohw\src\common.jl:197
[3] dolinsolve(integrator::OrdinaryDiffEq.ODEIntegrator{…}, linsolve::LinearSolve.LinearCache{…}; A::Matrix{…}, linu::Vector{…}, b::Vector{…}, du::Nothing, u::Nothing, p::Nothing, t::Nothing, weight::Nothing, solverdata::Nothing, reltol::Float64)
@ OrdinaryDiffEq C:\Users\User\.julia\packages\OrdinaryDiffEq\NbEDr\src\misc_utils.jl:107
[4] compute_step!(nlsolver::OrdinaryDiffEq.NLSolver{…}, integrator::OrdinaryDiffEq.ODEIntegrator{…}, γW::Float64)
@ OrdinaryDiffEq C:\Users\User\.julia\packages\OrdinaryDiffEq\NbEDr\src\nlsolve\newton.jl:193
[5] nlsolve!(nlsolver::OrdinaryDiffEq.NLSolver{…}, integrator::OrdinaryDiffEq.ODEIntegrator{…}, cache::OrdinaryDiffEq.TRBDF2Cache{…}, repeat_step::Bool)
@ OrdinaryDiffEq C:\Users\User\.julia\packages\OrdinaryDiffEq\NbEDr\src\nlsolve\nlsolve.jl:52
[6] perform_step!(integrator::OrdinaryDiffEq.ODEIntegrator{…}, cache::OrdinaryDiffEq.TRBDF2Cache{…}, repeat_step::Bool)
@ OrdinaryDiffEq C:\Users\User\.julia\packages\OrdinaryDiffEq\NbEDr\src\perform_step\sdirk_perform_step.jl:490
[7] perform_step!(integrator::Any, cache::OrdinaryDiffEq.TRBDF2Cache{<:Array}, repeat_step::Any)
@ OrdinaryDiffEq C:\Users\User\.julia\packages\OrdinaryDiffEq\NbEDr\src\perform_step\sdirk_perform_step.jl:467 [inlined]
[8] solve!(integrator::OrdinaryDiffEq.ODEIntegrator{…})
@ OrdinaryDiffEq C:\Users\User\.julia\packages\OrdinaryDiffEq\NbEDr\src\solve.jl:526
[9] __solve(::ODEProblem{…}, ::TRBDF2{…}; kwargs::@Kwargs{…})
@ OrdinaryDiffEq C:\Users\User\.julia\packages\OrdinaryDiffEq\NbEDr\src\solve.jl:6
[10] __solve
@ OrdinaryDiffEq C:\Users\User\.julia\packages\OrdinaryDiffEq\NbEDr\src\solve.jl:1 [inlined]
[11] #solve_call#34
@ DiffEqBase C:\Users\User\.julia\packages\DiffEqBase\d8Zv9\src\solve.jl:539 [inlined]
[12] solve_up(prob::ODEProblem{…}, sensealg::Nothing, u0::Vector{…}, p::SciMLBase.NullParameters, args::TRBDF2{…}; kwargs::@Kwargs{…})
@ DiffEqBase C:\Users\User\.julia\packages\DiffEqBase\d8Zv9\src\solve.jl:1000
[13] solve_up
@ DiffEqBase C:\Users\User\.julia\packages\DiffEqBase\d8Zv9\src\solve.jl:973 [inlined]
[14] solve(prob::ODEProblem{…}, args::TRBDF2{…}; sensealg::Nothing, u0::Nothing, p::Nothing, wrap::Val{…}, kwargs::@Kwargs{…})
@ DiffEqBase C:\Users\User\.julia\packages\DiffEqBase\d8Zv9\src\solve.jl:910
[15] top-level scope
@ c:\Users\User\.julia\dev\FiniteVolumeMethod\docs\src\literate_wyos\semilinear_equations.jl:295
Some type information was truncated. Use `show(err)` to see complete types.
I think the issue in this case is that jac_prototype
doesn't get correctly passed into prob
?
julia> f.jac_prototype
2×2 SparseMatrixCSC{Float64, Int64} with 4 stored entries:
1.0 1.0
1.0 1.0
julia> prob.f.jac_prototype
julia> prob.f.f1.jac_prototype
julia> prob.f.f2.jac_prototype
Indeed, solving with a non-split method throws a warning if the solver isn't set:
┌ Warning: Split ODE problem do not work with factorization linear solvers. Bug detailed in https://github.com/SciML/OrdinaryDiffEq.jl/pull/1643. Defaulting to linsolve=KrylovJL()
└ @ OrdinaryDiffEq C:\Users\accou\.julia\packages\OrdinaryDiffEq\NbEDr\src\alg_utils.jl:248
referencing https://github.com/SciML/OrdinaryDiffEq.jl/pull/1643. Some of the PDE benchmarks need this fixed.
CC: @vpuri3