首页 > 解决方案 > 终端事件发生后使用新参数重新启动 python scipy.solve_ivp 积分器

问题描述

我正在使用 scipy.integrate.solve_ivp 来求解 ODE 系统,因为它具有事件函数。

我需要这个函数的原因是,在积分过程中,有时我会得到一个奇异矩阵,每次发生这种情况时,我都需要完成积分并使用新参数重新启动它。

我想知道在发生终端事件后是否可以使用新参数重新启动 scipy.integrate.solve_ivp,如果可以,我该怎么做。

任何帮助将不胜感激。

这是我当前的脚本,基于 https://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.solve_ivp.html中的示例:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import numpy as np
from scipy.integrate import solve_ivp
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from animate_plot import animate

def upward_cannon(t, y):
    return [y[1], -0.5]

def hit_ground(t, y):
    return y[0]

def apex(t,y):
    return y[1]

hit_ground.terminal = True
hit_ground.direction = -1

t0 = 0

tf = 10

sol = solve_ivp(upward_cannon, t_span=[t0, tf], y0=[90, 10], t_eval=np.arange(t0,tf, 0.01), events=[hit_ground,apex],
                dense_output=True)

linesData = { 1: [[-0.0, 0.0],[0.0, 0.0]]}#,
            # 2: [[-0.5, 0],[0.5, 0.0]]}#, 3: [[-0.5, 0],[0.5, 0]]}

pointsofInterest = {}#3: [[0.5, 0.0]]}#, 2: [[180.0, 10]]}

model_markers = np.array([])

plot_title = 'Upward Particle'
plot_legend = ['Forward Dynamics']

q_rep = sol.y.T[:,0]

fig = plt.figure()

ax = fig.add_subplot(111)

xs = np.arange(t0, tf, 0.01)

for idx in range(0,q_rep.shape[0]):   #looping statement;declare the total number of frames
    y=q_rep[idx]       # traveling Sine wave
    ax.cla()
    ax.scatter(xs[idx],y, s=50)
    plt.ylim([-10, 190])
    plt.xlim([-100, 100])
    plt.pause(0.001)
plt.show()

先感谢您。

亲切的问候

标签: pythonscipyode

解决方案


你有两个选择,都是recursive.

选项 1:编写函数以在脚本内部调用自身。这将是真实recursion而优雅的。

选项 2:如果您的函数遇到这些值,您需要解析、使用argparsingos调用具有指定值的函数。

例子:

os.system(python3 filename.py -f argparseinputs)

推荐阅读