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=500, plot_freq=10): # Node coordinates xn = nodes(0, 1, 160) yn = nodes(0, 1, 160) zn = nodes(0, 0.25, 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 = 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) # Imposing the geometry by creating an obstacle # # # INLET # | | # | | # | | # | | # | | # | | # | | # | | # __________________| |___________________ # O O # U U # T T # L L # E E # T ________________________________________________________ T obst = zeros(rc) for k in range(0,nz): for i in range(0,nx//3): for j in range(ny//4,ny): obst[i,j,k] = 1 for k in range(0,nz): for i in range(2*nx//3,nx): for j in range(ny//4,ny): obst[i,j,k] = 1 for k in range(0,nz): vf.bnd[N].val[nx//3:2*nx//3, 0, k] = -par(0.01, xn[nx//3:2*nx//3+1]) uf.bnd[E].typ[0, :ny//4, k] = OUTLET uf.bnd[W].typ[0, :ny//4, k] = OUTLET for j in (B,T): uf.bnd[j].typ[:] = NEUMANN vf.bnd[j].typ[:] = NEUMANN wf.bnd[j].typ[:] = NEUMANN # Initialising the particles. n = 10000 # number of particles pt = initialiser(n, rho_p = 1000, d = 2.5e-6, verbose = False) # ============================================================================= # # 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, dt, (dx,dy,dz), obstacle = obst) # --------- # Pressure # --------- calc_p(p, (uf,vf,wf), rho, dt, (dx,dy,dz), obstacle = obst) # -------------------- # Velocity correction # -------------------- corr_uvw((uf,vf,wf), p, rho, dt, (dx,dy,dz), obstacle = obst) # Check the CFL number too cfl = cfl_max((uf,vf,wf), dt, (dx,dy,dz)) # Calculate the nodal velocities (un, vn, wn) = nodal_uvw((xn,yn,zn), (uf,vf,wf), obstacle = obst) # ---------------------------- # Lagrangian Particle Tracking # ---------------------------- # Iterate through the number of particles to update their positions # and velocities. calc_traj(pt, (un,vn,wn), rho, mu, (xn,yn,zn), (xc,yc,zc), dt, obst, n) # ============================================================================= # # Visualisation # # ============================================================================= if show_plot: if ts % plot_freq == 0: plot.gmv("impactor-%6.6d" % ts, (xn,yn,zn), unknowns = (uf, vf, wf, p), arrays = (un, vn, wn), tracers = (pt))
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=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))
def main(show_plot=True, time_steps=6000, plot_freq=60): # ============================================================================= # # Define problem # # ============================================================================= # Node coordinates xn = nodes(0, 0.6, 60) yn = nodes(0, 0.6, 60) zn = nodes(0, 0.3, 30) # 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, per=(True, True, False)) vf = Unknown("face-v-vel", Y, rv, DIRICHLET, per=(True, True, False)) wf = Unknown("face-w-vel", Z, rw, DIRICHLET, per=(True, True, False)) p = Unknown("pressure", C, rc, NEUMANN, per=(True, True, False)) cube = zeros(rc) for j in range(22, 38): for i in range(22, 38): for k in range(0,16): cube[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 = ones(ru)*0.05, zeros(rv), zeros(rw) calc_uvw((uf,vf,wf), (uf,vf,wf), rho, mu, dt, (dx,dy,dz), cube, force = ef) # --------- # Pressure # --------- calc_p(p, (uf,vf,wf), rho, dt, (dx,dy,dz), cube) # -------------------- # Velocity correction # -------------------- corr_uvw((uf,vf,wf), p, rho, dt, (dx,dy,dz), cube) # Check the CFL number too cfl = cfl_max((uf,vf,wf), dt, (dx,dy,dz)) # ============================================================================= # # Visualisation # # ============================================================================= if show_plot: if ts % plot_freq == 0: # Compute nodal velocities un, vn, wn = nodal_uvw((xn,yn,zn), (uf,vf,wf), cube) # Plot everything plot.gmv("cube-matrix-%6.6d" % ts, (xn,yn,zn), unknowns = (uf, vf, wf, p), arrays = (un, vn, wn) )