python差分法_数值偏微分方程-差分法(Python)
在前面的笔记里孤光一点萤:数值常微分方程-欧拉法与龙格-库塔法zhuanlan.zhihu.com
整理了常微分方程的一些数值解法。类似的方法可以拓展到解偏微分方程的问题,这里整理有限差分法的相关笔记。
计算机无法处理连续介质的无限多点,因此只能通过网格划分的方式,将带求解区域内连续分布的函数进行离散化,这样只用求解有限多的格点即可。同样地,在计算机里无法取极限求导数,只能通过离散化之后,用有限差商代替导数。由此,可以将带求解的偏微分方程转化为一组离散格点上的差分方程。解这组方程的问题,最终又归化为一个矩阵的求解问题,而矩阵求解这种“体力活”是计算机所擅长的。
由于我们使用划分的离散网格来近似连续的待求解空间,因此网格划分越密,求解越精确。同时,网格划分越密集,意味着最后得到的矩阵方程维度越高,计算量会非常庞大。这时候常用的高斯消元法(一个高斯消元的例子)往往会吃不消,需要使用松弛迭代法等。
首先,还是从单变量的方程开始。考虑函数
,其中
。将区间
分为N份,每一份就是步长
,则离散化后的格点坐标为:
。对于任意格点
:
一阶向前差分
一阶向后差分
一阶中心差分
由此可得:
一阶向前差商
一阶向后差商
一阶中心差商
二阶中心差商
现在拓展到二维情况:
例如对于方程
,待求解区域为正方形域
将待求解区域划分为矩形网格,每一个小矩形的长和宽(步长)分别为
和
,使用中心差商,可得:
对于这里的正方形区域,自然而然可以选取
,代入方程,得:
以此类推,可以得到对于点
,有:
这便是点
满足的差分方程,由于该方程包含点
及其上下左右一共5个点,也称为“五点差分格式”。
五点差分格式的截断误差为
阶。如果把左上、左下、右上、右下四个点也用上,为“九点差分格式”,误差可以降低到
阶。
为简便起见,这里以拉普拉斯方程
为例,则五点差分格式简化为:
在边界
上,
在划分网格时候要注意,如果划分网格为
个正方形格子,那么待求解的点有
个,因为区域边界上的点(即边界条件)是给定的,不用求。因此,给网格编号时候,从0开始编号再合适不过了,如下:
考虑第一个点
,根据五点差分格式,它的值由上下左右四个点确定,很显然,上、左分别为边界点
和
,右、下分为为点
和
,写为差分格式为:
第一列其他点同理,以此类推,如果将网格第
列上每个点的解记为:
,则最终可以写为:
其中
为
阶单位矩阵,
这里出现了一个迭代方程,想解
需要
,解
需要
......
然后把这一系列矩阵方程写成一个更大的矩阵方程:
把整个网格的每一列纵向连接为一个列向量:
则有:
,其中:
,
终于,我们把要求解的问题化简为了矩阵方程
的形式,可以方便地使用计算机求解,这里A是系数矩阵,列向量
便是问题的解。
对于上面的拉普拉斯方程,用Python求解:
为了方便,求解时直接使用了线性代数库
,这样计算的是矩阵方程的精确解,耗时有点长。可以用松弛迭代法来求数值解,有空再更。
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
N=79 # 矩阵维数
Imat = -np.eye(N)/4
def Gmatrix(N): # 生成G矩阵
mtr = np.eye(N)
for i in range(0, N - 1):
mtr[i][i + 1] = -1 / 4
for i in range(1, N):
mtr[i][i - 1] = -1 / 4
return mtr
def zero_mat(N,m): # 生成m个横向连接N阶零矩阵,m>=1
zero_matrix = np.zeros((N,N))
for i in range(m-1):
zero_matrix = np.block([zero_matrix,np.zeros((N,N))])
return zero_matrix
def zero_arr(N, m): # 生成m个纵向连接N阶列向量,m>=1
zero_array = np.zeros((N,1))
for i in range(m-1):
zero_array = np.block([[zero_array],[np.zeros((N,1))]])
return zero_array
def Kmatrix(N,Gmat,Imat):
Kmar_list = []
for i in range(N):
if i == 0:
Kmat_line = np.block([np.block([Gmat, Imat]),zero_mat(N,N-2)])
Kmar_list.append(Kmat_line)
elif i == 1:
Kmat_line = np.block([Imat, Kmar_list[-1][:,:-N]])
Kmar_list.append(Kmat_line)
else:
Kmat_line = np.block([np.zeros((N,N)), Kmar_list[-1][:,:-N]])
Kmar_list.append(Kmat_line)
Kmat = Kmar_list[0]
for j in range(N-1):
Kmat = np.block([[Kmat],[Kmar_list[j+1]]])
return Kmat
def Barray(N): # 方程右边
barr = np.ones((N,1))/4
barr = np.block([[barr],[zero_arr(N,N-2)]])
barr = np.block([[barr],[np.ones((N,1))/4]])
return barr
Gmat = Gmatrix(N)
Kmat = Kmatrix(N,Gmat,Imat)
Barr = Barray(N)
Phi = np.linalg.solve(Kmat,Barr)
def trans(N,Phi):
# 把线性方程组解得的列矢量分割,从左到右排列转化为方矩阵,方便可视化
phi = Phi[0:N]
for i in range(N-1):
j = i+1
phi = np.block([phi,Phi[(j*N):((j+1)*N)]])
return phi
Phi = trans(N,Phi)
x = np.linspace(0,1,N)
y = np.linspace(0,1,N)
X,Y = np.meshgrid(x,y)
fig = plt.figure()
ax = Axes3D(fig)
ax.plot_surface(X,Y,Phi,rstride=1,cstride=1,cmap=plt.get_cmap('rainbow'))
ax.contourf(X,Y,Phi,zdir='z',offset=1,cmap='rainbow')
plt.title('Difference methods for Laplace equation',fontsize='12')
plt.show()
作图如下:
通过控制作图参数里的offset,可以调整等高线的位置:
差分法求解的误差主要来自于差分公式对偏微分的近似替代,为了提高求解精度,可以把网格划分得更密,同时计算量也会显著增大。
Reference:
1、马文淦,《计算物理学》
2、李荣华,刘播,《微分方程数值解法》
python差分法_数值偏微分方程-差分法(Python)相关推荐
- python求差分_数值偏微分方程-差分法(Python)
在前面的笔记里孤光一点萤:数值常微分方程-欧拉法与龙格-库塔法zhuanlan.zhihu.com 整理了常微分方程的一些数值解法.类似的方法可以拓展到解偏微分方程的问题,这里整理有限差分法的相关笔 ...
- python示例_带有示例的Python功能指南
python示例 Python函数简介 (Introduction to Functions in Python) A function allows you to define a reusable ...
- 3 x 10的python表达式_这道数学题用PYTHON编程语言怎么写? 编程语言python是用
我觉着,这个应该这样解决比较符合计算机解题思路. 下面的回答的,思考的东西太多. # -*- coding: utf-8 -*- __author__ = 'lpe234' __date__ = '2 ...
- pythoncookbook和流畅的python对比_为什么你学Python效率比别人慢?因为你没有这套完整的学习资料...
以下资源免费获取方式! 关注!转发!私信"资料"即可免费领取! 入门书籍 1.<Python基础教程>(Beginning Python From Novice to ...
- 零基础学python 视频_全网最全Python视频教程真正零基础学习Python视频教程 490集...
Python Web开发-进阶提升 490集超强Python视频教程 真正零基础学习Python视频教程 [课程简介] 这是一门Python Web开发进阶课程,手把手教你用Python开发完整的商业 ...
- 为什么要学python语言_我们为什么要学习Python语言?
原标题:我们为什么要学习Python语言? 聊到我们为什么要学习Python语言?小编不禁又想起大佬潘石屹准备开启Python学习旅程时所发布的微博. 我们为什么要学习Python语言? 在农业社会时 ...
- 下载python步骤_下载及安装Python详细步骤
安装python分三个步骤: *下载python *安装python *检查是否安装成功 1.下载python (1)python下载地址 (2)选择下载的版本 (3)点开download后,找到下载 ...
- ubuntu更改默认python版本_更改Ubuntu默认python版本的方法
1.查看基本信息 # 列出所有已安装python ls /usr/bin/python* #查看默认的 Python 版本信息: python --version 2.基于用户修改 默认Python ...
- python编辑器_推荐一款Python编辑器,集Pycharm和Sublime优点于一身的王者
编程里面的编辑器就像是武林大会里面的高手,每一年都有新秀,黑马出现!比如有练习霸道的天罡之气的榜首Pycharm,力量雄厚霸道战斗力极强,但是对斗气消耗很大,占内存大而且启动速度有点慢!还有练习灵巧的 ...
最新文章
- 071_html语言代码
- python语言整数类型-Python 的内置数值类型
- 项目中需要总结的内容
- Linux性能分析工具汇总
- putty的保存功能如何使用
- Spring连接数据库的几种常用的方式
- oracle 11g crs stat,Oracle 11g RAC CRS磁盘丢失后恢复
- js 杂项(一)函数篇
- 基于Qt设计的学生考勤系统
- python电影爬取并下载_python爬取电影并下载
- tiny4412的I2C驱动实现案例(基于MMA7660)自己写的,亲测有效
- 启明星辰产品解读_IPS
- Zemax学习笔记——序列模式点光源与平行光设置
- Java 统计接口消耗时间
- 为什么要引入齐次坐标,齐次坐标的意义(二)
- LORA智能巡检手持机|无线数据采集终端
- 关于app2sd、a2sd、data2sd、a2sd+的区别的解释(扫盲贴)
- 确认过眼神,这就是亚信科技的核心能力
- 基于net6的头像上传功能
- Java泛型类,方法使用,Java继承的歪解