首页/文章/ 详情

scipy求解常微分方程组

2年前浏览2153

Scipy求解常微分方程组有scipy.integrate.solve_ivp和scipy.integrate.odeint,后者是较老的版本主要是采用 FORTRAN 的odepack库里面的lsoda 方法,而前者是后面更新的函数,支持的方法也更多,按照官方的文档介绍大致有如下的方法。

scipy.integrate.solve_ivp内可用的数值积分方法

函数的调用形式如下scipy.integrate.solve_ivp(fun,t_span,y0,method='RK45',t_eval=None,dense_output=False,events=None,vectorized=False,args=None,**options)

下面以几个例子进行说明首先是如下的简单形式,设初始值为0

[公式]

import matplotlib.pyplot as pltfrom scipy.integrate import solve_ivpplt.rcParams['font.sans-serif'] = ['Microsoft YaHei']def fun(t, y):
    dydt = [1]
    return dydt# 初始条件y0 = [2]yy = solve_ivp(fun, (0, 5000), y0, method='Radau')t = yy.tdata = yy.yplt.plot(t, data[0, :])plt.xlabel("时间s")plt.legend(["求解变量"])plt.show()

然后逐渐复杂一点,假设方程为

[公式]

发现得到的结果是这样的,很明显不合理

这是因为求解的时候输出的插值的问题,我们改一下代码,结果如下

是不是就合理多了

完整的代码如下

import matplotlib.pyplot as plt
from scipy.integrate import solve_ivp
import numpy as np
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']

def fun(t, y):
    print(t)
    dydt = [t]
    return dydt

# 初始条件
y0 = [0]

yy = solve_ivp(fun, (0, 5000), y0, method='Radau',t_eval = np.arange(1,5000,1) )
xx = solve_ivp(fun, (0, 5000), y0, method='Radau')
t = yy.t
data = yy.y
t2 = xx.t
data2 = xx.y
plt.plot(t, data[0, :])
plt.plot(t2, data2[0, :])
plt.xlabel("时间s")
plt.legend(["求解变量"])
plt.show()

现在看着还不高端,可以多定义两个函数让他看起来更高端一些,方程如下

[公式]

代码如下

import matplotlib.pyplot as plt
from scipy.integrate import solve_ivp
import numpy as np
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']

def fun(t, y):
    y1 = y[0]
    y2 = y[1]
    dydt = [y2, t*t-y2 t]
    return dydt

# 初始条件
y0 = [0,1]

yy = solve_ivp(fun, (0, 500), y0, method='Radau',t_eval = np.arange(1,500,1) )
t = yy.t
data = yy.y
plt.plot(t, data[0, :])
plt.plot(t, data[1, :])
plt.xlabel("时间s")
plt.legend(["求解变量"])
plt.show()
燃料电池传动流-固&热耦合python
著作权归作者所有,欢迎分享,未经许可,不得转载
首次发布时间:2022-02-19
最近编辑:2年前
蘑菇
硕士 | 工程师 签名征集中
获赞 102粉丝 117文章 15课程 11
点赞
收藏
未登录
还没有评论

课程
培训
服务
行家

VIP会员 学习 福利任务 兑换礼品
下载APP
联系我们
帮助与反馈