Skip to content

fix: DynamicQuantities compatibility in core + differentiation paths (rebased #3126)#3480

Merged
ChrisRackauckas merged 3 commits intoSciML:masterfrom
ChrisRackauckas-Claude:wave2-odecore-rebased
Apr 21, 2026
Merged

fix: DynamicQuantities compatibility in core + differentiation paths (rebased #3126)#3480
ChrisRackauckas merged 3 commits intoSciML:masterfrom
ChrisRackauckas-Claude:wave2-odecore-rebased

Conversation

@ChrisRackauckas-Claude
Copy link
Copy Markdown
Contributor

Rebase of #3126 onto the latest master. Original author: @MilesCranmerBot.

Wave 2 (post-DynamicQuantities release) for the DynamicQuantities × SciML rollout.
Tracking issue: JuliaPhysics/DynamicQuantities.jl#200

What this changes

OrdinaryDiffEqCore

  • Adds DynamicQuantities + Measurements integration test (lib/OrdinaryDiffEqCore/test/dynamicquantities_measurements.jl)
  • Uses a unitless bottom-eltype path in solver init to avoid zero(::Type{<:Quantity}) on runtime-unit quantity types
  • Includes related unit-safe initialization/caching updates used by this path

OrdinaryDiffEqDifferentiation

  • Makes unitful Jacobian derivative utilities robust for DynamicQuantities value-space factorization/solve
  • Removes silent AD backend fallback behavior

Rebase notes

Conflicts resolved in lib/OrdinaryDiffEqCore/Project.toml: kept master's DiffEqBase = "6.217" bound alongside the PR's new AllocCheck, DynamicQuantities = "1.8", Measurements, OrdinaryDiffEqTsit5, and FillArrays compat entries.

Supersedes #3126.
Related DiffEqBase PR: SciML/DiffEqBase.jl#1293

Co-Authored-By: Chris Rackauckas accounts@chrisrackauckas.com

MilesCranmerBot and others added 3 commits April 21, 2026 15:40
Core init changes so that Tsit5 (and other adaptive methods) can
solve problems whose eltype is a DynamicQuantities `Quantity` of a
`Measurement`:

- `initdt.jl`: use a value-based `oneunit(t)` and compute `dtmin`
  via `eps(DiffEqBase.value(t))`, avoiding `eps(::Quantity)` which
  is undefined for runtime-unit quantity types.
- `solve.jl`:
  - Default `dtmin`/`dtmax` use `zero(prob.tspan[1])` and a direct
    subtraction so units are preserved without going through the
    unitless `eltype(prob.tspan)(0)` path that drops DQ units.
  - `tTypeNoUnits` is derived via `DiffEqBase.value(oneunit(first(tspan)))`
    so units are stripped correctly for Unitful and DQ; `one(tType)`
    fails for runtime-unit DQ types.
  - Split the unitless/tolerance branch into a `scalar_type_tol`
    predicate so non-scalar Number arrays take the broadcasting
    path.
  - `rate_prototype` uses `oneunit(first(tspan))` instead of
    `oneunit(tType)` for the same reason as above.

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Adds `test/downstream/dynamicquantities_measurements.jl` covering a
Tsit5 solve of a problem whose state type combines DynamicQuantities
units with Measurements uncertainty propagation. Wires it into the
existing `Downstream` CI group so the extra deps (DynamicQuantities,
plus the existing Measurements) stay in `test/downstream/Project.toml`
and don't leak into `OrdinaryDiffEqCore`'s own test deps.

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Adds a narrow "strip units only" primitive that is orthogonal to the existing
`value` (strips everything, including AD) and `unitfulvalue` (strips AD, keeps
units) helpers. Defaults to the identity; Unitful, FlexUnits, and
DynamicQuantities extensions override it to return the underlying numeric value.

Switches the `tTypeNoUnits` derivation in `OrdinaryDiffEqCore/src/solve.jl`
from `DiffEqBase.value(oneunit(first(tspan)))` to
`DiffEqBase.stripunits(oneunit(first(tspan)))` so that ForwardDiff Duals in t0
are preserved through `tTypeNoUnits`. The previous `value`-based form collapsed
Duals to Float64, which then made `NLSolver{true, tTypeNoUnits}` use Float64
fields for ηold etc., and SDIRK solvers (KenCarp4/47/5/58, TRBDF2) that run
with a Dual t0 errored with `MethodError: Float64(::Dual)`.

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
@ChrisRackauckas ChrisRackauckas merged commit edb6916 into SciML:master Apr 21, 2026
143 of 242 checks passed
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.

3 participants