-
-
Notifications
You must be signed in to change notification settings - Fork 228
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
Compatibility with DynamicQuantities.jl – use oneunit(::T)
instead of oneunit(::Type{T})
#993
Comments
I pushed it along and got pretty far: using DynamicQuantities, OrdinaryDiffEq, RecursiveArrayTools
function RecursiveArrayTools.recursive_unitless_bottom_eltype(a::Type{
<:DynamicQuantities.Quantity{T}
}) where T
T
end
function RecursiveArrayTools.recursive_unitless_eltype(a::Type{<:DynamicQuantities.Quantity{T}}) where T
T
end
DiffEqBase.value(x::DynamicQuantities.Quantity) = x.value
@inline function DiffEqBase.UNITLESS_ABS2(x::AbstractArray)
mapreduce(DiffEqBase.UNITLESS_ABS2, DiffEqBase.abs2_and_sum, x, init = zero(real(first(DiffEqBase.value(x)))))
end
@inline function DiffEqBase.UNITLESS_ABS2(x::DynamicQuantities.Quantity)
abs(DiffEqBase.value(x))
end
function DiffEqBase.abs2_and_sum(x::DynamicQuantities.Quantity, y::Float64)
reduce(Base.add_sum, DiffEqBase.value(x), init = zero(real(DiffEqBase.value(x)))) +
reduce(Base.add_sum, y, init = zero(real(DiffEqBase.value(eltype(y)))))
end
DiffEqBase.recursive_length(u::Array) = length(u)
Base.sign(x::DynamicQuantities.Quantity) = Base.sign(DiffEqBase.value(x))
function DiffEqBase.prob2dtmin(prob; use_end_time = true)
DiffEqBase.prob2dtmin(prob.tspan, oneunit(first(prob.tspan)), use_end_time)
end
DiffEqBase.NAN_CHECK(x::DynamicQuantities.Quantity) = isnan(x)
Base.zero(x::Array{T}) where {T<:DynamicQuantities.Quantity} = zero.(x)
@inline function DiffEqBase.calculate_residuals(ũ, u₀, u₁, α, ρ, internalnorm, t)
@. DiffEqBase.calculate_residuals(ũ, u₀, u₁, α, ρ, internalnorm, t)
end
f(u, p, t) = u / t;
problem = ODEProblem(f, [1.0u"km/s"], (0.0u"s", 1.0u"s"));
sol = solve(problem, Tsit5(), dt = 0.1u"s") with just one internal modification. Two interface breaks are weird though: First one: julia> typeof(one(0.0u"s"))
Quantity{Float64, Dimensions{DynamicQuantities.FixedRational{Int32, 25200}}} that should just be Second there's something odd in brodcasting I haven't isolated yet. |
Thanks, nice work! Regarding Also one alternative to this sort of modification is some of the ideas in SymbolicML/DynamicQuantities.jl#76 |
Here is the PR to implement these changes: SymbolicML/DynamicQuantities.jl#74 So I think the missing part is switching to julia> sol = solve(problem, Tsit5(), dt = 0.1u"s")
ERROR: Cannot create a dimensionful 1 for a `UnionAbstractQuantity` type without knowing the dimensions. Please use `oneunit(::UnionAbstractQuantity)` instead.
Stacktrace:
[1] error(s::String)
@ Base ./error.jl:35
[2] oneunit(::Type{Quantity{Float64, Dimensions{DynamicQuantities.FixedRational{Int32, 25200}}}})
@ DynamicQuantities ~/Documents/DynamicQuantities.jl/src/utils.jl:191
[3] __init(prob::ODEProblem{…}, alg::Tsit5{…}, timeseries_init::Tuple{}, ts_init::Tuple{}, ks_init::Tuple{}, recompile::Type{…}; saveat::Tuple{}, tstops::Tuple{}, d_discontinuities::Tuple{}, save_idxs::Nothing, save_everystep::Bool, save_on::Bool, save_start::Bool, save_end::Nothing, callback::Nothing, dense::Bool, calck::Bool, dt::Quantity{…}, dtmin::Nothing, dtmax::Quantity{…}, force_dtmin::Bool, adaptive::Bool, gamma::Rational{…}, abstol::Nothing, reltol::Nothing, qmin::Rational{…}, qmax::Int64, qsteady_min::Int64, qsteady_max::Int64, beta1::Nothing, beta2::Nothing, qoldinit::Rational{…}, controller::Nothing, fullnormalize::Bool, failfactor::Int64, maxiters::Int64, internalnorm::typeof(DiffEqBase.ODE_DEFAULT_NORM), internalopnorm::typeof(LinearAlgebra.opnorm), isoutofdomain::typeof(DiffEqBase.ODE_DEFAULT_ISOUTOFDOMAIN), unstable_check::typeof(DiffEqBase.ODE_DEFAULT_UNSTABLE_CHECK), verbose::Bool, timeseries_errors::Bool, dense_errors::Bool, advance_to_tstop::Bool, stop_at_next_tstop::Bool, initialize_save::Bool, progress::Bool, progress_steps::Int64, progress_name::String, progress_message::typeof(DiffEqBase.ODE_DEFAULT_PROG_MESSAGE), progress_id::Symbol, userdata::Nothing, allow_extrapolation::Bool, initialize_integrator::Bool, alias_u0::Bool, alias_du0::Bool, initializealg::OrdinaryDiffEq.DefaultInit, kwargs::@Kwargs{})
@ OrdinaryDiffEq ~/.julia/packages/OrdinaryDiffEq/qxpST/src/solve.jl:220
[4] __solve(::ODEProblem{…}, ::Tsit5{…}; kwargs::@Kwargs{…})
@ OrdinaryDiffEq ~/.julia/packages/OrdinaryDiffEq/qxpST/src/solve.jl:5
[5] solve_call(_prob::ODEProblem{…}, args::Tsit5{…}; merge_callbacks::Bool, kwargshandle::Nothing, kwargs::@Kwargs{…})
@ DiffEqBase ~/.julia/packages/DiffEqBase/NYLhl/src/solve.jl:557
[6] solve_up(prob::ODEProblem{…}, sensealg::Nothing, u0::Vector{…}, p::SciMLBase.NullParameters, args::Tsit5{…}; kwargs::@Kwargs{…})
@ DiffEqBase ~/.julia/packages/DiffEqBase/NYLhl/src/solve.jl:1006
[7] solve(prob::ODEProblem{…}, args::Tsit5{…}; sensealg::Nothing, u0::Nothing, p::Nothing, wrap::Val{…}, kwargs::@Kwargs{…})
@ DiffEqBase ~/.julia/packages/DiffEqBase/NYLhl/src/solve.jl:929
[8] top-level scope
@ REPL[21]:1
Some type information was truncated. Use `show(err)` to see complete types. |
Trying out a DynamicQuantities.jl example with DifferentialEquations.jl but running into some issues with the use of
oneunit(::Type{T})
rather thanoneunit(::T)
. I think changing to the latter will make things compatible with both DynamicQuantities and Unitful.The text was updated successfully, but these errors were encountered: