Skip to content

Fix FieldError for Magnus/Linear integrators with OrdinaryDiffEqDiffe…#3464

Open
singhharsh1708 wants to merge 2 commits intoSciML:masterfrom
singhharsh1708:fix/magnus-autodiff-fielderror-3232
Open

Fix FieldError for Magnus/Linear integrators with OrdinaryDiffEqDiffe…#3464
singhharsh1708 wants to merge 2 commits intoSciML:masterfrom
singhharsh1708:fix/magnus-autodiff-fielderror-3232

Conversation

@singhharsh1708
Copy link
Copy Markdown
Contributor

Fix FieldError for Magnus/Linear integrators when OrdinaryDiffEqDifferentiation is loaded

Fixes #3232

Problem

Solving a non-autonomous linear ODE with any Magnus integrator (e.g. MagnusGL6, MagnusGL8, LieEuler, CG2, etc.) crashes with a FieldError when OrdinaryDiffEqDifferentiation is loaded (which happens automatically via DifferentialEquations.jl):

FieldError: type OrdinaryDiffEqLinear.MagnusGL6 has no field `autodiff`,
available fields: `krylov`, `m`, `iop`

Root Cause

MagnusGL6 <: OrdinaryDiffEqLinearExponentialAlgorithm <: OrdinaryDiffEqExponentialAlgorithm{0, false, ...}

In OrdinaryDiffEqDifferentiation/src/alg_utils.jl, the generic dispatch:

function _alg_autodiff(alg::Union{
        OrdinaryDiffEqExponentialAlgorithm{CS, AD},
        OrdinaryDiffEqAdaptiveExponentialAlgorithm{CS, AD},
    }) where {CS, AD}
    return alg.autodiff  # ← crashes: Magnus types have no autodiff field
end

catches all OrdinaryDiffEqLinearExponentialAlgorithm subtypes because they inherit from OrdinaryDiffEqExponentialAlgorithm{0, false, ...}. These algorithms are matrix-exponential methods that never use ForwardDiff/FiniteDiff — they only have fields krylov, m, and iop.

Fix

Add a more-specific _alg_autodiff override that intercepts OrdinaryDiffEqLinearExponentialAlgorithm before the generic ExponentialAlgorithm dispatch:

function _alg_autodiff(::OrdinaryDiffEqLinearExponentialAlgorithm)
    return Val{false}()
end

This is consistent with how OrdinaryDiffEqCore already handles these types in prepare_alg and has_autodiff.

Changes

File Change
OrdinaryDiffEqDifferentiation.jl Import OrdinaryDiffEqLinearExponentialAlgorithm from Core
alg_utils.jl Add _alg_autodiff override returning Val{false}()
differentiation_traits_tests.jl Regression test verifying _alg_autodiff, prepare_alg, and forwarddiffs_model

Testing

All 3 regression assertions pass with clean precompilation:

✓ _alg_autodiff returns Val{false}()
✓ prepare_alg returns alg unchanged  
✓ forwarddiffs_model returns false

…rentiation (SciML#3232)

Magnus integrators (MagnusGL6, MagnusGL8, etc.) and other
OrdinaryDiffEqLinearExponentialAlgorithm subtypes have no `autodiff`
field — only `krylov`, `m`, `iop`. When OrdinaryDiffEqDifferentiation
is loaded (e.g. via DifferentialEquations.jl), the generic
`_alg_autodiff(::OrdinaryDiffEqExponentialAlgorithm{CS,AD})` dispatch
would call `alg.autodiff` on these types, causing a FieldError crash.

Fix:
- Import OrdinaryDiffEqLinearExponentialAlgorithm into
  OrdinaryDiffEqDifferentiation
- Add _alg_autodiff(::OrdinaryDiffEqLinearExponentialAlgorithm)
  returning Val{false}(), intercepting calls before the generic
  ExponentialAlgorithm dispatch that accesses the nonexistent field
- The existing prepare_alg override in OrdinaryDiffEqCore (line 298)
  already handles the prepare_alg path correctly

Also adds regression tests verifying _alg_autodiff, prepare_alg, and
forwarddiffs_model all work correctly for LinearExponentialAlgorithm
subtypes.
@singhharsh1708 singhharsh1708 force-pushed the fix/magnus-autodiff-fielderror-3232 branch from ba144dc to ff465b8 Compare April 17, 2026 16:35
Comment thread lib/OrdinaryDiffEqDifferentiation/test/differentiation_traits_tests.jl Outdated
@singhharsh1708 singhharsh1708 force-pushed the fix/magnus-autodiff-fielderror-3232 branch from 7272537 to 8f47539 Compare April 17, 2026 18:05
@singhharsh1708
Copy link
Copy Markdown
Contributor Author

Replaced the mock struct with real integrators (MagnusGL6, MagnusGL4, MagnusGL8, LieEuler, CG2, CG3, CG4a) and moved the regression test to OrdinaryDiffEqLinear/test/linear_method_tests.jl — no Project.toml changes needed. All 7 pass locally.
Also noticed a pre-existing cG4a convergence order test failure (unrelated to this PR), opened #3466 for it.

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.

Non-autonomous Linear ODE MagnusGL6 FieldError due to attempted autodiff field access

2 participants