Python 如何在求解耦合微分方程时引入突变?

Python 如何在求解耦合微分方程时引入突变?,python,scipy,differential-equations,odeint,Python,Scipy,Differential Equations,Odeint,我一直在尝试使用odeint和solve_ivp求解以下三个耦合微分方程组。(这不是确切的系统。我修改它只是为了提高问题的可读性。) 这个很好用。但是现在我想用下面的方式来修改它:只要u、v或w中的任何一个低于阈值,它就会被重置为零,然后让系统进化。每当这三个值中的任何一个自动超过阈值时,就会发生这种情况。演化系统的“规则”保持不变 我已尝试通过以下操作修改代码: def model(x,t): # x is a list containing the values of u,v,w as

我一直在尝试使用odeint和solve_ivp求解以下三个耦合微分方程组。(这不是确切的系统。我修改它只是为了提高问题的可读性。)

这个很好用。但是现在我想用下面的方式来修改它:只要u、v或w中的任何一个低于阈值,它就会被重置为零,然后让系统进化。每当这三个值中的任何一个自动超过阈值时,就会发生这种情况。演化系统的“规则”保持不变

我已尝试通过以下操作修改代码:

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]
     
    if u < u_threshold:
        x[0] = 0
    
    dudt = u - u*v                           
    dvdt = -v + u*v - vw**2          
    dwdt = -w + 2*v*w
    
    return [dudt, dvdt, dwdt]
def model(x,t):#x是一个包含u,v,w值随时间t变化的列表
u=x[0]
v=x[1]
w=x[2]
如果u
我只给你看了,但你明白了。这似乎不起作用


请注意,我不能在任何变量达到阈值时停止模拟,因为这只是一个玩具模型。稍后,我将把它推广到数百个耦合方程组的系统。

它不起作用,因为状态向量
x
是只读的,没有副作用将变化传输回积分器的状态向量

即使它真的起作用了,这也不是个好主意:

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

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


因此,是的,最好的方法确实是使用
solve\u ivp
的事件机制停止模拟,或者根据同样在
solve\u ivp
后面的步进器类设计自己的时间循环,你说的“停止模拟”是什么意思?模拟是一系列的时间步,可以说每一步都“暂时停止”。这些跳跃背后的原因是什么?这是为了避免一些数值复杂性,还是这是模拟背后理论的一个硬结果?我所说的“停止模拟”,是指永久停止模拟。推理:这个系统是在模拟一个生物系统,其中u、v和w是生态系统中不同物种生物的密度。在生物系统中有一个有趣的效应:如果密度低于阈值,物种通常会灭绝。好吧,这是有道理的,你想阻止一个物种从0.1个个体的种群中恢复(除以不可分割的部分)。通常的方法是在固定时间(一个月或一年)运行模拟,然后修剪状态向量并使用修改后的状态重新启动。这并不明显比连续模拟慢,存在阵列操作来连接产生的状态数组。请参阅,以了解此功能的实现,原因稍有不同。
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]
     
    if u < u_threshold:
        x[0] = 0
    
    dudt = u - u*v                           
    dvdt = -v + u*v - vw**2          
    dwdt = -w + 2*v*w
    
    return [dudt, dvdt, dwdt]