Ejemplo n.º 1
0
def run(re=6000, eval_interval=0.05, total_time=3.0, domain_size=100, u_0=0.05,
        initialization_relaxation_rate=None, vtk_output=False, parallel=False, **kwargs):
    """Runs the kida vortex simulation.

    Args:
        re: Reynolds number
        eval_interval: interval in non-dimensional time to evaluate flow properties
        total_time: non-dimensional time of complete simulation
        domain_size: integer (not tuple) since domain is cubic
        u_0: maximum lattice velocity
        initialization_relaxation_rate: if not None, an advanced initialization scheme is run to initialize higher
                                        order moments correctly
        vtk_output: if vtk files are written out
        parallel: MPI parallelization with walberla
        **kwargs: passed to LbStep

    Returns:
        dictionary with simulation results
    """
    domain_shape = (domain_size, domain_size, domain_size)
    relaxation_rate = relaxation_rate_from_reynolds_number(re, u_0, domain_size)
    dh = ps.create_data_handling(domain_shape, periodicity=True, parallel=parallel)
    rr_subs = {'viscosity': relaxation_rate,
               'trt_magic': relaxation_rate_from_magic_number(relaxation_rate),
               'free': sp.Symbol("rr_f")}

    if 'relaxation_rates' in kwargs:
        kwargs['relaxation_rates'] = [rr_subs[r] if isinstance(r, str) else r for r in kwargs['relaxation_rates']]
    else:
        kwargs['relaxation_rates'] = [relaxation_rate]

    dh.log_on_root("Running kida vortex scenario of size {} with {}".format(domain_size, kwargs))
    dh.log_on_root("Compiling method")

    lb_step = LatticeBoltzmannStep(data_handling=dh, name="kida_vortex", **kwargs)

    set_initial_velocity(lb_step, u_0)
    residuum, init_steps = np.nan, 0
    if initialization_relaxation_rate is not None:
        dh.log_on_root("Running iterative initialization", level='PROGRESS')
        residuum, init_steps = lb_step.run_iterative_initialization(initialization_relaxation_rate,
                                                                    convergence_threshold=1e-12, max_steps=100000,
                                                                    check_residuum_after=2 * domain_size)
        dh.log_on_root("Iterative initialization finished after {} steps at residuum {}".format(init_steps, residuum))

    total_time_steps = normalized_time_to_time_step(total_time, domain_size, u_0)
    eval_time_steps = normalized_time_to_time_step(eval_interval, domain_size, u_0)

    initial_energy = parallel_mean(lb_step, mean_kinetic_energy, all_reduce=False)
    times = []
    energy_list = []
    enstrophy_list = []
    mlups_list = []
    energy_spectrum_arr = None

    while lb_step.time_steps_run < total_time_steps:
        mlups = lb_step.benchmark_run(eval_time_steps, number_of_cells=domain_size**3)
        if vtk_output:
            lb_step.write_vtk()

        current_time = time_step_to_normalized_time(lb_step.time_steps_run, domain_size, u_0)
        current_kinetic_energy = parallel_mean(lb_step, mean_kinetic_energy)
        current_enstrophy = parallel_mean(lb_step, mean_enstrophy)

        is_stable = np.isfinite(lb_step.data_handling.max(lb_step.velocity_data_name)) and current_enstrophy < 1e4
        if not is_stable:
            dh.log_on_root("Simulation got unstable - stopping", level='WARNING')
            break

        if current_time >= 0.5 and energy_spectrum_arr is None and domain_size <= 600:
            dh.log_on_root("Calculating energy spectrum")
            gathered_velocity = lb_step.velocity[:, :, :, :]

            if gathered_velocity is not None:
                energy_spectrum_arr = energy_density_spectrum(gathered_velocity)
            else:
                energy_spectrum_arr = False

        if dh.is_root:
            current_kinetic_energy /= initial_energy
            current_enstrophy *= domain_size ** 2

            times.append(current_time)
            energy_list.append(current_kinetic_energy)
            enstrophy_list.append(current_enstrophy)
            mlups_list.append(mlups)

            dh.log_on_root("Progress: {current_time:.02f} / {total_time} at {mlups:.01f} MLUPS\t"
                           "Enstrophy {current_enstrophy:.04f}\t"
                           "KinEnergy {current_kinetic_energy:.06f}".format(**locals()))

    if dh.is_root:
        return {
            'initialization_residuum': residuum,
            'initialization_steps': init_steps,
            'time': times,
            'kinetic_energy': energy_list,
            'enstrophy': enstrophy_list,
            'mlups': np.average(mlups_list),
            'energy_spectrum': list(energy_spectrum_arr),
            'stable': bool(np.isfinite(lb_step.data_handling.max(lb_step.velocity_data_name)))
        }
    else:
        return None
Ejemplo n.º 2
0
def rod_simulation(stencil_name,
                   diameter,
                   parallel=False,
                   entropic=False,
                   re=150,
                   time_to_simulate=17.0,
                   eval_interval=0.5,
                   write_vtk=True,
                   write_numpy=True):

    if stencil_name == 'D3Q19_new':
        stencil = Stencil.D3Q19
        maxwellian_moments = True
    elif stencil_name == 'D3Q19_old':
        stencil = Stencil.D3Q19
        maxwellian_moments = False
    elif stencil_name == 'D3Q27':
        stencil = Stencil.D3Q27
        maxwellian_moments = False
    else:
        raise ValueError("Unknown stencil name " + stencil_name)
    d = diameter
    length = 16 * d

    u_max_at_throat = 0.07
    u_max_at_inflow = 0.07 / (3**2)

    # Geometry parameters
    inflow_area = int(1.5 * d)
    constriction_length = int(1.8904 * d)
    throat_length = int(10 / 3 * d)
    constriction_diameter = int(d / 3)

    u_mean_at_throat = u_max_at_throat / 2
    lattice_viscosity = u_mean_at_throat * constriction_diameter / re
    omega = relaxation_rate_from_lattice_viscosity(lattice_viscosity)

    lbm_config = LBMConfig(stencil=LBStencil(stencil),
                           compressible=True,
                           method=Method.SRT,
                           relaxation_rate=omega,
                           entropic=entropic,
                           maxwellian_moments=maxwellian_moments)
    kernel_params = {}

    print("ω=", omega)

    dh = create_data_handling(domain_size=(length, d, d), parallel=parallel)
    sc = LatticeBoltzmannStep(data_handling=dh,
                              kernel_params=kernel_params,
                              name=stencil_name,
                              lbm_config=lbm_config)

    # -----------------   Boundary Setup   --------------------------------

    def pipe_geometry(x, *_):
        # initialize with full diameter everywhere
        result = np.ones_like(x) * d

        # constriction
        constriction_begin = inflow_area
        constriction_end = constriction_begin + constriction_length
        c_x = np.linspace(0, 1, constriction_length)
        result[constriction_begin:constriction_end] = d * (
            1 - c_x) + constriction_diameter * c_x

        # throat
        throat_start = constriction_end
        throat_end = throat_start + throat_length
        result[throat_start:throat_end] = constriction_diameter

        return result

    bh = sc.boundary_handling
    add_pipe_inflow_boundary(bh, u_max_at_inflow, make_slice[0, :, :])
    outflow = FixedDensity(1.0)
    bh.set_boundary(outflow, slice_from_direction('E', 3))
    wall = NoSlip()
    add_pipe_walls(bh, pipe_geometry, wall)

    # -----------------   Run  --------------------------------------------

    scenario_name = stencil_name

    if not os.path.exists(scenario_name):
        os.mkdir(scenario_name)

    def to_time_steps(non_dimensional_time):
        return int(diameter / (u_max_at_inflow / 2) * non_dimensional_time)

    time_steps = to_time_steps(time_to_simulate)
    eval_interval = to_time_steps(eval_interval)

    print("Total number of time steps", time_steps)

    for i in range(time_steps // eval_interval):
        sc.run(eval_interval)
        if write_vtk:
            sc.write_vtk()
        vel = sc.velocity[:, :, :, :]
        max_vel = np.max(vel)
        print("Time steps:", sc.time_steps_run, "/", time_steps,
              "Max velocity: ", max_vel)
        if np.isnan(max_vel):
            raise ValueError("Simulation went unstable")
        if write_numpy:
            np.save(scenario_name + f'/velocity_{sc.time_steps_run}',
                    sc.velocity_slice().filled(0.0))