Beispiel #1
0
def scaling_test(folder_name: str,
                 lattice_grid_shape: Tuple[int, int] = (420, 180),
                 plate_size: int = 40,
                 inlet_density: float = 1.0,
                 inlet_velocity: float = 0.1,
                 kinematic_viscosity: float = 0.04,
                 time_steps: int = 20000):
    """
    Executes the scaling test. Measures the time for simulation and saves results.

    Args:
        folder_name: folder where to save results
        lattice_grid_shape: lattice size
        plate_size: size of plate
        inlet_density: density into the domain
        inlet_velocity: velocity into the domain
        kinematic_viscosity: kinematic viscosity
        time_steps: number of time steps for simulation
    """
    # setup
    lx, ly = lattice_grid_shape
    omega = np.reciprocal(3 * kinematic_viscosity + 0.5)

    size = MPI.COMM_WORLD.Get_size()
    rank = MPI.COMM_WORLD.Get_rank()
    comm = MPI.COMM_WORLD
    x_size, y_size = get_xy_size(size)

    cartesian2d = comm.Create_cart(dims=[x_size, y_size],
                                   periods=[True, True],
                                   reorder=False)
    coords2d = cartesian2d.Get_coords(rank)

    n_local_x, n_local_y = get_local_coords(coords2d, lx, ly, x_size, y_size)

    density, velocity = density_1_velocity_x_u0_velocity_y_0_initial(
        (n_local_x + 2, n_local_y + 2), inlet_velocity)
    f = equilibrium_distr_func(density, velocity)

    bound_func = parallel_von_karman_boundary_conditions(
        coords2d, n_local_x, n_local_y, lx, ly, x_size, y_size, inlet_density,
        inlet_velocity, plate_size)
    communication_func = communication(cartesian2d)

    # main loop
    if rank == 0:
        start = time.time_ns()
    for i in range(time_steps):
        f, density, velocity = lattice_boltzmann_step(f, density, velocity,
                                                      omega, bound_func,
                                                      communication_func)
    if rank == 0:
        end = time.time_ns()
        runtime_ns = end - start
        runtime = runtime_ns / 10e9
        mlups = lx * ly * time_steps / runtime
        np.save(
            r'./figures/von_karman_vortex_shedding/' + folder_name + '/' +
            str(int(lx)) + '_' + str(int(ly)) + '_' + str(int(size)) + '.npy',
            np.array([mlups]))
def run_test():
    lx, ly = 420, 180
    d = 40
    u0 = 0.1
    density_in = 1.0
    kinematic_viscosity = 0.04
    omega = np.reciprocal(3 * kinematic_viscosity + 0.5)
    time_steps = 11

    p_coords = [3 * lx // 4, ly // 2]

    size = MPI.COMM_WORLD.Get_size()
    rank = MPI.COMM_WORLD.Get_rank()
    comm = MPI.COMM_WORLD
    x_size, y_size = get_xy_size(size)

    cartesian2d = comm.Create_cart(dims=[x_size, y_size], periods=[True, True], reorder=False)
    coords2d = cartesian2d.Get_coords(rank)

    n_local_x, n_local_y = get_local_coords(coords2d, lx, ly, x_size, y_size)

    density, velocity = density_1_velocity_x_u0_velocity_y_0_initial((n_local_x + 2, n_local_y + 2), u0)
    f = equilibrium_distr_func(density, velocity)
    process_coord, px, py = global_coord_to_local_coord(coords2d, p_coords[0], p_coords[1], lx, ly, x_size, y_size)
    if process_coord is not None:
        vel_at_p = [np.linalg.norm(velocity[px, py, ...])]

    bound_func = parallel_von_karman_boundary_conditions(coords2d, n_local_x, n_local_y, lx, ly, x_size, y_size, density_in, u0, d)
    communication_func = communication(cartesian2d)

    if rank == 0:
        pbar = tqdm(total=time_steps)
    for i in range(time_steps):
        if rank == 0:
            pbar.update(1)
        f, density, velocity = lattice_boltzmann_step(f, density, velocity, omega, bound_func, communication_func)
        if process_coord is not None:
            vel_at_p.append(np.linalg.norm(velocity[px, py, ...]))
            vel_at_p_test = np.load(r'./tests/von_karman_vortex_shedding/vel_at_p.npy')
            assert vel_at_p[-1] == vel_at_p_test[i + 1]

        for j in range(9):
            save_mpiio(cartesian2d, r'./tests/tmp/f_' + str(j) + '.npy', f[1:-1, 1:-1, j])
        if rank == 0:
            f_gather = [np.load(r'./tests/tmp/f_' + str(j) + '.npy') for j in range(9)]
            f_gather = np.stack(f_gather, axis=-1)
            f_test = np.load(r'./tests/von_karman_vortex_shedding/f_' + str(i) + '.npy')
            assert f_gather.shape == f_test.shape
            assert np.allclose(f_gather, f_test)
Beispiel #3
0
def milestone_7():
    lx, ly = 420, 180
    d = 40
    u0 = 0.1
    density_in = 1.0
    kinematic_viscosity = 0.04
    omega = np.reciprocal(3 * kinematic_viscosity + 0.5)
    time_steps = 100000

    p_coords = [3 * lx // 4, ly // 2]

    size = MPI.COMM_WORLD.Get_size()
    rank = MPI.COMM_WORLD.Get_rank()
    comm = MPI.COMM_WORLD
    x_size, y_size = get_xy_size(size)

    cartesian2d = comm.Create_cart(dims=[x_size, y_size],
                                   periods=[True, True],
                                   reorder=False)
    coords2d = cartesian2d.Get_coords(rank)

    n_local_x, n_local_y = get_local_coords(coords2d, lx, ly, x_size, y_size)

    def boundary(coord2d, n_local_x, n_local_y):
        def bc(f_pre_streaming,
               f_post_streaming,
               density=None,
               velocity=None,
               f_previous=None):
            # inlet
            if x_in_process(coord2d, 0, lx, x_size):
                f_post_streaming[1:-1, 1:-1, :] = inlet(
                    (n_local_x, n_local_y), density_in,
                    u0)(f_post_streaming.copy()[1:-1, 1:-1, :])

            # outlet
            if x_in_process(coord2d, lx - 1, lx, x_size) and x_in_process(
                    coord2d, lx - 2, lx, x_size):
                f_post_streaming[1:-1,
                                 1:-1, :] = outlet()(
                                     f_previous.copy()[1:-1, 1:-1, :],
                                     f_post_streaming.copy()[1:-1, 1:-1, :])
            elif x_in_process(coord2d, lx - 1, lx, x_size) or x_in_process(
                    coord2d, lx - 2, lx, x_size):
                # TODO communicate f_previous
                raise NotImplementedError

            # plate boundary condition
            y_min, y_max = ly // 2 - d // 2 + 1, ly // 2 + d // 2 - 1
            if x_in_process(coord2d, lx // 4, lx, x_size):  # left side
                local_x = global_to_local_direction(coord2d[0], lx // 4, lx,
                                                    x_size)
                for y in range(y_min, y_max):
                    if y_in_process(coord2d, y, ly, y_size):
                        local_y = global_to_local_direction(
                            coord2d[1], y, ly, y_size)
                        f_post_streaming[local_x, local_y,
                                         [3, 7, 6]] = f_pre_streaming[
                                             local_x, local_y, [1, 5, 8]]

                if y_in_process(coord2d, ly // 2 + d // 2 - 1, ly,
                                y_size):  # left side upper corner
                    local_y = global_to_local_direction(
                        coord2d[1], ly // 2 + d // 2 - 1, ly, y_size)
                    f_post_streaming[local_x, local_y,
                                     [3, 6]] = f_pre_streaming[local_x,
                                                               local_y, [1, 8]]
                if y_in_process(coord2d, ly // 2 - d // 2, ly,
                                y_size):  # left side lower corner
                    local_y = global_to_local_direction(
                        coord2d[1], ly // 2 - d // 2, ly, y_size)
                    f_post_streaming[local_x, local_y,
                                     [3, 7]] = f_pre_streaming[local_x,
                                                               local_y, [1, 5]]

            if x_in_process(coord2d, lx // 4 + 1, lx, x_size):  # right side
                local_x = global_to_local_direction(coord2d[0], lx // 4 + 1,
                                                    lx, x_size)
                for y in range(y_min, y_max):
                    if y_in_process(coord2d, y, ly, y_size):
                        local_y = global_to_local_direction(
                            coord2d[1], y, ly, y_size)
                        f_post_streaming[local_x, local_y,
                                         [1, 5, 8]] = f_pre_streaming[
                                             local_x, local_y, [3, 7, 6]]

                if y_in_process(coord2d, ly // 2 + d // 2 - 1, ly,
                                y_size):  # right side upper corner
                    local_y = global_to_local_direction(
                        coord2d[1], ly // 2 + d // 2 - 1, ly, y_size)
                    f_post_streaming[local_x, local_y,
                                     [1, 5]] = f_pre_streaming[local_x,
                                                               local_y, [3, 7]]
                if y_in_process(coord2d, ly // 2 - d // 2, ly,
                                y_size):  # right side lower corner
                    local_y = global_to_local_direction(
                        coord2d[1], ly // 2 - d // 2, ly, y_size)
                    f_post_streaming[local_x, local_y,
                                     [1, 8]] = f_pre_streaming[local_x,
                                                               local_y, [3, 6]]

            return f_post_streaming

        return bc

    density, velocity = density_1_velocity_x_u0_velocity_y_0_initial(
        (n_local_x + 2, n_local_y + 2), u0)
    f = equilibrium_distr_func(density, velocity)
    process_coord, px, py = global_coord_to_local_coord(
        coords2d, p_coords[0], p_coords[1], lx, ly, x_size, y_size)
    if process_coord is not None:
        vel_at_p = [np.linalg.norm(velocity[px, py, ...])]

    bound_func = boundary(coords2d, n_local_x, n_local_y)
    communication_func = communication(cartesian2d)
    if rank == 0:
        pbar = tqdm(total=time_steps)
    for i in range(time_steps):
        if rank == 0:
            pbar.update(1)
        f, density, velocity = lattice_boltzmann_step(f, density, velocity,
                                                      omega, bound_func,
                                                      communication_func)
        if process_coord is not None:
            vel_at_p.append(np.linalg.norm(velocity[px, py, ...]))

        if i % 100 == 0:
            abs_vel = np.linalg.norm(velocity[1:-1, 1:-1, :], axis=-1)
            assert abs_vel.shape == (n_local_x, n_local_y)
            save_mpiio(
                cartesian2d,
                r'./figures/von_karman_vortex_shedding/all_png_parallel/vel_norm.npy',
                abs_vel)

            if rank == 0:
                abs_vel = np.load(
                    r'./figures/von_karman_vortex_shedding/all_png_parallel/vel_norm.npy'
                )
                normalized_vel = abs_vel / np.amax(abs_vel)
                from PIL import Image
                from matplotlib import cm
                img = Image.fromarray(
                    np.uint8(cm.viridis(normalized_vel.T) * 255))
                img.save(
                    r'./figures/von_karman_vortex_shedding/all_png_parallel/' +
                    str(i) + '.png')
                os.remove(
                    r'./figures/von_karman_vortex_shedding/all_png_parallel/vel_norm.npy'
                )

    np.save(r'../figures/von_karman_vortex_shedding/vel_at_p.py', vel_at_p)
    vel_at_p = np.load(
        r'../figures/von_karman_vortex_shedding/vel_at_p.py.npy')
    np.save(r'../figures/von_karman_vortex_shedding/velocity.py', velocity)
    velocity = np.load(
        r'../figures/von_karman_vortex_shedding/velocity.py.npy')
    np.save(r'../figures/von_karman_vortex_shedding/density.py', density)
    density = np.load(r'../figures/von_karman_vortex_shedding/density.py.npy')
    absolute_velocity = np.linalg.norm(velocity, axis=-1)
    normalized_abs_velocity = absolute_velocity / np.amax(absolute_velocity)
    plt.imshow(normalized_abs_velocity.T)
    plt.colorbar()
    plt.show()

    plt.plot(np.arange(0, time_steps + 1), vel_at_p, linewidth=0.3)
    plt.show()

    vel_at_p = vel_at_p[70000:]

    plt.plot(vel_at_p)
    plt.show()

    yf = np.fft.fft(vel_at_p)
    freq = np.fft.fftfreq(len(vel_at_p), 1)

    plt.plot(freq, np.abs(yf.imag))
    plt.show()

    vortex_frequency = np.abs(freq[np.argmax(yf.imag)])
    print(vortex_frequency)
    strouhal = strouhal_number(vortex_frequency, d, u0)
    print(strouhal)
    reynolds = reynolds_number(d, u0, kinematic_viscosity)
    print(reynolds)
Beispiel #4
0
def x_strouhal(folder_name: str,
               lattice_grid_shape: Tuple[int, int] = (420, 180),
               plate_size: int = 40,
               inlet_density: float = 1.0,
               inlet_velocity: float = 0.1,
               kinematic_viscosity: float = 0.04,
               time_steps: int = 200000):
    """
    General functions to execute experiments to study the relationship of the strouhal numbers to a given x
    (e.g. reynolds number, nx, blockage ratio)

    Args:
        folder_name: folder to save the files to
        lattice_grid_shape: lattice size
        plate_size: size of the plate
        inlet_density: density into the domain
        inlet_velocity: velocity into the domain
        kinematic_viscosity: kinematic viscosity
        time_steps: number of time steps for the simulation
    """
    # setup
    lx, ly = lattice_grid_shape
    omega = np.reciprocal(3 * kinematic_viscosity + 0.5)

    p_coords = [3 * lx // 4, ly // 2]

    size = MPI.COMM_WORLD.Get_size()
    rank = MPI.COMM_WORLD.Get_rank()
    comm = MPI.COMM_WORLD
    x_size, y_size = get_xy_size(size)

    cartesian2d = comm.Create_cart(dims=[x_size, y_size],
                                   periods=[True, True],
                                   reorder=False)
    coords2d = cartesian2d.Get_coords(rank)

    n_local_x, n_local_y = get_local_coords(coords2d, lx, ly, x_size, y_size)

    density, velocity = density_1_velocity_x_u0_velocity_y_0_initial(
        (n_local_x + 2, n_local_y + 2), inlet_velocity)
    f = equilibrium_distr_func(density, velocity)
    process_coord, px, py = global_coord_to_local_coord(
        coords2d, p_coords[0], p_coords[1], lx, ly, x_size, y_size)
    if process_coord is not None:
        vel_at_p = [np.linalg.norm(velocity[px, py, ...])]

    bound_func = parallel_von_karman_boundary_conditions(
        coords2d, n_local_x, n_local_y, lx, ly, x_size, y_size, inlet_density,
        inlet_velocity, plate_size)
    communication_func = communication(cartesian2d)

    # main loop
    if rank == 0:
        pbar = tqdm(total=time_steps)
    for i in range(time_steps):
        if rank == 0:
            pbar.update(1)
        f, density, velocity = lattice_boltzmann_step(f, density, velocity,
                                                      omega, bound_func,
                                                      communication_func)
        if process_coord is not None:
            vel_at_p.append(np.linalg.norm(velocity[px, py, ...]))

    if process_coord is not None:
        if 'reynold' in folder_name:
            reynolds_number = plate_size * inlet_velocity / kinematic_viscosity
            np.save(
                r'./figures/von_karman_vortex_shedding/' + folder_name +
                '/vel_at_p_' + str(round(reynolds_number)) + '.npy', vel_at_p)
        elif 'nx' in folder_name:
            np.save(
                r'./figures/von_karman_vortex_shedding/' + folder_name +
                '/vel_at_p_' + str(int(lx)) + '.npy', vel_at_p)
        elif 'blockage' in folder_name:
            blockage_ratio = plate_size / ly
            np.save(
                r'./figures/von_karman_vortex_shedding/' + folder_name +
                '/vel_at_p_' + str(blockage_ratio) + '.npy', vel_at_p)
        else:
            raise Exception('Unknown experiment')
Beispiel #5
0
def plot_parallel_von_karman_vortex_street(
        lattice_grid_shape: Tuple[int, int] = (420, 180),
        plate_size: int = 40,
        inlet_density: float = 1.0,
        inlet_velocity: float = 0.1,
        kinematic_viscosity: float = 0.04,
        time_steps: int = 100000):
    """
    Executes the parallel version of the code of the von Karman vortex street and saves each 100 time steps the
    current velocity magnitude field.

    Args:
        lattice_grid_shape: lattice size
        plate_size: size of the plate
        inlet_density: density into the domain
        inlet_velocity: velocity into the domain
        kinematic_viscosity: kinematic viscosity
        time_steps: number of time steps for simulation
    """
    # setup
    lx, ly = lattice_grid_shape
    omega = np.reciprocal(3 * kinematic_viscosity + 0.5)

    p_coords = [3 * lx // 4, ly // 2]

    size = MPI.COMM_WORLD.Get_size()
    rank = MPI.COMM_WORLD.Get_rank()
    comm = MPI.COMM_WORLD
    x_size, y_size = get_xy_size(size)

    cartesian2d = comm.Create_cart(dims=[x_size, y_size],
                                   periods=[True, True],
                                   reorder=False)
    coords2d = cartesian2d.Get_coords(rank)

    n_local_x, n_local_y = get_local_coords(coords2d, lx, ly, x_size, y_size)

    density, velocity = density_1_velocity_x_u0_velocity_y_0_initial(
        (n_local_x + 2, n_local_y + 2), inlet_velocity)
    f = equilibrium_distr_func(density, velocity)
    process_coord, px, py = global_coord_to_local_coord(
        coords2d, p_coords[0], p_coords[1], lx, ly, x_size, y_size)
    if process_coord is not None:
        vel_at_p = [np.linalg.norm(velocity[px, py, ...])]

    bound_func = parallel_von_karman_boundary_conditions(
        coords2d, n_local_x, n_local_y, lx, ly, x_size, y_size, inlet_density,
        inlet_velocity, plate_size)
    communication_func = communication(cartesian2d)

    # main loop
    if rank == 0:
        pbar = tqdm(total=time_steps)
    for i in range(time_steps):
        if rank == 0:
            pbar.update(1)
        f, density, velocity = lattice_boltzmann_step(f, density, velocity,
                                                      omega, bound_func,
                                                      communication_func)
        if process_coord is not None:
            vel_at_p.append(np.linalg.norm(velocity[px, py, ...]))

        if i % 100 == 0:
            abs_vel = np.linalg.norm(velocity[1:-1, 1:-1, :], axis=-1)
            save_mpiio(
                cartesian2d,
                r'./figures/von_karman_vortex_shedding/all_png_parallel/vel_norm.npy',
                abs_vel)

            if rank == 0:
                abs_vel = np.load(
                    r'./figures/von_karman_vortex_shedding/all_png_parallel/vel_norm.npy'
                )
                normalized_vel = abs_vel / np.amax(abs_vel)
                img = Image.fromarray(
                    np.uint8(cm.viridis(normalized_vel.T) * 255))
                img.save(
                    r'./figures/von_karman_vortex_shedding/all_png_parallel/' +
                    str(i) + '.png')
                os.remove(
                    r'./figures/von_karman_vortex_shedding/all_png_parallel/vel_norm.npy'
                )