def test_field_slice(): """Tests (un)packing slices of a scalar field (from)to a buffer.""" fields = _generate_fields() for d in ['N', 'S', 'NW', 'SW', 'TNW', 'B']: for (src_arr, gpu_src_arr, gpu_dst_arr, gpu_buffer_arr) in fields: # Extract slice from N direction of the field slice_dir = direction_string_to_offset(d, dim=len(src_arr.shape)) pack_slice = get_slice_before_ghost_layer(slice_dir) unpack_slice = get_ghost_region_slice(slice_dir) src_field = Field.create_from_numpy_array("src_field", src_arr[pack_slice]) dst_field = Field.create_from_numpy_array("dst_field", src_arr[unpack_slice]) buffer = Field.create_generic("buffer", spatial_dimensions=1, field_type=FieldType.BUFFER, dtype=src_arr.dtype) pack_eqs = [Assignment(buffer.center(), src_field.center())] pack_types = { 'src_field': gpu_src_arr.dtype, 'buffer': gpu_buffer_arr.dtype } pack_code = create_cuda_kernel(pack_eqs, type_info=pack_types) pack_kernel = make_python_function(pack_code) pack_kernel(buffer=gpu_buffer_arr, src_field=gpu_src_arr[pack_slice]) # Unpack into ghost layer of dst_field in N direction unpack_eqs = [Assignment(dst_field.center(), buffer.center())] unpack_types = { 'dst_field': gpu_dst_arr.dtype, 'buffer': gpu_buffer_arr.dtype } unpack_code = create_cuda_kernel(unpack_eqs, type_info=unpack_types) unpack_kernel = make_python_function(unpack_code) unpack_kernel(buffer=gpu_buffer_arr, dst_field=gpu_dst_arr[unpack_slice]) dst_arr = gpu_dst_arr.get() np.testing.assert_equal(src_arr[pack_slice], dst_arr[unpack_slice])
def test_extrapolation_outflow_initialization_by_copy(): stencil = LBStencil(Stencil.D2Q9) domain_size = (1, 5) streaming_pattern = 'esotwist' zeroth_timestep = 'even' pdf_acc = AccessPdfValues(stencil, streaming_pattern=streaming_pattern, timestep=zeroth_timestep, streaming_dir='out') dh = create_data_handling(domain_size, default_target=Target.CPU) lb_method = create_lb_method(stencil=stencil) pdf_field = dh.add_array('f', values_per_cell=stencil.Q) dh.fill(pdf_field.name, np.nan, ghost_layers=True) pdf_arr = dh.cpu_arrays[pdf_field.name] bh = LatticeBoltzmannBoundaryHandling(lb_method, dh, pdf_field.name, streaming_pattern=streaming_pattern, target=Target.CPU) for y in range(1, 6): for j in range(stencil.Q): pdf_acc.write_pdf(pdf_arr, (1, y), j, j) normal_dir = (1, 0) outflow = ExtrapolationOutflow(normal_dir, lb_method, streaming_pattern=streaming_pattern, zeroth_timestep=zeroth_timestep) boundary_slice = get_ghost_region_slice(normal_dir) bh.set_boundary(outflow, boundary_slice) bh.prepare() blocks = list(dh.iterate()) index_list = blocks[0][ bh._index_array_name].boundary_object_to_index_list[outflow] assert len(index_list) == 13 for entry in index_list: direction = stencil[entry["dir"]] inv_dir = stencil.index(inverse_direction(direction)) assert entry[f'pdf'] == inv_dir assert entry[f'pdf_nd'] == inv_dir
def test_pdf_simple_extrapolation(stencil_enum, streaming_pattern): stencil = LBStencil(stencil_enum) # Field contains exactly one fluid cell domain_size = (3, ) * stencil.D for timestep in get_timesteps(streaming_pattern): dh = create_data_handling(domain_size, default_target=Target.CPU) lb_method = create_lb_method(lbm_config=LBMConfig(stencil=stencil)) pdf_field = dh.add_array('f', values_per_cell=stencil.Q) dh.fill(pdf_field.name, np.nan, ghost_layers=True) bh = LatticeBoltzmannBoundaryHandling(lb_method, dh, pdf_field.name, streaming_pattern, target=Target.CPU) # Set up outflows in all directions for normal_dir in stencil[1:]: boundary_obj = SimpleExtrapolationOutflow(normal_dir, stencil) boundary_slice = get_ghost_region_slice(normal_dir) bh.set_boundary(boundary_obj, boundary_slice) pdf_arr = dh.cpu_arrays[pdf_field.name] # Set up the domain with artificial PDF values # center = (1,) * dim out_access = AccessPdfValues(stencil, streaming_pattern, timestep, 'out') for cell in product(*(range(1, 4) for _ in range(stencil.D))): for q in range(stencil.Q): out_access.write_pdf(pdf_arr, cell, q, q) # Do boundary handling bh(prev_timestep=timestep) # Check PDF values in_access = AccessPdfValues(stencil, streaming_pattern, timestep.next(), 'in') # Inbound in center cell for cell in product(*(range(1, 4) for _ in range(stencil.D))): for q in range(stencil.Q): f = in_access.read_pdf(pdf_arr, cell, q) assert f == q
def test_pull_communication_slices(stencil): stencil = LBStencil(stencil) slices = get_communication_slices( stencil, streaming_pattern='pull', prev_timestep=Timestep.BOTH, ghost_layers=1) for i, d in enumerate(stencil): if i == 0: continue for s in slices[d]: if s[0][-1] == i: src = s[0][:-1] dst = s[1][:-1] break inner_slice = _fix_length_one_slices(get_slice_before_ghost_layer(d, ghost_layers=1)) inv_dir = (-e for e in d) gl_slice = _fix_length_one_slices(get_ghost_region_slice(inv_dir, ghost_layers=1)) assert src == inner_slice assert dst == gl_slice
def test_extrapolation_outflow_initialization_by_callback(): stencil = LBStencil(Stencil.D2Q9) domain_size = (1, 5) streaming_pattern = 'esotwist' zeroth_timestep = 'even' dh = create_data_handling(domain_size, default_target=Target.CPU) lb_method = create_lb_method(stencil=stencil) pdf_field = dh.add_array('f', values_per_cell=stencil.Q) dh.fill(pdf_field.name, np.nan, ghost_layers=True) bh = LatticeBoltzmannBoundaryHandling(lb_method, dh, pdf_field.name, streaming_pattern=streaming_pattern, target=Target.CPU) normal_dir = (1, 0) outflow = ExtrapolationOutflow(normal_direction=normal_dir, lb_method=lb_method, streaming_pattern=streaming_pattern, zeroth_timestep=zeroth_timestep, initial_density=lambda x, y: 1, initial_velocity=lambda x, y: (0, 0)) boundary_slice = get_ghost_region_slice(normal_dir) bh.set_boundary(outflow, boundary_slice) bh.prepare() weights = [w.evalf() for w in lb_method.weights] blocks = list(dh.iterate()) index_list = blocks[0][ bh._index_array_name].boundary_object_to_index_list[outflow] assert len(index_list) == 13 for entry in index_list: direction = stencil[entry["dir"]] inv_dir = stencil.index(inverse_direction(direction)) assert entry[f'pdf_nd'] == weights[inv_dir]