Julia中二阶常微分方程的不稳定性

Julia中二阶常微分方程的不稳定性,julia,differential-equations,Julia,Differential Equations,我想数值求解一个二阶常微分方程(见下面的第一个方程),它依赖于相对简单的函数(g,g'/g和f/g是cos,sine,cosh,sinh的叠加)。主要问题是这些函数依赖于函数α(例如cos(alpha*phi)),并且只知道其导数(参见下面的第二个等式,σ和d是固定的) 这显然很难解决,所以我首先尝试了更简单的方法,设置alpha=phi²。我的代码返回警告警告:自动dt将启动dt设置为NaN,导致不稳定。后接警告:检测到NaN dt。可能是状态、参数或派生值中的NaN值导致了此结果。代码运行

我想数值求解一个二阶常微分方程(见下面的第一个方程),它依赖于相对简单的函数(g,g'/g和f/g是cos,sine,cosh,sinh的叠加)。主要问题是这些函数依赖于函数α(例如cos(alpha*phi)),并且只知道其导数(参见下面的第二个等式,σ和d是固定的)

这显然很难解决,所以我首先尝试了更简单的方法,设置alpha=phi²。我的代码返回警告
警告:自动dt将启动dt设置为NaN,导致不稳定。
后接
警告:检测到NaN dt。可能是状态、参数或派生值中的NaN值导致了此结果。
代码运行,但绘制解决方案时会出现错误
ArgumentError:不允许对空集合进行缩减
,我认为这表明我的解决方案为空

我发现了一个类似的问题,其中出现错误是因为参数给出了发散的解决方案,但在我的例子中,ODE中的所有函数都在感兴趣的区间(-5,5)上定义得很好,所以我怀疑这是我的情况。那么,我有三个问题:

  • 如何知道NaN值的确切位置?
  • 如何避免此错误?
  • 有没有办法将完整表达式(d alpha/d phi)实现到积分器中?
  • 非常感谢

    编辑:根据@Lutz Lehmann的评论,我试图减少二阶常微分方程并同时求解三个方程,但Julia告诉我
    未定义错误:α未定义
    ,尽管我明确将其定义为第三个方程。我做错了什么

    EDIT2:正确重命名函数后,错误消失。但是,我收到了与以前相同的警告和错误,添加了
    Warning:First function call-producted-NaNs。正在退出。
    首先

    EDIT3:我现在已经编写了dα的表达式,这是一种更简单的方法,并更正了代码中的两个错误(由@Lutz Lehmann指出的符号和缺少的右括号)。在给α和a'一个小的非零初始值之后,我可以看到解在时间φ>2.12时爆炸,所以我猜问题就在那里

    EDIT4:我现在离问题的根源更近了,但我不知道如何进一步。我已经试着去看dα/dа方程中哪些项有问题,似乎sinh和cosh项出现了不稳定性。例如,尝试解算
    dα/dñ=2d*sinh(s2*α*ñ)
    会立即扰乱解算器,并返回
    警告:检测到不稳定。正在中止
    。但是朱莉娅应该能解决这个问题,那么我还缺什么呢


    为什么不把alpha方程和A的方程一起解呢?为3个组件建立一个一阶系统,并使用通用IVP解算器。我不确定你所说的“3个组件”是什么意思。你是说我应该把二阶常微分方程分解成一阶方程?是的,就是这样。您可以自动获得α的正确值,无需进行任何进一步的假设。(继续使用α而不是u[3]来更接近公式)((文本标记中的代码使用单引号,三引号代码围栏仅适用于段落。我相信它们在注释中不起作用。))这是针对
    g
    函数内部的。这些都应该是
    g(α,φ)
    ,然后用
    α
    替换所有
    α(φ)
    。另一种策略是使用密集输出单独求解第三个方程,然后使用密集输出插值函数获得
    α(ν)
    的值。符号错误在
    du[2]
    中,不应有加号。你能计算一下ODE函数在初始点的结果,看看是否有不规则的地方吗?
    using DifferentialEquations
    using Plots
    
    const global lp=1.               
    const global s2=81.
    const global  d=-9.0e-4
    const global B=1.    # Parameter in the gaussian f(\phi) defined below
    const global β =1.   # Parameter in the gaussian f(\phi) defined below
    const global k=1.    # Wave number           
    
    @variables α,ϕ
    
    # Useful functions
    #α(ϕ) = ϕ^2 
     
    g1(α,ϕ) = s2^2*α^2*sinh(s2*α*ϕ)*sin(2d*α)
    g2(α,ϕ) = cos(2d*α)+cosh(s2*α*ϕ)
    g3(α,ϕ) = -α*s2*sin(2d*α)+2d*cos(2d*α)+2d*cosh(s2*α*ϕ)
    g(α,ϕ) = exp(-2α)*g3(α,ϕ)/g2(α,ϕ)/2/lp
    dgg(α,ϕ) = g1(α,ϕ)/g2(α,ϕ)/g3(α,ϕ) # Derivative of g over g
    
    f1(α,ϕ) = -4B*lp*exp(2α)*ϕ*exp(-ϕ^2/β^2)/β^2
    f2(α,ϕ) = cos(2d*α)+cosh(s2*α*ϕ)
    f3(α,ϕ) = -α*s2*sin(2d*α)+2d*cos(2d*α)+2d*cosh(s2*α*ϕ)
    dfg(α,ϕ) = f1(α,ϕ)*f2(α,ϕ)/f3(α,ϕ) # Derivative of f over g
    
    α1(α,ϕ) = ϕ*s2*sin(2d*α)+2d*sinh(s2*α*ϕ)
    
    function eom(du,u,p,ϕ)
        α = u[1]
        A = u[2]
        dA = u[3]
        du[1] = α1(α,ϕ)/g3(α,ϕ)
        du[2] = dA
        du[3] = -2*dgg(α,ϕ)*dA-2*dfg(α,ϕ)*dA-k^2*A/g(α,ϕ)
    end 
    A₀ = [0.1,0.,0.1]               # initial state vector
    tspan = (-5.0,5.0)                  # time interval
    prob = ODEProblem(eom,A₀,tspan)
    sol = solve(prob,Tsit5())
    plot(sol)
    
    # Full solution to implement in the future
    # dαdϕ1(ϕ) = ϕ*s2*sin(2d*α)+2d*sinh(s2*α*ϕ)
    # dαdϕ(ϕ) = dαdϕ1(ϕ)/g3(ϕ) 
    
    # Original problem
    # function eom(ddu,du,u,p,ϕ)
    #     ddu[1] = -2dgg(ϕ)*du[1]-2dfg(ϕ)*du[1]-k^2*u[1]/g(ϕ)
    # end
    # u0 = [0.]                  # initial state vector
    # du0 = [0.]
    # tspan = (-5.0,5.0)                  # time interval
    # prob = SecondOrderODEProblem(eom,du0,u0,tspan)
    # sol = solve(prob,Tsit5())
    # plot(sol)