예제 #1
0
def test_pipe():
    """Ensures that pipe can be set up in 2D, 3D, with constant and callback diameter
    No tests are done that geometry is indeed correct"""

    def diameter_callback(x, domain_shape):
        d = domain_shape[1]
        y = np.ones_like(x) * d

        y[x > 0.5 * domain_shape[0]] = int(0.3 * d)
        return y

    plot = False
    for domain_size in [(30, 10, 10), (30, 10)]:
        for diameter in [5, 10, diameter_callback]:
            sc = LatticeBoltzmannStep(domain_size=domain_size, method=Method.SRT, relaxation_rate=1.9)
            add_pipe_walls(sc.boundary_handling, diameter)
            if plot:
                if len(domain_size) == 2:
                    plt.boundary_handling(sc.boundary_handling)
                    plt.title(f"2D, diameter={str(diameter,)}")
                    plt.show()
                elif len(domain_size) == 3:
                    plt.subplot(1, 2, 1)
                    plt.boundary_handling(sc.boundary_handling, make_slice[0.5, :, :])
                    plt.title(f"3D, diameter={str(diameter,)}")
                    plt.subplot(1, 2, 2)
                    plt.boundary_handling(sc.boundary_handling, make_slice[:, 0.5, :])
                    plt.title(f"3D, diameter={str(diameter, )}")
                    plt.show()
예제 #2
0
def long_run(steady=True, **kwargs):
    if steady:  # scenario 2D-1 in the paper
        sc = schaefer_turek_2d(60, max_lattice_velocity=0.05, **kwargs)
    else:  # Scenario 2D-2 (unsteady)
        sc = schaefer_turek_2d(40, u_max=1.5, max_lattice_velocity=0.01)

    for i in range(100):
        sc.run(10000)
        res = evaluate_static_quantities(sc)
        print(res)
    import lbmpy.plot as plt
    plt.vector_field_magnitude(sc.velocity[:, :])
    plt.show()
예제 #3
0
def write_phase_velocity_picture_sequence(sc,
                                          filename='falling_drop_%05d.png',
                                          time_steps_between_frames=25,
                                          total_steps=9000):
    import lbmpy.plot as plt
    outer_iterations = total_steps // time_steps_between_frames
    for i in range(outer_iterations):
        plt.figure(figsize=(14, 10))
        plt.subplot(1, 2, 1)
        plt.phase_plot(sc.phi[:, :], linewidth=0.1)
        plt.axis('off')
        plt.subplot(1, 2, 2)
        plt.vector_field(sc.velocity[:, 5:-15, :])
        plt.axis('off')
        plt.tight_layout()
        plt.savefig(filename % (i, ), bbox_inches='tight')
        plt.clf()
        sc.run(time_steps_between_frames)
    plt.show()
예제 #4
0
def test_plot():
    arr = np.ones([3, 3, 2])
    plt.multiple_scalar_fields(arr)
    plt.show()
예제 #5
0
def run(convergence_check_interval=1000, convergence_threshold=1e-12, plot_result=False, lambda_plus_sq=4 / 25, re=10,
        square_size=15, quadratic=True, analytic_initial_velocity=False, reynolds_nr_accuracy=1e-8,
        use_mean_for_reynolds=True, **params):
    """
    3D Channel benchmark with rectangular cross-section
    :return: tuple containing
        - size of spurious velocity normal to flow direction normalized to maximum flow velocity
        - number of iterations until convergence
        - the computed reynolds number
    """
    omega = lambda_plus_sq_to_relaxation_rate(lambda_plus_sq)
    params['relaxation_rates'] = [omega, relaxation_rate_from_magic_number(omega, 3 / 16)]

    stencil = params['stencil']
    viscosity_factor = 1 / 2 if stencil == 'D3Q15' and params['maxwellian_moments'] else 1 / 3

    print("Running size %d quadratic %d analyticInit %d " %
          (square_size, quadratic, analytic_initial_velocity) + str(params))
    domain_size = [3, square_size, square_size]
    if not quadratic:
        domain_size[2] //= 2
        if domain_size[2] % 2 == 0:
            domain_size[2] -= 1

    params['domain_size'] = domain_size
    initial_force_value = force_from_reynolds_number(re, domain_size[1], omega,
                                                     viscosity_factor, 2 if use_mean_for_reynolds else 1)
    if not quadratic:
        initial_force_value *= 2  # analytical solution for force is invalid if not quadratic - a good guess is doubled

    if analytic_initial_velocity:
        initial_field = create_initial_velocity_field(initial_force_value, omega, domain_size, viscosity_factor)
        params['initial_velocity'] = initial_field

    scenario = create_channel(force=sp.Symbol('Force'), kernel_params={'Force': initial_force_value}, **params)

    last_vel_field = None
    iterations = 0

    while True:
        scenario.run(convergence_check_interval)
        iterations += convergence_check_interval
        vel = scenario.velocity_slice(make_slice[:, :, :])
        if last_vel_field is not None:
            change_in_time = float(np.ma.average(np.abs(vel - last_vel_field)))

            max_vel = np.array([np.max(scenario.velocity_slice(make_slice[:, :, :])[..., i]) for i in range(3)])

            vel_for_reynolds = np.mean(
                scenario.velocity_slice(make_slice[1, :, :, ])[..., 0]) if use_mean_for_reynolds else max_vel[0]
            computed_re = reynolds_number(vel_for_reynolds, omega, domain_size[1], viscosity_factor)

            reynolds_number_wrong = False
            if reynolds_nr_accuracy is not None and change_in_time < 1e-5:
                reynolds_number_wrong = abs(computed_re / re - 1) > reynolds_nr_accuracy
                if reynolds_number_wrong:
                    old_force = scenario.kernel_params['Force']
                    scenario.kernel_params['Force'] = old_force * re / computed_re

            ref_square_size = 15
            scale_factor = square_size / ref_square_size
            scaled_velocity = scenario.velocity_slice(make_slice[:, :, :]) * scale_factor
            scaled_vorticity_rms = x_vorticity_rms(scaled_velocity, 1 / scale_factor)

            print("    ", iterations, "ReErr", computed_re / re - 1, " spuriousVel ", max_vel[1] / max_vel[0],
                  " Vort ", scaled_vorticity_rms, " Change ", change_in_time)

            if np.isnan(max_vel).any():
                break

            if change_in_time < convergence_threshold and not reynolds_number_wrong:
                break
        last_vel_field = np.copy(vel)

    if plot_result:
        import lbmpy.plot as plt
        vel_profile = vel[1, params['domain_size'][1] // 2, :, 0]
        plt.subplot(1, 2, 1)
        plt.plot(vel_profile)

        vel_cross_section = vel[1, :, :, 1:]
        plt.subplot(1, 2, 2)
        plt.vector_field(vel_cross_section, step=1)

        print(max_vel)
        print(max_vel / max_vel[0])

        plt.show()

    velocity_profile = list(scenario.velocity[1, :, 0.5, 0].data)

    return {
        'normalized_spurious_vel_max': max_vel[1] / max_vel[0],
        'scaled_vorticity_rms': scaled_vorticity_rms,
        'x_vorticity_rms': x_vorticity_rms(scenario.velocity[:, :, :], 1),
        'iterations': iterations,
        'computed_re': computed_re,
        'velocity_profile': velocity_profile,
    }