def testCircleEvolution(): r""" Evolves an initially circular level set to see if it remains circular. """ # create circle N = 50 t = 0. X, Y = np.meshgrid(np.linspace(-1, 1, N), np.linspace(-1, 1, N)) r = 0.3 dx = 2.0 / (N - 1) dy = dx dt = 0.1 phi = (X)**2 + (Y)**2 - r**2 phi = computeDistanceFunction(phi, dx) title = "Circle evolution" # set up plot plt.ion() plt.figure(num=1, figsize=(12, 9), dpi=100, facecolor='w') dovis(np.transpose(phi), title, [0, dx * (N - 4), 0, dx * (N - 4)], [2, N - 3, 2, N - 3], 0, 0) plt.show(block=False) nIt = 200 sL0 = 0.0 marksteinLength = 0.0 u = np.zeros_like(phi) v = np.zeros_like(phi) adVel = 0.1 # magnitude of advective velocity iblims = np.array([2, N - 3, 2, N - 3]) lims = np.array([2, N - 2, 2, N - 2]) ilo, ihi, jlo, jhi = lims gridlims = np.array([0, dx * (N - 4), 0, dx * (N - 4)]) # make velocities hyp = np.sqrt(X[:, :]**2 + Y[:, :]**2) u[:, :] = adVel * Y[:, :] / hyp[:, :] v[:, :] = adVel * X[:, :] / hyp[:, :] # fix signs u[:N / 2, :] = -1. * np.fabs(u[:N / 2, :]) u[N / 2:, :] = np.fabs(u[N / 2:, :]) v[:, :N / 2] = -1. * np.fabs(v[:, :N / 2]) v[:, N / 2:] = np.fabs(v[:, N / 2:]) for n in range(nIt): # flame speed sL = pythonisedfns.laminarFlameSpeed2d(phi, sL0, marksteinLength, u, v, iblims, dx=dx, dy=dx) # calculate fluxes Fx, Fy = findFluxes(phi, sL, lims, dx=dx, dy=dy, u=u, v=v) Fx = enforceOutflowBCs(Fx, lims) Fy = enforceOutflowBCs(Fy, lims) phi[ilo:ihi, jlo:jhi] -= 0.5 * dt * ( (Fx[ilo:ihi, jlo:jhi] + Fx[ilo + 1:ihi + 1, jlo:jhi]) / dx + (Fy[ilo:ihi, jlo:jhi] + Fy[ilo:ihi, jlo + 1:jhi + 1]) / dy) t += dt # enforce outflow boundary conditions phi = enforceOutflowBCs(phi, lims) # plotting dovis(phi, title, gridlims, iblims, n, t, u=u, v=v) plt.show(block=False) # reinitialise phi = computeDistanceFunction(phi, dx) return
def testPeriodicVortexEvolution(): r""" Evolves a circle in periodic vortex field. The vortex is initialised with the stream function ..math:: \Psi = \frac{1}{4\pi}\sin(4\pi (x+0.5))\sin(4\pi (y+0.5)), where the velocities are then given by :math:`u = \partial\Psi/\partial y`, :math:`v = -\partial\Psi/\partial x`. The vortex reverses direction after a certain number of timesteps to see how close the system returns to the initial conditions. Test found in: Enright, D.P., 2002. Use of the Particle Level Set Method for Enhanced Resolution of Free Surface Flows. Stanford University. Available at: http://web.stanford.edu/group/fpc/Publications/Enright Thesis.pdf. """ # create circle N = 50 t = 0. X, Y = np.meshgrid(np.linspace(0., 1., N), np.linspace(0., 1., N)) r = 0.2 dx = 1.0 / (N - 1.) dy = dx dt = 0.05 phi = (X - 0.5)**2 + (Y - 0.5)**2 - r**2 phi = computeDistanceFunction(phi, dx) phi = enforce2dPeriodicBCs(phi) title = "Distortion field evolution" print("Initial area enclosed: " + str(enclosedArea(phi, dx, dy))) # set up plot plt.ion() plt.figure(num=1, figsize=(12, 9), dpi=100, facecolor='w') dovis(np.transpose(phi), title, [0, dx * (N - 4), 0, dx * (N - 4)], [2, N - 3, 2, N - 3], 0, 0) plt.show(block=False) nIt = 200 sL0 = 0.0 marksteinLength = 0.0 u = np.zeros_like(phi) v = np.zeros_like(phi) adVel = 0.1 # magnitude of advective velocity iblims = np.array([2, N - 3, 2, N - 3]) lims = np.array([2, N - 2, 2, N - 2]) ilo, ihi, jlo, jhi = lims gridlims = np.array([0, dx * (N - 4), 0, dx * (N - 4)]) # make velocities u[:, :] = -adVel * np.sin(4. * (Y[:, :] + 0.5) * np.pi) * \ np.sin(4. * (X[:,:] + 0.5) * np.pi) v[:, :] = -adVel * np.cos(4. * (Y[:, :] + 0.5) * np.pi) * \ np.cos(4. * (X[:,:] + 0.5) * np.pi) for n in range(nIt): # flame speed sL = pythonisedfns.laminarFlameSpeed2d(phi, sL0, marksteinLength, u, v, iblims, dx=dx, dy=dx) # calculate fluxes Fx, Fy = findFluxes(phi, sL, lims, dx=dx, dy=dy, u=u, v=v) Fx = enforce2dPeriodicBCs(Fx) Fy = enforce2dPeriodicBCs(Fy) phi[ilo:ihi, jlo:jhi] -= 0.5 * dt * ( (Fx[ilo:ihi, jlo:jhi] + Fx[ilo + 1:ihi + 1, jlo:jhi]) / dx + (Fy[ilo:ihi, jlo:jhi] + Fy[ilo:ihi, jlo + 1:jhi + 1]) / dy) t += dt # enforce outflow boundary conditions phi = enforce2dPeriodicBCs(phi) # plotting dovis(np.transpose(phi), title, gridlims, iblims, n, t, u=u, v=v, area=enclosedArea(phi, dx, dy)) #streamplot(np.linspace(-0.5, 0.5, N), u, v, title) plt.show(block=False) # reinitialise phi = computeDistanceFunction(phi, dx) # now reverse the direction of the vortex and rewind u[:, :] = -u[:, :] v[:, :] = -v[:, :] for n in range(nIt): # flame speed sL = pythonisedfns.laminarFlameSpeed2d(phi, sL0, marksteinLength, u, v, iblims, dx=dx, dy=dx) # calculate fluxes Fx, Fy = findFluxes(phi, sL, lims, dx=dx, dy=dy, u=u, v=v) Fx = enforce2dPeriodicBCs(Fx) Fy = enforce2dPeriodicBCs(Fy) phi[ilo:ihi, jlo:jhi] -= 0.5 * dt * ( (Fx[ilo:ihi, jlo:jhi] + Fx[ilo + 1:ihi + 1, jlo:jhi]) / dx + (Fy[ilo:ihi, jlo:jhi] + Fy[ilo:ihi, jlo + 1:jhi + 1]) / dy) t += dt # enforce periodic boundary conditions phi = enforce2dPeriodicBCs(phi) # plotting dovis(np.transpose(phi), title, gridlims, iblims, n + nIt, t, u=u, v=v, area=enclosedArea(phi, dx, dy)) #streamplot(np.linspace(-0.5, 0.5, N), u, v, title) plt.show(block=False) # reinitialise phi = computeDistanceFunction(phi, dx) print("Final area enclosed: " + str(enclosedArea(phi, dx, dy))) return
def testSquareEvolution(): r""" Evolves an initially square level set to see if it remains square. """ # create square N = 80 X, Y = np.meshgrid(np.linspace(-1, 1, N), np.linspace(-1, 1, N)) t = 0. dx = 2.0 / (N - 1) dy = dx dt = 0.1 phi = np.ones((N, N)) phi[N / 2 - 5:N / 2 + 6, N / 2 - 5:N / 2 + 6] = -1. phi = computeDistanceFunction(phi, dx) title = "Square evolution" # set up plot plt.ion() plt.figure(num=1, figsize=(12, 9), dpi=100, facecolor='w') dovis(np.transpose(phi), title, [0, dx * (N - 4), 0, dx * (N - 4)], [2, N - 3, 2, N - 3], 0, 0) plt.show(block=False) nIt = 250 sL0 = 0.0 marksteinLength = 0.0 adVel = 0.05 # magnitude of advective velocity u = np.zeros_like(phi) v = np.zeros_like(phi) iblims = np.array([2, N - 3, 2, N - 3]) lims = np.array([2, N - 2, 2, N - 2]) ilo, ihi, jlo, jhi = lims gridlims = np.array([0, dx * (N - 4), 0, dx * (N - 4)]) # make velocities # rhs mask = (Y > 0.) * (Y > np.abs(X)) u[mask] = adVel # lhs mask = (Y < 0.) * (np.fabs(Y) > np.abs(X)) u[mask] = -1. * adVel # top mask = (X > 0.) * (X > np.abs(Y)) v[mask] = adVel # bottom mask = (X < 0.) * (np.fabs(X) > np.abs(Y)) v[mask] = -1. * adVel for n in range(nIt): # flame speed sL = pythonisedfns.laminarFlameSpeed2d(phi, sL0, marksteinLength, u, v, iblims, dx=dx, dy=dx) # calculate fluxes Fx, Fy = findFluxes(phi, sL, lims, dx=dx, dy=dy, u=u, v=v) Fx = enforceOutflowBCs(Fx, lims) Fy = enforceOutflowBCs(Fy, lims) phi[ilo:ihi, jlo:jhi] -= 0.5 * dt * ( (Fx[ilo:ihi, jlo:jhi] + Fx[ilo + 1:ihi + 1, jlo:jhi]) / dx + (Fy[ilo:ihi, jlo:jhi] + Fy[ilo:ihi, jlo + 1:jhi + 1]) / dy) t += dt # enforce outflow boundary conditions phi = enforceOutflowBCs(phi, lims) # plotting dovis(phi, title, gridlims, iblims, n, t, u=u, v=v) plt.show(block=False) # reinitialise phi = computeDistanceFunction(phi, dx) return
def testSineEvolution(): r""" Evolves level set with periodic boundary conditions. """ # create sine N = 85 sinewidth = np.rint(N / 10) sinewidth = sinewidth.astype(int) t = 0. dx = 2.0 / (N - 5) dy = dx dt = 0.1 phi = np.ones((N, N)) phi[N / 2 - sinewidth:N / 2 + sinewidth + 1, :] = -1. phi = computeDistanceFunction(phi, dx) title = "Periodic evolution" toCSV = False # set up plot plt.ion() plt.figure(num=1, figsize=(12, 9), dpi=100, facecolor='w') dovis(phi, title, [0, dx * (N - 5), 0, dx * (N - 5)], [2, N - 3, 2, N - 3], 0, 0) plt.show(block=False) nIt = 150 sL0 = 0.08 marksteinLength = 0.05 u = np.ones_like(phi) * 0.08 iblims = np.array([2, N - 3, 2, N - 3]) lims = np.array([2, N - 2, 2, N - 2]) ilo, ihi, jlo, jhi = lims gridlims = np.array([0, dx * (N - 5), 0, dx * (N - 5)]) if toCSV: headers = ['t', 'xcoord', 'ycoord', 'phi'] filepath = \ '/home/alice/Documents/Dropbox/LSMLIB/pylsmlib/pylsmlib/fire/' xs = [dx * n for n in range(N - 4)] ys = [dy * n for n in range(N - 4)] for n in range(nIt): # flame speed sL = pythonisedfns.laminarFlameSpeed2d(phi, sL0, marksteinLength, u, u, iblims, dx=dx, dy=dx) # calculate fluxes Fx, Fy = findFluxes(phi, sL, lims, dx=dx, dy=dy, u=u, v=u) Fx = enforcePeriodicBCs(Fx, lims) Fy = enforcePeriodicBCs(Fy, lims) phi[ilo:ihi, jlo:jhi] -= 0.5 * dt * ( (Fx[ilo:ihi, jlo:jhi] + Fx[ilo + 1:ihi + 1, jlo:jhi]) / dx + (Fy[ilo:ihi, jlo:jhi] + Fy[ilo:ihi, jlo + 1:jhi + 1]) / dy) t += dt # enforce periodic boundary conditions phi[:, :] = enforcePeriodicBCs(phi[:, :], lims) # plotting dovis(phi, title, gridlims, iblims, n, t) plt.show(block=False) # save to file if toCSV: # remember to ignore ghosts rows = [(t, xs[i], ys[j], phi[i, j]) for j in range(N - 4) for i in range(N - 4)] with open(filepath + 'sine' + str(n) + '.csv', 'w') as f: f_csv = csv.writer(f) f_csv.writerow(headers) f_csv.writerows(rows) # reinitialise phi[:, :] = computeDistanceFunction(phi[:, :], dx) return
def testSphereEvolution(): r""" Evolves an initially spherical set to see if it remains spherical. """ # create circle N = 20 t = 0. X, Y, Z = np.meshgrid(np.linspace(-1, 1, N), np.linspace(-1, 1, N), np.linspace(-1, 1, N)) r = 0.3 dx = 2.0 / (N - 1) dy = dx dz = dx dt = 0.1 phi = (X)**2 + (Y)**2 + (Z)**2 - r**2 phi = computeDistanceFunction(phi, dx) title = "Sphere evolution" toCSV = False # set up plot plt.ion() plt.figure(num=1, figsize=(12, 9), dpi=100, facecolor='w') dovis(np.transpose(phi[N / 2, :, :]), title, [0, dx * (N - 4), 0, dx * (N - 4)], [2, N - 3, 2, N - 3], 0, 0) plt.show(block=False) nIt = 100 sL0 = 0.2 marksteinLength = 0.05 u = 0.1 * np.zeros_like(phi) iblims = np.array([2, N - 3, 2, N - 3, 2, N - 3]) lims = np.array([2, N - 2, 2, N - 2, 2, N - 2]) ilo, ihi, jlo, jhi, klo, khi = lims # gridlims = np.array([0, dx*(N-4), 0, dx*(N-4), 0, dx*(N-4)]) if toCSV: headers = ['t', 'xcoord', 'ycoord', 'zcoord', 'phi'] filepath = \ '/home/alice/Documents/Dropbox/LSMLIB/pylsmlib/pylsmlib/fire/' xs = [dx * n for n in range(N - 4)] ys = [dy * n for n in range(N - 4)] zs = [dz * n for n in range(N - 4)] for n in range(nIt): # flame speed sL = pythonisedfns.laminarFlameSpeed(phi, sL0, marksteinLength, u, u, u, iblims, dx=dx, dy=dx, dz=dz) # calculate fluxes Fx, Fy, Fz = findFluxes3d(phi, sL, lims, dx=dx, dy=dy, dz=dz, u=u, v=u, w=u) Fx = enforceOutflowBCs3d(Fx, lims) Fy = enforceOutflowBCs3d(Fy, lims) Fz = enforceOutflowBCs3d(Fz, lims) phi[ilo:ihi, jlo:jhi, klo:khi] -= 0.5 * dt * ( (Fx[ilo:ihi, jlo:jhi, klo:khi] + Fx[ilo + 1:ihi + 1, jlo:jhi, klo:khi]) / dx + (Fy[ilo:ihi, jlo:jhi, klo:khi] + Fy[ilo:ihi, jlo + 1:jhi + 1, klo:khi]) / dy + (Fz[ilo:ihi, jlo:jhi, klo:khi] + Fz[ilo:ihi, jlo:jhi, klo + 1:khi + 1]) / dx) t += dt # enforce outflow boundary conditions phi = enforceOutflowBCs3d(phi, lims) # plotting dovis(np.transpose(phi[N / 2, :, :]), title, [0, dx * (N - 4), 0, dx * (N - 4)], [2, N - 3, 2, N - 3], n, t) plt.show(block=False) # save to file if toCSV: # remember to ignore ghosts rows = [(t, xs[i], ys[j], zs[k], phi[i, j, k]) for k in range(N - 4) for j in range(N - 4) for i in range(N - 4)] with open(filepath + 'sphere' + str(n) + '.csv', 'w') as f: f_csv = csv.writer(f) f_csv.writerow(headers) f_csv.writerows(rows) # reinitialise phi = computeDistanceFunction(phi, dx) return
def testCircleEvolution(): r""" Evolves an initially circular level set to see if it remains circular. """ # create circle N = 50 t = 0. X, Y = np.meshgrid(np.linspace(-1, 1, N), np.linspace(-1, 1, N)) r = 0.3 dx = 2.0 / (N - 1) dy = dx dt = 0.1 phi = (X) ** 2 + (Y) ** 2 - r ** 2 phi = computeDistanceFunction(phi, dx) title = "Circle evolution" # set up plot plt.ion() plt.figure(num=1, figsize=(12, 9), dpi=100, facecolor='w') dovis(np.transpose(phi), title, [0, dx*(N-4), 0, dx*(N-4)], [2, N-3, 2, N-3], 0, 0) plt.show(block=False) nIt = 200 sL0 = 0.0 marksteinLength = 0.0 u = np.zeros_like(phi) v = np.zeros_like(phi) adVel = 0.1 # magnitude of advective velocity iblims = np.array([2, N-3, 2, N-3]) lims = np.array([2, N-2, 2, N-2]) ilo, ihi, jlo, jhi = lims gridlims = np.array([0, dx*(N-4), 0, dx*(N-4)]) # make velocities hyp = np.sqrt(X[:, :]**2 + Y[:, :]**2) u[:, :] = adVel * Y[:, :] / hyp[:, :] v[:, :] = adVel * X[:, :] / hyp[:, :] # fix signs u[:N/2, :] = -1. * np.fabs(u[:N/2, :]) u[N/2:, :] = np.fabs(u[N/2:, :]) v[:, :N/2] = -1. * np.fabs(v[:, :N/2]) v[:, N/2:] = np.fabs(v[:, N/2:]) for n in range(nIt): # flame speed sL = pythonisedfns.laminarFlameSpeed2d(phi, sL0, marksteinLength, u, v, iblims, dx=dx, dy=dx) # calculate fluxes Fx, Fy = findFluxes(phi, sL, lims, dx=dx, dy=dy, u=u, v=v) Fx = enforceOutflowBCs(Fx, lims) Fy = enforceOutflowBCs(Fy, lims) phi[ilo:ihi, jlo:jhi] -= 0.5 * dt * ( (Fx[ilo:ihi, jlo:jhi] + Fx[ilo+1:ihi+1, jlo:jhi])/dx + (Fy[ilo:ihi, jlo:jhi] + Fy[ilo:ihi, jlo+1:jhi+1])/dy) t += dt # enforce outflow boundary conditions phi = enforceOutflowBCs(phi, lims) # plotting dovis(phi, title, gridlims, iblims, n, t, u=u, v=v) plt.show(block=False) # reinitialise phi = computeDistanceFunction(phi, dx) return
def testSquareEvolution(): r""" Evolves an initially square level set to see if it remains square. """ # create square N = 80 X, Y = np.meshgrid(np.linspace(-1, 1, N), np.linspace(-1, 1, N)) t = 0. dx = 2.0 / (N - 1) dy = dx dt = 0.1 phi = np.ones((N, N)) phi[N/2-5:N/2+6, N/2-5:N/2+6] = -1. phi = computeDistanceFunction(phi, dx) title = "Square evolution" # set up plot plt.ion() plt.figure(num=1, figsize=(12, 9), dpi=100, facecolor='w') dovis(np.transpose(phi), title, [0, dx*(N-4), 0, dx*(N-4)], [2, N-3, 2, N-3], 0, 0) plt.show(block=False) nIt = 250 sL0 = 0.0 marksteinLength = 0.0 adVel = 0.05 # magnitude of advective velocity u = np.zeros_like(phi) v = np.zeros_like(phi) iblims = np.array([2, N-3, 2, N-3]) lims = np.array([2, N-2, 2, N-2]) ilo, ihi, jlo, jhi = lims gridlims = np.array([0, dx*(N-4), 0, dx*(N-4)]) # make velocities # rhs mask = (Y > 0.) * (Y > np.abs(X)) u[mask] = adVel # lhs mask = (Y < 0.) * (np.fabs(Y) > np.abs(X)) u[mask] = -1.*adVel # top mask = (X > 0.) * (X > np.abs(Y)) v[mask] = adVel # bottom mask = (X < 0.) * (np.fabs(X) > np.abs(Y)) v[mask] = -1.*adVel for n in range(nIt): # flame speed sL = pythonisedfns.laminarFlameSpeed2d(phi, sL0, marksteinLength, u, v, iblims, dx=dx, dy=dx) # calculate fluxes Fx, Fy = findFluxes(phi, sL, lims, dx=dx, dy=dy, u=u, v=v) Fx = enforceOutflowBCs(Fx, lims) Fy = enforceOutflowBCs(Fy, lims) phi[ilo:ihi, jlo:jhi] -= 0.5 * dt * ( (Fx[ilo:ihi, jlo:jhi] + Fx[ilo+1:ihi+1, jlo:jhi])/dx + (Fy[ilo:ihi, jlo:jhi] + Fy[ilo:ihi, jlo+1:jhi+1])/dy) t += dt # enforce outflow boundary conditions phi = enforceOutflowBCs(phi, lims) # plotting dovis(phi, title, gridlims, iblims, n, t, u=u, v=v) plt.show(block=False) # reinitialise phi = computeDistanceFunction(phi, dx) return
def testPeriodicVortexEvolution(): r""" Evolves a circle in periodic vortex field. The vortex is initialised with the stream function ..math:: \Psi = \frac{1}{4\pi}\sin(4\pi (x+0.5))\sin(4\pi (y+0.5)), where the velocities are then given by :math:`u = \partial\Psi/\partial y`, :math:`v = -\partial\Psi/\partial x`. The vortex reverses direction after a certain number of timesteps to see how close the system returns to the initial conditions. Test found in: Enright, D.P., 2002. Use of the Particle Level Set Method for Enhanced Resolution of Free Surface Flows. Stanford University. Available at: http://web.stanford.edu/group/fpc/Publications/Enright Thesis.pdf. """ # create circle N = 50 t = 0. X, Y = np.meshgrid(np.linspace(0., 1., N), np.linspace(0., 1., N)) r = 0.2 dx = 1.0 / (N - 1.) dy = dx dt = 0.05 phi = (X-0.5) ** 2 + (Y-0.5) ** 2 - r ** 2 phi = computeDistanceFunction(phi, dx) phi = enforce2dPeriodicBCs(phi) title = "Distortion field evolution" print("Initial area enclosed: " + str(enclosedArea(phi, dx, dy))) # set up plot plt.ion() plt.figure(num=1, figsize=(12, 9), dpi=100, facecolor='w') dovis(np.transpose(phi), title, [0, dx*(N-4), 0, dx*(N-4)], [2, N-3, 2, N-3], 0, 0) plt.show(block=False) nIt = 200 sL0 = 0.0 marksteinLength = 0.0 u = np.zeros_like(phi) v = np.zeros_like(phi) adVel = 0.1 # magnitude of advective velocity iblims = np.array([2, N-3, 2, N-3]) lims = np.array([2, N-2, 2, N-2]) ilo, ihi, jlo, jhi = lims gridlims = np.array([0, dx*(N-4), 0, dx*(N-4)]) # make velocities u[:, :] = -adVel * np.sin(4. * (Y[:, :] + 0.5) * np.pi) * \ np.sin(4. * (X[:,:] + 0.5) * np.pi) v[:, :] = -adVel * np.cos(4. * (Y[:, :] + 0.5) * np.pi) * \ np.cos(4. * (X[:,:] + 0.5) * np.pi) for n in range(nIt): # flame speed sL = pythonisedfns.laminarFlameSpeed2d(phi, sL0, marksteinLength, u, v, iblims, dx=dx, dy=dx) # calculate fluxes Fx, Fy = findFluxes(phi, sL, lims, dx=dx, dy=dy, u=u, v=v) Fx = enforce2dPeriodicBCs(Fx) Fy = enforce2dPeriodicBCs(Fy) phi[ilo:ihi, jlo:jhi] -= 0.5 * dt * ( (Fx[ilo:ihi, jlo:jhi] + Fx[ilo+1:ihi+1, jlo:jhi])/dx + (Fy[ilo:ihi, jlo:jhi] + Fy[ilo:ihi, jlo+1:jhi+1])/dy) t += dt # enforce outflow boundary conditions phi = enforce2dPeriodicBCs(phi) # plotting dovis(np.transpose(phi), title, gridlims, iblims, n, t, u=u, v=v, area=enclosedArea(phi, dx, dy)) #streamplot(np.linspace(-0.5, 0.5, N), u, v, title) plt.show(block=False) # reinitialise phi = computeDistanceFunction(phi, dx) # now reverse the direction of the vortex and rewind u[:, :] = -u[:, :] v[:, :] = -v[:, :] for n in range(nIt): # flame speed sL = pythonisedfns.laminarFlameSpeed2d(phi, sL0, marksteinLength, u, v, iblims, dx=dx, dy=dx) # calculate fluxes Fx, Fy = findFluxes(phi, sL, lims, dx=dx, dy=dy, u=u, v=v) Fx = enforce2dPeriodicBCs(Fx) Fy = enforce2dPeriodicBCs(Fy) phi[ilo:ihi, jlo:jhi] -= 0.5 * dt * ( (Fx[ilo:ihi, jlo:jhi] + Fx[ilo+1:ihi+1, jlo:jhi])/dx + (Fy[ilo:ihi, jlo:jhi] + Fy[ilo:ihi, jlo+1:jhi+1])/dy) t += dt # enforce periodic boundary conditions phi = enforce2dPeriodicBCs(phi) # plotting dovis(np.transpose(phi), title, gridlims, iblims, n+nIt, t, u=u, v=v, area=enclosedArea(phi, dx, dy)) #streamplot(np.linspace(-0.5, 0.5, N), u, v, title) plt.show(block=False) # reinitialise phi = computeDistanceFunction(phi, dx) print("Final area enclosed: " + str(enclosedArea(phi, dx, dy))) return
def testSphereEvolution(): r""" Evolves an initially spherical set to see if it remains spherical. """ # create circle N = 20 t = 0. X, Y, Z = np.meshgrid(np.linspace(-1, 1, N), np.linspace(-1, 1, N), np.linspace(-1, 1, N)) r = 0.3 dx = 2.0 / (N - 1) dy = dx dz = dx dt = 0.1 phi = (X) ** 2 + (Y) ** 2 + (Z) ** 2 - r ** 2 phi = computeDistanceFunction(phi, dx) title = "Sphere evolution" toCSV = False # set up plot plt.ion() plt.figure(num=1, figsize=(12, 9), dpi=100, facecolor='w') dovis(np.transpose(phi[N/2, :, :]), title, [0, dx*(N-4), 0, dx*(N-4)], [2, N-3, 2, N-3], 0, 0) plt.show(block=False) nIt = 100 sL0 = 0.2 marksteinLength = 0.05 u = 0.1 * np.zeros_like(phi) iblims = np.array([2, N-3, 2, N-3, 2, N-3]) lims = np.array([2, N-2, 2, N-2, 2, N-2]) ilo, ihi, jlo, jhi, klo, khi = lims # gridlims = np.array([0, dx*(N-4), 0, dx*(N-4), 0, dx*(N-4)]) if toCSV: headers = ['t', 'xcoord', 'ycoord', 'zcoord', 'phi'] filepath = \ '/home/alice/Documents/Dropbox/LSMLIB/pylsmlib/pylsmlib/fire/' xs = [dx*n for n in range(N-4)] ys = [dy*n for n in range(N-4)] zs = [dz*n for n in range(N-4)] for n in range(nIt): # flame speed sL = pythonisedfns.laminarFlameSpeed(phi, sL0, marksteinLength, u, u, u, iblims, dx=dx, dy=dx, dz=dz) # calculate fluxes Fx, Fy, Fz = findFluxes3d(phi, sL, lims, dx=dx, dy=dy, dz=dz, u=u, v=u, w=u) Fx = enforceOutflowBCs3d(Fx, lims) Fy = enforceOutflowBCs3d(Fy, lims) Fz = enforceOutflowBCs3d(Fz, lims) phi[ilo:ihi, jlo:jhi, klo:khi] -= 0.5 * dt * ( (Fx[ilo:ihi, jlo:jhi, klo:khi] + Fx[ilo+1:ihi+1, jlo:jhi, klo:khi]) / dx + (Fy[ilo:ihi, jlo:jhi, klo:khi] + Fy[ilo:ihi, jlo+1:jhi+1, klo:khi]) / dy + (Fz[ilo:ihi, jlo:jhi, klo:khi] + Fz[ilo:ihi, jlo:jhi, klo+1:khi+1]) / dx) t += dt # enforce outflow boundary conditions phi = enforceOutflowBCs3d(phi, lims) # plotting dovis(np.transpose(phi[N/2, :, :]), title, [0, dx*(N-4), 0, dx*(N-4)], [2, N-3, 2, N-3], n, t) plt.show(block=False) # save to file if toCSV: # remember to ignore ghosts rows = [(t, xs[i], ys[j], zs[k], phi[i, j, k]) for k in range(N-4) for j in range(N-4) for i in range(N-4)] with open(filepath + 'sphere' + str(n) + '.csv', 'w') as f: f_csv = csv.writer(f) f_csv.writerow(headers) f_csv.writerows(rows) # reinitialise phi = computeDistanceFunction(phi, dx) return
def testSineEvolution(): r""" Evolves level set with periodic boundary conditions. """ # create sine N = 85 sinewidth = np.rint(N/10) sinewidth = sinewidth.astype(int) t = 0. dx = 2.0 / (N - 5) dy = dx dt = 0.1 phi = np.ones((N, N)) phi[N/2-sinewidth:N/2+sinewidth+1, :] = -1. phi = computeDistanceFunction(phi, dx) title = "Periodic evolution" toCSV = False # set up plot plt.ion() plt.figure(num=1, figsize=(12, 9), dpi=100, facecolor='w') dovis(phi, title, [0, dx*(N-5), 0, dx*(N-5)], [2, N-3, 2, N-3], 0, 0) plt.show(block=False) nIt = 150 sL0 = 0.08 marksteinLength = 0.05 u = np.ones_like(phi)*0.08 iblims = np.array([2, N-3, 2, N-3]) lims = np.array([2, N-2, 2, N-2]) ilo, ihi, jlo, jhi = lims gridlims = np.array([0, dx*(N-5), 0, dx*(N-5)]) if toCSV: headers = ['t', 'xcoord', 'ycoord', 'phi'] filepath = \ '/home/alice/Documents/Dropbox/LSMLIB/pylsmlib/pylsmlib/fire/' xs = [dx*n for n in range(N-4)] ys = [dy*n for n in range(N-4)] for n in range(nIt): # flame speed sL = pythonisedfns.laminarFlameSpeed2d(phi, sL0, marksteinLength, u, u, iblims, dx=dx, dy=dx) # calculate fluxes Fx, Fy = findFluxes(phi, sL, lims, dx=dx, dy=dy, u=u, v=u) Fx = enforcePeriodicBCs(Fx, lims) Fy = enforcePeriodicBCs(Fy, lims) phi[ilo:ihi, jlo:jhi] -= 0.5 * dt * ( (Fx[ilo:ihi, jlo:jhi] + Fx[ilo+1:ihi+1, jlo:jhi])/dx + (Fy[ilo:ihi, jlo:jhi] + Fy[ilo:ihi, jlo+1:jhi+1])/dy) t += dt # enforce periodic boundary conditions phi[:, :] = enforcePeriodicBCs(phi[:, :], lims) # plotting dovis(phi, title, gridlims, iblims, n, t) plt.show(block=False) # save to file if toCSV: # remember to ignore ghosts rows = [(t, xs[i], ys[j], phi[i, j]) for j in range(N-4) for i in range(N-4)] with open(filepath + 'sine' + str(n) + '.csv', 'w') as f: f_csv = csv.writer(f) f_csv.writerow(headers) f_csv.writerows(rows) # reinitialise phi[:, :] = computeDistanceFunction(phi[:, :], dx) return