Texto y código sujeto bajo Creative Commons Attribution license, CC-BY-SA. (c) Original por Lorena A. Barba y Gilbert Forsyth en 2013, traducido por F.J. Navarro-Brull para CAChemE.org %pylab inline from mpl_toolkits.mplot3d import Axes3D from matplotlib import cm import matplotlib.pyplot as plt import numpy as np def buildUpB(rho, dt, dx, dy, u, v): b = np.zeros_like(u) b[1:-1,1:-1]=rho*(1/dt*((u[2:,1:-1]-u[0:-2,1:-1])/(2*dx)+(v[1:-1,2:]-v[1:-1,0:-2])/(2*dy))-\ ((u[2:,1:-1]-u[0:-2,1:-1])/(2*dx))**2-\ 2*((u[1:-1,2:]-u[1:-1,0:-2])/(2*dy)*(v[2:,1:-1]-v[0:-2,1:-1])/(2*dx))-\ ((v[1:-1,2:]-v[1:-1,0:-2])/(2*dy))**2) #### Condición de contorno periódica de presión @ x = 2 b[-1,1:-1]=rho*(1/dt*((u[0,1:-1]-u[-2,1:-1])/(2*dx)+(v[-1,2:]-v[-1,0:-2])/(2*dy))-\ ((u[0,1:-1]-u[-2,1:-1])/(2*dx))**2-\ 2*((u[-1,2:]-u[-1,0:-2])/(2*dy)*(v[0,1:-1]-v[-2,1:-1])/(2*dx))-\ ((v[-1,2:]-v[-1,0:-2])/(2*dy))**2) #### Condición de contorno periódica de presión @ x = 0 b[0,1:-1]=rho*(1/dt*((u[1,1:-1]-u[-1,1:-1])/(2*dx)+(v[0,2:]-v[0,0:-2])/(2*dy))-\ ((u[1,1:-1]-u[-1,1:-1])/(2*dx))**2-\ 2*((u[0,2:]-u[0,0:-2])/(2*dy)*(v[1,1:-1]-v[-1,1:-1])/(2*dx))-\ ((v[0,2:]-v[0,0:-2])/(2*dy))**2) return b def presPoissPeriodic(p, dx, dy): pn = np.empty_like(p) for q in range(nit): pn[:]=p[:] p[1:-1,1:-1] = ((pn[2:,1:-1]+pn[0:-2,1:-1])*dy**2+(pn[1:-1,2:]+pn[1:-1,0:-2])*dx**2)/\ (2*(dx**2+dy**2)) - dx**2*dy**2/(2*(dx**2+dy**2))*b[1:-1,1:-1] #### Condición de contorno periódica de presión @ x = 2 p[-1,1:-1] = ((pn[0,1:-1]+pn[-2,1:-1])*dy**2+(pn[-1,2:]+pn[-1,0:-2])*dx**2)/\ (2*(dx**2+dy**2)) - dx**2*dy**2/(2*(dx**2+dy**2))*b[-1,1:-1] #### Condición de contorno periódica de presión @ x = 0 p[0,1:-1] = ((pn[1,1:-1]+pn[-1,1:-1])*dy**2+(pn[0,2:]+pn[0,0:-2])*dx**2)/\ (2*(dx**2+dy**2)) -\ dx**2*dy**2/(2*(dx**2+dy**2))*b[0,1:-1] #### Condicion de contorno en la pared, presión # dp/dy = 0 at y = 2 p[-1,:] = p[-2,:] # dp/dy = 0 at y = 0 p[0,:] = p[1,:] return p ## Creación de variables nx = 41 ny = 41 nt = 10 nit=50 c = 1 dx = 2.0/(nx-1) dy = 2.0/(ny-1) x = np.linspace(0,2,nx) y = np.linspace(0,2,ny) Y,X = np.meshgrid(y,x) ## Variables físicas rho = 1 nu = .1 F = 1 dt = .01 # Condiciones inciales u = np.zeros((ny,nx)) ## Crea un vecotr XxY de 0 un = np.zeros((ny,nx)) ## Crea un vecotr XxY de 0 v = np.zeros((ny,nx)) ## Crea un vecotr XxY de 0 vn = np.zeros((ny,nx)) ## Crea un vecotr XxY de 0 p = np.ones((ny,nx)) ## Crea un vecotr XxY de unos pn = np.ones((ny,nx)) ## Crea un vecotr XxY de unos b = np.zeros((ny,nx)) udiff = 1 stepcount = 0 while udiff > .001: un[:] = u[:] vn[:] = v[:] b = buildUpB(rho, dt, dx, dy, u, v) p = presPoissPeriodic(p, dx, dy) u[1:-1,1:-1] = un[1:-1,1:-1]-\ un[1:-1,1:-1]*dt/dx*(un[1:-1,1:-1]-un[0:-2,1:-1])-\ vn[1:-1,1:-1]*dt/dy*(un[1:-1,1:-1]-un[1:-1,0:-2])-\ dt/(2*rho*dx)*(p[2:,1:-1]-p[0:-2,1:-1])+\ nu*(dt/dx**2*(un[2:,1:-1]-2*un[1:-1,1:-1]+un[0:-2,1:-1])+\ dt/dy**2*(un[1:-1,2:]-2*un[1:-1,1:-1]+un[1:-1,0:-2]))+F*dt v[1:-1,1:-1] = vn[1:-1,1:-1]-\ un[1:-1,1:-1]*dt/dx*(vn[1:-1,1:-1]-vn[0:-2,1:-1])-\ vn[1:-1,1:-1]*dt/dy*(vn[1:-1,1:-1]-vn[1:-1,0:-2])-\ dt/(2*rho*dy)*(p[1:-1,2:]-p[1:-1,0:-2])+\ nu*(dt/dx**2*(vn[2:,1:-1]-2*vn[1:-1,1:-1]+vn[0:-2,1:-1])+\ (dt/dy**2*(vn[1:-1,2:]-2*vn[1:-1,1:-1]+vn[1:-1,0:-2]))) #### Condición periódica de contorno u @ x = 2 u[-1,1:-1] = un[-1,1:-1]-\ un[-1,1:-1]*dt/dx*(un[-1,1:-1]-un[-2,1:-1])-\ vn[-1,1:-1]*dt/dy*(un[-1,1:-1]-un[-1,0:-2])-\ dt/(2*rho*dx)*(p[0,1:-1]-p[-2,1:-1])+\ nu*(dt/dx**2*(un[0,1:-1]-2*un[-1,1:-1]+un[-2,1:-1])+\ dt/dy**2*(un[-1,2:]-2*un[-1,1:-1]+un[-1,0:-2]))+F*dt #### Condición periódica de contorno u @ x = 0 u[0,1:-1] = un[0,1:-1]-\ un[0,1:-1]*dt/dx*(un[0,1:-1]-un[-1,1:-1])-\ vn[0,1:-1]*dt/dy*(un[0,1:-1]-un[0,0:-2])-\ dt/(2*rho*dx)*(p[1,1:-1]-p[-1,1:-1])+\ nu*(dt/dx**2*(un[1,1:-1]-2*un[0,1:-1]+un[-1,1:-1])+\ dt/dy**2*(un[0,2:]-2*un[0,1:-1]+un[0,0:-2]))+F*dt #### Condición periódica de contorno v @ x = 2 v[-1,1:-1] = vn[-1,1:-1]-\ un[-1,1:-1]*dt/dx*(vn[-1,1:-1]-vn[-2,1:-1])-\ vn[-1,1:-1]*dt/dy*(vn[-1,1:-1]-vn[-1,0:-2])-\ dt/(2*rho*dy)*(p[-1,2:]-p[-1,0:-2])+\ nu*(dt/dx**2*(vn[0,1:-1]-2*vn[-1,1:-1]+vn[-2,1:-1])+\ (dt/dy**2*(vn[-1,2:]-2*vn[-1,1:-1]+vn[-1,0:-2]))) #### Condición periódica de contorno v @ x = 0 v[0,1:-1] = vn[0,1:-1]-\ un[0,1:-1]*dt/dx*(vn[0,1:-1]-vn[-1,1:-1])-\ vn[0,1:-1]*dt/dy*(vn[0,1:-1]-vn[0,0:-2])-\ dt/(2*rho*dy)*(p[0,2:]-p[0,0:-2])+\ nu*(dt/dx**2*(vn[1,1:-1]-2*vn[0,1:-1]+vn[-1,1:-1])+\ (dt/dy**2*(vn[0,2:]-2*vn[0,1:-1]+vn[0,0:-2]))) #### Pared C.C: u,v = 0 @ y = 0,2 u[:,0] = 0 u[:,-1] = 0 v[:,0] = 0 v[:,-1]=0 udiff = (np.sum(u)-np.sum(un))/np.sum(u) stepcount += 1 print stepcount fig = plt.figure(figsize = (11,7), dpi=100) plt.quiver(X[::3, ::3], Y[::3, ::3], u[::3, ::3], v[::3, ::3]) fig = plt.figure(figsize = (11,7), dpi=100) plt.quiver(X, Y, u, v) from IPython.core.display import HTML def css_styling(): styles = open("../styles/custom.css", "r").read() return HTML(styles) css_styling()