• MATLAB编辑一维热传导方程的模拟程序(最新整理)》由会员分享，可在线阅读，更多相关《MATLAB编辑一维热传导方程的模拟程序(最新整理)(4页珍藏版)》请在人人文库网上搜索。1、求解下列热传导问题：2T - 1 T =( )z ...

《MATLAB编辑一维热传导方程的模拟程序(最新整理)》由会员分享，可在线阅读，更多相关《MATLAB编辑一维热传导方程的模拟程序(最新整理)(4页珍藏版)》请在人人文库网上搜索。
1、求解下列热传导问题：2T - 1 T =( )z 2a t00zLT(z,0) = 1 - z 2T (0, t ) = 1,T (L, t ) = 0L = 1,a= 1程序：function heat_conduction() %一维齐次热传导方程options=空间杆长L,空间点数N ,时间点数M,扩散系数alfa,稳定条件的值lambda(取值必须小于0.5),;topic=seting; lines=1;def=1,100,1000,1,0.5;h=inputdlg(options,topic,lines,def); L=eval(h1);N=eval(h2);M=eval(h3);。
2、alfa=eval(h4); lambda=eval(h5);%lambda的值必须小于0.5%* h=L/N;%空间步长z=0:h:L;z=z;tao=lambda*h2/alfa;%时间步长tm=M*tao;%热传导的总时间tm t=0:tao:tm;t=t;%计算初值和边值T=zeros(N+1,M+1);Ti=init_fun(z);To=border_funo(t);Te=border_fune(t);T(:,1)=Ti;T(1,:)=To;T(N+1,:)=Te;%用差分法求出温度T与杆长L、时间t的关系for k=1:Mm=2;while m=NT(m,k+1)=lambda*(。
3、T(m+1,k)+T(m-1,k)+(-2*lambda+1)*T(m,k); m=m+1;end;end;%设置立体网格for i=1:M+1X(:,i)=z;end;for j=1:N+1Y(j,:)=t;end mesh(X,Y,T);view(1 -1 1);xlabel(Z);ylabel(t);zlabel(T);function y=init_fun(z)%初值条件y=1-z.2;returnfunction y=border_funo(t)%z=0的边界条件y=1+t.*0;returnfunction y=border_fune(t)%z=L的边界条件y=t*.0;retur。
4、n运行情况：按“run”运行时，弹出窗口将图中相关数据更改为：点击图框中的“OK”，在“command window”中输出结果为：“”“”At the end, Xiao Bian gives you a passage. Minand once said, people who learn to learn are very happy people. In every wonderful life, learning is an eternal theme. As a professional clerical and teaching position, I understand th。
5、e importance of continuous learning, life is diligent, nothing can be gained, only continuous learning can achieve better self. Only by constantly learning and mastering the latest relevant knowledge, can employees from all walks of life keep up with the pace of enterprise development and innovate to meet the needs of the market. This document is also edited by my studio professionals, there may be errors in the document, if there are errors, please correct, thank you。

展开全文
• MATLAB编辑一维热传导方程的模拟程序
• MATLAB编辑一维热传导方程的模拟程序 求解下列热传导问题 程序 function heat_conduction) %一维齐次热传导方程 options={'空间杆长L'空间点数N' '时间点数M'扩散系数alfa'稳定条件的值lambda(取值必须小于0.5,};...
• matlab程序，个人感觉很有帮助，在研究传热学的可以下来看看 含matlab程序，个人感觉很有帮助，在研究传热学的可以下来看看
• MATLAB 编辑 一维 热传 导方程的模拟程序 求解下列热传导问题: 2T z2 T 0,t 1, T L,t L 1, 程序: fun ctio n heat_c on ductio n) % 一维齐次热传导方程 稳定条options={'空间杆长L'空间点数N'时间点数M'扩散系数...
• 求解下列热传导问题: 2T 1 T 门 c , 2 0 0 z L z t T乙0 1 z2 T 0,t 1, T L,t 0 L 1, 1 程序 fun ctio n heat_c on ductio n) % 一维齐次热传导方程 稳定条options={'空间杆长L'空间点数N'时间点数M'扩散系数alfa' ...
• 上一篇实现了一维热传导方程数值解，这一篇实现二维热传导方程数值解。套路是一样的，先列微分方程，再改为差分方程，然后递推求解，不同的是一维热传导需要三维显示，而二维热传导需要四维，因此最后做了个三维动态...

上一篇实现了一维热传导方程数值解，这一篇实现二维热传导方程数值解。
套路是一样的，先列微分方程，再改为差分方程，然后递推求解，不同的是一维热传导需要三维显示，而二维热传导需要四维，因此最后做了个三维动态图。
二维热传导方程如下：

另外四条边界都是0。
写成差分方程为：

整理一下就能得到u(i+1,j,k)。
matlab代码如下：
clear all;close all;clc;
t = 0.03; %时间范围，计算到0.03秒
x = 1;y = 1; %空间范围，0-1米
m = 320; %时间t方向分320个格子
n = 32; %空间x方向分32个格子
k = 32; %空间y方向分32个格子
ht = t/(m-1); %时间步长dt
hx = x/(n-1); %空间步长dx
hy = y/(k-1); %空间步长dy
u = zeros(m,n,k);
%设置边界
[x,y] = meshgrid(0:hx:1,0:hy:1);
u(1,:,:) = sin(4*pi*x)+cos(4*pi*y);
%按照公式进行差分
for ii=1:m-1
for jj=2:n-1
for kk=2:k-1
u(ii+1,jj,kk) = ht*(u(ii,jj+1,kk)+u(ii,jj-1,kk)-2*u(ii,jj,kk))/hx^2 + ...
ht*(u(ii,jj,kk+1)+u(ii,jj,kk-1)-2*u(ii,jj,kk))/hy^2 + u(ii,jj,kk);
end
end
end
for i=1:200
figure(1);
mesh(x,y,reshape(u(i,:,:),[n k]));
axis([0 1 0 1 -2 2]);
% F=getframe(gcf);
% I=frame2im(F);
% [I,map]=rgb2ind(I,256);
% if i == 1
% imwrite(I,map,'test.gif','gif','Loopcount',inf,'DelayTime',0.05);
% else
% imwrite(I,map,'test.gif','gif','WriteMode','append','DelayTime',0.05);
% end
end
结果如下：

三维热传导用差分法也可以解，不过不太容易可视化，就不再实现了。
标签：end,kk,32,热传导,ii,差分法,matlab,jj
来源： https://www.cnblogs.com/tiandsp/p/14406223.html

展开全文
• 我们有兴趣使用 FTCS 方法获得一维热传导方程的稳态解。 边界条件是：在 x=0 和 0.3 m 处 T=300 K，在所有其他内部点处 T=100 K。 α = 〖3*10〗^(-6) m-2s-1 . 这里，t=30 分钟，Δx=0.015m 和 Δt=20 秒
• 我们有兴趣使用 CN 方法获得一维热传导方程的稳态解。 边界条件是：在 x=0 和 0.3 m 处 T=300 K，在所有其他内部点处 T=100 K。 α = 〖3*10〗^(-6) m-2s-1 . 这里，t=30 分钟，Δx=0.015m 和 Δt=20 秒
• 求解下列热传导问题 2T 1 T 0 z L z2 0 t T z,0 1 z2 T 0, t 1, T L,t 0 L 1, 1 程序 function heat_conduction) % 一维齐次热传导方程 options={' 空间杆长 L' 空间点数 N' ' 时间点数 M' 扩散系数 alfa' 稳定条 件...
• 一维热传导方程一维热传导方程一维热传导方程一维热传导方程一维热传导方程
• 抛物型方程的差分解法（如一维热传导方程）。本人在做建模比赛2020年A题时遇到热传导方程，然后我学习并总结了用有限差分法求解此类偏微分方程（抛物型方程）的解法。
能不能别白嫖啊٩(๑❛ᴗ❛๑)۶
目录
一、前言
二、问题与定义
1.问题
2.定义
三、求解格式
1、向前欧拉格式（古典显格式）
（1）差分格式
（2）收敛性与稳定性
2.向后欧拉格式（古典隐格式）
（1）差分格式
（2）收敛性与稳定性
3.Crank-Nicolson格式
（1）差分格式
（2）收敛性与稳定性
四、追赶法求解三对角线性方程组
五、实例+代码
1.题目1（《偏微分方程数值解法——孙志忠》书中题目）
2.题目2
（1）理论分析
（2）代码
（3）运行结果与分析

3.特殊的例子：题目3
（1）代码
（2）运行结果与分析

一、前言
1.本人在做建模比赛2020年A题时遇到热传导方程，然后我学习并总结了用有限差分法求解此类偏微分方程（抛物型方程）的解法。
2.本文借鉴《偏微分方程数值解法——孙志忠》，这本书写得浅显易懂。
3.本文不讲复杂的推理过程，只讲方法与结果。
4.相较其他博客而言（绝大多数都是用matlab），我的特点使用Python实现程序的
5.如有问题可在评论区讨论或是私信我

二、问题与定义

1.问题
考虑一维非齐次热传导方程的定解问题

2.定义
对x轴[0,1]区间作m等分，将t轴[0,T]区间作n等分，并记h=1/m，τ=T/n，分别称h和τ为空间步长和时间步长。
记为网格比。
记
网格剖分如下所示

定义网格函数
其中
是的近似

三、求解格式

1、向前欧拉格式（古典显格式）
（1）差分格式

可以看出k+1层结点可由第k层得出，因此可以简单循环即可

圆圈是指用到的点，画×是指差分格式是在这点列出的

（2）收敛性与稳定性
当r<=1/2时是收敛与稳定的，但是当r>1/2时是不稳定的，也不一定收敛。

2.向后欧拉格式（古典隐格式）
（1）差分格式

可以看出第k层的结点由k+1层结点得出，不能直接迭代求解，必须解方程组
将如上差分格式写为矩阵形式（注意不写的地方为0）

只需要在每一个时间层解这个三对角线性方程组即可，用AX=B代替以上方程组以方便叙述
有两种方法：第一种是直接将方程组两端乘上A逆即可得到X；第二种是用三对角线性方程组的特殊求解方法：追赶法来求解，当矩阵很大的时候速度比求逆矩阵要快得多，方法并不难，我放在最后
（2）收敛性与稳定性
对于任意步长比r必收敛与稳定

3.Crank-Nicolson格式
（1）差分格式

同样是在每一个时间层解一个三对角线性方程组即可
（2）收敛性与稳定性
对于任意步长比r必收敛与稳定

四、追赶法求解三对角线性方程组
追赶法

五、实例+代码
以下题目的结果均保存至excel中方便观察
1.题目1（《偏微分方程数值解法——孙志忠》书中题目）
时间步长与空间步长均取0.1

代码：
import numpy as np
import pandas as pd
import datetime

start_time = datetime.datetime.now()

np.set_printoptions(suppress=True)

def left_boundary(t):  # 左边值
return np.exp(t)

def right_boundary(t):  # 右边值
return np.exp(t + 1)

def initial_T(x_max, t_max, delta_x, delta_t, m, n):  # 给温度T初始化
T = np.zeros((n + 1, m + 1))
for i in range(m + 1):  # 初值
T[0, i] = np.exp(i * delta_x)

for i in range(1, n + 1):  # 注意不包括T[0,0]与T[0,-1]
T[i, 0] = left_boundary(i * delta_t)  # 左边值
T[i, -1] = right_boundary(i * delta_t)  # 右边值
return T

# 一、古典显格式
def one_dimensional_heat_conduction1(T, m, n, r):
# 可以发现当r>=0.5时就发散了
for k in range(1, n + 1):  # 时间层
for i in range(1, m):  # 空间层
T[k, i] = (1 - 2 * r) * T[k - 1, i] + r * (T[k - 1, i - 1] + T[k - 1, i + 1])
return T.round(6)

# 二、古典隐格式（乘逆矩阵法）
def one_dimensional_heat_conduction2(T, m, n, r):
A = np.eye(m - 1, k=0) * (1 + 2 * r) + np.eye(m - 1, k=1) * (-r) + np.eye(m - 1, k=-1) * (-r)
a = np.ones(m - 1) * (-r)
a[0] = 0
b = np.ones(m - 1) * (1 + 2 * r)
c = np.ones(m - 1) * (-r)
c[-1] = 0

F = np.zeros(m - 1)  # m-1个元素，索引0~(m-2)
for k in range(1, n + 1):  # 时间层range(1, n + 1)
F[0] = T[k - 1, 1] + r * T[k, 0]
F[-1] = T[k - 1, m - 1] + r * T[k, m]
for i in range(1, m - 2):  # 空间层
F[i] = T[k - 1, i + 1]  # 给F赋值
for i in range(1, m - 1):
T[k, 1:-1] = np.linalg.inv(A) @ F  # 左乘A逆
return T.round(6)

# 三、古典隐格式（追赶法）
def one_dimensional_heat_conduction3(T, m, n, r):
a = np.ones(m - 1) * (-r)
a[0] = 0
b = np.ones(m - 1) * (1 + 2 * r)
c = np.ones(m - 1) * (-r)
c[-1] = 0

F = np.zeros(m - 1)  # m-1个元素，索引0~(m-2)
for k in range(1, n + 1):  # 时间层range(1, n + 1)
F[0] = T[k - 1, 1] + r * T[k, 0]
F[-1] = T[k - 1, m - 1] + r * T[k, m]
y = np.zeros(m - 1)
beta = np.zeros(m - 1)
x = np.zeros(m - 1)
y[0] = F[0] / b[0]
d = b[0]
for i in range(1, m - 2):  # 空间层
F[i] = T[k - 1, i + 1]  # 给F赋值
for i in range(1, m - 1):
beta[i - 1] = c[i - 1] / d
d = b[i] - a[i] * beta[i - 1]
y[i] = (F[i] - a[i] * y[i - 1]) / d
x[-1] = y[-1]
for i in range(m - 3, -1, -1):
x[i] = y[i] - beta[i] * x[i + 1]
T[k, 1:-1] = x
return T.round(6)

# 四、Crank-Nicolson（乘逆矩阵法）
def one_dimensional_heat_conduction4(T, m, n, r):
A = np.eye(m - 1, k=0) * (1 + r) + np.eye(m - 1, k=1) * (-r * 0.5) + np.eye(m - 1, k=-1) * (-r * 0.5)
C = np.eye(m - 1, k=0) * (1 - r) + np.eye(m - 1, k=1) * (0.5 * r) + np.eye(m - 1, k=-1) * (0.5 * r)

for k in range(0, n):  # 时间层
F = np.zeros(m - 1)  # m-1个元素，索引0~(m-2)
F[0] = r / 2 * (T[k, 0] + T[k + 1, 0])
F[-1] = r / 2 * (T[k, m] + T[k + 1, m])
F = C @ T[k, 1:m] + F
T[k + 1, 1:-1] = np.linalg.inv(A) @ F
return T.round(6)

# 五、Crank-Nicolson（追赶法）
def one_dimensional_heat_conduction5(T, m, n, r):
C = np.eye(m - 1, k=0) * (1 - r) + np.eye(m - 1, k=1) * (0.5 * r) + np.eye(m - 1, k=-1) * (0.5 * r)
a = np.ones(m - 1) * (-0.5 * r)
a[0] = 0
b = np.ones(m - 1) * (1 + r)
c = np.ones(m - 1) * (-0.5 * r)
c[-1] = 0

for k in range(0, n):  # 时间层
F = np.zeros(m - 1)  # m-1个元素，索引0~(m-2)
F[0] = r * 0.5 * (T[k, 0] + T[k + 1, 0])
F[-1] = r * 0.5 * (T[k, m] + T[k + 1, m])
F = C @ T[k, 1:m] + F
y = np.zeros(m - 1)
beta = np.zeros(m - 1)
x = np.zeros(m - 1)
y[0] = F[0] / b[0]
d = b[0]
for i in range(1, m - 1):
beta[i - 1] = c[i - 1] / d
d = b[i] - a[i] * beta[i - 1]
y[i] = (F[i] - a[i] * y[i - 1]) / d
x[-1] = y[-1]
for i in range(m - 3, -1, -1):
x[i] = y[i] - beta[i] * x[i + 1]
T[k + 1, 1:-1] = x
return T.round(6)

def exact_solution(T, m, n, r, delta_x, delta_t):  # 偏微分方程精确解
for i in range(n + 1):
for j in range(m + 1):
T[i, j] = np.exp(i * delta_t + j * delta_x)
return T.round(6)

a = 1  # 热传导系数
x_max = 1
t_max = 1
delta_x = 0.1  # 空间步长
delta_t = 0.1  # 时间步长
m = int((x_max / delta_x).__round__(4))  # 长度等分成m份
n = int((t_max / delta_t).__round__(4))  # 时间等分成n份
t_grid = np.arange(0, t_max + delta_t, delta_t)  # 时间网格
x_grid = np.arange(0, x_max + delta_x, delta_x)  # 位置网格
r = (a * delta_t / (delta_x ** 2)).__round__(6)  # 网格比
T = initial_T(x_max, t_max, delta_x, delta_t, m, n)
print('长度等分成{}份'.format(m))
print('时间等分成{}份'.format(n))
print('网格比=', r)

p = pd.ExcelWriter('有限差分法-一维热传导-题目1.xlsx')

T1 = one_dimensional_heat_conduction1(T, m, n, r)
T1 = pd.DataFrame(T1, columns=x_grid, index=t_grid)  # colums是列号，index是行号
T1.to_excel(p, '古典显格式')

T2 = one_dimensional_heat_conduction2(T, m, n, r)
T2 = pd.DataFrame(T2, columns=x_grid, index=t_grid)  # colums是列号，index是行号
T2.to_excel(p, '古典隐格式（乘逆矩阵法）')

T3 = one_dimensional_heat_conduction3(T, m, n, r)
T3 = pd.DataFrame(T3, columns=x_grid, index=t_grid)  # colums是列号，index是行号
T3.to_excel(p, '古典隐格式（追赶法）')

T4 = one_dimensional_heat_conduction4(T, m, n, r)
T4 = pd.DataFrame(T4, columns=x_grid, index=t_grid)  # colums是列号，index是行号
T4.to_excel(p, 'Crank-Nicolson格式（乘逆矩阵法）')

T5 = one_dimensional_heat_conduction5(T, m, n, r)
T5 = pd.DataFrame(T5, columns=x_grid, index=t_grid)  # colums是列号，index是行号
T5.to_excel(p, 'Crank-Nicolson格式（追赶法）')

T6 = exact_solution(T, m, n, r, delta_x, delta_t)
T6 = pd.DataFrame(T6, columns=x_grid, index=t_grid)  # colums是列号，index是行号
T6.to_excel(p, '偏微分方程精确解')

p.save()

end_time = datetime.datetime.now()
print('运行时间为', (end_time - start_time))

书中Crank-Nicolson的数值解

可以看出与我的程序答案完全一致。
其余格式的结果与我的程序答案都是一样的。
结果分析大家就自己做了，我就不赘述了。

2.题目2

（1）理论分析
由生活实际知，温度不会无限制增大，当时间趋于一定的值时，温度将会稳定。
而由一维热传导方程知，
温度与距离将会呈线性关系，若以杆最左端为x=0则有：y=175+4x(x=5时y=195)

在这个题目中，f(x,t)=0，差分格式用矩阵比较容易表达与求解

如果f(x,t)≠0，那么可以自己在程序中修改矩阵的值
（2）代码
import numpy as np
import pandas as pd
import datetime

start_time = datetime.datetime.now()

np.set_printoptions(suppress=True)

def left_boundary(t):  # 左边值
T = 25 + 15 * t
if T < 175:
return T
else:
return 175

def right_boundary(t):  # 右边值
T = 25 + 17 * t
if T < 195:
return T
else:
return 195

def initial_T(x_max, t_max, delta_x, delta_t, m, n):  # 给温度T初始化
T = np.zeros((n + 1, m + 1))
for i in range(m + 1):  # 初值
T[0, i] = 25

for i in range(1, n + 1):  # 注意不包括T[0,0]与T[0,-1]
T[i, 0] = left_boundary(i * delta_t)  # 左边值
T[i, -1] = right_boundary(i * delta_t)  # 右边值
return T

# 一、古典显格式
def one_dimensional_heat_conduction1(T, m, n, r):
# 可以发现当r>=0.5时就发散了
for k in range(1, n + 1):  # 时间层
for i in range(1, m):  # 空间层
T[k, i] = (1 - 2 * r) * T[k - 1, i] + r * (T[k - 1, i - 1] + T[k - 1, i + 1])
return T.round(6)

# 二、古典隐格式（乘逆矩阵法）
def one_dimensional_heat_conduction2(T, m, n, r):
A = np.eye(m - 1, k=0) * (1 + 2 * r) + np.eye(m - 1, k=1) * (-r) + np.eye(m - 1, k=-1) * (-r)
a = np.ones(m - 1) * (-r)
a[0] = 0
b = np.ones(m - 1) * (1 + 2 * r)
c = np.ones(m - 1) * (-r)
c[-1] = 0

F = np.zeros(m - 1)  # m-1个元素，索引0~(m-2)
for k in range(1, n + 1):  # 时间层range(1, n + 1)
F[0] = T[k - 1, 1] + r * T[k, 0]
F[-1] = T[k - 1, m - 1] + r * T[k, m]
for i in range(1, m - 2):  # 空间层
F[i] = T[k - 1, i + 1]  # 给F赋值
for i in range(1, m - 1):
T[k, 1:-1] = np.linalg.inv(A) @ F  # 左乘A逆
return T.round(6)

# 三、古典隐格式（追赶法）
def one_dimensional_heat_conduction3(T, m, n, r):
a = np.ones(m - 1) * (-r)
a[0] = 0
b = np.ones(m - 1) * (1 + 2 * r)
c = np.ones(m - 1) * (-r)
c[-1] = 0

F = np.zeros(m - 1)  # m-1个元素，索引0~(m-2)
for k in range(1, n + 1):  # 时间层range(1, n + 1)
F[0] = T[k - 1, 1] + r * T[k, 0]
F[-1] = T[k - 1, m - 1] + r * T[k, m]
y = np.zeros(m - 1)
beta = np.zeros(m - 1)
x = np.zeros(m - 1)
y[0] = F[0] / b[0]
d = b[0]
for i in range(1, m - 2):  # 空间层
F[i] = T[k - 1, i + 1]  # 给F赋值
for i in range(1, m - 1):
beta[i - 1] = c[i - 1] / d
d = b[i] - a[i] * beta[i - 1]
y[i] = (F[i] - a[i] * y[i - 1]) / d
x[-1] = y[-1]
for i in range(m - 3, -1, -1):
x[i] = y[i] - beta[i] * x[i + 1]
T[k, 1:-1] = x
return T.round(6)

# 四、Crank-Nicolson（乘逆矩阵法）
def one_dimensional_heat_conduction4(T, m, n, r):
A = np.eye(m - 1, k=0) * (1 + r) + np.eye(m - 1, k=1) * (-r * 0.5) + np.eye(m - 1, k=-1) * (-r * 0.5)
C = np.eye(m - 1, k=0) * (1 - r) + np.eye(m - 1, k=1) * (0.5 * r) + np.eye(m - 1, k=-1) * (0.5 * r)

for k in range(0, n):  # 时间层
F = np.zeros(m - 1)  # m-1个元素，索引0~(m-2)
F[0] = r / 2 * (T[k, 0] + T[k + 1, 0])
F[-1] = r / 2 * (T[k, m] + T[k + 1, m])
F = C @ T[k, 1:m] + F
T[k + 1, 1:-1] = np.linalg.inv(A) @ F
return T.round(6)

# 五、Crank-Nicolson（追赶法）
def one_dimensional_heat_conduction5(T, m, n, r):
C = np.eye(m - 1, k=0) * (1 - r) + np.eye(m - 1, k=1) * (0.5 * r) + np.eye(m - 1, k=-1) * (0.5 * r)
a = np.ones(m - 1) * (-0.5 * r)
a[0] = 0
b = np.ones(m - 1) * (1 + r)
c = np.ones(m - 1) * (-0.5 * r)
c[-1] = 0

for k in range(0, n):  # 时间层
F = np.zeros(m - 1)  # m-1个元素，索引0~(m-2)
F[0] = r * 0.5 * (T[k, 0] + T[k + 1, 0])
F[-1] = r * 0.5 * (T[k, m] + T[k + 1, m])
F = C @ T[k, 1:m] + F
y = np.zeros(m - 1)
beta = np.zeros(m - 1)
x = np.zeros(m - 1)
y[0] = F[0] / b[0]
d = b[0]
for i in range(1, m - 1):
beta[i - 1] = c[i - 1] / d
d = b[i] - a[i] * beta[i - 1]
y[i] = (F[i] - a[i] * y[i - 1]) / d
x[-1] = y[-1]
for i in range(m - 3, -1, -1):
x[i] = y[i] - beta[i] * x[i + 1]
T[k + 1, 1:-1] = x
return T.round(6)

a = 0.5  # 热传导系数
x_max = 5
t_max = 100
delta_x = 0.1  # 空间步长
delta_t = 0.1  # 时间步长
m = int((x_max / delta_x).__round__(4))  # 长度等分成m份
n = int((t_max / delta_t).__round__(4))  # 时间等分成n份
t_grid = np.arange(0, t_max + delta_t, delta_t)  # 时间网格
x_grid = np.arange(0, x_max + delta_x, delta_x)  # 位置网格
r = (a * delta_t / (delta_x ** 2)).__round__(6)  # 网格比
T = initial_T(x_max, t_max, delta_x, delta_t, m, n)
print('长度等分成{}份'.format(m))
print('时间等分成{}份'.format(n))
print('网格比=', r)

p = pd.ExcelWriter('有限差分法-一维热传导-题目2.xlsx')

T1 = one_dimensional_heat_conduction1(T, m, n, r)
T1 = pd.DataFrame(T1, columns=x_grid, index=t_grid)  # colums是列号，index是行号
T1.to_excel(p, '古典显格式')

T2 = one_dimensional_heat_conduction2(T, m, n, r)
T2 = pd.DataFrame(T2, columns=x_grid, index=t_grid)  # colums是列号，index是行号
T2.to_excel(p, '古典隐格式（乘逆矩阵法）')

T3 = one_dimensional_heat_conduction3(T, m, n, r)
T3 = pd.DataFrame(T3, columns=x_grid, index=t_grid)  # colums是列号，index是行号
T3.to_excel(p, '古典隐格式（追赶法）')

T4 = one_dimensional_heat_conduction4(T, m, n, r)
T4 = pd.DataFrame(T4, columns=x_grid, index=t_grid)  # colums是列号，index是行号
T4.to_excel(p, 'Crank-Nicolson格式（乘逆矩阵法）')

T5 = one_dimensional_heat_conduction5(T, m, n, r)
T5 = pd.DataFrame(T5, columns=x_grid, index=t_grid)  # colums是列号，index是行号
T5.to_excel(p, 'Crank-Nicolson格式（追赶法）')

p.save()

end_time = datetime.datetime.now()
print('运行时间为', (end_time - start_time))

（3）运行结果与分析

长度等分成50份 时间等分成1000份 网格比= 5.0 C:/Users/86189/Desktop/Technology/Python_File/数学建模/自己总结/有限差分法-一维热传导-题目1.py:43: RuntimeWarning: overflow encountered in double_scalars   T[k, i] = (1 - 2 * r) * T[k - 1, i] + r * (T[k - 1, i - 1] + T[k - 1, i + 1]) C:/Users/86189/Desktop/Technology/Python_File/数学建模/自己总结/有限差分法-一维热传导-题目1.py:44: RuntimeWarning: overflow encountered in multiply   return T.round(6) 运行时间为 0:00:06.094756

可以发现显格式已经不收敛了，其余格式都收敛；
最终的温度都稳定为y=175+4x，符合理论分析。

3.特殊的例子：题目3

这里仅仅是修改了边值条件，但是情况却大有不同了！
（1）代码
注：结果会存到“有限差分法-一维热传导.xlsx”中，方便大家观察
import numpy as np
import pandas as pd
import datetime

start_time = datetime.datetime.now()

np.set_printoptions(suppress=True)

def left_boundary(t):  # 左边
return 175

def right_boundary(t):  # 右边值
return 195

def initial_T(x_max, t_max, delta_x, delta_t, m, n):  # 给温度T初始化
T = np.zeros((n + 1, m + 1))
for i in range(m + 1):  # 初值
T[0, i] = 25

for i in range(1, n + 1):  # 注意不包括T[0,0]与T[0,-1]
T[i, 0] = left_boundary(i * delta_t)  # 左边值
T[i, -1] = right_boundary(i * delta_t)  # 右边值
return T

# 一、古典显格式
def one_dimensional_heat_conduction1(T, m, n, r):
# 可以发现当r>=0.5时就发散了
for k in range(1, n + 1):  # 时间层
for i in range(1, m):  # 空间层
T[k, i] = (1 - 2 * r) * T[k - 1, i] + r * (T[k - 1, i - 1] + T[k - 1, i + 1])
return T.round(6)

# 二、古典隐格式（乘逆矩阵法）
def one_dimensional_heat_conduction2(T, m, n, r):
A = np.eye(m - 1, k=0) * (1 + 2 * r) + np.eye(m - 1, k=1) * (-r) + np.eye(m - 1, k=-1) * (-r)
a = np.ones(m - 1) * (-r)
a[0] = 0
b = np.ones(m - 1) * (1 + 2 * r)
c = np.ones(m - 1) * (-r)
c[-1] = 0

F = np.zeros(m - 1)  # m-1个元素，索引0~(m-2)
for k in range(1, n + 1):  # 时间层range(1, n + 1)
F[0] = T[k - 1, 1] + r * T[k, 0]
F[-1] = T[k - 1, m - 1] + r * T[k, m]
for i in range(1, m - 2):  # 空间层
F[i] = T[k - 1, i + 1]  # 给F赋值
for i in range(1, m - 1):
T[k, 1:-1] = np.linalg.inv(A) @ F  # 左乘A逆
return T.round(6)

# 三、古典隐格式（追赶法）
def one_dimensional_heat_conduction3(T, m, n, r):
a = np.ones(m - 1) * (-r)
a[0] = 0
b = np.ones(m - 1) * (1 + 2 * r)
c = np.ones(m - 1) * (-r)
c[-1] = 0

F = np.zeros(m - 1)  # m-1个元素，索引0~(m-2)
for k in range(1, n + 1):  # 时间层range(1, n + 1)
F[0] = T[k - 1, 1] + r * T[k, 0]
F[-1] = T[k - 1, m - 1] + r * T[k, m]
y = np.zeros(m - 1)
beta = np.zeros(m - 1)
x = np.zeros(m - 1)
y[0] = F[0] / b[0]
d = b[0]
for i in range(1, m - 2):  # 空间层
F[i] = T[k - 1, i + 1]  # 给F赋值
for i in range(1, m - 1):
beta[i - 1] = c[i - 1] / d
d = b[i] - a[i] * beta[i - 1]
y[i] = (F[i] - a[i] * y[i - 1]) / d
x[-1] = y[-1]
for i in range(m - 3, -1, -1):
x[i] = y[i] - beta[i] * x[i + 1]
T[k, 1:-1] = x
return T.round(6)

# 四、Crank-Nicolson（乘逆矩阵法）
def one_dimensional_heat_conduction4(T, m, n, r):
A = np.eye(m - 1, k=0) * (1 + r) + np.eye(m - 1, k=1) * (-r * 0.5) + np.eye(m - 1, k=-1) * (-r * 0.5)
C = np.eye(m - 1, k=0) * (1 - r) + np.eye(m - 1, k=1) * (0.5 * r) + np.eye(m - 1, k=-1) * (0.5 * r)

for k in range(0, n):  # 时间层
F = np.zeros(m - 1)  # m-1个元素，索引0~(m-2)
F[0] = r / 2 * (T[k, 0] + T[k + 1, 0])
F[-1] = r / 2 * (T[k, m] + T[k + 1, m])
F = C @ T[k, 1:m] + F
T[k + 1, 1:-1] = np.linalg.inv(A) @ F
return T.round(6)

# 五、Crank-Nicolson（追赶法）
def one_dimensional_heat_conduction5(T, m, n, r):
C = np.eye(m - 1, k=0) * (1 - r) + np.eye(m - 1, k=1) * (0.5 * r) + np.eye(m - 1, k=-1) * (0.5 * r)
a = np.ones(m - 1) * (-0.5 * r)
a[0] = 0
b = np.ones(m - 1) * (1 + r)
c = np.ones(m - 1) * (-0.5 * r)
c[-1] = 0

for k in range(0, n):  # 时间层
F = np.zeros(m - 1)  # m-1个元素，索引0~(m-2)
F[0] = r * 0.5 * (T[k, 0] + T[k + 1, 0])
F[-1] = r * 0.5 * (T[k, m] + T[k + 1, m])
F = C @ T[k, 1:m] + F
y = np.zeros(m - 1)
beta = np.zeros(m - 1)
x = np.zeros(m - 1)
y[0] = F[0] / b[0]
d = b[0]
for i in range(1, m - 1):
beta[i - 1] = c[i - 1] / d
d = b[i] - a[i] * beta[i - 1]
y[i] = (F[i] - a[i] * y[i - 1]) / d
x[-1] = y[-1]
for i in range(m - 3, -1, -1):
x[i] = y[i] - beta[i] * x[i + 1]
T[k + 1, 1:-1] = x
return T.round(6)

a = 0.5  # 热传导系数
x_max = 5
t_max = 100
delta_x = 0.1  # 空间步长
delta_t = 0.1  # 时间步长
m = int((x_max / delta_x).__round__(4))  # 长度等分成m份
n = int((t_max / delta_t).__round__(4))  # 时间等分成n份
t_grid = np.arange(0, t_max + delta_t, delta_t)  # 时间网格
x_grid = np.arange(0, x_max + delta_x, delta_x)  # 位置网格
r = (a * delta_t / (delta_x ** 2)).__round__(6)  # 网格比
T = initial_T(x_max, t_max, delta_x, delta_t, m, n)
print('长度等分成{}份'.format(m))
print('时间等分成{}份'.format(n))
print('网格比=', r)

p = pd.ExcelWriter('有限差分法-一维热传导-题目3.xlsx')

T1 = one_dimensional_heat_conduction1(T, m, n, r)
T1 = pd.DataFrame(T1, columns=x_grid, index=t_grid)  # colums是列号，index是行号
T1.to_excel(p, '古典显格式')

T2 = one_dimensional_heat_conduction2(T, m, n, r)
T2 = pd.DataFrame(T2, columns=x_grid, index=t_grid)  # colums是列号，index是行号
T2.to_excel(p, '古典隐格式（乘逆矩阵法）')

T3 = one_dimensional_heat_conduction3(T, m, n, r)
T3 = pd.DataFrame(T3, columns=x_grid, index=t_grid)  # colums是列号，index是行号
T3.to_excel(p, '古典隐格式（追赶法）')

T4 = one_dimensional_heat_conduction4(T, m, n, r)
T4 = pd.DataFrame(T4, columns=x_grid, index=t_grid)  # colums是列号，index是行号
T4.to_excel(p, 'Crank-Nicolson格式（乘逆矩阵法）')

T5 = one_dimensional_heat_conduction5(T, m, n, r)
T5 = pd.DataFrame(T5, columns=x_grid, index=t_grid)  # colums是列号，index是行号
T5.to_excel(p, 'Crank-Nicolson格式（追赶法）')

p.save()

end_time = datetime.datetime.now()
print('运行时间为', (end_time - start_time))

（2）运行结果与分析

长度等分成50份 时间等分成1000份 网格比= 5.0 C:/Users/86189/Desktop/Technology/Python_File/数学建模/自己总结/有限差分法-一维热传导-题目3.py:35: RuntimeWarning: overflow encountered in double_scalars   T[k, i] = (1 - 2 * r) * T[k - 1, i] + r * (T[k - 1, i - 1] + T[k - 1, i + 1]) C:/Users/86189/Desktop/Technology/Python_File/数学建模/自己总结/有限差分法-一维热传导-题目3.py:36: RuntimeWarning: overflow encountered in multiply   return T.round(6) 运行时间为 0:00:05.578520

显格式仍不收敛。

注意！Crank-Nicolson格式虽然最终收敛于y=175+4x，但是可以发现在最初的1秒内出现了数值伪振荡，这是因为我们给定的边值不合理导致的。通俗的讲，试想在生活实际中那能让一根杆在极短时间从25摄氏度跃变至175摄氏度，这合理吗？并不合理，这么大的变化率导致CN格式出现了数值伪振荡。并且只有当网格比稍大的时候才会出现这种情况，网格比小时仍然可用CN格式

展开全文
• 通过偏微分方程描述了二维...通过MATLAB编程，分析了一维具有均匀厚度无限大板和二维矩形区域的瞬态传热现象。采用图形显示方式使得偏微分方程求解更为直观和容易理解，计算结果证明了有限容积求解方法是可行、稳定的。
• 求解一维热传导问题/给定边界条件/纯手打代码/参考书籍为数值计算方法
• 该代码使用有限差分格式和 ADI... 由于对称性，计算域是在（整个块的）中平面没有通量边界条件的第象限。 三对角矩阵使用 Thomas 算法求解。 绘制特定时间的所得温度等值线。 如果需要，可以修改代码以识别稳定状态。
• 热传导方程的差分格式原理与matlab实现

万次阅读 多人点赞 2016-11-20 21:14:22
本博客介绍抛物型方程中种最基本形式：热传导方程的差分格式。 分别介绍了热传导方程的古典显格式、古典隐格式、Crank-Nicolson格式及其数值求解方法以及matlab代码。


function [  ] = ParabolicEquation( h,k )
%求解抛物型方程中的一种：热传导方程
%h:x轴步长
%k:t轴步长

r=k/(h*h);%网格比
Mx=floor(1.0/h)+1;%网格在x轴上的节点个数（算上0）
Nt=floor(1.0/k)+1;%网格在t轴上的节点个数（算上0）
N=(Mx-2)*(Nt-1); %U的维数

%%
%********************************古典显格式*********************************
%直接递推的方法求古典显格式

UxianM=zeros(Mx,Nt);
Uxian=[];
%先赋初值和边界值
for x=1:Mx
UxianM(x,1)=InitialConditions((x-1)*h);
end
for t=1:Nt
UxianM(1,t)=BoundaryConditions(0,(t-1)*k);
UxianM(Mx,t)=BoundaryConditions(1,(t-1)*k);
end
%利用显格式公式逐行递推
for t=2:Nt
for x=2:Mx-1
UxianM(x,t)=r*UxianM(x-1,t-1)+(1-2*r)*UxianM(x,t-1)+r*UxianM(x+1,t-1);
end
end
%将结果按Ku=f方法的u的结构重排
for t=2:Nt
Uxian= [Uxian;UxianM(2:Mx-1,t)];
end

%%
%************************古典隐格式*****************************************

%求K,将K看出三对角块矩阵，形如：
% C 0           ...
% D C 0         ...
% 0 D C 0       ...
% 0 0 D C 0     ...
%       ...     ...
% ...          D C

%先计算C（C是三对角矩阵）
C=eye(Mx-2)*(1+2*r);
C=C+diag(ones(1,Mx-3)*(-r),1);  %上次对角
C=C+diag(ones(1,Mx-3)*(-r),-1); %下次对角

%计算D
D=eye(Mx-2)*-1;

%计算K
temp={};
for t=1:Nt-1
temp{t}=C;
end
mid = repmat({C},Nt-1,Nt-1);%对角块
for x=1:Nt-1
for t=1:Nt-1
if x~=t
mid{x,t}=zeros(Mx-2,Mx-2); %非主对角线置0
end
if x==t+1
mid{x,t}=D; %下次对角线上的块为D
end
end
end
Kyin=cell2mat(mid);

%求f
%将f分块
% f1
% f2
% ...
% fNt-1

%f中大多数值为0，非0值用初边值条件添加
fyin=zeros(N,1);

%先计算f1
f1=zeros(Mx-2,1);
%计算f（1，1），中心点为U11
f1=zeros(Mx-2,1);
f1(1)=r*BoundaryConditions(0,k)+InitialConditions(h);
%计算f（Mx-2，1），中心点为U（Mx-2，1）
f1(Mx-2)=r*BoundaryConditions(1,(Mx-1)*k)+InitialConditions(h*(Mx-2));
%计算f（x，1） (x!=1且x!=Mx-2)
for x=2:Mx-3
f1(x)=InitialConditions(h*x);
end
fyin(1:Mx-2)=f1;

%计算边值条件计算f2~fNt-1
for t=2:Nt-1
fyin((Mx-2)*(t-1)+1)=r* BoundaryConditions(0,k*(t));
fyin((Mx-2)*t)=r* BoundaryConditions(1,k*(t));
end

%求u
Uyin=inv(Kyin)*fyin;

%%
%********************Crank-Nicolson格式*************************************
%追赶法求解
%An*Un+1=Bn*Un+en

%求An
An=eye(Mx-2)*(1+r);
An=An+diag(ones(1,Mx-3)*(-0.5*r),1);  %上次对角
An=An+diag(ones(1,Mx-3)*(-0.5*r),-1); %下次对角
InvA=inv(An);

%求Bn
Bn=eye(Mx-2)*(1-r);
Bn=Bn+diag(ones(1,Mx-3)*(0.5*r),1);  %上次对角
Bn=Bn+diag(ones(1,Mx-3)*(0.5*r),-1); %下次对角

Cn=InvA*Bn;

%追赶法
U0=[];%初值
for x=1:Mx
U0(x)=InitialConditions((x-1)*h);
end

UcnM=zeros(Mx-2,Nt-1);
Ucn=[];

%求U1  An*Un+1=Bn*Un+en,e1恰好是0向量
UcnM(:,1)=Cn*U0(2:Mx-1)'+zeros(Mx-2,1);

%利用显格式公式逐行递推
for t=2:Nt-1
n=t-1;
en=zeros(Mx-2,1);
en(1)=0.5*r*BoundaryConditions(0,n*k)+0.5*r*BoundaryConditions(0,(n+1)*k);
en(Mx-2)=0.5*r*BoundaryConditions(1,n*k)+0.5*r*BoundaryConditions(1,(n+1)*k);
UcnM(:,n+1)=Cn*UcnM(:,n)+en;
end

%将结果按Ku=f方法的u的结构重排
for t=1:Nt-1
Ucn= [Ucn;UcnM(:,t)];
end

%%
%计算精确解，用于误差分析****************************************************
U_M=zeros(Mx-2,Nt-1);
U=[];
for x=1:Mx-2
for t=1:Nt-1
U_M(x,t)=ExactSolution(x*h,t*k);
end
end
%将结果按Ku=f方法的u的结构重排
for t=1:Nt-1
U=[U;U_M(1:Mx-2,t)];
end

%%
%结果比较******************************************************************
%比较标准误差（均方根误差）

temp=(U-Uxian).^2;
temp=sum(sum(temp));
temp=temp/(Mx*Nt);
Exian=sqrt(temp);

temp=(U-Uyin).^2;
temp=sum(sum(temp));
temp=temp/(Mx*Nt);
Eyin=sqrt(temp);

temp=(U-Ucn).^2;
temp=sum(sum(temp));
temp=temp/(Mx*Nt);
Ecn=sqrt(temp);

fprintf('h: %d;k= %d\n',h,k);
fprintf('古典显格式标准误差：%d\n',Exian);
fprintf('古典隐格式标准误差：%d\n',Eyin);
fprintf('CN格式标准误差：%d\n',Ecn);

end

function [ Uxt ] = InitialConditions ( x )
%在此函数中定义初值条件

Uxt=sin(pi*x);

end

function [ Uxt ] = ExactSolution( x,t)
%在此函数中定义待求函数的精确解u(x,t),用于比较数值解

Uxt=exp(-1*pi*pi*t)*sin(pi*x);

end

function [ Uxt ] = BoundaryConditions( LeftOrRight,t )
%在此函数中定义边值条件
%LeftOrRight标识左边界条件还是右边界条件 0代表左，1代表右

Uxt=-1;
if LeftOrRight==0
Uxt=0;
elseif LeftOrRight==1
Uxt=0;
else
%不应该出现此情况，抛异常
error('错误使用边界条件!');
end

end


展开全文
• 热传导方程有限差分法的MATLAB实现 适用于解决热传导方面的偏微分问题
• matlab求解一维热传导问题

万次阅读 2019-01-18 18:43:04
Matlab 求解一维热传导方程 %%传热模型 clear ; g = ‘squareg’; %定义以为正方形 b = ‘squareb1’; %定义边界条件为零 c = 1; a = 0; f = 0; d = 1; %产生初始三角网格 [p,e,t]=initmesh(g); %定义初始条件 u0 = ...

...

matlab 订阅