def test_central_moment_to_cumulant_transformation(): """Transforms from central moments to cumulants and back, then checks for identity""" for stencil in [LBStencil(Stencil.D2Q9), LBStencil(Stencil.D3Q27)]: indices = moments_up_to_component_order(2, dim=stencil.D) symbol_format = "m_%d_%d_%d" if stencil.D == 3 else "m_%d_%d" moment_symbols = { idx: sp.Symbol(symbol_format % idx) for idx in indices } forward = { idx: cumulant_as_function_of_central_moments( idx, moments_dict=moment_symbols) for idx in indices } backward = { idx: sp.simplify( central_moment_as_function_of_cumulants( idx, cumulants_dict=forward)) for idx in indices } for idx in indices: if sum(idx) == 1: continue assert backward[idx] == moment_symbols[idx]
def test_dimensionality(): for d in LBStencil(Stencil.D2Q9).stencil_entries: assert len(d) == 2 assert LBStencil(Stencil.D2Q9).D == 2 for stencil in get_3d_stencils(): assert stencil.D == 3
def test_visualize(): plt.clf() plt.cla() d2q9, d3q19 = LBStencil(Stencil.D2Q9), LBStencil(Stencil.D3Q19) figure = plt.gcf() with warnings.catch_warnings(): warnings.simplefilter("ignore") d2q9.plot(figure=figure, data=[str(i) for i in range(9)]) d3q19.plot(figure=figure, data=sp.symbols("a_:19"))
def test_moment_equality_table(): pytest.importorskip('ipy_table') d3q19 = LBStencil(Stencil.D3Q19) table1 = moment_equality_table(d3q19, max_order=3) assert len(table1.array) == 5 table2 = moment_equality_table_by_stencil({'D3Q19': d3q19, 'D3Q27': LBStencil(Stencil.D3Q27)}, moments_up_to_component_order(2, dim=3)) assert len(table2.array) == 11 assert len(table2.array[0]) == 2 + 2
def test_forward_transform(cumulants, stencil): stencil = LBStencil(stencil) if cumulants == 'monomial': moment_polynomials = get_default_moment_set_for_stencil(stencil) elif cumulants == 'polynomial': moment_polynomials = [ item for sublist in cascaded_moment_sets_literature(stencil) for item in sublist ] pdfs = sp.symbols(f"f_:{stencil.Q}") rho = sp.Symbol('rho') u = sp.symbols(f"u_:{stencil.D}") matrix_transform = PdfsToCentralMomentsByMatrix(stencil, moment_polynomials, rho, u) fast_transform = FastCentralMomentTransform(stencil, moment_polynomials, rho, u) shift_transform = PdfsToCentralMomentsByShiftMatrix( stencil, moment_polynomials, rho, u) assert shift_transform.moment_exponents == fast_transform.moment_exponents if cumulants == 'monomial' and not have_same_entries( stencil, LBStencil(Stencil.D3Q15)): assert fast_transform.mono_to_poly_matrix == sp.eye(stencil.Q) assert shift_transform.mono_to_poly_matrix == sp.eye(stencil.Q) else: assert not fast_transform.mono_to_poly_matrix == sp.eye(stencil.Q) assert not shift_transform.mono_to_poly_matrix == sp.eye(stencil.Q) f_to_k_matrix = matrix_transform.forward_transform(pdfs) f_to_k_matrix = f_to_k_matrix.new_without_subexpressions( ).main_assignments_dict f_to_k_fast = fast_transform.forward_transform(pdfs) f_to_k_fast = f_to_k_fast.new_without_subexpressions( ).main_assignments_dict f_to_k_shift = shift_transform.forward_transform(pdfs, simplification=False) f_to_k_shift = f_to_k_shift.new_without_subexpressions( ).main_assignments_dict cm_symbols = matrix_transform.pre_collision_symbols for moment_symbol in cm_symbols: rhs_matrix = f_to_k_matrix[moment_symbol].expand() rhs_fast = f_to_k_fast[moment_symbol].expand() rhs_shift = f_to_k_shift[moment_symbol].expand() assert ( rhs_matrix - rhs_fast ) == 0, f"Mismatch between matrix and fast transform at {moment_symbol}." assert ( rhs_matrix - rhs_shift ) == 0, f"Mismatch between matrix and shift-matrix transform at {moment_symbol}."
def test_relaxation_rate(): lbm_config = LBMConfig(stencil=LBStencil(Stencil.D3Q19), method=Method.MRT_RAW, relaxation_rates=[1 + i / 10 for i in range(19)]) method = create_lb_method(lbm_config=lbm_config) with pytest.raises(ValueError) as e: get_shear_relaxation_rate(method) assert 'Shear moments are relaxed with different relaxation' in str(e.value) omegas = sp.symbols("omega_:4") lbm_config = LBMConfig(stencil=LBStencil(Stencil.D3Q19), method=Method.MRT, relaxation_rates=omegas) method = create_lb_method(lbm_config=lbm_config) assert get_shear_relaxation_rate(method) == omegas[0]
def get_all_stencils(): return [ LBStencil(Stencil.D2Q9, 'walberla'), LBStencil(Stencil.D3Q15, 'walberla'), LBStencil(Stencil.D3Q19, 'walberla'), LBStencil(Stencil.D3Q27, 'walberla'), LBStencil(Stencil.D2Q9, 'counterclockwise'), LBStencil(Stencil.D2Q9, 'braunschweig'), LBStencil(Stencil.D3Q19, 'braunschweig'), LBStencil(Stencil.D3Q27, 'premnath'), LBStencil(Stencil.D3Q27, "fakhari"), ]
def test_cumulants_from_pdfs(): """ Tests if the following transformations are equivalent: - directly pdfs to cumulant - indirect pdfs -> raw moments -> cumulants """ stencil = LBStencil(Stencil.D2Q9) indices = moments_up_to_component_order(2, dim=stencil.D) pdf_symbols = sp.symbols(f"f_:{stencil.Q}") direct_version = cumulants_from_pdfs(stencil, pdf_symbols=pdf_symbols, cumulant_indices=indices) polynomial_moment_indices = exponents_to_polynomial_representations( indices) direct_version2 = cumulants_from_pdfs( stencil, pdf_symbols=pdf_symbols, cumulant_indices=polynomial_moment_indices) for idx, value in direct_version.items(): poly = exponent_to_polynomial_representation(idx) assert direct_version2[poly] == value moment_dict = { idx: discrete_moment(pdf_symbols, idx, stencil) for idx in indices } indirect_version = { idx: cumulant_as_function_of_raw_moments(idx, moment_dict) for idx in indices } for idx in indices: assert sp.simplify(direct_version[idx] - indirect_version[idx]) == 0
def test_stream_only_kernel(streaming_pattern): domain_size = (4, 4) stencil = LBStencil(Stencil.D2Q9) dh = ps.create_data_handling(domain_size, default_target=Target.CPU) pdfs = dh.add_array('pdfs', values_per_cell=len(stencil)) pdfs_tmp = dh.add_array_like('pdfs_tmp', 'pdfs') for t in get_timesteps(streaming_pattern): accessor = get_accessor(streaming_pattern, t) src = pdfs dst = pdfs if is_inplace(streaming_pattern) else pdfs_tmp dh.fill(src.name, 0.0) dh.fill(dst.name, 0.0) stream_kernel = create_stream_only_kernel(stencil, src, dst, accessor=accessor) stream_func = create_kernel(stream_kernel).compile() # Check functionality acc_in = AccessPdfValues(stencil, streaming_dir='in', accessor=accessor) for i in range(len(stencil)): acc_in.write_pdf(dh.cpu_arrays[src.name], (1,1), i, i) dh.run_kernel(stream_func) acc_out = AccessPdfValues(stencil, streaming_dir='out', accessor=accessor) for i in range(len(stencil)): assert acc_out.read_pdf(dh.cpu_arrays[dst.name], (1,1), i) == i
def test_contact_angle(): stencil = LBStencil(Stencil.D2Q9) contact_angle = 45 phase_value = 0.5 domain_size = (9, 9) dh = ps.create_data_handling(domain_size, periodicity=(False, False)) C = dh.add_array("C", values_per_cell=1) dh.fill("C", 0.0, ghost_layers=True) dh.fill("C", phase_value, ghost_layers=False) bh = BoundaryHandling(dh, C.name, stencil, target=ps.Target.CPU) bh.set_boundary(ContactAngle(45, 5), ps.make_slice[:, 0]) bh() h = 1.0 myA = 1.0 - 0.5 * h * (4.0 / 5) * math.cos(math.radians(contact_angle)) phase_on_boundary = (myA - np.sqrt(myA * myA - 4.0 * (myA - 1.0) * phase_value)) / (myA - 1.0) - phase_value np.testing.assert_almost_equal(dh.cpu_arrays["C"][5, 0], phase_on_boundary) assert ContactAngle(45, 5) == ContactAngle(45, 5) assert ContactAngle(46, 5) != ContactAngle(45, 5)
def test_equivalence_short(setup): relaxation_rates = [1.8, 1.7, 1.0, 1.0, 1.0, 1.0] stencil = LBStencil(setup[0]) compressible = setup[1] method = setup[2] force = (setup[3], 0) if stencil.D == 2 else (setup[3], 0, 0) domain_size = (20, 30) if stencil.D == 2 else (10, 13, 7) lbm_config = LBMConfig(stencil=stencil, method=method, compressible=compressible, relaxation_rates=relaxation_rates, force_model=ForceModel.GUO, force=force) lbm_opt_split = LBMOptimisation(split=True) lbm_opt = LBMOptimisation(split=False) with_split = create_lid_driven_cavity(domain_size=domain_size, lbm_config=lbm_config, lbm_optimisation=lbm_opt_split) without_split = create_lid_driven_cavity(domain_size=domain_size, lbm_config=lbm_config, lbm_optimisation=lbm_opt) with_split.run(100) without_split.run(100) np.testing.assert_almost_equal(with_split.velocity_slice(), without_split.velocity_slice())
def test_equilibrium_pdfs(stencil_name, cm_transform): stencil = LBStencil(stencil_name) lbm_config = LBMConfig(stencil=stencil, method=Method.CUMULANT, central_moment_transform_class=cm_transform) c_lb_method = create_lb_method(lbm_config=lbm_config) rho = c_lb_method.zeroth_order_equilibrium_moment_symbol u = c_lb_method.first_order_equilibrium_moment_symbols pdfs = c_lb_method.post_collision_pdf_symbols cqe_assignments = [Assignment(sym, sym) for sym in u] + [Assignment(rho, rho)] cqe = AssignmentCollection(main_assignments=cqe_assignments) method_equilibrium_eqs = c_lb_method.get_equilibrium( cqe, False, False).main_assignments_dict # Reference Equations ref_equilibrium = reference_equilibria.get(stencil_name, None) if ref_equilibrium is None: raw_moments = list( extract_monomials(c_lb_method.cumulants, dim=stencil.D)) ref_equilibrium = generate_equilibrium_by_matching_moments( stencil, tuple(raw_moments), rho=rho, u=u, c_s_sq=sp.Rational(1, 3), order=2 * stencil.D) reference_equilibria[stencil_name] = ref_equilibrium for i in range(stencil.Q): method_eq = method_equilibrium_eqs[pdfs[i]] ref_eq = ref_equilibrium[i] assert method_eq.expand() - ref_eq.expand() == sp.sympify(0), \ f"Equilibrium equation for pdf index {i} did not match."
def test_set_get_constant_velocity(stencil, force_model, compressible): ref_velocity = [0.01, -0.2, 0.1] force = (0.1, 0.12, -0.17) stencil = LBStencil(stencil) lbm_config = LBMConfig(stencil=stencil, force_model=force_model, method=Method.TRT, compressible=compressible, force=force) method = create_lb_method(lbm_config=lbm_config) size = (1, 1, 1)[:method.dim] pdf_arr = np.zeros(size + (len(method.stencil),)) setter = compile_macroscopic_values_setter(method, pdf_arr=pdf_arr, ghost_layers=0, quantities_to_set={'velocity': ref_velocity[:method.dim]}, ) setter(pdf_arr) getter = compile_macroscopic_values_getter(method, ['velocity'], pdf_arr=pdf_arr, ghost_layers=0) velocity_output_field = np.zeros(size + (method.dim, )) getter(pdfs=pdf_arr, velocity=velocity_output_field) if method.dim == 2: computed_velocity = velocity_output_field[0, 0, :] else: computed_velocity = velocity_output_field[0, 0, 0, :] np.testing.assert_almost_equal(np.array(ref_velocity[:method.dim]), computed_velocity)
def test_set_get_density_velocity_with_fields(stencil, force_model, compressible, streaming_pattern, prev_timestep): force = (0.1, 0.12, -0.17) stencil = LBStencil(stencil) lbm_config = LBMConfig(stencil=stencil, force_model=force_model, method=Method.TRT, compressible=compressible, force=force) method = create_lb_method(lbm_config=lbm_config) ghost_layers = 1 inner_size = (3, 7, 4)[:method.dim] total_size = tuple(s + 2 * ghost_layers for s in inner_size) pdf_arr = np.zeros(total_size + (len(method.stencil),)) inner_slice = (slice(ghost_layers, -ghost_layers, 1), ) * method.dim density_input_field = np.zeros(total_size) velocity_input_field = np.zeros(total_size + (method.dim, )) density_input_field[inner_slice] = 1 + 0.2 * (np.random.random_sample(inner_size) - 0.5) velocity_input_field[inner_slice] = 0.1 * \ (np.random.random_sample(inner_size + (method.dim, )) - 0.5) quantities_to_set = {'density': density_input_field, 'velocity': velocity_input_field} setter = compile_macroscopic_values_setter(method, pdf_arr=pdf_arr, quantities_to_set=quantities_to_set, ghost_layers=ghost_layers, streaming_pattern=streaming_pattern, previous_timestep=prev_timestep) setter(pdf_arr) getter = compile_macroscopic_values_getter(method, ['density', 'velocity'], pdf_arr=pdf_arr, ghost_layers=ghost_layers, streaming_pattern=streaming_pattern, previous_timestep=prev_timestep) density_output_field = np.zeros_like(density_input_field) velocity_output_field = np.zeros_like(velocity_input_field) getter(pdfs=pdf_arr, density=density_output_field, velocity=velocity_output_field) np.testing.assert_almost_equal(density_input_field, density_output_field) np.testing.assert_almost_equal(velocity_input_field, velocity_output_field)
def test_free_slip_equivalence(): # check if Free slip BC does the same if the normal direction is specified or not stencil = LBStencil(Stencil.D2Q9) dh = create_data_handling(domain_size=(4, 4), periodicity=(False, False)) src1 = dh.add_array('src1', values_per_cell=stencil.Q, alignment=True) src2 = dh.add_array('src2', values_per_cell=stencil.Q, alignment=True) dh.fill('src1', 0.0, ghost_layers=True) dh.fill('src2', 0.0, ghost_layers=True) shape = dh.gather_array('src1', ghost_layers=True).shape num = 0 for x in range(shape[0]): for y in range(shape[1]): for direction in range(shape[2]): dh.cpu_arrays['src1'][x, y, direction] = num dh.cpu_arrays['src2'][x, y, direction] = num num += 1 method = create_lb_method(lbm_config=LBMConfig( stencil=stencil, method=Method.SRT, relaxation_rate=1.8)) bh1 = LatticeBoltzmannBoundaryHandling(method, dh, 'src1', name="bh1") free_slip1 = FreeSlip(stencil=stencil) bh1.set_boundary(free_slip1, slice_from_direction('N', dh.dim)) bh2 = LatticeBoltzmannBoundaryHandling(method, dh, 'src2', name="bh2") free_slip2 = FreeSlip(stencil=stencil, normal_direction=(0, -1)) bh2.set_boundary(free_slip2, slice_from_direction('N', dh.dim)) bh1() bh2() assert np.array_equal(dh.cpu_arrays['src1'], dh.cpu_arrays['src2'])
def test_optimised_and_full_communication_equivalence(stencil_name): target = ps.Target.CPU stencil = LBStencil(stencil_name) domain_size = (4, ) * stencil.D dh = ps.create_data_handling(domain_size, periodicity=(True, ) * stencil.D, parallel=False, default_target=target) pdf = dh.add_array("pdf", values_per_cell=len(stencil), dtype=np.int64) dh.fill("pdf", 0, ghost_layers=True) pdf_tmp = dh.add_array("pdf_tmp", values_per_cell=len(stencil), dtype=np.int64) dh.fill("pdf_tmp", 0, ghost_layers=True) gl = dh.ghost_layers_of_field("pdf") num = 0 for idx, x in np.ndenumerate(dh.cpu_arrays['pdf']): dh.cpu_arrays['pdf'][idx] = num dh.cpu_arrays['pdf_tmp'][idx] = num num += 1 lbm_config = LBMConfig(stencil=stencil, kernel_type="stream_pull_only") lbm_opt = LBMOptimisation(symbolic_field=pdf, symbolic_temporary_field=pdf_tmp) config = ps.CreateKernelConfig(target=dh.default_target, cpu_openmp=True) ac = create_lb_update_rule(lbm_config=lbm_config, lbm_optimisation=lbm_opt) ast = ps.create_kernel(ac, config=config) stream = ast.compile() full_communication = dh.synchronization_function(pdf.name, target=dh.default_target, optimization={"openmp": True}) full_communication() dh.run_kernel(stream) dh.swap("pdf", "pdf_tmp") pdf_full_communication = np.copy(dh.cpu_arrays['pdf']) num = 0 for idx, x in np.ndenumerate(dh.cpu_arrays['pdf']): dh.cpu_arrays['pdf'][idx] = num dh.cpu_arrays['pdf_tmp'][idx] = num num += 1 optimised_communication = LBMPeriodicityHandling(stencil=stencil, data_handling=dh, pdf_field_name=pdf.name, streaming_pattern='pull') optimised_communication() dh.run_kernel(stream) dh.swap("pdf", "pdf_tmp") if stencil.D == 3: for i in range(gl, domain_size[0]): for j in range(gl, domain_size[1]): for k in range(gl, domain_size[2]): for f in range(len(stencil)): assert dh.cpu_arrays['pdf'][i, j, k, f] == pdf_full_communication[i, j, k, f], print(f) else: for i in range(gl, domain_size[0]): for j in range(gl, domain_size[1]): for f in range(len(stencil)): assert dh.cpu_arrays['pdf'][i, j, f] == pdf_full_communication[i, j, f]
def test_free_functions(): assert not ps.stencil.is_symmetric([(1, 0), (0, 1)]) assert not ps.stencil.is_valid([(1, 0), (1, 1, 0)]) assert not ps.stencil.is_valid([(2, 0), (0, 1)], max_neighborhood=1) with pytest.raises(ValueError) as e: LBStencil("name_that_does_not_exist") assert "No such stencil" in str(e.value)
def test_simplifications_srt_d2q9_compressible(): omega = sp.symbols('omega') method = create_srt(LBStencil(Stencil.D2Q9), omega, compressible=True, equilibrium_order=2, moment_transform_class=None) check_method(method, [53, 58, 1], [53, 42, 1])
def test_gram_schmidt_orthogonalization(): moments = moments_up_to_component_order(2, 2) assert len(moments) == 9 stencil = LBStencil(Stencil.D2Q9) orthogonal_moments = gram_schmidt(moments, stencil) pdfs_to_moments = moment_matrix(orthogonal_moments, stencil) assert (pdfs_to_moments * pdfs_to_moments.T).is_diagonal()
def test_weights(stencil_name): stencil = LBStencil(stencil_name) cumulant_method = create_with_default_polynomial_cumulants(stencil, [1]) moment_method = create_srt(stencil, 1, compressible=True, maxwellian_moments=True) assert cumulant_method.weights == moment_method.weights
def test_hydro_lb(): stencil_hydro = LBStencil(Stencil.D3Q27) density_liquid = 1.0 density_gas = 0.001 surface_tension = 0.0001 W = 5 # phase-field parameter drho3 = (density_liquid - density_gas) / 3 # coefficient related to surface tension beta = 12.0 * (surface_tension / W) # coefficient related to surface tension kappa = 1.5 * surface_tension * W u = fields("vel_field(" + str(stencil_hydro.D) + "): [" + str(stencil_hydro.D) + "D]", layout='fzyx') C = fields("phase_field: [" + str(stencil_hydro.D) + "D]", layout='fzyx') g = fields("lb_velocity_field(" + str(stencil_hydro.Q) + "): [" + str(stencil_hydro.D) + "D]", layout='fzyx') g_tmp = fields("lb_velocity_field_tmp(" + str(stencil_hydro.Q) + "): [" + str(stencil_hydro.D) + "D]", layout='fzyx') # calculate the relaxation rate for the hydro lb as well as the body force density = density_gas + C.center * (density_liquid - density_gas) # force acting on all phases of the model body_force = [0, 0, 0] relaxation_time = 0.03 + 0.5 relaxation_rate = 1.0 / relaxation_time lbm_config = LBMConfig(stencil=stencil_hydro, method=Method.MRT, weighted=True, relaxation_rates=[relaxation_rate, 1, 1, 1, 1, 1]) method_hydro = create_lb_method(lbm_config=lbm_config) # create the kernels for the initialization of the g and h field g_updates = initializer_kernel_hydro_lb(g, u, method_hydro) force_g = hydrodynamic_force(g, C, method_hydro, relaxation_time, density_liquid, density_gas, kappa, beta, body_force) force_model_g = MultiphaseForceModel(force=force_g, rho=density) hydro_lb_update_rule_normal = get_collision_assignments_hydro(lb_method=method_hydro, density=density, velocity_input=u, force_model=force_model_g, sub_iterations=2, symbolic_fields={"symbolic_field": g, "symbolic_temporary_field": g_tmp}, kernel_type='collide_only') hydro_lb_update_rule_push = get_collision_assignments_hydro(lb_method=method_hydro, density=density, velocity_input=u, force_model=force_model_g, sub_iterations=2, symbolic_fields={"symbolic_field": g, "symbolic_temporary_field": g_tmp}, kernel_type='collide_stream_push')
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 compare_weights(method, maxwellian_moments, stencil_name): stencil = LBStencil(stencil_name) hardcoded_weights = get_weights(stencil) method = create_lb_method(LBMConfig(stencil=stencil, method=method, maxwellian_moments=maxwellian_moments)) weights = method.weights for i in range(len(weights)): assert hardcoded_weights[i] == weights[i]
def test_slices_not_empty(stencil, streaming_pattern, timestep): stencil = LBStencil(stencil) arr = np.zeros((4,) * stencil.D + (stencil.Q,)) slices = get_communication_slices(stencil, streaming_pattern=streaming_pattern, prev_timestep=timestep, ghost_layers=1) for _, slices_list in slices.items(): for src, dst in slices_list: assert all(s != 0 for s in arr[src].shape) assert all(s != 0 for s in arr[dst].shape)
def test_moment_transform_equivalences(stencil, monomials): stencil = LBStencil(stencil) pdfs = sp.symbols(f"f_:{stencil.Q}") rho = sp.Symbol('rho') u = sp.symbols(f"u_:{stencil.D}") moment_polynomials = get_default_moment_set_for_stencil(stencil) if monomials: polys_nonaliased = non_aliased_polynomial_raw_moments( moment_polynomials, stencil) moment_exponents = sorted(extract_monomials(polys_nonaliased), key=exponent_tuple_sort_key) moment_polynomials = None else: moment_exponents = None matrix_transform = PdfsToMomentsByMatrixTransform( stencil, moment_polynomials, rho, u, moment_exponents=moment_exponents) chimera_transform = PdfsToMomentsByChimeraTransform( stencil, moment_polynomials, rho, u, moment_exponents=moment_exponents) f_to_m_matrix = matrix_transform.forward_transform( pdfs, return_monomials=monomials) f_to_m_matrix = f_to_m_matrix.new_without_subexpressions( ).main_assignments_dict f_to_m_chimera = chimera_transform.forward_transform( pdfs, return_monomials=monomials) f_to_m_chimera = f_to_m_chimera.new_without_subexpressions( ).main_assignments_dict m_to_f_matrix = matrix_transform.backward_transform( pdfs, start_from_monomials=monomials) m_to_f_matrix = m_to_f_matrix.new_without_subexpressions( ).main_assignments_dict m_to_f_chimera = chimera_transform.backward_transform( pdfs, start_from_monomials=monomials) m_to_f_chimera = m_to_f_chimera.new_without_subexpressions( ).main_assignments_dict m_pre_matrix = matrix_transform.pre_collision_monomial_symbols if monomials else matrix_transform.pre_collision_symbols m_pre_chimera = chimera_transform.pre_collision_monomial_symbols if monomials else chimera_transform.pre_collision_symbols for m1, m2 in zip(m_pre_matrix, m_pre_chimera): rhs_matrix = f_to_m_matrix[m1] rhs_chimera = f_to_m_chimera[m2] diff = (rhs_matrix - rhs_chimera).expand() assert diff == 0, f"Mismatch between matrix and chimera forward transform at {m1}, {m2}." for f in pdfs: rhs_matrix = m_to_f_matrix[f] rhs_chimera = m_to_f_chimera[f] diff = (rhs_matrix - rhs_chimera).expand() assert diff == 0, f"Mismatch between matrix and chimera backward transform at {f}"
def test_src_dst_same_shape(stencil, streaming_pattern, timestep): stencil = LBStencil(stencil) arr = np.zeros((4,) * stencil.D + (stencil.Q,)) slices = get_communication_slices(stencil, streaming_pattern=streaming_pattern, prev_timestep=timestep, ghost_layers=1) for _, slices_list in slices.items(): for src, dst in slices_list: src_shape = arr[src].shape dst_shape = arr[dst].shape assert src_shape == dst_shape
def test_boundary_utility_functions(): stencil = LBStencil(Stencil.D2Q9) method = create_lb_method(lbm_config=LBMConfig(stencil=stencil)) noslip = NoSlip("noslip") assert noslip == NoSlip("noslip") assert not noslip == NoSlip("test") assert not noslip == UBB((0, 0), name="ubb") assert noslip.name == "noslip" noslip.name = "test name setter" assert noslip.name == "test name setter" ubb = UBB((0, 0), name="ubb") assert ubb == UBB((0, 0), name="ubb") assert not noslip == UBB((0, 0), name="test") assert not ubb == NoSlip("noslip") simple_extrapolation = SimpleExtrapolationOutflow( normal_direction=stencil[4], stencil=stencil, name="simple") assert simple_extrapolation == SimpleExtrapolationOutflow( normal_direction=stencil[4], stencil=stencil, name="simple") assert not simple_extrapolation == SimpleExtrapolationOutflow( normal_direction=stencil[4], stencil=stencil, name="test") assert not simple_extrapolation == NoSlip("noslip") outflow = ExtrapolationOutflow(normal_direction=stencil[4], lb_method=method, name="outflow") assert outflow == ExtrapolationOutflow(normal_direction=stencil[4], lb_method=method, name="outflow") assert not outflow == ExtrapolationOutflow( normal_direction=stencil[4], lb_method=method, name="test") assert not outflow == simple_extrapolation density = FixedDensity(density=1.0, name="fixedDensity") assert density == FixedDensity(density=1.0, name="fixedDensity") assert not density == FixedDensity(density=1.0, name="test") assert not density == UBB((0, 0), name="ubb") diffusion = DiffusionDirichlet(concentration=1.0, name="diffusion") assert diffusion == DiffusionDirichlet(concentration=1.0, name="diffusion") assert not diffusion == DiffusionDirichlet(concentration=1.0, name="test") assert not diffusion == density neumann = NeumannByCopy(name="Neumann") assert neumann == NeumannByCopy(name="Neumann") assert not neumann == NeumannByCopy(name="test") assert not neumann == diffusion stream = StreamInConstant(constant=1.0, name="stream") assert stream == StreamInConstant(constant=1.0, name="stream") assert not stream == StreamInConstant(constant=1.0, name="test") assert not stream == noslip
def test_advanced_streaming_noslip_single_cell(stencil, streaming_pattern, prev_timestep): """ Advanced Streaming NoSlip Test """ stencil = LBStencil(stencil) pdf_field = ps.fields(f'pdfs({stencil.Q}): [{stencil.D}D]') prev_pdf_access = AccessPdfValues(stencil, streaming_pattern, prev_timestep, 'out') next_pdf_access = AccessPdfValues(stencil, streaming_pattern, prev_timestep.next(), 'in') pdfs = np.zeros((3, ) * stencil.D + (stencil.Q, )) pos = (1, ) * stencil.D for d in range(stencil.Q): prev_pdf_access.write_pdf(pdfs, pos, d, d) lbm_config = LBMConfig(stencil=stencil, method=Method.SRT) lb_method = create_lb_method(lbm_config=lbm_config) noslip = NoSlip() index_struct_dtype = numpy_data_type_for_boundary_object(noslip, stencil.D) index_field = Field('indexVector', FieldType.INDEXED, index_struct_dtype, layout=[0], shape=(TypedSymbol("indexVectorSize", create_type(np.int64)), 1), strides=(1, 1)) index_vector = np.array([pos + (d, ) for d in range(stencil.Q)], dtype=index_struct_dtype) ast = create_lattice_boltzmann_boundary_kernel( pdf_field, index_field, lb_method, noslip, prev_timestep=prev_timestep, streaming_pattern=streaming_pattern) flex_kernel = ast.compile() flex_kernel(pdfs=pdfs, indexVector=index_vector, indexVectorSize=len(index_vector)) reflected_pdfs = [ next_pdf_access.read_pdf(pdfs, pos, d) for d in range(stencil.Q) ] inverse_pdfs = [inverse_dir_index(stencil, d) for d in range(stencil.Q)] assert reflected_pdfs == inverse_pdfs
def test_trt(stencil_name, continuous_moments): stencil = LBStencil(stencil_name) original_method = create_trt(stencil, sp.Symbol("omega1"), sp.Symbol("omega2"), maxwellian_moments=continuous_moments) changed_method = __change_relaxation_rate_of_conserved_moments( original_method) check_method_equivalence(original_method, changed_method, True) check_method_equivalence(original_method, changed_method, False)
def test_simplifications_trt_d3q19_force_compressible(): o1, o2 = sp.symbols("omega_1 omega_2") force_model = Luo( [sp.Rational(1, 3), sp.Rational(1, 2), sp.Rational(1, 5)]) method = create_trt_with_magic_number(LBStencil(Stencil.D3Q19), o1, compressible=False, force_model=force_model) check_method(method, [270, 284, 1], [243, 178, 1])