Julia中二阶常微分方程的不稳定性
我想数值求解一个二阶常微分方程(见下面的第一个方程),它依赖于相对简单的函数(g,g'/g和f/g是cos,sine,cosh,sinh的叠加)。主要问题是这些函数依赖于函数α(例如cos(alpha*phi)),并且只知道其导数(参见下面的第二个等式,σ和d是固定的) 这显然很难解决,所以我首先尝试了更简单的方法,设置alpha=phi²。我的代码返回警告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值导致了此结果。代码运行
警告:自动dt将启动dt设置为NaN,导致不稳定。
后接警告:检测到NaN dt。可能是状态、参数或派生值中的NaN值导致了此结果。
代码运行,但绘制解决方案时会出现错误ArgumentError:不允许对空集合进行缩减
,我认为这表明我的解决方案为空
我发现了一个类似的问题,其中出现错误是因为参数给出了发散的解决方案,但在我的例子中,ODE中的所有函数都在感兴趣的区间(-5,5)上定义得很好,所以我怀疑这是我的情况。那么,我有三个问题:
未定义错误:α未定义
,尽管我明确将其定义为第三个方程。我做错了什么
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)