Skip to content

Commit d40ae0d

Browse files
Add compatibility layer for OrdinaryDiffEqCore DEOptions API change
Adds @static if compatibility to support both old and new versions of OrdinaryDiffEqCore before and after PR SciML/OrdinaryDiffEq.jl#2895. The PR adds typeof(verbose) as a type parameter to DEOptions. This change makes DelayDiffEq.jl robust to this API change by detecting at compile time which version of DEOptions is available and using the appropriate constructor. Implementation: - Adds _count_deoptions_typeparams() to count type parameters - Uses DEOPTIONS_HAS_VERBOSE_TYPEPARAM constant for compile-time detection - Old version (OrdinaryDiffEqCore ≤ 1.36): 20 type parameters - New version (OrdinaryDiffEqCore ≥ 1.37): 21 type parameters Benefits: - Zero runtime overhead (@static if is compile-time) - Automatic version detection - Backward and forward compatible - No version number checking needed 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent 0694bb5 commit d40ae0d

File tree

1 file changed

+149
-57
lines changed

1 file changed

+149
-57
lines changed

src/solve.jl

Lines changed: 149 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,33 @@ function SciMLBase.__solve(prob::SciMLBase.AbstractDDEProblem,
66
integrator.sol
77
end
88

9+
# Compile-time detection for OrdinaryDiffEqCore version compatibility
10+
# Detects if DEOptions has typeof(verbose) as a type parameter (PR #2895)
11+
"""
12+
_count_deoptions_typeparams()
13+
14+
Count the number of type parameters in OrdinaryDiffEqCore.DEOptions.
15+
Used for compile-time detection of API changes.
16+
"""
17+
function _count_deoptions_typeparams()
18+
count = 0
19+
T = OrdinaryDiffEqCore.DEOptions
20+
while T isa UnionAll
21+
count += 1
22+
T = T.body
23+
end
24+
return count
25+
end
26+
27+
"""
28+
DEOPTIONS_HAS_VERBOSE_TYPEPARAM
29+
30+
Compile-time constant that is `true` if OrdinaryDiffEqCore.DEOptions includes
31+
`typeof(verbose)` as a type parameter (OrdinaryDiffEqCore >= 1.37.0 or with PR #2895).
32+
Old version has 20 parameters, new version has 21 parameters (adds typeof(verbose)).
33+
"""
34+
const DEOPTIONS_HAS_VERBOSE_TYPEPARAM = _count_deoptions_typeparams() >= 21
35+
936
function SciMLBase.__init(prob::SciMLBase.AbstractDDEProblem,
1037
alg::AbstractMethodOfStepsAlgorithm,
1138
timeseries_init = (),
@@ -251,63 +278,128 @@ function SciMLBase.__init(prob::SciMLBase.AbstractDDEProblem,
251278
save_everystep || isempty(saveat) || saveat isa Number ||
252279
prob.tspan[2] in saveat : save_end
253280

254-
opts = OrdinaryDiffEqCore.DEOptions{typeof(abstol_internal), typeof(reltol_internal),
255-
QT, tType, typeof(controller),
256-
typeof(internalnorm), typeof(internalopnorm),
257-
typeof(save_end_user),
258-
typeof(callback_set),
259-
typeof(isoutofdomain),
260-
typeof(progress_message), typeof(unstable_check),
261-
typeof(tstops_internal),
262-
typeof(d_discontinuities_internal), typeof(userdata),
263-
typeof(save_idxs),
264-
typeof(maxiters), typeof(tstops),
265-
typeof(saveat), typeof(d_discontinuities)}(maxiters,
266-
save_everystep,
267-
adaptive,
268-
abstol_internal,
269-
reltol_internal,
270-
QT(gamma),
271-
QT(qmax),
272-
QT(qmin),
273-
QT(qsteady_max),
274-
QT(qsteady_min),
275-
QT(qoldinit),
276-
QT(failfactor),
277-
tType(dtmax),
278-
tType(dtmin),
279-
controller,
280-
internalnorm,
281-
internalopnorm,
282-
save_idxs,
283-
tstops_internal,
284-
saveat_internal,
285-
d_discontinuities_internal,
286-
tstops,
287-
saveat,
288-
d_discontinuities,
289-
userdata,
290-
progress,
291-
progress_steps,
292-
progress_name,
293-
progress_message,
294-
progress_id,
295-
timeseries_errors,
296-
dense_errors,
297-
dense,
298-
save_on,
299-
save_start,
300-
save_end,
301-
save_discretes,
302-
save_end_user,
303-
callback_set,
304-
isoutofdomain,
305-
unstable_check,
306-
verbose,
307-
calck,
308-
force_dtmin,
309-
advance_to_tstop,
310-
stop_at_next_tstop)
281+
# Construct DEOptions with compatibility for both old and new OrdinaryDiffEqCore
282+
# Old version (before PR #2895): DEOptions without typeof(verbose) type parameter
283+
# New version (with PR #2895): DEOptions with typeof(verbose) type parameter
284+
@static if DEOPTIONS_HAS_VERBOSE_TYPEPARAM
285+
# New version: include typeof(verbose) as a type parameter
286+
opts = OrdinaryDiffEqCore.DEOptions{typeof(abstol_internal), typeof(reltol_internal),
287+
QT, tType, typeof(controller),
288+
typeof(internalnorm), typeof(internalopnorm),
289+
typeof(save_end_user),
290+
typeof(callback_set),
291+
typeof(isoutofdomain),
292+
typeof(progress_message), typeof(unstable_check),
293+
typeof(tstops_internal),
294+
typeof(d_discontinuities_internal), typeof(userdata),
295+
typeof(save_idxs),
296+
typeof(maxiters), typeof(tstops),
297+
typeof(saveat), typeof(d_discontinuities), typeof(verbose)}(maxiters,
298+
save_everystep,
299+
adaptive,
300+
abstol_internal,
301+
reltol_internal,
302+
QT(gamma),
303+
QT(qmax),
304+
QT(qmin),
305+
QT(qsteady_max),
306+
QT(qsteady_min),
307+
QT(qoldinit),
308+
QT(failfactor),
309+
tType(dtmax),
310+
tType(dtmin),
311+
controller,
312+
internalnorm,
313+
internalopnorm,
314+
save_idxs,
315+
tstops_internal,
316+
saveat_internal,
317+
d_discontinuities_internal,
318+
tstops,
319+
saveat,
320+
d_discontinuities,
321+
userdata,
322+
progress,
323+
progress_steps,
324+
progress_name,
325+
progress_message,
326+
progress_id,
327+
timeseries_errors,
328+
dense_errors,
329+
dense,
330+
save_on,
331+
save_start,
332+
save_end,
333+
save_discretes,
334+
save_end_user,
335+
callback_set,
336+
isoutofdomain,
337+
unstable_check,
338+
verbose,
339+
calck,
340+
force_dtmin,
341+
advance_to_tstop,
342+
stop_at_next_tstop)
343+
else
344+
# Old version: without typeof(verbose) type parameter
345+
opts = OrdinaryDiffEqCore.DEOptions{typeof(abstol_internal), typeof(reltol_internal),
346+
QT, tType, typeof(controller),
347+
typeof(internalnorm), typeof(internalopnorm),
348+
typeof(save_end_user),
349+
typeof(callback_set),
350+
typeof(isoutofdomain),
351+
typeof(progress_message), typeof(unstable_check),
352+
typeof(tstops_internal),
353+
typeof(d_discontinuities_internal), typeof(userdata),
354+
typeof(save_idxs),
355+
typeof(maxiters), typeof(tstops),
356+
typeof(saveat), typeof(d_discontinuities)}(maxiters,
357+
save_everystep,
358+
adaptive,
359+
abstol_internal,
360+
reltol_internal,
361+
QT(gamma),
362+
QT(qmax),
363+
QT(qmin),
364+
QT(qsteady_max),
365+
QT(qsteady_min),
366+
QT(qoldinit),
367+
QT(failfactor),
368+
tType(dtmax),
369+
tType(dtmin),
370+
controller,
371+
internalnorm,
372+
internalopnorm,
373+
save_idxs,
374+
tstops_internal,
375+
saveat_internal,
376+
d_discontinuities_internal,
377+
tstops,
378+
saveat,
379+
d_discontinuities,
380+
userdata,
381+
progress,
382+
progress_steps,
383+
progress_name,
384+
progress_message,
385+
progress_id,
386+
timeseries_errors,
387+
dense_errors,
388+
dense,
389+
save_on,
390+
save_start,
391+
save_end,
392+
save_discretes,
393+
save_end_user,
394+
callback_set,
395+
isoutofdomain,
396+
unstable_check,
397+
verbose,
398+
calck,
399+
force_dtmin,
400+
advance_to_tstop,
401+
stop_at_next_tstop)
402+
end
311403

312404
# create fixed point solver
313405
fpsolver = build_fpsolver(alg, alg.fpsolve, u, uEltypeNoUnits, uBottomEltypeNoUnits,

0 commit comments

Comments
 (0)