最近感觉CSDN有点大病,用各种浏览器都不显示最上面那一栏(就是点赞、数据、发布啥啥的那一栏),今天用ubuntu偶然发现又显示了, 赶紧把之前写的东西发出来记录一下,不知道问题出在哪:(
后面四步,每一步都是一个不同的方程,分别是:二维拉普拉斯方程、二维泊松方程、二维空腔流动、二维管渠流动
二阶中心差分
进行离散:稳态
),那么可以通过迭代的方法求解 p i , j n p_{i,j}^n pi,jn ,即将离散方程转化为五点差分形式
:import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
def plot2D(x,y,p):
plt.ion() # 这个东西是方便close,不然close不鸟
fig=plt.figure(figsize=(11,7),dpi=100) # 在Matplotlib 3.4版本之后,将fig.gca弃用了
ax = fig.add_subplot(projection='3d')
X,Y=np.meshgrid(x,y)
surf=ax.plot_surface(X,Y,p[:],rstride=1,cstride=1,cmap=cm.viridis,
linewidth=0,antialiased=False)
ax.set_xlim(0,2)
ax.set_ylim(0, 1)
ax.view_init(30,225)
# create x and y coordinate
nx=100
ny=100
x=np.linspace(0,2,nx)
y=np.linspace(0,1,ny)
dx=2/(nx-1)
dy=1/(ny-1)
# initial p
p=np.zeros((nx,ny))
# boundary p
p[0,:]=0
p[-1,:]=y
p[:,0]=p[:,1] # dp/dy=0 at y=0
p[:,-1]=p[:,-2] # dp/dy=0 at y=1
# start iteration
error=1
pn=np.empty_like(p)
while error>=1e-6:
pn=p.copy()
p[1:-1,1:-1]=((dy**2*(p[2:,1:-1]+p[0:-2,1:-1]))+dx**2*(p[1:-1,2:]+p[1:-1,0:-2]))/(2*(dx**2+dy**2))
# boundary
p[0, :] = 0
p[-1, :] = y
p[:, 0] = p[:, 1] # dp/dy=0 at y=0
p[:, -1] = p[:, -2] # dp/dy=0 at y=1
# error= norm L2
error=np.linalg.norm(x=p-pn,ord=2)
# draw in every iteration
plt.close()
plot2D(x,y,p)
plt.show()
plt.pause(1)
package
的概念。SIMPLE算法
∂ v ∂ t + u ∂ v ∂ x + v ∂ v ∂ y = − 1 ρ ∂ p ∂ y + ν ( ∂ 2 v ∂ x 2 + ∂ 2 v ∂ y 2 ) \frac{\partial v}{\partial t}+u\frac{\partial v}{\partial x}+v\frac{\partial v}{\partial y} = -\frac{1}{\rho}\frac{\partial p}{\partial y}+\nu\left(\frac{\partial^2 v}{\partial x^2}+\frac{\partial^2 v}{\partial y^2}\right) ∂t∂v+u∂x∂v+v∂y∂v=−ρ1∂y∂p+ν(∂x2∂2v+∂y2∂2v)
∂ 2 p ∂ x 2 + ∂ 2 p ∂ y 2 = − ρ ( ∂ u ∂ x ∂ u ∂ x + 2 ∂ u ∂ y ∂ v ∂ x + ∂ v ∂ y ∂ v ∂ y ) \frac{\partial^2 p}{\partial x^2}+\frac{\partial^2 p}{\partial y^2} = -\rho\left(\frac{\partial u}{\partial x}\frac{\partial u}{\partial x}+2\frac{\partial u}{\partial y}\frac{\partial v}{\partial x}+\frac{\partial v}{\partial y}\frac{\partial v}{\partial y} \right) ∂x2∂2p+∂y2∂2p=−ρ(∂x∂u∂x∂u+2∂y∂u∂x∂v+∂y∂v∂y∂v)
u = 1 u=1 u=1 at y = 2 y=2 y=2 (the “lid”);
u , v = 0 u, v=0 u,v=0 on the other boundaries;
∂ p ∂ y = 0 \frac{\partial p}{\partial y}=0 ∂y∂p=0 at y = 0 y=0 y=0;
p = 0 p=0 p=0 at y = 2 y=2 y=2
∂ p ∂ x = 0 \frac{\partial p}{\partial x}=0 ∂x∂p=0 at x = 0 , 2 x=0,2 x=0,2
import numpy
from matplotlib import pyplot, cm
from mpl_toolkits.mplot3d import Axes3D
%matplotlib inline
nx = 41
ny = 41
nt = 500
nit = 50
c = 1
dx = 2 / (nx - 1)
dy = 2 / (ny - 1)
x = numpy.linspace(0, 2, nx)
y = numpy.linspace(0, 2, ny)
X, Y = numpy.meshgrid(x, y)
rho = 1
nu = .1
dt = .001
u = numpy.zeros((ny, nx))
v = numpy.zeros((ny, nx))
p = numpy.zeros((ny, nx))
b = numpy.zeros((ny, nx))
def build_up_b(b, rho, dt, u, v, dx, dy):
b[1:-1, 1:-1] = (rho * (1 / dt *
((u[1:-1, 2:] - u[1:-1, 0:-2]) /
(2 * dx) + (v[2:, 1:-1] - v[0:-2, 1:-1]) / (2 * dy)) -
((u[1:-1, 2:] - u[1:-1, 0:-2]) / (2 * dx))**2 -
2 * ((u[2:, 1:-1] - u[0:-2, 1:-1]) / (2 * dy) *
(v[1:-1, 2:] - v[1:-1, 0:-2]) / (2 * dx))-
((v[2:, 1:-1] - v[0:-2, 1:-1]) / (2 * dy))**2))
return b
def pressure_poisson(p, dx, dy, b):
pn = numpy.empty_like(p)
pn = p.copy()
for q in range(nit):
pn = p.copy()
p[1:-1, 1:-1] = (((pn[1:-1, 2:] + pn[1:-1, 0:-2]) * dy**2 +
(pn[2:, 1:-1] + pn[0:-2, 1:-1]) * dx**2) /
(2 * (dx**2 + dy**2)) -
dx**2 * dy**2 / (2 * (dx**2 + dy**2)) *
b[1:-1,1:-1])
p[:, -1] = p[:, -2] # dp/dx = 0 at x = 2
p[0, :] = p[1, :] # dp/dy = 0 at y = 0
p[:, 0] = p[:, 1] # dp/dx = 0 at x = 0
p[-1, :] = 0 # p = 0 at y = 2
return p
def cavity_flow(nt, u, v, dt, dx, dy, p, rho, nu):
un = numpy.empty_like(u)
vn = numpy.empty_like(v)
b = numpy.zeros((ny, nx))
for n in range(nt):
un = u.copy()
vn = v.copy()
b = build_up_b(b, rho, dt, u, v, dx, dy)
p = pressure_poisson(p, dx, dy, b)
u[1:-1, 1:-1] = (un[1:-1, 1:-1]-
un[1:-1, 1:-1] * dt / dx *
(un[1:-1, 1:-1] - un[1:-1, 0:-2]) -
vn[1:-1, 1:-1] * dt / dy *
(un[1:-1, 1:-1] - un[0:-2, 1:-1]) -
dt / (2 * rho * dx) * (p[1:-1, 2:] - p[1:-1, 0:-2]) +
nu * (dt / dx**2 *
(un[1:-1, 2:] - 2 * un[1:-1, 1:-1] + un[1:-1, 0:-2]) +
dt / dy**2 *
(un[2:, 1:-1] - 2 * un[1:-1, 1:-1] + un[0:-2, 1:-1])))
v[1:-1,1:-1] = (vn[1:-1, 1:-1] -
un[1:-1, 1:-1] * dt / dx *
(vn[1:-1, 1:-1] - vn[1:-1, 0:-2]) -
vn[1:-1, 1:-1] * dt / dy *
(vn[1:-1, 1:-1] - vn[0:-2, 1:-1]) -
dt / (2 * rho * dy) * (p[2:, 1:-1] - p[0:-2, 1:-1]) +
nu * (dt / dx**2 *
(vn[1:-1, 2:] - 2 * vn[1:-1, 1:-1] + vn[1:-1, 0:-2]) +
dt / dy**2 *
(vn[2:, 1:-1] - 2 * vn[1:-1, 1:-1] + vn[0:-2, 1:-1])))
u[0, :] = 0
u[:, 0] = 0
u[:, -1] = 0
u[-1, :] = 1 # set velocity on cavity lid equal to 1
v[0, :] = 0
v[-1, :] = 0
v[:, 0] = 0
v[:, -1] = 0
return u, v, p
u = numpy.zeros((ny, nx))
v = numpy.zeros((ny, nx))
p = numpy.zeros((ny, nx))
b = numpy.zeros((ny, nx))
nt = 100 # change to 700
u, v, p = cavity_flow(nt, u, v, dt, dx, dy, p, rho, nu)
fig = pyplot.figure(figsize=(11,7), dpi=100)
# plotting the pressure field as a contour
pyplot.contourf(X, Y, p, alpha=0.5, cmap=cm.viridis)
pyplot.colorbar()
# plotting the pressure field outlines
pyplot.contour(X, Y, p, cmap=cm.viridis)
# plotting velocity field
pyplot.quiver(X[::2, ::2], Y[::2, ::2], u[::2, ::2], v[::2, ::2])
pyplot.xlabel('X')
pyplot.ylabel('Y');
streamplot
画图,这样流线是连续的,用quiver
画图流线是间断的。fig = pyplot.figure(figsize=(11, 7), dpi=100)
pyplot.contourf(X, Y, p, alpha=0.5, cmap=cm.viridis)
pyplot.colorbar()
pyplot.contour(X, Y, p, cmap=cm.viridis)
pyplot.streamplot(X, Y, u, v)
pyplot.xlabel('X')
pyplot.ylabel('Y');