-
-
Notifications
You must be signed in to change notification settings - Fork 120
Closed
Description
Hi!
I am trying to create a workspace using DEDataArray as follow:
mutable struct Workspace{T} <: DEDataVector{T}
x::Vector{T} = zeros(12)
q::Quaternion = Quaternion(1,0,0,0)where Quaternion is defined in ReferenceFrameRotations.jl. Here, I get the following error:
ERROR: LoadError: setindex! not defined for Quaternion{Float64}
Stacktrace:
[1] error(::String, ::Type{T} where T) at ./error.jl:42
[2] error_if_canonical_setindex(::IndexLinear, ::Quaternion{Float64}, ::Int64) at ./abstractarray.jl:1081
[3] setindex! at ./abstractarray.jl:1072 [inlined]
[4] copyto!(::Quaternion{Float64}, ::Quaternion{Float64}) at ./multidimensional.jl:962
[5] recursivecopy!(::Quaternion{Float64}, ::Quaternion{Float64}) at /Users/ronan.arraes/.julia/packages/RecursiveArrayTools/YIS5B/src/utils.jl:25
[6] macro expansion at /Users/ronan.arraes/.julia/packages/DiffEqBase/8A5uo/src/data_array.jl:60 [inlined]
[7] recursivecopy!(::Workspace{Float64}, ::Workspace{Float64}) at /Users/ronan.arraes/.julia/packages/DiffEqBase/8A5uo/src/data_array.jl:60
[8] apply_step!(::OrdinaryDiffEq.ODEIntegrator{Tsit5,true,Workspace{Float64},Nothing,Float64,Tuple{Configuration{Float64},Auxiliary{OrbitPropagatorJ4{Float64},Float64},StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}},Float64,Float64,Float64,Array{Workspace{Float64},1},ODESolution{Float64,2,Array{Workspace{Float64},1},Nothing,Nothing,Array{Float64,1},Array{Array{Workspace{Float64},1},1},ODEProblem{Workspace{Float64},Tuple{Float64,Float64},true,Tuple{Configuration{Float64},Auxiliary{OrbitPropagatorJ4{Float64},Float64},StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}},ODEFunction{true,typeof(dyn),UniformScaling{Bool},Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing},Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}},DiffEqBase.StandardODEProblem},Tsit5,OrdinaryDiffEq.InterpolationData{ODEFunction{true,typeof(dyn),UniformScaling{Bool},Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing},Array{Workspace{Float64},1},Array{Float64,1},Array{Array{Workspace{Float64},1},1},OrdinaryDiffEq.Tsit5Cache{Workspace{Float64},Workspace{Float64},Workspace{Float64},OrdinaryDiffEq.Tsit5ConstantCache{Float64,Float64}}},DiffEqBase.DEStats},ODEFunction{true,typeof(dyn),UniformScaling{Bool},Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing},OrdinaryDiffEq.Tsit5Cache{Workspace{Float64},Workspace{Float64},Workspace{Float64},OrdinaryDiffEq.Tsit5ConstantCache{Float64,Float64}},OrdinaryDiffEq.DEOptions{Float64,Float64,Float64,Float64,typeof(DiffEqBase.ODE_DEFAULT_NORM),typeof(opnorm),CallbackSet{Tuple{},Tuple{DiscreteCallback{typeof(condition_control_loop),typeof(affect_control_loop!),typeof(DiffEqBase.INITIALIZE_DEFAULT)}}},typeof(DiffEqBase.ODE_DEFAULT_ISOUTOFDOMAIN),typeof(DiffEqBase.ODE_DEFAULT_PROG_MESSAGE),typeof(DiffEqBase.ODE_DEFAULT_UNSTABLE_CHECK),DataStructures.BinaryHeap{Float64,DataStructures.LessThan},DataStructures.BinaryHeap{Float64,DataStructures.LessThan},Nothing,Nothing,Int64,StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},Array{Float64,1},Array{Float64,1}},Workspace{Float64},Float64,Nothing,OrdinaryDiffEq.DefaultInit}) at /Users/ronan.arraes/.julia/packages/OrdinaryDiffEq/V4HnF/src/integrators/integrator_utils.jl:288
The problem is that Quaternion (like SVector) is an immutable AbstractArray. In the current code, this is handle as follows:
if Tf <: Union{Number,SArray}
expressions[i] = :( dest.$f = getfield( src, $qf ) )
elseif Tf <: AbstractArray
expressions[i] = :( recursivecopy!(dest.$f, getfield( src, $qf ) ) )
else
expressions[i] = :( dest.$f = deepcopy( getfield( src, $qf ) ) )
endThus, an element of type SVector is copied as b = a. However, Quaternion will be copied using recursivecopy!. This, in turn, will call copyto! that is not defined.
Thus, I have two suggestions:
- Create a simple API like
DiffEqBase.ismutablearray(::Some_type) = true. If this istrue, then proceed withrecursivecopy!. Otherwise, copy the element usingb = a. - (I think this is better) Check if the method
setindex!is implemented for the type. If it is, then proceed withrecursivecopy!. Otherwise, copy the element usingb = a.
P.S.: If this is accepted, I can submit a PR.
Metadata
Metadata
Assignees
Labels
No labels