
简介这份资源面向学习数值计算、偏微分方程求解的高校学生与工程技术人员聚焦用Matlab实现有限差分法求解二维热传导问题。内容围绕热传导方程∂u/∂tα(∂²u/∂x²∂²u/∂y²)展开涵盖网格划分、边界条件设定、温度场初始化、时间步长迭代更新并引入追赶法处理对角线占优的稀疏矩阵以逐行或逐列方式提升计算效率帮助读者理解离散化思路与数值稳定性控制。压缩包共4个文件以3个m脚本文件为主分别承担网格初始化、单步扩散计算与结果可视化等功能另附1张jpg示例图直观展示温度分布效果整体约27KB轻量便于快速运行与二次修改。目前已有4518人学习下载适合希望掌握有限差分编程实现、矩阵求解技巧与热传导模拟流程的读者参考借鉴。1. 从一块被加热的金属板说起为什么有限差分法解二维热传导值得你花两小时搞懂想象你手里有一块 20cm×20cm 的铝板左边整条边焊在 100℃ 的恒温热源上其余三边暴露在 25℃ 的空气中板子内部初始温度也是 25℃。现在问你30 秒后板子中心点的温度是多少60 秒后整块板的温度分布长什么样这个问题听起来像课后习题但它背后是电子散热、电池热管理、建筑保温、焊接热影响区分析里天天要面对的真实场景。解析解只有极少数规则边界和常物性条件下才写得出来。工程上真正能打的工具是数值方法而有限差分法解二维热传导问题是其中门槛最低、最容易在 Matlab 里从零跑通的一条路。这篇文章不讲泛泛的数值分析概论。我会把显式格式、隐式格式、稳定性条件、边界处理、矩阵组装、可视化这几件事按“能直接抄进 Matlab 跑出图”的标准拆开讲。适合两类人一类是刚接触数值传热、想用一个完整案例把有限差分法吃透的学生或初级工程师另一类是手头有实际二维导热问题、需要快速搭一个可改参数的计算框架的从业者。读完你至少能得到一个可运行的求解器骨架以及一份“哪里容易翻车”的清单。2. 二维热传导方程怎么离散从偏微分到可迭代的代数式2.1 控制方程与定解条件先写清楚二维瞬态热传导方程常物性、无内热源的标准形式是ρ·c·∂T/∂t k·(∂²T/∂x² ∂²T/∂y²)其中 ρ 是密度c 是比热容k 是导热系数T 是温度t 是时间。工程上常把它改写成∂T/∂t α·(∂²T/∂x² ∂²T/∂y²)α k/(ρ·c) 叫热扩散率单位 m²/s。这个 α 是后面稳定性判断的核心参数铝的 α 大约 9.7×10⁻⁵ m²/s水大约 1.4×10⁻⁷ m²/s差了近三个数量级直接决定时间步长能取多大。定解条件分三类初始条件 T(x,y,0)T₀(x,y)边界条件可以是第一类给定温度、第二类给定热流、第三类对流换热。本文以第一类边界为主最后会补第三类对流的处理方式。2.2 显式差分格式最直观但最挑时间步把求解区域划成均匀网格x 方向 Nx 个节点y 方向 Ny 个节点步长 dx、dy。时间方向步长 dt。对时间用前向差分对空间用中心差分(T[i,j]^(n1) - T[i,j]^n)/dt α·[(T[i1,j]^n - 2T[i,j]^n T[i-1,j]^n)/dx² (T[i,j1]^n - 2T[i,j]^n T[i,j-1]^n)/dy²]整理后得到显式迭代式T[i,j]^(n1) T[i,j]^n α·dt·[(T[i1,j]^n - 2T[i,j]^n T[i-1,j]^n)/dx² (T[i,j1]^n - 2T[i,j]^n T[i,j-1]^n)/dy²]这个式子最大的好处是每个新时刻的温度只依赖旧时刻的邻居值不需要解方程组一行循环就能推进。代价是稳定性限制。二维显式格式的稳定性条件是α·dt·(1/dx² 1/dy²) ≤ 1/2如果 dxdyh则简化为 α·dt/h² ≤ 1/4。这就是很多人第一次跑显式格式时温度爆炸的原因——dt 取大了。2.3 隐式格式无条件稳定但每步要解方程组显式格式的稳定性限制在细网格下非常致命。比如 h1mm铝的 α9.7×10⁻⁵要求 dt ≤ 0.25×h²/α ≈ 2.6×10⁻³ 秒。要模拟 60 秒得迭代两万三千步。这时候隐式格式就值得上了。对时间用后向差分空间仍用中心差分(T[i,j]^(n1) - T[i,j]^n)/dt α·[(T[i1,j]^(n1) - 2T[i,j]^(n1) T[i-1,j]^(n1))/dx² (T[i,j1]^(n1) - 2T[i,j]^(n1) T[i,j-1]^(n1))/dy²]整理后每个节点的方程里出现五个未知量自身、上下左右邻居。把所有内节点方程联立得到一个大型稀疏线性方程组 A·T^(n1)b。二维问题节点数轻松上万必须用稀疏矩阵存储和求解。Matlab 里组装这个矩阵的常见做法是用 kron 函数构造二维拉普拉斯算子的稀疏表示或者直接用循环加 spalloc 逐点填。前者代码短但可读性差后者慢但容易改边界。我一般先用循环版跑通逻辑确认结果合理后再换 kron 版提速。2.4 显式与隐式的选型判断对比项显式格式隐式格式每步计算量极小只需邻居加减需解稀疏线性方程组稳定性条件稳定dt 受 h² 限制无条件稳定适合场景短时间、粗网格、快速验证长时间、细网格、工程计算Matlab 实现难度低双重循环即可中需组装稀疏矩阵边界条件改动直接改边界节点值需同步改矩阵对应行实际项目中如果只是验证一个想法或者网格不超过 50×50、模拟时间不长显式格式足够。如果网格到 200×200 以上或者要算到稳态隐式格式更划算。3. 在 Matlab 里把显式求解器跑起来网格、初值、边界、迭代3.1 参数定义与网格生成先定义物理参数和网格。下面这段代码可以直接复制运行改参数就能换材料、换尺寸。% 二维瞬态热传导 - 显式有限差分 clear; clc; close all; % 物理参数以铝为例 k 237; % 导热系数 W/(m·K) rho 2700; % 密度 kg/m³ c 900; % 比热容 J/(kg·K) alpha k/(rho*c); % 热扩散率 m²/s % 几何与网格 Lx 0.2; % x方向长度 m Ly 0.2; % y方向长度 m Nx 41; % x方向节点数 Ny 41; % y方向节点数 dx Lx/(Nx-1); dy Ly/(Ny-1); % 时间参数 t_end 30; % 模拟总时间 s dt 0.25 * min(dx^2, dy^2) / alpha * 0.9; % 稳定性余量0.9 Nt ceil(t_end/dt); dt t_end/Nt; % 回调整齐 % 检查稳定性 r alpha*dt*(1/dx^2 1/dy^2); fprintf(稳定性参数 r %.4f (需 0.5)\n, r);这里 dt 的取法用了 0.9 的安全系数。理论上 r≤0.5 就稳定但实际编程中浮点误差和边界处理可能让临界值附近出现振荡留 10% 余量是血泪经验。Nt 用 ceil 再回算 dt保证时间步数整数且总时间准确。3.2 初始条件与边界条件的赋值初始温度全场 25℃左边界 100℃其余三边 25℃。% 初始温度场 T0 25; T T0 * ones(Nx, Ny); % 边界条件 T_left 100; % 左边界温度 T_other 25; % 其余边界温度 % 应用初始边界 T(1, :) T_left; T(end, :) T_other; T(:, 1) T_other; T(:, end) T_other;注意边界节点的索引方式T(1,:) 是 x 方向第一个节点对应整条 y 边T(:,1) 是 y 方向第一个节点对应整条 x 边。Matlab 是列优先存储T(i,j) 中 i 是行索引对应 xj 是列索引对应 y。这个约定要在整个代码里保持一致否则后处理画图时 x 和 y 会颠倒。3.3 显式迭代主循环% 预分配新温度场 T_new T; % 记录中心点温度历史 center_i round(Nx/2); center_j round(Ny/2); T_center zeros(Nt, 1); % 主循环 for n 1:Nt % 内节点更新 for i 2:Nx-1 for j 2:Ny-1 d2x (T(i1,j) - 2*T(i,j) T(i-1,j))/dx^2; d2y (T(i,j1) - 2*T(i,j) T(i,j-1))/dy^2; T_new(i,j) T(i,j) alpha*dt*(d2x d2y); end end % 边界条件每步重新施加 T_new(1, :) T_left; T_new(end, :) T_other; T_new(:, 1) T_other; T_new(:, end) T_other; % 更新 T T_new; T_center(n) T(center_i, center_j); end这段代码里有两个容易忽略的点。第一边界条件必须在每步迭代后重新赋值因为内节点更新不会碰边界但如果你用 TT_new 整体覆盖边界值会被上一步的旧值保留——如果边界是定值其实不变但如果是时变边界或对流边界就必须每步更新。第二T_new 初始化后内节点被覆盖边界被重新赋值逻辑才完整。3.4 结果可视化与温度曲线% 温度场云图 figure; imagesc(linspace(0,Ly,Ny), linspace(0,Lx,Nx), T); colorbar; xlabel(y (m)); ylabel(x (m)); title(sprintf(t %.1f s 温度分布, t_end)); axis equal tight; % 中心点温度随时间变化 figure; plot((1:Nt)*dt, T_center, LineWidth, 1.5); xlabel(时间 (s)); ylabel(中心点温度 (℃)); title(中心点温度历史); grid on;imagesc 的第一个参数对应列y方向第二个参数对应行x方向所以 xlabel 写 yylabel 写 x这是 Matlab 画矩阵的常见反直觉点。如果发现图的方向和物理直觉不符先检查这里。4. 隐式格式的矩阵组装与稀疏求解从逐点方程到 A\b4.1 二维隐式方程的标准形式隐式格式下每个内节点 (i,j) 的方程写成T[i,j]^(n1) - α·dt/dx²·(T[i1,j]^(n1) - 2T[i,j]^(n1) T[i-1,j]^(n1)) - α·dt/dy²·(T[i,j1]^(n1) - 2T[i,j]^(n1) T[i,j-1]^(n1)) T[i,j]^n令 rx α·dt/dx²ry α·dt/dy²整理后-rx·T[i-1,j] (12rx2ry)·T[i,j] - rx·T[i1,j] - ry·T[i,j-1] - ry·T[i,j1] T[i,j]^n这就是五点格式。把所有内节点按某种顺序编号成一维未知量就得到稀疏线性方程组。4.2 用稀疏矩阵组装系数矩阵下面用逐点填法组装虽然比 kron 慢但边界处理直观适合理解和修改。% 隐式格式求解器 Nx 41; Ny 41; dx Lx/(Nx-1); dy Ly/(Ny-1); dt 0.5; % 隐式格式对dt无稳定性限制取大些 Nt 60; alpha k/(rho*c); rx alpha*dt/dx^2; ry alpha*dt/dy^2; % 内节点编号映射 n_inner (Nx-2)*(Ny-2); idx (i,j) (i-2)*(Ny-2) (j-1); % i从2到Nx-1, j从2到Ny-1 % 组装稀疏矩阵 rows []; cols []; vals []; for i 2:Nx-1 for j 2:Ny-1 p idx(i,j); % 自身 rows(end1) p; cols(end1) p; vals(end1) 1 2*rx 2*ry; % 左邻居 if i 2 rows(end1) p; cols(end1) idx(i-1,j); vals(end1) -rx; end % 右邻居 if i Nx-1 rows(end1) p; cols(end1) idx(i1,j); vals(end1) -rx; end % 下邻居 if j 2 rows(end1) p; cols(end1) idx(i,j-1); vals(end1) -ry; end % 上邻居 if j Ny-1 rows(end1) p; cols(end1) idx(i,j1); vals(end1) -ry; end end end A sparse(rows, cols, vals, n_inner, n_inner);这段代码里 idx 函数把二维索引 (i,j) 映射到一维编号。边界节点不进入未知量它们的影响通过右端项 b 体现。注意 if 判断当 i2 时左邻居是边界节点不加入矩阵其贡献移到 b 里。4.3 右端项构造与时间推进T T0 * ones(Nx, Ny); T(1,:) T_left; T(end,:) T_other; T(:,1) T_other; T(:,end) T_other; for n 1:Nt b zeros(n_inner, 1); for i 2:Nx-1 for j 2:Ny-1 p idx(i,j); b(p) T(i,j); % 边界贡献 if i 2 b(p) b(p) rx * T_left; end if i Nx-1 b(p) b(p) rx * T_other; end if j 2 b(p) b(p) ry * T_other; end if j Ny-1 b(p) b(p) ry * T_other; end end end T_vec A \ b; % 回填到二维 for i 2:Nx-1 for j 2:Ny-1 T(i,j) T_vec(idx(i,j)); end end endA\b 在 Matlab 里对稀疏矩阵自动调用合适的直接求解器41×41 网格的内节点数是 39×391521求解瞬间完成。如果网格到 200×200内节点近四万仍然在可接受范围。再大就要考虑迭代求解器如 pcg。4.4 显式与隐式结果对比验证同一个物理问题用显式和隐式各跑一遍中心点温度曲线应该趋于一致。如果差异明显优先检查三处边界条件是否每步都正确施加、dx 和 dy 是否与索引方向匹配、dt 是否在显式稳定性范围内。我一般会先用粗网格21×21和短时间5秒做交叉验证确认两套代码给出相近结果后再上细网格。5. 避坑与排查有限差分法解二维热传导最常见的五个翻车点5.1 温度场出现棋盘振荡现象温度云图上出现相邻节点高低交替的棋盘格纹路或者中心点温度曲线上下抖动。原因显式格式的稳定性条件被突破r 值超过 0.5。常见于 dx 和 dy 不相等时只按其中一个方向估算 dt或者改了网格数忘了重算 dt。解决在代码里显式计算 r alphadt(1/dx^21/dy^2)加判断 if r0.5 就报错或自动缩小 dt。不要凭感觉设 dt。5.2 边界温度不生效现象左边界设了 100℃但结果里边界附近温度始终接近初始值 25℃。原因边界节点在迭代中被内节点更新覆盖或者隐式格式里边界贡献没有加到右端项 b 里。显式格式中如果先更新内节点再赋值边界顺序是对的但如果先赋值边界再更新内节点且循环范围包含了边界就会覆盖。解决显式格式中内节点循环从 2 到 Nx-1不碰边界每步结束后重新赋值边界。隐式格式中检查 b 的边界贡献是否遗漏。5.3 隐式格式结果与显式差异大现象同样物理参数下隐式格式算出的温度明显偏高或偏低。原因dt 取得太大虽然隐式格式无条件稳定但时间精度是一阶的dt 过大导致时间离散误差显著。另外边界贡献的符号容易搞反。解决先用小 dt 跑隐式和显式结果对比确认一致后再逐步放大 dt 观察精度变化。边界贡献的符号如果边界温度高于内节点热量流入b 里应该是加号。5.4 网格方向与物理方向不一致现象云图上高温区出现在错误的方向或者 x 和 y 的边界条件对调了。原因Matlab 矩阵索引 T(i,j) 中 i 对应行通常画图时是 y 轴j 对应列x 轴。如果代码里把 i 当 x、j 当 y但画图时没有对应转置就会颠倒。解决统一约定。我一般约定 T(i,j) 中 i 是 x 方向索引j 是 y 方向索引画图时 imagesc(y_vec, x_vec, T) 并设置 axis xy。在代码开头注释写清楚避免后面改乱。5.5 长时间模拟后温度不收敛到稳态现象模拟时间足够长后温度场仍在缓慢变化没有达到稳态。原因如果边界条件全是第一类定温稳态一定存在且唯一。不收敛通常是迭代步数不够或者边界条件实际是绝热第二类导致能量守恒但分布不唯一。检查边界设置是否和预期一致。解决对于第一类边界可以解析估算稳态时间尺度 τ ≈ L²/α。铝板 L0.2mτ ≈ 0.04/9.7e-5 ≈ 412 秒。模拟时间至少取 3τ 才能接近稳态。如果边界有对流时间尺度会不同。6. 从能跑到好用变导热系数、对流边界与结果验证的三个进阶技巧6.1 处理第三类对流边界实际工程中更常见的是对流边界比如板子右边界暴露在 25℃ 空气中对流换热系数 h10 W/(m²·K)。这时候边界节点的方程要用能量平衡推导。右边界节点 (Nx,j) 的离散方程用虚拟节点法或能量平衡法可得T[Nx,j]^(n1) T[Nx,j]^n alphadt[ (T[Nx-1,j]^n - T[Nx,j]^n)/dx² * 2 (T[Nx,j1]^n - 2T[Nx,j]^n T[Nx,j-1]^n)/dy² ] 2hdt/(rhocdx)*(T_inf - T[Nx,j]^n)这里的关键是边界节点与内节点的差分格式不同需要单独写循环。隐式格式下对流边界会改变矩阵对应行的系数和右端项。我一般先在显式格式里把对流边界调通确认热流方向合理再移植到隐式。6.2 变导热系数与非线性问题的处理如果材料导热系数随温度变化kk(T)方程变成非线性。显式格式处理起来很自然每步用当前温度算 k再更新温度。隐式格式则需要迭代因为矩阵系数依赖未知温度。常见做法是 Picard 迭代先用上一步温度算 k 组装矩阵解一次再用新温度更新 k重复两三次。% 变导热系数显式格式片段 for i 2:Nx-1 for j 2:Ny-1 k_ij k0 beta*(T(i,j) - T_ref); % 线性温度依赖 alpha_ij k_ij/(rho*c); d2x (T(i1,j) - 2*T(i,j) T(i-1,j))/dx^2; d2y (T(i,j1) - 2*T(i,j) T(i,j-1))/dy^2; T_new(i,j) T(i,j) alpha_ij*dt*(d2x d2y); end end注意稳定性判断里的 alpha 要取最大值否则高温区可能局部失稳。6.3 用解析解和能量守恒做验证数值解最怕的是“看起来合理但实际错了”。两个低成本验证手段第一一维极限验证。把 y 方向边界设成绝热问题退化为一维有解析解分离变量法或误差函数解。用粗网格跑数值解和解析解对比误差应随网格加密而减小。第二能量守恒检查。如果所有边界都是绝热总热量应守恒。计算每步的总热能 sum(T(:))rhocdxdy观察是否恒定。如果漂移说明格式有问题。验证手段操作通过标准一维退化y方向绝热对比解析解中心点误差2%能量守恒全绝热边界追踪总热量相对漂移0.1%网格收敛加密网格观察解变化变化量随h²减小显隐交叉同参数显式与隐式对比曲线重合我自己的习惯是任何新写的求解器先跑全绝热能量守恒再跑一维退化对比两个都过了才敢用到实际问题上。这个习惯帮我省了无数次回头查错的功夫。希望帮到你。本文还有配套的精品资源点击获取