【问题标题】:Scipy ode integrate to unknown limit of t, based on the size of solutionScipy ode 根据解的大小积分到 t 的未知极限
【发布时间】:2018-04-27 03:43:10
【问题描述】:

我正在对穿过电磁场的带电粒子进行建模,并且正在使用 scipy ode。显然,这里的代码是简化的,但可以作为示例。我遇到的问题是我想在限制 r 而不是 t 之后结束积分。因此,将 dx/dt 积分到 norm(x) > r。

我不想仅仅改变函数以在 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]))

【问题讨论】:

  • 一种变体是在目标函数中搜索符号变化,并采用类似于割线的方法来细化根的时间,如math.stackexchange.com/a/2750364/115115 中所做的那样。一般主题是“事件处理”。

标签: python scipy ode numerical-integration


【解决方案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)

请注意,对于ode,RHS 的签名必须更改为def RHS(t, state, Efield, q, mp):,自变量在前,与odeint 不同。

输出是以自变量的dt为增量计算的解,直到循环结束时为止(因为达到t_max,或者积分器失败,或者遇到break的条件)。

【讨论】:

  • 这实际上非常好,因为我还可以根据当前条件选择动态时间步长。那是我汗流浃背的另一件事!
猜你喜欢
  • 1970-01-01
  • 2015-07-10
  • 2015-03-30
  • 2012-12-03
  • 2014-07-28
  • 1970-01-01
  • 1970-01-01
  • 2012-11-27
  • 1970-01-01
相关资源
最近更新 更多