Hi,
As part of my ODE problem, I create a mutable struct Event to store data in a readable manner within the Callback framework of DifferentialEquations.jl. I have then implemented an instance Buffer of type Event to continuously track data for a fixed duration already before an event gets detected by a given Callback function. For some reason, I am not able to update the Buffer instance properly within my framework. My code looks like:
#Create new type "Event" with 4 fields
mutable struct Event
t::Array{Float64,1}
u::Array{Float64,3}
v::Array{Float64,3}
θ::Array{Float64,3}
end
The 3-dimensional arrays u,v and θ each contain different properties for a series of [time, x position, y position] respectively.
I initialize the Buffer as zeros arrays and create a function to update the Buffer of fixed size with the latest values from the ode integrator:
#Update Buffer values with new integrator values
function buffer!(integrator,Buffer::Event)
update!(Buffer.t,integrator.t)
update!(Buffer.u,integrator.u[:,:,1])
update!(Buffer.v,integrator.u[:,:,2])
update!(Buffer.θ,integrator.u[:,:,3])
end
where the function update! is given by:
#Functions to copy old values and add new ones at the end (updating buffer)
function update!(u::Array{Float64,3},v::Array{Float64,2})
u[1:end-1,:,:] = u[2:end,:,:] #move each value
u[end,:,:] = v #add new value at the end
end
function update!(u::Array{Float64,1},v::Float64)
u[1:end-1] = u[2:end] #move each value
u[end] = v #add new value at the end
end
Finally, I use the buffer! function within a condition and affect! function that I pass as a DiscreteCallback.
When I print the output of u,v and θ for the last five timesteps for a single position x=1, y=1 in order to check the buffer update at each iteration, I obtain:
#Iteration 1
"Buffer.u[end-5:end,1,1] = [0.0, 0.0, 0.0, -0.644079, -0.000371415, 0.0230215]"
"Buffer.v[...] = [0.0, 0.0, 0.0, -0.644079, -0.000371415, 0.0230215]"
"Buffer.θ[...] = [0.0, 0.0, 0.0, -0.644079, -0.000371415, 0.0230215]"
#Iteration 2
"Buffer.u[...] = [-0.644079, -0.000371415, 0.0230215, -0.644093, -0.000400668, 0.0242796]"
"Buffer.v[...] = [-0.644079, -0.000371415, 0.0230215, -0.644093, -0.000400668, 0.0242796]"
"Buffer.θ[...] = [-0.644079, -0.000371415, 0.0230215, -0.644093, -0.000400668, 0.0242796]"
...
What I would like to see is:
#Iteration 1
"Buffer.u[...] = [0.0, 0.0, 0.0, 0.0, 0.0, -0.644079]"
"Buffer.v[...] = [0.0, 0.0, 0.0, 0.0, 0.0, -0.000371415]"
"Buffer.θ[...] = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0230215]"
#Iteration 2
"Buffer.u[...] = [0.0, 0.0, 0.0, 0.0, -0.644079, -0.644093]"
"Buffer.v[...] = [0.0, 0.0, 0.0, 0.0, -0.000371415, -0.000400668]"
"Buffer.θ[...] = [0.0, 0.0, 0.0, 0.0, 0.0230215, 0.0242796]"
...
As you can see, update! copies all three integrator.u arrays [:, :, 1], [:, :, 2] and [:, :, 3] to each field u,v and θ instead of copying them individually to the respective field. The update of Buffer.t works fine and if I just update a single field (u,v or θ) it also works fine. As additional information, my Buffer variable is global to be recognized in the callback function. I use Julia 1.1.1 and I have tried implementations with getfield and setfield! which do not change my issue.
Despite the limited information, I would be thankful for any advice on what I am doing wrong here and how I can address and update the individual fields correctly.
Luis