Skip to content

Commit 8f47539

Browse files
Harsh SinghHarsh Singh
authored andcommitted
Use real Magnus integrators in regression test for #3232
1 parent ff465b8 commit 8f47539

File tree

3 files changed

+38
-27
lines changed

3 files changed

+38
-27
lines changed

lib/OrdinaryDiffEqDifferentiation/src/alg_utils.jl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,6 @@ Base.@pure function determine_chunksize(u, CS)
7272
end
7373
end
7474

75-
76-
7775
function DiffEqBase.prepare_alg(
7876
alg::Union{
7977
OrdinaryDiffEqAdaptiveImplicitAlgorithm{

lib/OrdinaryDiffEqDifferentiation/test/differentiation_traits_tests.jl

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -45,29 +45,24 @@ sol = solve(prob2, Rosenbrock23(autodiff = AutoFiniteDiff()))
4545
@test (good_sol[:, end], sol[:, end], rtol = 1.0e-2)
4646

4747
# Regression test for issue #3232:
48-
# OrdinaryDiffEqLinearExponentialAlgorithm subtypes (MagnusGL6, etc.)
49-
# have no `autodiff` field; _alg_autodiff and prepare_alg must not crash.
50-
using OrdinaryDiffEqDifferentiation: _alg_autodiff
51-
using OrdinaryDiffEqCore: OrdinaryDiffEqLinearExponentialAlgorithm
52-
using DiffEqBase: prepare_alg
53-
54-
struct MockMagnusAlg <: OrdinaryDiffEqLinearExponentialAlgorithm
55-
krylov::Bool
56-
m::Int
57-
iop::Int
58-
end
59-
60-
@testset "LinearExponentialAlgorithm autodiff traits (issue #3232)" begin
61-
mock = MockMagnusAlg(false, 30, 0)
62-
63-
# _alg_autodiff must return Val{false}() instead of accessing alg.autodiff
64-
@test _alg_autodiff(mock) == Val{false}()
65-
66-
# prepare_alg must return the algorithm unchanged (no AD preparation needed)
67-
u0 = ones(2)
68-
mock_prob = ODEProblem((du, u, p, t) -> du .= 0, u0, (0.0, 1.0))
69-
@test prepare_alg(mock, u0, nothing, mock_prob) === mock
70-
71-
# forwarddiffs_model must return false
72-
@test SciMLBase.forwarddiffs_model(mock) == false
48+
# MagnusGL6 (and all OrdinaryDiffEqLinearExponentialAlgorithm subtypes)
49+
# have no `autodiff` field. When OrdinaryDiffEqDifferentiation is loaded,
50+
# _alg_autodiff must not crash by trying to access alg.autodiff.
51+
using OrdinaryDiffEqLinear
52+
using SciMLOperators: MatrixOperator
53+
54+
@testset "MagnusGL6 solve with Differentiation loaded (issue #3232)" begin
55+
function update_func!(A, u, p, t)
56+
A[1, 1] = cos(t)
57+
A[2, 1] = sin(t)
58+
A[1, 2] = -sin(t)
59+
A[2, 2] = cos(t)
60+
end
61+
A = MatrixOperator(ones(2, 2), update_func! = update_func!)
62+
prob = ODEProblem(A, ones(2), (1.0, 6.0))
63+
64+
# This would crash with FieldError before the fix
65+
sol = solve(prob, MagnusGL6(), dt = 1 / 10)
66+
@test sol.retcode == ReturnCode.Success
67+
@test length(sol.t) > 1
7368
end

lib/OrdinaryDiffEqLinear/test/linear_method_tests.jl

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,3 +267,21 @@ test_setup = Dict(:alg => Vern9(), :reltol => 1.0e-14, :abstol => 1.0e-14)
267267

268268
sim = analyticless_test_convergence(dts, prob, CayleyEuler(), test_setup)
269269
@test sim.𝒪est[:l2] 1 atol = 0.2
270+
271+
# Regression test for https://github.com/SciML/OrdinaryDiffEq.jl/issues/3232
272+
# Magnus/Linear integrators must not FieldError when OrdinaryDiffEqDifferentiation
273+
# is loaded (which happens transitively via DifferentialEquations.jl).
274+
@testset "Regression #3232: non-autonomous Magnus solve does not FieldError" begin
275+
function update_func_3232!(A, u, p, t)
276+
A[1, 1] = cos(t)
277+
A[2, 1] = sin(t)
278+
A[1, 2] = -sin(t)
279+
A[2, 2] = cos(t)
280+
end
281+
A_3232 = MatrixOperator(ones(2, 2), update_func! = update_func_3232!)
282+
prob_3232 = ODEProblem(A_3232, ones(2), (1.0, 6.0))
283+
for alg in (MagnusGL6(), MagnusGL4(), MagnusGL8(), LieEuler(), CG2(), CG3(), CG4a())
284+
sol = solve(prob_3232, alg, dt = 1 / 10)
285+
@test sol.retcode == ReturnCode.Success
286+
end
287+
end

0 commit comments

Comments
 (0)