def genShockBubble(nx, ny, gamma, grid=None): """ Generate Shock-bubble interaction case for the Euler equations """ width = 4.0 height = 1.0 g = 0.0 rho = np.ones((ny, nx), dtype=np.float32) u = np.zeros((ny, nx), dtype=np.float32) v = np.zeros((ny, nx), dtype=np.float32) E = np.zeros((ny, nx), dtype=np.float32) p = np.ones((ny, nx), dtype=np.float32) x0, x1, y0, y1, dx, dy = getExtent(width, height, nx, ny, grid) x = np.linspace(x0, x1, nx, dtype=np.float32) y = np.linspace(y0, y1, ny, dtype=np.float32) xv, yv = np.meshgrid(x, y, sparse=False, indexing='xy') #Bubble radius = 0.25 x_center = 0.5 y_center = 0.5 bubble = np.sqrt((xv - x_center)**2 + (yv - y_center)**2) <= radius rho = np.where(bubble, 0.1, rho) #Left boundary left = (xv < 0.1) rho = np.where(left, 3.81250, rho) u = np.where(left, 2.57669, u) #Energy p = np.where(left, 10.0, p) E = 0.5 * rho * (u**2 + v**2) + p / (gamma - 1.0) bc = BoundaryCondition({ 'north': BoundaryCondition.Type.Reflective, 'south': BoundaryCondition.Type.Reflective, 'east': BoundaryCondition.Type.Periodic, 'west': BoundaryCondition.Type.Periodic }) #Construct simulator arguments = { 'rho': rho, 'rho_u': rho * u, 'rho_v': rho * v, 'E': E, 'nx': nx, 'ny': ny, 'dx': dx, 'dy': dy, 'g': g, 'gamma': gamma, 'boundary_conditions': bc } return arguments
def genRayleighTaylor(nx, ny, gamma, version=0, grid=None): """ Generates Rayleigh-Taylor instability case """ width = 0.5 height = 1.5 g = 0.1 rho = np.zeros((ny, nx), dtype=np.float32) u = np.zeros((ny, nx), dtype=np.float32) v = np.zeros((ny, nx), dtype=np.float32) p = np.zeros((ny, nx), dtype=np.float32) x0, x1, y0, y1, dx, dy = getExtent(width, height, nx, ny, grid) x = np.linspace(x0, x1, nx, dtype=np.float32) - width * 0.5 y = np.linspace(y0, y1, ny, dtype=np.float32) - height * 0.5 xv, yv = np.meshgrid(x, y, sparse=False, indexing='xy') #This gives a squigly interfact if (version == 0): y_threshold = 0.01 * np.cos(2 * np.pi * np.abs(x) / 0.5) rho = np.where(yv <= y_threshold, 1.0, rho) rho = np.where(yv > y_threshold, 2.0, rho) elif (version == 1): rho = np.where(yv <= 0.0, 1.0, rho) rho = np.where(yv > 0.0, 2.0, rho) v = 0.01 * (1.0 + np.cos(2 * np.pi * xv / 0.5)) / 4 else: assert False, "Invalid version" p = 2.5 - rho * g * yv E = 0.5 * rho * (u**2 + v**2) + p / (gamma - 1.0) bc = BoundaryCondition({ 'north': BoundaryCondition.Type.Reflective, 'south': BoundaryCondition.Type.Reflective, 'east': BoundaryCondition.Type.Reflective, 'west': BoundaryCondition.Type.Reflective }) #Construct simulator arguments = { 'rho': rho, 'rho_u': rho * u, 'rho_v': rho * v, 'E': E, 'nx': nx, 'ny': ny, 'dx': dx, 'dy': dy, 'g': g, 'gamma': gamma, 'boundary_conditions': bc } return arguments
def __init__(self, context, rho, rho_u, rho_v, E, nx, ny, dx, dy, g, gamma, theta=1.3, cfl_scale=0.9, boundary_conditions=BoundaryCondition(), block_width=16, block_height=8): # Call super constructor super().__init__(context, nx, ny, dx, dy, boundary_conditions, cfl_scale, 2, block_width, block_height) self.g = np.float32(g) self.gamma = np.float32(gamma) self.theta = np.float32(theta) #Get kernels module = context.get_module("cuda/EE2D_KP07_dimsplit.cu", defines={ 'BLOCK_WIDTH': self.block_size[0], 'BLOCK_HEIGHT': self.block_size[1] }, compile_args={ 'no_extern_c': True, 'options': ["--use_fast_math"], }, jit_compile_args={}) self.kernel = module.get_function("KP07DimsplitKernel") self.kernel.prepare("iiffffffiiPiPiPiPiPiPiPiPiP") #Create data by uploading to device self.u0 = Common.ArakawaA2D(self.stream, nx, ny, 2, 2, [rho, rho_u, rho_v, E]) self.u1 = Common.ArakawaA2D(self.stream, nx, ny, 2, 2, [None, None, None, None]) self.cfl_data = gpuarray.GPUArray(self.grid_size, dtype=np.float32) dt_x = np.min(self.dx / (np.abs(rho_u / rho) + np.sqrt(gamma * rho))) dt_y = np.min(self.dy / (np.abs(rho_v / rho) + np.sqrt(gamma * rho))) self.dt = min(dt_x, dt_y) self.cfl_data.fill(self.dt, stream=self.stream)
def __init__(self, context, h0, hu0, hv0, nx, ny, dx, dy, g, cfl_scale=0.9, boundary_conditions=BoundaryCondition(), block_width=16, block_height=16): # Call super constructor super().__init__(context, nx, ny, dx, dy, boundary_conditions, cfl_scale, 2, block_width, block_height) self.g = np.float32(g) #Get kernels module = context.get_module("cuda/SWE2D_WAF.cu", defines={ 'BLOCK_WIDTH': self.block_size[0], 'BLOCK_HEIGHT': self.block_size[1] }, compile_args={ 'no_extern_c': True, 'options': ["--use_fast_math"], }, jit_compile_args={}) self.kernel = module.get_function("WAFKernel") self.kernel.prepare("iiffffiiPiPiPiPiPiPiP") #Create data by uploading to device self.u0 = Common.ArakawaA2D(self.stream, nx, ny, 2, 2, [h0, hu0, hv0]) self.u1 = Common.ArakawaA2D(self.stream, nx, ny, 2, 2, [None, None, None]) self.cfl_data = gpuarray.GPUArray(self.grid_size, dtype=np.float32) dt_x = np.min(self.dx / (np.abs(hu0 / h0) + np.sqrt(g * h0))) dt_y = np.min(self.dy / (np.abs(hv0 / h0) + np.sqrt(g * h0))) dt = min(dt_x, dt_y) self.cfl_data.fill(dt, stream=self.stream)
def genKelvinHelmholtz(nx, ny, gamma, roughness=0.125, grid=None): """ Roughness parameter in (0, 1.0] determines how "squiggly" the interface betweeen the zones is """ def genZones(nx, ny, n): """ Generates the zones of the two fluids of K-H """ zone = np.zeros((ny, nx), dtype=np.int32) def genSmoothRandom(nx, n): n = max(1, min(n, nx)) if n == nx: return np.random.random(nx) - 0.5 else: from scipy.interpolate import interp1d #Control points and interpolator xp = np.linspace(0.0, 1.0, n) yp = np.random.random(n) - 0.5 if (n == 1): kind = 'nearest' elif (n == 2): kind = 'linear' elif (n == 3): kind = 'quadratic' else: kind = 'cubic' f = interp1d(xp, yp, kind=kind) #Interpolation points x = np.linspace(0.0, 1.0, nx) return f(x) x0, x1, y0, y1, _, dy = getExtent(1.0, 1.0, nx, ny, grid) x = np.linspace(x0, x1, nx) y = np.linspace(y0, y1, ny) _, y = np.meshgrid(x, y) #print(y+a[0]) a = genSmoothRandom(nx, n) * dy zone = np.where(y > 0.25 + a, zone, 1) a = genSmoothRandom(nx, n) * dy zone = np.where(y < 0.75 + a, zone, 1) return zone width = 2.0 height = 1.0 g = 0.0 gamma = 1.4 rho = np.empty((ny, nx), dtype=np.float32) u = np.empty((ny, nx), dtype=np.float32) v = np.zeros((ny, nx), dtype=np.float32) p = 2.5 * np.ones((ny, nx), dtype=np.float32) #Generate the different zones zones = genZones(nx, ny, max(1, min(nx, int(nx * roughness)))) #Zone 0 zone0 = zones == 0 rho = np.where(zone0, 1.0, rho) u = np.where(zone0, 0.5, u) #Zone 1 zone1 = zones == 1 rho = np.where(zone1, 2.0, rho) u = np.where(zone1, -0.5, u) E = 0.5 * rho * (u**2 + v**2) + p / (gamma - 1.0) _, _, _, _, dx, dy = getExtent(width, height, nx, ny, grid) bc = BoundaryCondition({ 'north': BoundaryCondition.Type.Periodic, 'south': BoundaryCondition.Type.Periodic, 'east': BoundaryCondition.Type.Periodic, 'west': BoundaryCondition.Type.Periodic }) #Construct simulator arguments = { 'rho': rho, 'rho_u': rho * u, 'rho_v': rho * v, 'E': E, 'nx': nx, 'ny': ny, 'dx': dx, 'dy': dy, 'g': g, 'gamma': gamma, 'boundary_conditions': bc } return arguments