Compressible Couette Flow - mlwong/HAMeRS GitHub Wiki

Tutorial 02: Compressible Couette Flow

Tutorial Goal

In this tutorial, the setup of a simulation of compressible Couette flow in a two-dimensional domain is demonstrated. This is a viscous, single-species problem. The following capabilities of HAMeRS will be shown:

  • Fifth-order shock capturing method WCNS5-JS
  • Sixth-order conservative and non-conservative viscous flux methods
  • No-slip boundary conditions

Problem Description

Two parallel plates of infinite extent are separated by a distance h in the y-direction. Both plates are treated as no-slip isothermal walls at a temperature Tw. The top plate moves at a velocity Uw in the x-direction with respect to the bottom plate. In the case of ideal gas with constant ratio of specific heats γ, shear viscosity μ and thermal conductivity κ, there is an analytical solution for the Navier-Stokes equations:

Taking γ=1.4, μ=0.417 kg/(s·m), Pr=0.72, cp=1005.0 J/(kg·K), h=1.0 m, Tw=300.0 K, Uw=69.445 m/s, we have pc=1.0x105 N/m2, Ma=0.2 and Re=200.0.

The velocity and pressure fields are initialized as those given by analytical solutions. The density field is initialized uniformly as the averaged value of the analytical solution over the entire domain. The density profile should converge to that given by the analytical solution.

Initial Conditions

The file containing the initial conditions of this problem (CouetteFlow2D.cpp) can be found in problems/Navier-Stokes/initial_conditions and the initial conditions should be set up by ln -sf <absolute path to CouetteFlow2D.cpp> src/apps/Navier-Stokes/NavierStokesInitialConditions.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. Only settings of several important blocks are discussed. 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 viscous, we first set the application type to be Navier-Stokes:

Application = "Navier-Stokes"

The block NavierStokes is the next thing to set:

NavierStokes
{
    // Name of project
    project_name = "2D Couette flow in x-direction"

    // 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 = 287.142857143
        }

        // Equation of shear viscosity to use
        equation_of_shear_viscosity = "CONSTANT"

        Equation_of_shear_viscosity_mixing_rules
        {
            species_mu = 0.417
            species_M = 1.0
        }

        // Equation of bulk viscosity to use
        equation_of_bulk_viscosity = "CONSTANT"

        Equation_of_bulk_viscosity_mixing_rules
        {
            species_mu_v = 0.0
            species_M = 1.0
        }

        // Equation of thermal conductivity to use
        equation_of_thermal_conductivity = "PRANDTL"

        Equation_of_thermal_conductivity_mixing_rules
        {
            species_c_p = 1005
            species_Pr = 0.72
            species_M = 1.0
            species_mu = 0.417

            equation_of_shear_viscosity = "CONSTANT"
        }
    }

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

    Convective_flux_reconstructor{}

    use_conservative_form_diffusive_flux = TRUE

    // Diffusive flux reconstructor to use
    diffusive_flux_reconstructor = "SIXTH_ORDER"

    Diffusive_flux_reconstructor{}

    Boundary_data
    {
       boundary_edge_ylo
       {
           boundary_condition = "ISOTHERMAL_NO_SLIP"
           temperature        = 300.0
           velocity           = 0.0, 0.0
       }
       boundary_edge_yhi
       {
           boundary_condition = "ISOTHERMAL_NO_SLIP"
           temperature        = 300.0
           velocity           = 69.445, 0.0
       }

       boundary_node_xlo_ylo
       {
           boundary_condition = "YISOTHERMAL_NO_SLIP"
       }
       boundary_node_xhi_ylo
       {
           boundary_condition = "YISOTHERMAL_NO_SLIP"
       }
       boundary_node_xlo_yhi
       {
           boundary_condition = "YISOTHERMAL_NO_SLIP"
       }
       boundary_node_xhi_yhi
       {
           boundary_condition = "YISOTHERMAL_NO_SLIP"
       }
    }
}

The molecular weight is arbitrarily set to 1.0 for all transport coefficients as it is not needed for mixture rules in single-species flow. Only boundary edges and nodes at the non-periodic boundary conditions are needed to be set. If non-conservative sixth-order accurate method for diffusive/viscous flux is used, use_conservative_form_diffusive_flux should be set to FALSE and diffusive_flux_reconstructor should be replaced by nonconservative_diffusive_flux_divergence_operator:

    ...

    use_conservative_form_diffusive_flux = FALSE

    // Non-conservative diffusive flux divergence operator to use
    nonconservative_diffusive_flux_divergence_operator = "SIXTH_ORDER"

    Nonconservative_diffusive_flux_divergence_operator{}

    ...

The following settings are used for CartesianGeometry:

CartesianGeometry
{
    domain_boxes = [(0, 0), (15, 95)] // Lower and upper indices of computational 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, 0
}

Since uniform grid is used in this tutorial, the block ExtendedTagAndInitialize is empty and max_levels is set to 1 in PatchHierarchy:

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

    ratio_to_coarser
    {}

    largest_patch_size
    {
        level_0 = 1000, 1000
    }

    smallest_patch_size
    {
       level_0 = 4, 4
    }
}

The following settings are used for RungeKuttaLevelIntegrator and TimeRefinementIntegrator:

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

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

The settings for Main, GriddingAlgorithm and TimerManager are very similar to those of tutorial 1 and are not discussed here.

Running HAMeRS

To run the simulation with one core, first put the input file inside a directory named tutorial_02 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 viz folder with VisIt. The figure below shows the converged density field from VisIt:

⚠️ **GitHub.com Fallback** ⚠️