用Python复现经典流体力学实验:手把手教你跑通LBM圆柱绕流仿真(附完整源码)

张开发
2026/4/15 13:52:14 15 分钟阅读

分享文章

用Python复现经典流体力学实验:手把手教你跑通LBM圆柱绕流仿真(附完整源码)
用Python构建流体力学数字实验室LBM圆柱绕流仿真全流程解析当第一次在屏幕上看到卡门涡街的模拟结果时那种将物理现象数字化重现的震撼感至今难忘。作为计算流体力学领域的重要方法格子玻尔兹曼方法LBM以其天然的并行性和清晰的物理图像正在成为复杂流动模拟的有力工具。本文将带您从零开始用Python构建完整的LBM圆柱绕流仿真系统不仅呈现代码实现更着重解析每个参数背后的物理意义和工程考量。1. LBM基础与仿真环境搭建LBM的核心思想是将连续的流体运动离散化为大量虚拟粒子的碰撞和迁移过程。与传统的纳维-斯托克斯方程求解不同LBM直接在微观尺度建模通过统计平均得到宏观流动特性。这种自下而上的建模方式特别适合处理复杂边界和微观流动问题。环境准备# 基础环境配置 import numpy as np import matplotlib.pyplot as plt from matplotlib import cm表LBM仿真关键参数对照表参数物理意义代码变量典型取值Re雷诺数Re100-220uLB入口速度uLB0.04ω弛豫频率omega1/(3ν0.5)τ弛豫时间1/omega0.5-1.0cₛ格子声速-1/√3D2Q9模型配置# D2Q9模型参数 q 9 # 离散速度方向数 c np.array([(x,y) for x in [0,-1,1] for y in [0,-1,1]]) # 速度矢量 t np.array([4/9][1/9]*4[1/36]*4) # 权重系数 noslip [np.where((c -c[i]).all(axis1))[0][0] for i in range(q)] # 反弹边界索引2. 物理模型到数值实现的映射雷诺数是圆柱绕流问题的核心无量纲数决定了流动状态。在LBM中我们通过调整粘性系数ν和特征速度来实现特定雷诺数的模拟# 雷诺数相关参数计算 Re 100.0 # 目标雷诺数 uLB 0.04 # 格子单位下的入口速度 r ny/9 # 圆柱半径 nulb uLB*r/Re # 格子粘性系数 omega 1.0 / (3.*nulb0.5) # 弛豫频率关键公式解析雷诺数定义$Re \frac{UD}{ν}$LBM粘性关系$ν c_s^2(τ-\frac{1}{2})Δ_t$平衡态分布函数$f_i^{eq} w_iρ[1 3(\vec{e_i}·\vec{u}) \frac{9}{2}(\vec{e_i}·\vec{u})^2 - \frac{3}{2}u^2]$圆柱几何定义采用numpy的fromfunction高效生成# 圆柱障碍物定义 cx, cy nx//4, ny//2 # 圆心位置 obstacle np.fromfunction( lambda x,y: (x-cx)**2 (y-cy)**2 r**2, (nx,ny))3. 核心算法实现与边界处理LBM的每个时间步包含碰撞和迁移两个主要阶段边界条件的正确处理对结果准确性至关重要。主循环结构for time in range(maxIter): # 1. 出口边界处理充分发展流动 fin[i1, -1, :] fin[i1, -2, :] # 2. 宏观量计算 rho np.sum(fin, axis0) u np.dot(c.T, fin.transpose(1,0,2)) / rho # 3. 入口边界Zou-He速度边界 u[:,0,:] vel[:,0,:] rho[0,:] 1./(1.-u[0,0,:]) * (np.sum(fin[i2,0,:], axis0) 2*np.sum(fin[i1,0,:], axis0)) # 4. 平衡态计算与碰撞 feq equilibrium(rho, u) fin[i3,0,:] fin[i1,0,:] feq[i3,0,:] - fin[i1,0,:] fout fin - omega * (fin - feq) # 5. 圆柱表面反弹边界 for i in range(q): fout[i, obstacle] fin[noslip[i], obstacle] # 6. 迁移步骤 for i in range(q): fin[i] np.roll( np.roll(fout[i], c[i,0], axis0), c[i,1], axis1)边界条件处理要点周期性边界上下边界采用roll操作自然实现Zou-He速度边界精确保证入口速度分布反弹边界简单有效地处理圆柱表面无滑移条件出口边界充分发展假设减少计算域尺寸影响4. 结果可视化与验证仿真结果的正确性验证是数值实验的关键环节。我们通过流场可视化、涡街频率分析和受力计算等多角度验证结果。流场可视化# 速度场可视化 if time % 10000 0: plt.clf() plt.imshow(np.sqrt(u[0]**2 u[1]**2).T, cmapcm.Reds, originlower) plt.colorbar(labelVelocity Magnitude) plt.savefig(fvel_{time//10000:04d}.png)阻力系数计算# 圆柱受力分析 fx, fy 0, 0 for i in range(q): for x in range(cx-3*r, cx3*r): for y in range(cy-3*r, cy3*r): if obstacle[x,y]: x1, y1 x c[i,0], y c[i,1] if not obstacle[x1,y1]: fx c[i,0] * (fout[i,x,y] fout[noslip[i],x1,y1]) fy c[i,1] * (fout[i,x,y] fout[noslip[i],x1,y1]) Cd abs(2 * fx / (r * uLB**2)) # 阻力系数 Cl abs(2 * fy / (r * uLB**2)) # 升力系数表典型雷诺数下的涡街特性雷诺数斯特劳哈尔数阻力系数尾涡模式50-1000.12-0.15~1.5稳定对称100-2000.15-0.20~1.2周期性涡街2000.18-0.22~1.0复杂湍流5. 性能优化与工程实践大规模LBM仿真的计算效率至关重要。以下是几个经过验证的优化策略numpy向量化优化# 向量化平衡态计算 def equilibrium(rho, u): cu 3.0 * np.einsum(ij,jkl-ikl, c, u) usqr 1.5 * (u[0]**2 u[1]**2) feq np.zeros((q, nx, ny)) for i in range(q): feq[i] rho * t[i] * (1 cu[i] 0.5*cu[i]**2 - usqr) return feq实用技巧使用einsum替代dot处理高维张量运算适当减小计算域保持尾流区足够长度采用非均匀网格或局部加密提升圆柱附近分辨率实现多进程并行加速长时间模拟在Re100的测试案例中经过20万次迭代后阻力系数稳定在1.2左右升力系数呈现周期性振荡典型的卡门涡街结构清晰可见。整个仿真过程在普通笔记本电脑上约需2小时完成通过适当降低网格分辨率可显著缩短计算时间。

更多文章