在DifferentialEquations.jl中的n个回调之后,是否有惯用的方式终止集成

Rol*_*wer 5 differential-equations julia

首先,我正在使用该DifferentialEquations.jl库,这太棒了!无论如何,我的问题如下:

例如,我有以下微分方程:

function f(du, u, t)
    du[1] = u[3]
    du[2] = u[4]
    du[3] = -u[1] - 2 * u[1] * u[2]
    du[4] = -u[2] - u[1]^2 + u[2]^2
end
Run Code Online (Sandbox Code Playgroud)

我有一个回调,每次轨迹越过y轴都会触发:

function condition(u, t, integrator)
    u[2]
end
Run Code Online (Sandbox Code Playgroud)

但是,我需要积分恰好在3个交叉点后终止。我知道可以通过使用以下效果终止集成:

function affect!(integrator)
    terminate!(integrator)
end
Run Code Online (Sandbox Code Playgroud)

但是在满足终止条件之前,允许对回调数目进行计数的正确方法是什么。此外,是否有一种方法可以将此方法扩展到具有n个不同计数的n个事件?

在研究中,我经常需要查看Poincare映射,然后将第一,第二,第三等返回到该映射,因此我需要一个框架来允许我执行此计数终止。我对Julia还是陌生的,因此我想尽早增强良好的惯用代码。感谢您的任何帮助,请随时提出要求。

Kor*_*sbo 5

有一个userdata关键字自变量solve对此很有用。它允许您将对象传递给积分器。回调函数可以创造性地使用这些对象。

如果传递userdata = Dict(:my_key=>:my_value)solve,那么你可以访问此integrator.opts.userdata[:my_key]

这是一个最小的示例,它控制回调在实际终止模拟之前被触发多少次:

function f(du, u, t)
    du[1] = sin(t)
end
function condition(u, t, integrator)
    u[1] 
end

function affect!(integrator)
    integrator.opts.userdata[:callback_count] +=1
    if integrator.opts.userdata[:callback_count] == integrator.opts.userdata[:max_count]
        terminate!(integrator)
    end
end


callback = ContinuousCallback(condition, affect!)

u0 = [-1.]
tspan = (0., 100.)

prob = ODEProblem(f, u0, tspan)
sol = solve(prob; callback=callback, userdata=Dict(:callback_count=>0, :max_count=>3))
Run Code Online (Sandbox Code Playgroud)