MATLAB实现SIMPLE算法求解方腔驱动流:压力修正与交错网格实战

MATLAB实现SIMPLE算法求解方腔驱动流:压力修正与交错网格实战 简介基于Matlab的simple算法方腔驱动流求解资源面向流体力学初学者与课程设计、毕业设计等场景。资源包含完整Matlab代码、中英文算法说明文档及README覆盖Re50、400、1000、5000等多组工况网格从101×101至501×501时间步长0.005s至0.001s可直接运行并观测方腔流场演化。包内共5个文件含2个.m源码、2个PDF算法讲解中英文各一和1个md说明文档整体仅235KB轻量便于下载。已有337人学习适合用于理解SIMPLE算法在不可压缩黏性流动求解中的实现细节也可作为课程设计或工程实训的起点。通过代码与文档对照读者可掌握交错网格、压力修正迭代等关键步骤并可在不同雷诺数下比较流场涡结构变化提升对CFD数值求解流程的直观认识。1. 方腔驱动流是检验SIMPLE算法收敛性的试金石做CFD的人几乎都绕不开方腔驱动流lid-driven cavity顶盖以恒定速度运动其余三壁固定流体在封闭方腔内形成复杂涡结构。这个看起来简单的算例包含了压力-速度耦合、边界层分离、角涡生成等全部典型特征而且有Ghia等人用基准解提供了从Re100到10000的精确数据用来验证程序正确性再好不过。用MATLAB实现SIMPLE算法求解这个问题最大的价值不在于“能跑出来”而在于你能从残差曲线和流函数等值线里直观看到压力修正、交错网格、松弛因子这些抽象概念到底在求解过程中扮演什么角色。无论你是课程设计还是入门CFD编程这个项目都能让你在动手过程中理解SIMPLE为什么需要“预测-修正”两步走以及为什么雷诺数一高网格和时间步长就必须跟着调整。2. SIMPLE算法的压力-速度耦合与交错网格布置2.1 从动量方程到压力修正方程SIMPLE的全称是Semi-Implicit Method for Pressure-Linked Equations核心思路是先用猜测的压力场求解动量方程得到速度场再通过压力修正方程修正速度和压力反复迭代直到满足连续方程。在二维不可压方腔流中控制方程是Navier-Stokes方程和连续性方程。离散后动量方程可以写成形如[ a_P u_P \sum a_{nb} u_{nb} (p_W - p_E) A b_u ]其中 (a_P) 是主节点系数(a_{nb}) 是邻点系数(A) 是控制体界面面积(b_u) 是源项。这里最关键的是压力梯度项如果压力和速度存储在同一套节点上离散后的压力梯度在均匀网格上可能无法检测到棋盘状的压力波动。这就是为什么原始SIMPLE算法需要交错网格。压力修正方程由连续性方程推导而来。假设速度修正 (u) 和压力修正 (p) 满足 (u -D_e (p_E - p_P))代入离散连续方程后得到关于 (p) 的方程[ a_P pP \sum a{nb} p_{nb} b ]其中 (b) 是质量残差即当前速度场不满足连续方程的质量不平衡量。求解这个方程得到 (p) 后更新压力和速度[ p_P p_P \alpha_p p_P,\quad u_e u_e^* d_e (p_P - p_E) ](\alpha_p) 是压力松弛因子一般取0.60.8过大容易震荡发散过小收敛太慢。这里的 (d_e) 是动量方程系数倒数的组合体现压力修正对速度的传递作用。2.2 交错网格为什么不能把所有变量放在同一套网格交错网格的思路是把 (u) 速度存储在控制体东、西界面上(v) 速度存储在控制体南、北界面上压力 (p) 存储在主控制体中心。这样做之后压力梯度项自然地作用在速度所在的控制体界面上棋盘压力场就无法“骗过”离散方程了。MATLAB实现中常见的做法是定义三套网格坐标% 均匀网格参数 nx 101; ny 101; % 主控制体数 Lx 1.0; Ly 1.0; % 方腔边长 dx Lx / (nx-1); dy Ly / (ny-1); % 压力节点主网格坐标 xp linspace(0, Lx, nx); yp linspace(0, Ly, ny); % u速度节点位于x方向界面个数为 nx-1 个内部界面 % 这里为便于索引用与压力网格相同的维数边界处速度设为边界值 xu (xp(1:end-1) xp(2:end)) / 2; % u节点x坐标交错半个网格 yu yp; % u节点y坐标与主网格一致 % v速度节点位于y方向界面 xv xp; yv (yp(1:end-1) yp(2:end)) / 2;这段代码里xu是相邻压力节点的中点对应控制体界面yv同理。这样做的结果是求解 (u) 动量方程时压力梯度直接取相邻两个压力节点的值相减不会出现同节点上的压力差为零的问题。注意数组维度的匹配压力是nx×ny的二维数组而 (u) 和 (v) 的维度分别是(nx-1)×ny和nx×(ny-1)在索引时要格外小心边界。2.3 离散系数与源项处理在交错网格上离散动量方程时对流项采用迎风格式upwind保证对角占优扩散项采用中心差分。以 (u_e) 为例其离散系数为[ a_E \max(-F_e, 0) D_e,\quad a_W \max(F_w, 0) D_w ]其中 (F_e \rho u_e \Delta y) 是界面质量流量(D_e \mu \Delta y / \delta x_e) 是扩散导纳。(\max(-F_e, 0)) 表示当 (F_e) 为正流体从左向右流过界面时东侧系数取0符合迎风的思想。源项处理上重力忽略不计源项主要来自压力梯度。在SIMPLE迭代中先用上一轮压力场计算动量方程的猜测速度 (u^)、(v^)这一步叫作“预测”。实际代码中往往把所有系数矩阵组装成稀疏矩阵用MATLAB的左除运算符\直接求解线性方程组而不是自己写迭代求解器因为稀疏矩阵直接法对小规模问题更快且稳定。3. 用MATLAB搭建方腔驱动流求解器3.1 几何与边界条件设定方腔驱动流的边界条件很简单顶盖 (yL_y) 处 (uU_{lid})通常取1.0(v0)其余三壁 (uv0)。压力边界不需要在壁上显式指定因为交错网格中压力方程在边界处通过速度的von Neumann条件自然处理。但在编码时要注意顶盖的 (u) 速度在角点上的处理角点处同时属于顶盖和侧壁一般取平均或直接按顶盖速度处理实测中角点速度赋值对收敛性影响很小但会影响局部涡的精度。网格参数直接决定计算量。Re50时用 (101\times101) 网格Re1000时也用 (101\times101) 网格而Re5000时用 (501\times501) 网格这个选择不是随意的需要满足高雷诺数下边界层分辨的最小网格数要求。通俗地说雷诺数越高腔体内涡的尺度越小太粗的网格会把小尺度涡结构直接抹平。3.2 SIMPLE迭代主循环的代码骨架下面给出一个简化但完整的迭代主体框架省略了系数组装的具体细节但保留了SIMPLE的四个核心步骤预测、修正、更新、判断。% 参数初始化 Re 1000; nx 101; ny 101; U_lid 1.0; % 顶盖速度 rho 1.0; mu U_lid * Lx / Re; % 由Re数反推动力粘性 alpha_u 0.7; % 速度松弛因子 alpha_p 0.6; % 压力松弛因子 max_iter 5000; % 最大迭代数 tol 1e-6; % 残差容限 % 初始化速度、压力场 u zeros(nx-1, ny); % u速度存储在界面 v zeros(nx, ny-1); p zeros(nx, ny); for iter 1:max_iter % ---- 步骤1用当前压力场求解动量方程获得猜测速度u*, v* ---- [u_star, v_star] solve_momentum(u, v, p, mu, dx, dy, U_lid); % ---- 步骤2由连续性方程构造压力修正方程并求解 ---- [p_prime] solve_pressure_correction(u_star, v_star, dx, dy); % ---- 步骤3修正速度和压力 ---- u u_star alpha_p * d_u .* (p_prime(1:end-1,:) - p_prime(2:end,:)); v v_star alpha_p * d_v .* (p_prime(:,1:end-1) - p_prime(:,2:end)); p p alpha_p * p_prime; % ---- 步骤4计算质量残差并判定收敛 ---- [max_res, L2_res] compute_residual(u, v, dx, dy); if L2_res tol fprintf(Converged at iteration %d\n, iter); break; end end这里solve_momentum函数负责组装并求解两个动量方程solve_pressure_correction求解压力修正的泊松方程d_u和d_v是动量方程系数导出的修正系数矩阵。注意alpha_p同时出现在压力修正和速度修正中这样做的理论依据是压力和速度修正都要经过欠松弛否则迭代容易出现锯齿状震荡。实际上更稳健的做法是对压力修正方程使用独立的松弛比如压力项取0.6、速度项取0.7这需要根据残差曲线微调。3.3 松弛因子与收敛判断的实现松弛因子在SIMPLE算法里是两个完全不同的东西。第一个是显式欠松弛用在速度更新上u (1 - alpha_u) * u_old alpha_u * u_new;第二个是压力修正的隐含欠松弛反映在修正方程中略去 (\sum a_{nb} p_{nb}) 项。工程上最常用的做法是对速度和压力分别设置独立因子并且观察变化曲线。判断收敛不能只看残差绝对值因为不同网格数下残差尺度差别很大。实际项目中我一般同时监控两个量一是连续性方程的最大质量残差二是腔体内特征点的速度值随迭代的波动幅度。后者很实用如果迭代到后期残差还在慢慢下降但特征点速度已经不再变化说明流场已达到稳态工程精度可以提前终止。反过来如果特征点速度仍在单调变化说明还没有真正收敛残差小于容限也可能只是假收敛。4. 不同雷诺数下的网格与时间步长匹配策略4.1 RE50与RE400的稳态推进Re50时腔内流动是低雷诺数层流一个主涡占据腔体中心角涡很小。此时用 (101\times101) 网格、(\Delta t0.005s) 做瞬态推进大概几百步就能收敛到稳态。这个工况适合用来验证程序的正确性因为收敛快可以快速对比流函数极值。Re400时主涡中心下移靠近腔体中心左上和右上角涡开始变明显主涡周围出现二次涡。这时网格密度 (101\times101) 仍然够用但需要注意顶盖附近的边界层(\partial u/\partial y) 在顶盖处变化剧烈如果不加密网格得到的壁面摩擦系数会偏高。一个常见的做法是先跑Re50把收敛流场作为Re400的初始猜测。这样做的好处是动量方程的对流项从一个接近真实的流场出发非线性迭代更平滑不容易因初始猜测太差而发散。在我的经验里直接用均匀零场跑Re400大概率也能收敛但残差曲线会出现一个先升后降的平台期平台期持续越长浪费的迭代步越多。4.2 RE1000与RE4000的高雷诺数挑战Re1000时的流动已经表现出明显的非对称涡结构左上角涡和右下角涡的大小差别清晰可见。用 (101\times101) 网格和 (\Delta t0.005s) 时收敛所需的SIMPLE迭代次数比Re50时高一个数量级原因是压力修正方程的条件数变差高低频误差衰减不均衡。这时需要把压力松弛因子适当调低比如从0.6降到0.4否则压力修正容易过头导致速度场剧烈振荡。Re5000时流动开始出现向湍流过渡的特征腔内涡结构更复杂顶盖边界层很薄此时网格必须加到 (501\times501)时间步长要缩小到 (\Delta t0.001s)否则对流项稳定性条件 (CFL U\Delta t/\Delta x) 会超过0.5。保守估计这个工况单次迭代要处理约25万个控制体的系数矩阵MATLAB稀疏矩阵直接法在普通工作站上需要几秒钟一次总迭代数千步整个算例跑几个小时很正常。如果内存不足可以把直接法换成ILU预条件共轭梯度法但收敛性需要重新调参数。4.3 参数选择与结果验证不同工况的参数配置可以整理成下表方便直接对照雷诺数网格规模时间步长(s)压力松弛因子速度松弛因子预计迭代步数50101×1010.0050.80.7200-500400101×1010.0050.70.7800-15001000101×1010.0050.60.62000-40005000501×5010.0010.40.55000表中的松弛因子是我调试时的常用初值不是最优值。判断这些参数是否合理的方法很简单跑几十步后看中间截面的速度分布是否光滑如果相邻点出现锯齿状波动说明压力修正过强或网格长宽比过大。验证结果的“标尺”是腔体中轴线(x0.5) 和 (y0.5)上的速度剖面。Ghia的基准数据表在网上很容易找到把数值解与基准解画在一起如果 (u) 和 (v) 曲线偏差不超过5%说明程序主逻辑没有大问题如果偏差集中在角点附近多半是边界条件处理问题而不是SIMPLE算法的锅。5. 从残差曲线到流场后处理收敛判据与常见坑5.1 监控哪些量才能判断收敛实际调试中我建议每50步输出三个量连续性残差的最大值、动量残差的L2范数、以及腔内点如 ((0.5,0.25))的速度值。只盯最大残差的坏处是它会受个别网格点影响比如顶盖转角处的残差可能一直偏大导致总达不到设定容限。更可靠的做法是同时画出残差曲线和速度监测点曲线后者在残差还在下降但已经平缓时基本稳定说明流场已经进入准稳态。5.2 压力参考点与迭代发散的处理压力修正方程的解是差一个常数仍满足方程的必须指定某点的压力为基准值。常见做法是设置左下角压力为零p_prime(1,1) 0; % 固定压力参考点若不固定残差会正常下降但压力场整体漂移每轮迭代的压力值会一起升降。发散的第一征兆是残差NaN此时优先检查两点一是动量方程系数中负数项过多说明网格 (Re_\Delta \rho U \Delta x / \mu) 大于2需要加密网格或减小时间步长二是速度松弛因子大于1导致相邻迭代的更新量互相叠加放大。还有一种隐蔽的坑边界上的速度在交错网格中可能多更新一次导致顶盖附近出现非物理振荡解决方法是把边界速度在每轮迭代前重新赋值。5.3 与基准解对比的快速验证技巧拿到收敛流场后导出沿腔体中心线的速度剖面数据与Ghia表的对比不必逐点求相对误差而是关注极值位置和零速度穿越点。Re1000时 (y0) 方向的 (u) 速度剖面主负峰值在 (y\approx0.18) 附近Re5000时主涡中心更靠近几何中心这些特征与基准解偏差超过一个网格间距时基本可以断定网格分辨率不足。最后调整输出图像的配色用等值线图展示流函数时注意流函数需要从速度场积分得到不能直接用速度画否则无法呈现“涡”的闭合结构。一个简单的流函数计算方法是用数值积分在网格上累加速度分量得到的结果能清晰看到主涡和角涡的分界线这也是你写报告和答辩时最有力的展示素材。本文还有配套的精品资源点击获取