CFD for Automotive Flows

2. simpleFoam and Conditions in Automotive Flows

simpleFoam is a steady-state solver for incompressible, turbulent flow, widely used within the OpenFOAM suite for CFD simulations. It employs the SIMPLE (Semi-Implicit Method for Pressure-Linked Equations) algorithm to solve the Navier-Stokes equations, enabling the analysis of fluid flow through and around objects without the computational overhead of tracking changes over time. This characteristic makes simpleFoam particularly well-suited for studies where the focus is on understanding the final, steady-state flow field rather than the transient behaviors leading up to that state.

In our 2D flow study over a car model, simpleFoam plays a crucial role in predicting how the airflow interacts with the car's surface at a steady state, which is essential for assessing aerodynamic performance, such as lift and drag forces.

The use of the k-omega turbulence model, with specified initial values of k=0.24 for the turbulent kinetic energy and omega=1.78 for the specific rate of dissipation, allows for a more accurate simulation of the turbulent flows around the car. The k-omega model is renowned for its robustness and accuracy in near-wall treatments, making it an appropriate choice for detailed studies involving complex geometries like vehicles. By employing simpleFoam alongside this turbulence model, our study benefits from a solver that is both efficient and capable of capturing the critical nuances of turbulent airflow, providing insights necessary for aerodynamic optimization.


c. Solver setup

The file structure for this case is as follows. You can find details of the files listed below in this section.

~/OpenFOAM/lecture03/car
                     ├── 0
                     │   ├── k
                     │   ├── nut
                     │   ├── omega
                     │   ├── p
                     │   └── U.orig
                     ├── Allclean
                     ├── anim
                     │   ├── output.gif
                     │   └── video.pvsm
                     ├── constant
                     │   ├── geometry
                     │   │   └── carModel.zip
                     │   ├── momentumTransport
                     │   └── physicalProperties
                     └── system
                         ├── blockMeshDict
                         ├── controlDict
                         ├── fvSchemes
                         ├── fvSolution
                         ├── meshQualityDict
                         ├── snappyHexMeshDict
                         └── surfaceFeaturesDict

0 (zero) directory

The U.orig and p files are similar to our first case of ''Cavity Problem''. We set the inlet, outlet, lowerWall (a moving wall in this case), upperWall and frontAndBack boundary conditions in terms of velocity and pressure in these files.

The other files k (turbulent kinetic energy) and omega (specific rate of dissipation) are as follows.

/*--------------------------------*- C++ -*----------------------------------*\
  =========                 | Header section typical for OpenFOAM files, indicating
  \\      /  F ield         | the file's purpose within the OpenFOAM framework.
   \\    /   O peration     | It's more of a decorative comment block.
    \\  /    A nd           | 
     \\/     M anipulation  |
\*---------------------------------------------------------------------------*/

FoamFile // Indicates the start of the file format definition.
{
    format      ascii; // Specifies the file format as ASCII text, making it human-readable.
    class       volScalarField; // Defines the data type as a scalar field defined over the volume mesh.
    object      k; // Specifies that this file describes the turbulent kinetic energy field, denoted as 'k'.
}
// End of the file format definition block.

dimensions      [0 2 -2 0 0 0 0]; // Specifies the physical dimensions of 'k' ([mass, length, time, temperature, quantity, current, luminous intensity]),
                                  // indicating that k has dimensions of m^2/s^2 (velocity squared).

internalField   uniform 0.24; // Sets the initial value of 'k' throughout the domain to 0.24 m^2/s^2.

boundaryField // Begins the definition of boundary conditions for 'k'.
{
    inlet // Defines conditions at the inlet boundary.
    {
        type            fixedValue; // Sets 'k' to a fixed value at the inlet.
        value           uniform 0.24; // The fixed value of 'k' at the inlet, 0.24 m^2/s^2.
    }

    outlet // Defines conditions at the outlet boundary.
    {
        type            inletOutlet; // A conditional type used for outlets where the flow can both enter and leave.
        inletValue      uniform 0.24; // The value of 'k' when there's inflow at the outlet, 0.24 m^2/s^2.
        value           uniform 0.24; // Used to initialize the field and as the outflow condition.
    }

    lowerWall // Defines conditions at the lower wall boundary.
    {
        type            kqRWallFunction; // Specifies a wall function for 'k', suitable for near-wall turbulence modeling.
        value           uniform 0.24; // Initial value of 'k' at the wall, for initialization purposes.
    }

    car // Defines conditions on the surface of the car.
    {
        type            kqRWallFunction; // Again, a wall function for 'k', indicating the same treatment as the lower wall.
        value           uniform 0.24; // Initial value of 'k' at the car's surface.
    }

    upperWall // Defines conditions at the upper wall boundary.
    {
        type slip; // Specifies a slip condition, meaning no shear stress (idealized free-slip wall).
    }

    frontAndBack // For 2D simulations, defines conditions at the front and back planes.
    {
        type slip; // Slip condition applied, as these boundaries are not physically present in a 2D simulation.
    }
}

// ************************************************************************* //
// End of the file, indicating the closure of the k field definition.
/*--------------------------------*- C++ -*----------------------------------*\
  =========                 | Header section for OpenFOAM files, not affecting
  \\      /  F ield         | functionality but indicating the file's role in the
   \\    /   O peration     | OpenFOAM framework as part of the documentation.
    \\  /    A nd           | 
     \\/     M anipulation  |
\*---------------------------------------------------------------------------*/
FoamFile // Start of the FoamFile block, describing the file's metadata.
{
    format      ascii; // The file is in ASCII format, making it readable and editable.
    class       volScalarField; // Type of field, a scalar field defined over the volume.
    object      omega; // The specific field described by this file, omega (specific rate of dissipation).
}
// End of the FoamFile block.

dimensions      [0 0 -1 0 0 0 0]; // Physical dimensions of omega, which is time^-1.

internalField   uniform 1.78; // Sets a uniform initial value of omega throughout the domain to 1.78 s^-1.

boundaryField // Starts the definition of boundary conditions for omega.
{
    inlet // Boundary condition settings for the inlet.
    {
        type            fixedValue; // Omega is set to a fixed value at the inlet.
        value           uniform 1.78; // The fixed value of omega at the inlet, 1.78 s^-1.
    }

    outlet // Boundary condition settings for the outlet.
    {
        type            inletOutlet; // Conditional type for outlets allowing both inflow and outflow.
        inletValue      uniform 1.78; // Value of omega for inflowing fluid at the outlet, 1.78 s^-1.
        value           uniform 1.78; // Used for outflow; also initializes the field, 1.78 s^-1.
    }

    lowerWall // Settings for the lower wall boundary.
    {
        type            omegaWallFunction; // Specifies a wall function for omega, suitable for near-wall regions.
        value           uniform 1.78; // Initial value of omega for wall functions, not directly used in calculations.
    }

    car // Settings for the boundary representing the car surface.
    {
        type            omegaWallFunction; // Again, a wall function for omega, for near-wall turbulence modeling.
        value           uniform 1.78; // Initial value for omega, used by the wall function.
    }

    upperWall // Boundary condition settings for the upper wall.
    {
        type slip; // Specifies a slip condition, implying no shear stress (idealized free-slip wall).
    }

    frontAndBack // For 2D simulations, settings for the front and back boundaries.
    {
        type slip; // Slip condition applied, indicating no physical boundary in the flow direction for 2D cases.
    }
}

// ************************************************************************* //
// Marks the end of the file, concluding the setup for omega.

constant directory

In this directory, momentumTransport and physicalProperties files exist. We set the turbulence model kOmegaSST and kinematic viscosity of air ($ \nu = 1.5\times 10^(-5)~\mathrm{m^2/s} $) in these files, respectively. Please take your time to check the files line by line.


system directory

Here we have the blockMeshDict, surfaceFeaturesDict and snappyHexMeshDict files which we investigated in the previous section.

Moreover, the controlDict, fvSchemes and fvSolution files are locaed here. Please find the explanation for these files below and have a look at them line by line.

controlDict file:

/*--------------------------------*- C++ -*----------------------------------*\
  =========                 |
  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
   \\    /   O peration     | Website:  https://openfoam.org
    \\  /    A nd           | Version:  10
     \\/     M anipulation  |
\*---------------------------------------------------------------------------*/
FoamFile
{
    format      ascii;
    class       dictionary;
    object      controlDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

application     simpleFoam;

startFrom       startTime;

startTime       0;

stopAt          endTime;

endTime         2500;

deltaT          5;

writeControl    timeStep;

writeInterval   5;

purgeWrite      0;

writeFormat     binary;

writePrecision  6;

writeCompression off;

timeFormat      general;

timePrecision   6;

runTimeModifiable true;

// ************************************************************************* //

fvSolution file:

/*--------------------------------*- C++ -*----------------------------------*\
  =========                 | Header section for OpenFOAM files, providing
  \\      /  F ield         | general information. This is a standard comment
   \\    /   O peration     | block and does not affect the simulation.
    \\  /    A nd           | 
     \\/     M anipulation  |
\*---------------------------------------------------------------------------*/
FoamFile // Starts the FoamFile block, which describes the file's metadata.
{
    format      ascii; // Specifies the file is in ASCII format, making it human-readable.
    class       dictionary; // Indicates the file type is a dictionary.
    object      fvSolution; // Specifies the object this file configures: fvSolution.
}
// End of the FoamFile block.

solvers // Start of the solvers section, defining settings for solving each variable.
{
    p // Solver settings for the pressure field.
    {
        solver          GAMG; // Generalized Algebraic Multigrid solver, efficient for large systems.
        smoother        GaussSeidel; // Smoothing algorithm used by the multigrid solver.
        tolerance       1e-7; // Absolute tolerance for solving.
        relTol          0.01; // Relative tolerance, solver stops if the residual is reduced by this factor.
    }

    Phi // Solver settings for the flux field (not directly specified, inherits from 'p').
    {
        $p; // Inherits all settings from the pressure solver 'p'.
    }

    U // Solver settings for the velocity field.
    {
        solver          smoothSolver; // Solver that uses smoothing techniques.
        smoother        GaussSeidel; // Smoothing algorithm used by the solver.
        tolerance       1e-8; // Absolute tolerance for solving.
        relTol          0.1; // Relative tolerance.
        nSweeps         1; // Number of smoothing sweeps to perform.
    }

    k // Solver settings for the turbulent kinetic energy.
    {
        solver          smoothSolver; // Uses smoothing techniques for solving.
        smoother        GaussSeidel; // Smoothing algorithm.
        tolerance       1e-8; // Absolute tolerance.
        relTol          0.1; // Relative tolerance.
        nSweeps         1; // Number of smoothing sweeps.
    }

    omega // Solver settings for the specific rate of dissipation.
    {
        solver          smoothSolver; // Uses smoothing techniques for solving.
        smoother        GaussSeidel; // Smoothing algorithm.
        tolerance       1e-8; // Absolute tolerance.
        relTol          0.1; // Relative tolerance.
        nSweeps         1; // Number of smoothing sweeps.
    }
}

SIMPLE // Settings for the SIMPLE algorithm, used for pressure-velocity coupling.
{
    nNonOrthogonalCorrectors 0; // Number of non-orthogonal correctors. Zero implies no correction for non-orthogonality.
    consistent yes; // Ensures consistency in the pressure and velocity fields.
}

potentialFlow // Settings for initializing the flow field using potential flow solutions.
{
    nNonOrthogonalCorrectors 10; // Number of correctors for potential flow calculation, helpful for complex geometries.
}

relaxationFactors // Settings for under-relaxation, which can improve convergence stability.
{
    equations // Specific settings for equations.
    {
        U               0.9; // Under-relaxation factor for velocity, helps stabilize the solution.
        k               0.5; // Under-relaxation factor for the turbulent kinetic energy.
        omega           0.5; // Under-relaxation factor for the specific rate of dissipation.
    }
}

cache // Cache settings, can speed up certain operations by storing computed values.
{
    grad(U); // Specifies that the gradient of U should be cached.
}

// ************************************************************************* //

fvSchemes file:

/*--------------------------------*- C++ -*----------------------------------*\
  =========                 | Header section, standard in OpenFOAM files, 
  \\      /  F ield         | providing general information and not affecting 
   \\    /   O peration     | the functionality of the file.
    \\  /    A nd           | 
     \\/     M anipulation  |
\*---------------------------------------------------------------------------*/
FoamFile // Indicates the start of the FoamFile block, defining the file's metadata.
{
    format      ascii; // The file format is ASCII, making it human-readable.
    class       dictionary; // Specifies that this file is a dictionary.
    object      fvSchemes; // The object this dictionary configures: fvSchemes.
}
// End of the FoamFile block.

ddtSchemes // Time differentiation schemes.
{
    default         steadyState; // Uses steadyState scheme as the default, indicating no time derivative is considered (steady-state simulation).
}

gradSchemes // Gradient schemes.
{
    default         Gauss linear; // Default scheme for gradients is Gauss linear, providing a balance between accuracy and robustness.
    grad(U)         cellLimited Gauss linear 1; // For velocity gradient calculation, uses cellLimited Gauss linear to limit overshoots and undershoots.
}

divSchemes // Divergence schemes.
{
    default         none; // No default scheme specified, must be defined for each term explicitly.
    div(phi,U)      bounded Gauss linearUpwindV grad(U); // For velocity divergence, uses a bounded linear upwind scheme ensuring values stay within physical bounds.
    div(phi,k)      bounded Gauss upwind; // For turbulent kinetic energy divergence, uses a bounded upwind scheme for stability.
    div(phi,omega)  bounded Gauss upwind; // For specific dissipation rate divergence, also uses a bounded upwind scheme.
    div((nuEff*dev2(T(grad(U))))) Gauss linear; // For the divergence of the deviatoric part of the stress tensor, uses Gauss linear.
}

laplacianSchemes // Laplacian schemes.
{
    default         Gauss linear corrected; // Default Laplacian scheme is Gauss linear corrected, improving accuracy for non-orthogonal meshes.
}

interpolationSchemes // Interpolation schemes.
{
    default         linear; // Default interpolation scheme is linear, offering a good compromise between accuracy and computational cost.
}

snGradSchemes // Surface-normal gradient schemes.
{
    default         corrected; // Default scheme is corrected, enhancing accuracy for non-orthogonal meshes by adjusting gradients at faces.
}

wallDist // Wall distance calculation method.
{
    method meshWave; // Uses the meshWave method to calculate distances to walls, important for wall functions in turbulence models.
}

// ************************************************************************* //

d. Computing

To compute the 2D flow over the car geometry, first run

potentialFoam

to get the initial state of velocity and pressure distribution, and then, run

simpleFoam

As it is set in the system/controlDict file, the simpleFoam command will run OpenFOAM and it will write output of each time step until $ 2500~\mathrm{s} $. The time step size is set as $ \Delta t = 5~\mathrm{s} $. It will write for each 5 time steps. So, the output files will include data for each $ 25~\mathrm{s} $.


e. Post-processing

You can just run paraFoam to open and make visualizations in ParaView.

Figure: Streamtraces and velocity distribution around the car