-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathlbmFlowAroundCylinder.py
99 lines (81 loc) · 3.31 KB
/
lbmFlowAroundCylinder.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#!/usr/bin/python3
# Copyright (C) 2015 Universite de Geneve, Switzerland
# E-mail contact: jonas.latt@unige.ch
#
# 2D flow around a cylinder
#
from numpy import *
import matplotlib.pyplot as plt
from matplotlib import cm
###### Flow definition #########################################################
maxIter = 200000 # Total number of time iterations.
Re = 150.0 # Reynolds number.
nx, ny = 420, 180 # Numer of lattice nodes.
ly = ny-1 # Height of the domain in lattice units.
cx, cy, r = nx//4, ny//2, ny//9 # Coordinates of the cylinder.
uLB = 0.04 # Velocity in lattice units.
nulb = uLB*r/Re; # Viscoscity in lattice units.
omega = 1 / (3*nulb+0.5); # Relaxation parameter.
###### Lattice Constants #######################################################
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])
###### Function Definitions ####################################################
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
def equilibrium(rho, u): # Equilibrium distribution function.
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
###### Setup: cylindrical obstacle and velocity inlet with perturbation ########
# Creation of a mask with 1/0 values, defining the shape of the obstacle.
def obstacle_fun(x, y):
return (x-cx)**2+(y-cy)**2<r**2
obstacle = fromfunction(obstacle_fun, (nx,ny))
# Initial velocity profile: almost zero, with a slight perturbation to trigger
# the instability.
def inivel(d, x, y):
return (1-d) * uLB * (1 + 1e-4*sin(y/ly*2*pi))
vel = fromfunction(inivel, (2,nx,ny))
# Initialization of the populations at equilibrium with the given velocity.
fin = equilibrium(1, vel)
###### Main time loop ##########################################################
for time in range(maxIter):
# Right wall: outflow condition.
fin[col3,-1,:] = fin[col3,-2,:]
# Compute macroscopic variables, density and velocity.
rho, u = macroscopic(fin)
# Left wall: inflow condition.
u[:,0,:] = vel[:,0,:]
rho[0,:] = 1/(1-u[0,0,:]) * ( sum(fin[col2,0,:], axis=0) +
2*sum(fin[col3,0,:], axis=0) )
# Compute equilibrium.
feq = equilibrium(rho, u)
fin[[0,1,2],0,:] = feq[[0,1,2],0,:] + fin[[8,7,6],0,:] - feq[[8,7,6],0,:]
# Collision step.
fout = fin - omega * (fin - feq)
# Bounce-back condition for obstacle.
for i in range(9):
fout[i, obstacle] = fin[8-i, obstacle]
# Streaming step.
for i in range(9):
fin[i,:,:] = roll(
roll(fout[i,:,:], v[i,0], axis=0),
v[i,1], axis=1 )
# Visualization of the velocity.
if (time%100==0):
plt.clf()
plt.imshow(sqrt(u[0]**2+u[1]**2).transpose(), cmap=cm.Reds)
plt.savefig("vel.{0:04d}.png".format(time//100))