Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ using OrdinaryDiffEqCore: OrdinaryDiffEqAlgorithm, OrdinaryDiffEqAdaptiveImplici
OrdinaryDiffEqImplicitAlgorithm, CompositeAlgorithm,
OrdinaryDiffEqExponentialAlgorithm,
OrdinaryDiffEqAdaptiveExponentialAlgorithm,
OrdinaryDiffEqLinearExponentialAlgorithm,
StochasticDiffEqNewtonAlgorithm, StochasticDiffEqNewtonAdaptiveAlgorithm,
StochasticDiffEqJumpNewtonAdaptiveAlgorithm,
StochasticDiffEqJumpNewtonDiffusionAdaptiveAlgorithm,
Expand Down
6 changes: 6 additions & 0 deletions lib/OrdinaryDiffEqDifferentiation/src/alg_utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ function _alg_autodiff(
) where {CS, AD, FDT, ST, CJ, Controller}
return Val{AD}()
end
# OrdinaryDiffEqLinearExponentialAlgorithm subtypes (Magnus integrators, LieEuler,
# CG methods, etc.) have NO autodiff field — their only fields are krylov, m, iop.
# They must be excluded before the generic ExponentialAlgorithm dispatch below.
function _alg_autodiff(::OrdinaryDiffEqLinearExponentialAlgorithm)
return Val{false}()
end
function _alg_autodiff(
alg::Union{
OrdinaryDiffEqExponentialAlgorithm{CS, AD},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,26 @@ sol = solve(prob2, Rosenbrock23(autodiff = AutoForwardDiff(chunksize = 1)))

sol = solve(prob2, Rosenbrock23(autodiff = AutoFiniteDiff()))
@test ≈(good_sol[:, end], sol[:, end], rtol = 1.0e-2)

# Regression test for issue #3232:
# MagnusGL6 (and all OrdinaryDiffEqLinearExponentialAlgorithm subtypes)
# have no `autodiff` field. When OrdinaryDiffEqDifferentiation is loaded,
# _alg_autodiff must not crash by trying to access alg.autodiff.
using OrdinaryDiffEqLinear
using SciMLOperators: MatrixOperator

@testset "MagnusGL6 solve with Differentiation loaded (issue #3232)" begin
function update_func!(A, u, p, t)
A[1, 1] = cos(t)
A[2, 1] = sin(t)
A[1, 2] = -sin(t)
A[2, 2] = cos(t)
end
A = MatrixOperator(ones(2, 2), update_func! = update_func!)
prob = ODEProblem(A, ones(2), (1.0, 6.0))

# This would crash with FieldError before the fix
sol = solve(prob, MagnusGL6(), dt = 1 / 10)
@test sol.retcode == ReturnCode.Success
@test length(sol.t) > 1
end
18 changes: 18 additions & 0 deletions lib/OrdinaryDiffEqLinear/test/linear_method_tests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -267,3 +267,21 @@ test_setup = Dict(:alg => Vern9(), :reltol => 1.0e-14, :abstol => 1.0e-14)

sim = analyticless_test_convergence(dts, prob, CayleyEuler(), test_setup)
@test sim.𝒪est[:l2] ≈ 1 atol = 0.2

# Regression test for https://github.com/SciML/OrdinaryDiffEq.jl/issues/3232
# Magnus/Linear integrators must not FieldError when OrdinaryDiffEqDifferentiation
# is loaded (which happens transitively via DifferentialEquations.jl).
@testset "Regression #3232: non-autonomous Magnus solve does not FieldError" begin
function update_func_3232!(A, u, p, t)
A[1, 1] = cos(t)
A[2, 1] = sin(t)
A[1, 2] = -sin(t)
A[2, 2] = cos(t)
end
A_3232 = MatrixOperator(ones(2, 2), update_func! = update_func_3232!)
prob_3232 = ODEProblem(A_3232, ones(2), (1.0, 6.0))
for alg in (MagnusGL6(), MagnusGL4(), MagnusGL8(), LieEuler(), CG2(), CG3(), CG4a())
sol = solve(prob_3232, alg, dt = 1 / 10)
@test sol.retcode == ReturnCode.Success
end
end
Loading