def main(show_plot=True, time_steps=4800, plot_freq=480): # ============================================================================= # # Define problem # # ============================================================================= # Node coordinates xn = nodes(0, 1, 256) yn = nodes(0, 0.125, 32) zn = nodes(0, 0.125, 4) # Cell coordinates xc = avg(xn) yc = avg(yn) zc = avg(zn) # Cell dimensions nx, ny, nz, dx, dy, dz, rc, ru, rv, rw = cartesian_grid(xn, yn, zn) # Set physical properties rho, mu, cap, kappa = properties.air(rc) # Time-stepping parameters dt = 0.002 # time step ndt = time_steps # number of time steps # Create unknowns; names, positions and sizes uf = Unknown('face-u-vel', X, ru, DIRICHLET) vf = Unknown('face-v-vel', Y, rv, DIRICHLET) wf = Unknown('face-w-vel', Z, rw, DIRICHLET) p = Unknown('pressure', C, rc, NEUMANN) # Specify boundary conditions uf.bnd[W].typ[:1, :, :] = DIRICHLET for k in range(0, nz): uf.bnd[W].val[:1, :, k] = par(0.1, yn) uf.bnd[E].typ[:1, :, :] = OUTLET for j in (B, T): uf.bnd[j].typ[:] = NEUMANN vf.bnd[j].typ[:] = NEUMANN wf.bnd[j].typ[:] = NEUMANN obst = zeros(rc) for j in range(0, 24): for i in range(64 + j, 64 + 24): for k in range(0, nz): obst[i, j, k] = 1 # ============================================================================= # # Solution algorithm # # ============================================================================= # ---------- # # Time loop # # ---------- for ts in range(1, ndt + 1): write.time_step(ts) # ----------------- # Store old values # ----------------- uf.old[:] = uf.val[:] vf.old[:] = vf.val[:] wf.old[:] = wf.val[:] # ---------------------- # Momentum conservation # ---------------------- ef = zeros(ru), zeros(rv), zeros(rw) calc_uvw((uf,vf,wf), (uf,vf,wf), rho, mu, \ zeros(rc), ef, dt, (dx,dy,dz), obst) # --------- # Pressure # --------- calc_p(p, (uf, vf, wf), rho, dt, (dx, dy, dz), obst) # -------------------- # Velocity correction # -------------------- corr_uvw((uf, vf, wf), p, rho, dt, (dx, dy, dz), obst) # Compute volume balance for checking err = vol_balance((uf, vf, wf), (dx, dy, dz), obst) print('Maximum volume error after correction: %12.5e' % abs(err).max()) # Check the CFL number too cfl = cfl_max((uf, vf, wf), dt, (dx, dy, dz)) print('Maximum CFL number: %12.5e' % cfl) # ============================================================================= # # Visualisation # # ============================================================================= if show_plot: if ts % plot_freq == 0: plot.isolines(p.val, (uf, vf, wf), (xn, yn, zn), Z) plot.tecplot("obst-staggered-%6.6d.plt" % ts, (xn, yn, zn), (uf, vf, wf, p))
# --------- # Pressure # --------- calc_p(p, (uf, vf, wf), rho, dt, (dx, dy, dz), obst) p_tot = p_tot + p.val # -------------------- # Velocity correction # -------------------- corr_uvw((uf, vf, wf), p, rho, dt, (dx, dy, dz), obst) # Compute volume balance for checking err = vol_balance((uf, vf, wf), (dx, dy, dz), obst) print('Maximum volume error after correction: %12.5e' % abs(err).max()) # Check the CFL number too cfl = cfl_max((uf, vf, wf), dt, (dx, dy, dz)) print('Maximum CFL number: %12.5e' % cfl) # ============================================================================= # # Visualisation # # ============================================================================= if ts % 50 == 0: plot.isolines(p_tot, (uf, vf, wf), (xn, yn, zn), Z) plot.isolines(t.val, (uf, vf, wf), (xn, yn, zn), Z) plot.isolines(rho, (uf, vf, wf), (xn, yn, zn), Z)
def main(show_plot=True, time_steps=1800, plot_freq=180): # ============================================================================= # # Define problem # # ============================================================================= # Node coordinates xn = nodes(0, 10, 300) yn = nodes(0, 1, 40, 1 / 500, 1 / 500) zn = nodes(0, 3, 3) # Cell coordinates xc = avg(xn) yc = avg(yn) zc = avg(zn) # Cell dimensions nx, ny, nz, dx, dy, dz, rc, ru, rv, rw = cartesian_grid(xn, yn, zn) # Set physical properties rho = zeros(rc) mu = zeros(rc) kappa = zeros(rc) cap = zeros(rc) rho[:, :, :] = 1. mu[:, :, :] = 0.1 kappa[:, :, :] = 0.15 cap[:, :, :] = 1.0 # Time-stepping parameters dt = 0.003 # time step ndt = time_steps # number of time steps # Create unknowns; names, positions and sizes uc = Unknown("cell-u-vel", C, rc, DIRICHLET) vc = Unknown("cell-v-vel", C, rc, DIRICHLET) wc = Unknown("cell-w-vel", C, rc, DIRICHLET) uf = Unknown("face-u-vel", X, ru, DIRICHLET) vf = Unknown("face-v-vel", Y, rv, DIRICHLET) wf = Unknown("face-w-vel", Z, rw, DIRICHLET) t = Unknown("temperature", C, rc, NEUMANN) p = Unknown("pressure", C, rc, NEUMANN) # Specify boundary conditions uc.bnd[W].typ[:1, :, :] = DIRICHLET for k in range(0, nz): uc.bnd[W].val[:1, :, k] = par(1.0, yn) uc.bnd[E].typ[:1, :, :] = OUTLET uc.bnd[E].val[:1, :, :] = 1.0 for j in (B, T): uc.bnd[j].typ[:] = NEUMANN vc.bnd[j].typ[:] = NEUMANN wc.bnd[j].typ[:] = NEUMANN t.bnd[W].typ[:1, :, :] = DIRICHLET for k in range(0, nz): t.bnd[W].val[:1, :, k] = 1.0 - yc t.bnd[S].typ[:, :1, :] = DIRICHLET t.bnd[S].val[:, :1, :] = +1.0 t.bnd[N].typ[:, :1, :] = DIRICHLET t.bnd[N].val[:, :1, :] = 0.0 # Specify initial conditions uc.val[:, :, :] = 1.0 t.val[:, :, :] = 0 # Copy the values to face velocities uf.val[:] = avg(X, uc.val) vf.val[:] = avg(Y, vc.val) wf.val[:] = avg(Z, wc.val) for j in (W, E): uf.bnd[j].val[:] = uc.bnd[j].val[:] vf.bnd[j].val[:] = avg(Y, vc.bnd[j].val[:]) wf.bnd[j].val[:] = avg(Z, wc.bnd[j].val[:]) for j in (S, N): uf.bnd[j].val[:] = avg(X, uc.bnd[j].val[:]) vf.bnd[j].val[:] = vc.bnd[j].val[:] wf.bnd[j].val[:] = avg(Z, wc.bnd[j].val[:]) for j in (B, T): uf.bnd[j].val[:] = avg(X, uc.bnd[j].val[:]) vf.bnd[j].val[:] = avg(Y, vc.bnd[j].val[:]) wf.bnd[j].val[:] = wc.bnd[j].val[:] obstacle = None # ============================================================================= # # Solution algorithm # # ============================================================================= # ---------- # # Time loop # # ---------- for ts in range(1, ndt + 1): write.time_step(ts) # ----------------- # Store old values # ----------------- t.old[:] = t.val[:] uc.old[:] = uc.val[:] vc.old[:] = vc.val[:] wc.old[:] = wc.val[:] # ----------------------- # Temperature (enthalpy) # ----------------------- calc_t(t, (uf, vf, wf), (rho * cap), kappa, dt, (dx, dy, dz), obstacle) # ---------------------- # Momentum conservation # ---------------------- ef = zeros(rc), 150.0 * t.val, zeros(rc) calc_uvw((uc, vc, wc), (uf, vf, wf), rho, mu, dt, (dx, dy, dz), obstacle, force=ef) # --------- # Pressure # --------- calc_p(p, (uf, vf, wf), rho, dt, (dx, dy, dz), obstacle) # -------------------- # Velocity correction # -------------------- corr_uvw((uc, vc, wc), p, rho, dt, (dx, dy, dz), obstacle) corr_uvw((uf, vf, wf), p, rho, dt, (dx, dy, dz), obstacle) # Check the CFL number too cfl = cfl_max((uc, vc, wc), dt, (dx, dy, dz)) # ============================================================================= # # Visualisation # # ============================================================================= if show_plot: if ts % plot_freq == 0: plot.isolines(t.val, (uc, vc, wc), (xn, yn, zn), Z) plot.isolines(p.val, (uc, vc, wc), (xn, yn, zn), Z) plot.tecplot("tp-collocated-%6.6d" % ts, (xn, yn, zn), (uc, vc, wc, t, p))
def main(show_plot=True, time_steps=1800, plot_freq=180): # ============================================================================= # # Define problem # # ============================================================================= # Node coordinates xn = nodes(0, 10, 300) yn = nodes(0, 1, 40, 1 / 500, 1 / 500) zn = nodes(0, 3, 3) # Cell coordinates xc = avg(xn) yc = avg(yn) zc = avg(zn) # Cell dimensions nx, ny, nz, dx, dy, dz, rc, ru, rv, rw = cartesian_grid(xn, yn, zn) # Set physical properties rho = zeros(rc) mu = zeros(rc) kappa = zeros(rc) cap = zeros(rc) rho[:, :, :] = 1. mu[:, :, :] = 0.1 kappa[:, :, :] = 0.15 cap[:, :, :] = 1.0 # Time-stepping parameters dt = 0.003 # time step ndt = time_steps # number of time steps # Create unknowns; names, positions and sizes uf = Unknown('face-u-vel', X, ru, DIRICHLET) vf = Unknown('face-v-vel', Y, rv, DIRICHLET) wf = Unknown('face-w-vel', Z, rw, DIRICHLET) t = Unknown('temperature', C, rc, NEUMANN) p = Unknown('pressure', C, rc, NEUMANN) # Specify boundary conditions uf.bnd[W].typ[:1, :, :] = DIRICHLET for k in range(0, nz): uf.bnd[W].val[:1, :, k] = par(1.0, yn) uf.bnd[E].typ[:1, :, :] = OUTLET uf.bnd[E].val[:1, :, :] = 1.0 for j in (B, T): uf.bnd[j].typ[:] = NEUMANN vf.bnd[j].typ[:] = NEUMANN wf.bnd[j].typ[:] = NEUMANN t.bnd[W].typ[:1, :, :] = DIRICHLET for k in range(0, nz): t.bnd[W].val[:1, :, k] = 1.0 - yc t.bnd[S].typ[:, :1, :] = DIRICHLET t.bnd[S].val[:, :1, :] = +1.0 t.bnd[N].typ[:, :1, :] = DIRICHLET t.bnd[N].val[:, :1, :] = 0.0 # Specify initial conditions uf.val[:, :, :] = 1.0 t.val[:, :, :] = 0 obst = zeros(rc) # ============================================================================= # # Solution algorithm # # ============================================================================= # ---------- # # Time loop # # ---------- for ts in range(1, ndt + 1): write.time_step(ts) # ----------------- # Store old values # ----------------- t.old[:] = t.val[:] uf.old[:] = uf.val[:] vf.old[:] = vf.val[:] wf.old[:] = wf.val[:] # ----------------------- # Temperature (enthalpy) # ----------------------- calc_t(t, (uf, vf, wf), (rho * cap), kappa, dt, (dx, dy, dz), obst) # ---------------------- # Momentum conservation # ---------------------- ef = zeros(ru), 150.0 * avg(Y, t.val), zeros(rw) calc_uvw((uf,vf,wf), (uf,vf,wf), rho, mu, \ zeros(rc), ef, dt, (dx,dy,dz), obst) # --------- # Pressure # --------- calc_p(p, (uf, vf, wf), rho, dt, (dx, dy, dz), obst) # -------------------- # Velocity correction # -------------------- corr_uvw((uf, vf, wf), p, rho, dt, (dx, dy, dz), obst) # Compute volume balance for checking err = vol_balance((uf, vf, wf), (dx, dy, dz), obst) print('Maximum volume error after correction: %12.5e' % abs(err).max()) # Check the CFL number too cfl = cfl_max((uf, vf, wf), dt, (dx, dy, dz)) print('Maximum CFL number: %12.5e' % cfl) # ============================================================================= # # Visualisation # # ============================================================================= if show_plot: if ts % plot_freq == 0: plot.isolines(t.val, (uf, vf, wf), (xn, yn, zn), Z) plot.isolines(p.val, (uf, vf, wf), (xn, yn, zn), Z) plot.tecplot("tp-staggered-%6.6d.plt" % ts, (xn, yn, zn), (uf, vf, wf, t, p))
def main(show_plot=True, time_steps=600, plot_freq=60): # ============================================================================= # # Define problem # # ============================================================================= planes = ('XY', 'XZ', 'YZ') tests = array([11,12,13,14, 21,22,23,24, 31,32,33,34, 41,42,43,44]) TEST = tests[int(floor(random() * 16))] PLANE = planes[int(floor(random() * 3))] TEST = 23 # Node coordinates xn = nodes(0, 1, 160) yn = nodes(0, 1, 160) zn = nodes(0, 0.025, 4) # Cell coordinates xc = avg(xn) yc = avg(yn) zc = avg(zn) # Cell dimensions nx,ny,nz, dx,dy,dz, rc,ru,rv,rw = cartesian_grid(xn,yn,zn) # Set physical properties rho, mu, cap, kappa = properties.air(rc) # Time-stepping parameters dt = 0.15 # time step ndt = time_steps # number of time steps # Create unknowns names, positions and sizes uf = create_unknown('face-u-vel', X, ru, DIRICHLET) vf = create_unknown('face-v-vel', Y, rv, DIRICHLET) wf = create_unknown('face-w-vel', Z, rw, DIRICHLET) p = create_unknown('pressure', C, rc, NEUMANN) print(TEST) # Specify boundary conditions if TEST == 11: for k in range(0,nz): uf.bnd[W].val[0,ny//4:3*ny//4,k] = +par(0.01, yn[ny//4:3*ny//4+1]) uf.bnd[E].typ[0,ny//4:3*ny//4,k] = OUTLET elif TEST == 12: # vertical mirror from 11 for k in range(0,nz): uf.bnd[E].val[0,ny//4:3*ny//4,k] = -par(0.01, yn[ny//4:3*ny//4+1]) uf.bnd[W].typ[0,ny//4:3*ny//4,k] = OUTLET elif TEST == 13: # rotate 11 for k in range(0,nz): vf.bnd[S].val[nx//4:3*nx//4,0,k] = +par(0.01, xn[nx//4:3*nx//4+1]) vf.bnd[N].typ[nx//4:3*nx//4,0,k] = OUTLET elif TEST == 14: # horizontal mirror 13 for k in range(0,nz): vf.bnd[N].val[nx//4:3*nx//4,0,k] = -par(0.01, xn[nx//4:3*nx//4+1]) vf.bnd[S].typ[nx//4:3*nx//4,0,k] = OUTLET elif TEST == 21: # 2 exits for k in range(0,nz): uf.bnd[W].val[0, ny//4:3*ny//4,k] = +par(0.01, yn[ny//4:3*ny//4+1]) uf.bnd[E].typ[0, 0:ny//4,k] = OUTLET uf.bnd[E].typ[0,3*ny//4:ny, k] = OUTLET elif TEST == 22: # vertical mirror 21 for k in range(0,nz): uf.bnd[E].val[0, ny//4:3*ny//4,k] = -par(0.01, yn[ny//4:3*ny//4+1]) uf.bnd[W].typ[0, 0:ny//4,k] = OUTLET uf.bnd[W].typ[0,3*ny//4:ny, k] = OUTLET elif TEST == 23: # rotated 21 for k in range(0,nz): vf.bnd[S].val[ nx//4:3*nx//4,0,k] = +par(0.01, xn[nx//4:3*nx//4+1]) vf.bnd[N].typ[ :nx//4,0,k] = OUTLET vf.bnd[N].typ[3*nx//4:nx, 0,k] = OUTLET elif TEST == 24: # horizontal mirror of 23 for k in range(0,nz): vf.bnd[N].val[ nx//4:3*nx//4,0,k] = -par(0.01, xn[nx//4:3*nx//4+1]) vf.bnd[S].typ[ :nx//4,0,k] = OUTLET vf.bnd[S].typ[3*nx//4:nx, 0,k] = OUTLET elif TEST == 31: # inlet and outlet at the same face for k in range(0,nz): uf.bnd[W].val[0,3*ny//4:ny, k] = +par(0.01, yn[3*ny//4:ny+1]) uf.bnd[W].typ[0, :ny//4,k] = OUTLET elif TEST == 32: # vertical mirror of 31 for k in range(0,nz): uf.bnd[E].val[0,3*ny//4:ny, k] = -par(0.01, yn[3*ny//4:ny+1]) uf.bnd[E].typ[0, 0:ny//4,k] = OUTLET elif TEST == 33: # rotated 31 for k in range(0,nz): vf.bnd[S].val[3*nx//4:nx, 0,k] = +par(0.01, xn[3*nx//4:nx+1]) vf.bnd[S].typ[ :nx//4,0,k] = OUTLET elif TEST == 34: # horizontal mirror of 33 for k in range(0,nz): vf.bnd[N].val[3*nx//4:nx, 0,k] = -par(0.01, xn[3*nx//4:nx+1]) vf.bnd[N].typ[ :nx//4,0,k] = OUTLET elif TEST == 41: # inlet and outlet at the same face, one more outlet for k in range(0,nz): uf.bnd[W].val[0,3*ny//4:ny, k] = +par(0.01, yn[3*ny//4:ny+1]) uf.bnd[W].typ[0, :ny//8,k] = OUTLET uf.bnd[E].typ[0, :ny//8,k] = OUTLET elif TEST == 42: # vertical mirror of 41 for k in range(0,nz): uf.bnd[E].val[0,3*ny//4:ny, k] = -par(0.01, yn[3*ny//4:ny+1]) uf.bnd[E].typ[0, :ny//8,k] = OUTLET uf.bnd[W].typ[0, :ny//8,k] = OUTLET elif TEST == 43: # rotated 41 for k in range(0,nz): vf.bnd[S].val[3*nx//4:nx, 0,k] = +par(0.01, xn[3*nx//4:nx+1]) vf.bnd[S].typ[ 0:nx//8,0,k] = OUTLET vf.bnd[N].typ[ 0:nx//8,0,k] = OUTLET elif TEST == 44: # horizontal mirror of 43 for k in range(0,nz): vf.bnd[N].val[3*ny//4:nx, 0,k] = -par(0.01, xn[3*nx//4:nx+1]) vf.bnd[N].typ[ :nx//8,0,k] = OUTLET vf.bnd[S].typ[ :nx//8,0,k] = OUTLET for j in (B,T): uf.bnd[j].typ[:] = NEUMANN vf.bnd[j].typ[:] = NEUMANN wf.bnd[j].typ[:] = NEUMANN # Create a cylindrical obstacle in the middle just for kicks obst = zeros(rc) for k in range(0,nz): for j in range(0,ny): for i in range(0,nx): dist = sqrt( (j-ny//2+1)**2 + (i-nx//2+1)**2 ) if dist < ny/4: obst[i,j,k] = 1 # ============================================================================= # # Solution algorithm # # ============================================================================= # ---------- # # Time loop # # ---------- for ts in range(1,ndt+1): write.time_step(ts) # ----------------- # Store old values # ----------------- uf.old[:] = uf.val[:] vf.old[:] = vf.val[:] wf.old[:] = wf.val[:] # ---------------------- # Momentum conservation # ---------------------- ef = zeros(ru), zeros(rv), zeros(rw) calc_uvw((uf,vf,wf), (uf,vf,wf), rho, mu, \ zeros(rc), ef, dt, (dx,dy,dz), obst) # --------- # Pressure # --------- calc_p(p, (uf,vf,wf), rho, dt, (dx,dy,dz), obst) # -------------------- # Velocity correction # -------------------- corr_uvw((uf,vf,wf), p, rho, dt, (dx,dy,dz), obst) # Compute volume balance for checking err = vol_balance((uf,vf,wf), (dx,dy,dz), obst) print('Maximum volume error after correction: %12.5e' % abs(err).max()) # Check the CFL number too cfl = cfl_max((uf,vf,wf), dt, (dx,dy,dz)) print('Maximum CFL number: %12.5e' % cfl) # ============================================================================= # # Visualisation # # ============================================================================= if show_plot: if ts % plot_freq == 0: plot.isolines(p.val, (uf,vf,wf), (xn,yn,zn), Z)
p_tot[c] = p_tot[c] + p[c].val # -------------------- # Velocity correction # -------------------- for c in (AIR,H2O): corr_uvw((uf[c],vf[c],wf[c]), p[c], rho[c], \ dt, (dx[c],dy[c],dz[c]), obst[c]) # Compute volume balance for checking for c in (AIR,H2O): err = vol_balance((uf[c],vf[c],wf[c]), \ (dx[c],dy[c],dz[c]), obst[c]) print('Maximum volume error after correction: %12.5e' % abs(err).max()) # Check the CFL number too for c in (AIR,H2O): cfl = cfl_max((uf[c],vf[c],wf[c]), dt, (dx[c],dy[c],dz[c])) print('Maximum CFL number: %12.5e' % cfl) # ============================================================================= # # Visualisation # # ============================================================================= if ts % 100 == 0: for c in (AIR,H2O): plot.isolines(t[c].val, (uf[c],vf[c],wf[c]), (xn[c],yn[c],zn[c]), Z) plot.isolines(p_tot[c], (uf[c],vf[c],wf[c]), (xn[c],yn[c],zn[c]), Z)
def main(show_plot=True, time_steps=12, plot_freq=1): # ============================================================================= # # Define problem # # ============================================================================= xn = nodes(0, 1, 64, 1.0 / 256, 1.0 / 256) yn = nodes(0, 1, 64, 1.0 / 256, 1.0 / 256) zn = nodes(0, 0.1, 5) # Cell dimensions nx, ny, nz, dx, dy, dz, rc, ru, rv, rw = cartesian_grid(xn, yn, zn) # Set physical properties grashof = 1.4105E+06 prandtl = 0.7058 rho = zeros(rc) mu = zeros(rc) kappa = zeros(rc) cap = zeros(rc) rho[:, :, :] = 1.0 mu[:, :, :] = 1.0 / sqrt(grashof) kappa[:, :, :] = 1.0 / (prandtl * sqrt(grashof)) cap[:, :, :] = 1.0 # Time-stepping parameters dt = 2 # time step ndt = time_steps # number of time steps # Create unknowns; names, positions and sizes uf = Unknown("face-u-vel", X, ru, DIRICHLET) vf = Unknown("face-v-vel", Y, rv, DIRICHLET) wf = Unknown("face-w-vel", Z, rw, DIRICHLET) t = Unknown("temperature", C, rc, NEUMANN) p = Unknown("pressure", C, rc, NEUMANN) p_tot = Unknown("total-pressure", C, rc, NEUMANN) # This is a new test t.bnd[W].typ[:] = DIRICHLET t.bnd[W].val[:] = -0.5 t.bnd[E].typ[:] = DIRICHLET t.bnd[E].val[:] = +0.5 for j in (B, T): uf.bnd[j].typ[:] = NEUMANN vf.bnd[j].typ[:] = NEUMANN wf.bnd[j].typ[:] = NEUMANN # ============================================================================= # # Solution algorithm # # ============================================================================= # ---------- # # Time loop # # ---------- for ts in range(1, ndt + 1): write.time_step(ts) # ----------------- # Store old values # ----------------- t.old[:] = t.val[:] uf.old[:] = uf.val[:] vf.old[:] = vf.val[:] wf.old[:] = wf.val[:] # --------------------------- # Start inner iteration loop # --------------------------- # Allocate space for results from previous iteration t_prev = zeros(rc) u_prev = zeros(ru) v_prev = zeros(rv) w_prev = zeros(rw) for inner in range(1, 33): write.iteration(inner) # Store results from previous iteration t_prev[:] = t.val[:] u_prev[:] = uf.val[:] v_prev[:] = vf.val[:] w_prev[:] = wf.val[:] # Temperature (enthalpy) calc_t(t, (uf, vf, wf), (rho * cap), kappa, dt, (dx, dy, dz), advection_scheme="upwind", under_relaxation=0.75) # Momentum conservation ext_f = zeros(ru), avg(Y, t.val), zeros(rw) calc_uvw((uf, vf, wf), (uf, vf, wf), rho, mu, dt, (dx, dy, dz), pressure=p_tot, force=ext_f, advection_scheme="upwind", under_relaxation=0.75) # Pressure calc_p(p, (uf, vf, wf), rho, dt, (dx, dy, dz), verbose=False) p_tot.val += 0.25 * p.val # Velocity correction corr_uvw((uf, vf, wf), p, rho, dt, (dx, dy, dz), verbose=False) # Print differences in results between two iterations t_diff = abs(t.val[:] - t_prev) u_diff = abs(uf.val[:] - u_prev) v_diff = abs(vf.val[:] - v_prev) w_diff = abs(wf.val[:] - w_prev) print("t_diff = ", norm(t_diff)) print("u_diff = ", norm(u_diff)) print("v_diff = ", norm(v_diff)) print("w_diff = ", norm(w_diff)) # -------------------------------------------------- # Check the CFL number at the end of iteration loop # -------------------------------------------------- cfl = cfl_max((uf, vf, wf), dt, (dx, dy, dz)) # ============================================================================= # # Visualisation # # ============================================================================= if show_plot: if ts % plot_freq == 0: plot.isolines(t.val, (uf, vf, wf), (xn, yn, zn), Z) plot.gmv("tdc-staggered-%6.6d" % ts, (xn, yn, zn), (uf, vf, wf, t))
def main(show_plot=True, time_steps=1, plot_freq=1): # ============================================================================= # # Define problem # # ============================================================================= NX = 32 NY = NX NZ = 32 xn = nodes(0, 1, NX) yn = nodes(0, 1, NY) zn = nodes(0, 1, NZ) # Cell dimensions nx, ny, nz, dx, dy, dz, rc, ru, rv, rw = cartesian_grid(xn, yn, zn) # Set physical properties grashof = 1.4105E+06 prandtl = 0.7058 rho = zeros(rc) mu = zeros(rc) kappa = zeros(rc) cap = zeros(rc) rho[:, :, :] = 1.0 mu[:, :, :] = 1.0 / sqrt(grashof) kappa[:, :, :] = 1.0 / (prandtl * sqrt(grashof)) cap[:, :, :] = 1.0 # Time-stepping parameters dt = 2.0e10 # time step ndt = time_steps # number of time steps # Create unknowns; names, positions and sizes uf = Unknown("face-u-vel", X, ru, DIRICHLET) vf = Unknown("face-v-vel", Y, rv, DIRICHLET) wf = Unknown("face-w-vel", Z, rw, DIRICHLET) t = Unknown("temperature", C, rc, NEUMANN, per=(False, True, True)) # This is a new test t.bnd[W].typ[:] = DIRICHLET t.bnd[W].val[:] = -0.0 t.bnd[E].typ[:] = DIRICHLET t.bnd[E].val[:] = +0.0 t_src = zeros(t.val.shape) t_src[NX // 8:NY // 2, NX // 8:NY // 2, :] = 1.0 t_src[5 * NX // 8:3 * NY // 4, 5 * NX // 8:3 * NY // 4, :] = -4.0 # ============================================================================= # # Solution algorithm # # ============================================================================= # ---------- # # Time loop # # ---------- for ts in range(1, ndt + 1): write.time_step(ts) # ----------------- # Store old values # ----------------- t.old[:] = t.val[:] uf.old[:] = uf.val[:] vf.old[:] = vf.val[:] wf.old[:] = wf.val[:] # ----------------------- # Temperature (enthalpy) # ----------------------- calc_phi(t, (uf, vf, wf), (rho * cap), kappa, dt, (dx, dy, dz), source=t_src) # ============================================================================= # # Visualisation # # ============================================================================= if show_plot: if ts % plot_freq == 0: plot.isolines(t.val, (uf, vf, wf), (xn, yn, zn), Z, levels=21) plot.gmv("tdc-staggered-%6.6d.gmv" % ts, (xn, yn, zn), (uf, vf, wf, t))
def main(show_plot=True, time_steps=1800, plot_freq=180): # ============================================================================= # # Define problem # # ============================================================================= # Node coordinates xn = nodes(0, 1.25, 256) yn = nodes(0, 0.125, 32) zn = nodes(0, 0.125, 32) # Cell coordinates xc = avg(xn) yc = avg(yn) zc = avg(zn) # Cell dimensions nx, ny, nz, \ dx, dy, dz, \ rc, ru, rv, rw = cartesian_grid(xn, yn, zn) # Set physical properties rho, mu, cap, kappa = properties.air(rc) # Time-stepping parameters dt = 0.005 # time step ndt = time_steps # number of time steps # Create unknowns; names, positions and sizes uc = create_unknown('cell-u-vel', C, rc, DIRICHLET) vc = create_unknown('cell-v-vel', C, rc, DIRICHLET) wc = create_unknown('cell-w-vel', C, rc, DIRICHLET) uf = create_unknown('face-u-vel', X, ru, DIRICHLET) vf = create_unknown('face-v-vel', Y, rv, DIRICHLET) wf = create_unknown('face-w-vel', Z, rw, DIRICHLET) p = create_unknown('pressure', C, rc, NEUMANN) # Specify boundary conditions uc.bnd[W].typ[:1, :, :] = DIRICHLET uc.bnd[W].val[:1, :, :] = 0.1 * outer(par(1.0, yn), par(1.0, zn)) uc.bnd[E].typ[:1, :, :] = OUTLET for j in (B, T): uc.bnd[j].typ[:] = NEUMANN vc.bnd[j].typ[:] = NEUMANN wc.bnd[j].typ[:] = NEUMANN adj_n_bnds(p) # Create obstacles obst = zeros(rc) class key: """ Class Docstring. """ ip = -1 im = -1 jp = -1 jm = -1 kp = -1 km = -1 block = (key(), key(), key(), key()) th = 5 block[0].im = 3 * nx / 16 # i minus block[0].ip = block[0].im + th # i plus block[0].jm = 0 # j minus block[0].jp = 3 * ny / 4 # j plus block[0].km = 0 # k minus block[0].kp = 3 * ny / 4 # k plus block[1].im = 5 * nx / 16 # i minus block[1].ip = block[1].im + th # i plus block[1].jm = ny / 4 # j minus block[1].jp = ny # j plus block[1].km = ny / 4 # k minus block[1].kp = ny # k plus block[2].im = 7 * nx / 16 # i minus block[2].ip = block[2].im + th # i plus block[2].jm = 0 # j minus block[2].jp = 3 * ny / 4 # j plus block[2].km = 0 # k minus block[2].kp = 3 * ny / 4 # k plus block[3].im = 9 * nx / 16 # i minus block[3].ip = block[3].im + th # i plus block[3].jm = ny / 4 # j minus block[3].jp = ny # j plus block[3].km = ny / 4 # k minus block[3].kp = ny # k plus for o in range(0, 4): for i in range(floor(block[o].im), floor(block[o].ip)): for j in range(floor(block[o].jm), floor(block[o].jp)): for k in range(floor(block[o].km), floor(block[o].kp)): obst[i, j, k] = 1 # ============================================================================= # # Solution algorithm # # ============================================================================= # ----------- # # Time loop # # ----------- for ts in range(1, ndt + 1): write.time_step(ts) # ------------------ # Store old values # ------------------ uc.old[:] = uc.val[:] vc.old[:] = vc.val[:] wc.old[:] = wc.val[:] # ----------------------- # Momentum conservation # ----------------------- ef = zeros(rc), zeros(rc), zeros(rc) calc_uvw((uc, vc, wc), (uf, vf, wf), rho, mu, zeros(rc), ef, dt, (dx, dy, dz), obst) # ---------- # Pressure # ---------- calc_p(p, (uf, vf, wf), rho, dt, (dx, dy, dz), obst) # --------------------- # Velocity correction # --------------------- corr_uvw((uc, vc, wc), p, rho, dt, (dx, dy, dz), obst) corr_uvw((uf, vf, wf), p, rho, dt, (dx, dy, dz), obst) # Compute volume balance for checking err = vol_balance((uf, vf, wf), (dx, dy, dz), obst) print('Maximum volume error after correction: %12.5e' % abs(err).max()) # Check the CFL number too cfl = cfl_max((uc, vc, wc), dt, (dx, dy, dz)) print('Maximum CFL number: %12.5e' % cfl) # ============================================================================= # # Visualisation # # ============================================================================= if show_plot: if ts % plot_freq == 0: plot.isolines(p.val, (uc, vc, wc), (xn, yn, zn), Y) plot.isolines(p.val, (uc, vc, wc), (xn, yn, zn), Z)
def main(show_plot=True, time_steps=4800, plot_freq=480): # ============================================================================= # # Define problem # # ============================================================================= # Node coordinates xn = nodes(0, 1, 256) yn = nodes(0, 0.125, 32) zn = nodes(0, 0.125, 4) # Cell coordinates xc = avg(xn) yc = avg(yn) zc = avg(zn) # Cell dimensions nx,ny,nz, dx,dy,dz, rc,ru,rv,rw = cartesian_grid(xn,yn,zn) # Set physical properties rho, mu, cap, kappa = properties.air(rc) # Time-stepping parameters dt = 0.002 # time step ndt = time_steps # number of time steps # Create unknowns; names, positions and sizes uc = Unknown("cell-u-vel", C, rc, DIRICHLET) vc = Unknown("cell-v-vel", C, rc, DIRICHLET) wc = Unknown("cell-w-vel", C, rc, DIRICHLET) uf = Unknown("face-u-vel", X, ru, DIRICHLET) vf = Unknown("face-v-vel", Y, rv, DIRICHLET) wf = Unknown("face-w-vel", Z, rw, DIRICHLET) p = Unknown("pressure", C, rc, NEUMANN) # Specify boundary conditions uc.bnd[W].typ[:1,:,:] = DIRICHLET for k in range(0,nz): uc.bnd[W].val[:1,:,k] = par(0.1, yn) uc.bnd[E].typ[:1,:,:] = OUTLET for j in (B,T): uf.bnd[j].typ[:] = NEUMANN vf.bnd[j].typ[:] = NEUMANN wf.bnd[j].typ[:] = NEUMANN fin = zeros(rc) for j in range(0, 24): for i in range(64+j, 64+24): for k in range(0,nz): fin[i,j,k] = 1 # ============================================================================= # # Solution algorithm # # ============================================================================= # ---------- # # Time loop # # ---------- for ts in range(1,ndt+1): write.time_step(ts) # ----------------- # Store old values # ----------------- uc.old[:] = uc.val[:] vc.old[:] = vc.val[:] wc.old[:] = wc.val[:] # ---------------------- # Momentum conservation # ---------------------- calc_uvw((uc,vc,wc), (uf,vf,wf), rho, mu, dt, (dx,dy,dz), obstacle = fin) # --------- # Pressure # --------- calc_p(p, (uf,vf,wf), rho, dt, (dx,dy,dz), obstacle = fin) # -------------------- # Velocity correction # -------------------- corr_uvw((uc,vc,wc), p, rho, dt, (dx,dy,dz), obstacle = fin) corr_uvw((uf,vf,wf), p, rho, dt, (dx,dy,dz), obstacle = fin) # Check the CFL number too cfl = cfl_max((uc,vc,wc), dt, (dx,dy,dz)) # ============================================================================= # # Visualisation # # ============================================================================= if show_plot: if ts % plot_freq == 0: plot.isolines(p.val, (uc,vc,wc), (xn,yn,zn), Z) plot.tecplot("obstacle-collocated-%6.6d" % ts, (xn, yn, zn), (uc, vc, wc, p))
def main(show_plot=True, time_steps=1200, plot_freq=120): # ============================================================================= # # Define problem # # ============================================================================= xn = nodes(0, 1, 64, 1.0/256, 1.0/256) yn = nodes(0, 1, 64, 1.0/256, 1.0/256) zn = nodes(0, 0.1, 5) # Cell dimensions nx,ny,nz, dx,dy,dz, rc,ru,rv,rw = cartesian_grid(xn,yn,zn) # Set physical properties grashof = 1.4105E+06 prandtl = 0.7058 rho = zeros(rc) mu = zeros(rc) kappa = zeros(rc) cap = zeros(rc) rho [:,:,:] = 1.0 mu [:,:,:] = 1.0 / sqrt(grashof) kappa[:,:,:] = 1.0 / (prandtl * sqrt(grashof)) cap [:,:,:] = 1.0 # Time-stepping parameters dt = 0.02 # time step ndt = time_steps # number of time steps # Create unknowns; names, positions and sizes uf = Unknown("face-u-vel", X, ru, DIRICHLET) vf = Unknown("face-v-vel", Y, rv, DIRICHLET) wf = Unknown("face-w-vel", Z, rw, DIRICHLET) t = Unknown("temperature", C, rc, NEUMANN) p = Unknown("pressure", C, rc, NEUMANN) p_tot = Unknown("total-pressure", C, rc, NEUMANN) # This is a new test t.bnd[W].typ[:] = DIRICHLET t.bnd[W].val[:] = -0.5 t.bnd[E].typ[:] = DIRICHLET t.bnd[E].val[:] = +0.5 for j in (B,T): uf.bnd[j].typ[:] = NEUMANN vf.bnd[j].typ[:] = NEUMANN wf.bnd[j].typ[:] = NEUMANN # ============================================================================= # # Solution algorithm # # ============================================================================= # ---------- # # Time loop # # ---------- for ts in range(1,ndt+1): write.time_step(ts) # ----------------- # Store old values # ----------------- t.old[:] = t.val[:] uf.old[:] = uf.val[:] vf.old[:] = vf.val[:] wf.old[:] = wf.val[:] # ----------------------- # Temperature (enthalpy) # ----------------------- calc_t(t, (uf,vf,wf), (rho*cap), kappa, dt, (dx,dy,dz)) # ---------------------- # Momentum conservation # ---------------------- ext_f = zeros(ru), avg(Y,t.val), zeros(rw) calc_uvw((uf,vf,wf), (uf,vf,wf), rho, mu, dt, (dx,dy,dz), pressure = p_tot, force = ext_f) # --------- # Pressure # --------- calc_p(p, (uf,vf,wf), rho, dt, (dx,dy,dz)) p_tot.val += p.val # -------------------- # Velocity correction # -------------------- corr_uvw((uf,vf,wf), p, rho, dt, (dx,dy,dz)) # Check the CFL number too cfl = cfl_max((uf,vf,wf), dt, (dx,dy,dz)) # ============================================================================= # # Visualisation # # ============================================================================= if show_plot: if ts % plot_freq == 0: plot.isolines(t.val, (uf, vf, wf), (xn, yn, zn), Z) plot.gmv("tdc-staggered-%6.6d" % ts, (xn, yn, zn), (uf, vf, wf, t))
def main(show_plot=True, time_steps=1800, plot_freq=180): # ============================================================================= # # Define problem # # ============================================================================= # Node coordinates xn = nodes(0, 1.25, 256) yn = nodes(0, 0.125, 32) zn = nodes(0, 0.125, 32) # Cell coordinates xc = avg(xn) yc = avg(yn) zc = avg(zn) # Cell dimensions nx,ny,nz, dx,dy,dz, rc,ru,rv,rw = cartesian_grid(xn,yn,zn) # Set physical properties rho, mu, cap, kappa = properties.air(rc) # Time-stepping parameters dt = 0.005 # time step ndt = time_steps # number of time steps # Create unknowns; names, positions and sizes uf = Unknown("face-u-vel", X, ru, DIRICHLET) vf = Unknown("face-v-vel", Y, rv, DIRICHLET) wf = Unknown("face-w-vel", Z, rw, DIRICHLET) p = Unknown("pressure", C, rc, NEUMANN) # Specify boundary conditions uf.bnd[W].typ[:1,:,:] = DIRICHLET uf.bnd[W].val[:1,:,:] = 0.1 * outer( par(1.0, yn), par(1.0, zn) ) uf.bnd[E].typ[:1,:,:] = OUTLET # Create obstacles plates = zeros(rc) class key: ip = -1 im = -1 jp = -1 jm = -1 kp = -1 km = -1 block = (key(), key(), key(), key()); th = 5; block[0].im = 3*nx/16 # i minus block[0].ip = block[0].im + th # i plus block[0].jm = 0 # j minus block[0].jp = 3*ny/4 # j plus block[0].km = 0 # k minus block[0].kp = 3*ny/4 # k plus block[1].im = 5*nx/16 # i minus block[1].ip = block[1].im + th # i plus block[1].jm = ny/4 # j minus block[1].jp = ny # j plus block[1].km = ny/4 # k minus block[1].kp = ny # k plus block[2].im = 7*nx/16 # i minus block[2].ip = block[2].im + th # i plus block[2].jm = 0 # j minus block[2].jp = 3*ny/4 # j plus block[2].km = 0 # k minus block[2].kp = 3*ny/4 # k plus block[3].im = 9*nx/16 # i minus block[3].ip = block[3].im + th # i plus block[3].jm = ny/4 # j minus block[3].jp = ny # j plus block[3].km = ny/4 # k minus block[3].kp = ny # k plus for o in range(0, 4): for i in range(int(floor(block[o].im)), int(floor(block[o].ip))): for j in range(int(floor(block[o].jm)), int(floor(block[o].jp))): for k in range(int(floor(block[o].km)), int(floor(block[o].kp))): plates[i, j, k] = 1 # ============================================================================= # # Solution algorithm # # ============================================================================= # ---------- # # Time loop # # ---------- for ts in range(1,ndt+1): write.time_step(ts) # ----------------- # Store old values # ----------------- uf.old[:] = uf.val[:] vf.old[:] = vf.val[:] wf.old[:] = wf.val[:] # ---------------------- # Momentum conservation # ---------------------- calc_uvw((uf,vf,wf), (uf,vf,wf), rho, mu, dt, (dx,dy,dz), obstacle = plates) # --------- # Pressure # --------- calc_p(p, (uf,vf,wf), rho, dt, (dx,dy,dz), obstacle = plates) # -------------------- # Velocity correction # -------------------- corr_uvw((uf,vf,wf), p, rho, dt, (dx,dy,dz), obstacle = plates) # Check the CFL number too cfl = cfl_max((uf,vf,wf), dt, (dx,dy,dz)) # ============================================================================= # # Visualisation # # ============================================================================= if show_plot: if ts % plot_freq == 0: plot.isolines(p.val, (uf,vf,wf), (xn,yn,zn), Y) plot.isolines(p.val, (uf,vf,wf), (xn,yn,zn), Z) plot.gmv("obst-thinner-staggered-%6.6d" % ts, (xn,yn,zn), (uf,vf,wf,p))
def main(show_plot=True, time_steps=1200, plot_freq=120): # ============================================================================= # # Define problem # # ============================================================================= xn = nodes(0, 1, 64, 1.0/256, 1.0/256) yn = nodes(0, 1, 64, 1.0/256, 1.0/256) zn = nodes(0, 0.1, 5) # Cell dimensions nx,ny,nz, dx,dy,dz, rc,ru,rv,rw = cartesian_grid(xn,yn,zn) # Set physical properties grashof = 1.4105E+06 prandtl = 0.7058 rho = zeros(rc) mu = zeros(rc) kappa = zeros(rc) cap = zeros(rc) rho [:,:,:] = 1.0 mu [:,:,:] = 1.0 / sqrt(grashof) kappa[:,:,:] = 1.0 / (prandtl * sqrt(grashof)) cap [:,:,:] = 1.0 # Time-stepping parameters dt = 0.02 # time step ndt = time_steps # number of time steps # Create unknowns; names, positions and sizes uc = Unknown('cell-u-vel', C, rc, DIRICHLET) vc = Unknown('cell-v-vel', C, rc, DIRICHLET) wc = Unknown('cell-w-vel', C, rc, DIRICHLET) uf = Unknown('face-u-vel', X, ru, DIRICHLET) vf = Unknown('face-v-vel', Y, rv, DIRICHLET) wf = Unknown('face-w-vel', Z, rw, DIRICHLET) t = Unknown('temperature', C, rc, NEUMANN) p = Unknown('pressure', C, rc, NEUMANN) p_tot = zeros(rc) # This is a new test t.bnd[W].typ[:] = DIRICHLET t.bnd[W].val[:] = -0.5 t.bnd[E].typ[:] = DIRICHLET t.bnd[E].val[:] = +0.5 for j in (B,T): uc.bnd[j].typ[:] = NEUMANN vc.bnd[j].typ[:] = NEUMANN wc.bnd[j].typ[:] = NEUMANN obst = zeros(rc) # ============================================================================= # # Solution algorithm # # ============================================================================= #----------- # # Time loop # #----------- for ts in range(1,ndt+1): write.time_step(ts) #------------------ # Store old values #------------------ t.old[:] = t.val[:] uc.old[:] = uc.val[:] vc.old[:] = vc.val[:] wc.old[:] = wc.val[:] #------------------------ # Temperature (enthalpy) #------------------------ calc_t(t, (uf,vf,wf), (rho*cap), kappa, dt, (dx,dy,dz), obst) #----------------------- # Momentum conservation #----------------------- ef = zeros(rc), t.val, zeros(rc) calc_uvw((uc,vc,wc), (uf,vf,wf), rho, mu, p_tot, ef, dt, (dx,dy,dz), obst) #---------- # Pressure #---------- calc_p(p, (uf,vf,wf), rho, dt, (dx,dy,dz), obst) p_tot = p_tot + p.val #--------------------- # Velocity correction #--------------------- corr_uvw((uc,vc,wc), p, rho, dt, (dx,dy,dz), obst) corr_uvw((uf,vf,wf), p, rho, dt, (dx,dy,dz), obst) # Compute volume balance for checking err = vol_balance((uf,vf,wf), (dx,dy,dz), obst) print('Maximum volume error after correction: %12.5e' % abs(err).max()) # Check the CFL number too cfl = cfl_max((uc,vc,wc), dt, (dx,dy,dz)) print('Maximum CFL number: %12.5e' % cfl) # ============================================================================= # # Visualisation # # ============================================================================= if show_plot: if ts % plot_freq == 0: plot.isolines(t.val, (uc, vc, wc), (xn, yn, zn), Z) plot.gmv("tdc-collocated-%6.6d.gmv" % ts, (xn, yn, zn), (uc, vc, wc, t))