Hello,
I wish to integrate a system of jump differential equations with JumpProblem. Variables in the system behave differently and I discrimiate between them using ComponentArray. The problem requires the definition of multiple jumps. I encounter the following problem. If I define the affect! functions manually one-by-one the code works as expected. If instead I create them with a function I get the error type NamedTuple has no field u. I spent some time inquiring the error but to no avail. I would be very interested to know what I am doing wrong.
Many thanks for your attention.
Below the two codes. The first works as expected
function psi!(du, u, p, t)
du.st_vec .= 0.0
du.mpr = 6.0.*c(t)*u.mpr/4.0
du.jpr = 0.0
end
sse_prob = ODEProblem(psi!, u0, (0.0, tf),p)
function rate!(u,p,t)
return c(t)/4.0
end
# "Manual" definition of the affect functions
function affect1!(integrator)
v = copyto!(integrator.p.tmp_psi, integrator.u.u.st_vec) # copy this to avoid aliasing later
mart = integrator.u.u.mpr
jump = integrator.u.u.jpr
jump_prob = real(dot(v,v))
if jump_prob > 0.0
normv = sqrt(jump_prob)
else
normv=1.0
end
mul!(integrator.u.u.st_vec, integrator.p.jump_ops[1], v, 1/normv,false)
integrator.u.u.mpr = -2.0*mart
integrator.u.u.jpr = -2.0*jump
nothing
end
function affect2!(integrator)
v = copyto!(integrator.p.tmp_psi, integrator.u.u.st_vec) # copy this to avoid aliasing later
mart = integrator.u.u.mpr
jump = integrator.u.u.jpr
jump_prob = real(dot(v,v))
if jump_prob > 0.0
normv = sqrt(jump_prob)
else
normv=1.0
end
mul!(integrator.u.u.st_vec, integrator.p.jump_ops[2], v, 1/normv,false)
integrator.u.u.mpr = -2.0*mart
integrator.u.u.jpr = -2.0*jump
nothing
end
function affect3!(integrator)
v = copyto!(integrator.p.tmp_psi, integrator.u.u.st_vec) # copy this to avoid aliasing later
mart = integrator.u.u.mpr
jump = integrator.u.u.jpr
jump_prob = real(dot(v,v))
if jump_prob > 0.0
normv = sqrt(jump_prob)
else
normv=1.0
end
mul!(integrator.u.u.st_vec, integrator.p.jump_ops[3], v, 1/normv,false)
integrator.u.u.mpr = -2.0*mart
integrator.u.u.jpr = -2.0*jump
nothing
end
# Construction of the JumpSet
jump1=VariableRateJump(rate!, affect1!)
jump2=VariableRateJump(rate!, affect2!)
jump3=VariableRateJump(rate!, affect3!)
jump_prob = JumpProblem(sse_prob, DirectFW(), jump1,jump2,jump3 );
ensemble_sse = EnsembleProblem(jump_prob)
jump_sol_sse = DifferentialEquations.solve(ensemble_sse, Tsit5(), EnsembleSerial(), trajectories=num_traj; save_everystep=true, dense=false,abstol=1e-8,reltol=1e-8,maxiters=Int(1e6));
As said the above code gives the expected result.
If I now replace the second part of the above with
# Function to construct the distinct Jumps
function create_jump_affect(affected_id::Int)
function jump_affect_by_id!(integrator)
v = copyto!(integrator.p.tmp_psi, integrator.u.u.st_vec) # copy this to avoid aliasing later
mart = integrator.u.u.mpr
jump = integrator.u.u.jpr
jump_prob = real(dot(v,v))
if jump_prob > 0.0
normv = sqrt(jump_prob)
else
normv=1.0
end
mul!(integrator.u.u.st_vec, integrator.p.jump_ops[affected_id], v, 1/normv,false)
integrator.u.u.mpr = -2.0*mart
integrator.u.u.jpr = -2.0*jump
nothing
end
return jump_affect_by_id!
end
# Generate individual jumps by putting them in an array
jumps = VariableRateJump[]
for i in 1:3
push!(jumps,VariableRateJump(rate!, create_jump_affect(i)))
end
# Create a JumpSet with the provided constant rate jumps and empty/nil for other jump types
function create_jump_set(variable_jumps::Vector{VariableRateJump})
return JumpSet((), tuple(variable_jumps...), nothing, nothing)
end
# JumpSet
jump_prob = JumpProblem(sse_prob, DirectFW(), jumpset )
ensemble_sse = EnsembleProblem(jump_prob)
jump_sol_sse = DifferentialEquations.solve(ensemble_sse, Tsit5(), EnsembleSerial(), trajectories=num_traj; save_everystep=true, dense=false,abstol=1e-8,reltol=1e-8,maxiters=Int(1e6));
I get the error
type NamedTuple has no field u