栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

LBM学习记录3 Python实现D2Q9圆柱绕流

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

LBM学习记录3 Python实现D2Q9圆柱绕流

在https://blog.csdn.net/weixin_58913471/article/details/117561995?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link 基础上进行理解,重写,补充。

from numpy import *
import matplotlib.pyplot as plt
from matplotlib import cm

雷诺数(Re)是反应粘性和惯性之间平衡的无量纲数。
R e = u L ν Re = ufrac{L}{nu} Re=uνL​
流体速度u,特征长度 L L L, ν nu ν流体粘度
低速、高粘度和封闭的流体条件导致低Re,粘性力占主导地位。如果Re<<1,这种流体被称为Stokes或者Creeping flow. 由于孔径小,这种流动在许多多孔介质中的液体中是很常见的。
omega 松弛频率
如果 ω omega ω很小,流体只能缓慢地收敛到其平衡状态:高粘性。
流体的粘性与松弛参数 ω omega ω成反比。
ν = δ t c s 2 ( 1 ω − 1 2 ) nu=delta t c_{s}^{2}left(frac{1}{omega}-frac{1}{2}right) ν=δtcs2​(ω1​−21​)
其中, c s 2 = 1 3 c_{s}^{2}=frac{1}{3} cs2​=31​

maxIter = 200000  # 迭代次数
Re = 220.0         # 雷诺数
uLB = 0.04        # 模型的入口速度
nx, ny = 420, 180 # x, y轴长度
ly = ny-1         # 用于计算入口,为模型增加扰动,当雷诺数较小时,计算缺少扰动
cx, cy, r = nx//4, ny//2, ny//9  # 圆柱坐标
nulb = uLB*r/Re   # 粘性系数
omega = 1/(3*nulb+0.5)  # 松弛频率

t i t_i ti​ 用于补偿不同长度的速度

流入条件

密度

2   5   8
 | /
1–>4<–7
/  | 
0   3   6

因为

ρ ( x , t ) = ∑ i = 0 8 f i i n ( x , t ) rho(boldsymbol{x}, t)=sum_{i=0}^{8} f_{i}^{mathrm{in}}(boldsymbol{x}, t) ρ(x,t)=i=0∑8​fiin​(x,t)

u ( x , t ) = 1 ρ ( x , t ) δ x δ t ∑ i = 0 8 v i f i i n ( x , t ) boldsymbol{u}(boldsymbol{x}, t)=frac{1}{rho(boldsymbol{x}, t)} frac{delta x}{delta t} sum_{i=0}^{8} boldsymbol{v}_{i} f_{i}^{mathrm{in}}(boldsymbol{x}, t) u(x,t)=ρ(x,t)1​δtδx​i=0∑8​vi​fiin​(x,t)

定义

ρ 1 = f 0 + f 1 + f 2 (  unknown  ) ρ 2 = f 3 + f 4 + f 5  (known)  ρ 3 = f 6 + f 7 + f 8 (  known  ) begin{aligned} &rho_{1}=f_{0}+f_{1}+f_{2}(text { unknown }) \ &rho_{2}=f_{3}+f_{4}+f_{5} text { (known) } \ &rho_{3}=f_{6}+f_{7}+f_{8}(text { known }) end{aligned} ​ρ1​=f0​+f1​+f2​( unknown )ρ2​=f3​+f4​+f5​ (known) ρ3​=f6​+f7​+f8​( known )​

同时

ρ = ρ 1 + ρ 2 + ρ 3 ρ u x = ρ 1 − ρ 3 begin{aligned} &rho=rho_{1}+rho_{2}+rho_{3} \ &rho u_{x}=rho_{1}-rho_{3} end{aligned} ​ρ=ρ1​+ρ2​+ρ3​ρux​=ρ1​−ρ3​​

u x u_x ux​速度 x x x方向的分量

因此

ρ = ρ 2 + 2 ρ 3 1 − u x rho=frac{rho_{2}+2 rho_{3}}{1-u_{x}} ρ=1−ux​ρ2​+2ρ3​​

rho[0,:] = 1/(1-u[0,0,:])*(sum(fin[col2,0,:],axis=0)+2*sum(fin[col3,0,:],axis=0))

流入侧f0 f1 f2的密度分布函数

E ( i , ρ , u ) = ρ t i ( 1 + v i ⋅ u c s 2 + 1 2 c s 4 ( v i ⋅ u ) 2 − 1 2 c s 2 ∣ u ∣ 2 ) E(i, rho, boldsymbol{u})=rho t_{i}left(1+frac{boldsymbol{v}_{boldsymbol{i}} cdot boldsymbol{u}}{c_{s}^{2}}+frac{1}{2 c_{s}^{4}}left(boldsymbol{v}_{boldsymbol{i}} cdot boldsymbol{u}right)^{2}-frac{1}{2 c_{s}^{2}}|boldsymbol{u}|^{2}right) E(i,ρ,u)=ρti​(1+cs2​vi​⋅u​+2cs4​1​(vi​⋅u)2−2cs2​1​∣u∣2)

密度总是接近于他们的平衡状态。
首先将未知密度分布函数初始化为其平衡值。
随后,检查相反分布函数偏离平衡的程度,再加上这个值作为修正。

f 0 i n = E ( 0 , ρ , u ) + ( f 8 i n − E ( 8 , ρ , u ) ) f 1 i n = E ( 1 , ρ , u ) + ( f 7 i n − E ( 7 , ρ , u ) ) f 2 i n = E ( 2 , ρ , u ) + ( f 6 i n − E ( 6 , ρ , u ) ) begin{aligned} f_{0}^{mathrm{in}} &=E(0, rho, boldsymbol{u})+left(f_{8}^{mathrm{in}}-E(8, rho, boldsymbol{u})right) \ f_{1}^{mathrm{in}} &=E(1, rho, boldsymbol{u})+left(f_{7}^{mathrm{in}}-E(7, rho, boldsymbol{u})right) \ f_{2}^{mathrm{in}} &=E(2, rho, boldsymbol{u})+left(f_{6}^{mathrm{in}}-E(6, rho, boldsymbol{u})right) end{aligned} f0in​f1in​f2in​​=E(0,ρ,u)+(f8in​−E(8,ρ,u))=E(1,ρ,u)+(f7in​−E(7,ρ,u))=E(2,ρ,u)+(f6in​−E(6,ρ,u))​

fin[[0,1,2],0,:] = feq[[0,1,2],0,:] + fin[[8,7,6],0,:] - feq[[8,7,6],0,:]
v = array([[1,1], [1,0], [1,-1],
           [0,1], [0,0], [0,-1],
           [-1,1], [-1,0], [-1,-1]])

t = array([1/36, 1/9, 1/36,
          1/9, 4/9, 1/9,
          1/36, 1/9, 1/36])

col1 = array([0, 1, 2])
col2 = array([3, 4, 5])
col3 = array([6, 7, 8])

密度

ρ ( x , t ) = ∑ i = 0 8 f i i n ( x , t ) rho(boldsymbol{x}, t)=sum_{i=0}^{8} f_{i}^{mathrm{in}}(boldsymbol{x}, t) ρ(x,t)=i=0∑8​fiin​(x,t)

rho = zeros((nx, ny))
for ix in range(nx):
    for iy in range(ny):
        rho[ix, iy] = 0
        for i in range(9):
            rho[ix, iy] += fin[i, ix, iy]

压力
压力正比于密度,根据理想气体状态方程,在等温气体中
p = c s 2 ρ p=c_{s}^{2} rho p=cs2​ρ
在D2Q9模型中
c s 2 = 1 3 δ x 2 δ t 2 c_{s}^{2}=frac{1}{3} frac{delta x^{2}}{delta t^{2}} cs2​=31​δt2δx2​

速度

6   3   0
 | /
7<–4–>1
/  | 
8   5   2

v 0 v_0 v0​(1,1), v 1 v_1 v1​(1,0), v 2 v_2 v2​(1,-1)
v 3 v_3 v3​(0,1), v 4 v_4 v4​(0,0), v 5 v_5 v5​(0,-1)
v 6 v_6 v6​(-1,1), v 7 v_7 v7​(-1,0), v 8 v_8 v8​(-1,-1)

u ( x , t ) = 1 ρ ( x , t ) δ x δ t ∑ i = 0 8 v i f i i n ( x , t ) boldsymbol{u}(boldsymbol{x}, t)=frac{1}{rho(boldsymbol{x}, t)} frac{delta x}{delta t} sum_{i=0}^{8} boldsymbol{v}_{i} f_{i}^{mathrm{in}}(boldsymbol{x}, t) u(x,t)=ρ(x,t)1​δtδx​i=0∑8​vi​fiin​(x,t)

v = np.array([[1,1], [1,0], [1,-1], [0,1], [0,0], [0,-1], [-1,1], [-1,0], [-1,-1]])
u = zeros((2, nx, ny))
for ix in range(nx):
    for iy in range(ny):
        u[0, ix, iy] = 0
        u[1, ix, iy] = 0
        for i in range(9):
            u[0,ix,iy] += v[i,0]*fin[i,ix,iy]
            u[1,ix,iy] += v[i,1]*fin[i,ix,iy]
def macroscopic(fin):
    rho = sum(fin, axis=0)
    u = zeros((2, nx, ny))
    for i in range(9):
        u[0,:,:] += v[i,0] * fin[i,:,:]
        u[1,:,:] += v[i,1] * fin[i,:,:]
    u /= rho
    return rho, u

平衡方程
E ( i , ρ , u ) = ρ t i ( 1 + v i ⋅ u c s 2 + 1 2 c s 4 ( v i ⋅ u ) 2 − 1 2 c s 2 ∣ u ∣ 2 ) E(i, rho, boldsymbol{u})=rho t_{i}left(1+frac{boldsymbol{v}_{boldsymbol{i}} cdot boldsymbol{u}}{c_{s}^{2}}+frac{1}{2 c_{s}^{4}}left(boldsymbol{v}_{boldsymbol{i}} cdot boldsymbol{u}right)^{2}-frac{1}{2 c_{s}^{2}}|boldsymbol{u}|^{2}right) E(i,ρ,u)=ρti​(1+cs2​vi​⋅u​+2cs4​1​(vi​⋅u)2−2cs2​1​∣u∣2)

# 平衡态计算
def equilibrium(rho, u):
    usqr = 3/2 * (u[0]**2 + u[1]**2)
    feq = zeros((9, nx, ny))
    for i in range(9):
        cu = 3 * (v[i,0]*u[0,:,:] + v[i,1]*u[1,:,:])
        feq[i,:,:] = rho*t[i] * (1 + cu + 0.5*cu**2 - usqr)
    return feq

碰撞

f i out  − f i in  = − ω ( f i in  − E ( i , ρ , u ⃗ ) ) f_{i}^{text {out }}-f_{i}^{text {in }}=-omegaleft(f_{i}^{text {in }}-E(i, rho, vec{u})right) fiout ​−fiin ​=−ω(fiin ​−E(i,ρ,u ))

fout = fin-omega*(fin-eq)

迁移

for ix in range(nx):
    for iy in range(ny):
        for i in range(9):
            next_x = ix + v[i,0]
            if next_x<0:
                next_x = nx-1
            if next_x>=nx:
                next_y = 0
            
            next_y = iy + v[i,1]
            if next_y<0:
                next_y = ny-1
            if next_y>=ny:
                next_y = 0    
            
            fin[i,next_x,next_y] = fout[i,ix,iy]

np.roll(a,shift,axis=None) 将数组a,沿着axis方向,滚动shift长度
可改写成

for i in range(9):
    fin[i, :, :] = roll(roll(fout[i,:,:],v[i,0], axis=0), v[i,1], axis=1)

边界条件
Bounce-back BCs
反弹边界条件是处理静止无滑移壁面的一类常用格式,是指当离散分布函数到达边界节点时,将沿着其进入的方向散射回流体,包括on-grid bounce-back(边界与晶格点对齐)和 mid-grid bounce-back(边界在界外节点和界内节点之间的中心)。

on-grid bounce-back

mid-grid bounce-back

f i in  ( x , t + 1 ) = f j out  ( x , t ) f_{i}^{text {in }}(x, t+1)=f_{j}^{text {out }}(x, t) fiin ​(x,t+1)=fjout ​(x,t)

v i = − v j v_{i}=-v_{j} vi​=−vj​

for i in range(9):
    fout[i,obstacle] = fin[8-i, obstacle]
def obstacle_fun(x, y):
    return (x-cx)**2 + (y-cy)**2 < r**2

fromfunction从函数中创建数组,返回数组,符合条件值为True,不符合为False。

obstacle = fromfunction(obstacle_fun, (nx, ny))
# 初始速度曲线:几乎为零,有一个轻微的扰动来触发不稳定。
def inivel(d, x, y):
    return (1-d) * uLB * (1+1e-4*sin(y/ly*2*pi))
vel = fromfunction(inivel, (2, nx, ny))
# 以给定的速度初始化处于平衡状态的种群
fin = equilibrium(1, vel)
for time in range(maxIter):
    # 右边界分布函数
    fin[col3, -1, :] = fin[col3, -2, :]
    
    #计算宏观密度和速度
    rho, u = macroscopic(fin)
    
    # 重新计算左边界的分布函数
    u[:, 0, :] = vel[:, 0, :]
    rho[0,:] = 1/(1-u[0,0,:]) * (sum(fin[col2,0,:], axis=0) + 2*sum(fin[col3,0,:], axis=0))
    
    # 计算平衡态
    feq = equilibrium(rho, u)
    fin[[0,1,2],0,:] = feq[[0,1,2],0,:]+fin[[8,7,6],0,:]-feq[[8,7,6],0,:]
    
    # 碰撞过程
    fout = fin - omega * (fin - feq)
    
    # 对圆柱内节点进行反弹
    for i in range(9):
        fout[i, obstacle] = fin[8-i, obstacle]
    
    # 扩散过程
    for i in range(9):
        fin[i, :, :] = roll(roll(fout[i,:,:],v[i,0], axis=0), v[i,1], axis=1)
        
    # 可视化
    if (time%100==0):
        plt.clf()
        plt.imshow(sqrt(u[0]**2+u[1]**2).transpose(), cmap=cm.Reds)
        plt.savefig("/share/home/yszhang/PBS/LBM/pic/"+str(time//100)+".jpg")
import cv2

file_dir = '/pic/'
video = cv2.VideoWriter('video.avi',cv2.VideoWriter_fourcc(*'MJPG'),5,(1280,720))

for i in range(2000):
    img = cv2.imread(file_dir+str(i)+'.jpg')     
    img = cv2.resize(img,(1280,720))
    video.write(img)

video.release()
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/844404.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号