Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Measurements no longer supported by DifferentialEquations 7.7.0 #950

Closed
MartinOtter opened this issue Mar 28, 2023 · 5 comments · Fixed by SciML/RecursiveArrayTools.jl#260

Comments

@MartinOtter
Copy link

Previously, DifferentialEquations supported AbstractFloat types for states and state derivatives, e.g., Measurements.Measurement{Float64} instead of the default Float64.
This seems to be no longer the case with version 7.7.0.
Modia with DifferentialEquations 7.5.0 supported Measurements.
Modia with DifferentialEquations 7.7.0 gives errors, when Measurements is used.

Find below a simple test model, that demonstrates the issue (without Modia):

module Test_ode_pendulum_with_Measurement

using DifferentialEquations, Measurements, StaticArrays

mutable struct Model{R<:Real, F<:Real}
    m::R  # mass
    L::R  # length
    d::R  # damping
    g::F  # gravity (not used as Measurment)
    ϕ::R  # angle
    ω::R  # der(angle)
    α::R  # der(der(angle))
    r::SVector{2,R}   # absolute position of end point

    function Model{R,F}(m::R, L::R, d::R, g::F) where {R<:Real, F<:Real}
        new(m, L, d, g, 0, 0, 0, SVector{2,R}(0,0))
    end
end

Model(;m::R=0, L::R=0, d::R=0, g::F=0) where {R<:Real, F<:Real} = Model{R,F}(m,L,d,g)

"simplePendulum: Compute m::Model at actual time instant"
function simplePendulum!(m::Model, t, x)::Nothing
    m.ϕ = x[1]
    m.ω = x[2]
    m.α = (-m.m*m.g*m.L*sin(m.ϕ) - m.d*m.ω) / (m.m*m.L^2)
    m.r = @SVector [m.L*sin(m.ϕ), -m.L*cos(m.ϕ)]
    return nothing
end

"SimplePendulum1: Called by integrator"
function simplePendulum1!(der_x, x, m::Model, t)
    simplePendulum!(m, t, x)
    der_x[1] = m.ω
    der_x[2] = m.α
end

t_start = 0.0
t_inc   = 0.01
t_end   = 7.0
tspan   = (t_start, t_end)
tspan2  = t_start:t_inc:t_end


# Problem 1 with Float64
model1 = Model(m=1.0, L=1.0, d=0.2, g=9.81)
# println("model1 = $model1")
x1₀ =/2, 0.0]

prob1 = ODEProblem(simplePendulum1!, x1₀, tspan, model1)
sol1 = solve(prob1, Tsit5(), reltol = 1e-6, saveat=t_inc)

# Problem 2 with Measurement
model2 = Model(m=1.0 ± 0.1, L=1.00 ± 0.01, d=0.2± 0.05, g=9.81)
x2₀ =/2 ± 0.1, 0.0 ± 0]

prob2 = ODEProblem(simplePendulum1!, x2₀, tspan, model2)
sol2  = solve(prob2, Tsit5(), reltol = 1e-6, saveat=t_inc)

end

An error occurs when translating this model due to "prob2". The error message is

ERROR: LoadError: MethodError: no method matching Float64(::Measurements.Measurement{Float64})
Closest candidates are:
  (::Type{T})(::Real, ::RoundingMode) where T<:AbstractFloat at rounding.jl:200
  (::Type{T})(::T) where T<:Number at boot.jl:772
  (::Type{T})(::AbstractChar) where T<:Union{AbstractChar, Number} at char.jl:50
  ...
Stacktrace:
  [1] convert(#unused#::Type{Float64}, x::Measurements.Measurement{Float64})
    @ Base .\number.jl:7
  [2] setindex!(A::Vector{Float64}, x::Measurements.Measurement{Float64}, i1::Int64)
    @ Base .\array.jl:966
  [3] macro expansion
    @ D:\otter\home\.julia\packages\FastBroadcast\xrPat\src\FastBroadcast.jl:428 [inlined]
  [4] macro expansion
    @ .\simdloop.jl:77 [inlined]
  [5] macro expansion
    @ D:\otter\home\.julia\packages\FastBroadcast\xrPat\src\FastBroadcast.jl:427 [inlined]
  [6] _fast_materialize!
    @ D:\otter\home\.julia\packages\FastBroadcast\xrPat\src\FastBroadcast.jl:385 [inlined]
  [7] fast_materialize!
    @ D:\otter\home\.julia\packages\FastBroadcast\xrPat\src\FastBroadcast.jl:37 [inlined]
  [8] calculate_residuals!
    @ D:\otter\home\.julia\packages\DiffEqBase\qPmC2\src\calculate_residuals.jl:96 [inlined]
  [9] perform_step!(integrator::OrdinaryDiffEq.ODEIntegrator{OrdinaryDiffEq.Tsit5{typeof(Ordinary ...
@ChrisRackauckas
Copy link
Member

I had just noticed this too in a docs build:

https://buildkite.com/julialang/scimldocs/builds/954#01872778-7d13-489d-9623-44879ea51abf/642-1132

@giordano is this expected? It looks like some times value is still giving a measurement. Was its behavior on arrays changed?

https://github.com/SciML/DiffEqBase.jl/blob/master/ext/DiffEqBaseMeasurementsExt.jl is our extension code. It's failing in the residual calculation which would be using the value from the norm.

@giordano
Copy link

Can you try Measurements.jl v2.8.0? The most notable change in 2.9.0 is JuliaPhysics/Measurements.jl#135

@MartinOtter
Copy link
Author

Can you try Measurements.jl v2.8.0? The most notable change in 2.9.0 is JuliaPhysics/Measurements.jl#135

I tried with Measurements.jl v2.8.0 and the same error appears.

@MartinOtter
Copy link
Author

Can you try Measurements.jl v2.8.0? The most notable change in 2.9.0 is JuliaPhysics/Measurements.jl#135

I tried with Measurements.jl v2.8.0 and the same error appears.

Sorry, I made a mistake.
Yes, when using Measurements.jl v2.8.0, the error does not appear.

@giordano
Copy link

Then probably something was relying on the fact that one(::Measurement{T}) would return an instance of Measurement{T}, but that was incorrect.

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 a pull request may close this issue.

3 participants