我正在模拟带电粒子在电磁场中移动并使用scipy ode。显然,这里的代码是简化的,但作为一个例子。我遇到的问题是我希望在r限制之后结束集成,而不是t。因此,将dx / dt积分到norm(x)>的点。河
然而,我不想仅仅改变函数来整合r,因为位置是t的函数。我可以对一个不相关的变量做一个明确的积分吗?
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]))
答案 0 :(得分:1)
您可以使用scipy.integrate.ode逐步执行集成来控制流程。示例:
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)
请注意,对于def RHS(t, state, Efield, q, mp):
,RHS的签名必须更改为ode
,自变量优先于odeint
。
输出是以自变量的dt
为增量计算的解,直到循环结束的时间(因为到达t_max
,或者积分器失败,或{的条件为{遇到过{1}}。