예제 #1
0
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]
예제 #2
0
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)
예제 #3
0
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."
예제 #4
0
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())
예제 #5
0
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'])
예제 #6
0
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)
예제 #7
0
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]
예제 #8
0
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')
예제 #9
0
파일: test_weights.py 프로젝트: mabau/lbmpy
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]
예제 #10
0
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
예제 #11
0
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
예제 #12
0
def test_moment_comparison_table():
    pytest.importorskip('ipy_table')

    lbm_config_new = LBMConfig(stencil=LBStencil(Stencil.D3Q19), maxwellian_moments=True)
    lbm_config_old = LBMConfig(stencil=LBStencil(Stencil.D3Q19), maxwellian_moments=False)

    new = create_lb_method(lbm_config=lbm_config_new)
    old = create_lb_method(lbm_config=lbm_config_old)

    assert old.zeroth_order_equilibrium_moment_symbol == new.zeroth_order_equilibrium_moment_symbol

    assert '<td' in new._repr_html_()

    res_deviations_only = compare_moment_based_lb_methods(old, new, show_deviations_only=True)
    assert len(res_deviations_only.array) == 4

    res_all = compare_moment_based_lb_methods(old, new, show_deviations_only=False)
    assert len(res_all.array) == 20

    d3q27 = create_lb_method(LBMConfig(stencil=LBStencil(Stencil.D3Q27)))
    compare_moment_based_lb_methods(d3q27, new, show_deviations_only=False)
    compare_moment_based_lb_methods(new, d3q27, show_deviations_only=False)
예제 #13
0
def test_population_and_moment_space_equivalence(setup):
    stencil = LBStencil(setup[0])
    method = setup[1]
    nested_moments = setup[2]
    fmodel = setup[3]
    force = sp.symbols(f'F_:{stencil.D}')
    conserved_moments = 1 + stencil.D

    rr = [
        *[0] * conserved_moments,
        *sp.symbols(f'omega_:{stencil.Q - conserved_moments}')
    ]
    lbm_config = LBMConfig(
        stencil=stencil,
        method=method,
        relaxation_rates=rr,
        nested_moments=nested_moments,
        force_model=fmodel,
        force=force,
        weighted=True,
        compressible=True,
        moment_transform_class=PdfsToMomentsByChimeraTransform)

    lbm_opt = LBMOptimisation(cse_global=False,
                              cse_pdfs=False,
                              pre_simplification=True,
                              simplification=False)

    lb_method_moment_space = create_lb_method(lbm_config=lbm_config)

    lbm_config = replace(lbm_config, moment_transform_class=None)
    lb_method_pdf_space = create_lb_method(lbm_config=lbm_config)

    rho = lb_method_moment_space.zeroth_order_equilibrium_moment_symbol
    u = lb_method_moment_space.first_order_equilibrium_moment_symbols
    keep = set((rho, ) + u)
    cr_moment_space = create_lb_collision_rule(
        lb_method=lb_method_moment_space, lbm_optimisation=lbm_opt)
    cr_moment_space = cr_moment_space.new_without_subexpressions(
        subexpressions_to_keep=keep)

    lbm_opt = replace(lbm_opt, simplification='auto')
    cr_pdf_space = create_lb_collision_rule(lb_method=lb_method_pdf_space,
                                            lbm_optimisation=lbm_opt)
    cr_pdf_space = cr_pdf_space.new_without_subexpressions(
        subexpressions_to_keep=keep)

    for a, b in zip(cr_moment_space.main_assignments,
                    cr_pdf_space.main_assignments):
        diff = (a.rhs - b.rhs).expand()
        assert diff == 0, f"Mismatch between population- and moment-space equations in PDFs {a.lhs}, {b.lhs}"
예제 #14
0
def test_creation(method_enum, double_precision):
    """Simple test that makes sure that only float variables are created"""
    lbm_config = LBMConfig(method=method_enum, relaxation_rate=1.5)
    config = ps.CreateKernelConfig(
        data_type="float64" if double_precision else "float32")
    func = create_lb_function(lbm_config=lbm_config, config=config)
    code = ps.get_code_str(func)

    if double_precision:
        assert 'float' not in code
        assert 'double' in code
    else:
        assert 'double' not in code
        assert 'float' in code
def test_relaxation_rate_setter():
    o1, o2, o3 = sp.symbols("o1 o2 o3")

    lbm_config_1 = LBMConfig(method=Method.SRT,
                             stencil=LBStencil(Stencil.D2Q9),
                             relaxation_rates=[o3])
    lbm_config_2 = LBMConfig(method=Method.MRT,
                             stencil=LBStencil(Stencil.D2Q9),
                             relaxation_rates=[o3, o3, o3, o3])
    lbm_config_3 = LBMConfig(method=Method.MRT,
                             stencil=LBStencil(Stencil.D2Q9),
                             relaxation_rates=[o3] * 9,
                             entropic=True)

    method = create_lb_method(lbm_config=lbm_config_1)
    method2 = create_lb_method(lbm_config=lbm_config_2)
    method3 = create_lb_method(lbm_config=lbm_config_3)
    method.set_zeroth_moment_relaxation_rate(o1)
    method.set_first_moment_relaxation_rate(o2)
    assert get_shear_relaxation_rate(method) == o3
    method.set_zeroth_moment_relaxation_rate(o3)
    method.set_first_moment_relaxation_rate(o3)
    method2.set_conserved_moments_relaxation_rate(o3)
    assert method.collision_matrix == method2.collision_matrix == method3.collision_matrix
예제 #16
0
def test_scenario(method_enum, double_precision):
    lbm_config = LBMConfig(method=method_enum, relaxation_rate=1.5)
    config = ps.CreateKernelConfig(
        data_type="double" if double_precision else "float32")
    sc = create_lid_driven_cavity((16, 16, 8),
                                  lbm_config=lbm_config,
                                  config=config)
    sc.run(1)
    code = ps.get_code_str(sc.ast)

    if double_precision:
        assert 'float' not in code
        assert 'double' in code
    else:
        assert 'double' not in code
        assert 'float' in code
예제 #17
0
def test_lbm_vectorization(instruction_set, aligned_and_padding, nontemporal,
                           double_precision, fixed_loop_sizes):
    vectorization_options = {
        'instruction_set': instruction_set,
        'assume_aligned': aligned_and_padding[0],
        'nontemporal': nontemporal,
        'assume_inner_stride_one': True,
        'assume_sufficient_line_padding': aligned_and_padding[1]
    }
    time_steps = 100
    size1 = (64, 32)
    size2 = (666, 34)
    relaxation_rate = 1.8

    print("Computing reference solutions")
    ldc1_ref = create_lid_driven_cavity(size1, relaxation_rate=relaxation_rate)
    ldc1_ref.run(time_steps)
    ldc2_ref = create_lid_driven_cavity(size2, relaxation_rate=relaxation_rate)
    ldc2_ref.run(time_steps)

    lbm_config = LBMConfig(relaxation_rate=relaxation_rate)
    config = ps.CreateKernelConfig(
        data_type="double" if double_precision else "float32",
        cpu_vectorize_info=vectorization_options)
    lbm_opt_split = LBMOptimisation(cse_global=True, split=True)
    lbm_opt = LBMOptimisation(cse_global=True, split=False)

    print(
        f"Vectorization test, double precision {double_precision}, vectorization {vectorization_options}, "
        f"fixed loop sizes {fixed_loop_sizes}")
    ldc1 = create_lid_driven_cavity(size1,
                                    fixed_loop_sizes=fixed_loop_sizes,
                                    lbm_config=lbm_config,
                                    lbm_optimisation=lbm_opt,
                                    config=config)
    ldc1.run(time_steps)
    np.testing.assert_almost_equal(ldc1_ref.velocity[:, :],
                                   ldc1.velocity[:, :])

    ldc2 = create_lid_driven_cavity(size2,
                                    fixed_loop_sizes=fixed_loop_sizes,
                                    lbm_config=lbm_config,
                                    lbm_optimisation=lbm_opt_split,
                                    config=config)
    ldc2.run(time_steps)
    np.testing.assert_almost_equal(ldc2_ref.velocity[:, :],
                                   ldc2.velocity[:, :])
예제 #18
0
def test_gpu_block_size_limiting():
    pytest.importorskip("pycuda")
    too_large = 2048 * 2048
    lbm_config = LBMConfig(method=Method.CUMULANT,
                           stencil=LBStencil(Stencil.D3Q19),
                           relaxation_rate=1.8,
                           compressible=True)
    config = CreateKernelConfig(
        target=Target.GPU,
        gpu_indexing_params={'block_size': (too_large, too_large, too_large)})
    ast = create_lb_ast(lbm_config=lbm_config, config=config)
    limited_block_size = ast.indexing.call_parameters((1024, 1024, 1024))
    kernel = ast.compile()
    assert all(b < too_large for b in limited_block_size['block'])
    bs = [too_large, too_large, too_large]
    ast.indexing.limit_block_size_by_register_restriction(bs, kernel.num_regs)
    assert all(b < too_large for b in bs)
예제 #19
0
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
예제 #20
0
def test_simple_equilibrium_conservation(setup, method):
    if setup[0] == Target.GPU:
        pytest.importorskip("pycuda")
    src = np.zeros((3, 3, 9))
    dst = np.zeros_like(src)
    config = CreateKernelConfig(target=setup[0], backend=setup[1])
    lbm_config = LBMConfig(stencil=LBStencil(Stencil.D2Q9), method=method,
                           relaxation_rate=1.8, compressible=False)
    func = create_lb_function(lbm_config=lbm_config, config=config)

    if setup[0] == Target.GPU:
        import pycuda.gpuarray as gpuarray
        gpu_src, gpu_dst = gpuarray.to_gpu(src), gpuarray.to_gpu(dst)
        func(src=gpu_src, dst=gpu_dst)
        gpu_src.get(src)
        gpu_dst.get(dst)
    else:
        func(src=src, dst=dst)

    np.testing.assert_allclose(np.sum(np.abs(dst)), 0.0, atol=1e-13)
예제 #21
0
def test_momentum_density_shift(force_model):
    target = Target.CPU

    stencil = LBStencil(Stencil.D2Q9)
    domain_size = (4, 4)
    dh = ps.create_data_handling(domain_size=domain_size,
                                 default_target=target)

    rho = dh.add_array('rho', values_per_cell=1)
    dh.fill('rho', 0.0, ghost_layers=True)

    momentum_density = dh.add_array('momentum_density', values_per_cell=dh.dim)
    dh.fill('momentum_density', 0.0, ghost_layers=True)

    src = dh.add_array('src', values_per_cell=len(stencil))
    dh.fill('src', 0.0, ghost_layers=True)

    lbm_config = LBMConfig(method=Method.SRT,
                           compressible=True,
                           force_model=force_model,
                           force=(1, 2))
    method = create_lb_method(lbm_config=lbm_config)

    cqc = method.conserved_quantity_computation

    momentum_density_getter = cqc.output_equations_from_pdfs(
        src.center_vector, {
            'density': rho.center,
            'momentum_density': momentum_density.center_vector
        })

    config = ps.CreateKernelConfig(target=dh.default_target)
    momentum_density_ast = ps.create_kernel(momentum_density_getter,
                                            config=config)
    momentum_density_kernel = momentum_density_ast.compile()

    dh.run_kernel(momentum_density_kernel)
    assert np.sum(dh.gather_array(
        momentum_density.name)[:, :, 0]) == np.prod(domain_size) / 2
    assert np.sum(dh.gather_array(
        momentum_density.name)[:, :, 1]) == np.prod(domain_size)
예제 #22
0
def test_split_number_of_operations(stencil, compressible, method):
    # For the following configurations the number of operations for splitted and un-splitted version are
    # exactly equal. This is not true for D3Q15 and D3Q27 because some sub-expressions are computed in multiple
    # splitted, inner loops.
    lbm_config = LBMConfig(stencil=LBStencil(stencil),
                           method=method,
                           compressible=compressible,
                           force_model=ForceModel.LUO,
                           force=(1e-6, 1e-5, 1e-7))
    lbm_opt_split = LBMOptimisation(split=True)
    lbm_opt = LBMOptimisation(split=False)

    ast_with_splitting = create_lb_ast(lbm_config=lbm_config,
                                       lbm_optimisation=lbm_opt_split)
    ast_without_splitting = create_lb_ast(lbm_config=lbm_config,
                                          lbm_optimisation=lbm_opt)

    op_with_splitting = count_operations_in_ast(ast_with_splitting)
    op_without_splitting = count_operations_in_ast(ast_without_splitting)
    assert op_without_splitting['muls'] == op_with_splitting['muls']
    assert op_without_splitting['adds'] == op_with_splitting['adds']
    assert op_without_splitting['divs'] == op_with_splitting['divs']
예제 #23
0
def test_allen_cahn_lb():
    stencil_phase = LBStencil(Stencil.D3Q15)
    # fields
    u = fields("vel_field(" + str(stencil_phase.D) + "): [" + str(stencil_phase.D) + "D]", layout='fzyx')
    C = fields("phase_field: [" + str(stencil_phase.D) + "D]", layout='fzyx')
    C_tmp = fields("phase_field_tmp: [" + str(stencil_phase.D) + "D]", layout='fzyx')

    h = fields("lb_phase_field(" + str(len(stencil_phase)) + "): [" + str(stencil_phase.D) + "D]", layout='fzyx')
    h_tmp = fields("lb_phase_field_tmp(" + str(len(stencil_phase)) + "): [" + str(stencil_phase.D) + "D]", layout='fzyx')

    M = 0.02
    W = 5
    w_c = 1.0 / (0.5 + (3.0 * M))

    lbm_config = LBMConfig(stencil=stencil_phase, method=Method.SRT,
                           relaxation_rate=w_c, compressible=True)

    method_phase = create_lb_method(lbm_config=lbm_config)

    h_updates = initializer_kernel_phase_field_lb(h, C, u, method_phase, W)

    force_h = [f / 3 for f in interface_tracking_force(C, stencil_phase, W)]
    force_model_h = MultiphaseForceModel(force=force_h)

    allen_cahn_lb = get_collision_assignments_phase(lb_method=method_phase,
                                                    velocity_input=u,
                                                    output={'density': C_tmp},
                                                    force_model=force_model_h,
                                                    symbolic_fields={"symbolic_field": h,
                                                                     "symbolic_temporary_field": h_tmp},
                                                    kernel_type='stream_pull_collide')

    allen_cahn_lb = get_collision_assignments_phase(lb_method=method_phase,
                                                    velocity_input=u,
                                                    output={'density': C_tmp},
                                                    force_model=force_model_h,
                                                    symbolic_fields={"symbolic_field": h,
                                                                     "symbolic_temporary_field": h_tmp},
                                                    kernel_type='collide_only')
예제 #24
0
def test_lbm_vectorization_short():
    print("Computing reference solutions")
    size1 = (64, 32)
    relaxation_rate = 1.8

    ldc1_ref = create_lid_driven_cavity(size1, relaxation_rate=relaxation_rate)
    ldc1_ref.run(10)

    lbm_config = LBMConfig(relaxation_rate=relaxation_rate)
    config = ps.CreateKernelConfig(
        cpu_vectorize_info={
            'instruction_set': get_supported_instruction_sets()[-1],
            'assume_aligned': True,
            'nontemporal': True,
            'assume_inner_stride_one': True,
            'assume_sufficient_line_padding': False,
        })
    ldc1 = create_lid_driven_cavity(size1,
                                    lbm_config=lbm_config,
                                    config=config,
                                    fixed_loop_sizes=False)
    ldc1.run(10)
예제 #25
0
def test_forcing_space_equivalences(force_model):
    if force_model == ForceModel.HE:
        #   We don't expect equivalence for the He model since its
        #   moments are derived from the continuous maxwellian
        return
    stencil = LBStencil(Stencil.D3Q27)
    force = sp.symbols(f"F_:{stencil.D}")
    lbm_config = LBMConfig(stencil=stencil,
                           method=Method.SRT,
                           force=force,
                           force_model=force_model)
    fmodel = lbm_config.force_model

    lb_method = create_lb_method(lbm_config=lbm_config)
    inv_moment_matrix = lb_method.moment_matrix.inv()

    force_pdfs = sp.Matrix(fmodel(lb_method))
    force_moments = fmodel.moment_space_forcing(lb_method)

    diff = (force_pdfs - (inv_moment_matrix * force_moments)).expand()
    for i, d in enumerate(diff):
        assert d == 0, f"Mismatch between population and moment space forcing " \
                       f"in force model {force_model}, population f_{i}"
예제 #26
0
def test_modes_central_moment_longrun(stencil, force_model, compressible):
    """check force terms in mode space"""
    stencil = LBStencil(stencil)
    omega_s = sp.Symbol("omega_s")
    F = list(sp.symbols(f"F_:{stencil.D}"))

    lbm_config = LBMConfig(method=Method.CENTRAL_MOMENT,
                           stencil=stencil,
                           relaxation_rate=omega_s,
                           compressible=compressible,
                           force_model=force_model,
                           force=tuple(F))
    method = create_lb_method(lbm_config=lbm_config)

    subs_dict = method.subs_dict_relxation_rate
    force_moments = method.force_model.moment_space_forcing(method)
    force_moments = force_moments.subs(subs_dict)

    # The mass mode should be zero
    assert force_moments[0] == 0

    # The momentum moments should contain the force
    assert list(force_moments[1:stencil.D + 1]) == F
예제 #27
0
def test_create_cumulant_method_from_existing():
    lbm_config = LBMConfig(stencil=LBStencil(Stencil.D2Q9),
                           method=Method.CUMULANT,
                           relaxation_rate=1.5)
    method = create_lb_method(lbm_config=lbm_config)
    old_relaxation_info_dict = method.relaxation_info_dict

    def modification_func(cumulant, eq, rate):
        if rate == 0:
            return cumulant, eq, 1.0
        return cumulant, eq, rate

    new_method = create_lb_method_from_existing(method, modification_func)
    new_relaxation_info_dict = new_method.relaxation_info_dict

    for i, (o, n) in enumerate(
            zip(old_relaxation_info_dict.items(),
                new_relaxation_info_dict.items())):
        assert o[0] == n[0]
        assert o[1].equilibrium_value == n[1].equilibrium_value
        if o[1].relaxation_rate == 0:
            assert n[1].relaxation_rate == 1.0
        else:
            assert o[1].relaxation_rate == n[1].relaxation_rate
예제 #28
0
def test_force_driven_channel_short(scenario):
    pytest.importorskip("pycuda")
    ds = scenario[0]
    method = scenario[1]
    compressible = scenario[2]
    block_size = scenario[3]
    field_layout = scenario[4]

    lbm_config = LBMConfig(method=method,
                           compressible=compressible,
                           relaxation_rates=[1.95, 1.9, 1.92, 1.92])
    lbm_opt = LBMOptimisation(field_layout=field_layout)

    # Different methods
    if block_size is not False:
        config = CreateKernelConfig(
            gpu_indexing_params={'block_size': block_size})
    else:
        config = CreateKernelConfig(gpu_indexing='line')

    run_equivalence_test(domain_size=ds,
                         lbm_config=lbm_config,
                         lbm_opt=lbm_opt,
                         config=config)
예제 #29
0
def test_simple(target):
    if target == Target.GPU:
        import pytest
        pytest.importorskip('pycuda')

    dh = create_data_handling((4, 4), parallel=False, default_target=target)
    dh.add_array('pdfs', values_per_cell=9, cpu=True, gpu=target != Target.CPU)
    for i in range(9):
        dh.fill("pdfs", i, value_idx=i, ghost_layers=True)

    if target == Target.GPU:
        dh.all_to_gpu()

    lbm_config = LBMConfig(stencil=LBStencil(Stencil.D2Q9),
                           compressible=False,
                           relaxation_rate=1.8)
    config = CreateKernelConfig(target=target)

    lb_func = create_lb_function(lbm_config=lbm_config, config=config)

    bh = LatticeBoltzmannBoundaryHandling(lb_func.method,
                                          dh,
                                          'pdfs',
                                          target=target)

    wall = NoSlip()
    moving_wall = UBB((1, 0))
    bh.set_boundary(wall, make_slice[0, :])
    bh.set_boundary(wall, make_slice[-1, :])
    bh.set_boundary(wall, make_slice[:, 0])
    bh.set_boundary(moving_wall, make_slice[:, -1])

    bh.prepare()
    bh()

    if target == Target.GPU:
        dh.all_to_cpu()
    # left lower corner
    assert (dh.cpu_arrays['pdfs'][0, 0, 6] == 7)

    assert (dh.cpu_arrays['pdfs'][0, 1, 4] == 3)
    assert (dh.cpu_arrays['pdfs'][0, 1, 6] == 7)

    assert (dh.cpu_arrays['pdfs'][1, 0, 1] == 2)
    assert (dh.cpu_arrays['pdfs'][1, 0, 6] == 7)

    # left side
    assert (all(dh.cpu_arrays['pdfs'][0, 2:4, 4] == 3))
    assert (all(dh.cpu_arrays['pdfs'][0, 2:4, 6] == 7))
    assert (all(dh.cpu_arrays['pdfs'][0, 2:4, 5] == 5))

    # left upper corner
    assert (dh.cpu_arrays['pdfs'][0, 4, 4] == 3)
    assert (dh.cpu_arrays['pdfs'][0, 4, 8] == 5)

    assert (dh.cpu_arrays['pdfs'][0, 5, 8] == 5 + 6 / 36)

    assert (dh.cpu_arrays['pdfs'][1, 5, 8] == 5 + 6 / 36)
    assert (dh.cpu_arrays['pdfs'][1, 5, 2] == 1)

    # top side
    assert (all(dh.cpu_arrays['pdfs'][2:4, 5, 2] == 1))
    assert (all(dh.cpu_arrays['pdfs'][2:4, 5, 7] == 6 - 6 / 36))
    assert (all(dh.cpu_arrays['pdfs'][2:4, 5, 8] == 5 + 6 / 36))

    # right upper corner
    assert (dh.cpu_arrays['pdfs'][4, 5, 2] == 1)
    assert (dh.cpu_arrays['pdfs'][4, 5, 7] == 6 - 6 / 36)

    assert (dh.cpu_arrays['pdfs'][5, 5, 7] == 6 - 6 / 36)

    assert (dh.cpu_arrays['pdfs'][5, 4, 3] == 4)
    assert (dh.cpu_arrays['pdfs'][5, 4, 7] == 6)

    # right side
    assert (all(dh.cpu_arrays['pdfs'][5, 2:4, 3] == 4))
    assert (all(dh.cpu_arrays['pdfs'][5, 2:4, 5] == 8))
    assert (all(dh.cpu_arrays['pdfs'][5, 2:4, 7] == 6))

    # right lower corner
    assert (dh.cpu_arrays['pdfs'][5, 1, 3] == 4)
    assert (dh.cpu_arrays['pdfs'][5, 1, 5] == 8)

    assert (dh.cpu_arrays['pdfs'][5, 0, 5] == 8)

    assert (dh.cpu_arrays['pdfs'][4, 0, 1] == 2)
    assert (dh.cpu_arrays['pdfs'][4, 0, 5] == 8)

    # lower side
    assert (all(dh.cpu_arrays['pdfs'][0, 2:4, 4] == 3))
    assert (all(dh.cpu_arrays['pdfs'][0, 2:4, 6] == 7))
    assert (all(dh.cpu_arrays['pdfs'][0, 2:4, 8] == 5))
예제 #30
0
def test_free_slip_index_list():
    stencil = LBStencil(Stencil.D2Q9)
    dh = create_data_handling(domain_size=(4, 4), periodicity=(False, False))
    src = dh.add_array('src', values_per_cell=len(stencil), alignment=True)
    dh.fill('src', 0.0, ghost_layers=True)

    lbm_config = LBMConfig(stencil=stencil,
                           method=Method.SRT,
                           relaxation_rate=1.8)
    method = create_lb_method(lbm_config=lbm_config)

    bh = LatticeBoltzmannBoundaryHandling(method, dh, 'src', name="bh")

    free_slip = FreeSlip(stencil=stencil)
    add_box_boundary(bh, free_slip)

    bh.prepare()
    for b in dh.iterate():
        for b_obj, idx_arr in b[
                bh._index_array_name].boundary_object_to_index_list.items():
            index_array = idx_arr

    # normal directions
    normal_west = (1, 0)
    normal_east = (-1, 0)
    normal_south = (0, 1)
    normal_north = (0, -1)

    normal_south_west = (1, 1)
    normal_north_west = (1, -1)
    normal_south_east = (-1, 1)
    normal_north_east = (-1, -1)

    for cell in index_array:
        direction = stencil[cell[2]]
        inv_dir = inverse_direction(direction)

        boundary_cell = (cell[0] + direction[0], cell[1] + direction[1])
        normal = (cell[3], cell[4])
        # the data is written on the inverse direction of the fluid cell near the boundary
        # the data is read from the mirrored direction of the inverse direction where the mirror axis is the normal
        assert cell[5] == stencil.index(mirror_stencil(list(inv_dir), normal))

        if boundary_cell[0] == 0 and 0 < boundary_cell[1] < 5:
            assert normal == normal_west

        if boundary_cell[0] == 5 and 0 < boundary_cell[1] < 5:
            assert normal == normal_east

        if 0 < boundary_cell[0] < 5 and boundary_cell[1] == 0:
            assert normal == normal_south

        if 0 < boundary_cell[0] < 5 and boundary_cell[1] == 5:
            assert normal == normal_north

        if boundary_cell == (0, 0):
            assert cell[2] == cell[5]
            assert normal == normal_south_west

        if boundary_cell == (5, 0):
            assert cell[2] == cell[5]
            assert normal == normal_south_east

        if boundary_cell == (0, 5):
            assert cell[2] == cell[5]
            assert normal == normal_north_west

        if boundary_cell == (5, 5):
            assert cell[2] == cell[5]
            assert normal == normal_north_east