Skip to content

Density Wave Advection

Man-Long (Norman) Wong edited this page Sep 23, 2019 · 21 revisions

Tutorial 01: Density Wave Advection

Tutorial Goal

In this tutorial, the setup of a simulation of advection of density/entropy wave in a two-dimensional domain is demonstrated. This is an inviscid, single-species and fully periodic problem. The following capabilities of HAMeRS will be shown:

  • Sixth-order shock capturing method WCNS6-LD
  • Third-order TVD-RK3 time integration method
  • One level of adaptive mesh refinement using Jameson sensor on density field to identify regions for refinement
  • Periodic boundary conditions

Problem Description

This is a non-dimensional single-species problem which involves the advection of a square region of heavier gas surrounded by ambient lighter gas. The initial conditions of the problem is:

The ratio of specific heats is 1.4 and the gas constant is 1.0. The problem has a size of [0.0, 1.0) x [0.0, 1.0).

Initial Conditions

The file containing the initial conditions of this problem (DensityWaveAdvection2D.cpp) can be found in problems/Euler/initial_conditions and the initial conditions should be set up by ln -sf <absolute path to DensityWaveAdvection2D.cpp> src/apps/Euler/EulerInitialConditions.cpp. The code has to be re-compiled after the link to the actual initial condition file is set.

Input File Configurations

The configurations of the input file are discussed in this section. The input file format is in the basic C-syntax. The first thing to choose in the input file is whether it is an Euler (inviscid) or Navier-Stokes (diffusive and viscous) application. Since our problem is inviscid, we first set the application type to be Euler:

Application = "Euler"

After that, configurations have to be done on the Euler application. Properties of the application such as project name, number of species, flow model, equation of state, method of inviscid flux derivative, etc. are all specified inside the block of Euler:

Euler
{
    // Name of project
    project_name = "2D advection of density wave"

    // Number of species
    num_species = 1

    // Flow model to use
    flow_model = "SINGLE_SPECIES"

    Flow_model
    {
        // Equation of state to use
        equation_of_state = "IDEAL_GAS"

        Equation_of_state_mixing_rules
        {
            species_gamma = 1.4
            species_R = 1.0
        }
    }

    // Convective flux reconstructor to use
    convective_flux_reconstructor = "WCNS6_LD_HLLC_HLL"

    Convective_flux_reconstructor{}

    Boundary_data{}
    
    Gradient_tagger
    {
        gradient_sensors = "JAMESON_GRADIENT"

        JAMESON_GRADIENT
        {
            Jameson_gradient_variables = "DENSITY"

            Jameson_gradient_tol = 2.0e-4
        }
    }
}

The block for boundary conditions Boundary_data is empty since the problem is periodic in all directions. The periodicity of the problem is set in another block CartesianGeometry. Since flow_model is chosen to be SINGLE_SPECIES, num_species can only be set as 1. Otherwise, error will be shown. Gradient_tagger is included in this block to set the parameters of the gradient tagger. This is consistent with the adoption of gradient tagger in ExtendedTagAndInitialize. The Jameson gradient sensor based on density field is chosen to tag cells for refinement.

The next important block to be set after Euler is Main. There are options to choose the dimension of the simulation, the log file, visualization file and restart file settings. In this tutorial, the following options are chosen:

Main
{
    // Dimension of problem
    dim = 2

    // Base name of log file
    base_name = "2D_density_wave_advection"

    // Whether all nodes log to individual files,
    // if false only node 0 will log
    log_all_nodes = TRUE

    // Visualization dump parameters
    // Setting to dump viz output: CONSTANT_TIME_INTERVAL, CONSTANT_TIMESTEP_INTERVAL
    viz_dump_setting = "CONSTANT_TIME_INTERVAL"
    // Frequency at which to dump viz output (0 to turn off)
    viz_dump_interval = 0.05
    // Name of directory in which to place viz output
    viz_dump_dirname = "viz_2D_density_wave_advection"
    // Number of processors which write to each viz file
    visit_number_procs_per_file = 1

    // Restart dump parameters
    // Frequency at which to dump restart output
    // (-1 to be as same as viz_dump_interval, 0 to turn off)
    restart_interval = -1
}

The computational domain is set in CartesianGeometry. The periodicity of the domain is also set in this block:

CartesianGeometry
{
    domain_boxes = [(0, 0), (127, 127)] // Lower and upper indices of compuational domain
    x_lo         = 0.0, 0.0             // Lower end of computational domain
    x_up         = 1.0, 1.0             // Upper end of computational domain

    // Periodic_dimension. A non-zero value indicates that the direction is periodic
    periodic_dimension = 1, 1
}

The tagging method to tag cells for mesh refinement is chosen in ExtendedTagAndInitialize:

ExtendedTagAndInitialize
{
    // Tagging method for refinement to use
    tagging_method = "GRADIENT_DETECTOR"
}

The parameters of adaptive mesh refinement are set in PatcHierarchy. In this tutorial, the maximum number of mesh levels is set to 2. This is equivalent to having one level of refinement. The details of this block can be referred to SAMRAI::hier::PatchHierarchy of the SAMRAI document.

PatchHierarchy
{
    // Maximum number of levels in hierarchy
    max_levels = 2

    ratio_to_coarser
    {
        // Vector ratio to next coarser level
        level_1 = 2, 2
    }

    largest_patch_size
    {
        level_0 = 1000, 1000
    }

    smallest_patch_size
    {
       level_0 = 4, 4
    }
}

GriddingAlgorithm manages AMR patch hierarchy construction operations in SAMRAI. Default settings of GriddingAlgorithm is used. The details of this block can be referred to SAMRAI::mesh::GriddingAlgorithm of the SAMRAI document.

GriddingAlgorithm{}

The Runge-Kutta (RK) time integration method and Courant–Friedrichs–Lewy (CFL) condition are set in RungeKuttaLevelIntegrator. Since RungeKuttaWeights are not specified in this block, the default TVD-RK3 scheme is used for time integration.

RungeKuttaLevelIntegrator
{
    cfl                      = 0.4e0 // Max cfl factor used in problem
    cfl_init                 = 0.4e0 // Initial cfl factor
    lag_dt_computation       = FALSE
    use_ghosts_to_compute_dt = TRUE
}

TimeRefinementIntegrator mainly specifies the start and end time of the simulation. The details can be referred to SAMRAI::algs::TimeRefinementIntegrator of the SAMRAI document.

TimeRefinementIntegrator
{
    start_time           = 0.0e0 // Initial simulation time
    end_time             = 1.0e0 // Final simulation time
    grow_dt              = 1.0e0 // Growth factor for timesteps
    max_integrator_steps = 10000 // Max number of simulation timesteps
}

The timers in the classes apps::main::*, apps::Euler::*, algs::GriddingAlgorithm::* are printed. The details can be found in SAMRAI::tbox::TimerManager of the SAMRAI document.

TimerManager
{
    print_threshold = 0.01
    timer_list      = "apps::main::*",
                      "apps::Euler::*",
                      "algs::GriddingAlgorithm::*"
}

Running HAMeRS

To run the simulation with one core, first put the input file inside a directory named tutorial_01 under HAMeRS. Then, execute the built main executable inside build/src/exec/main with the input file:

../build/exec/main <input filename>

To run the simulation with multiple cores, you can try mpirun/mpiexec/srun, depending on the MPI library used for the compilation of HAMeRS. For example, if mpirun is used:

mpirun -np <number of processors> ../build/src/exec/main <input filename>

Visualization Using VisIt

The data can be visualized by opening dumps.visit inside the folder viz_2D_density_wave_advection with VisIt. The figures below show the density field and AMR mesh at different times generated from VisIt: