Hm, as I said I don’t have experience with DifferentialEquations.jl, but as far as I can tell and debug, every variable is a PrecisionCarrier.
I just took the OP’s code and put precify on everything:
using DifferentialEquations
using Plots
using PrecisionCarriers
function solve_equations()
kavlength = 599
k = precify(Vector(logrange(1, 10^4, kavlength + 1)))
kav = precify((k[1:end - 1] + k[2:end]) / 2)
iconds = precify(initialConditions(kav, kavlength))
tspan = precify((0.0, 1.5))
teval = range(tspan[1], tspan[2], 501) # already a precified range from tspan
ddrho0 = precify(zeros(kavlength))
omega2 = precify(zeros(kavlength))
prob = ODEProblem(diffEquations!, iconds, tspan, (kav, kavlength, ddrho0, omega2), saveat=teval)
sol = solve(prob, Vern9(), abstol=precify(1e-15), reltol=precify(1e-15))
# savefig(heatmap(sol.t, kav, log10.(abs.(sol[6:5 + kavlength, :])), yscale=:log10, dpi=600, title="\\delta\\rho_0", xlabel="t", ylabel="k"), "heatmap.svg")
end
function initialConditions(kav, kavlength)
rho0 = ones(kavlength) ./ (2 .* sqrt.(16 .+ kav.^2))
drho0 = zeros(size(rho0))
arr = [15, -0.8, 1, 0.001, 0]
initial = vcat(arr, rho0, drho0)
return initial
end
function ddrho0!(a, H, omega2, rho0, drho0, ddrho0)
for i in eachindex(omega2)
rho2 = (0.25 + omega2[i] * rho0[i]^2 + drho0[i]^2 / 4) / (2 * rho0[i])
ddrho0[i] = 4 * rho2 / a^2 - H * drho0[i] - 4 * omega2[i] * rho0[i] / a^2
end
nothing
end
function diffEquations!(du, u, args, t)
kav, kavlength, ddrho0, omega2 = args
infl, dinfl, a, sigma, dsigma = @view u[1:5]
rho0 = @view u[6:6 + kavlength - 1]
drho0 = @view u[6 + kavlength:6 + 2 * kavlength - 1]
H = sqrt((dinfl^2 + infl^2) / 6)
da = a * H
R = dinfl^2 - 2 * infl^2
m2Eff = -a^2 * R / 30
@. omega2 = kav^2 + m2Eff
ddrho0!(a, H, omega2, rho0, drho0, ddrho0)
ddinfl = -3 * H * dinfl - infl
ddsigma = - H * dsigma - m2Eff * sigma / a^2
du[1] = dinfl
du[2] = ddinfl
du[3] = da
du[4] = dsigma
du[5] = ddsigma
du[6:5 + kavlength] .= drho0
du[6 + kavlength:5 + 2 * kavlength] .= ddrho0
nothing
end
solve_equations()
If I do the evil thing and force a convert(Float64, PrecisionCarrier)
to return a PrecisionCarrier again, I get the following error, because somewhere it seems to cache values into a Vector{Float64}
:
TypeError: in typeassert, expected Float64, got a value of type PrecisionCarrier{Float64}
Stacktrace:
[1] setindex!(A::Vector{Float64}, x::PrecisionCarrier{Float64}, i::Int64)
@ Base ./array.jl:987
[2] macro expansion
@ ~/.julia/packages/DiffEqBase/yhgdI/src/calculate_residuals.jl:107 [inlined]
[3] macro expansion
@ ./simdloop.jl:77 [inlined]
[4] calculate_residuals!
@ ~/.julia/packages/DiffEqBase/yhgdI/src/calculate_residuals.jl:106 [inlined]
[5] perform_step!(integrator::OrdinaryDiffEqCore.ODEIntegrator{Vern9{typeof(OrdinaryDiffEqCore.trivial_limiter!), typeof(OrdinaryDiffEqCore.trivial_limiter!), Static.False}, true, Vector{PrecisionCarrier{Float64}}, Nothing, PrecisionCarrier{Float64}, Tuple{Vector{PrecisionCarrier{Float64}}, Int64, Vector{PrecisionCarrier{Float64}}, Vector{PrecisionCarrier{Float64}}}, PrecisionCarrier{Float64}, PrecisionCarrier{Float64}, PrecisionCarrier{Float64}, PrecisionCarrier{Float64}, Vector{Vector{PrecisionCarrier{Float64}}}, ODESolution{PrecisionCarrier{Float64}, 2, Vector{Vector{PrecisionCarrier{Float64}}}, Nothing, Nothing, Vector{PrecisionCarrier{Float64}}, Vector{Vector{Vector{PrecisionCarrier{Float64}}}}, Nothing, ODEProblem{Vector{PrecisionCarrier{Float64}}, Tuple{PrecisionCarrier{Float64}, PrecisionCarrier{Float64}}, true, Tuple{Vector{PrecisionCarrier{Float64}}, Int64, Vector{PrecisionCarrier{Float64}}, Vector{PrecisionCarrier{Float64}}}, ODEFunction{true, SciMLBase.AutoSpecialize, typeof(diffEquations!), LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing, Nothing, Nothing}, @Kwargs{saveat::LinRange{PrecisionCarrier{Float64}, Int64}}, SciMLBase.StandardODEProblem}, Vern9{typeof(OrdinaryDiffEqCore.trivial_limiter!), typeof(OrdinaryDiffEqCore.trivial_limiter!), Static.False}, OrdinaryDiffEqCore.InterpolationData{ODEFunction{true, SciMLBase.AutoSpecialize, typeof(diffEquations!), LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing, Nothing, Nothing}, Vector{Vector{PrecisionCarrier{Float64}}}, Vector{PrecisionCarrier{Float64}}, Vector{Vector{Vector{PrecisionCarrier{Float64}}}}, Nothing, OrdinaryDiffEqVerner.Vern9Cache{Vector{PrecisionCarrier{Float64}}, Vector{PrecisionCarrier{Float64}}, Vector{Float64}, typeof(OrdinaryDiffEqCore.trivial_limiter!), typeof(OrdinaryDiffEqCore.trivial_limiter!), Static.False}, Nothing}, SciMLBase.DEStats, Nothing, Nothing, Nothing, Nothing}, ODEFunction{true, SciMLBase.AutoSpecialize, typeof(diffEquations!), LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing, Nothing, Nothing}, OrdinaryDiffEqVerner.Vern9Cache{Vector{PrecisionCarrier{Float64}}, Vector{PrecisionCarrier{Float64}}, Vector{Float64}, typeof(OrdinaryDiffEqCore.trivial_limiter!), typeof(OrdinaryDiffEqCore.trivial_limiter!), Static.False}, OrdinaryDiffEqCore.DEOptions{PrecisionCarrier{Float64}, PrecisionCarrier{Float64}, PrecisionCarrier{Float64}, PrecisionCarrier{Float64}, PIController{Rational{Int64}}, typeof(DiffEqBase.ODE_DEFAULT_NORM), typeof(LinearAlgebra.opnorm), Nothing, CallbackSet{Tuple{}, Tuple{}}, typeof(DiffEqBase.ODE_DEFAULT_ISOUTOFDOMAIN), typeof(DiffEqBase.ODE_DEFAULT_PROG_MESSAGE), typeof(DiffEqBase.ODE_DEFAULT_UNSTABLE_CHECK), DataStructures.BinaryHeap{PrecisionCarrier{Float64}, DataStructures.FasterForward}, DataStructures.BinaryHeap{PrecisionCarrier{Float64}, DataStructures.FasterForward}, Nothing, Nothing, Int64, Tuple{}, LinRange{PrecisionCarrier{Float64}, Int64}, Tuple{}}, Nothing, Float64, Nothing, OrdinaryDiffEqCore.DefaultInit, Nothing}, cache::OrdinaryDiffEqVerner.Vern9Cache{Vector{PrecisionCarrier{Float64}}, Vector{PrecisionCarrier{Float64}}, Vector{Float64}, typeof(OrdinaryDiffEqCore.trivial_limiter!), typeof(OrdinaryDiffEqCore.trivial_limiter!), Static.False}, repeat_step::Bool)
@ OrdinaryDiffEqVerner ~/.julia/packages/OrdinaryDiffEqVerner/rIAEX/src/verner_rk_perform_step.jl:1152
[6] perform_step!
@ ~/.julia/packages/OrdinaryDiffEqVerner/rIAEX/src/verner_rk_perform_step.jl:1043 [inlined]
[7] solve!(integrator::OrdinaryDiffEqCore.ODEIntegrator{Vern9{typeof(OrdinaryDiffEqCore.trivial_limiter!), typeof(OrdinaryDiffEqCore.trivial_limiter!), Static.False}, true, Vector{PrecisionCarrier{Float64}}, Nothing, PrecisionCarrier{Float64}, Tuple{Vector{PrecisionCarrier{Float64}}, Int64, Vector{PrecisionCarrier{Float64}}, Vector{PrecisionCarrier{Float64}}}, PrecisionCarrier{Float64}, PrecisionCarrier{Float64}, PrecisionCarrier{Float64}, PrecisionCarrier{Float64}, Vector{Vector{PrecisionCarrier{Float64}}}, ODESolution{PrecisionCarrier{Float64}, 2, Vector{Vector{PrecisionCarrier{Float64}}}, Nothing, Nothing, Vector{PrecisionCarrier{Float64}}, Vector{Vector{Vector{PrecisionCarrier{Float64}}}}, Nothing, ODEProblem{Vector{PrecisionCarrier{Float64}}, Tuple{PrecisionCarrier{Float64}, PrecisionCarrier{Float64}}, true, Tuple{Vector{PrecisionCarrier{Float64}}, Int64, Vector{PrecisionCarrier{Float64}}, Vector{PrecisionCarrier{Float64}}}, ODEFunction{true, SciMLBase.AutoSpecialize, typeof(diffEquations!), LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing, Nothing, Nothing}, @Kwargs{saveat::LinRange{PrecisionCarrier{Float64}, Int64}}, SciMLBase.StandardODEProblem}, Vern9{typeof(OrdinaryDiffEqCore.trivial_limiter!), typeof(OrdinaryDiffEqCore.trivial_limiter!), Static.False}, OrdinaryDiffEqCore.InterpolationData{ODEFunction{true, SciMLBase.AutoSpecialize, typeof(diffEquations!), LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing, Nothing, Nothing}, Vector{Vector{PrecisionCarrier{Float64}}}, Vector{PrecisionCarrier{Float64}}, Vector{Vector{Vector{PrecisionCarrier{Float64}}}}, Nothing, OrdinaryDiffEqVerner.Vern9Cache{Vector{PrecisionCarrier{Float64}}, Vector{PrecisionCarrier{Float64}}, Vector{Float64}, typeof(OrdinaryDiffEqCore.trivial_limiter!), typeof(OrdinaryDiffEqCore.trivial_limiter!), Static.False}, Nothing}, SciMLBase.DEStats, Nothing, Nothing, Nothing, Nothing}, ODEFunction{true, SciMLBase.AutoSpecialize, typeof(diffEquations!), LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing, Nothing, Nothing}, OrdinaryDiffEqVerner.Vern9Cache{Vector{PrecisionCarrier{Float64}}, Vector{PrecisionCarrier{Float64}}, Vector{Float64}, typeof(OrdinaryDiffEqCore.trivial_limiter!), typeof(OrdinaryDiffEqCore.trivial_limiter!), Static.False}, OrdinaryDiffEqCore.DEOptions{PrecisionCarrier{Float64}, PrecisionCarrier{Float64}, PrecisionCarrier{Float64}, PrecisionCarrier{Float64}, PIController{Rational{Int64}}, typeof(DiffEqBase.ODE_DEFAULT_NORM), typeof(LinearAlgebra.opnorm), Nothing, CallbackSet{Tuple{}, Tuple{}}, typeof(DiffEqBase.ODE_DEFAULT_ISOUTOFDOMAIN), typeof(DiffEqBase.ODE_DEFAULT_PROG_MESSAGE), typeof(DiffEqBase.ODE_DEFAULT_UNSTABLE_CHECK), DataStructures.BinaryHeap{PrecisionCarrier{Float64}, DataStructures.FasterForward}, DataStructures.BinaryHeap{PrecisionCarrier{Float64}, DataStructures.FasterForward}, Nothing, Nothing, Int64, Tuple{}, LinRange{PrecisionCarrier{Float64}, Int64}, Tuple{}}, Nothing, Float64, Nothing, OrdinaryDiffEqCore.DefaultInit, Nothing})
@ OrdinaryDiffEqCore ~/.julia/packages/OrdinaryDiffEqCore/zs1s7/src/solve.jl:620
[8] #__solve#62
@ ~/.julia/packages/OrdinaryDiffEqCore/zs1s7/src/solve.jl:7 [inlined]
[9] __solve
@ ~/.julia/packages/OrdinaryDiffEqCore/zs1s7/src/solve.jl:1 [inlined]
[10] solve_call(_prob::ODEProblem{Vector{PrecisionCarrier{Float64}}, Tuple{PrecisionCarrier{Float64}, PrecisionCarrier{Float64}}, true, Tuple{Vector{PrecisionCarrier{Float64}}, Int64, Vector{PrecisionCarrier{Float64}}, Vector{PrecisionCarrier{Float64}}}, ODEFunction{true, SciMLBase.AutoSpecialize, typeof(diffEquations!), LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing, Nothing, Nothing}, @Kwargs{saveat::LinRange{PrecisionCarrier{Float64}, Int64}}, SciMLBase.StandardODEProblem}, args::Vern9{typeof(OrdinaryDiffEqCore.trivial_limiter!), typeof(OrdinaryDiffEqCore.trivial_limiter!), Static.False}; merge_callbacks::Bool, kwargshandle::Nothing, kwargs::@Kwargs{abstol::PrecisionCarrier{Float64}, reltol::PrecisionCarrier{Float64}})
@ DiffEqBase ~/.julia/packages/DiffEqBase/yhgdI/src/solve.jl:667
[11] solve_call
@ ~/.julia/packages/DiffEqBase/yhgdI/src/solve.jl:624 [inlined]
[12] #solve_up#45
@ ~/.julia/packages/DiffEqBase/yhgdI/src/solve.jl:1199 [inlined]
[13] solve_up
@ ~/.julia/packages/DiffEqBase/yhgdI/src/solve.jl:1177 [inlined]
[14] #solve#43
@ ~/.julia/packages/DiffEqBase/yhgdI/src/solve.jl:1089 [inlined]
[15] solve_equations()
@ Main ~/repos/PrecisionCarriers.jl/notebooks/jl_notebook_cell_df34fa98e69747e1a8f8a730347b8e2f_W0sZmlsZQ==.jl:16
[16] top-level scope
@ ~/repos/PrecisionCarriers.jl/notebooks/jl_notebook_cell_df34fa98e69747e1a8f8a730347b8e2f_W0sZmlsZQ==.jl:64
I realize that convert
should always return the requested type, so I patched that behavior out of my package now. With the “normal” convert
behavior, it now runs but reports basically zero epsilons everywhere, which I find hard to believe. Also, it still apparently saves a Vector{Float64}
somewhere.
You can get the crashing behavior again by changing the first convert overload in src/functionality/conversion.jl
to
function Base.convert(::Type{T}, p::P) where {T <: AbstractFloat}
return P{T}(convert(T, p.x), p.big)
end