Python 根据解的大小,将Scipy ode积分到未知极限t
我正在模拟带电粒子在电磁场中的运动,并使用scipy ode。显然,这里的代码是简化的,但可以作为示例使用。我遇到的问题是,我想在限制r之后结束积分,而不是限制t。积分dx/dt,直到范数(x)>r 我不想把函数改成积分r,因为位置是t的函数。我能对无关变量做定积分吗Python 根据解的大小,将Scipy ode积分到未知极限t,python,scipy,ode,numerical-integration,Python,Scipy,Ode,Numerical Integration,我正在模拟带电粒子在电磁场中的运动,并使用scipy ode。显然,这里的代码是简化的,但可以作为示例使用。我遇到的问题是,我想在限制r之后结束积分,而不是限制t。积分dx/dt,直到范数(x)>r 我不想把函数改成积分r,因为位置是t的函数。我能对无关变量做定积分吗 import numpy as np import matplotlib.pyplot as plt from scipy.integrate import odeint def RHS(state, t, Efield, q,
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint
def RHS(state, t, Efield, q, mp):
ds0 = state[3]
ds1 = state[4]
ds2 = state[5]
ds3 = q/mp * Efield*state[0]
ds4 = q/mp * Efield*state[1]
ds5 = q/mp * Efield*state[2]
r = np.linalg.norm((state[0], state[1], state[2]))
# if r > 30000 then do stop integration.....?
# return the two state derivatives
return [ds0, ds1, ds2, ds3, ds4, ds5]
ts = np.arange(0.0, 10.0, 0.1)
state0 = [1.0, 2.0, 3.0, 0.0, 0.0, 0.0]
Efield=1.0
q=1.0
mp=1.0
stateFinal = odeint(RHS, state0, ts, args=(Efield, q, mp))
print(np.linalg.norm(stateFinal[-1,0:2]))
您可以通过使用逐步执行集成来控制流程。例如:
from scipy.integrate import ode
t_initial = 0
dt = 0.1
t_max = 10
r = ode(RHS).set_initial_value(state0, t_initial).set_f_params(Efield, q, mp)
solution = [state0]
while r.successful() and r.t < t_max:
new_val = r.integrate(r.t + dt)
solution.append(new_val)
if np.linalg.norm((new_val[0], new_val[1], new_val[2])) > 30000:
break
print(solution)
从scipy.integrate导入ode
t_初始值=0
dt=0.1
t_max=10
r=ode(RHS)。设置初始值(state0,t_initial)。设置参数(Efield,q,mp)
解决方案=[state0]
当r.successful()和r.t
请注意,RHS的签名必须更改为def RHS(t,state,Efield,q,mp):
对于ode
,自变量排在第一位,与odeint
不同
输出是以自变量的
dt
增量计算的解决方案,直到循环结束(因为达到t_max
,或者积分器失败,或者遇到了中断
的条件) 一种变体是搜索目标函数中的符号变化,并使用类似割线法的方法来细化根的时间,如中所做。一般的主题是“事件处理”。这实际上非常好,因为我还可以根据当前条件选择动态时间步。那是另一件让我汗流浃背的事!