利用有限元法求解一维热传导问题

       我们都知道热传导方程是大名鼎鼎的傅里叶提出的,而对于此方程的解也可以用傅里叶变换的方法得到,但笔者已经记不起该怎么求解了(尽管上学期才刚学过数理方法啊)。但是无伤大雅,因为我已经掌握了(其实还没有)对付这一顽固的偏微分方程的大杀器——有限元!!!

       那么有人要问了:什么是有限元呢?在这里,我打算贴出一个很棒的知乎回答来解释,我也从中受益颇丰。链接如下:

http://有限元分析(FEA)是个什么东东 - J Pan的文章 - 知乎 https://zhuanlan.zhihu.com/p/56326567​​​​​​

       当然仅靠上面这种科普类型的文章我觉得是远远不够的,还是需要找几本专门的教科书来真正掌握其原理和思想。

       闲话不多说,在默认读者(如果有的话)已经大致了解有限元的基础上,我们就可以开始学习运用有限元了。实际上,运用有限元更简单的例子可能是稳态情况下的一维热传导问题,但是,笔者受外界不可抗力的影响,先上手的是非稳态的问题(不过稳态也没什么难度)。

       在求解偏微分方程的时候,我们当然需要知道各种约束条件,比如边界条件、初值条件等等。而在下方的程序中,我选择使用第三类边界条件,即q = h(Ta - Tside)。

       下面简单介绍一下程序步骤。首先是进行网格划分,网格个数当然是越多越好,但是求解的时间也会相应大大增加,比如在下方程序中因为我把网格数设置为了500,相应的刚度矩阵就是501行501列,再加上我将时间步长设置较小,往往运行一次需要几分钟时间(不过我也有在考虑利用pytorch进行GPU加速来减小运行时间,希望可行吧)。

       在划分完网格之后,就是定义各种矩阵,比如:刚度矩阵、边界条件矩阵、质量矩阵以及载荷向量,当然,如果考虑更加复杂的情况,即考虑棒自身内部有热源,那么热源也会相应地产生一个矩阵。

       接下来就是定义时间步长和你想要迭代的时间,再初始化每个温度节点的温度值。

       至此就来到了程序中最重要的一步,即在一个for循环中不断求解方程组,更新各个节点的温度,直至循环结束。

       最后的最后,就是将数据可视化,这里用到了matplotlib库,呈现出来的结果就是一道道优美的曲线,代价就是电脑的风扇可能会表达小小的不满。

       先写这些吧,接下来的一周要着手完成二维热传导的问题,祝我好运!

# 导入必要的库
import numpy as np
import matplotlib.pyplot as plt

# 定义问题域、边界条件和初始条件
# 棒的横截面积默认为1;棒内没有热源;
L = 1  # 棒长

# k = float(input('热扩散系数:'))
# c = float(input('比热:'))
# p = float(input('密度:'))
# h_left = float(input('左端换热系数:'))
# h_right = float(input('右端换热系数:'))

k = 0.00015
c = 4000
p = 1
h_left = 0
h_right = 20

lamda = k * c * p  # 热导率

Ta1 = 50  # 设置左端环境温度
Ta2 = 0  # 设置右端环境温度
T0 = 100  # 设置棒的初始温度

# 网格划分和节点编号
N = 50
dl = L / N  # 单元长度(即节点间距)
x = np.linspace(0, L, N + 1)  # 节点坐标数组

# 构建刚度矩阵
K = np.zeros((N + 1, N + 1))  # 总体刚度矩阵初始化为零矩阵(N+1)*(N+1)

for i in range(N):  # 遍历每个单元

    # 单元刚度矩阵 K_e (2*2)
    K_e = lamda / dl * np.array([[1, -1],
                                 [-1, 1]])
    K[i:i + 2, i:i + 2] += K_e

# 构建边界条件矩阵
Boundary = np.zeros((N + 1, N + 1))

Boundary[0, 0] = h_left
Boundary[-1, -1] = h_right

# 构建质量矩阵
m = np.zeros((N + 1, N + 1))
for e in range(N + 1):
    for f in range(N + 1):
        if e == f:
            m[e, f] = 2 * dl * p * c / 3
        elif e == f + 1:
            m[e, f] = dl * p * c / 6
        elif f == e + 1:
            m[e, f] = dl * p * c / 6
m[0, 0] = dl * p * c / 3
m[-1, -1] = dl * p * c / 3

# 构建载荷向量
F = np.zeros(N + 1)

F[0] = h_left * Ta1
F[-1] = h_right * Ta2

dt = 1000  # 时间步长
t_max = 10000  # 设置传热时间(t/s)

# 定义初始条件
u = np.ones(N + 1) * T0

plt.figure()
plt.xlabel('x (m)')  # 设置x轴标签
plt.ylabel('T (°C)')  # 设置y轴标签
plt.title('One-dimensional heat conduction problem')  # 设置标题


t = np.arange(0, t_max + dt, dt)

for ti in t:  # 遍历每个时间步

    u = np.linalg.solve((K + Boundary + m / dt), np.dot(m / dt, u) + F)

    plt.plot(x, u, label=f't={ti}')  # 绘制最终状态的曲线

plt.savefig("photo2.png", dpi=500)

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
三维热传导方程是一个非常复杂的偏微分方程,可以用有限差分法(FDM)或有限元法(FEM)进行求解。以下是使用FDM在Matlab中求解三维热传导方程的一般步骤: 1. 定义计算区域和网格 首先需要定义热传导问题的计算区域和离散化网格。对于三维问题,可以使用三维网格来离散化计算区域。 2. 定义初始和边界条件 需要定义问题的初始和边界条件。初始条件是指在计算开始时物体的温度分布。边界条件是指在物体表面的温度分布或通量。 3. 设定时间步长和求解时间 需要设定时间步长和求解时间。时间步长决定了每个时间步长内的计算精度,而求解时间决定了计算的总时间。通常需要进行多个时间步长的迭代计算。 4. 迭代求解 使用差分法在网格上迭代求解热传导方程。在每个时间步长内,需要根据上一步的温度分布计算当前时间步长的温度分布。 5. 结果可视化 在计算完成后,需要将计算结果可视化。可以使用Matlab的plot3函数来绘制三维温度分布图。 以下是一个简单的三维热传导方程的Matlab代码示例: ``` % 定义计算区域和网格 L = 1; W = 1; H = 1; nx = 21; ny = 21; nz = 21; dx = L / (nx - 1); dy = W / (ny - 1); dz = H / (nz - 1); x = linspace(0, L, nx); y = linspace(0, W, ny); z = linspace(0, H, nz); [X, Y, Z] = meshgrid(x, y, z); % 定义初始和边界条件 T = zeros(nx, ny, nz); T(:, :, 1) = 100; % 底部温度为100 T(:, :, end) = 0; % 顶部温度为0 T(1, :, :) = 50; % 左侧温度为50 T(end, :, :) = 50; % 右侧温度为50 T(:, 1, :) = 50; % 前侧温度为50 T(:, end, :) = 50; % 后侧温度为50 % 设定时间步长和求解时间 dt = 0.01; tmax = 10; t = 0; % 迭代求解 while t <= tmax T_old = T; for i = 2:nx-1 for j = 2:ny-1 for k = 2:nz-1 T(i, j, k) = T_old(i, j, k) + dt * ( ... (T_old(i+1, j, k) - 2*T_old(i, j, k) + T_old(i-1, j, k)) / dx^2 + ... (T_old(i, j+1, k) - 2*T_old(i, j, k) + T_old(i, j-1, k)) / dy^2 + ... (T_old(i, j, k+1) - 2*T_old(i, j, k) + T_old(i, j, k-1)) / dz^2 ); end end end t = t + dt; end % 结果可视化 figure; h = slice(X, Y, Z, T, [0, L/2, L], [0, W/2, W], [0, H/2, H]); set(h, 'EdgeColor', 'none', 'FaceAlpha', 0.5); xlabel('x'); ylabel('y'); zlabel('z'); colorbar; ``` 这个代码会计算一个长度为L,宽度为W,高度为H的立方体,底部温度为100,顶部温度为0,四周边界温度为50的三维热传导问题。它会使用差分法在网格上迭代求解热传导方程,并在计算完成后绘制三维温度分布图。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值