尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

D2Q9与D3Q19模型的LBM MATLAB仿真实现与调试

D2Q9与D3Q19模型的LBM MATLAB仿真实现与调试 简介面向流体模拟与格子玻尔兹曼方法LBM入门及进阶学习者这份资源提供了D2Q9与D3Q19两种经典模型的MATLAB完整实现适用于高校计算机、电子信息工程、数学等专业的课程设计、期末大作业与毕业设计。包内共10个文件以5个M脚本为核心代码配合3张PNG示意图展示模拟结果另含1个RAR案例数据包和1个ASV备份文件整体仅78KB轻量易用。目前已有151人学习参考。代码采用参数化编程参数修改方便注释详细清晰并附带可直接运行的数据便于读者快速复现多孔介质流动等场景理解LBM在二维与三维网格上的迭代更新与后处理思路。作者系资深算法工程师十年Matlab仿真经验代码结构规范兼具教学与实用价值。1. 先跑通这份 D2Q9 代码再谈 LBM 的理论修正解压「国外经典LBM D2Q9 D3Q19模型的matlab代码.zip」后多数人的操作路径是打开 main.m、按 F5、盯着云图看有没有漩涡。如果只追求“能出图”这确实够用但 LBM格子玻尔兹曼方法这类代码最需要搞明白的不是循环怎么写而是离散速度模型里的方向表、权重、松弛时间 tau 三样东西要保持内部一致。D2Q9 是二维九速模型D3Q19 是三维十九速模型切换两者不只是把数组从三维变四维连平衡态分布函数、反弹边界映射、声速与粘度的换算都得同步调整。这篇博文按“理论—实现—扩展—排错”的顺序把两套模型的 MATLAB 代码拆开讲先说明为什么 D2Q9 和 D3Q19 选这两组速度方向再给一段能直接运行的 D2Q9 核心循环然后扩展到 D3Q19 的三维数据布局与边界处理最后把参数约束和调试技巧收在一起。适合第一次写 LBM、想弄清代码每一步在做什么的科研新手也适合把已有 C 语言 LBM 移植到 MATLAB 快速验证的从业者。2. 离散速度模型的结构D2Q9 与 D3Q19 的方向表、权重和声速2.1 速度模型从哪里来矩条件决定方向集合LBM 在每个格点上存若干个离散速度方向的分布函数值宏观密度和动量只是分布函数的零阶和一阶矩rho Σ f_irho·u Σ f_i·c_i要让这两个矩方程在宏观尺度还原出不可压 N-S 方程速度集合的二阶矩张量 Σ w_i·c_iα·c_iβ 必须与单位张量成正比三阶矩 Σ w_i·c_iα·c_iβ·c_iγ 要保持对称。D2Q9 的 9 个方向中心、四个轴方向、四个对角方向恰好能满足到四阶各向同性所以成为二维最常用的基架。提示方向表不是随便列的。D2Q9 的权重 4/9、1/9、1/36 由各向同性条件解出改任何一个值恢复出的方程都会多出不想要的各向异性误差。网上能搜到的 D2Q9 示例代码里方向表顺序经常不一致。常见做法是把 9 个方向写成两个向量cx [0 1 0 -1 0 1 -1 -1 1]cy [0 0 1 0 -1 1 1 -1 -1]。索引 2 到 5 对应四个轴方向6 到 9 对应四个对角方向。这个顺序直接决定后面反弹边界的映射改代码前先确认它否则边界条件会张冠李戴。2.2 D3Q19 为什么是 19 而不是 27三维的完整邻域有 27 个方向包含体对角线 (±1, ±1, ±1)。但从矩条件看重建 N-S 方程只需要速度矩到三阶体对角线对四阶各向同性的贡献在低速等温流动中可以用其他方向组合替代。D3Q19 保留了中心 1 个、轴向 6 个和面内对角 12 个每个格点存的分布从 27 降到 19迁移循环少处理 8 个方向内存少约 30%在 Re 低于 2000 的等温算例里精度损失通常在 1% 以内。这也解释了为什么不少代码包把 D2Q9 与 D3Q19 放在一起两者的平衡态公式形式完全一致差别只在方向表、权重和数组维度。D3Q19 的权重为静止 1/3、轴向 1/18、面内对角 1/36声速 cs² 仍然是 1/3松弛时间与粘度的关系 nu cs²·(tau − 0.5) 在两个模型里也通用。2.3 平衡态分布与宏观量MATLAB 最小实现BGK 碰撞需要平衡态分布 f_eq。在格子单位dx1, dt1下D2Q9 和 D3Q19 的平衡态公式统一写成f_eq_i w_i · rho · (1 3·(c_i·u) 4.5·(c_i·u)² − 1.5·(u·u))对应的 MATLAB 函数可以先按二维写function f feq_2d(rho, ux, uy, cx, cy, w) % rho, ux, uy 与网格同尺寸cx, cy, w 为 9 元素方向表 f zeros([size(rho), 9]); for i 1:9 cu cx(i)*ux cy(i)*uy; % 离散速度与宏观速度的点积 usq ux.^2 uy.^2; % 宏观速度模平方 f(:,:,i) w(i) .* rho .* (1 3*cu 4.5*cu.^2 - 1.5*usq); end end这段代码里 cu 和 usq 是标量权重乘在整场矩阵上MATLAB 的广播机制会把 cx(i)*ux 展开成与 ux 同尺寸的矩阵。usq 在 9 次循环里重复计算性能损失可以忽略换来的是公式和教材完全对应调试时不容易看花眼。三维版本只需把数组扩成四维cu 里加一项 cz(i)*uz权重换成 D3Q19 的函数体不需要改结构。模型方向数静止权重轴方向权重对角方向权重cs²D2Q994/91/94 个1/364 个1/3D3Q19191/31/186 个1/3612 个1/3宏观量恢复不需要额外公式直接对分布函数求和rho sum(f, 3); % 密度零阶矩 ux sum(f .* reshape(cx,1,1,9), 3) ./ rho; % x 方向速度一阶矩 uy sum(f .* reshape(cy,1,1,9), 3) ./ rho; % y 方向速度一阶矩reshape(cx,1,1,9) 把 9 元素方向表变成 1×1×9让 f 的每个方向切片乘上对应的速度分量。这种写法比 squeeze 和 permute 组合更直白也避免把 cx 广播到错误维度。3. 用 MATLAB 重写 D2Q9 核心数据布局、碰撞迁移与反弹边界3.1 为什么把方向放最后一维D2Q9 的分布函数在 MATLAB 里最常见的数据布局是 f(ny, nx, 9)网格尺寸放前两维方向放第三维。这带来两个直接好处第一碰撞时 sum(f,3) 一次调用就得到密度场第二计算宏观速度时用 reshape 的方向向量做广播避免写 9 行逐方向加和。需要提醒的是MATLAB 数组第一维是行y 方向第二维是列x 方向这和图像的 (row, col) 习惯一致。C 语言代码里常见的布局是 f[nx][ny][9] 或 f[9][nx][ny]x 和 y 的先后与这里相反。移植时最容易出的错是 x、y 互换后 circshift 的移位方向反了导致流场整体转 90 度还不容易发现。解决办法是先把 cx、cy 两个方向表写清楚迁移部分严格按 [cy cx] 的顺序传给 circshift并加注释说明。3.2 顶盖驱动流的最小主循环下面这段代码是可复现的 D2Q9 顶盖驱动流结构左右用周期边界底部反弹顶部是移动壁面。它把碰撞放在迁移前f 在每个时间步开始时存的是“已经到达当前格点的分布”碰撞后得到出射分布再由迁移送到相邻格点。% 网格与参数 nx 100; ny 100; % 流场宽度与高度格子单位 uLid 0.05; % 顶盖速度建议小于 0.1 tau 0.6; % 松弛时间 maxIter 4000; % 迭代步数 % D2Q9 方向表与权重 cx [0 1 0 -1 0 1 -1 -1 1]; cy [0 0 1 0 -1 1 1 -1 -1]; w [4/9 1/9 1/9 1/9 1/9 1/36 1/36 1/36 1/36]; % 初始化为静止平衡态rho1, u0 rho ones(ny, nx); ux zeros(ny, nx); uy zeros(ny, nx); f zeros(ny, nx, 9); for i 1:9 f(:,:,i) w(i); % rho1 代入平衡态后的值 end for it 1:maxIter % 宏观量 rho sum(f, 3); ux sum(f .* reshape(cx,1,1,9), 3) ./ rho; uy sum(f .* reshape(cy,1,1,9), 3) ./ rho; ux(end,:) uLid; % 顶盖行强制速度 uy(end,:) 0; % BGK 碰撞 for i 1:9 cu cx(i)*ux cy(i)*uy; usq ux.^2 uy.^2; feq w(i) .* rho .* (1 3*cu 4.5*cu.^2 - 1.5*usq); f(:,:,i) f(:,:,i) - (f(:,:,i) - feq) / tau; end % 迁移左右周期边界由 circshift 自动闭合 for i 1:9 f(:,:,i) circshift(f(:,:,i), [cy(i) cx(i)]); end % 底部反弹边界方向 5、8、9 反弹为 3、6、7 f(1,:,5) f(1,:,3); f(1,:,8) f(1,:,6); f(1,:,9) f(1,:,7); % 顶部重新填充平衡态分布 for i 1:9 cu cx(i)*uLid; f(end,:,i) w(i) .* rho(end,:) .* (1 3*cu 4.5*cu.^2 - 1.5*uLid.^2); end % 每 500 步输出一次最大密度偏差 if mod(it, 500) 0 fprintf(step %d, max|rho-1| %.3e\n, it, max(abs(rho(:)-1))); end end迁移部分 circshift 的第一个参数是行偏移对应 cy第二个是列偏移对应 cx。cy1 表示分布沿 y 正方向送出一个格子在 MATLAB 里正好是行号加一所以这里方向表不需要为数组坐标做特殊翻转。这正是先定义好方向表的好处写代码时能直接从物理方向推导偏移。反弹边界的映射关系要重点核对壁面出射方向反弹方向底部 y15, 8, 93, 6, 7右壁 xnx2, 6, 94, 8, 7左壁 x14, 7, 82, 9, 6顶部 yny3, 6, 75, 8, 9以底部为例方向 5 是 (0,-1)指向壁内反弹后变成方向 3 的 (0,1)。方向 8 是 (-1,-1)反弹后应变成方向 6 的 (1,1)写成 f(1,:,8) f(1,:,6)方向 9 是 (1,-1)对应方向 7 的 (-1,1)。把这个映射表保存为注释之后加回流边界或入口边界时不容易改乱。3.3 参数怎么由物理量反推这段代码里 U、L、tau 全是格子单位。真实物理量要通过无量纲数换算反过来给定 Re 和物理粘度 nu_phys也能反推网格数。经验做法是uLid 0.05; % 格子速度通常取 0.01~0.1 tau 0.6; % 松弛时间 nu (tau - 0.5) / 3; % 格子运动粘度 Re 100; % 目标雷诺数 L_phys 0.1; % 特征长度单位米 nu_phys uLid * L_phys / Re; % 物理粘度 nx ceil(Re * nu / uLid); % 由格子雷诺数相等反推格数这里 nu (tau − 0.5)/3 是从 nu cs²·(tau − 0.5) 在格子单位下推出来的。如果 tau 取 0.6nu 就是 0.0333要保持 Re 不变uLid 和网格数必须同时调整不能只改一个。初学者最常见的错误是把顶盖速度直接设成物理速度比如 1 m/s导致 Ma 数爆掉结果在二维算例里看起来还能跑但压力场已经完全失真。4. 从二维到三维D3Q19 的索引生成、内存布局与边界处理4.1 用函数生成 D3Q19 方向表避免手写 19 行手写 19 个方向的 cx、cy、cz 容易漏写或多写而且权重和方向必须严格对齐。更稳妥的方式是用代码生成先放静止方向再放 6 个轴向最后放 12 个面内对角。生成顺序不是唯一的但后面的反弹映射依赖这个顺序所以生成器和主循环要打包在一起。function [cx, cy, cz, w] d3q19() % 返回 D3Q19 方向表与权重顺序静止、轴向、面内对角 list [0 0 0]; % 静止方向 for d 1:3 for s [-1 1] v zeros(1,3); v(d) s; % 沿第 d 个坐标轴的 ± 方向 list [list; v]; end end for d 1:2 for d2 (d1):3 for s1 [-1 1] for s2 [-1 1] v zeros(1,3); v(d) s1; v(d2) s2; % 两个非零分量的四种符号组合 list [list; v]; end end end end cx list(:,1); cy list(:,2); cz list(:,3); w [1/3; repmat(1/18, 6, 1); repmat(1/36, 12, 1)]; end执行后 length 应为 19sum(w) 应为 1。函数式生成的好处是反弹映射也能用同样的 cx、cy、cz 自动推导不用去死记方向编号。比如算壁面反弹时可以循环找反向方向% 生成反弹映射表jmap(i) 是与方向 i 相反的方向编号 for i 1:19 for j 1:19 if cx(j) -cx(i) cy(j) -cy(i) cz(j) -cz(i) jmap(i) j; break; end end end这段代码在任何壁面上都适用只要知道壁面所在的位置和方向就能批量做反弹替换比手写一堆 f(…, i) f(…, j) 更不容易漏。4.2 三维数据布局与迁移D3Q19 的分布函数存成 f(ny, nx, nz, 19)方向放第四维。第二维是 x第一维是 y第三维是 z这与 circshift 的移位向量 [y, x, z] 对应。宏量计算与 D2Q9 几乎一样只是把 reshape 的目标维度从 3 改成 4rho sum(f, 4); ux sum(f .* reshape(cx,1,1,1,19), 4) ./ rho; uy sum(f .* reshape(cy,1,1,1,19), 4) ./ rho; uz sum(f .* reshape(cz,1,1,1,19), 4) ./ rho;迁移循环改成for i 1:19 f(:,:,:,i) circshift(f(:,:,:,i), [cy(i) cx(i) cz(i)]); end注意 [cy(i) cx(i) cz(i)] 的顺序MATLAB circshift 的每个移位值对应数组对应维度的平移量cy 对应第一维cx 对应第二维cz 对应第三维。这个顺序在三维里尤其容易被写成 [cx cy cz]一旦写反流场会在 x-y 平面内转置后处理云图看起来还是挺光滑的只有对拍数据时才会发现问题。内存方面double 类型下 D3Q19 每格要 19×8152 字节128³ 网格约 319 MB这还只是分布函数本身不算辅助数组。网格规模D2Q9 占用D3Q19 占用100²720 KB不适用64³不适用约 40 MB128³不适用约 319 MB4.3 三维算例怎么验证先跑 2.5D 再跑真三维三维顶盖驱动流最直接的验证方式是做“2.5D”测试z 方向用周期边界x 方向也走周期边界只保留 y 方向上下壁面。这样流场沿 z 和 x 方向均匀退化成一个“柱状顶盖流”稳定后的中心线速度剖面和二维顶盖驱动流的结果应当一致。用这个方法先验证 D3Q19 的碰撞、迁移和 y 方向反弹是否写对再放开 z 方向条件去做真三维算例排错范围会小很多。验证代码的数据流可以这样组织跑完把中心线上的 ux 用 save 存成 .mat 文件再与二维 D2Q9 的结果画在同一条坐标轴里% 提取三维算例中心线速度 midZ ceil(nz/2); centerLine squeeze(ux(:, ceil(nx/2), midZ)); save(d3q19_centerline.mat, centerLine); % 与 D2Q9 结果叠加对比 load(d2q9_centerline.mat); plot(centerLine_2d, b-, centerLine, r--); legend(D2Q9, D3Q19);如果两条曲线明显错位优先检查方向表生成是否正确再检查 circshift 的移位顺序。这个“先 2.5D、后真 3D”的验证顺序是处理 D3Q19 代码最有效率的做法。5. 参数约束与排错速查把“跑通”变成“跑对”5.1 三个必须同时满足的约束LBM 的三组参数不是独立选的。tau 决定数值粘度uLid 决定马赫数两者共同决定能达到的雷诺数。三维 D3Q19 与二维 D2Q9 在这套约束上完全一致差别只在可用的网格规模。约束表达式典型范围超限后果松弛时间nu (tau − 0.5)/30.5001 ~ 1.5tau ≤ 0.5 直接 NaN格子速度Ma uLid / cs0.01 ~ 0.1超过 0.15 出现可压缩误差分辨率Re uLid·L / nu按物理算例反推 L分辨率不足时回流捕捉不到tau 越接近 0.5数值粘度越小理论上能算更高 Re但数值稳定性直线下降。tau 超过 1.0 之后耗散偏大稳态流场会被抹得过于平滑。常见的折中是 0.5~0.8 之间用顶盖速度 0.05~0.1 去配目标 Re。5.2 三类典型症状的排查路径最常碰到的三个现象按频率排序跑几步就 NaN、云图对称但数值错、压力场出现棋盘状振荡。NaN 的先查 tau 是否小于等于 0.5再查初始化时是否把分布函数设成了全零全零分布计算 u 时会除零最后查反弹边界是否在迁移后执行顺序反了会把边界格点污染掉。云图看起来“差不多对”但中心速度偏小通常是 nu 公式里漏了除以 3或 circshift 移位顺序导致有效速度减半。棋盘振荡则几乎总是反弹方向映射写反比如 f(1,:,5) f(1,:,3) 误写成 f(1,:,3) f(1,:,5)静压出现逐格交替的斑点。提示第一次调试时把 tau 设成 0.7uLid 设成 0.05在 50×50 网格上跑 500 步。如果这个组合能稳定得到对称涡旋再逐步调大 Re 和网格能更快定位是哪一步引入的问题。5.3 用探针点与残差曲线替代云图检查把云图颜色调成“好看”很容易真正能暴露问题的指标是最大密度偏差 max|rho − 1| 和固定探针点的速度曲线。在代码里加两个探针一个取几何中心的速度分量另一个取距顶盖 1/4 处的位置每个时间步记录值1000 步后画成折线。健康的收敛过程是残差单调下降后进入平台期曲线不出现振荡台阶。把这套探针逻辑写成一个独立的体积力函数或边界修饰函数D2Q9 和 D3Q19 共用同一份验证脚本只替换方向表和网格尺寸。之后每次修改边界条件或碰撞算子跑一次探针脚本就能判断改动是否破坏了宏观行为不必每次盯着云图猜问题。流过场对拍 Ghia 数据时直接 importdata 加载参考表用误差超过 2% 的节点数作为回归断言LBM 代码的改造效率会明显提升。本文还有配套的精品资源点击获取
返回列表