У меня есть динамическая система, для которой может произойти много событий. Я хочу прекратить интеграцию траектории по событию, но также хочу знать, какое событие было активировано.

Обходной путь, который я нашел, заключается в использовании глобальной переменной для сохранения индекса события в функции affect!. Вот модифицированная версия примера прыгающего мяча. :

using DifferentialEquations

function f(du,u,p,t)
  du[1] = u[2]
  du[2] = -p
  du[3] = u[4]
  du[4] = 0.0
end

function condition(out,u,t,integrator) # Event when event_f(u,t) == 0
  out[1] = u[1]
  out[2] = (u[3] - 10.0)u[3]
end

event_idx = [0, ]  # global variable
function affect!(integrator, idx)
    event_idx[1] = idx
    terminate!(integrator)
end

cb = VectorContinuousCallback(condition,affect!,2)

u0 = [50.0,0.0,0.0,2.0]
tspan = (0.0,15.0)
p = 9.8
prob = ODEProblem(f,u0,tspan,p)
sol = solve(prob,Tsit5(),callback=cb,dt=1e-3,adaptive=false)
println(sol.retcode)
println(event_idx) # [1]

Есть ли лучшее решение для этого?

1
xdze2 23 Окт 2019 в 14:50
Вы также можете использовать integrator.p в качестве кеша, изменить это значение и использовать sol.prob.p в конце. Но да, это или Ref — прекрасный способ сделать это.
 – 
Chris Rackauckas
24 Окт 2019 в 17:30
Спасибо! Я не знал, что могу получить доступ к sol.prob.p (и для дифференциальных уравнений.jl это причина, по которой я пытаюсь перейти на Джулию)
 – 
xdze2
25 Окт 2019 в 14:45

1 ответ

Вы можете использовать integrator.p в качестве кеша, изменить это значение и использовать sol.prob.p в конце. Но да, это или Ref — прекрасный способ сделать это.

0
Chris Rackauckas 21 Май 2021 в 15:24