微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在求解耦合微分方程时如何引入突然跳跃?

如何解决在求解耦合微分方程时如何引入突然跳跃?

我一直在尝试使用odeint和solve_ivp解决以下三个耦合的微分方程组。 (这不是确切的系统。我已经对其进行了修改,以提高问题的可读性。)

def model(x,t):    # x is a list containing the values of u,v,w as they change with time t 
    u = x[0]
    v = x[1]
    w = x[2]
    
    dudt = u - u*v                           
    dvdt = -v + u*v - v*w**2          
    dwdt = -w + 2*v*w
    
    return [dudt,dvdt,dwdt]

这很好。但是,现在我想通过以下方式对此进行修改:每当u,v或w都低于阈值时,它将重置为零,然后让系统演进。每当这三个条件中的任何一个自动超过阈值时,都会发生这种情况。系统发展的“规则”保持不变。

我尝试通过执行以下操作来修改代码

def model(x,w as they change with time t 
    u = x[0]
    v = x[1]
    w = x[2]
     
    if u < u_threshold:
        x[0] = 0
    
    dudt = u - u*v                           
    dvdt = -v + u*v - vw**2          
    dwdt = -w + 2*v*w
    
    return [dudt,dwdt]

我只为你展示了它,但是你明白了。这似乎不起作用。

请注意,每次有变量达到阈值时,我都无法停止仿真,因为这只是一个玩具模型。稍后,我将其推广到包含数百个耦合方程组的系统。

解决方法

它不起作用,因为状态向量$allResult =[]; foreach($arrayes as $array){ $allResult = array_merge($allResult,$array['identity']['result']); } 是只读的,因此没有副作用将更改传送回积分器的状态向量。

即使它确实起作用,也将是一个坏主意

  • ODE函数x通常不会在求解曲线的点上调用,然后在较高阶的RK方法中也不会随着时间的增加而调用。

  • 这样的跳跃会使ODE非常不平滑,从而破坏了时间步长控制器中使用的所有假设。其结果可能会有所不同,但都不利于最小努力集成。

是的,最好的方法的确是使用model的事件机制停止仿真,或者基于同样落后于solve_ivp的步进器类来构建自己的时间循环。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。